{"version":3,"file":"itinerary_editor-WQcKKpcg.js","sources":["../../../node_modules/date-fns/constants.js","../../../node_modules/date-fns/constructFrom.js","../../../node_modules/date-fns/toDate.js","../../../node_modules/date-fns/_lib/defaultOptions.js","../../../node_modules/date-fns/startOfWeek.js","../../../node_modules/date-fns/startOfISOWeek.js","../../../node_modules/date-fns/getISOWeekYear.js","../../../node_modules/date-fns/_lib/getTimezoneOffsetInMilliseconds.js","../../../node_modules/date-fns/_lib/normalizeDates.js","../../../node_modules/date-fns/startOfDay.js","../../../node_modules/date-fns/differenceInCalendarDays.js","../../../node_modules/date-fns/startOfISOWeekYear.js","../../../node_modules/date-fns/isDate.js","../../../node_modules/date-fns/isValid.js","../../../node_modules/date-fns/startOfYear.js","../../../node_modules/date-fns/locale/en-US/_lib/formatDistance.js","../../../node_modules/date-fns/locale/_lib/buildFormatLongFn.js","../../../node_modules/date-fns/locale/en-US/_lib/formatLong.js","../../../node_modules/date-fns/locale/en-US/_lib/formatRelative.js","../../../node_modules/date-fns/locale/_lib/buildLocalizeFn.js","../../../node_modules/date-fns/locale/en-US/_lib/localize.js","../../../node_modules/date-fns/locale/_lib/buildMatchFn.js","../../../node_modules/date-fns/locale/_lib/buildMatchPatternFn.js","../../../node_modules/date-fns/locale/en-US/_lib/match.js","../../../node_modules/date-fns/locale/en-US.js","../../../node_modules/date-fns/getDayOfYear.js","../../../node_modules/date-fns/getISOWeek.js","../../../node_modules/date-fns/getWeekYear.js","../../../node_modules/date-fns/startOfWeekYear.js","../../../node_modules/date-fns/getWeek.js","../../../node_modules/date-fns/_lib/addLeadingZeros.js","../../../node_modules/date-fns/_lib/format/lightFormatters.js","../../../node_modules/date-fns/_lib/format/formatters.js","../../../node_modules/date-fns/_lib/format/longFormatters.js","../../../node_modules/date-fns/_lib/protectedTokens.js","../../../node_modules/date-fns/format.js","../../../node_modules/date-fns/locale/fr/_lib/formatDistance.js","../../../node_modules/date-fns/locale/fr/_lib/formatLong.js","../../../node_modules/date-fns/locale/fr/_lib/formatRelative.js","../../../node_modules/date-fns/locale/fr/_lib/localize.js","../../../node_modules/date-fns/locale/fr/_lib/match.js","../../../node_modules/date-fns/locale/fr.js","../../../node_modules/@editorjs/editorjs/dist/editorjs.mjs","../../../node_modules/@editorjs/underline/dist/underline.mjs","../../../node_modules/@editorjs/list/dist/list.mjs","../../../node_modules/@editorjs/paragraph/dist/paragraph.mjs","../../../app/javascript/controllers/editorJs/mergeTag.js","../../../node_modules/vue/dist/vue.runtime.esm.js","../../../node_modules/vue-demi/lib/index.mjs","../../../node_modules/@vue/devtools-api/lib/esm/env.js","../../../node_modules/@vue/devtools-api/lib/esm/const.js","../../../node_modules/@vue/devtools-api/lib/esm/time.js","../../../node_modules/@vue/devtools-api/lib/esm/proxy.js","../../../node_modules/@vue/devtools-api/lib/esm/index.js","../../../node_modules/pinia/dist/pinia.mjs","../../../app/javascript/itineraries-editor/store.js","../../../node_modules/vue-i18n/dist/vue-i18n.esm.js","../../../node_modules/editorjs-html/build/edjsHTML.node.js","../../../node_modules/v-click-outside/dist/v-click-outside.umd.js","../../../app/javascript/itineraries-editor/Item.vue","../../../app/javascript/itineraries-editor/MergeTagSelect.vue","../../../app/javascript/itineraries-editor/utils.js","../../../app/javascript/itineraries-editor/Header.vue","../../../app/javascript/itineraries-editor/Intro.vue","../../../app/javascript/itineraries-editor/DateSection.vue","../../../app/javascript/itineraries-editor/Signature.vue","../../../node_modules/bootstrap/js/src/util.js","../../../node_modules/bootstrap/js/src/modal.js","../../../app/javascript/itineraries-editor/App.vue","../../../app/javascript/itineraries-editor/translate.js","../../../app/javascript/packs/itineraries_editor.js"],"sourcesContent":["/**\n * @module constants\n * @summary Useful constants\n * @description\n * Collection of useful date constants.\n *\n * The constants could be imported from `date-fns/constants`:\n *\n * ```ts\n * import { maxTime, minTime } from \"./constants/date-fns/constants\";\n *\n * function isAllowedTime(time) {\n * return time <= maxTime && time >= minTime;\n * }\n * ```\n */\n\n/**\n * @constant\n * @name daysInWeek\n * @summary Days in 1 week.\n */\nexport const daysInWeek = 7;\n\n/**\n * @constant\n * @name daysInYear\n * @summary Days in 1 year.\n *\n * @description\n * How many days in a year.\n *\n * One years equals 365.2425 days according to the formula:\n *\n * > Leap year occurs every 4 years, except for years that are divisible by 100 and not divisible by 400.\n * > 1 mean year = (365+1/4-1/100+1/400) days = 365.2425 days\n */\nexport const daysInYear = 365.2425;\n\n/**\n * @constant\n * @name maxTime\n * @summary Maximum allowed time.\n *\n * @example\n * import { maxTime } from \"./constants/date-fns/constants\";\n *\n * const isValid = 8640000000000001 <= maxTime;\n * //=> false\n *\n * new Date(8640000000000001);\n * //=> Invalid Date\n */\nexport const maxTime = Math.pow(10, 8) * 24 * 60 * 60 * 1000;\n\n/**\n * @constant\n * @name minTime\n * @summary Minimum allowed time.\n *\n * @example\n * import { minTime } from \"./constants/date-fns/constants\";\n *\n * const isValid = -8640000000000001 >= minTime;\n * //=> false\n *\n * new Date(-8640000000000001)\n * //=> Invalid Date\n */\nexport const minTime = -maxTime;\n\n/**\n * @constant\n * @name millisecondsInWeek\n * @summary Milliseconds in 1 week.\n */\nexport const millisecondsInWeek = 604800000;\n\n/**\n * @constant\n * @name millisecondsInDay\n * @summary Milliseconds in 1 day.\n */\nexport const millisecondsInDay = 86400000;\n\n/**\n * @constant\n * @name millisecondsInMinute\n * @summary Milliseconds in 1 minute\n */\nexport const millisecondsInMinute = 60000;\n\n/**\n * @constant\n * @name millisecondsInHour\n * @summary Milliseconds in 1 hour\n */\nexport const millisecondsInHour = 3600000;\n\n/**\n * @constant\n * @name millisecondsInSecond\n * @summary Milliseconds in 1 second\n */\nexport const millisecondsInSecond = 1000;\n\n/**\n * @constant\n * @name minutesInYear\n * @summary Minutes in 1 year.\n */\nexport const minutesInYear = 525600;\n\n/**\n * @constant\n * @name minutesInMonth\n * @summary Minutes in 1 month.\n */\nexport const minutesInMonth = 43200;\n\n/**\n * @constant\n * @name minutesInDay\n * @summary Minutes in 1 day.\n */\nexport const minutesInDay = 1440;\n\n/**\n * @constant\n * @name minutesInHour\n * @summary Minutes in 1 hour.\n */\nexport const minutesInHour = 60;\n\n/**\n * @constant\n * @name monthsInQuarter\n * @summary Months in 1 quarter.\n */\nexport const monthsInQuarter = 3;\n\n/**\n * @constant\n * @name monthsInYear\n * @summary Months in 1 year.\n */\nexport const monthsInYear = 12;\n\n/**\n * @constant\n * @name quartersInYear\n * @summary Quarters in 1 year\n */\nexport const quartersInYear = 4;\n\n/**\n * @constant\n * @name secondsInHour\n * @summary Seconds in 1 hour.\n */\nexport const secondsInHour = 3600;\n\n/**\n * @constant\n * @name secondsInMinute\n * @summary Seconds in 1 minute.\n */\nexport const secondsInMinute = 60;\n\n/**\n * @constant\n * @name secondsInDay\n * @summary Seconds in 1 day.\n */\nexport const secondsInDay = secondsInHour * 24;\n\n/**\n * @constant\n * @name secondsInWeek\n * @summary Seconds in 1 week.\n */\nexport const secondsInWeek = secondsInDay * 7;\n\n/**\n * @constant\n * @name secondsInYear\n * @summary Seconds in 1 year.\n */\nexport const secondsInYear = secondsInDay * daysInYear;\n\n/**\n * @constant\n * @name secondsInMonth\n * @summary Seconds in 1 month\n */\nexport const secondsInMonth = secondsInYear / 12;\n\n/**\n * @constant\n * @name secondsInQuarter\n * @summary Seconds in 1 quarter.\n */\nexport const secondsInQuarter = secondsInMonth * 3;\n\n/**\n * @constant\n * @name constructFromSymbol\n * @summary Symbol enabling Date extensions to inherit properties from the reference date.\n *\n * The symbol is used to enable the `constructFrom` function to construct a date\n * using a reference date and a value. It allows to transfer extra properties\n * from the reference date to the new date. It's useful for extensions like\n * [`TZDate`](https://github.com/date-fns/tz) that accept a time zone as\n * a constructor argument.\n */\nexport const constructFromSymbol = Symbol.for(\"constructDateFrom\");\n","import { constructFromSymbol } from \"./constants.js\";\n\n/**\n * @name constructFrom\n * @category Generic Helpers\n * @summary Constructs a date using the reference date and the value\n *\n * @description\n * The function constructs a new date using the constructor from the reference\n * date and the given value. It helps to build generic functions that accept\n * date extensions.\n *\n * It defaults to `Date` if the passed reference date is a number or a string.\n *\n * Starting from v3.7.0, it allows to construct a date using `[Symbol.for(\"constructDateFrom\")]`\n * enabling to transfer extra properties from the reference date to the new date.\n * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)\n * that accept a time zone as a constructor argument.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n *\n * @param date - The reference date to take constructor from\n * @param value - The value to create the date\n *\n * @returns Date initialized using the given date and value\n *\n * @example\n * import { constructFrom } from \"./constructFrom/date-fns\";\n *\n * // A function that clones a date preserving the original type\n * function cloneDate(date: DateType): DateType {\n * return constructFrom(\n * date, // Use constructor from the given date\n * date.getTime() // Use the date value to create a new date\n * );\n * }\n */\nexport function constructFrom(date, value) {\n if (typeof date === \"function\") return date(value);\n\n if (date && typeof date === \"object\" && constructFromSymbol in date)\n return date[constructFromSymbol](value);\n\n if (date instanceof Date) return new date.constructor(value);\n\n return new Date(value);\n}\n\n// Fallback for modularized imports:\nexport default constructFrom;\n","import { constructFrom } from \"./constructFrom.js\";\n\n/**\n * @name toDate\n * @category Common Helpers\n * @summary Convert the given argument to an instance of Date.\n *\n * @description\n * Convert the given argument to an instance of Date.\n *\n * If the argument is an instance of Date, the function returns its clone.\n *\n * If the argument is a number, it is treated as a timestamp.\n *\n * If the argument is none of the above, the function returns Invalid Date.\n *\n * Starting from v3.7.0, it clones a date using `[Symbol.for(\"constructDateFrom\")]`\n * enabling to transfer extra properties from the reference date to the new date.\n * It's useful for extensions like [`TZDate`](https://github.com/date-fns/tz)\n * that accept a time zone as a constructor argument.\n *\n * **Note**: *all* Date arguments passed to any *date-fns* function is processed by `toDate`.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param argument - The value to convert\n *\n * @returns The parsed date in the local time zone\n *\n * @example\n * // Clone the date:\n * const result = toDate(new Date(2014, 1, 11, 11, 30, 30))\n * //=> Tue Feb 11 2014 11:30:30\n *\n * @example\n * // Convert the timestamp to date:\n * const result = toDate(1392098430000)\n * //=> Tue Feb 11 2014 11:30:30\n */\nexport function toDate(argument, context) {\n // [TODO] Get rid of `toDate` or `constructFrom`?\n return constructFrom(context || argument, argument);\n}\n\n// Fallback for modularized imports:\nexport default toDate;\n","let defaultOptions = {};\n\nexport function getDefaultOptions() {\n return defaultOptions;\n}\n\nexport function setDefaultOptions(newOptions) {\n defaultOptions = newOptions;\n}\n","import { getDefaultOptions } from \"./_lib/defaultOptions.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * The {@link startOfWeek} function options.\n */\n\n/**\n * @name startOfWeek\n * @category Week Helpers\n * @summary Return the start of a week for the given date.\n *\n * @description\n * Return the start of a week for the given date.\n * The result will be in the local timezone.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The original date\n * @param options - An object with options\n *\n * @returns The start of a week\n *\n * @example\n * // The start of a week for 2 September 2014 11:55:00:\n * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Sun Aug 31 2014 00:00:00\n *\n * @example\n * // If the week starts on Monday, the start of the week for 2 September 2014 11:55:00:\n * const result = startOfWeek(new Date(2014, 8, 2, 11, 55, 0), { weekStartsOn: 1 })\n * //=> Mon Sep 01 2014 00:00:00\n */\nexport function startOfWeek(date, options) {\n const defaultOptions = getDefaultOptions();\n const weekStartsOn =\n options?.weekStartsOn ??\n options?.locale?.options?.weekStartsOn ??\n defaultOptions.weekStartsOn ??\n defaultOptions.locale?.options?.weekStartsOn ??\n 0;\n\n const _date = toDate(date, options?.in);\n const day = _date.getDay();\n const diff = (day < weekStartsOn ? 7 : 0) + day - weekStartsOn;\n\n _date.setDate(_date.getDate() - diff);\n _date.setHours(0, 0, 0, 0);\n return _date;\n}\n\n// Fallback for modularized imports:\nexport default startOfWeek;\n","import { startOfWeek } from \"./startOfWeek.js\";\n\n/**\n * The {@link startOfISOWeek} function options.\n */\n\n/**\n * @name startOfISOWeek\n * @category ISO Week Helpers\n * @summary Return the start of an ISO week for the given date.\n *\n * @description\n * Return the start of an ISO week for the given date.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The original date\n * @param options - An object with options\n *\n * @returns The start of an ISO week\n *\n * @example\n * // The start of an ISO week for 2 September 2014 11:55:00:\n * const result = startOfISOWeek(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Mon Sep 01 2014 00:00:00\n */\nexport function startOfISOWeek(date, options) {\n return startOfWeek(date, { ...options, weekStartsOn: 1 });\n}\n\n// Fallback for modularized imports:\nexport default startOfISOWeek;\n","import { constructFrom } from \"./constructFrom.js\";\nimport { startOfISOWeek } from \"./startOfISOWeek.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * The {@link getISOWeekYear} function options.\n */\n\n/**\n * @name getISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Get the ISO week-numbering year of the given date.\n *\n * @description\n * Get the ISO week-numbering year of the given date,\n * which always starts 3 days before the year's first Thursday.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * @param date - The given date\n *\n * @returns The ISO week-numbering year\n *\n * @example\n * // Which ISO-week numbering year is 2 January 2005?\n * const result = getISOWeekYear(new Date(2005, 0, 2))\n * //=> 2004\n */\nexport function getISOWeekYear(date, options) {\n const _date = toDate(date, options?.in);\n const year = _date.getFullYear();\n\n const fourthOfJanuaryOfNextYear = constructFrom(_date, 0);\n fourthOfJanuaryOfNextYear.setFullYear(year + 1, 0, 4);\n fourthOfJanuaryOfNextYear.setHours(0, 0, 0, 0);\n const startOfNextYear = startOfISOWeek(fourthOfJanuaryOfNextYear);\n\n const fourthOfJanuaryOfThisYear = constructFrom(_date, 0);\n fourthOfJanuaryOfThisYear.setFullYear(year, 0, 4);\n fourthOfJanuaryOfThisYear.setHours(0, 0, 0, 0);\n const startOfThisYear = startOfISOWeek(fourthOfJanuaryOfThisYear);\n\n if (_date.getTime() >= startOfNextYear.getTime()) {\n return year + 1;\n } else if (_date.getTime() >= startOfThisYear.getTime()) {\n return year;\n } else {\n return year - 1;\n }\n}\n\n// Fallback for modularized imports:\nexport default getISOWeekYear;\n","import { toDate } from \"../toDate.js\";\n\n/**\n * Google Chrome as of 67.0.3396.87 introduced timezones with offset that includes seconds.\n * They usually appear for dates that denote time before the timezones were introduced\n * (e.g. for 'Europe/Prague' timezone the offset is GMT+00:57:44 before 1 October 1891\n * and GMT+01:00:00 after that date)\n *\n * Date#getTimezoneOffset returns the offset in minutes and would return 57 for the example above,\n * which would lead to incorrect calculations.\n *\n * This function returns the timezone offset in milliseconds that takes seconds in account.\n */\nexport function getTimezoneOffsetInMilliseconds(date) {\n const _date = toDate(date);\n const utcDate = new Date(\n Date.UTC(\n _date.getFullYear(),\n _date.getMonth(),\n _date.getDate(),\n _date.getHours(),\n _date.getMinutes(),\n _date.getSeconds(),\n _date.getMilliseconds(),\n ),\n );\n utcDate.setUTCFullYear(_date.getFullYear());\n return +date - +utcDate;\n}\n","import { constructFrom } from \"../constructFrom.js\";\n\nexport function normalizeDates(context, ...dates) {\n const normalize = constructFrom.bind(\n null,\n context || dates.find((date) => typeof date === \"object\"),\n );\n return dates.map(normalize);\n}\n","import { toDate } from \"./toDate.js\";\n\n/**\n * The {@link startOfDay} function options.\n */\n\n/**\n * @name startOfDay\n * @category Day Helpers\n * @summary Return the start of a day for the given date.\n *\n * @description\n * Return the start of a day for the given date.\n * The result will be in the local timezone.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The original date\n * @param options - The options\n *\n * @returns The start of a day\n *\n * @example\n * // The start of a day for 2 September 2014 11:55:00:\n * const result = startOfDay(new Date(2014, 8, 2, 11, 55, 0))\n * //=> Tue Sep 02 2014 00:00:00\n */\nexport function startOfDay(date, options) {\n const _date = toDate(date, options?.in);\n _date.setHours(0, 0, 0, 0);\n return _date;\n}\n\n// Fallback for modularized imports:\nexport default startOfDay;\n","import { getTimezoneOffsetInMilliseconds } from \"./_lib/getTimezoneOffsetInMilliseconds.js\";\nimport { normalizeDates } from \"./_lib/normalizeDates.js\";\nimport { millisecondsInDay } from \"./constants.js\";\nimport { startOfDay } from \"./startOfDay.js\";\n\n/**\n * The {@link differenceInCalendarDays} function options.\n */\n\n/**\n * @name differenceInCalendarDays\n * @category Day Helpers\n * @summary Get the number of calendar days between the given dates.\n *\n * @description\n * Get the number of calendar days between the given dates. This means that the times are removed\n * from the dates and then the difference in days is calculated.\n *\n * @param laterDate - The later date\n * @param earlierDate - The earlier date\n * @param options - The options object\n *\n * @returns The number of calendar days\n *\n * @example\n * // How many calendar days are between\n * // 2 July 2011 23:00:00 and 2 July 2012 00:00:00?\n * const result = differenceInCalendarDays(\n * new Date(2012, 6, 2, 0, 0),\n * new Date(2011, 6, 2, 23, 0)\n * )\n * //=> 366\n * // How many calendar days are between\n * // 2 July 2011 23:59:00 and 3 July 2011 00:01:00?\n * const result = differenceInCalendarDays(\n * new Date(2011, 6, 3, 0, 1),\n * new Date(2011, 6, 2, 23, 59)\n * )\n * //=> 1\n */\nexport function differenceInCalendarDays(laterDate, earlierDate, options) {\n const [laterDate_, earlierDate_] = normalizeDates(\n options?.in,\n laterDate,\n earlierDate,\n );\n\n const laterStartOfDay = startOfDay(laterDate_);\n const earlierStartOfDay = startOfDay(earlierDate_);\n\n const laterTimestamp =\n +laterStartOfDay - getTimezoneOffsetInMilliseconds(laterStartOfDay);\n const earlierTimestamp =\n +earlierStartOfDay - getTimezoneOffsetInMilliseconds(earlierStartOfDay);\n\n // Round the number of days to the nearest integer because the number of\n // milliseconds in a day is not constant (e.g. it's different in the week of\n // the daylight saving time clock shift).\n return Math.round((laterTimestamp - earlierTimestamp) / millisecondsInDay);\n}\n\n// Fallback for modularized imports:\nexport default differenceInCalendarDays;\n","import { constructFrom } from \"./constructFrom.js\";\nimport { getISOWeekYear } from \"./getISOWeekYear.js\";\nimport { startOfISOWeek } from \"./startOfISOWeek.js\";\n\n/**\n * The {@link startOfISOWeekYear} function options.\n */\n\n/**\n * @name startOfISOWeekYear\n * @category ISO Week-Numbering Year Helpers\n * @summary Return the start of an ISO week-numbering year for the given date.\n *\n * @description\n * Return the start of an ISO week-numbering year,\n * which always starts 3 days before the year's first Thursday.\n * The result will be in the local timezone.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The original date\n * @param options - An object with options\n *\n * @returns The start of an ISO week-numbering year\n *\n * @example\n * // The start of an ISO week-numbering year for 2 July 2005:\n * const result = startOfISOWeekYear(new Date(2005, 6, 2))\n * //=> Mon Jan 03 2005 00:00:00\n */\nexport function startOfISOWeekYear(date, options) {\n const year = getISOWeekYear(date, options);\n const fourthOfJanuary = constructFrom(options?.in || date, 0);\n fourthOfJanuary.setFullYear(year, 0, 4);\n fourthOfJanuary.setHours(0, 0, 0, 0);\n return startOfISOWeek(fourthOfJanuary);\n}\n\n// Fallback for modularized imports:\nexport default startOfISOWeekYear;\n","/**\n * @name isDate\n * @category Common Helpers\n * @summary Is the given value a date?\n *\n * @description\n * Returns true if the given value is an instance of Date. The function works for dates transferred across iframes.\n *\n * @param value - The value to check\n *\n * @returns True if the given value is a date\n *\n * @example\n * // For a valid date:\n * const result = isDate(new Date())\n * //=> true\n *\n * @example\n * // For an invalid date:\n * const result = isDate(new Date(NaN))\n * //=> true\n *\n * @example\n * // For some value:\n * const result = isDate('2014-02-31')\n * //=> false\n *\n * @example\n * // For an object:\n * const result = isDate({})\n * //=> false\n */\nexport function isDate(value) {\n return (\n value instanceof Date ||\n (typeof value === \"object\" &&\n Object.prototype.toString.call(value) === \"[object Date]\")\n );\n}\n\n// Fallback for modularized imports:\nexport default isDate;\n","import { isDate } from \"./isDate.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * @name isValid\n * @category Common Helpers\n * @summary Is the given date valid?\n *\n * @description\n * Returns false if argument is Invalid Date and true otherwise.\n * Argument is converted to Date using `toDate`. See [toDate](https://date-fns.org/docs/toDate)\n * Invalid Date is a Date, whose time value is NaN.\n *\n * Time value of Date: http://es5.github.io/#x15.9.1.1\n *\n * @param date - The date to check\n *\n * @returns The date is valid\n *\n * @example\n * // For the valid date:\n * const result = isValid(new Date(2014, 1, 31))\n * //=> true\n *\n * @example\n * // For the value, convertible into a date:\n * const result = isValid(1393804800000)\n * //=> true\n *\n * @example\n * // For the invalid date:\n * const result = isValid(new Date(''))\n * //=> false\n */\nexport function isValid(date) {\n return !((!isDate(date) && typeof date !== \"number\") || isNaN(+toDate(date)));\n}\n\n// Fallback for modularized imports:\nexport default isValid;\n","import { toDate } from \"./toDate.js\";\n\n/**\n * The {@link startOfYear} function options.\n */\n\n/**\n * @name startOfYear\n * @category Year Helpers\n * @summary Return the start of a year for the given date.\n *\n * @description\n * Return the start of a year for the given date.\n * The result will be in the local timezone.\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type, it is the type returned from the context function if it is passed, or inferred from the arguments.\n *\n * @param date - The original date\n * @param options - The options\n *\n * @returns The start of a year\n *\n * @example\n * // The start of a year for 2 September 2014 11:55:00:\n * const result = startOfYear(new Date(2014, 8, 2, 11, 55, 00))\n * //=> Wed Jan 01 2014 00:00:00\n */\nexport function startOfYear(date, options) {\n const date_ = toDate(date, options?.in);\n date_.setFullYear(date_.getFullYear(), 0, 1);\n date_.setHours(0, 0, 0, 0);\n return date_;\n}\n\n// Fallback for modularized imports:\nexport default startOfYear;\n","const formatDistanceLocale = {\n lessThanXSeconds: {\n one: \"less than a second\",\n other: \"less than {{count}} seconds\",\n },\n\n xSeconds: {\n one: \"1 second\",\n other: \"{{count}} seconds\",\n },\n\n halfAMinute: \"half a minute\",\n\n lessThanXMinutes: {\n one: \"less than a minute\",\n other: \"less than {{count}} minutes\",\n },\n\n xMinutes: {\n one: \"1 minute\",\n other: \"{{count}} minutes\",\n },\n\n aboutXHours: {\n one: \"about 1 hour\",\n other: \"about {{count}} hours\",\n },\n\n xHours: {\n one: \"1 hour\",\n other: \"{{count}} hours\",\n },\n\n xDays: {\n one: \"1 day\",\n other: \"{{count}} days\",\n },\n\n aboutXWeeks: {\n one: \"about 1 week\",\n other: \"about {{count}} weeks\",\n },\n\n xWeeks: {\n one: \"1 week\",\n other: \"{{count}} weeks\",\n },\n\n aboutXMonths: {\n one: \"about 1 month\",\n other: \"about {{count}} months\",\n },\n\n xMonths: {\n one: \"1 month\",\n other: \"{{count}} months\",\n },\n\n aboutXYears: {\n one: \"about 1 year\",\n other: \"about {{count}} years\",\n },\n\n xYears: {\n one: \"1 year\",\n other: \"{{count}} years\",\n },\n\n overXYears: {\n one: \"over 1 year\",\n other: \"over {{count}} years\",\n },\n\n almostXYears: {\n one: \"almost 1 year\",\n other: \"almost {{count}} years\",\n },\n};\n\nexport const formatDistance = (token, count, options) => {\n let result;\n\n const tokenValue = formatDistanceLocale[token];\n if (typeof tokenValue === \"string\") {\n result = tokenValue;\n } else if (count === 1) {\n result = tokenValue.one;\n } else {\n result = tokenValue.other.replace(\"{{count}}\", count.toString());\n }\n\n if (options?.addSuffix) {\n if (options.comparison && options.comparison > 0) {\n return \"in \" + result;\n } else {\n return result + \" ago\";\n }\n }\n\n return result;\n};\n","export function buildFormatLongFn(args) {\n return (options = {}) => {\n // TODO: Remove String()\n const width = options.width ? String(options.width) : args.defaultWidth;\n const format = args.formats[width] || args.formats[args.defaultWidth];\n return format;\n };\n}\n","import { buildFormatLongFn } from \"../../_lib/buildFormatLongFn.js\";\n\nconst dateFormats = {\n full: \"EEEE, MMMM do, y\",\n long: \"MMMM do, y\",\n medium: \"MMM d, y\",\n short: \"MM/dd/yyyy\",\n};\n\nconst timeFormats = {\n full: \"h:mm:ss a zzzz\",\n long: \"h:mm:ss a z\",\n medium: \"h:mm:ss a\",\n short: \"h:mm a\",\n};\n\nconst dateTimeFormats = {\n full: \"{{date}} 'at' {{time}}\",\n long: \"{{date}} 'at' {{time}}\",\n medium: \"{{date}}, {{time}}\",\n short: \"{{date}}, {{time}}\",\n};\n\nexport const formatLong = {\n date: buildFormatLongFn({\n formats: dateFormats,\n defaultWidth: \"full\",\n }),\n\n time: buildFormatLongFn({\n formats: timeFormats,\n defaultWidth: \"full\",\n }),\n\n dateTime: buildFormatLongFn({\n formats: dateTimeFormats,\n defaultWidth: \"full\",\n }),\n};\n","const formatRelativeLocale = {\n lastWeek: \"'last' eeee 'at' p\",\n yesterday: \"'yesterday at' p\",\n today: \"'today at' p\",\n tomorrow: \"'tomorrow at' p\",\n nextWeek: \"eeee 'at' p\",\n other: \"P\",\n};\n\nexport const formatRelative = (token, _date, _baseDate, _options) =>\n formatRelativeLocale[token];\n","/**\n * The localize function argument callback which allows to convert raw value to\n * the actual type.\n *\n * @param value - The value to convert\n *\n * @returns The converted value\n */\n\n/**\n * The map of localized values for each width.\n */\n\n/**\n * The index type of the locale unit value. It types conversion of units of\n * values that don't start at 0 (i.e. quarters).\n */\n\n/**\n * Converts the unit value to the tuple of values.\n */\n\n/**\n * The tuple of localized era values. The first element represents BC,\n * the second element represents AD.\n */\n\n/**\n * The tuple of localized quarter values. The first element represents Q1.\n */\n\n/**\n * The tuple of localized day values. The first element represents Sunday.\n */\n\n/**\n * The tuple of localized month values. The first element represents January.\n */\n\nexport function buildLocalizeFn(args) {\n return (value, options) => {\n const context = options?.context ? String(options.context) : \"standalone\";\n\n let valuesArray;\n if (context === \"formatting\" && args.formattingValues) {\n const defaultWidth = args.defaultFormattingWidth || args.defaultWidth;\n const width = options?.width ? String(options.width) : defaultWidth;\n\n valuesArray =\n args.formattingValues[width] || args.formattingValues[defaultWidth];\n } else {\n const defaultWidth = args.defaultWidth;\n const width = options?.width ? String(options.width) : args.defaultWidth;\n\n valuesArray = args.values[width] || args.values[defaultWidth];\n }\n const index = args.argumentCallback ? args.argumentCallback(value) : value;\n\n // @ts-expect-error - For some reason TypeScript just don't want to match it, no matter how hard we try. I challenge you to try to remove it!\n return valuesArray[index];\n };\n}\n","import { buildLocalizeFn } from \"../../_lib/buildLocalizeFn.js\";\n\nconst eraValues = {\n narrow: [\"B\", \"A\"],\n abbreviated: [\"BC\", \"AD\"],\n wide: [\"Before Christ\", \"Anno Domini\"],\n};\n\nconst quarterValues = {\n narrow: [\"1\", \"2\", \"3\", \"4\"],\n abbreviated: [\"Q1\", \"Q2\", \"Q3\", \"Q4\"],\n wide: [\"1st quarter\", \"2nd quarter\", \"3rd quarter\", \"4th quarter\"],\n};\n\n// Note: in English, the names of days of the week and months are capitalized.\n// If you are making a new locale based on this one, check if the same is true for the language you're working on.\n// Generally, formatted dates should look like they are in the middle of a sentence,\n// e.g. in Spanish language the weekdays and months should be in the lowercase.\nconst monthValues = {\n narrow: [\"J\", \"F\", \"M\", \"A\", \"M\", \"J\", \"J\", \"A\", \"S\", \"O\", \"N\", \"D\"],\n abbreviated: [\n \"Jan\",\n \"Feb\",\n \"Mar\",\n \"Apr\",\n \"May\",\n \"Jun\",\n \"Jul\",\n \"Aug\",\n \"Sep\",\n \"Oct\",\n \"Nov\",\n \"Dec\",\n ],\n\n wide: [\n \"January\",\n \"February\",\n \"March\",\n \"April\",\n \"May\",\n \"June\",\n \"July\",\n \"August\",\n \"September\",\n \"October\",\n \"November\",\n \"December\",\n ],\n};\n\nconst dayValues = {\n narrow: [\"S\", \"M\", \"T\", \"W\", \"T\", \"F\", \"S\"],\n short: [\"Su\", \"Mo\", \"Tu\", \"We\", \"Th\", \"Fr\", \"Sa\"],\n abbreviated: [\"Sun\", \"Mon\", \"Tue\", \"Wed\", \"Thu\", \"Fri\", \"Sat\"],\n wide: [\n \"Sunday\",\n \"Monday\",\n \"Tuesday\",\n \"Wednesday\",\n \"Thursday\",\n \"Friday\",\n \"Saturday\",\n ],\n};\n\nconst dayPeriodValues = {\n narrow: {\n am: \"a\",\n pm: \"p\",\n midnight: \"mi\",\n noon: \"n\",\n morning: \"morning\",\n afternoon: \"afternoon\",\n evening: \"evening\",\n night: \"night\",\n },\n abbreviated: {\n am: \"AM\",\n pm: \"PM\",\n midnight: \"midnight\",\n noon: \"noon\",\n morning: \"morning\",\n afternoon: \"afternoon\",\n evening: \"evening\",\n night: \"night\",\n },\n wide: {\n am: \"a.m.\",\n pm: \"p.m.\",\n midnight: \"midnight\",\n noon: \"noon\",\n morning: \"morning\",\n afternoon: \"afternoon\",\n evening: \"evening\",\n night: \"night\",\n },\n};\n\nconst formattingDayPeriodValues = {\n narrow: {\n am: \"a\",\n pm: \"p\",\n midnight: \"mi\",\n noon: \"n\",\n morning: \"in the morning\",\n afternoon: \"in the afternoon\",\n evening: \"in the evening\",\n night: \"at night\",\n },\n abbreviated: {\n am: \"AM\",\n pm: \"PM\",\n midnight: \"midnight\",\n noon: \"noon\",\n morning: \"in the morning\",\n afternoon: \"in the afternoon\",\n evening: \"in the evening\",\n night: \"at night\",\n },\n wide: {\n am: \"a.m.\",\n pm: \"p.m.\",\n midnight: \"midnight\",\n noon: \"noon\",\n morning: \"in the morning\",\n afternoon: \"in the afternoon\",\n evening: \"in the evening\",\n night: \"at night\",\n },\n};\n\nconst ordinalNumber = (dirtyNumber, _options) => {\n const number = Number(dirtyNumber);\n\n // If ordinal numbers depend on context, for example,\n // if they are different for different grammatical genders,\n // use `options.unit`.\n //\n // `unit` can be 'year', 'quarter', 'month', 'week', 'date', 'dayOfYear',\n // 'day', 'hour', 'minute', 'second'.\n\n const rem100 = number % 100;\n if (rem100 > 20 || rem100 < 10) {\n switch (rem100 % 10) {\n case 1:\n return number + \"st\";\n case 2:\n return number + \"nd\";\n case 3:\n return number + \"rd\";\n }\n }\n return number + \"th\";\n};\n\nexport const localize = {\n ordinalNumber,\n\n era: buildLocalizeFn({\n values: eraValues,\n defaultWidth: \"wide\",\n }),\n\n quarter: buildLocalizeFn({\n values: quarterValues,\n defaultWidth: \"wide\",\n argumentCallback: (quarter) => quarter - 1,\n }),\n\n month: buildLocalizeFn({\n values: monthValues,\n defaultWidth: \"wide\",\n }),\n\n day: buildLocalizeFn({\n values: dayValues,\n defaultWidth: \"wide\",\n }),\n\n dayPeriod: buildLocalizeFn({\n values: dayPeriodValues,\n defaultWidth: \"wide\",\n formattingValues: formattingDayPeriodValues,\n defaultFormattingWidth: \"wide\",\n }),\n};\n","export function buildMatchFn(args) {\n return (string, options = {}) => {\n const width = options.width;\n\n const matchPattern =\n (width && args.matchPatterns[width]) ||\n args.matchPatterns[args.defaultMatchWidth];\n const matchResult = string.match(matchPattern);\n\n if (!matchResult) {\n return null;\n }\n const matchedString = matchResult[0];\n\n const parsePatterns =\n (width && args.parsePatterns[width]) ||\n args.parsePatterns[args.defaultParseWidth];\n\n const key = Array.isArray(parsePatterns)\n ? findIndex(parsePatterns, (pattern) => pattern.test(matchedString))\n : // [TODO] -- I challenge you to fix the type\n findKey(parsePatterns, (pattern) => pattern.test(matchedString));\n\n let value;\n\n value = args.valueCallback ? args.valueCallback(key) : key;\n value = options.valueCallback\n ? // [TODO] -- I challenge you to fix the type\n options.valueCallback(value)\n : value;\n\n const rest = string.slice(matchedString.length);\n\n return { value, rest };\n };\n}\n\nfunction findKey(object, predicate) {\n for (const key in object) {\n if (\n Object.prototype.hasOwnProperty.call(object, key) &&\n predicate(object[key])\n ) {\n return key;\n }\n }\n return undefined;\n}\n\nfunction findIndex(array, predicate) {\n for (let key = 0; key < array.length; key++) {\n if (predicate(array[key])) {\n return key;\n }\n }\n return undefined;\n}\n","export function buildMatchPatternFn(args) {\n return (string, options = {}) => {\n const matchResult = string.match(args.matchPattern);\n if (!matchResult) return null;\n const matchedString = matchResult[0];\n\n const parseResult = string.match(args.parsePattern);\n if (!parseResult) return null;\n let value = args.valueCallback\n ? args.valueCallback(parseResult[0])\n : parseResult[0];\n\n // [TODO] I challenge you to fix the type\n value = options.valueCallback ? options.valueCallback(value) : value;\n\n const rest = string.slice(matchedString.length);\n\n return { value, rest };\n };\n}\n","import { buildMatchFn } from \"../../_lib/buildMatchFn.js\";\nimport { buildMatchPatternFn } from \"../../_lib/buildMatchPatternFn.js\";\n\nconst matchOrdinalNumberPattern = /^(\\d+)(th|st|nd|rd)?/i;\nconst parseOrdinalNumberPattern = /\\d+/i;\n\nconst matchEraPatterns = {\n narrow: /^(b|a)/i,\n abbreviated: /^(b\\.?\\s?c\\.?|b\\.?\\s?c\\.?\\s?e\\.?|a\\.?\\s?d\\.?|c\\.?\\s?e\\.?)/i,\n wide: /^(before christ|before common era|anno domini|common era)/i,\n};\nconst parseEraPatterns = {\n any: [/^b/i, /^(a|c)/i],\n};\n\nconst matchQuarterPatterns = {\n narrow: /^[1234]/i,\n abbreviated: /^q[1234]/i,\n wide: /^[1234](th|st|nd|rd)? quarter/i,\n};\nconst parseQuarterPatterns = {\n any: [/1/i, /2/i, /3/i, /4/i],\n};\n\nconst matchMonthPatterns = {\n narrow: /^[jfmasond]/i,\n abbreviated: /^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,\n wide: /^(january|february|march|april|may|june|july|august|september|october|november|december)/i,\n};\nconst parseMonthPatterns = {\n narrow: [\n /^j/i,\n /^f/i,\n /^m/i,\n /^a/i,\n /^m/i,\n /^j/i,\n /^j/i,\n /^a/i,\n /^s/i,\n /^o/i,\n /^n/i,\n /^d/i,\n ],\n\n any: [\n /^ja/i,\n /^f/i,\n /^mar/i,\n /^ap/i,\n /^may/i,\n /^jun/i,\n /^jul/i,\n /^au/i,\n /^s/i,\n /^o/i,\n /^n/i,\n /^d/i,\n ],\n};\n\nconst matchDayPatterns = {\n narrow: /^[smtwf]/i,\n short: /^(su|mo|tu|we|th|fr|sa)/i,\n abbreviated: /^(sun|mon|tue|wed|thu|fri|sat)/i,\n wide: /^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i,\n};\nconst parseDayPatterns = {\n narrow: [/^s/i, /^m/i, /^t/i, /^w/i, /^t/i, /^f/i, /^s/i],\n any: [/^su/i, /^m/i, /^tu/i, /^w/i, /^th/i, /^f/i, /^sa/i],\n};\n\nconst matchDayPeriodPatterns = {\n narrow: /^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,\n any: /^([ap]\\.?\\s?m\\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i,\n};\nconst parseDayPeriodPatterns = {\n any: {\n am: /^a/i,\n pm: /^p/i,\n midnight: /^mi/i,\n noon: /^no/i,\n morning: /morning/i,\n afternoon: /afternoon/i,\n evening: /evening/i,\n night: /night/i,\n },\n};\n\nexport const match = {\n ordinalNumber: buildMatchPatternFn({\n matchPattern: matchOrdinalNumberPattern,\n parsePattern: parseOrdinalNumberPattern,\n valueCallback: (value) => parseInt(value, 10),\n }),\n\n era: buildMatchFn({\n matchPatterns: matchEraPatterns,\n defaultMatchWidth: \"wide\",\n parsePatterns: parseEraPatterns,\n defaultParseWidth: \"any\",\n }),\n\n quarter: buildMatchFn({\n matchPatterns: matchQuarterPatterns,\n defaultMatchWidth: \"wide\",\n parsePatterns: parseQuarterPatterns,\n defaultParseWidth: \"any\",\n valueCallback: (index) => index + 1,\n }),\n\n month: buildMatchFn({\n matchPatterns: matchMonthPatterns,\n defaultMatchWidth: \"wide\",\n parsePatterns: parseMonthPatterns,\n defaultParseWidth: \"any\",\n }),\n\n day: buildMatchFn({\n matchPatterns: matchDayPatterns,\n defaultMatchWidth: \"wide\",\n parsePatterns: parseDayPatterns,\n defaultParseWidth: \"any\",\n }),\n\n dayPeriod: buildMatchFn({\n matchPatterns: matchDayPeriodPatterns,\n defaultMatchWidth: \"any\",\n parsePatterns: parseDayPeriodPatterns,\n defaultParseWidth: \"any\",\n }),\n};\n","import { formatDistance } from \"./en-US/_lib/formatDistance.js\";\nimport { formatLong } from \"./en-US/_lib/formatLong.js\";\nimport { formatRelative } from \"./en-US/_lib/formatRelative.js\";\nimport { localize } from \"./en-US/_lib/localize.js\";\nimport { match } from \"./en-US/_lib/match.js\";\n\n/**\n * @category Locales\n * @summary English locale (United States).\n * @language English\n * @iso-639-2 eng\n * @author Sasha Koss [@kossnocorp](https://github.com/kossnocorp)\n * @author Lesha Koss [@leshakoss](https://github.com/leshakoss)\n */\nexport const enUS = {\n code: \"en-US\",\n formatDistance: formatDistance,\n formatLong: formatLong,\n formatRelative: formatRelative,\n localize: localize,\n match: match,\n options: {\n weekStartsOn: 0 /* Sunday */,\n firstWeekContainsDate: 1,\n },\n};\n\n// Fallback for modularized imports:\nexport default enUS;\n","import { differenceInCalendarDays } from \"./differenceInCalendarDays.js\";\nimport { startOfYear } from \"./startOfYear.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * The {@link getDayOfYear} function options.\n */\n\n/**\n * @name getDayOfYear\n * @category Day Helpers\n * @summary Get the day of the year of the given date.\n *\n * @description\n * Get the day of the year of the given date.\n *\n * @param date - The given date\n * @param options - The options\n *\n * @returns The day of year\n *\n * @example\n * // Which day of the year is 2 July 2014?\n * const result = getDayOfYear(new Date(2014, 6, 2))\n * //=> 183\n */\nexport function getDayOfYear(date, options) {\n const _date = toDate(date, options?.in);\n const diff = differenceInCalendarDays(_date, startOfYear(_date));\n const dayOfYear = diff + 1;\n return dayOfYear;\n}\n\n// Fallback for modularized imports:\nexport default getDayOfYear;\n","import { millisecondsInWeek } from \"./constants.js\";\nimport { startOfISOWeek } from \"./startOfISOWeek.js\";\nimport { startOfISOWeekYear } from \"./startOfISOWeekYear.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * The {@link getISOWeek} function options.\n */\n\n/**\n * @name getISOWeek\n * @category ISO Week Helpers\n * @summary Get the ISO week of the given date.\n *\n * @description\n * Get the ISO week of the given date.\n *\n * ISO week-numbering year: http://en.wikipedia.org/wiki/ISO_week_date\n *\n * @param date - The given date\n * @param options - The options\n *\n * @returns The ISO week\n *\n * @example\n * // Which week of the ISO-week numbering year is 2 January 2005?\n * const result = getISOWeek(new Date(2005, 0, 2))\n * //=> 53\n */\nexport function getISOWeek(date, options) {\n const _date = toDate(date, options?.in);\n const diff = +startOfISOWeek(_date) - +startOfISOWeekYear(_date);\n\n // Round the number of weeks to the nearest integer because the number of\n // milliseconds in a week is not constant (e.g. it's different in the week of\n // the daylight saving time clock shift).\n return Math.round(diff / millisecondsInWeek) + 1;\n}\n\n// Fallback for modularized imports:\nexport default getISOWeek;\n","import { getDefaultOptions } from \"./_lib/defaultOptions.js\";\nimport { constructFrom } from \"./constructFrom.js\";\nimport { startOfWeek } from \"./startOfWeek.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * The {@link getWeekYear} function options.\n */\n\n/**\n * @name getWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Get the local week-numbering year of the given date.\n *\n * @description\n * Get the local week-numbering year of the given date.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system\n *\n * @param date - The given date\n * @param options - An object with options.\n *\n * @returns The local week-numbering year\n *\n * @example\n * // Which week numbering year is 26 December 2004 with the default settings?\n * const result = getWeekYear(new Date(2004, 11, 26))\n * //=> 2005\n *\n * @example\n * // Which week numbering year is 26 December 2004 if week starts on Saturday?\n * const result = getWeekYear(new Date(2004, 11, 26), { weekStartsOn: 6 })\n * //=> 2004\n *\n * @example\n * // Which week numbering year is 26 December 2004 if the first week contains 4 January?\n * const result = getWeekYear(new Date(2004, 11, 26), { firstWeekContainsDate: 4 })\n * //=> 2004\n */\nexport function getWeekYear(date, options) {\n const _date = toDate(date, options?.in);\n const year = _date.getFullYear();\n\n const defaultOptions = getDefaultOptions();\n const firstWeekContainsDate =\n options?.firstWeekContainsDate ??\n options?.locale?.options?.firstWeekContainsDate ??\n defaultOptions.firstWeekContainsDate ??\n defaultOptions.locale?.options?.firstWeekContainsDate ??\n 1;\n\n const firstWeekOfNextYear = constructFrom(options?.in || date, 0);\n firstWeekOfNextYear.setFullYear(year + 1, 0, firstWeekContainsDate);\n firstWeekOfNextYear.setHours(0, 0, 0, 0);\n const startOfNextYear = startOfWeek(firstWeekOfNextYear, options);\n\n const firstWeekOfThisYear = constructFrom(options?.in || date, 0);\n firstWeekOfThisYear.setFullYear(year, 0, firstWeekContainsDate);\n firstWeekOfThisYear.setHours(0, 0, 0, 0);\n const startOfThisYear = startOfWeek(firstWeekOfThisYear, options);\n\n if (+_date >= +startOfNextYear) {\n return year + 1;\n } else if (+_date >= +startOfThisYear) {\n return year;\n } else {\n return year - 1;\n }\n}\n\n// Fallback for modularized imports:\nexport default getWeekYear;\n","import { getDefaultOptions } from \"./_lib/defaultOptions.js\";\nimport { constructFrom } from \"./constructFrom.js\";\nimport { getWeekYear } from \"./getWeekYear.js\";\nimport { startOfWeek } from \"./startOfWeek.js\";\n\n/**\n * The {@link startOfWeekYear} function options.\n */\n\n/**\n * @name startOfWeekYear\n * @category Week-Numbering Year Helpers\n * @summary Return the start of a local week-numbering year for the given date.\n *\n * @description\n * Return the start of a local week-numbering year.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system\n *\n * @typeParam DateType - The `Date` type, the function operates on. Gets inferred from passed arguments. Allows to use extensions like [`UTCDate`](https://github.com/date-fns/utc).\n * @typeParam ResultDate - The result `Date` type.\n *\n * @param date - The original date\n * @param options - An object with options\n *\n * @returns The start of a week-numbering year\n *\n * @example\n * // The start of an a week-numbering year for 2 July 2005 with default settings:\n * const result = startOfWeekYear(new Date(2005, 6, 2))\n * //=> Sun Dec 26 2004 00:00:00\n *\n * @example\n * // The start of a week-numbering year for 2 July 2005\n * // if Monday is the first day of week\n * // and 4 January is always in the first week of the year:\n * const result = startOfWeekYear(new Date(2005, 6, 2), {\n * weekStartsOn: 1,\n * firstWeekContainsDate: 4\n * })\n * //=> Mon Jan 03 2005 00:00:00\n */\nexport function startOfWeekYear(date, options) {\n const defaultOptions = getDefaultOptions();\n const firstWeekContainsDate =\n options?.firstWeekContainsDate ??\n options?.locale?.options?.firstWeekContainsDate ??\n defaultOptions.firstWeekContainsDate ??\n defaultOptions.locale?.options?.firstWeekContainsDate ??\n 1;\n\n const year = getWeekYear(date, options);\n const firstWeek = constructFrom(options?.in || date, 0);\n firstWeek.setFullYear(year, 0, firstWeekContainsDate);\n firstWeek.setHours(0, 0, 0, 0);\n const _date = startOfWeek(firstWeek, options);\n return _date;\n}\n\n// Fallback for modularized imports:\nexport default startOfWeekYear;\n","import { millisecondsInWeek } from \"./constants.js\";\nimport { startOfWeek } from \"./startOfWeek.js\";\nimport { startOfWeekYear } from \"./startOfWeekYear.js\";\nimport { toDate } from \"./toDate.js\";\n\n/**\n * The {@link getWeek} function options.\n */\n\n/**\n * @name getWeek\n * @category Week Helpers\n * @summary Get the local week index of the given date.\n *\n * @description\n * Get the local week index of the given date.\n * The exact calculation depends on the values of\n * `options.weekStartsOn` (which is the index of the first day of the week)\n * and `options.firstWeekContainsDate` (which is the day of January, which is always in\n * the first week of the week-numbering year)\n *\n * Week numbering: https://en.wikipedia.org/wiki/Week#The_ISO_week_date_system\n *\n * @param date - The given date\n * @param options - An object with options\n *\n * @returns The week\n *\n * @example\n * // Which week of the local week numbering year is 2 January 2005 with default options?\n * const result = getWeek(new Date(2005, 0, 2))\n * //=> 2\n *\n * @example\n * // Which week of the local week numbering year is 2 January 2005,\n * // if Monday is the first day of the week,\n * // and the first week of the year always contains 4 January?\n * const result = getWeek(new Date(2005, 0, 2), {\n * weekStartsOn: 1,\n * firstWeekContainsDate: 4\n * })\n * //=> 53\n */\nexport function getWeek(date, options) {\n const _date = toDate(date, options?.in);\n const diff = +startOfWeek(_date, options) - +startOfWeekYear(_date, options);\n\n // Round the number of weeks to the nearest integer because the number of\n // milliseconds in a week is not constant (e.g. it's different in the week of\n // the daylight saving time clock shift).\n return Math.round(diff / millisecondsInWeek) + 1;\n}\n\n// Fallback for modularized imports:\nexport default getWeek;\n","export function addLeadingZeros(number, targetLength) {\n const sign = number < 0 ? \"-\" : \"\";\n const output = Math.abs(number).toString().padStart(targetLength, \"0\");\n return sign + output;\n}\n","import { addLeadingZeros } from \"../addLeadingZeros.js\";\n\n/*\n * | | Unit | | Unit |\n * |-----|--------------------------------|-----|--------------------------------|\n * | a | AM, PM | A* | |\n * | d | Day of month | D | |\n * | h | Hour [1-12] | H | Hour [0-23] |\n * | m | Minute | M | Month |\n * | s | Second | S | Fraction of second |\n * | y | Year (abs) | Y | |\n *\n * Letters marked by * are not implemented but reserved by Unicode standard.\n */\n\nexport const lightFormatters = {\n // Year\n y(date, token) {\n // From http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_tokens\n // | Year | y | yy | yyy | yyyy | yyyyy |\n // |----------|-------|----|-------|-------|-------|\n // | AD 1 | 1 | 01 | 001 | 0001 | 00001 |\n // | AD 12 | 12 | 12 | 012 | 0012 | 00012 |\n // | AD 123 | 123 | 23 | 123 | 0123 | 00123 |\n // | AD 1234 | 1234 | 34 | 1234 | 1234 | 01234 |\n // | AD 12345 | 12345 | 45 | 12345 | 12345 | 12345 |\n\n const signedYear = date.getFullYear();\n // Returns 1 for 1 BC (which is year 0 in JavaScript)\n const year = signedYear > 0 ? signedYear : 1 - signedYear;\n return addLeadingZeros(token === \"yy\" ? year % 100 : year, token.length);\n },\n\n // Month\n M(date, token) {\n const month = date.getMonth();\n return token === \"M\" ? String(month + 1) : addLeadingZeros(month + 1, 2);\n },\n\n // Day of the month\n d(date, token) {\n return addLeadingZeros(date.getDate(), token.length);\n },\n\n // AM or PM\n a(date, token) {\n const dayPeriodEnumValue = date.getHours() / 12 >= 1 ? \"pm\" : \"am\";\n\n switch (token) {\n case \"a\":\n case \"aa\":\n return dayPeriodEnumValue.toUpperCase();\n case \"aaa\":\n return dayPeriodEnumValue;\n case \"aaaaa\":\n return dayPeriodEnumValue[0];\n case \"aaaa\":\n default:\n return dayPeriodEnumValue === \"am\" ? \"a.m.\" : \"p.m.\";\n }\n },\n\n // Hour [1-12]\n h(date, token) {\n return addLeadingZeros(date.getHours() % 12 || 12, token.length);\n },\n\n // Hour [0-23]\n H(date, token) {\n return addLeadingZeros(date.getHours(), token.length);\n },\n\n // Minute\n m(date, token) {\n return addLeadingZeros(date.getMinutes(), token.length);\n },\n\n // Second\n s(date, token) {\n return addLeadingZeros(date.getSeconds(), token.length);\n },\n\n // Fraction of second\n S(date, token) {\n const numberOfDigits = token.length;\n const milliseconds = date.getMilliseconds();\n const fractionalSeconds = Math.trunc(\n milliseconds * Math.pow(10, numberOfDigits - 3),\n );\n return addLeadingZeros(fractionalSeconds, token.length);\n },\n};\n","import { getDayOfYear } from \"../../getDayOfYear.js\";\nimport { getISOWeek } from \"../../getISOWeek.js\";\nimport { getISOWeekYear } from \"../../getISOWeekYear.js\";\nimport { getWeek } from \"../../getWeek.js\";\nimport { getWeekYear } from \"../../getWeekYear.js\";\n\nimport { addLeadingZeros } from \"../addLeadingZeros.js\";\nimport { lightFormatters } from \"./lightFormatters.js\";\n\nconst dayPeriodEnum = {\n am: \"am\",\n pm: \"pm\",\n midnight: \"midnight\",\n noon: \"noon\",\n morning: \"morning\",\n afternoon: \"afternoon\",\n evening: \"evening\",\n night: \"night\",\n};\n\n/*\n * | | Unit | | Unit |\n * |-----|--------------------------------|-----|--------------------------------|\n * | a | AM, PM | A* | Milliseconds in day |\n * | b | AM, PM, noon, midnight | B | Flexible day period |\n * | c | Stand-alone local day of week | C* | Localized hour w/ day period |\n * | d | Day of month | D | Day of year |\n * | e | Local day of week | E | Day of week |\n * | f | | F* | Day of week in month |\n * | g* | Modified Julian day | G | Era |\n * | h | Hour [1-12] | H | Hour [0-23] |\n * | i! | ISO day of week | I! | ISO week of year |\n * | j* | Localized hour w/ day period | J* | Localized hour w/o day period |\n * | k | Hour [1-24] | K | Hour [0-11] |\n * | l* | (deprecated) | L | Stand-alone month |\n * | m | Minute | M | Month |\n * | n | | N | |\n * | o! | Ordinal number modifier | O | Timezone (GMT) |\n * | p! | Long localized time | P! | Long localized date |\n * | q | Stand-alone quarter | Q | Quarter |\n * | r* | Related Gregorian year | R! | ISO week-numbering year |\n * | s | Second | S | Fraction of second |\n * | t! | Seconds timestamp | T! | Milliseconds timestamp |\n * | u | Extended year | U* | Cyclic year |\n * | v* | Timezone (generic non-locat.) | V* | Timezone (location) |\n * | w | Local week of year | W* | Week of month |\n * | x | Timezone (ISO-8601 w/o Z) | X | Timezone (ISO-8601) |\n * | y | Year (abs) | Y | Local week-numbering year |\n * | z | Timezone (specific non-locat.) | Z* | Timezone (aliases) |\n *\n * Letters marked by * are not implemented but reserved by Unicode standard.\n *\n * Letters marked by ! are non-standard, but implemented by date-fns:\n * - `o` modifies the previous token to turn it into an ordinal (see `format` docs)\n * - `i` is ISO day of week. For `i` and `ii` is returns numeric ISO week days,\n * i.e. 7 for Sunday, 1 for Monday, etc.\n * - `I` is ISO week of year, as opposed to `w` which is local week of year.\n * - `R` is ISO week-numbering year, as opposed to `Y` which is local week-numbering year.\n * `R` is supposed to be used in conjunction with `I` and `i`\n * for universal ISO week-numbering date, whereas\n * `Y` is supposed to be used in conjunction with `w` and `e`\n * for week-numbering date specific to the locale.\n * - `P` is long localized date format\n * - `p` is long localized time format\n */\n\nexport const formatters = {\n // Era\n G: function (date, token, localize) {\n const era = date.getFullYear() > 0 ? 1 : 0;\n switch (token) {\n // AD, BC\n case \"G\":\n case \"GG\":\n case \"GGG\":\n return localize.era(era, { width: \"abbreviated\" });\n // A, B\n case \"GGGGG\":\n return localize.era(era, { width: \"narrow\" });\n // Anno Domini, Before Christ\n case \"GGGG\":\n default:\n return localize.era(era, { width: \"wide\" });\n }\n },\n\n // Year\n y: function (date, token, localize) {\n // Ordinal number\n if (token === \"yo\") {\n const signedYear = date.getFullYear();\n // Returns 1 for 1 BC (which is year 0 in JavaScript)\n const year = signedYear > 0 ? signedYear : 1 - signedYear;\n return localize.ordinalNumber(year, { unit: \"year\" });\n }\n\n return lightFormatters.y(date, token);\n },\n\n // Local week-numbering year\n Y: function (date, token, localize, options) {\n const signedWeekYear = getWeekYear(date, options);\n // Returns 1 for 1 BC (which is year 0 in JavaScript)\n const weekYear = signedWeekYear > 0 ? signedWeekYear : 1 - signedWeekYear;\n\n // Two digit year\n if (token === \"YY\") {\n const twoDigitYear = weekYear % 100;\n return addLeadingZeros(twoDigitYear, 2);\n }\n\n // Ordinal number\n if (token === \"Yo\") {\n return localize.ordinalNumber(weekYear, { unit: \"year\" });\n }\n\n // Padding\n return addLeadingZeros(weekYear, token.length);\n },\n\n // ISO week-numbering year\n R: function (date, token) {\n const isoWeekYear = getISOWeekYear(date);\n\n // Padding\n return addLeadingZeros(isoWeekYear, token.length);\n },\n\n // Extended year. This is a single number designating the year of this calendar system.\n // The main difference between `y` and `u` localizers are B.C. years:\n // | Year | `y` | `u` |\n // |------|-----|-----|\n // | AC 1 | 1 | 1 |\n // | BC 1 | 1 | 0 |\n // | BC 2 | 2 | -1 |\n // Also `yy` always returns the last two digits of a year,\n // while `uu` pads single digit years to 2 characters and returns other years unchanged.\n u: function (date, token) {\n const year = date.getFullYear();\n return addLeadingZeros(year, token.length);\n },\n\n // Quarter\n Q: function (date, token, localize) {\n const quarter = Math.ceil((date.getMonth() + 1) / 3);\n switch (token) {\n // 1, 2, 3, 4\n case \"Q\":\n return String(quarter);\n // 01, 02, 03, 04\n case \"QQ\":\n return addLeadingZeros(quarter, 2);\n // 1st, 2nd, 3rd, 4th\n case \"Qo\":\n return localize.ordinalNumber(quarter, { unit: \"quarter\" });\n // Q1, Q2, Q3, Q4\n case \"QQQ\":\n return localize.quarter(quarter, {\n width: \"abbreviated\",\n context: \"formatting\",\n });\n // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n case \"QQQQQ\":\n return localize.quarter(quarter, {\n width: \"narrow\",\n context: \"formatting\",\n });\n // 1st quarter, 2nd quarter, ...\n case \"QQQQ\":\n default:\n return localize.quarter(quarter, {\n width: \"wide\",\n context: \"formatting\",\n });\n }\n },\n\n // Stand-alone quarter\n q: function (date, token, localize) {\n const quarter = Math.ceil((date.getMonth() + 1) / 3);\n switch (token) {\n // 1, 2, 3, 4\n case \"q\":\n return String(quarter);\n // 01, 02, 03, 04\n case \"qq\":\n return addLeadingZeros(quarter, 2);\n // 1st, 2nd, 3rd, 4th\n case \"qo\":\n return localize.ordinalNumber(quarter, { unit: \"quarter\" });\n // Q1, Q2, Q3, Q4\n case \"qqq\":\n return localize.quarter(quarter, {\n width: \"abbreviated\",\n context: \"standalone\",\n });\n // 1, 2, 3, 4 (narrow quarter; could be not numerical)\n case \"qqqqq\":\n return localize.quarter(quarter, {\n width: \"narrow\",\n context: \"standalone\",\n });\n // 1st quarter, 2nd quarter, ...\n case \"qqqq\":\n default:\n return localize.quarter(quarter, {\n width: \"wide\",\n context: \"standalone\",\n });\n }\n },\n\n // Month\n M: function (date, token, localize) {\n const month = date.getMonth();\n switch (token) {\n case \"M\":\n case \"MM\":\n return lightFormatters.M(date, token);\n // 1st, 2nd, ..., 12th\n case \"Mo\":\n return localize.ordinalNumber(month + 1, { unit: \"month\" });\n // Jan, Feb, ..., Dec\n case \"MMM\":\n return localize.month(month, {\n width: \"abbreviated\",\n context: \"formatting\",\n });\n // J, F, ..., D\n case \"MMMMM\":\n return localize.month(month, {\n width: \"narrow\",\n context: \"formatting\",\n });\n // January, February, ..., December\n case \"MMMM\":\n default:\n return localize.month(month, { width: \"wide\", context: \"formatting\" });\n }\n },\n\n // Stand-alone month\n L: function (date, token, localize) {\n const month = date.getMonth();\n switch (token) {\n // 1, 2, ..., 12\n case \"L\":\n return String(month + 1);\n // 01, 02, ..., 12\n case \"LL\":\n return addLeadingZeros(month + 1, 2);\n // 1st, 2nd, ..., 12th\n case \"Lo\":\n return localize.ordinalNumber(month + 1, { unit: \"month\" });\n // Jan, Feb, ..., Dec\n case \"LLL\":\n return localize.month(month, {\n width: \"abbreviated\",\n context: \"standalone\",\n });\n // J, F, ..., D\n case \"LLLLL\":\n return localize.month(month, {\n width: \"narrow\",\n context: \"standalone\",\n });\n // January, February, ..., December\n case \"LLLL\":\n default:\n return localize.month(month, { width: \"wide\", context: \"standalone\" });\n }\n },\n\n // Local week of year\n w: function (date, token, localize, options) {\n const week = getWeek(date, options);\n\n if (token === \"wo\") {\n return localize.ordinalNumber(week, { unit: \"week\" });\n }\n\n return addLeadingZeros(week, token.length);\n },\n\n // ISO week of year\n I: function (date, token, localize) {\n const isoWeek = getISOWeek(date);\n\n if (token === \"Io\") {\n return localize.ordinalNumber(isoWeek, { unit: \"week\" });\n }\n\n return addLeadingZeros(isoWeek, token.length);\n },\n\n // Day of the month\n d: function (date, token, localize) {\n if (token === \"do\") {\n return localize.ordinalNumber(date.getDate(), { unit: \"date\" });\n }\n\n return lightFormatters.d(date, token);\n },\n\n // Day of year\n D: function (date, token, localize) {\n const dayOfYear = getDayOfYear(date);\n\n if (token === \"Do\") {\n return localize.ordinalNumber(dayOfYear, { unit: \"dayOfYear\" });\n }\n\n return addLeadingZeros(dayOfYear, token.length);\n },\n\n // Day of week\n E: function (date, token, localize) {\n const dayOfWeek = date.getDay();\n switch (token) {\n // Tue\n case \"E\":\n case \"EE\":\n case \"EEE\":\n return localize.day(dayOfWeek, {\n width: \"abbreviated\",\n context: \"formatting\",\n });\n // T\n case \"EEEEE\":\n return localize.day(dayOfWeek, {\n width: \"narrow\",\n context: \"formatting\",\n });\n // Tu\n case \"EEEEEE\":\n return localize.day(dayOfWeek, {\n width: \"short\",\n context: \"formatting\",\n });\n // Tuesday\n case \"EEEE\":\n default:\n return localize.day(dayOfWeek, {\n width: \"wide\",\n context: \"formatting\",\n });\n }\n },\n\n // Local day of week\n e: function (date, token, localize, options) {\n const dayOfWeek = date.getDay();\n const localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;\n switch (token) {\n // Numerical value (Nth day of week with current locale or weekStartsOn)\n case \"e\":\n return String(localDayOfWeek);\n // Padded numerical value\n case \"ee\":\n return addLeadingZeros(localDayOfWeek, 2);\n // 1st, 2nd, ..., 7th\n case \"eo\":\n return localize.ordinalNumber(localDayOfWeek, { unit: \"day\" });\n case \"eee\":\n return localize.day(dayOfWeek, {\n width: \"abbreviated\",\n context: \"formatting\",\n });\n // T\n case \"eeeee\":\n return localize.day(dayOfWeek, {\n width: \"narrow\",\n context: \"formatting\",\n });\n // Tu\n case \"eeeeee\":\n return localize.day(dayOfWeek, {\n width: \"short\",\n context: \"formatting\",\n });\n // Tuesday\n case \"eeee\":\n default:\n return localize.day(dayOfWeek, {\n width: \"wide\",\n context: \"formatting\",\n });\n }\n },\n\n // Stand-alone local day of week\n c: function (date, token, localize, options) {\n const dayOfWeek = date.getDay();\n const localDayOfWeek = (dayOfWeek - options.weekStartsOn + 8) % 7 || 7;\n switch (token) {\n // Numerical value (same as in `e`)\n case \"c\":\n return String(localDayOfWeek);\n // Padded numerical value\n case \"cc\":\n return addLeadingZeros(localDayOfWeek, token.length);\n // 1st, 2nd, ..., 7th\n case \"co\":\n return localize.ordinalNumber(localDayOfWeek, { unit: \"day\" });\n case \"ccc\":\n return localize.day(dayOfWeek, {\n width: \"abbreviated\",\n context: \"standalone\",\n });\n // T\n case \"ccccc\":\n return localize.day(dayOfWeek, {\n width: \"narrow\",\n context: \"standalone\",\n });\n // Tu\n case \"cccccc\":\n return localize.day(dayOfWeek, {\n width: \"short\",\n context: \"standalone\",\n });\n // Tuesday\n case \"cccc\":\n default:\n return localize.day(dayOfWeek, {\n width: \"wide\",\n context: \"standalone\",\n });\n }\n },\n\n // ISO day of week\n i: function (date, token, localize) {\n const dayOfWeek = date.getDay();\n const isoDayOfWeek = dayOfWeek === 0 ? 7 : dayOfWeek;\n switch (token) {\n // 2\n case \"i\":\n return String(isoDayOfWeek);\n // 02\n case \"ii\":\n return addLeadingZeros(isoDayOfWeek, token.length);\n // 2nd\n case \"io\":\n return localize.ordinalNumber(isoDayOfWeek, { unit: \"day\" });\n // Tue\n case \"iii\":\n return localize.day(dayOfWeek, {\n width: \"abbreviated\",\n context: \"formatting\",\n });\n // T\n case \"iiiii\":\n return localize.day(dayOfWeek, {\n width: \"narrow\",\n context: \"formatting\",\n });\n // Tu\n case \"iiiiii\":\n return localize.day(dayOfWeek, {\n width: \"short\",\n context: \"formatting\",\n });\n // Tuesday\n case \"iiii\":\n default:\n return localize.day(dayOfWeek, {\n width: \"wide\",\n context: \"formatting\",\n });\n }\n },\n\n // AM or PM\n a: function (date, token, localize) {\n const hours = date.getHours();\n const dayPeriodEnumValue = hours / 12 >= 1 ? \"pm\" : \"am\";\n\n switch (token) {\n case \"a\":\n case \"aa\":\n return localize.dayPeriod(dayPeriodEnumValue, {\n width: \"abbreviated\",\n context: \"formatting\",\n });\n case \"aaa\":\n return localize\n .dayPeriod(dayPeriodEnumValue, {\n width: \"abbreviated\",\n context: \"formatting\",\n })\n .toLowerCase();\n case \"aaaaa\":\n return localize.dayPeriod(dayPeriodEnumValue, {\n width: \"narrow\",\n context: \"formatting\",\n });\n case \"aaaa\":\n default:\n return localize.dayPeriod(dayPeriodEnumValue, {\n width: \"wide\",\n context: \"formatting\",\n });\n }\n },\n\n // AM, PM, midnight, noon\n b: function (date, token, localize) {\n const hours = date.getHours();\n let dayPeriodEnumValue;\n if (hours === 12) {\n dayPeriodEnumValue = dayPeriodEnum.noon;\n } else if (hours === 0) {\n dayPeriodEnumValue = dayPeriodEnum.midnight;\n } else {\n dayPeriodEnumValue = hours / 12 >= 1 ? \"pm\" : \"am\";\n }\n\n switch (token) {\n case \"b\":\n case \"bb\":\n return localize.dayPeriod(dayPeriodEnumValue, {\n width: \"abbreviated\",\n context: \"formatting\",\n });\n case \"bbb\":\n return localize\n .dayPeriod(dayPeriodEnumValue, {\n width: \"abbreviated\",\n context: \"formatting\",\n })\n .toLowerCase();\n case \"bbbbb\":\n return localize.dayPeriod(dayPeriodEnumValue, {\n width: \"narrow\",\n context: \"formatting\",\n });\n case \"bbbb\":\n default:\n return localize.dayPeriod(dayPeriodEnumValue, {\n width: \"wide\",\n context: \"formatting\",\n });\n }\n },\n\n // in the morning, in the afternoon, in the evening, at night\n B: function (date, token, localize) {\n const hours = date.getHours();\n let dayPeriodEnumValue;\n if (hours >= 17) {\n dayPeriodEnumValue = dayPeriodEnum.evening;\n } else if (hours >= 12) {\n dayPeriodEnumValue = dayPeriodEnum.afternoon;\n } else if (hours >= 4) {\n dayPeriodEnumValue = dayPeriodEnum.morning;\n } else {\n dayPeriodEnumValue = dayPeriodEnum.night;\n }\n\n switch (token) {\n case \"B\":\n case \"BB\":\n case \"BBB\":\n return localize.dayPeriod(dayPeriodEnumValue, {\n width: \"abbreviated\",\n context: \"formatting\",\n });\n case \"BBBBB\":\n return localize.dayPeriod(dayPeriodEnumValue, {\n width: \"narrow\",\n context: \"formatting\",\n });\n case \"BBBB\":\n default:\n return localize.dayPeriod(dayPeriodEnumValue, {\n width: \"wide\",\n context: \"formatting\",\n });\n }\n },\n\n // Hour [1-12]\n h: function (date, token, localize) {\n if (token === \"ho\") {\n let hours = date.getHours() % 12;\n if (hours === 0) hours = 12;\n return localize.ordinalNumber(hours, { unit: \"hour\" });\n }\n\n return lightFormatters.h(date, token);\n },\n\n // Hour [0-23]\n H: function (date, token, localize) {\n if (token === \"Ho\") {\n return localize.ordinalNumber(date.getHours(), { unit: \"hour\" });\n }\n\n return lightFormatters.H(date, token);\n },\n\n // Hour [0-11]\n K: function (date, token, localize) {\n const hours = date.getHours() % 12;\n\n if (token === \"Ko\") {\n return localize.ordinalNumber(hours, { unit: \"hour\" });\n }\n\n return addLeadingZeros(hours, token.length);\n },\n\n // Hour [1-24]\n k: function (date, token, localize) {\n let hours = date.getHours();\n if (hours === 0) hours = 24;\n\n if (token === \"ko\") {\n return localize.ordinalNumber(hours, { unit: \"hour\" });\n }\n\n return addLeadingZeros(hours, token.length);\n },\n\n // Minute\n m: function (date, token, localize) {\n if (token === \"mo\") {\n return localize.ordinalNumber(date.getMinutes(), { unit: \"minute\" });\n }\n\n return lightFormatters.m(date, token);\n },\n\n // Second\n s: function (date, token, localize) {\n if (token === \"so\") {\n return localize.ordinalNumber(date.getSeconds(), { unit: \"second\" });\n }\n\n return lightFormatters.s(date, token);\n },\n\n // Fraction of second\n S: function (date, token) {\n return lightFormatters.S(date, token);\n },\n\n // Timezone (ISO-8601. If offset is 0, output is always `'Z'`)\n X: function (date, token, _localize) {\n const timezoneOffset = date.getTimezoneOffset();\n\n if (timezoneOffset === 0) {\n return \"Z\";\n }\n\n switch (token) {\n // Hours and optional minutes\n case \"X\":\n return formatTimezoneWithOptionalMinutes(timezoneOffset);\n\n // Hours, minutes and optional seconds without `:` delimiter\n // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n // so this token always has the same output as `XX`\n case \"XXXX\":\n case \"XX\": // Hours and minutes without `:` delimiter\n return formatTimezone(timezoneOffset);\n\n // Hours, minutes and optional seconds with `:` delimiter\n // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n // so this token always has the same output as `XXX`\n case \"XXXXX\":\n case \"XXX\": // Hours and minutes with `:` delimiter\n default:\n return formatTimezone(timezoneOffset, \":\");\n }\n },\n\n // Timezone (ISO-8601. If offset is 0, output is `'+00:00'` or equivalent)\n x: function (date, token, _localize) {\n const timezoneOffset = date.getTimezoneOffset();\n\n switch (token) {\n // Hours and optional minutes\n case \"x\":\n return formatTimezoneWithOptionalMinutes(timezoneOffset);\n\n // Hours, minutes and optional seconds without `:` delimiter\n // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n // so this token always has the same output as `xx`\n case \"xxxx\":\n case \"xx\": // Hours and minutes without `:` delimiter\n return formatTimezone(timezoneOffset);\n\n // Hours, minutes and optional seconds with `:` delimiter\n // Note: neither ISO-8601 nor JavaScript supports seconds in timezone offsets\n // so this token always has the same output as `xxx`\n case \"xxxxx\":\n case \"xxx\": // Hours and minutes with `:` delimiter\n default:\n return formatTimezone(timezoneOffset, \":\");\n }\n },\n\n // Timezone (GMT)\n O: function (date, token, _localize) {\n const timezoneOffset = date.getTimezoneOffset();\n\n switch (token) {\n // Short\n case \"O\":\n case \"OO\":\n case \"OOO\":\n return \"GMT\" + formatTimezoneShort(timezoneOffset, \":\");\n // Long\n case \"OOOO\":\n default:\n return \"GMT\" + formatTimezone(timezoneOffset, \":\");\n }\n },\n\n // Timezone (specific non-location)\n z: function (date, token, _localize) {\n const timezoneOffset = date.getTimezoneOffset();\n\n switch (token) {\n // Short\n case \"z\":\n case \"zz\":\n case \"zzz\":\n return \"GMT\" + formatTimezoneShort(timezoneOffset, \":\");\n // Long\n case \"zzzz\":\n default:\n return \"GMT\" + formatTimezone(timezoneOffset, \":\");\n }\n },\n\n // Seconds timestamp\n t: function (date, token, _localize) {\n const timestamp = Math.trunc(+date / 1000);\n return addLeadingZeros(timestamp, token.length);\n },\n\n // Milliseconds timestamp\n T: function (date, token, _localize) {\n return addLeadingZeros(+date, token.length);\n },\n};\n\nfunction formatTimezoneShort(offset, delimiter = \"\") {\n const sign = offset > 0 ? \"-\" : \"+\";\n const absOffset = Math.abs(offset);\n const hours = Math.trunc(absOffset / 60);\n const minutes = absOffset % 60;\n if (minutes === 0) {\n return sign + String(hours);\n }\n return sign + String(hours) + delimiter + addLeadingZeros(minutes, 2);\n}\n\nfunction formatTimezoneWithOptionalMinutes(offset, delimiter) {\n if (offset % 60 === 0) {\n const sign = offset > 0 ? \"-\" : \"+\";\n return sign + addLeadingZeros(Math.abs(offset) / 60, 2);\n }\n return formatTimezone(offset, delimiter);\n}\n\nfunction formatTimezone(offset, delimiter = \"\") {\n const sign = offset > 0 ? \"-\" : \"+\";\n const absOffset = Math.abs(offset);\n const hours = addLeadingZeros(Math.trunc(absOffset / 60), 2);\n const minutes = addLeadingZeros(absOffset % 60, 2);\n return sign + hours + delimiter + minutes;\n}\n","const dateLongFormatter = (pattern, formatLong) => {\n switch (pattern) {\n case \"P\":\n return formatLong.date({ width: \"short\" });\n case \"PP\":\n return formatLong.date({ width: \"medium\" });\n case \"PPP\":\n return formatLong.date({ width: \"long\" });\n case \"PPPP\":\n default:\n return formatLong.date({ width: \"full\" });\n }\n};\n\nconst timeLongFormatter = (pattern, formatLong) => {\n switch (pattern) {\n case \"p\":\n return formatLong.time({ width: \"short\" });\n case \"pp\":\n return formatLong.time({ width: \"medium\" });\n case \"ppp\":\n return formatLong.time({ width: \"long\" });\n case \"pppp\":\n default:\n return formatLong.time({ width: \"full\" });\n }\n};\n\nconst dateTimeLongFormatter = (pattern, formatLong) => {\n const matchResult = pattern.match(/(P+)(p+)?/) || [];\n const datePattern = matchResult[1];\n const timePattern = matchResult[2];\n\n if (!timePattern) {\n return dateLongFormatter(pattern, formatLong);\n }\n\n let dateTimeFormat;\n\n switch (datePattern) {\n case \"P\":\n dateTimeFormat = formatLong.dateTime({ width: \"short\" });\n break;\n case \"PP\":\n dateTimeFormat = formatLong.dateTime({ width: \"medium\" });\n break;\n case \"PPP\":\n dateTimeFormat = formatLong.dateTime({ width: \"long\" });\n break;\n case \"PPPP\":\n default:\n dateTimeFormat = formatLong.dateTime({ width: \"full\" });\n break;\n }\n\n return dateTimeFormat\n .replace(\"{{date}}\", dateLongFormatter(datePattern, formatLong))\n .replace(\"{{time}}\", timeLongFormatter(timePattern, formatLong));\n};\n\nexport const longFormatters = {\n p: timeLongFormatter,\n P: dateTimeLongFormatter,\n};\n","const dayOfYearTokenRE = /^D+$/;\nconst weekYearTokenRE = /^Y+$/;\n\nconst throwTokens = [\"D\", \"DD\", \"YY\", \"YYYY\"];\n\nexport function isProtectedDayOfYearToken(token) {\n return dayOfYearTokenRE.test(token);\n}\n\nexport function isProtectedWeekYearToken(token) {\n return weekYearTokenRE.test(token);\n}\n\nexport function warnOrThrowProtectedError(token, format, input) {\n const _message = message(token, format, input);\n console.warn(_message);\n if (throwTokens.includes(token)) throw new RangeError(_message);\n}\n\nfunction message(token, format, input) {\n const subject = token[0] === \"Y\" ? \"years\" : \"days of the month\";\n return `Use \\`${token.toLowerCase()}\\` instead of \\`${token}\\` (in \\`${format}\\`) for formatting ${subject} to the input \\`${input}\\`; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md`;\n}\n","import { defaultLocale } from \"./_lib/defaultLocale.js\";\nimport { getDefaultOptions } from \"./_lib/defaultOptions.js\";\nimport { formatters } from \"./_lib/format/formatters.js\";\nimport { longFormatters } from \"./_lib/format/longFormatters.js\";\nimport {\n isProtectedDayOfYearToken,\n isProtectedWeekYearToken,\n warnOrThrowProtectedError,\n} from \"./_lib/protectedTokens.js\";\nimport { isValid } from \"./isValid.js\";\nimport { toDate } from \"./toDate.js\";\n\n// Rexports of internal for libraries to use.\n// See: https://github.com/date-fns/date-fns/issues/3638#issuecomment-1877082874\nexport { formatters, longFormatters };\n\n// This RegExp consists of three parts separated by `|`:\n// - [yYQqMLwIdDecihHKkms]o matches any available ordinal number token\n// (one of the certain letters followed by `o`)\n// - (\\w)\\1* matches any sequences of the same letter\n// - '' matches two quote characters in a row\n// - '(''|[^'])+('|$) matches anything surrounded by two quote characters ('),\n// except a single quote symbol, which ends the sequence.\n// Two quote characters do not end the sequence.\n// If there is no matching single quote\n// then the sequence will continue until the end of the string.\n// - . matches any single character unmatched by previous parts of the RegExps\nconst formattingTokensRegExp =\n /[yYQqMLwIdDecihHKkms]o|(\\w)\\1*|''|'(''|[^'])+('|$)|./g;\n\n// This RegExp catches symbols escaped by quotes, and also\n// sequences of symbols P, p, and the combinations like `PPPPPPPppppp`\nconst longFormattingTokensRegExp = /P+p+|P+|p+|''|'(''|[^'])+('|$)|./g;\n\nconst escapedStringRegExp = /^'([^]*?)'?$/;\nconst doubleQuoteRegExp = /''/g;\nconst unescapedLatinCharacterRegExp = /[a-zA-Z]/;\n\nexport { format as formatDate };\n\n/**\n * The {@link format} function options.\n */\n\n/**\n * @name format\n * @alias formatDate\n * @category Common Helpers\n * @summary Format the date.\n *\n * @description\n * Return the formatted date string in the given format. The result may vary by locale.\n *\n * > ⚠️ Please note that the `format` tokens differ from Moment.js and other libraries.\n * > See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md\n *\n * The characters wrapped between two single quotes characters (') are escaped.\n * Two single quotes in a row, whether inside or outside a quoted sequence, represent a 'real' single quote.\n * (see the last example)\n *\n * Format of the string is based on Unicode Technical Standard #35:\n * https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table\n * with a few additions (see note 7 below the table).\n *\n * Accepted patterns:\n * | Unit | Pattern | Result examples | Notes |\n * |---------------------------------|---------|-----------------------------------|-------|\n * | Era | G..GGG | AD, BC | |\n * | | GGGG | Anno Domini, Before Christ | 2 |\n * | | GGGGG | A, B | |\n * | Calendar year | y | 44, 1, 1900, 2017 | 5 |\n * | | yo | 44th, 1st, 0th, 17th | 5,7 |\n * | | yy | 44, 01, 00, 17 | 5 |\n * | | yyy | 044, 001, 1900, 2017 | 5 |\n * | | yyyy | 0044, 0001, 1900, 2017 | 5 |\n * | | yyyyy | ... | 3,5 |\n * | Local week-numbering year | Y | 44, 1, 1900, 2017 | 5 |\n * | | Yo | 44th, 1st, 1900th, 2017th | 5,7 |\n * | | YY | 44, 01, 00, 17 | 5,8 |\n * | | YYY | 044, 001, 1900, 2017 | 5 |\n * | | YYYY | 0044, 0001, 1900, 2017 | 5,8 |\n * | | YYYYY | ... | 3,5 |\n * | ISO week-numbering year | R | -43, 0, 1, 1900, 2017 | 5,7 |\n * | | RR | -43, 00, 01, 1900, 2017 | 5,7 |\n * | | RRR | -043, 000, 001, 1900, 2017 | 5,7 |\n * | | RRRR | -0043, 0000, 0001, 1900, 2017 | 5,7 |\n * | | RRRRR | ... | 3,5,7 |\n * | Extended year | u | -43, 0, 1, 1900, 2017 | 5 |\n * | | uu | -43, 01, 1900, 2017 | 5 |\n * | | uuu | -043, 001, 1900, 2017 | 5 |\n * | | uuuu | -0043, 0001, 1900, 2017 | 5 |\n * | | uuuuu | ... | 3,5 |\n * | Quarter (formatting) | Q | 1, 2, 3, 4 | |\n * | | Qo | 1st, 2nd, 3rd, 4th | 7 |\n * | | QQ | 01, 02, 03, 04 | |\n * | | QQQ | Q1, Q2, Q3, Q4 | |\n * | | QQQQ | 1st quarter, 2nd quarter, ... | 2 |\n * | | QQQQQ | 1, 2, 3, 4 | 4 |\n * | Quarter (stand-alone) | q | 1, 2, 3, 4 | |\n * | | qo | 1st, 2nd, 3rd, 4th | 7 |\n * | | qq | 01, 02, 03, 04 | |\n * | | qqq | Q1, Q2, Q3, Q4 | |\n * | | qqqq | 1st quarter, 2nd quarter, ... | 2 |\n * | | qqqqq | 1, 2, 3, 4 | 4 |\n * | Month (formatting) | M | 1, 2, ..., 12 | |\n * | | Mo | 1st, 2nd, ..., 12th | 7 |\n * | | MM | 01, 02, ..., 12 | |\n * | | MMM | Jan, Feb, ..., Dec | |\n * | | MMMM | January, February, ..., December | 2 |\n * | | MMMMM | J, F, ..., D | |\n * | Month (stand-alone) | L | 1, 2, ..., 12 | |\n * | | Lo | 1st, 2nd, ..., 12th | 7 |\n * | | LL | 01, 02, ..., 12 | |\n * | | LLL | Jan, Feb, ..., Dec | |\n * | | LLLL | January, February, ..., December | 2 |\n * | | LLLLL | J, F, ..., D | |\n * | Local week of year | w | 1, 2, ..., 53 | |\n * | | wo | 1st, 2nd, ..., 53th | 7 |\n * | | ww | 01, 02, ..., 53 | |\n * | ISO week of year | I | 1, 2, ..., 53 | 7 |\n * | | Io | 1st, 2nd, ..., 53th | 7 |\n * | | II | 01, 02, ..., 53 | 7 |\n * | Day of month | d | 1, 2, ..., 31 | |\n * | | do | 1st, 2nd, ..., 31st | 7 |\n * | | dd | 01, 02, ..., 31 | |\n * | Day of year | D | 1, 2, ..., 365, 366 | 9 |\n * | | Do | 1st, 2nd, ..., 365th, 366th | 7 |\n * | | DD | 01, 02, ..., 365, 366 | 9 |\n * | | DDD | 001, 002, ..., 365, 366 | |\n * | | DDDD | ... | 3 |\n * | Day of week (formatting) | E..EEE | Mon, Tue, Wed, ..., Sun | |\n * | | EEEE | Monday, Tuesday, ..., Sunday | 2 |\n * | | EEEEE | M, T, W, T, F, S, S | |\n * | | EEEEEE | Mo, Tu, We, Th, Fr, Sa, Su | |\n * | ISO day of week (formatting) | i | 1, 2, 3, ..., 7 | 7 |\n * | | io | 1st, 2nd, ..., 7th | 7 |\n * | | ii | 01, 02, ..., 07 | 7 |\n * | | iii | Mon, Tue, Wed, ..., Sun | 7 |\n * | | iiii | Monday, Tuesday, ..., Sunday | 2,7 |\n * | | iiiii | M, T, W, T, F, S, S | 7 |\n * | | iiiiii | Mo, Tu, We, Th, Fr, Sa, Su | 7 |\n * | Local day of week (formatting) | e | 2, 3, 4, ..., 1 | |\n * | | eo | 2nd, 3rd, ..., 1st | 7 |\n * | | ee | 02, 03, ..., 01 | |\n * | | eee | Mon, Tue, Wed, ..., Sun | |\n * | | eeee | Monday, Tuesday, ..., Sunday | 2 |\n * | | eeeee | M, T, W, T, F, S, S | |\n * | | eeeeee | Mo, Tu, We, Th, Fr, Sa, Su | |\n * | Local day of week (stand-alone) | c | 2, 3, 4, ..., 1 | |\n * | | co | 2nd, 3rd, ..., 1st | 7 |\n * | | cc | 02, 03, ..., 01 | |\n * | | ccc | Mon, Tue, Wed, ..., Sun | |\n * | | cccc | Monday, Tuesday, ..., Sunday | 2 |\n * | | ccccc | M, T, W, T, F, S, S | |\n * | | cccccc | Mo, Tu, We, Th, Fr, Sa, Su | |\n * | AM, PM | a..aa | AM, PM | |\n * | | aaa | am, pm | |\n * | | aaaa | a.m., p.m. | 2 |\n * | | aaaaa | a, p | |\n * | AM, PM, noon, midnight | b..bb | AM, PM, noon, midnight | |\n * | | bbb | am, pm, noon, midnight | |\n * | | bbbb | a.m., p.m., noon, midnight | 2 |\n * | | bbbbb | a, p, n, mi | |\n * | Flexible day period | B..BBB | at night, in the morning, ... | |\n * | | BBBB | at night, in the morning, ... | 2 |\n * | | BBBBB | at night, in the morning, ... | |\n * | Hour [1-12] | h | 1, 2, ..., 11, 12 | |\n * | | ho | 1st, 2nd, ..., 11th, 12th | 7 |\n * | | hh | 01, 02, ..., 11, 12 | |\n * | Hour [0-23] | H | 0, 1, 2, ..., 23 | |\n * | | Ho | 0th, 1st, 2nd, ..., 23rd | 7 |\n * | | HH | 00, 01, 02, ..., 23 | |\n * | Hour [0-11] | K | 1, 2, ..., 11, 0 | |\n * | | Ko | 1st, 2nd, ..., 11th, 0th | 7 |\n * | | KK | 01, 02, ..., 11, 00 | |\n * | Hour [1-24] | k | 24, 1, 2, ..., 23 | |\n * | | ko | 24th, 1st, 2nd, ..., 23rd | 7 |\n * | | kk | 24, 01, 02, ..., 23 | |\n * | Minute | m | 0, 1, ..., 59 | |\n * | | mo | 0th, 1st, ..., 59th | 7 |\n * | | mm | 00, 01, ..., 59 | |\n * | Second | s | 0, 1, ..., 59 | |\n * | | so | 0th, 1st, ..., 59th | 7 |\n * | | ss | 00, 01, ..., 59 | |\n * | Fraction of second | S | 0, 1, ..., 9 | |\n * | | SS | 00, 01, ..., 99 | |\n * | | SSS | 000, 001, ..., 999 | |\n * | | SSSS | ... | 3 |\n * | Timezone (ISO-8601 w/ Z) | X | -08, +0530, Z | |\n * | | XX | -0800, +0530, Z | |\n * | | XXX | -08:00, +05:30, Z | |\n * | | XXXX | -0800, +0530, Z, +123456 | 2 |\n * | | XXXXX | -08:00, +05:30, Z, +12:34:56 | |\n * | Timezone (ISO-8601 w/o Z) | x | -08, +0530, +00 | |\n * | | xx | -0800, +0530, +0000 | |\n * | | xxx | -08:00, +05:30, +00:00 | 2 |\n * | | xxxx | -0800, +0530, +0000, +123456 | |\n * | | xxxxx | -08:00, +05:30, +00:00, +12:34:56 | |\n * | Timezone (GMT) | O...OOO | GMT-8, GMT+5:30, GMT+0 | |\n * | | OOOO | GMT-08:00, GMT+05:30, GMT+00:00 | 2 |\n * | Timezone (specific non-locat.) | z...zzz | GMT-8, GMT+5:30, GMT+0 | 6 |\n * | | zzzz | GMT-08:00, GMT+05:30, GMT+00:00 | 2,6 |\n * | Seconds timestamp | t | 512969520 | 7 |\n * | | tt | ... | 3,7 |\n * | Milliseconds timestamp | T | 512969520900 | 7 |\n * | | TT | ... | 3,7 |\n * | Long localized date | P | 04/29/1453 | 7 |\n * | | PP | Apr 29, 1453 | 7 |\n * | | PPP | April 29th, 1453 | 7 |\n * | | PPPP | Friday, April 29th, 1453 | 2,7 |\n * | Long localized time | p | 12:00 AM | 7 |\n * | | pp | 12:00:00 AM | 7 |\n * | | ppp | 12:00:00 AM GMT+2 | 7 |\n * | | pppp | 12:00:00 AM GMT+02:00 | 2,7 |\n * | Combination of date and time | Pp | 04/29/1453, 12:00 AM | 7 |\n * | | PPpp | Apr 29, 1453, 12:00:00 AM | 7 |\n * | | PPPppp | April 29th, 1453 at ... | 7 |\n * | | PPPPpppp| Friday, April 29th, 1453 at ... | 2,7 |\n * Notes:\n * 1. \"Formatting\" units (e.g. formatting quarter) in the default en-US locale\n * are the same as \"stand-alone\" units, but are different in some languages.\n * \"Formatting\" units are declined according to the rules of the language\n * in the context of a date. \"Stand-alone\" units are always nominative singular:\n *\n * `format(new Date(2017, 10, 6), 'do LLLL', {locale: cs}) //=> '6. listopad'`\n *\n * `format(new Date(2017, 10, 6), 'do MMMM', {locale: cs}) //=> '6. listopadu'`\n *\n * 2. Any sequence of the identical letters is a pattern, unless it is escaped by\n * the single quote characters (see below).\n * If the sequence is longer than listed in table (e.g. `EEEEEEEEEEE`)\n * the output will be the same as default pattern for this unit, usually\n * the longest one (in case of ISO weekdays, `EEEE`). Default patterns for units\n * are marked with \"2\" in the last column of the table.\n *\n * `format(new Date(2017, 10, 6), 'MMM') //=> 'Nov'`\n *\n * `format(new Date(2017, 10, 6), 'MMMM') //=> 'November'`\n *\n * `format(new Date(2017, 10, 6), 'MMMMM') //=> 'N'`\n *\n * `format(new Date(2017, 10, 6), 'MMMMMM') //=> 'November'`\n *\n * `format(new Date(2017, 10, 6), 'MMMMMMM') //=> 'November'`\n *\n * 3. Some patterns could be unlimited length (such as `yyyyyyyy`).\n * The output will be padded with zeros to match the length of the pattern.\n *\n * `format(new Date(2017, 10, 6), 'yyyyyyyy') //=> '00002017'`\n *\n * 4. `QQQQQ` and `qqqqq` could be not strictly numerical in some locales.\n * These tokens represent the shortest form of the quarter.\n *\n * 5. The main difference between `y` and `u` patterns are B.C. years:\n *\n * | Year | `y` | `u` |\n * |------|-----|-----|\n * | AC 1 | 1 | 1 |\n * | BC 1 | 1 | 0 |\n * | BC 2 | 2 | -1 |\n *\n * Also `yy` always returns the last two digits of a year,\n * while `uu` pads single digit years to 2 characters and returns other years unchanged:\n *\n * | Year | `yy` | `uu` |\n * |------|------|------|\n * | 1 | 01 | 01 |\n * | 14 | 14 | 14 |\n * | 376 | 76 | 376 |\n * | 1453 | 53 | 1453 |\n *\n * The same difference is true for local and ISO week-numbering years (`Y` and `R`),\n * except local week-numbering years are dependent on `options.weekStartsOn`\n * and `options.firstWeekContainsDate` (compare [getISOWeekYear](https://date-fns.org/docs/getISOWeekYear)\n * and [getWeekYear](https://date-fns.org/docs/getWeekYear)).\n *\n * 6. Specific non-location timezones are currently unavailable in `date-fns`,\n * so right now these tokens fall back to GMT timezones.\n *\n * 7. These patterns are not in the Unicode Technical Standard #35:\n * - `i`: ISO day of week\n * - `I`: ISO week of year\n * - `R`: ISO week-numbering year\n * - `t`: seconds timestamp\n * - `T`: milliseconds timestamp\n * - `o`: ordinal number modifier\n * - `P`: long localized date\n * - `p`: long localized time\n *\n * 8. `YY` and `YYYY` tokens represent week-numbering years but they are often confused with years.\n * You should enable `options.useAdditionalWeekYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md\n *\n * 9. `D` and `DD` tokens represent days of the year but they are often confused with days of the month.\n * You should enable `options.useAdditionalDayOfYearTokens` to use them. See: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md\n *\n * @param date - The original date\n * @param format - The string of tokens\n * @param options - An object with options\n *\n * @returns The formatted date string\n *\n * @throws `date` must not be Invalid Date\n * @throws `options.locale` must contain `localize` property\n * @throws `options.locale` must contain `formatLong` property\n * @throws use `yyyy` instead of `YYYY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md\n * @throws use `yy` instead of `YY` for formatting years using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md\n * @throws use `d` instead of `D` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md\n * @throws use `dd` instead of `DD` for formatting days of the month using [format provided] to the input [input provided]; see: https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md\n * @throws format string contains an unescaped latin alphabet character\n *\n * @example\n * // Represent 11 February 2014 in middle-endian format:\n * const result = format(new Date(2014, 1, 11), 'MM/dd/yyyy')\n * //=> '02/11/2014'\n *\n * @example\n * // Represent 2 July 2014 in Esperanto:\n * import { eoLocale } from 'date-fns/locale/eo'\n * const result = format(new Date(2014, 6, 2), \"do 'de' MMMM yyyy\", {\n * locale: eoLocale\n * })\n * //=> '2-a de julio 2014'\n *\n * @example\n * // Escape string by single quote characters:\n * const result = format(new Date(2014, 6, 2, 15), \"h 'o''clock'\")\n * //=> \"3 o'clock\"\n */\nexport function format(date, formatStr, options) {\n const defaultOptions = getDefaultOptions();\n const locale = options?.locale ?? defaultOptions.locale ?? defaultLocale;\n\n const firstWeekContainsDate =\n options?.firstWeekContainsDate ??\n options?.locale?.options?.firstWeekContainsDate ??\n defaultOptions.firstWeekContainsDate ??\n defaultOptions.locale?.options?.firstWeekContainsDate ??\n 1;\n\n const weekStartsOn =\n options?.weekStartsOn ??\n options?.locale?.options?.weekStartsOn ??\n defaultOptions.weekStartsOn ??\n defaultOptions.locale?.options?.weekStartsOn ??\n 0;\n\n const originalDate = toDate(date, options?.in);\n\n if (!isValid(originalDate)) {\n throw new RangeError(\"Invalid time value\");\n }\n\n let parts = formatStr\n .match(longFormattingTokensRegExp)\n .map((substring) => {\n const firstCharacter = substring[0];\n if (firstCharacter === \"p\" || firstCharacter === \"P\") {\n const longFormatter = longFormatters[firstCharacter];\n return longFormatter(substring, locale.formatLong);\n }\n return substring;\n })\n .join(\"\")\n .match(formattingTokensRegExp)\n .map((substring) => {\n // Replace two single quote characters with one single quote character\n if (substring === \"''\") {\n return { isToken: false, value: \"'\" };\n }\n\n const firstCharacter = substring[0];\n if (firstCharacter === \"'\") {\n return { isToken: false, value: cleanEscapedString(substring) };\n }\n\n if (formatters[firstCharacter]) {\n return { isToken: true, value: substring };\n }\n\n if (firstCharacter.match(unescapedLatinCharacterRegExp)) {\n throw new RangeError(\n \"Format string contains an unescaped latin alphabet character `\" +\n firstCharacter +\n \"`\",\n );\n }\n\n return { isToken: false, value: substring };\n });\n\n // invoke localize preprocessor (only for french locales at the moment)\n if (locale.localize.preprocessor) {\n parts = locale.localize.preprocessor(originalDate, parts);\n }\n\n const formatterOptions = {\n firstWeekContainsDate,\n weekStartsOn,\n locale,\n };\n\n return parts\n .map((part) => {\n if (!part.isToken) return part.value;\n\n const token = part.value;\n\n if (\n (!options?.useAdditionalWeekYearTokens &&\n isProtectedWeekYearToken(token)) ||\n (!options?.useAdditionalDayOfYearTokens &&\n isProtectedDayOfYearToken(token))\n ) {\n warnOrThrowProtectedError(token, formatStr, String(date));\n }\n\n const formatter = formatters[token[0]];\n return formatter(originalDate, token, locale.localize, formatterOptions);\n })\n .join(\"\");\n}\n\nfunction cleanEscapedString(input) {\n const matched = input.match(escapedStringRegExp);\n\n if (!matched) {\n return input;\n }\n\n return matched[1].replace(doubleQuoteRegExp, \"'\");\n}\n\n// Fallback for modularized imports:\nexport default format;\n","const formatDistanceLocale = {\n lessThanXSeconds: {\n one: \"moins d’une seconde\",\n other: \"moins de {{count}} secondes\",\n },\n\n xSeconds: {\n one: \"1 seconde\",\n other: \"{{count}} secondes\",\n },\n\n halfAMinute: \"30 secondes\",\n\n lessThanXMinutes: {\n one: \"moins d’une minute\",\n other: \"moins de {{count}} minutes\",\n },\n\n xMinutes: {\n one: \"1 minute\",\n other: \"{{count}} minutes\",\n },\n\n aboutXHours: {\n one: \"environ 1 heure\",\n other: \"environ {{count}} heures\",\n },\n\n xHours: {\n one: \"1 heure\",\n other: \"{{count}} heures\",\n },\n\n xDays: {\n one: \"1 jour\",\n other: \"{{count}} jours\",\n },\n\n aboutXWeeks: {\n one: \"environ 1 semaine\",\n other: \"environ {{count}} semaines\",\n },\n\n xWeeks: {\n one: \"1 semaine\",\n other: \"{{count}} semaines\",\n },\n\n aboutXMonths: {\n one: \"environ 1 mois\",\n other: \"environ {{count}} mois\",\n },\n\n xMonths: {\n one: \"1 mois\",\n other: \"{{count}} mois\",\n },\n\n aboutXYears: {\n one: \"environ 1 an\",\n other: \"environ {{count}} ans\",\n },\n\n xYears: {\n one: \"1 an\",\n other: \"{{count}} ans\",\n },\n\n overXYears: {\n one: \"plus d’un an\",\n other: \"plus de {{count}} ans\",\n },\n\n almostXYears: {\n one: \"presqu’un an\",\n other: \"presque {{count}} ans\",\n },\n};\n\nexport const formatDistance = (token, count, options) => {\n let result;\n const form = formatDistanceLocale[token];\n if (typeof form === \"string\") {\n result = form;\n } else if (count === 1) {\n result = form.one;\n } else {\n result = form.other.replace(\"{{count}}\", String(count));\n }\n\n if (options?.addSuffix) {\n if (options.comparison && options.comparison > 0) {\n return \"dans \" + result;\n } else {\n return \"il y a \" + result;\n }\n }\n\n return result;\n};\n","import { buildFormatLongFn } from \"../../_lib/buildFormatLongFn.js\";\n\nconst dateFormats = {\n full: \"EEEE d MMMM y\",\n long: \"d MMMM y\",\n medium: \"d MMM y\",\n short: \"dd/MM/y\",\n};\n\nconst timeFormats = {\n full: \"HH:mm:ss zzzz\",\n long: \"HH:mm:ss z\",\n medium: \"HH:mm:ss\",\n short: \"HH:mm\",\n};\n\nconst dateTimeFormats = {\n full: \"{{date}} 'à' {{time}}\",\n long: \"{{date}} 'à' {{time}}\",\n medium: \"{{date}}, {{time}}\",\n short: \"{{date}}, {{time}}\",\n};\n\nexport const formatLong = {\n date: buildFormatLongFn({\n formats: dateFormats,\n defaultWidth: \"full\",\n }),\n\n time: buildFormatLongFn({\n formats: timeFormats,\n defaultWidth: \"full\",\n }),\n\n dateTime: buildFormatLongFn({\n formats: dateTimeFormats,\n defaultWidth: \"full\",\n }),\n};\n","const formatRelativeLocale = {\n lastWeek: \"eeee 'dernier à' p\",\n yesterday: \"'hier à' p\",\n today: \"'aujourd’hui à' p\",\n tomorrow: \"'demain à' p'\",\n nextWeek: \"eeee 'prochain à' p\",\n other: \"P\",\n};\n\nexport const formatRelative = (token, _date, _baseDate, _options) =>\n formatRelativeLocale[token];\n","import { buildLocalizeFn } from \"../../_lib/buildLocalizeFn.js\";\n\nconst eraValues = {\n narrow: [\"av. J.-C\", \"ap. J.-C\"],\n abbreviated: [\"av. J.-C\", \"ap. J.-C\"],\n wide: [\"avant Jésus-Christ\", \"après Jésus-Christ\"],\n};\n\nconst quarterValues = {\n narrow: [\"T1\", \"T2\", \"T3\", \"T4\"],\n abbreviated: [\"1er trim.\", \"2ème trim.\", \"3ème trim.\", \"4ème trim.\"],\n wide: [\"1er trimestre\", \"2ème trimestre\", \"3ème trimestre\", \"4ème trimestre\"],\n};\n\nconst monthValues = {\n narrow: [\"J\", \"F\", \"M\", \"A\", \"M\", \"J\", \"J\", \"A\", \"S\", \"O\", \"N\", \"D\"],\n abbreviated: [\n \"janv.\",\n \"févr.\",\n \"mars\",\n \"avr.\",\n \"mai\",\n \"juin\",\n \"juil.\",\n \"août\",\n \"sept.\",\n \"oct.\",\n \"nov.\",\n \"déc.\",\n ],\n\n wide: [\n \"janvier\",\n \"février\",\n \"mars\",\n \"avril\",\n \"mai\",\n \"juin\",\n \"juillet\",\n \"août\",\n \"septembre\",\n \"octobre\",\n \"novembre\",\n \"décembre\",\n ],\n};\n\nconst dayValues = {\n narrow: [\"D\", \"L\", \"M\", \"M\", \"J\", \"V\", \"S\"],\n short: [\"di\", \"lu\", \"ma\", \"me\", \"je\", \"ve\", \"sa\"],\n abbreviated: [\"dim.\", \"lun.\", \"mar.\", \"mer.\", \"jeu.\", \"ven.\", \"sam.\"],\n\n wide: [\n \"dimanche\",\n \"lundi\",\n \"mardi\",\n \"mercredi\",\n \"jeudi\",\n \"vendredi\",\n \"samedi\",\n ],\n};\n\nconst dayPeriodValues = {\n narrow: {\n am: \"AM\",\n pm: \"PM\",\n midnight: \"minuit\",\n noon: \"midi\",\n morning: \"mat.\",\n afternoon: \"ap.m.\",\n evening: \"soir\",\n night: \"mat.\",\n },\n abbreviated: {\n am: \"AM\",\n pm: \"PM\",\n midnight: \"minuit\",\n noon: \"midi\",\n morning: \"matin\",\n afternoon: \"après-midi\",\n evening: \"soir\",\n night: \"matin\",\n },\n wide: {\n am: \"AM\",\n pm: \"PM\",\n midnight: \"minuit\",\n noon: \"midi\",\n morning: \"du matin\",\n afternoon: \"de l’après-midi\",\n evening: \"du soir\",\n night: \"du matin\",\n },\n};\n\nconst ordinalNumber = (dirtyNumber, options) => {\n const number = Number(dirtyNumber);\n const unit = options?.unit;\n\n if (number === 0) return \"0\";\n\n const feminineUnits = [\"year\", \"week\", \"hour\", \"minute\", \"second\"];\n let suffix;\n\n if (number === 1) {\n suffix = unit && feminineUnits.includes(unit) ? \"ère\" : \"er\";\n } else {\n suffix = \"ème\";\n }\n\n return number + suffix;\n};\n\nconst LONG_MONTHS_TOKENS = [\"MMM\", \"MMMM\"];\n\nexport const localize = {\n preprocessor: (date, parts) => {\n // Replaces the `do` tokens with `d` when used with long month tokens and the day of the month is greater than one.\n // Use case \"do MMMM\" => 1er août, 29 août\n // see https://github.com/date-fns/date-fns/issues/1391\n\n if (date.getDate() === 1) return parts;\n\n const hasLongMonthToken = parts.some(\n (part) => part.isToken && LONG_MONTHS_TOKENS.includes(part.value),\n );\n\n if (!hasLongMonthToken) return parts;\n\n return parts.map((part) =>\n part.isToken && part.value === \"do\"\n ? { isToken: true, value: \"d\" }\n : part,\n );\n },\n\n ordinalNumber,\n\n era: buildLocalizeFn({\n values: eraValues,\n defaultWidth: \"wide\",\n }),\n\n quarter: buildLocalizeFn({\n values: quarterValues,\n defaultWidth: \"wide\",\n argumentCallback: (quarter) => quarter - 1,\n }),\n\n month: buildLocalizeFn({\n values: monthValues,\n defaultWidth: \"wide\",\n }),\n\n day: buildLocalizeFn({\n values: dayValues,\n defaultWidth: \"wide\",\n }),\n\n dayPeriod: buildLocalizeFn({\n values: dayPeriodValues,\n defaultWidth: \"wide\",\n }),\n};\n","import { buildMatchFn } from \"../../_lib/buildMatchFn.js\";\nimport { buildMatchPatternFn } from \"../../_lib/buildMatchPatternFn.js\";\n\nconst matchOrdinalNumberPattern = /^(\\d+)(ième|ère|ème|er|e)?/i;\nconst parseOrdinalNumberPattern = /\\d+/i;\n\nconst matchEraPatterns = {\n narrow: /^(av\\.J\\.C|ap\\.J\\.C|ap\\.J\\.-C)/i,\n abbreviated: /^(av\\.J\\.-C|av\\.J-C|apr\\.J\\.-C|apr\\.J-C|ap\\.J-C)/i,\n wide: /^(avant Jésus-Christ|après Jésus-Christ)/i,\n};\nconst parseEraPatterns = {\n any: [/^av/i, /^ap/i],\n};\n\nconst matchQuarterPatterns = {\n narrow: /^T?[1234]/i,\n abbreviated: /^[1234](er|ème|e)? trim\\.?/i,\n wide: /^[1234](er|ème|e)? trimestre/i,\n};\nconst parseQuarterPatterns = {\n any: [/1/i, /2/i, /3/i, /4/i],\n};\n\nconst matchMonthPatterns = {\n narrow: /^[jfmasond]/i,\n abbreviated:\n /^(janv|févr|mars|avr|mai|juin|juill|juil|août|sept|oct|nov|déc)\\.?/i,\n wide: /^(janvier|février|mars|avril|mai|juin|juillet|août|septembre|octobre|novembre|décembre)/i,\n};\nconst parseMonthPatterns = {\n narrow: [\n /^j/i,\n /^f/i,\n /^m/i,\n /^a/i,\n /^m/i,\n /^j/i,\n /^j/i,\n /^a/i,\n /^s/i,\n /^o/i,\n /^n/i,\n /^d/i,\n ],\n\n any: [\n /^ja/i,\n /^f/i,\n /^mar/i,\n /^av/i,\n /^ma/i,\n /^juin/i,\n /^juil/i,\n /^ao/i,\n /^s/i,\n /^o/i,\n /^n/i,\n /^d/i,\n ],\n};\n\nconst matchDayPatterns = {\n narrow: /^[lmjvsd]/i,\n short: /^(di|lu|ma|me|je|ve|sa)/i,\n abbreviated: /^(dim|lun|mar|mer|jeu|ven|sam)\\.?/i,\n wide: /^(dimanche|lundi|mardi|mercredi|jeudi|vendredi|samedi)/i,\n};\nconst parseDayPatterns = {\n narrow: [/^d/i, /^l/i, /^m/i, /^m/i, /^j/i, /^v/i, /^s/i],\n any: [/^di/i, /^lu/i, /^ma/i, /^me/i, /^je/i, /^ve/i, /^sa/i],\n};\n\nconst matchDayPeriodPatterns = {\n narrow: /^(a|p|minuit|midi|mat\\.?|ap\\.?m\\.?|soir|nuit)/i,\n any: /^([ap]\\.?\\s?m\\.?|du matin|de l'après[-\\s]midi|du soir|de la nuit)/i,\n};\nconst parseDayPeriodPatterns = {\n any: {\n am: /^a/i,\n pm: /^p/i,\n midnight: /^min/i,\n noon: /^mid/i,\n morning: /mat/i,\n afternoon: /ap/i,\n evening: /soir/i,\n night: /nuit/i,\n },\n};\n\nexport const match = {\n ordinalNumber: buildMatchPatternFn({\n matchPattern: matchOrdinalNumberPattern,\n parsePattern: parseOrdinalNumberPattern,\n valueCallback: (value) => parseInt(value),\n }),\n\n era: buildMatchFn({\n matchPatterns: matchEraPatterns,\n defaultMatchWidth: \"wide\",\n parsePatterns: parseEraPatterns,\n defaultParseWidth: \"any\",\n }),\n\n quarter: buildMatchFn({\n matchPatterns: matchQuarterPatterns,\n defaultMatchWidth: \"wide\",\n parsePatterns: parseQuarterPatterns,\n defaultParseWidth: \"any\",\n valueCallback: (index) => index + 1,\n }),\n\n month: buildMatchFn({\n matchPatterns: matchMonthPatterns,\n defaultMatchWidth: \"wide\",\n parsePatterns: parseMonthPatterns,\n defaultParseWidth: \"any\",\n }),\n\n day: buildMatchFn({\n matchPatterns: matchDayPatterns,\n defaultMatchWidth: \"wide\",\n parsePatterns: parseDayPatterns,\n defaultParseWidth: \"any\",\n }),\n\n dayPeriod: buildMatchFn({\n matchPatterns: matchDayPeriodPatterns,\n defaultMatchWidth: \"any\",\n parsePatterns: parseDayPeriodPatterns,\n defaultParseWidth: \"any\",\n }),\n};\n","import { formatDistance } from \"./fr/_lib/formatDistance.js\";\nimport { formatLong } from \"./fr/_lib/formatLong.js\";\nimport { formatRelative } from \"./fr/_lib/formatRelative.js\";\nimport { localize } from \"./fr/_lib/localize.js\";\nimport { match } from \"./fr/_lib/match.js\";\n\n/**\n * @category Locales\n * @summary French locale.\n * @language French\n * @iso-639-2 fra\n * @author Jean Dupouy [@izeau](https://github.com/izeau)\n * @author François B [@fbonzon](https://github.com/fbonzon)\n */\nexport const fr = {\n code: \"fr\",\n formatDistance: formatDistance,\n formatLong: formatLong,\n formatRelative: formatRelative,\n localize: localize,\n match: match,\n options: {\n weekStartsOn: 1 /* Monday */,\n firstWeekContainsDate: 4,\n },\n};\n\n// Fallback for modularized imports:\nexport default fr;\n","(function(){\"use strict\";try{if(typeof document<\"u\"){var e=document.createElement(\"style\");e.appendChild(document.createTextNode(\".ce-hint--align-start{text-align:left}.ce-hint--align-center{text-align:center}.ce-hint__description{opacity:.6;margin-top:3px}\")),document.head.appendChild(e)}}catch(t){console.error(\"vite-plugin-css-injected-by-js\",t)}})();\nvar ko = typeof globalThis < \"u\" ? globalThis : typeof window < \"u\" ? window : typeof global < \"u\" ? global : typeof self < \"u\" ? self : {};\nfunction Fe(n) {\n return n && n.__esModule && Object.prototype.hasOwnProperty.call(n, \"default\") ? n.default : n;\n}\nfunction ze() {\n}\nObject.assign(ze, {\n default: ze,\n register: ze,\n revert: function() {\n },\n __esModule: !0\n});\nElement.prototype.matches || (Element.prototype.matches = Element.prototype.matchesSelector || Element.prototype.mozMatchesSelector || Element.prototype.msMatchesSelector || Element.prototype.oMatchesSelector || Element.prototype.webkitMatchesSelector || function(n) {\n const e = (this.document || this.ownerDocument).querySelectorAll(n);\n let t = e.length;\n for (; --t >= 0 && e.item(t) !== this; )\n ;\n return t > -1;\n});\nElement.prototype.closest || (Element.prototype.closest = function(n) {\n let e = this;\n if (!document.documentElement.contains(e))\n return null;\n do {\n if (e.matches(n))\n return e;\n e = e.parentElement || e.parentNode;\n } while (e !== null);\n return null;\n});\nElement.prototype.prepend || (Element.prototype.prepend = function(e) {\n const t = document.createDocumentFragment();\n Array.isArray(e) || (e = [e]), e.forEach((o) => {\n const i = o instanceof Node;\n t.appendChild(i ? o : document.createTextNode(o));\n }), this.insertBefore(t, this.firstChild);\n});\nElement.prototype.scrollIntoViewIfNeeded || (Element.prototype.scrollIntoViewIfNeeded = function(n) {\n n = arguments.length === 0 ? !0 : !!n;\n const e = this.parentNode, t = window.getComputedStyle(e, null), o = parseInt(t.getPropertyValue(\"border-top-width\")), i = parseInt(t.getPropertyValue(\"border-left-width\")), s = this.offsetTop - e.offsetTop < e.scrollTop, r = this.offsetTop - e.offsetTop + this.clientHeight - o > e.scrollTop + e.clientHeight, l = this.offsetLeft - e.offsetLeft < e.scrollLeft, a = this.offsetLeft - e.offsetLeft + this.clientWidth - i > e.scrollLeft + e.clientWidth, c = s && !r;\n (s || r) && n && (e.scrollTop = this.offsetTop - e.offsetTop - e.clientHeight / 2 - o + this.clientHeight / 2), (l || a) && n && (e.scrollLeft = this.offsetLeft - e.offsetLeft - e.clientWidth / 2 - i + this.clientWidth / 2), (s || r || l || a) && !n && this.scrollIntoView(c);\n});\nwindow.requestIdleCallback = window.requestIdleCallback || function(n) {\n const e = Date.now();\n return setTimeout(function() {\n n({\n didTimeout: !1,\n timeRemaining: function() {\n return Math.max(0, 50 - (Date.now() - e));\n }\n });\n }, 1);\n};\nwindow.cancelIdleCallback = window.cancelIdleCallback || function(n) {\n clearTimeout(n);\n};\nlet vo = (n = 21) => crypto.getRandomValues(new Uint8Array(n)).reduce((e, t) => (t &= 63, t < 36 ? e += t.toString(36) : t < 62 ? e += (t - 26).toString(36).toUpperCase() : t > 62 ? e += \"-\" : e += \"_\", e), \"\");\nvar It = /* @__PURE__ */ ((n) => (n.VERBOSE = \"VERBOSE\", n.INFO = \"INFO\", n.WARN = \"WARN\", n.ERROR = \"ERROR\", n))(It || {});\nconst w = {\n BACKSPACE: 8,\n TAB: 9,\n ENTER: 13,\n SHIFT: 16,\n CTRL: 17,\n ALT: 18,\n ESC: 27,\n SPACE: 32,\n LEFT: 37,\n UP: 38,\n DOWN: 40,\n RIGHT: 39,\n DELETE: 46,\n META: 91,\n SLASH: 191\n}, wo = {\n LEFT: 0,\n WHEEL: 1,\n RIGHT: 2,\n BACKWARD: 3,\n FORWARD: 4\n};\nfunction Be(n, e, t = \"log\", o, i = \"color: inherit\") {\n if (!(\"console\" in window) || !window.console[t])\n return;\n const s = [\"info\", \"log\", \"warn\", \"error\"].includes(t), r = [];\n switch (Be.logLevel) {\n case \"ERROR\":\n if (t !== \"error\")\n return;\n break;\n case \"WARN\":\n if (![\"error\", \"warn\"].includes(t))\n return;\n break;\n case \"INFO\":\n if (!s || n)\n return;\n break;\n }\n o && r.push(o);\n const l = \"Editor.js 2.30.7\", a = `line-height: 1em;\n color: #006FEA;\n display: inline-block;\n font-size: 11px;\n line-height: 1em;\n background-color: #fff;\n padding: 4px 9px;\n border-radius: 30px;\n border: 1px solid rgba(56, 138, 229, 0.16);\n margin: 4px 5px 4px 0;`;\n n && (s ? (r.unshift(a, i), e = `%c${l}%c ${e}`) : e = `( ${l} )${e}`);\n try {\n s ? o ? console[t](`${e} %o`, ...r) : console[t](e, ...r) : console[t](e);\n } catch {\n }\n}\nBe.logLevel = \"VERBOSE\";\nfunction xo(n) {\n Be.logLevel = n;\n}\nconst I = Be.bind(window, !1), X = Be.bind(window, !0);\nfunction re(n) {\n return Object.prototype.toString.call(n).match(/\\s([a-zA-Z]+)/)[1].toLowerCase();\n}\nfunction O(n) {\n return re(n) === \"function\" || re(n) === \"asyncfunction\";\n}\nfunction R(n) {\n return re(n) === \"object\";\n}\nfunction Q(n) {\n return re(n) === \"string\";\n}\nfunction yo(n) {\n return re(n) === \"boolean\";\n}\nfunction bt(n) {\n return re(n) === \"number\";\n}\nfunction kt(n) {\n return re(n) === \"undefined\";\n}\nfunction V(n) {\n return n ? Object.keys(n).length === 0 && n.constructor === Object : !0;\n}\nfunction Mt(n) {\n return n > 47 && n < 58 || // number keys\n n === 32 || n === 13 || // Space bar & return key(s)\n n === 229 || // processing key input for certain languages — Chinese, Japanese, etc.\n n > 64 && n < 91 || // letter keys\n n > 95 && n < 112 || // Numpad keys\n n > 185 && n < 193 || // ;=,-./` (in order)\n n > 218 && n < 223;\n}\nasync function Eo(n, e = () => {\n}, t = () => {\n}) {\n async function o(i, s, r) {\n try {\n await i.function(i.data), await s(kt(i.data) ? {} : i.data);\n } catch {\n r(kt(i.data) ? {} : i.data);\n }\n }\n return n.reduce(async (i, s) => (await i, o(s, e, t)), Promise.resolve());\n}\nfunction At(n) {\n return Array.prototype.slice.call(n);\n}\nfunction Oe(n, e) {\n return function() {\n const t = this, o = arguments;\n window.setTimeout(() => n.apply(t, o), e);\n };\n}\nfunction Bo(n) {\n return n.name.split(\".\").pop();\n}\nfunction To(n) {\n return /^[-\\w]+\\/([-+\\w]+|\\*)$/.test(n);\n}\nfunction vt(n, e, t) {\n let o;\n return (...i) => {\n const s = this, r = () => {\n o = null, t || n.apply(s, i);\n }, l = t && !o;\n window.clearTimeout(o), o = window.setTimeout(r, e), l && n.apply(s, i);\n };\n}\nfunction Ve(n, e, t = void 0) {\n let o, i, s, r = null, l = 0;\n t || (t = {});\n const a = function() {\n l = t.leading === !1 ? 0 : Date.now(), r = null, s = n.apply(o, i), r || (o = i = null);\n };\n return function() {\n const c = Date.now();\n !l && t.leading === !1 && (l = c);\n const u = e - (c - l);\n return o = this, i = arguments, u <= 0 || u > e ? (r && (clearTimeout(r), r = null), l = c, s = n.apply(o, i), r || (o = i = null)) : !r && t.trailing !== !1 && (r = setTimeout(a, u)), s;\n };\n}\nfunction Co() {\n const n = {\n win: !1,\n mac: !1,\n x11: !1,\n linux: !1\n }, e = Object.keys(n).find((t) => window.navigator.appVersion.toLowerCase().indexOf(t) !== -1);\n return e && (n[e] = !0), n;\n}\nfunction Le(n) {\n return n[0].toUpperCase() + n.slice(1);\n}\nfunction qe(n, ...e) {\n if (!e.length)\n return n;\n const t = e.shift();\n if (R(n) && R(t))\n for (const o in t)\n R(t[o]) ? (n[o] || Object.assign(n, { [o]: {} }), qe(n[o], t[o])) : Object.assign(n, { [o]: t[o] });\n return qe(n, ...e);\n}\nfunction tt(n) {\n const e = Co();\n return n = n.replace(/shift/gi, \"⇧\").replace(/backspace/gi, \"⌫\").replace(/enter/gi, \"⏎\").replace(/up/gi, \"↑\").replace(/left/gi, \"→\").replace(/down/gi, \"↓\").replace(/right/gi, \"←\").replace(/escape/gi, \"⎋\").replace(/insert/gi, \"Ins\").replace(/delete/gi, \"␡\").replace(/\\+/gi, \" + \"), e.mac ? n = n.replace(/ctrl|cmd/gi, \"⌘\").replace(/alt/gi, \"⌥\") : n = n.replace(/cmd/gi, \"Ctrl\").replace(/windows/gi, \"WIN\"), n;\n}\nfunction So(n) {\n try {\n return new URL(n).href;\n } catch {\n }\n return n.substring(0, 2) === \"//\" ? window.location.protocol + n : window.location.origin + n;\n}\nfunction Io() {\n return vo(10);\n}\nfunction Mo(n) {\n window.open(n, \"_blank\");\n}\nfunction Ao(n = \"\") {\n return `${n}${Math.floor(Math.random() * 1e8).toString(16)}`;\n}\nfunction Ze(n, e, t) {\n const o = `«${e}» is deprecated and will be removed in the next major release. Please use the «${t}» instead.`;\n n && X(o, \"warn\");\n}\nfunction ue(n, e, t) {\n const o = t.value ? \"value\" : \"get\", i = t[o], s = `#${e}Cache`;\n if (t[o] = function(...r) {\n return this[s] === void 0 && (this[s] = i.apply(this, ...r)), this[s];\n }, o === \"get\" && t.set) {\n const r = t.set;\n t.set = function(l) {\n delete n[s], r.apply(this, l);\n };\n }\n return t;\n}\nconst Ot = 650;\nfunction pe() {\n return window.matchMedia(`(max-width: ${Ot}px)`).matches;\n}\nconst Ge = typeof window < \"u\" && window.navigator && window.navigator.platform && (/iP(ad|hone|od)/.test(window.navigator.platform) || window.navigator.platform === \"MacIntel\" && window.navigator.maxTouchPoints > 1);\nfunction Oo(n, e) {\n const t = Array.isArray(n) || R(n), o = Array.isArray(e) || R(e);\n return t || o ? JSON.stringify(n) === JSON.stringify(e) : n === e;\n}\nclass d {\n /**\n * Check if passed tag has no closed tag\n *\n * @param {HTMLElement} tag - element to check\n * @returns {boolean}\n */\n static isSingleTag(e) {\n return e.tagName && [\n \"AREA\",\n \"BASE\",\n \"BR\",\n \"COL\",\n \"COMMAND\",\n \"EMBED\",\n \"HR\",\n \"IMG\",\n \"INPUT\",\n \"KEYGEN\",\n \"LINK\",\n \"META\",\n \"PARAM\",\n \"SOURCE\",\n \"TRACK\",\n \"WBR\"\n ].includes(e.tagName);\n }\n /**\n * Check if element is BR or WBR\n *\n * @param {HTMLElement} element - element to check\n * @returns {boolean}\n */\n static isLineBreakTag(e) {\n return e && e.tagName && [\n \"BR\",\n \"WBR\"\n ].includes(e.tagName);\n }\n /**\n * Helper for making Elements with class name and attributes\n *\n * @param {string} tagName - new Element tag name\n * @param {string[]|string} [classNames] - list or name of CSS class name(s)\n * @param {object} [attributes] - any attributes\n * @returns {HTMLElement}\n */\n static make(e, t = null, o = {}) {\n const i = document.createElement(e);\n if (Array.isArray(t)) {\n const s = t.filter((r) => r !== void 0);\n i.classList.add(...s);\n } else\n t && i.classList.add(t);\n for (const s in o)\n Object.prototype.hasOwnProperty.call(o, s) && (i[s] = o[s]);\n return i;\n }\n /**\n * Creates Text Node with the passed content\n *\n * @param {string} content - text content\n * @returns {Text}\n */\n static text(e) {\n return document.createTextNode(e);\n }\n /**\n * Append one or several elements to the parent\n *\n * @param {Element|DocumentFragment} parent - where to append\n * @param {Element|Element[]|DocumentFragment|Text|Text[]} elements - element or elements list\n */\n static append(e, t) {\n Array.isArray(t) ? t.forEach((o) => e.appendChild(o)) : e.appendChild(t);\n }\n /**\n * Append element or a couple to the beginning of the parent elements\n *\n * @param {Element} parent - where to append\n * @param {Element|Element[]} elements - element or elements list\n */\n static prepend(e, t) {\n Array.isArray(t) ? (t = t.reverse(), t.forEach((o) => e.prepend(o))) : e.prepend(t);\n }\n /**\n * Swap two elements in parent\n *\n * @param {HTMLElement} el1 - from\n * @param {HTMLElement} el2 - to\n * @deprecated\n */\n static swap(e, t) {\n const o = document.createElement(\"div\"), i = e.parentNode;\n i.insertBefore(o, e), i.insertBefore(e, t), i.insertBefore(t, o), i.removeChild(o);\n }\n /**\n * Selector Decorator\n *\n * Returns first match\n *\n * @param {Element} el - element we searching inside. Default - DOM Document\n * @param {string} selector - searching string\n * @returns {Element}\n */\n static find(e = document, t) {\n return e.querySelector(t);\n }\n /**\n * Get Element by Id\n *\n * @param {string} id - id to find\n * @returns {HTMLElement | null}\n */\n static get(e) {\n return document.getElementById(e);\n }\n /**\n * Selector Decorator.\n *\n * Returns all matches\n *\n * @param {Element|Document} el - element we searching inside. Default - DOM Document\n * @param {string} selector - searching string\n * @returns {NodeList}\n */\n static findAll(e = document, t) {\n return e.querySelectorAll(t);\n }\n /**\n * Returns CSS selector for all text inputs\n */\n static get allInputsSelector() {\n return \"[contenteditable=true], textarea, input:not([type]), \" + [\"text\", \"password\", \"email\", \"number\", \"search\", \"tel\", \"url\"].map((t) => `input[type=\"${t}\"]`).join(\", \");\n }\n /**\n * Find all contenteditable, textarea and editable input elements passed holder contains\n *\n * @param holder - element where to find inputs\n */\n static findAllInputs(e) {\n return At(e.querySelectorAll(d.allInputsSelector)).reduce((t, o) => d.isNativeInput(o) || d.containsOnlyInlineElements(o) ? [...t, o] : [...t, ...d.getDeepestBlockElements(o)], []);\n }\n /**\n * Search for deepest node which is Leaf.\n * Leaf is the vertex that doesn't have any child nodes\n *\n * @description Method recursively goes throw the all Node until it finds the Leaf\n * @param {Node} node - root Node. From this vertex we start Deep-first search\n * {@link https://en.wikipedia.org/wiki/Depth-first_search}\n * @param {boolean} [atLast] - find last text node\n * @returns - it can be text Node or Element Node, so that caret will able to work with it\n * Can return null if node is Document or DocumentFragment, or node is not attached to the DOM\n */\n static getDeepestNode(e, t = !1) {\n const o = t ? \"lastChild\" : \"firstChild\", i = t ? \"previousSibling\" : \"nextSibling\";\n if (e && e.nodeType === Node.ELEMENT_NODE && e[o]) {\n let s = e[o];\n if (d.isSingleTag(s) && !d.isNativeInput(s) && !d.isLineBreakTag(s))\n if (s[i])\n s = s[i];\n else if (s.parentNode[i])\n s = s.parentNode[i];\n else\n return s.parentNode;\n return this.getDeepestNode(s, t);\n }\n return e;\n }\n /**\n * Check if object is DOM node\n *\n * @param {*} node - object to check\n * @returns {boolean}\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static isElement(e) {\n return bt(e) ? !1 : e && e.nodeType && e.nodeType === Node.ELEMENT_NODE;\n }\n /**\n * Check if object is DocumentFragment node\n *\n * @param {object} node - object to check\n * @returns {boolean}\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static isFragment(e) {\n return bt(e) ? !1 : e && e.nodeType && e.nodeType === Node.DOCUMENT_FRAGMENT_NODE;\n }\n /**\n * Check if passed element is contenteditable\n *\n * @param {HTMLElement} element - html element to check\n * @returns {boolean}\n */\n static isContentEditable(e) {\n return e.contentEditable === \"true\";\n }\n /**\n * Checks target if it is native input\n *\n * @param {*} target - HTML element or string\n * @returns {boolean}\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n static isNativeInput(e) {\n const t = [\n \"INPUT\",\n \"TEXTAREA\"\n ];\n return e && e.tagName ? t.includes(e.tagName) : !1;\n }\n /**\n * Checks if we can set caret\n *\n * @param {HTMLElement} target - target to check\n * @returns {boolean}\n */\n static canSetCaret(e) {\n let t = !0;\n if (d.isNativeInput(e))\n switch (e.type) {\n case \"file\":\n case \"checkbox\":\n case \"radio\":\n case \"hidden\":\n case \"submit\":\n case \"button\":\n case \"image\":\n case \"reset\":\n t = !1;\n break;\n }\n else\n t = d.isContentEditable(e);\n return t;\n }\n /**\n * Checks node if it is empty\n *\n * @description Method checks simple Node without any childs for emptiness\n * If you have Node with 2 or more children id depth, you better use {@link Dom#isEmpty} method\n * @param {Node} node - node to check\n * @param {string} [ignoreChars] - char or substring to treat as empty\n * @returns {boolean} true if it is empty\n */\n static isNodeEmpty(e, t) {\n let o;\n return this.isSingleTag(e) && !this.isLineBreakTag(e) ? !1 : (this.isElement(e) && this.isNativeInput(e) ? o = e.value : o = e.textContent.replace(\"​\", \"\"), t && (o = o.replace(new RegExp(t, \"g\"), \"\")), o.trim().length === 0);\n }\n /**\n * checks node if it is doesn't have any child nodes\n *\n * @param {Node} node - node to check\n * @returns {boolean}\n */\n static isLeaf(e) {\n return e ? e.childNodes.length === 0 : !1;\n }\n /**\n * breadth-first search (BFS)\n * {@link https://en.wikipedia.org/wiki/Breadth-first_search}\n *\n * @description Pushes to stack all DOM leafs and checks for emptiness\n * @param {Node} node - node to check\n * @param {string} [ignoreChars] - char or substring to treat as empty\n * @returns {boolean}\n */\n static isEmpty(e, t) {\n const o = [e];\n for (; o.length > 0; )\n if (e = o.shift(), !!e) {\n if (this.isLeaf(e) && !this.isNodeEmpty(e, t))\n return !1;\n e.childNodes && o.push(...Array.from(e.childNodes));\n }\n return !0;\n }\n /**\n * Check if string contains html elements\n *\n * @param {string} str - string to check\n * @returns {boolean}\n */\n static isHTMLString(e) {\n const t = d.make(\"div\");\n return t.innerHTML = e, t.childElementCount > 0;\n }\n /**\n * Return length of node`s text content\n *\n * @param {Node} node - node with content\n * @returns {number}\n */\n static getContentLength(e) {\n return d.isNativeInput(e) ? e.value.length : e.nodeType === Node.TEXT_NODE ? e.length : e.textContent.length;\n }\n /**\n * Return array of names of block html elements\n *\n * @returns {string[]}\n */\n static get blockElements() {\n return [\n \"address\",\n \"article\",\n \"aside\",\n \"blockquote\",\n \"canvas\",\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 \"hr\",\n \"li\",\n \"main\",\n \"nav\",\n \"noscript\",\n \"ol\",\n \"output\",\n \"p\",\n \"pre\",\n \"ruby\",\n \"section\",\n \"table\",\n \"tbody\",\n \"thead\",\n \"tr\",\n \"tfoot\",\n \"ul\",\n \"video\"\n ];\n }\n /**\n * Check if passed content includes only inline elements\n *\n * @param {string|HTMLElement} data - element or html string\n * @returns {boolean}\n */\n static containsOnlyInlineElements(e) {\n let t;\n Q(e) ? (t = document.createElement(\"div\"), t.innerHTML = e) : t = e;\n const o = (i) => !d.blockElements.includes(i.tagName.toLowerCase()) && Array.from(i.children).every(o);\n return Array.from(t.children).every(o);\n }\n /**\n * Find and return all block elements in the passed parent (including subtree)\n *\n * @param {HTMLElement} parent - root element\n * @returns {HTMLElement[]}\n */\n static getDeepestBlockElements(e) {\n return d.containsOnlyInlineElements(e) ? [e] : Array.from(e.children).reduce((t, o) => [...t, ...d.getDeepestBlockElements(o)], []);\n }\n /**\n * Helper for get holder from {string} or return HTMLElement\n *\n * @param {string | HTMLElement} element - holder's id or holder's HTML Element\n * @returns {HTMLElement}\n */\n static getHolder(e) {\n return Q(e) ? document.getElementById(e) : e;\n }\n /**\n * Returns true if element is anchor (is A tag)\n *\n * @param {Element} element - element to check\n * @returns {boolean}\n */\n static isAnchor(e) {\n return e.tagName.toLowerCase() === \"a\";\n }\n /**\n * Return element's offset related to the document\n *\n * @todo handle case when editor initialized in scrollable popup\n * @param el - element to compute offset\n */\n static offset(e) {\n const t = e.getBoundingClientRect(), o = window.pageXOffset || document.documentElement.scrollLeft, i = window.pageYOffset || document.documentElement.scrollTop, s = t.top + i, r = t.left + o;\n return {\n top: s,\n left: r,\n bottom: s + t.height,\n right: r + t.width\n };\n }\n}\nfunction Lo(n) {\n return !/[^\\t\\n\\r ]/.test(n);\n}\nfunction _o(n) {\n const e = window.getComputedStyle(n), t = parseFloat(e.fontSize), o = parseFloat(e.lineHeight) || t * 1.2, i = parseFloat(e.paddingTop), s = parseFloat(e.borderTopWidth), r = parseFloat(e.marginTop), l = t * 0.8, a = (o - t) / 2;\n return r + s + i + a + l;\n}\nfunction Lt(n) {\n n.dataset.empty = d.isEmpty(n) ? \"true\" : \"false\";\n}\nconst No = {\n blockTunes: {\n toggler: {\n \"Click to tune\": \"\",\n \"or drag to move\": \"\"\n }\n },\n inlineToolbar: {\n converter: {\n \"Convert to\": \"\"\n }\n },\n toolbar: {\n toolbox: {\n Add: \"\"\n }\n },\n popover: {\n Filter: \"\",\n \"Nothing found\": \"\",\n \"Convert to\": \"\"\n }\n}, Po = {\n Text: \"\",\n Link: \"\",\n Bold: \"\",\n Italic: \"\"\n}, Do = {\n link: {\n \"Add a link\": \"\"\n },\n stub: {\n \"The block can not be displayed correctly.\": \"\"\n }\n}, Ro = {\n delete: {\n Delete: \"\",\n \"Click to delete\": \"\"\n },\n moveUp: {\n \"Move up\": \"\"\n },\n moveDown: {\n \"Move down\": \"\"\n }\n}, _t = {\n ui: No,\n toolNames: Po,\n tools: Do,\n blockTunes: Ro\n}, Nt = class ae {\n /**\n * Type-safe translation for internal UI texts:\n * Perform translation of the string by namespace and a key\n *\n * @example I18n.ui(I18nInternalNS.ui.blockTunes.toggler, 'Click to tune')\n * @param internalNamespace - path to translated string in dictionary\n * @param dictKey - dictionary key. Better to use default locale original text\n */\n static ui(e, t) {\n return ae._t(e, t);\n }\n /**\n * Translate for external strings that is not presented in default dictionary.\n * For example, for user-specified tool names\n *\n * @param namespace - path to translated string in dictionary\n * @param dictKey - dictionary key. Better to use default locale original text\n */\n static t(e, t) {\n return ae._t(e, t);\n }\n /**\n * Adjust module for using external dictionary\n *\n * @param dictionary - new messages list to override default\n */\n static setDictionary(e) {\n ae.currentDictionary = e;\n }\n /**\n * Perform translation both for internal and external namespaces\n * If there is no translation found, returns passed key as a translated message\n *\n * @param namespace - path to translated string in dictionary\n * @param dictKey - dictionary key. Better to use default locale original text\n */\n static _t(e, t) {\n const o = ae.getNamespace(e);\n return !o || !o[t] ? t : o[t];\n }\n /**\n * Find messages section by namespace path\n *\n * @param namespace - path to section\n */\n static getNamespace(e) {\n return e.split(\".\").reduce((o, i) => !o || !Object.keys(o).length ? {} : o[i], ae.currentDictionary);\n }\n};\nNt.currentDictionary = _t;\nlet z = Nt;\nclass Pt extends Error {\n}\nclass Te {\n constructor() {\n this.subscribers = {};\n }\n /**\n * Subscribe any event on callback\n *\n * @param eventName - event name\n * @param callback - subscriber\n */\n on(e, t) {\n e in this.subscribers || (this.subscribers[e] = []), this.subscribers[e].push(t);\n }\n /**\n * Subscribe any event on callback. Callback will be called once and be removed from subscribers array after call.\n *\n * @param eventName - event name\n * @param callback - subscriber\n */\n once(e, t) {\n e in this.subscribers || (this.subscribers[e] = []);\n const o = (i) => {\n const s = t(i), r = this.subscribers[e].indexOf(o);\n return r !== -1 && this.subscribers[e].splice(r, 1), s;\n };\n this.subscribers[e].push(o);\n }\n /**\n * Emit callbacks with passed data\n *\n * @param eventName - event name\n * @param data - subscribers get this data when they were fired\n */\n emit(e, t) {\n V(this.subscribers) || !this.subscribers[e] || this.subscribers[e].reduce((o, i) => {\n const s = i(o);\n return s !== void 0 ? s : o;\n }, t);\n }\n /**\n * Unsubscribe callback from event\n *\n * @param eventName - event name\n * @param callback - event handler\n */\n off(e, t) {\n if (this.subscribers[e] === void 0) {\n console.warn(`EventDispatcher .off(): there is no subscribers for event \"${e.toString()}\". Probably, .off() called before .on()`);\n return;\n }\n for (let o = 0; o < this.subscribers[e].length; o++)\n if (this.subscribers[e][o] === t) {\n delete this.subscribers[e][o];\n break;\n }\n }\n /**\n * Destroyer\n * clears subscribers list\n */\n destroy() {\n this.subscribers = {};\n }\n}\nfunction G(n) {\n Object.setPrototypeOf(this, {\n /**\n * Block id\n *\n * @returns {string}\n */\n get id() {\n return n.id;\n },\n /**\n * Tool name\n *\n * @returns {string}\n */\n get name() {\n return n.name;\n },\n /**\n * Tool config passed on Editor's initialization\n *\n * @returns {ToolConfig}\n */\n get config() {\n return n.config;\n },\n /**\n * .ce-block element, that wraps plugin contents\n *\n * @returns {HTMLElement}\n */\n get holder() {\n return n.holder;\n },\n /**\n * True if Block content is empty\n *\n * @returns {boolean}\n */\n get isEmpty() {\n return n.isEmpty;\n },\n /**\n * True if Block is selected with Cross-Block selection\n *\n * @returns {boolean}\n */\n get selected() {\n return n.selected;\n },\n /**\n * Set Block's stretch state\n *\n * @param {boolean} state — state to set\n */\n set stretched(t) {\n n.stretched = t;\n },\n /**\n * True if Block is stretched\n *\n * @returns {boolean}\n */\n get stretched() {\n return n.stretched;\n },\n /**\n * True if Block has inputs to be focused\n */\n get focusable() {\n return n.focusable;\n },\n /**\n * Call Tool method with errors handler under-the-hood\n *\n * @param {string} methodName - method to call\n * @param {object} param - object with parameters\n * @returns {unknown}\n */\n call(t, o) {\n return n.call(t, o);\n },\n /**\n * Save Block content\n *\n * @returns {Promise}\n */\n save() {\n return n.save();\n },\n /**\n * Validate Block data\n *\n * @param {BlockToolData} data - data to validate\n * @returns {Promise}\n */\n validate(t) {\n return n.validate(t);\n },\n /**\n * Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback\n * Can be useful for block changes invisible for editor core.\n */\n dispatchChange() {\n n.dispatchChange();\n },\n /**\n * Tool could specify several entries to be displayed at the Toolbox (for example, \"Heading 1\", \"Heading 2\", \"Heading 3\")\n * This method returns the entry that is related to the Block (depended on the Block data)\n */\n getActiveToolboxEntry() {\n return n.getActiveToolboxEntry();\n }\n });\n}\nclass Ce {\n constructor() {\n this.allListeners = [];\n }\n /**\n * Assigns event listener on element and returns unique identifier\n *\n * @param {EventTarget} element - DOM element that needs to be listened\n * @param {string} eventType - event type\n * @param {Function} handler - method that will be fired on event\n * @param {boolean|AddEventListenerOptions} options - useCapture or {capture, passive, once}\n */\n on(e, t, o, i = !1) {\n const s = Ao(\"l\"), r = {\n id: s,\n element: e,\n eventType: t,\n handler: o,\n options: i\n };\n if (!this.findOne(e, t, o))\n return this.allListeners.push(r), e.addEventListener(t, o, i), s;\n }\n /**\n * Removes event listener from element\n *\n * @param {EventTarget} element - DOM element that we removing listener\n * @param {string} eventType - event type\n * @param {Function} handler - remove handler, if element listens several handlers on the same event type\n * @param {boolean|AddEventListenerOptions} options - useCapture or {capture, passive, once}\n */\n off(e, t, o, i) {\n const s = this.findAll(e, t, o);\n s.forEach((r, l) => {\n const a = this.allListeners.indexOf(s[l]);\n a > -1 && (this.allListeners.splice(a, 1), r.element.removeEventListener(r.eventType, r.handler, r.options));\n });\n }\n /**\n * Removes listener by id\n *\n * @param {string} id - listener identifier\n */\n offById(e) {\n const t = this.findById(e);\n t && t.element.removeEventListener(t.eventType, t.handler, t.options);\n }\n /**\n * Finds and returns first listener by passed params\n *\n * @param {EventTarget} element - event target\n * @param {string} [eventType] - event type\n * @param {Function} [handler] - event handler\n * @returns {ListenerData|null}\n */\n findOne(e, t, o) {\n const i = this.findAll(e, t, o);\n return i.length > 0 ? i[0] : null;\n }\n /**\n * Return all stored listeners by passed params\n *\n * @param {EventTarget} element - event target\n * @param {string} eventType - event type\n * @param {Function} handler - event handler\n * @returns {ListenerData[]}\n */\n findAll(e, t, o) {\n let i;\n const s = e ? this.findByEventTarget(e) : [];\n return e && t && o ? i = s.filter((r) => r.eventType === t && r.handler === o) : e && t ? i = s.filter((r) => r.eventType === t) : i = s, i;\n }\n /**\n * Removes all listeners\n */\n removeAll() {\n this.allListeners.map((e) => {\n e.element.removeEventListener(e.eventType, e.handler, e.options);\n }), this.allListeners = [];\n }\n /**\n * Module cleanup on destruction\n */\n destroy() {\n this.removeAll();\n }\n /**\n * Search method: looks for listener by passed element\n *\n * @param {EventTarget} element - searching element\n * @returns {Array} listeners that found on element\n */\n findByEventTarget(e) {\n return this.allListeners.filter((t) => {\n if (t.element === e)\n return t;\n });\n }\n /**\n * Search method: looks for listener by passed event type\n *\n * @param {string} eventType - event type\n * @returns {ListenerData[]} listeners that found on element\n */\n findByType(e) {\n return this.allListeners.filter((t) => {\n if (t.eventType === e)\n return t;\n });\n }\n /**\n * Search method: looks for listener by passed handler\n *\n * @param {Function} handler - event handler\n * @returns {ListenerData[]} listeners that found on element\n */\n findByHandler(e) {\n return this.allListeners.filter((t) => {\n if (t.handler === e)\n return t;\n });\n }\n /**\n * Returns listener data found by id\n *\n * @param {string} id - listener identifier\n * @returns {ListenerData}\n */\n findById(e) {\n return this.allListeners.find((t) => t.id === e);\n }\n}\nclass y {\n /**\n * @class\n * @param options - Module options\n * @param options.config - Module config\n * @param options.eventsDispatcher - Common event bus\n */\n constructor({ config: e, eventsDispatcher: t }) {\n if (this.nodes = {}, this.listeners = new Ce(), this.readOnlyMutableListeners = {\n /**\n * Assigns event listener on DOM element and pushes into special array that might be removed\n *\n * @param {EventTarget} element - DOM Element\n * @param {string} eventType - Event name\n * @param {Function} handler - Event handler\n * @param {boolean|AddEventListenerOptions} options - Listening options\n */\n on: (o, i, s, r = !1) => {\n this.mutableListenerIds.push(\n this.listeners.on(o, i, s, r)\n );\n },\n /**\n * Clears all mutable listeners\n */\n clearAll: () => {\n for (const o of this.mutableListenerIds)\n this.listeners.offById(o);\n this.mutableListenerIds = [];\n }\n }, this.mutableListenerIds = [], new.target === y)\n throw new TypeError(\"Constructors for abstract class Module are not allowed.\");\n this.config = e, this.eventsDispatcher = t;\n }\n /**\n * Editor modules setter\n *\n * @param {EditorModules} Editor - Editor's Modules\n */\n set state(e) {\n this.Editor = e;\n }\n /**\n * Remove memorized nodes\n */\n removeAllNodes() {\n for (const e in this.nodes) {\n const t = this.nodes[e];\n t instanceof HTMLElement && t.remove();\n }\n }\n /**\n * Returns true if current direction is RTL (Right-To-Left)\n */\n get isRtl() {\n return this.config.i18n.direction === \"rtl\";\n }\n}\nclass b {\n constructor() {\n this.instance = null, this.selection = null, this.savedSelectionRange = null, this.isFakeBackgroundEnabled = !1, this.commandBackground = \"backColor\", this.commandRemoveFormat = \"removeFormat\";\n }\n /**\n * Editor styles\n *\n * @returns {{editorWrapper: string, editorZone: string}}\n */\n static get CSS() {\n return {\n editorWrapper: \"codex-editor\",\n editorZone: \"codex-editor__redactor\"\n };\n }\n /**\n * Returns selected anchor\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorNode}\n *\n * @returns {Node|null}\n */\n static get anchorNode() {\n const e = window.getSelection();\n return e ? e.anchorNode : null;\n }\n /**\n * Returns selected anchor element\n *\n * @returns {Element|null}\n */\n static get anchorElement() {\n const e = window.getSelection();\n if (!e)\n return null;\n const t = e.anchorNode;\n return t ? d.isElement(t) ? t : t.parentElement : null;\n }\n /**\n * Returns selection offset according to the anchor node\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Selection/anchorOffset}\n *\n * @returns {number|null}\n */\n static get anchorOffset() {\n const e = window.getSelection();\n return e ? e.anchorOffset : null;\n }\n /**\n * Is current selection range collapsed\n *\n * @returns {boolean|null}\n */\n static get isCollapsed() {\n const e = window.getSelection();\n return e ? e.isCollapsed : null;\n }\n /**\n * Check current selection if it is at Editor's zone\n *\n * @returns {boolean}\n */\n static get isAtEditor() {\n return this.isSelectionAtEditor(b.get());\n }\n /**\n * Check if passed selection is at Editor's zone\n *\n * @param selection - Selection object to check\n */\n static isSelectionAtEditor(e) {\n if (!e)\n return !1;\n let t = e.anchorNode || e.focusNode;\n t && t.nodeType === Node.TEXT_NODE && (t = t.parentNode);\n let o = null;\n return t && t instanceof Element && (o = t.closest(`.${b.CSS.editorZone}`)), o ? o.nodeType === Node.ELEMENT_NODE : !1;\n }\n /**\n * Check if passed range at Editor zone\n *\n * @param range - range to check\n */\n static isRangeAtEditor(e) {\n if (!e)\n return;\n let t = e.startContainer;\n t && t.nodeType === Node.TEXT_NODE && (t = t.parentNode);\n let o = null;\n return t && t instanceof Element && (o = t.closest(`.${b.CSS.editorZone}`)), o ? o.nodeType === Node.ELEMENT_NODE : !1;\n }\n /**\n * Methods return boolean that true if selection exists on the page\n */\n static get isSelectionExists() {\n return !!b.get().anchorNode;\n }\n /**\n * Return first range\n *\n * @returns {Range|null}\n */\n static get range() {\n return this.getRangeFromSelection(this.get());\n }\n /**\n * Returns range from passed Selection object\n *\n * @param selection - Selection object to get Range from\n */\n static getRangeFromSelection(e) {\n return e && e.rangeCount ? e.getRangeAt(0) : null;\n }\n /**\n * Calculates position and size of selected text\n *\n * @returns {DOMRect | ClientRect}\n */\n static get rect() {\n let e = document.selection, t, o = {\n x: 0,\n y: 0,\n width: 0,\n height: 0\n };\n if (e && e.type !== \"Control\")\n return e = e, t = e.createRange(), o.x = t.boundingLeft, o.y = t.boundingTop, o.width = t.boundingWidth, o.height = t.boundingHeight, o;\n if (!window.getSelection)\n return I(\"Method window.getSelection is not supported\", \"warn\"), o;\n if (e = window.getSelection(), e.rangeCount === null || isNaN(e.rangeCount))\n return I(\"Method SelectionUtils.rangeCount is not supported\", \"warn\"), o;\n if (e.rangeCount === 0)\n return o;\n if (t = e.getRangeAt(0).cloneRange(), t.getBoundingClientRect && (o = t.getBoundingClientRect()), o.x === 0 && o.y === 0) {\n const i = document.createElement(\"span\");\n if (i.getBoundingClientRect) {\n i.appendChild(document.createTextNode(\"​\")), t.insertNode(i), o = i.getBoundingClientRect();\n const s = i.parentNode;\n s.removeChild(i), s.normalize();\n }\n }\n return o;\n }\n /**\n * Returns selected text as String\n *\n * @returns {string}\n */\n static get text() {\n return window.getSelection ? window.getSelection().toString() : \"\";\n }\n /**\n * Returns window SelectionUtils\n * {@link https://developer.mozilla.org/ru/docs/Web/API/Window/getSelection}\n *\n * @returns {Selection}\n */\n static get() {\n return window.getSelection();\n }\n /**\n * Set focus to contenteditable or native input element\n *\n * @param element - element where to set focus\n * @param offset - offset of cursor\n */\n static setCursor(e, t = 0) {\n const o = document.createRange(), i = window.getSelection();\n return d.isNativeInput(e) ? d.canSetCaret(e) ? (e.focus(), e.selectionStart = e.selectionEnd = t, e.getBoundingClientRect()) : void 0 : (o.setStart(e, t), o.setEnd(e, t), i.removeAllRanges(), i.addRange(o), o.getBoundingClientRect());\n }\n /**\n * Check if current range exists and belongs to container\n *\n * @param container - where range should be\n */\n static isRangeInsideContainer(e) {\n const t = b.range;\n return t === null ? !1 : e.contains(t.startContainer);\n }\n /**\n * Adds fake cursor to the current range\n */\n static addFakeCursor() {\n const e = b.range;\n if (e === null)\n return;\n const t = d.make(\"span\", \"codex-editor__fake-cursor\");\n t.dataset.mutationFree = \"true\", e.collapse(), e.insertNode(t);\n }\n /**\n * Check if passed element contains a fake cursor\n *\n * @param el - where to check\n */\n static isFakeCursorInsideContainer(e) {\n return d.find(e, \".codex-editor__fake-cursor\") !== null;\n }\n /**\n * Removes fake cursor from a container\n *\n * @param container - container to look for\n */\n static removeFakeCursor(e = document.body) {\n const t = d.find(e, \".codex-editor__fake-cursor\");\n t && t.remove();\n }\n /**\n * Removes fake background\n */\n removeFakeBackground() {\n this.isFakeBackgroundEnabled && (this.isFakeBackgroundEnabled = !1, document.execCommand(this.commandRemoveFormat));\n }\n /**\n * Sets fake background\n */\n setFakeBackground() {\n document.execCommand(this.commandBackground, !1, \"#a8d6ff\"), this.isFakeBackgroundEnabled = !0;\n }\n /**\n * Save SelectionUtils's range\n */\n save() {\n this.savedSelectionRange = b.range;\n }\n /**\n * Restore saved SelectionUtils's range\n */\n restore() {\n if (!this.savedSelectionRange)\n return;\n const e = window.getSelection();\n e.removeAllRanges(), e.addRange(this.savedSelectionRange);\n }\n /**\n * Clears saved selection\n */\n clearSaved() {\n this.savedSelectionRange = null;\n }\n /**\n * Collapse current selection\n */\n collapseToEnd() {\n const e = window.getSelection(), t = document.createRange();\n t.selectNodeContents(e.focusNode), t.collapse(!1), e.removeAllRanges(), e.addRange(t);\n }\n /**\n * Looks ahead to find passed tag from current selection\n *\n * @param {string} tagName - tag to found\n * @param {string} [className] - tag's class name\n * @param {number} [searchDepth] - count of tags that can be included. For better performance.\n * @returns {HTMLElement|null}\n */\n findParentTag(e, t, o = 10) {\n const i = window.getSelection();\n let s = null;\n return !i || !i.anchorNode || !i.focusNode ? null : ([\n /** the Node in which the selection begins */\n i.anchorNode,\n /** the Node in which the selection ends */\n i.focusNode\n ].forEach((l) => {\n let a = o;\n for (; a > 0 && l.parentNode && !(l.tagName === e && (s = l, t && l.classList && !l.classList.contains(t) && (s = null), s)); )\n l = l.parentNode, a--;\n }), s);\n }\n /**\n * Expands selection range to the passed parent node\n *\n * @param {HTMLElement} element - element which contents should be selected\n */\n expandToTag(e) {\n const t = window.getSelection();\n t.removeAllRanges();\n const o = document.createRange();\n o.selectNodeContents(e), t.addRange(o);\n }\n}\nfunction Fo(n, e) {\n const { type: t, target: o, addedNodes: i, removedNodes: s } = n;\n return n.type === \"attributes\" && n.attributeName === \"data-empty\" ? !1 : !!(e.contains(o) || t === \"childList\" && (Array.from(i).some((a) => a === e) || Array.from(s).some((a) => a === e)));\n}\nconst Je = \"redactor dom changed\", Dt = \"block changed\", Rt = \"fake cursor is about to be toggled\", Ft = \"fake cursor have been set\", ye = \"editor mobile layout toggled\";\nfunction Qe(n, e) {\n if (!n.conversionConfig)\n return !1;\n const t = n.conversionConfig[e];\n return O(t) || Q(t);\n}\nfunction _e(n, e) {\n return Qe(n.tool, e);\n}\nfunction Ht(n, e) {\n return Object.entries(n).some(([t, o]) => e[t] && Oo(e[t], o));\n}\nasync function zt(n, e) {\n const o = (await n.save()).data, i = e.find((s) => s.name === n.name);\n return i !== void 0 && !Qe(i, \"export\") ? [] : e.reduce((s, r) => {\n if (!Qe(r, \"import\") || r.toolbox === void 0)\n return s;\n const l = r.toolbox.filter((a) => {\n if (V(a) || a.icon === void 0)\n return !1;\n if (a.data !== void 0) {\n if (Ht(a.data, o))\n return !1;\n } else if (r.name === n.name)\n return !1;\n return !0;\n });\n return s.push({\n ...r,\n toolbox: l\n }), s;\n }, []);\n}\nfunction wt(n, e) {\n return n.mergeable ? n.name === e.name ? !0 : _e(e, \"export\") && _e(n, \"import\") : !1;\n}\nfunction Ho(n, e) {\n const t = e == null ? void 0 : e.export;\n return O(t) ? t(n) : Q(t) ? n[t] : (t !== void 0 && I(\"Conversion «export» property must be a string or function. String means key of saved data object to export. Function should export processed string to export.\"), \"\");\n}\nfunction xt(n, e) {\n const t = e == null ? void 0 : e.import;\n return O(t) ? t(n) : Q(t) ? {\n [t]: n\n } : (t !== void 0 && I(\"Conversion «import» property must be a string or function. String means key of tool data to import. Function accepts a imported string and return composed tool data.\"), {});\n}\nvar A = /* @__PURE__ */ ((n) => (n.Default = \"default\", n.Separator = \"separator\", n.Html = \"html\", n))(A || {}), J = /* @__PURE__ */ ((n) => (n.APPEND_CALLBACK = \"appendCallback\", n.RENDERED = \"rendered\", n.MOVED = \"moved\", n.UPDATED = \"updated\", n.REMOVED = \"removed\", n.ON_PASTE = \"onPaste\", n))(J || {});\nclass D extends Te {\n /**\n * @param options - block constructor options\n * @param [options.id] - block's id. Will be generated if omitted.\n * @param options.data - Tool's initial data\n * @param options.tool — block's tool\n * @param options.api - Editor API module for pass it to the Block Tunes\n * @param options.readOnly - Read-Only flag\n * @param [eventBus] - Editor common event bus. Allows to subscribe on some Editor events. Could be omitted when \"virtual\" Block is created. See BlocksAPI@composeBlockData.\n */\n constructor({\n id: e = Io(),\n data: t,\n tool: o,\n readOnly: i,\n tunesData: s\n }, r) {\n super(), this.cachedInputs = [], this.toolRenderedElement = null, this.tunesInstances = /* @__PURE__ */ new Map(), this.defaultTunesInstances = /* @__PURE__ */ new Map(), this.unavailableTunesData = {}, this.inputIndex = 0, this.editorEventBus = null, this.handleFocus = () => {\n this.dropInputsCache(), this.updateCurrentInput();\n }, this.didMutated = (l = void 0) => {\n const a = l === void 0, c = l instanceof InputEvent;\n !a && !c && this.detectToolRootChange(l);\n let u;\n a || c ? u = !0 : u = !(l.length > 0 && l.every((p) => {\n const { addedNodes: g, removedNodes: f, target: k } = p;\n return [\n ...Array.from(g),\n ...Array.from(f),\n k\n ].some((S) => (d.isElement(S) || (S = S.parentElement), S && S.closest('[data-mutation-free=\"true\"]') !== null));\n })), u && (this.dropInputsCache(), this.updateCurrentInput(), this.toggleInputsEmptyMark(), this.call(\n \"updated\"\n /* UPDATED */\n ), this.emit(\"didMutated\", this));\n }, this.name = o.name, this.id = e, this.settings = o.settings, this.config = o.settings.config || {}, this.editorEventBus = r || null, this.blockAPI = new G(this), this.tool = o, this.toolInstance = o.create(t, this.blockAPI, i), this.tunes = o.tunes, this.composeTunes(s), this.holder = this.compose(), window.requestIdleCallback(() => {\n this.watchBlockMutations(), this.addInputEvents(), this.toggleInputsEmptyMark();\n });\n }\n /**\n * CSS classes for the Block\n *\n * @returns {{wrapper: string, content: string}}\n */\n static get CSS() {\n return {\n wrapper: \"ce-block\",\n wrapperStretched: \"ce-block--stretched\",\n content: \"ce-block__content\",\n selected: \"ce-block--selected\",\n dropTarget: \"ce-block--drop-target\"\n };\n }\n /**\n * Find and return all editable elements (contenteditable and native inputs) in the Tool HTML\n */\n get inputs() {\n if (this.cachedInputs.length !== 0)\n return this.cachedInputs;\n const e = d.findAllInputs(this.holder);\n return this.inputIndex > e.length - 1 && (this.inputIndex = e.length - 1), this.cachedInputs = e, e;\n }\n /**\n * Return current Tool`s input\n * If Block doesn't contain inputs, return undefined\n */\n get currentInput() {\n return this.inputs[this.inputIndex];\n }\n /**\n * Set input index to the passed element\n *\n * @param element - HTML Element to set as current input\n */\n set currentInput(e) {\n const t = this.inputs.findIndex((o) => o === e || o.contains(e));\n t !== -1 && (this.inputIndex = t);\n }\n /**\n * Return first Tool`s input\n * If Block doesn't contain inputs, return undefined\n */\n get firstInput() {\n return this.inputs[0];\n }\n /**\n * Return first Tool`s input\n * If Block doesn't contain inputs, return undefined\n */\n get lastInput() {\n const e = this.inputs;\n return e[e.length - 1];\n }\n /**\n * Return next Tool`s input or undefined if it doesn't exist\n * If Block doesn't contain inputs, return undefined\n */\n get nextInput() {\n return this.inputs[this.inputIndex + 1];\n }\n /**\n * Return previous Tool`s input or undefined if it doesn't exist\n * If Block doesn't contain inputs, return undefined\n */\n get previousInput() {\n return this.inputs[this.inputIndex - 1];\n }\n /**\n * Get Block's JSON data\n *\n * @returns {object}\n */\n get data() {\n return this.save().then((e) => e && !V(e.data) ? e.data : {});\n }\n /**\n * Returns tool's sanitizer config\n *\n * @returns {object}\n */\n get sanitize() {\n return this.tool.sanitizeConfig;\n }\n /**\n * is block mergeable\n * We plugin have merge function then we call it mergeable\n *\n * @returns {boolean}\n */\n get mergeable() {\n return O(this.toolInstance.merge);\n }\n /**\n * If Block contains inputs, it is focusable\n */\n get focusable() {\n return this.inputs.length !== 0;\n }\n /**\n * Check block for emptiness\n *\n * @returns {boolean}\n */\n get isEmpty() {\n const e = d.isEmpty(this.pluginsContent, \"/\"), t = !this.hasMedia;\n return e && t;\n }\n /**\n * Check if block has a media content such as images, iframe and other\n *\n * @returns {boolean}\n */\n get hasMedia() {\n const e = [\n \"img\",\n \"iframe\",\n \"video\",\n \"audio\",\n \"source\",\n \"input\",\n \"textarea\",\n \"twitterwidget\"\n ];\n return !!this.holder.querySelector(e.join(\",\"));\n }\n /**\n * Set selected state\n * We don't need to mark Block as Selected when it is empty\n *\n * @param {boolean} state - 'true' to select, 'false' to remove selection\n */\n set selected(e) {\n var i, s;\n this.holder.classList.toggle(D.CSS.selected, e);\n const t = e === !0 && b.isRangeInsideContainer(this.holder), o = e === !1 && b.isFakeCursorInsideContainer(this.holder);\n (t || o) && ((i = this.editorEventBus) == null || i.emit(Rt, { state: e }), t ? b.addFakeCursor() : b.removeFakeCursor(this.holder), (s = this.editorEventBus) == null || s.emit(Ft, { state: e }));\n }\n /**\n * Returns True if it is Selected\n *\n * @returns {boolean}\n */\n get selected() {\n return this.holder.classList.contains(D.CSS.selected);\n }\n /**\n * Set stretched state\n *\n * @param {boolean} state - 'true' to enable, 'false' to disable stretched state\n */\n set stretched(e) {\n this.holder.classList.toggle(D.CSS.wrapperStretched, e);\n }\n /**\n * Return Block's stretched state\n *\n * @returns {boolean}\n */\n get stretched() {\n return this.holder.classList.contains(D.CSS.wrapperStretched);\n }\n /**\n * Toggle drop target state\n *\n * @param {boolean} state - 'true' if block is drop target, false otherwise\n */\n set dropTarget(e) {\n this.holder.classList.toggle(D.CSS.dropTarget, e);\n }\n /**\n * Returns Plugins content\n *\n * @returns {HTMLElement}\n */\n get pluginsContent() {\n return this.toolRenderedElement;\n }\n /**\n * Calls Tool's method\n *\n * Method checks tool property {MethodName}. Fires method with passes params If it is instance of Function\n *\n * @param {string} methodName - method to call\n * @param {object} params - method argument\n */\n call(e, t) {\n if (O(this.toolInstance[e])) {\n e === \"appendCallback\" && I(\n \"`appendCallback` hook is deprecated and will be removed in the next major release. Use `rendered` hook instead\",\n \"warn\"\n );\n try {\n this.toolInstance[e].call(this.toolInstance, t);\n } catch (o) {\n I(`Error during '${e}' call: ${o.message}`, \"error\");\n }\n }\n }\n /**\n * Call plugins merge method\n *\n * @param {BlockToolData} data - data to merge\n */\n async mergeWith(e) {\n await this.toolInstance.merge(e);\n }\n /**\n * Extracts data from Block\n * Groups Tool's save processing time\n *\n * @returns {object}\n */\n async save() {\n const e = await this.toolInstance.save(this.pluginsContent), t = this.unavailableTunesData;\n [\n ...this.tunesInstances.entries(),\n ...this.defaultTunesInstances.entries()\n ].forEach(([s, r]) => {\n if (O(r.save))\n try {\n t[s] = r.save();\n } catch (l) {\n I(`Tune ${r.constructor.name} save method throws an Error %o`, \"warn\", l);\n }\n });\n const o = window.performance.now();\n let i;\n return Promise.resolve(e).then((s) => (i = window.performance.now(), {\n id: this.id,\n tool: this.name,\n data: s,\n tunes: t,\n time: i - o\n })).catch((s) => {\n I(`Saving process for ${this.name} tool failed due to the ${s}`, \"log\", \"red\");\n });\n }\n /**\n * Uses Tool's validation method to check the correctness of output data\n * Tool's validation method is optional\n *\n * @description Method returns true|false whether data passed the validation or not\n * @param {BlockToolData} data - data to validate\n * @returns {Promise} valid\n */\n async validate(e) {\n let t = !0;\n return this.toolInstance.validate instanceof Function && (t = await this.toolInstance.validate(e)), t;\n }\n /**\n * Returns data to render in Block Tunes menu.\n * Splits block tunes into 2 groups: block specific tunes and common tunes\n */\n getTunes() {\n const e = [], t = [], o = typeof this.toolInstance.renderSettings == \"function\" ? this.toolInstance.renderSettings() : [];\n return d.isElement(o) ? e.push({\n type: A.Html,\n element: o\n }) : Array.isArray(o) ? e.push(...o) : e.push(o), [\n ...this.tunesInstances.values(),\n ...this.defaultTunesInstances.values()\n ].map((s) => s.render()).forEach((s) => {\n d.isElement(s) ? t.push({\n type: A.Html,\n element: s\n }) : Array.isArray(s) ? t.push(...s) : t.push(s);\n }), {\n toolTunes: e,\n commonTunes: t\n };\n }\n /**\n * Update current input index with selection anchor node\n */\n updateCurrentInput() {\n this.currentInput = d.isNativeInput(document.activeElement) || !b.anchorNode ? document.activeElement : b.anchorNode;\n }\n /**\n * Allows to say Editor that Block was changed. Used to manually trigger Editor's 'onChange' callback\n * Can be useful for block changes invisible for editor core.\n */\n dispatchChange() {\n this.didMutated();\n }\n /**\n * Call Tool instance destroy method\n */\n destroy() {\n this.unwatchBlockMutations(), this.removeInputEvents(), super.destroy(), O(this.toolInstance.destroy) && this.toolInstance.destroy();\n }\n /**\n * Tool could specify several entries to be displayed at the Toolbox (for example, \"Heading 1\", \"Heading 2\", \"Heading 3\")\n * This method returns the entry that is related to the Block (depended on the Block data)\n */\n async getActiveToolboxEntry() {\n const e = this.tool.toolbox;\n if (e.length === 1)\n return Promise.resolve(this.tool.toolbox[0]);\n const t = await this.data, o = e;\n return o == null ? void 0 : o.find((i) => Ht(i.data, t));\n }\n /**\n * Exports Block data as string using conversion config\n */\n async exportDataAsString() {\n const e = await this.data;\n return Ho(e, this.tool.conversionConfig);\n }\n /**\n * Make default Block wrappers and put Tool`s content there\n *\n * @returns {HTMLDivElement}\n */\n compose() {\n const e = d.make(\"div\", D.CSS.wrapper), t = d.make(\"div\", D.CSS.content), o = this.toolInstance.render();\n e.dataset.id = this.id, this.toolRenderedElement = o, t.appendChild(this.toolRenderedElement);\n let i = t;\n return [...this.tunesInstances.values(), ...this.defaultTunesInstances.values()].forEach((s) => {\n if (O(s.wrap))\n try {\n i = s.wrap(i);\n } catch (r) {\n I(`Tune ${s.constructor.name} wrap method throws an Error %o`, \"warn\", r);\n }\n }), e.appendChild(i), e;\n }\n /**\n * Instantiate Block Tunes\n *\n * @param tunesData - current Block tunes data\n * @private\n */\n composeTunes(e) {\n Array.from(this.tunes.values()).forEach((t) => {\n (t.isInternal ? this.defaultTunesInstances : this.tunesInstances).set(t.name, t.create(e[t.name], this.blockAPI));\n }), Object.entries(e).forEach(([t, o]) => {\n this.tunesInstances.has(t) || (this.unavailableTunesData[t] = o);\n });\n }\n /**\n * Adds focus event listeners to all inputs and contenteditable\n */\n addInputEvents() {\n this.inputs.forEach((e) => {\n e.addEventListener(\"focus\", this.handleFocus), d.isNativeInput(e) && e.addEventListener(\"input\", this.didMutated);\n });\n }\n /**\n * removes focus event listeners from all inputs and contenteditable\n */\n removeInputEvents() {\n this.inputs.forEach((e) => {\n e.removeEventListener(\"focus\", this.handleFocus), d.isNativeInput(e) && e.removeEventListener(\"input\", this.didMutated);\n });\n }\n /**\n * Listen common editor Dom Changed event and detect mutations related to the Block\n */\n watchBlockMutations() {\n var e;\n this.redactorDomChangedCallback = (t) => {\n const { mutations: o } = t;\n o.some((s) => Fo(s, this.toolRenderedElement)) && this.didMutated(o);\n }, (e = this.editorEventBus) == null || e.on(Je, this.redactorDomChangedCallback);\n }\n /**\n * Remove redactor dom change event listener\n */\n unwatchBlockMutations() {\n var e;\n (e = this.editorEventBus) == null || e.off(Je, this.redactorDomChangedCallback);\n }\n /**\n * Sometimes Tool can replace own main element, for example H2 -> H4 or UL -> OL\n * We need to detect such changes and update a link to tools main element with the new one\n *\n * @param mutations - records of block content mutations\n */\n detectToolRootChange(e) {\n e.forEach((t) => {\n if (Array.from(t.removedNodes).includes(this.toolRenderedElement)) {\n const i = t.addedNodes[t.addedNodes.length - 1];\n this.toolRenderedElement = i;\n }\n });\n }\n /**\n * Clears inputs cached value\n */\n dropInputsCache() {\n this.cachedInputs = [];\n }\n /**\n * Mark inputs with 'data-empty' attribute with the empty state\n */\n toggleInputsEmptyMark() {\n this.inputs.forEach(Lt);\n }\n}\nclass zo extends y {\n constructor() {\n super(...arguments), this.insert = (e = this.config.defaultBlock, t = {}, o = {}, i, s, r, l) => {\n const a = this.Editor.BlockManager.insert({\n id: l,\n tool: e,\n data: t,\n index: i,\n needToFocus: s,\n replace: r\n });\n return new G(a);\n }, this.composeBlockData = async (e) => {\n const t = this.Editor.Tools.blockTools.get(e);\n return new D({\n tool: t,\n api: this.Editor.API,\n readOnly: !0,\n data: {},\n tunesData: {}\n }).data;\n }, this.update = async (e, t, o) => {\n const { BlockManager: i } = this.Editor, s = i.getBlockById(e);\n if (s === void 0)\n throw new Error(`Block with id \"${e}\" not found`);\n const r = await i.update(s, t, o);\n return new G(r);\n }, this.convert = async (e, t, o) => {\n var h, p;\n const { BlockManager: i, Tools: s } = this.Editor, r = i.getBlockById(e);\n if (!r)\n throw new Error(`Block with id \"${e}\" not found`);\n const l = s.blockTools.get(r.name), a = s.blockTools.get(t);\n if (!a)\n throw new Error(`Block Tool with type \"${t}\" not found`);\n const c = ((h = l == null ? void 0 : l.conversionConfig) == null ? void 0 : h.export) !== void 0, u = ((p = a.conversionConfig) == null ? void 0 : p.import) !== void 0;\n if (c && u) {\n const g = await i.convert(r, t, o);\n return new G(g);\n } else {\n const g = [\n c ? !1 : Le(r.name),\n u ? !1 : Le(t)\n ].filter(Boolean).join(\" and \");\n throw new Error(`Conversion from \"${r.name}\" to \"${t}\" is not possible. ${g} tool(s) should provide a \"conversionConfig\"`);\n }\n }, this.insertMany = (e, t = this.Editor.BlockManager.blocks.length - 1) => {\n this.validateIndex(t);\n const o = e.map(({ id: i, type: s, data: r }) => this.Editor.BlockManager.composeBlock({\n id: i,\n tool: s || this.config.defaultBlock,\n data: r\n }));\n return this.Editor.BlockManager.insertMany(o, t), o.map((i) => new G(i));\n };\n }\n /**\n * Available methods\n *\n * @returns {Blocks}\n */\n get methods() {\n return {\n clear: () => this.clear(),\n render: (e) => this.render(e),\n renderFromHTML: (e) => this.renderFromHTML(e),\n delete: (e) => this.delete(e),\n swap: (e, t) => this.swap(e, t),\n move: (e, t) => this.move(e, t),\n getBlockByIndex: (e) => this.getBlockByIndex(e),\n getById: (e) => this.getById(e),\n getCurrentBlockIndex: () => this.getCurrentBlockIndex(),\n getBlockIndex: (e) => this.getBlockIndex(e),\n getBlocksCount: () => this.getBlocksCount(),\n getBlockByElement: (e) => this.getBlockByElement(e),\n stretchBlock: (e, t = !0) => this.stretchBlock(e, t),\n insertNewBlock: () => this.insertNewBlock(),\n insert: this.insert,\n insertMany: this.insertMany,\n update: this.update,\n composeBlockData: this.composeBlockData,\n convert: this.convert\n };\n }\n /**\n * Returns Blocks count\n *\n * @returns {number}\n */\n getBlocksCount() {\n return this.Editor.BlockManager.blocks.length;\n }\n /**\n * Returns current block index\n *\n * @returns {number}\n */\n getCurrentBlockIndex() {\n return this.Editor.BlockManager.currentBlockIndex;\n }\n /**\n * Returns the index of Block by id;\n *\n * @param id - block id\n */\n getBlockIndex(e) {\n const t = this.Editor.BlockManager.getBlockById(e);\n if (!t) {\n X(\"There is no block with id `\" + e + \"`\", \"warn\");\n return;\n }\n return this.Editor.BlockManager.getBlockIndex(t);\n }\n /**\n * Returns BlockAPI object by Block index\n *\n * @param {number} index - index to get\n */\n getBlockByIndex(e) {\n const t = this.Editor.BlockManager.getBlockByIndex(e);\n if (t === void 0) {\n X(\"There is no block at index `\" + e + \"`\", \"warn\");\n return;\n }\n return new G(t);\n }\n /**\n * Returns BlockAPI object by Block id\n *\n * @param id - id of block to get\n */\n getById(e) {\n const t = this.Editor.BlockManager.getBlockById(e);\n return t === void 0 ? (X(\"There is no block with id `\" + e + \"`\", \"warn\"), null) : new G(t);\n }\n /**\n * Get Block API object by any child html element\n *\n * @param element - html element to get Block by\n */\n getBlockByElement(e) {\n const t = this.Editor.BlockManager.getBlock(e);\n if (t === void 0) {\n X(\"There is no block corresponding to element `\" + e + \"`\", \"warn\");\n return;\n }\n return new G(t);\n }\n /**\n * Call Block Manager method that swap Blocks\n *\n * @param {number} fromIndex - position of first Block\n * @param {number} toIndex - position of second Block\n * @deprecated — use 'move' instead\n */\n swap(e, t) {\n I(\n \"`blocks.swap()` method is deprecated and will be removed in the next major release. Use `block.move()` method instead\",\n \"info\"\n ), this.Editor.BlockManager.swap(e, t);\n }\n /**\n * Move block from one index to another\n *\n * @param {number} toIndex - index to move to\n * @param {number} fromIndex - index to move from\n */\n move(e, t) {\n this.Editor.BlockManager.move(e, t);\n }\n /**\n * Deletes Block\n *\n * @param {number} blockIndex - index of Block to delete\n */\n delete(e = this.Editor.BlockManager.currentBlockIndex) {\n try {\n const t = this.Editor.BlockManager.getBlockByIndex(e);\n this.Editor.BlockManager.removeBlock(t);\n } catch (t) {\n X(t, \"warn\");\n return;\n }\n this.Editor.BlockManager.blocks.length === 0 && this.Editor.BlockManager.insert(), this.Editor.BlockManager.currentBlock && this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock, this.Editor.Caret.positions.END), this.Editor.Toolbar.close();\n }\n /**\n * Clear Editor's area\n */\n async clear() {\n await this.Editor.BlockManager.clear(!0), this.Editor.InlineToolbar.close();\n }\n /**\n * Fills Editor with Blocks data\n *\n * @param {OutputData} data — Saved Editor data\n */\n async render(e) {\n if (e === void 0 || e.blocks === void 0)\n throw new Error(\"Incorrect data passed to the render() method\");\n this.Editor.ModificationsObserver.disable(), await this.Editor.BlockManager.clear(), await this.Editor.Renderer.render(e.blocks), this.Editor.ModificationsObserver.enable();\n }\n /**\n * Render passed HTML string\n *\n * @param {string} data - HTML string to render\n * @returns {Promise}\n */\n renderFromHTML(e) {\n return this.Editor.BlockManager.clear(), this.Editor.Paste.processText(e, !0);\n }\n /**\n * Stretch Block's content\n *\n * @param {number} index - index of Block to stretch\n * @param {boolean} status - true to enable, false to disable\n * @deprecated Use BlockAPI interface to stretch Blocks\n */\n stretchBlock(e, t = !0) {\n Ze(\n !0,\n \"blocks.stretchBlock()\",\n \"BlockAPI\"\n );\n const o = this.Editor.BlockManager.getBlockByIndex(e);\n o && (o.stretched = t);\n }\n /**\n * Insert new Block\n * After set caret to this Block\n *\n * @todo remove in 3.0.0\n * @deprecated with insert() method\n */\n insertNewBlock() {\n I(\"Method blocks.insertNewBlock() is deprecated and it will be removed in the next major release. Use blocks.insert() instead.\", \"warn\"), this.insert();\n }\n /**\n * Validated block index and throws an error if it's invalid\n *\n * @param index - index to validate\n */\n validateIndex(e) {\n if (typeof e != \"number\")\n throw new Error(\"Index should be a number\");\n if (e < 0)\n throw new Error(\"Index should be greater than or equal to 0\");\n if (e === null)\n throw new Error(\"Index should be greater than or equal to 0\");\n }\n}\nfunction Uo(n, e) {\n return typeof n == \"number\" ? e.BlockManager.getBlockByIndex(n) : typeof n == \"string\" ? e.BlockManager.getBlockById(n) : e.BlockManager.getBlockById(n.id);\n}\nclass jo extends y {\n constructor() {\n super(...arguments), this.setToFirstBlock = (e = this.Editor.Caret.positions.DEFAULT, t = 0) => this.Editor.BlockManager.firstBlock ? (this.Editor.Caret.setToBlock(this.Editor.BlockManager.firstBlock, e, t), !0) : !1, this.setToLastBlock = (e = this.Editor.Caret.positions.DEFAULT, t = 0) => this.Editor.BlockManager.lastBlock ? (this.Editor.Caret.setToBlock(this.Editor.BlockManager.lastBlock, e, t), !0) : !1, this.setToPreviousBlock = (e = this.Editor.Caret.positions.DEFAULT, t = 0) => this.Editor.BlockManager.previousBlock ? (this.Editor.Caret.setToBlock(this.Editor.BlockManager.previousBlock, e, t), !0) : !1, this.setToNextBlock = (e = this.Editor.Caret.positions.DEFAULT, t = 0) => this.Editor.BlockManager.nextBlock ? (this.Editor.Caret.setToBlock(this.Editor.BlockManager.nextBlock, e, t), !0) : !1, this.setToBlock = (e, t = this.Editor.Caret.positions.DEFAULT, o = 0) => {\n const i = Uo(e, this.Editor);\n return i === void 0 ? !1 : (this.Editor.Caret.setToBlock(i, t, o), !0);\n }, this.focus = (e = !1) => e ? this.setToLastBlock(this.Editor.Caret.positions.END) : this.setToFirstBlock(this.Editor.Caret.positions.START);\n }\n /**\n * Available methods\n *\n * @returns {Caret}\n */\n get methods() {\n return {\n setToFirstBlock: this.setToFirstBlock,\n setToLastBlock: this.setToLastBlock,\n setToPreviousBlock: this.setToPreviousBlock,\n setToNextBlock: this.setToNextBlock,\n setToBlock: this.setToBlock,\n focus: this.focus\n };\n }\n}\nclass $o extends y {\n /**\n * Available methods\n *\n * @returns {Events}\n */\n get methods() {\n return {\n emit: (e, t) => this.emit(e, t),\n off: (e, t) => this.off(e, t),\n on: (e, t) => this.on(e, t)\n };\n }\n /**\n * Subscribe on Events\n *\n * @param {string} eventName - event name to subscribe\n * @param {Function} callback - event handler\n */\n on(e, t) {\n this.eventsDispatcher.on(e, t);\n }\n /**\n * Emit event with data\n *\n * @param {string} eventName - event to emit\n * @param {object} data - event's data\n */\n emit(e, t) {\n this.eventsDispatcher.emit(e, t);\n }\n /**\n * Unsubscribe from Event\n *\n * @param {string} eventName - event to unsubscribe\n * @param {Function} callback - event handler\n */\n off(e, t) {\n this.eventsDispatcher.off(e, t);\n }\n}\nclass ot extends y {\n /**\n * Return namespace section for tool or block tune\n *\n * @param toolName - tool name\n * @param isTune - is tool a block tune\n */\n static getNamespace(e, t) {\n return t ? `blockTunes.${e}` : `tools.${e}`;\n }\n /**\n * Return I18n API methods with global dictionary access\n */\n get methods() {\n return {\n t: () => {\n X(\"I18n.t() method can be accessed only from Tools\", \"warn\");\n }\n };\n }\n /**\n * Return I18n API methods with tool namespaced dictionary\n *\n * @param toolName - tool name\n * @param isTune - is tool a block tune\n */\n getMethodsForTool(e, t) {\n return Object.assign(\n this.methods,\n {\n t: (o) => z.t(ot.getNamespace(e, t), o)\n }\n );\n }\n}\nclass Yo extends y {\n /**\n * Editor.js Core API modules\n */\n get methods() {\n return {\n blocks: this.Editor.BlocksAPI.methods,\n caret: this.Editor.CaretAPI.methods,\n tools: this.Editor.ToolsAPI.methods,\n events: this.Editor.EventsAPI.methods,\n listeners: this.Editor.ListenersAPI.methods,\n notifier: this.Editor.NotifierAPI.methods,\n sanitizer: this.Editor.SanitizerAPI.methods,\n saver: this.Editor.SaverAPI.methods,\n selection: this.Editor.SelectionAPI.methods,\n styles: this.Editor.StylesAPI.classes,\n toolbar: this.Editor.ToolbarAPI.methods,\n inlineToolbar: this.Editor.InlineToolbarAPI.methods,\n tooltip: this.Editor.TooltipAPI.methods,\n i18n: this.Editor.I18nAPI.methods,\n readOnly: this.Editor.ReadOnlyAPI.methods,\n ui: this.Editor.UiAPI.methods\n };\n }\n /**\n * Returns Editor.js Core API methods for passed tool\n *\n * @param toolName - tool name\n * @param isTune - is tool a block tune\n */\n getMethodsForTool(e, t) {\n return Object.assign(\n this.methods,\n {\n i18n: this.Editor.I18nAPI.getMethodsForTool(e, t)\n }\n );\n }\n}\nclass Wo extends y {\n /**\n * Available methods\n *\n * @returns {InlineToolbar}\n */\n get methods() {\n return {\n close: () => this.close(),\n open: () => this.open()\n };\n }\n /**\n * Open Inline Toolbar\n */\n open() {\n this.Editor.InlineToolbar.tryToShow();\n }\n /**\n * Close Inline Toolbar\n */\n close() {\n this.Editor.InlineToolbar.close();\n }\n}\nclass Ko extends y {\n /**\n * Available methods\n *\n * @returns {Listeners}\n */\n get methods() {\n return {\n on: (e, t, o, i) => this.on(e, t, o, i),\n off: (e, t, o, i) => this.off(e, t, o, i),\n offById: (e) => this.offById(e)\n };\n }\n /**\n * Ads a DOM event listener. Return it's id.\n *\n * @param {HTMLElement} element - Element to set handler to\n * @param {string} eventType - event type\n * @param {() => void} handler - event handler\n * @param {boolean} useCapture - capture event or not\n */\n on(e, t, o, i) {\n return this.listeners.on(e, t, o, i);\n }\n /**\n * Removes DOM listener from element\n *\n * @param {Element} element - Element to remove handler from\n * @param eventType - event type\n * @param handler - event handler\n * @param {boolean} useCapture - capture event or not\n */\n off(e, t, o, i) {\n this.listeners.off(e, t, o, i);\n }\n /**\n * Removes DOM listener by the listener id\n *\n * @param id - id of the listener to remove\n */\n offById(e) {\n this.listeners.offById(e);\n }\n}\nvar Ut = { exports: {} };\n(function(n, e) {\n (function(t, o) {\n n.exports = o();\n })(window, function() {\n return function(t) {\n var o = {};\n function i(s) {\n if (o[s])\n return o[s].exports;\n var r = o[s] = { i: s, l: !1, exports: {} };\n return t[s].call(r.exports, r, r.exports, i), r.l = !0, r.exports;\n }\n return i.m = t, i.c = o, i.d = function(s, r, l) {\n i.o(s, r) || Object.defineProperty(s, r, { enumerable: !0, get: l });\n }, i.r = function(s) {\n typeof Symbol < \"u\" && Symbol.toStringTag && Object.defineProperty(s, Symbol.toStringTag, { value: \"Module\" }), Object.defineProperty(s, \"__esModule\", { value: !0 });\n }, i.t = function(s, r) {\n if (1 & r && (s = i(s)), 8 & r || 4 & r && typeof s == \"object\" && s && s.__esModule)\n return s;\n var l = /* @__PURE__ */ Object.create(null);\n if (i.r(l), Object.defineProperty(l, \"default\", { enumerable: !0, value: s }), 2 & r && typeof s != \"string\")\n for (var a in s)\n i.d(l, a, (function(c) {\n return s[c];\n }).bind(null, a));\n return l;\n }, i.n = function(s) {\n var r = s && s.__esModule ? function() {\n return s.default;\n } : function() {\n return s;\n };\n return i.d(r, \"a\", r), r;\n }, i.o = function(s, r) {\n return Object.prototype.hasOwnProperty.call(s, r);\n }, i.p = \"/\", i(i.s = 0);\n }([function(t, o, i) {\n i(1), /*!\n * Codex JavaScript Notification module\n * https://github.com/codex-team/js-notifier\n */\n t.exports = function() {\n var s = i(6), r = \"cdx-notify--bounce-in\", l = null;\n return { show: function(a) {\n if (a.message) {\n (function() {\n if (l)\n return !0;\n l = s.getWrapper(), document.body.appendChild(l);\n })();\n var c = null, u = a.time || 8e3;\n switch (a.type) {\n case \"confirm\":\n c = s.confirm(a);\n break;\n case \"prompt\":\n c = s.prompt(a);\n break;\n default:\n c = s.alert(a), window.setTimeout(function() {\n c.remove();\n }, u);\n }\n l.appendChild(c), c.classList.add(r);\n }\n } };\n }();\n }, function(t, o, i) {\n var s = i(2);\n typeof s == \"string\" && (s = [[t.i, s, \"\"]]);\n var r = { hmr: !0, transform: void 0, insertInto: void 0 };\n i(4)(s, r), s.locals && (t.exports = s.locals);\n }, function(t, o, i) {\n (t.exports = i(3)(!1)).push([t.i, `.cdx-notify--error{background:#fffbfb!important}.cdx-notify--error::before{background:#fb5d5d!important}.cdx-notify__input{max-width:130px;padding:5px 10px;background:#f7f7f7;border:0;border-radius:3px;font-size:13px;color:#656b7c;outline:0}.cdx-notify__input:-ms-input-placeholder{color:#656b7c}.cdx-notify__input::placeholder{color:#656b7c}.cdx-notify__input:focus:-ms-input-placeholder{color:rgba(101,107,124,.3)}.cdx-notify__input:focus::placeholder{color:rgba(101,107,124,.3)}.cdx-notify__button{border:none;border-radius:3px;font-size:13px;padding:5px 10px;cursor:pointer}.cdx-notify__button:last-child{margin-left:10px}.cdx-notify__button--cancel{background:#f2f5f7;box-shadow:0 2px 1px 0 rgba(16,19,29,0);color:#656b7c}.cdx-notify__button--cancel:hover{background:#eee}.cdx-notify__button--confirm{background:#34c992;box-shadow:0 1px 1px 0 rgba(18,49,35,.05);color:#fff}.cdx-notify__button--confirm:hover{background:#33b082}.cdx-notify__btns-wrapper{display:-ms-flexbox;display:flex;-ms-flex-flow:row nowrap;flex-flow:row nowrap;margin-top:5px}.cdx-notify__cross{position:absolute;top:5px;right:5px;width:10px;height:10px;padding:5px;opacity:.54;cursor:pointer}.cdx-notify__cross::after,.cdx-notify__cross::before{content:'';position:absolute;left:9px;top:5px;height:12px;width:2px;background:#575d67}.cdx-notify__cross::before{transform:rotate(-45deg)}.cdx-notify__cross::after{transform:rotate(45deg)}.cdx-notify__cross:hover{opacity:1}.cdx-notifies{position:fixed;z-index:2;bottom:20px;left:20px;font-family:-apple-system,BlinkMacSystemFont,\"Segoe UI\",Roboto,Oxygen,Ubuntu,Cantarell,\"Fira Sans\",\"Droid Sans\",\"Helvetica Neue\",sans-serif}.cdx-notify{position:relative;width:220px;margin-top:15px;padding:13px 16px;background:#fff;box-shadow:0 11px 17px 0 rgba(23,32,61,.13);border-radius:5px;font-size:14px;line-height:1.4em;word-wrap:break-word}.cdx-notify::before{content:'';position:absolute;display:block;top:0;left:0;width:3px;height:calc(100% - 6px);margin:3px;border-radius:5px;background:0 0}@keyframes bounceIn{0%{opacity:0;transform:scale(.3)}50%{opacity:1;transform:scale(1.05)}70%{transform:scale(.9)}100%{transform:scale(1)}}.cdx-notify--bounce-in{animation-name:bounceIn;animation-duration:.6s;animation-iteration-count:1}.cdx-notify--success{background:#fafffe!important}.cdx-notify--success::before{background:#41ffb1!important}`, \"\"]);\n }, function(t, o) {\n t.exports = function(i) {\n var s = [];\n return s.toString = function() {\n return this.map(function(r) {\n var l = function(a, c) {\n var u = a[1] || \"\", h = a[3];\n if (!h)\n return u;\n if (c && typeof btoa == \"function\") {\n var p = (f = h, \"/*# sourceMappingURL=data:application/json;charset=utf-8;base64,\" + btoa(unescape(encodeURIComponent(JSON.stringify(f)))) + \" */\"), g = h.sources.map(function(k) {\n return \"/*# sourceURL=\" + h.sourceRoot + k + \" */\";\n });\n return [u].concat(g).concat([p]).join(`\n`);\n }\n var f;\n return [u].join(`\n`);\n }(r, i);\n return r[2] ? \"@media \" + r[2] + \"{\" + l + \"}\" : l;\n }).join(\"\");\n }, s.i = function(r, l) {\n typeof r == \"string\" && (r = [[null, r, \"\"]]);\n for (var a = {}, c = 0; c < this.length; c++) {\n var u = this[c][0];\n typeof u == \"number\" && (a[u] = !0);\n }\n for (c = 0; c < r.length; c++) {\n var h = r[c];\n typeof h[0] == \"number\" && a[h[0]] || (l && !h[2] ? h[2] = l : l && (h[2] = \"(\" + h[2] + \") and (\" + l + \")\"), s.push(h));\n }\n }, s;\n };\n }, function(t, o, i) {\n var s, r, l = {}, a = (s = function() {\n return window && document && document.all && !window.atob;\n }, function() {\n return r === void 0 && (r = s.apply(this, arguments)), r;\n }), c = function(v) {\n var m = {};\n return function(x) {\n if (typeof x == \"function\")\n return x();\n if (m[x] === void 0) {\n var E = (function(M) {\n return document.querySelector(M);\n }).call(this, x);\n if (window.HTMLIFrameElement && E instanceof window.HTMLIFrameElement)\n try {\n E = E.contentDocument.head;\n } catch {\n E = null;\n }\n m[x] = E;\n }\n return m[x];\n };\n }(), u = null, h = 0, p = [], g = i(5);\n function f(v, m) {\n for (var x = 0; x < v.length; x++) {\n var E = v[x], M = l[E.id];\n if (M) {\n M.refs++;\n for (var T = 0; T < M.parts.length; T++)\n M.parts[T](E.parts[T]);\n for (; T < E.parts.length; T++)\n M.parts.push(j(E.parts[T], m));\n } else {\n var P = [];\n for (T = 0; T < E.parts.length; T++)\n P.push(j(E.parts[T], m));\n l[E.id] = { id: E.id, refs: 1, parts: P };\n }\n }\n }\n function k(v, m) {\n for (var x = [], E = {}, M = 0; M < v.length; M++) {\n var T = v[M], P = m.base ? T[0] + m.base : T[0], B = { css: T[1], media: T[2], sourceMap: T[3] };\n E[P] ? E[P].parts.push(B) : x.push(E[P] = { id: P, parts: [B] });\n }\n return x;\n }\n function C(v, m) {\n var x = c(v.insertInto);\n if (!x)\n throw new Error(\"Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid.\");\n var E = p[p.length - 1];\n if (v.insertAt === \"top\")\n E ? E.nextSibling ? x.insertBefore(m, E.nextSibling) : x.appendChild(m) : x.insertBefore(m, x.firstChild), p.push(m);\n else if (v.insertAt === \"bottom\")\n x.appendChild(m);\n else {\n if (typeof v.insertAt != \"object\" || !v.insertAt.before)\n throw new Error(`[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n`);\n var M = c(v.insertInto + \" \" + v.insertAt.before);\n x.insertBefore(m, M);\n }\n }\n function S(v) {\n if (v.parentNode === null)\n return !1;\n v.parentNode.removeChild(v);\n var m = p.indexOf(v);\n m >= 0 && p.splice(m, 1);\n }\n function _(v) {\n var m = document.createElement(\"style\");\n return v.attrs.type === void 0 && (v.attrs.type = \"text/css\"), ee(m, v.attrs), C(v, m), m;\n }\n function ee(v, m) {\n Object.keys(m).forEach(function(x) {\n v.setAttribute(x, m[x]);\n });\n }\n function j(v, m) {\n var x, E, M, T;\n if (m.transform && v.css) {\n if (!(T = m.transform(v.css)))\n return function() {\n };\n v.css = T;\n }\n if (m.singleton) {\n var P = h++;\n x = u || (u = _(m)), E = fe.bind(null, x, P, !1), M = fe.bind(null, x, P, !0);\n } else\n v.sourceMap && typeof URL == \"function\" && typeof URL.createObjectURL == \"function\" && typeof URL.revokeObjectURL == \"function\" && typeof Blob == \"function\" && typeof btoa == \"function\" ? (x = function(B) {\n var Y = document.createElement(\"link\");\n return B.attrs.type === void 0 && (B.attrs.type = \"text/css\"), B.attrs.rel = \"stylesheet\", ee(Y, B.attrs), C(B, Y), Y;\n }(m), E = (function(B, Y, ge) {\n var ie = ge.css, He = ge.sourceMap, mo = Y.convertToAbsoluteUrls === void 0 && He;\n (Y.convertToAbsoluteUrls || mo) && (ie = g(ie)), He && (ie += `\n/*# sourceMappingURL=data:application/json;base64,` + btoa(unescape(encodeURIComponent(JSON.stringify(He)))) + \" */\");\n var bo = new Blob([ie], { type: \"text/css\" }), mt = B.href;\n B.href = URL.createObjectURL(bo), mt && URL.revokeObjectURL(mt);\n }).bind(null, x, m), M = function() {\n S(x), x.href && URL.revokeObjectURL(x.href);\n }) : (x = _(m), E = (function(B, Y) {\n var ge = Y.css, ie = Y.media;\n if (ie && B.setAttribute(\"media\", ie), B.styleSheet)\n B.styleSheet.cssText = ge;\n else {\n for (; B.firstChild; )\n B.removeChild(B.firstChild);\n B.appendChild(document.createTextNode(ge));\n }\n }).bind(null, x), M = function() {\n S(x);\n });\n return E(v), function(B) {\n if (B) {\n if (B.css === v.css && B.media === v.media && B.sourceMap === v.sourceMap)\n return;\n E(v = B);\n } else\n M();\n };\n }\n t.exports = function(v, m) {\n if (typeof DEBUG < \"u\" && DEBUG && typeof document != \"object\")\n throw new Error(\"The style-loader cannot be used in a non-browser environment\");\n (m = m || {}).attrs = typeof m.attrs == \"object\" ? m.attrs : {}, m.singleton || typeof m.singleton == \"boolean\" || (m.singleton = a()), m.insertInto || (m.insertInto = \"head\"), m.insertAt || (m.insertAt = \"bottom\");\n var x = k(v, m);\n return f(x, m), function(E) {\n for (var M = [], T = 0; T < x.length; T++) {\n var P = x[T];\n (B = l[P.id]).refs--, M.push(B);\n }\n for (E && f(k(E, m), m), T = 0; T < M.length; T++) {\n var B;\n if ((B = M[T]).refs === 0) {\n for (var Y = 0; Y < B.parts.length; Y++)\n B.parts[Y]();\n delete l[B.id];\n }\n }\n };\n };\n var $, oe = ($ = [], function(v, m) {\n return $[v] = m, $.filter(Boolean).join(`\n`);\n });\n function fe(v, m, x, E) {\n var M = x ? \"\" : E.css;\n if (v.styleSheet)\n v.styleSheet.cssText = oe(m, M);\n else {\n var T = document.createTextNode(M), P = v.childNodes;\n P[m] && v.removeChild(P[m]), P.length ? v.insertBefore(T, P[m]) : v.appendChild(T);\n }\n }\n }, function(t, o) {\n t.exports = function(i) {\n var s = typeof window < \"u\" && window.location;\n if (!s)\n throw new Error(\"fixUrls requires window.location\");\n if (!i || typeof i != \"string\")\n return i;\n var r = s.protocol + \"//\" + s.host, l = r + s.pathname.replace(/\\/[^\\/]*$/, \"/\");\n return i.replace(/url\\s*\\(((?:[^)(]|\\((?:[^)(]+|\\([^)(]*\\))*\\))*)\\)/gi, function(a, c) {\n var u, h = c.trim().replace(/^\"(.*)\"$/, function(p, g) {\n return g;\n }).replace(/^'(.*)'$/, function(p, g) {\n return g;\n });\n return /^(#|data:|http:\\/\\/|https:\\/\\/|file:\\/\\/\\/|\\s*$)/i.test(h) ? a : (u = h.indexOf(\"//\") === 0 ? h : h.indexOf(\"/\") === 0 ? r + h : l + h.replace(/^\\.\\//, \"\"), \"url(\" + JSON.stringify(u) + \")\");\n });\n };\n }, function(t, o, i) {\n var s, r, l, a, c, u, h, p, g;\n t.exports = (s = \"cdx-notifies\", r = \"cdx-notify\", l = \"cdx-notify__cross\", a = \"cdx-notify__button--confirm\", c = \"cdx-notify__button--cancel\", u = \"cdx-notify__input\", h = \"cdx-notify__button\", p = \"cdx-notify__btns-wrapper\", { alert: g = function(f) {\n var k = document.createElement(\"DIV\"), C = document.createElement(\"DIV\"), S = f.message, _ = f.style;\n return k.classList.add(r), _ && k.classList.add(r + \"--\" + _), k.innerHTML = S, C.classList.add(l), C.addEventListener(\"click\", k.remove.bind(k)), k.appendChild(C), k;\n }, confirm: function(f) {\n var k = g(f), C = document.createElement(\"div\"), S = document.createElement(\"button\"), _ = document.createElement(\"button\"), ee = k.querySelector(\".\" + l), j = f.cancelHandler, $ = f.okHandler;\n return C.classList.add(p), S.innerHTML = f.okText || \"Confirm\", _.innerHTML = f.cancelText || \"Cancel\", S.classList.add(h), _.classList.add(h), S.classList.add(a), _.classList.add(c), j && typeof j == \"function\" && (_.addEventListener(\"click\", j), ee.addEventListener(\"click\", j)), $ && typeof $ == \"function\" && S.addEventListener(\"click\", $), S.addEventListener(\"click\", k.remove.bind(k)), _.addEventListener(\"click\", k.remove.bind(k)), C.appendChild(S), C.appendChild(_), k.appendChild(C), k;\n }, prompt: function(f) {\n var k = g(f), C = document.createElement(\"div\"), S = document.createElement(\"button\"), _ = document.createElement(\"input\"), ee = k.querySelector(\".\" + l), j = f.cancelHandler, $ = f.okHandler;\n return C.classList.add(p), S.innerHTML = f.okText || \"Ok\", S.classList.add(h), S.classList.add(a), _.classList.add(u), f.placeholder && _.setAttribute(\"placeholder\", f.placeholder), f.default && (_.value = f.default), f.inputType && (_.type = f.inputType), j && typeof j == \"function\" && ee.addEventListener(\"click\", j), $ && typeof $ == \"function\" && S.addEventListener(\"click\", function() {\n $(_.value);\n }), S.addEventListener(\"click\", k.remove.bind(k)), C.appendChild(_), C.appendChild(S), k.appendChild(C), k;\n }, getWrapper: function() {\n var f = document.createElement(\"DIV\");\n return f.classList.add(s), f;\n } });\n }]);\n });\n})(Ut);\nvar Xo = Ut.exports;\nconst Vo = /* @__PURE__ */ Fe(Xo);\nclass qo {\n /**\n * Show web notification\n *\n * @param {NotifierOptions | ConfirmNotifierOptions | PromptNotifierOptions} options - notification options\n */\n show(e) {\n Vo.show(e);\n }\n}\nclass Zo extends y {\n /**\n * @param moduleConfiguration - Module Configuration\n * @param moduleConfiguration.config - Editor's config\n * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher\n */\n constructor({ config: e, eventsDispatcher: t }) {\n super({\n config: e,\n eventsDispatcher: t\n }), this.notifier = new qo();\n }\n /**\n * Available methods\n */\n get methods() {\n return {\n show: (e) => this.show(e)\n };\n }\n /**\n * Show notification\n *\n * @param {NotifierOptions} options - message option\n */\n show(e) {\n return this.notifier.show(e);\n }\n}\nclass Go extends y {\n /**\n * Available methods\n */\n get methods() {\n const e = () => this.isEnabled;\n return {\n toggle: (t) => this.toggle(t),\n get isEnabled() {\n return e();\n }\n };\n }\n /**\n * Set or toggle read-only state\n *\n * @param {boolean|undefined} state - set or toggle state\n * @returns {boolean} current value\n */\n toggle(e) {\n return this.Editor.ReadOnly.toggle(e);\n }\n /**\n * Returns current read-only state\n */\n get isEnabled() {\n return this.Editor.ReadOnly.isEnabled;\n }\n}\nvar jt = { exports: {} };\n(function(n, e) {\n (function(t, o) {\n n.exports = o();\n })(ko, function() {\n function t(h) {\n var p = h.tags, g = Object.keys(p), f = g.map(function(k) {\n return typeof p[k];\n }).every(function(k) {\n return k === \"object\" || k === \"boolean\" || k === \"function\";\n });\n if (!f)\n throw new Error(\"The configuration was invalid\");\n this.config = h;\n }\n var o = [\"P\", \"LI\", \"TD\", \"TH\", \"DIV\", \"H1\", \"H2\", \"H3\", \"H4\", \"H5\", \"H6\", \"PRE\"];\n function i(h) {\n return o.indexOf(h.nodeName) !== -1;\n }\n var s = [\"A\", \"B\", \"STRONG\", \"I\", \"EM\", \"SUB\", \"SUP\", \"U\", \"STRIKE\"];\n function r(h) {\n return s.indexOf(h.nodeName) !== -1;\n }\n t.prototype.clean = function(h) {\n const p = document.implementation.createHTMLDocument(), g = p.createElement(\"div\");\n return g.innerHTML = h, this._sanitize(p, g), g.innerHTML;\n }, t.prototype._sanitize = function(h, p) {\n var g = l(h, p), f = g.firstChild();\n if (f)\n do {\n if (f.nodeType === Node.TEXT_NODE)\n if (f.data.trim() === \"\" && (f.previousElementSibling && i(f.previousElementSibling) || f.nextElementSibling && i(f.nextElementSibling))) {\n p.removeChild(f), this._sanitize(h, p);\n break;\n } else\n continue;\n if (f.nodeType === Node.COMMENT_NODE) {\n p.removeChild(f), this._sanitize(h, p);\n break;\n }\n var k = r(f), C;\n k && (C = Array.prototype.some.call(f.childNodes, i));\n var S = !!p.parentNode, _ = i(p) && i(f) && S, ee = f.nodeName.toLowerCase(), j = a(this.config, ee, f), $ = k && C;\n if ($ || c(f, j) || !this.config.keepNestedBlockElements && _) {\n if (!(f.nodeName === \"SCRIPT\" || f.nodeName === \"STYLE\"))\n for (; f.childNodes.length > 0; )\n p.insertBefore(f.childNodes[0], f);\n p.removeChild(f), this._sanitize(h, p);\n break;\n }\n for (var oe = 0; oe < f.attributes.length; oe += 1) {\n var fe = f.attributes[oe];\n u(fe, j, f) && (f.removeAttribute(fe.name), oe = oe - 1);\n }\n this._sanitize(h, f);\n } while (f = g.nextSibling());\n };\n function l(h, p) {\n return h.createTreeWalker(\n p,\n NodeFilter.SHOW_TEXT | NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_COMMENT,\n null,\n !1\n );\n }\n function a(h, p, g) {\n return typeof h.tags[p] == \"function\" ? h.tags[p](g) : h.tags[p];\n }\n function c(h, p) {\n return typeof p > \"u\" ? !0 : typeof p == \"boolean\" ? !p : !1;\n }\n function u(h, p, g) {\n var f = h.name.toLowerCase();\n return p === !0 ? !1 : typeof p[f] == \"function\" ? !p[f](h.value, g) : typeof p[f] > \"u\" || p[f] === !1 ? !0 : typeof p[f] == \"string\" ? p[f] !== h.value : !1;\n }\n return t;\n });\n})(jt);\nvar Jo = jt.exports;\nconst Qo = /* @__PURE__ */ Fe(Jo);\nfunction it(n, e) {\n return n.map((t) => {\n const o = O(e) ? e(t.tool) : e;\n return V(o) || (t.data = st(t.data, o)), t;\n });\n}\nfunction q(n, e = {}) {\n const t = {\n tags: e\n };\n return new Qo(t).clean(n);\n}\nfunction st(n, e) {\n return Array.isArray(n) ? ei(n, e) : R(n) ? ti(n, e) : Q(n) ? oi(n, e) : n;\n}\nfunction ei(n, e) {\n return n.map((t) => st(t, e));\n}\nfunction ti(n, e) {\n const t = {};\n for (const o in n) {\n if (!Object.prototype.hasOwnProperty.call(n, o))\n continue;\n const i = n[o], s = ii(e[o]) ? e[o] : e;\n t[o] = st(i, s);\n }\n return t;\n}\nfunction oi(n, e) {\n return R(e) ? q(n, e) : e === !1 ? q(n, {}) : n;\n}\nfunction ii(n) {\n return R(n) || yo(n) || O(n);\n}\nclass si extends y {\n /**\n * Available methods\n *\n * @returns {SanitizerConfig}\n */\n get methods() {\n return {\n clean: (e, t) => this.clean(e, t)\n };\n }\n /**\n * Perform sanitizing of a string\n *\n * @param {string} taintString - what to sanitize\n * @param {SanitizerConfig} config - sanitizer config\n * @returns {string}\n */\n clean(e, t) {\n return q(e, t);\n }\n}\nclass ni extends y {\n /**\n * Available methods\n *\n * @returns {Saver}\n */\n get methods() {\n return {\n save: () => this.save()\n };\n }\n /**\n * Return Editor's data\n *\n * @returns {OutputData}\n */\n save() {\n const e = \"Editor's content can not be saved in read-only mode\";\n return this.Editor.ReadOnly.isEnabled ? (X(e, \"warn\"), Promise.reject(new Error(e))) : this.Editor.Saver.save();\n }\n}\nclass ri extends y {\n constructor() {\n super(...arguments), this.selectionUtils = new b();\n }\n /**\n * Available methods\n *\n * @returns {SelectionAPIInterface}\n */\n get methods() {\n return {\n findParentTag: (e, t) => this.findParentTag(e, t),\n expandToTag: (e) => this.expandToTag(e),\n save: () => this.selectionUtils.save(),\n restore: () => this.selectionUtils.restore(),\n setFakeBackground: () => this.selectionUtils.setFakeBackground(),\n removeFakeBackground: () => this.selectionUtils.removeFakeBackground()\n };\n }\n /**\n * Looks ahead from selection and find passed tag with class name\n *\n * @param {string} tagName - tag to find\n * @param {string} className - tag's class name\n * @returns {HTMLElement|null}\n */\n findParentTag(e, t) {\n return this.selectionUtils.findParentTag(e, t);\n }\n /**\n * Expand selection to passed tag\n *\n * @param {HTMLElement} node - tag that should contain selection\n */\n expandToTag(e) {\n this.selectionUtils.expandToTag(e);\n }\n}\nclass li extends y {\n /**\n * Available methods\n */\n get methods() {\n return {\n getBlockTools: () => Array.from(this.Editor.Tools.blockTools.values())\n };\n }\n}\nclass ai extends y {\n /**\n * Exported classes\n */\n get classes() {\n return {\n /**\n * Base Block styles\n */\n block: \"cdx-block\",\n /**\n * Inline Tools styles\n */\n inlineToolButton: \"ce-inline-tool\",\n inlineToolButtonActive: \"ce-inline-tool--active\",\n /**\n * UI elements\n */\n input: \"cdx-input\",\n loader: \"cdx-loader\",\n button: \"cdx-button\",\n /**\n * Settings styles\n */\n settingsButton: \"cdx-settings-button\",\n settingsButtonActive: \"cdx-settings-button--active\"\n };\n }\n}\nclass ci extends y {\n /**\n * Available methods\n *\n * @returns {Toolbar}\n */\n get methods() {\n return {\n close: () => this.close(),\n open: () => this.open(),\n toggleBlockSettings: (e) => this.toggleBlockSettings(e),\n toggleToolbox: (e) => this.toggleToolbox(e)\n };\n }\n /**\n * Open toolbar\n */\n open() {\n this.Editor.Toolbar.moveAndOpen();\n }\n /**\n * Close toolbar and all included elements\n */\n close() {\n this.Editor.Toolbar.close();\n }\n /**\n * Toggles Block Setting of the current block\n *\n * @param {boolean} openingState — opening state of Block Setting\n */\n toggleBlockSettings(e) {\n if (this.Editor.BlockManager.currentBlockIndex === -1) {\n X(\"Could't toggle the Toolbar because there is no block selected \", \"warn\");\n return;\n }\n e ?? !this.Editor.BlockSettings.opened ? (this.Editor.Toolbar.moveAndOpen(), this.Editor.BlockSettings.open()) : this.Editor.BlockSettings.close();\n }\n /**\n * Open toolbox\n *\n * @param {boolean} openingState - Opening state of toolbox\n */\n toggleToolbox(e) {\n if (this.Editor.BlockManager.currentBlockIndex === -1) {\n X(\"Could't toggle the Toolbox because there is no block selected \", \"warn\");\n return;\n }\n e ?? !this.Editor.Toolbar.toolbox.opened ? (this.Editor.Toolbar.moveAndOpen(), this.Editor.Toolbar.toolbox.open()) : this.Editor.Toolbar.toolbox.close();\n }\n}\nvar $t = { exports: {} };\n/*!\n * CodeX.Tooltips\n * \n * @version 1.0.5\n * \n * @licence MIT\n * @author CodeX \n * \n * \n */\n(function(n, e) {\n (function(t, o) {\n n.exports = o();\n })(window, function() {\n return function(t) {\n var o = {};\n function i(s) {\n if (o[s])\n return o[s].exports;\n var r = o[s] = { i: s, l: !1, exports: {} };\n return t[s].call(r.exports, r, r.exports, i), r.l = !0, r.exports;\n }\n return i.m = t, i.c = o, i.d = function(s, r, l) {\n i.o(s, r) || Object.defineProperty(s, r, { enumerable: !0, get: l });\n }, i.r = function(s) {\n typeof Symbol < \"u\" && Symbol.toStringTag && Object.defineProperty(s, Symbol.toStringTag, { value: \"Module\" }), Object.defineProperty(s, \"__esModule\", { value: !0 });\n }, i.t = function(s, r) {\n if (1 & r && (s = i(s)), 8 & r || 4 & r && typeof s == \"object\" && s && s.__esModule)\n return s;\n var l = /* @__PURE__ */ Object.create(null);\n if (i.r(l), Object.defineProperty(l, \"default\", { enumerable: !0, value: s }), 2 & r && typeof s != \"string\")\n for (var a in s)\n i.d(l, a, (function(c) {\n return s[c];\n }).bind(null, a));\n return l;\n }, i.n = function(s) {\n var r = s && s.__esModule ? function() {\n return s.default;\n } : function() {\n return s;\n };\n return i.d(r, \"a\", r), r;\n }, i.o = function(s, r) {\n return Object.prototype.hasOwnProperty.call(s, r);\n }, i.p = \"\", i(i.s = 0);\n }([function(t, o, i) {\n t.exports = i(1);\n }, function(t, o, i) {\n i.r(o), i.d(o, \"default\", function() {\n return s;\n });\n class s {\n constructor() {\n this.nodes = { wrapper: null, content: null }, this.showed = !1, this.offsetTop = 10, this.offsetLeft = 10, this.offsetRight = 10, this.hidingDelay = 0, this.handleWindowScroll = () => {\n this.showed && this.hide(!0);\n }, this.loadStyles(), this.prepare(), window.addEventListener(\"scroll\", this.handleWindowScroll, { passive: !0 });\n }\n get CSS() {\n return { tooltip: \"ct\", tooltipContent: \"ct__content\", tooltipShown: \"ct--shown\", placement: { left: \"ct--left\", bottom: \"ct--bottom\", right: \"ct--right\", top: \"ct--top\" } };\n }\n show(l, a, c) {\n this.nodes.wrapper || this.prepare(), this.hidingTimeout && clearTimeout(this.hidingTimeout);\n const u = Object.assign({ placement: \"bottom\", marginTop: 0, marginLeft: 0, marginRight: 0, marginBottom: 0, delay: 70, hidingDelay: 0 }, c);\n if (u.hidingDelay && (this.hidingDelay = u.hidingDelay), this.nodes.content.innerHTML = \"\", typeof a == \"string\")\n this.nodes.content.appendChild(document.createTextNode(a));\n else {\n if (!(a instanceof Node))\n throw Error(\"[CodeX Tooltip] Wrong type of «content» passed. It should be an instance of Node or String. But \" + typeof a + \" given.\");\n this.nodes.content.appendChild(a);\n }\n switch (this.nodes.wrapper.classList.remove(...Object.values(this.CSS.placement)), u.placement) {\n case \"top\":\n this.placeTop(l, u);\n break;\n case \"left\":\n this.placeLeft(l, u);\n break;\n case \"right\":\n this.placeRight(l, u);\n break;\n case \"bottom\":\n default:\n this.placeBottom(l, u);\n }\n u && u.delay ? this.showingTimeout = setTimeout(() => {\n this.nodes.wrapper.classList.add(this.CSS.tooltipShown), this.showed = !0;\n }, u.delay) : (this.nodes.wrapper.classList.add(this.CSS.tooltipShown), this.showed = !0);\n }\n hide(l = !1) {\n if (this.hidingDelay && !l)\n return this.hidingTimeout && clearTimeout(this.hidingTimeout), void (this.hidingTimeout = setTimeout(() => {\n this.hide(!0);\n }, this.hidingDelay));\n this.nodes.wrapper.classList.remove(this.CSS.tooltipShown), this.showed = !1, this.showingTimeout && clearTimeout(this.showingTimeout);\n }\n onHover(l, a, c) {\n l.addEventListener(\"mouseenter\", () => {\n this.show(l, a, c);\n }), l.addEventListener(\"mouseleave\", () => {\n this.hide();\n });\n }\n destroy() {\n this.nodes.wrapper.remove(), window.removeEventListener(\"scroll\", this.handleWindowScroll);\n }\n prepare() {\n this.nodes.wrapper = this.make(\"div\", this.CSS.tooltip), this.nodes.content = this.make(\"div\", this.CSS.tooltipContent), this.append(this.nodes.wrapper, this.nodes.content), this.append(document.body, this.nodes.wrapper);\n }\n loadStyles() {\n const l = \"codex-tooltips-style\";\n if (document.getElementById(l))\n return;\n const a = i(2), c = this.make(\"style\", null, { textContent: a.toString(), id: l });\n this.prepend(document.head, c);\n }\n placeBottom(l, a) {\n const c = l.getBoundingClientRect(), u = c.left + l.clientWidth / 2 - this.nodes.wrapper.offsetWidth / 2, h = c.bottom + window.pageYOffset + this.offsetTop + a.marginTop;\n this.applyPlacement(\"bottom\", u, h);\n }\n placeTop(l, a) {\n const c = l.getBoundingClientRect(), u = c.left + l.clientWidth / 2 - this.nodes.wrapper.offsetWidth / 2, h = c.top + window.pageYOffset - this.nodes.wrapper.clientHeight - this.offsetTop;\n this.applyPlacement(\"top\", u, h);\n }\n placeLeft(l, a) {\n const c = l.getBoundingClientRect(), u = c.left - this.nodes.wrapper.offsetWidth - this.offsetLeft - a.marginLeft, h = c.top + window.pageYOffset + l.clientHeight / 2 - this.nodes.wrapper.offsetHeight / 2;\n this.applyPlacement(\"left\", u, h);\n }\n placeRight(l, a) {\n const c = l.getBoundingClientRect(), u = c.right + this.offsetRight + a.marginRight, h = c.top + window.pageYOffset + l.clientHeight / 2 - this.nodes.wrapper.offsetHeight / 2;\n this.applyPlacement(\"right\", u, h);\n }\n applyPlacement(l, a, c) {\n this.nodes.wrapper.classList.add(this.CSS.placement[l]), this.nodes.wrapper.style.left = a + \"px\", this.nodes.wrapper.style.top = c + \"px\";\n }\n make(l, a = null, c = {}) {\n const u = document.createElement(l);\n Array.isArray(a) ? u.classList.add(...a) : a && u.classList.add(a);\n for (const h in c)\n c.hasOwnProperty(h) && (u[h] = c[h]);\n return u;\n }\n append(l, a) {\n Array.isArray(a) ? a.forEach((c) => l.appendChild(c)) : l.appendChild(a);\n }\n prepend(l, a) {\n Array.isArray(a) ? (a = a.reverse()).forEach((c) => l.prepend(c)) : l.prepend(a);\n }\n }\n }, function(t, o) {\n t.exports = `.ct{z-index:999;opacity:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;pointer-events:none;-webkit-transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1);transition:opacity 50ms ease-in,transform 70ms cubic-bezier(.215,.61,.355,1),-webkit-transform 70ms cubic-bezier(.215,.61,.355,1);will-change:opacity,top,left;-webkit-box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);box-shadow:0 8px 12px 0 rgba(29,32,43,.17),0 4px 5px -3px rgba(5,6,12,.49);border-radius:9px}.ct,.ct:before{position:absolute;top:0;left:0}.ct:before{content:\"\";bottom:0;right:0;background-color:#1d202b;z-index:-1;border-radius:4px}@supports(-webkit-mask-box-image:url(\"\")){.ct:before{border-radius:0;-webkit-mask-box-image:url('data:image/svg+xml;charset=utf-8,') 48% 41% 37.9% 53.3%}}@media (--mobile){.ct{display:none}}.ct__content{padding:6px 10px;color:#cdd1e0;font-size:12px;text-align:center;letter-spacing:.02em;line-height:1em}.ct:after{content:\"\";width:8px;height:8px;position:absolute;background-color:#1d202b;z-index:-1}.ct--bottom{-webkit-transform:translateY(5px);transform:translateY(5px)}.ct--bottom:after{top:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--top{-webkit-transform:translateY(-5px);transform:translateY(-5px)}.ct--top:after{top:auto;bottom:-3px;left:50%;-webkit-transform:translateX(-50%) rotate(-45deg);transform:translateX(-50%) rotate(-45deg)}.ct--left{-webkit-transform:translateX(-5px);transform:translateX(-5px)}.ct--left:after{top:50%;left:auto;right:0;-webkit-transform:translate(41.6%,-50%) rotate(-45deg);transform:translate(41.6%,-50%) rotate(-45deg)}.ct--right{-webkit-transform:translateX(5px);transform:translateX(5px)}.ct--right:after{top:50%;left:0;-webkit-transform:translate(-41.6%,-50%) rotate(-45deg);transform:translate(-41.6%,-50%) rotate(-45deg)}.ct--shown{opacity:1;-webkit-transform:none;transform:none}`;\n }]).default;\n });\n})($t);\nvar di = $t.exports;\nconst hi = /* @__PURE__ */ Fe(di);\nlet U = null;\nfunction nt() {\n U || (U = new hi());\n}\nfunction ui(n, e, t) {\n nt(), U == null || U.show(n, e, t);\n}\nfunction Ne(n = !1) {\n nt(), U == null || U.hide(n);\n}\nfunction Pe(n, e, t) {\n nt(), U == null || U.onHover(n, e, t);\n}\nfunction pi() {\n U == null || U.destroy(), U = null;\n}\nclass fi extends y {\n /**\n * @class\n * @param moduleConfiguration - Module Configuration\n * @param moduleConfiguration.config - Editor's config\n * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher\n */\n constructor({ config: e, eventsDispatcher: t }) {\n super({\n config: e,\n eventsDispatcher: t\n });\n }\n /**\n * Available methods\n */\n get methods() {\n return {\n show: (e, t, o) => this.show(e, t, o),\n hide: () => this.hide(),\n onHover: (e, t, o) => this.onHover(e, t, o)\n };\n }\n /**\n * Method show tooltip on element with passed HTML content\n *\n * @param {HTMLElement} element - element on which tooltip should be shown\n * @param {TooltipContent} content - tooltip content\n * @param {TooltipOptions} options - tooltip options\n */\n show(e, t, o) {\n ui(e, t, o);\n }\n /**\n * Method hides tooltip on HTML page\n */\n hide() {\n Ne();\n }\n /**\n * Decorator for showing Tooltip by mouseenter/mouseleave\n *\n * @param {HTMLElement} element - element on which tooltip should be shown\n * @param {TooltipContent} content - tooltip content\n * @param {TooltipOptions} options - tooltip options\n */\n onHover(e, t, o) {\n Pe(e, t, o);\n }\n}\nclass gi extends y {\n /**\n * Available methods / getters\n */\n get methods() {\n return {\n nodes: this.editorNodes\n /**\n * There can be added some UI methods, like toggleThinMode() etc\n */\n };\n }\n /**\n * Exported classes\n */\n get editorNodes() {\n return {\n /**\n * Top-level editor instance wrapper\n */\n wrapper: this.Editor.UI.nodes.wrapper,\n /**\n * Element that holds all the Blocks\n */\n redactor: this.Editor.UI.nodes.redactor\n };\n }\n}\nfunction Yt(n, e) {\n const t = {};\n return Object.entries(n).forEach(([o, i]) => {\n if (R(i)) {\n const s = e ? `${e}.${o}` : o;\n Object.values(i).every((l) => Q(l)) ? t[o] = s : t[o] = Yt(i, s);\n return;\n }\n t[o] = i;\n }), t;\n}\nconst K = Yt(_t);\nfunction mi(n, e) {\n const t = {};\n return Object.keys(n).forEach((o) => {\n const i = e[o];\n i !== void 0 ? t[i] = n[o] : t[o] = n[o];\n }), t;\n}\nconst Wt = class ve {\n /**\n * @param {HTMLElement[]} nodeList — the list of iterable HTML-items\n * @param {string} focusedCssClass - user-provided CSS-class that will be set in flipping process\n */\n constructor(e, t) {\n this.cursor = -1, this.items = [], this.items = e || [], this.focusedCssClass = t;\n }\n /**\n * Returns Focused button Node\n *\n * @returns {HTMLElement}\n */\n get currentItem() {\n return this.cursor === -1 ? null : this.items[this.cursor];\n }\n /**\n * Sets cursor to specified position\n *\n * @param cursorPosition - new cursor position\n */\n setCursor(e) {\n e < this.items.length && e >= -1 && (this.dropCursor(), this.cursor = e, this.items[this.cursor].classList.add(this.focusedCssClass));\n }\n /**\n * Sets items. Can be used when iterable items changed dynamically\n *\n * @param {HTMLElement[]} nodeList - nodes to iterate\n */\n setItems(e) {\n this.items = e;\n }\n /**\n * Sets cursor next to the current\n */\n next() {\n this.cursor = this.leafNodesAndReturnIndex(ve.directions.RIGHT);\n }\n /**\n * Sets cursor before current\n */\n previous() {\n this.cursor = this.leafNodesAndReturnIndex(ve.directions.LEFT);\n }\n /**\n * Sets cursor to the default position and removes CSS-class from previously focused item\n */\n dropCursor() {\n this.cursor !== -1 && (this.items[this.cursor].classList.remove(this.focusedCssClass), this.cursor = -1);\n }\n /**\n * Leafs nodes inside the target list from active element\n *\n * @param {string} direction - leaf direction. Can be 'left' or 'right'\n * @returns {number} index of focused node\n */\n leafNodesAndReturnIndex(e) {\n if (this.items.length === 0)\n return this.cursor;\n let t = this.cursor;\n return t === -1 ? t = e === ve.directions.RIGHT ? -1 : 0 : this.items[t].classList.remove(this.focusedCssClass), e === ve.directions.RIGHT ? t = (t + 1) % this.items.length : t = (this.items.length + t - 1) % this.items.length, d.canSetCaret(this.items[t]) && Oe(() => b.setCursor(this.items[t]), 50)(), this.items[t].classList.add(this.focusedCssClass), t;\n }\n};\nWt.directions = {\n RIGHT: \"right\",\n LEFT: \"left\"\n};\nlet me = Wt;\nclass le {\n /**\n * @param options - different constructing settings\n */\n constructor(e) {\n this.iterator = null, this.activated = !1, this.flipCallbacks = [], this.onKeyDown = (t) => {\n if (this.isEventReadyForHandling(t))\n switch (le.usedKeys.includes(t.keyCode) && t.preventDefault(), t.keyCode) {\n case w.TAB:\n this.handleTabPress(t);\n break;\n case w.LEFT:\n case w.UP:\n this.flipLeft();\n break;\n case w.RIGHT:\n case w.DOWN:\n this.flipRight();\n break;\n case w.ENTER:\n this.handleEnterPress(t);\n break;\n }\n }, this.iterator = new me(e.items, e.focusedItemClass), this.activateCallback = e.activateCallback, this.allowedKeys = e.allowedKeys || le.usedKeys;\n }\n /**\n * True if flipper is currently activated\n */\n get isActivated() {\n return this.activated;\n }\n /**\n * Array of keys (codes) that is handled by Flipper\n * Used to:\n * - preventDefault only for this keys, not all keydowns (@see constructor)\n * - to skip external behaviours only for these keys, when filler is activated (@see BlockEvents@arrowRightAndDown)\n */\n static get usedKeys() {\n return [\n w.TAB,\n w.LEFT,\n w.RIGHT,\n w.ENTER,\n w.UP,\n w.DOWN\n ];\n }\n /**\n * Active tab/arrows handling by flipper\n *\n * @param items - Some modules (like, InlineToolbar, BlockSettings) might refresh buttons dynamically\n * @param cursorPosition - index of the item that should be focused once flipper is activated\n */\n activate(e, t) {\n this.activated = !0, e && this.iterator.setItems(e), t !== void 0 && this.iterator.setCursor(t), document.addEventListener(\"keydown\", this.onKeyDown, !0);\n }\n /**\n * Disable tab/arrows handling by flipper\n */\n deactivate() {\n this.activated = !1, this.dropCursor(), document.removeEventListener(\"keydown\", this.onKeyDown);\n }\n /**\n * Focus first item\n */\n focusFirst() {\n this.dropCursor(), this.flipRight();\n }\n /**\n * Focuses previous flipper iterator item\n */\n flipLeft() {\n this.iterator.previous(), this.flipCallback();\n }\n /**\n * Focuses next flipper iterator item\n */\n flipRight() {\n this.iterator.next(), this.flipCallback();\n }\n /**\n * Return true if some button is focused\n */\n hasFocus() {\n return !!this.iterator.currentItem;\n }\n /**\n * Registeres function that should be executed on each navigation action\n *\n * @param cb - function to execute\n */\n onFlip(e) {\n this.flipCallbacks.push(e);\n }\n /**\n * Unregisteres function that is executed on each navigation action\n *\n * @param cb - function to stop executing\n */\n removeOnFlip(e) {\n this.flipCallbacks = this.flipCallbacks.filter((t) => t !== e);\n }\n /**\n * Drops flipper's iterator cursor\n *\n * @see DomIterator#dropCursor\n */\n dropCursor() {\n this.iterator.dropCursor();\n }\n /**\n * This function is fired before handling flipper keycodes\n * The result of this function defines if it is need to be handled or not\n *\n * @param {KeyboardEvent} event - keydown keyboard event\n * @returns {boolean}\n */\n isEventReadyForHandling(e) {\n return this.activated && this.allowedKeys.includes(e.keyCode);\n }\n /**\n * When flipper is activated tab press will leaf the items\n *\n * @param {KeyboardEvent} event - tab keydown event\n */\n handleTabPress(e) {\n switch (e.shiftKey ? me.directions.LEFT : me.directions.RIGHT) {\n case me.directions.RIGHT:\n this.flipRight();\n break;\n case me.directions.LEFT:\n this.flipLeft();\n break;\n }\n }\n /**\n * Enter press will click current item if flipper is activated\n *\n * @param {KeyboardEvent} event - enter keydown event\n */\n handleEnterPress(e) {\n this.activated && (this.iterator.currentItem && (e.stopPropagation(), e.preventDefault(), this.iterator.currentItem.click()), O(this.activateCallback) && this.activateCallback(this.iterator.currentItem));\n }\n /**\n * Fired after flipping in any direction\n */\n flipCallback() {\n this.iterator.currentItem && this.iterator.currentItem.scrollIntoViewIfNeeded(), this.flipCallbacks.forEach((e) => e());\n }\n}\nconst bi = '', ki = '', vi = '', wi = '', xi = '', yi = '', Ei = '', Bi = '', yt = '', Ti = '', Ci = '', Kt = '', Si = '', Ii = '', Mi = '', Ai = \"__\", Oi = \"--\";\nfunction te(n) {\n return (e, t) => [[n, e].filter((i) => !!i).join(Ai), t].filter((i) => !!i).join(Oi);\n}\nconst be = te(\"ce-hint\"), ke = {\n root: be(),\n alignedStart: be(null, \"align-left\"),\n alignedCenter: be(null, \"align-center\"),\n title: be(\"title\"),\n description: be(\"description\")\n};\nclass Li {\n /**\n * Constructs the hint content instance\n *\n * @param params - hint content parameters\n */\n constructor(e) {\n this.nodes = {\n root: d.make(\"div\", [ke.root, e.alignment === \"center\" ? ke.alignedCenter : ke.alignedStart]),\n title: d.make(\"div\", ke.title, { textContent: e.title })\n }, this.nodes.root.appendChild(this.nodes.title), e.description !== void 0 && (this.nodes.description = d.make(\"div\", ke.description, { textContent: e.description }), this.nodes.root.appendChild(this.nodes.description));\n }\n /**\n * Returns the root element of the hint content\n */\n getElement() {\n return this.nodes.root;\n }\n}\nclass rt {\n /**\n * Constructs the instance\n *\n * @param params - instance parameters\n */\n constructor(e) {\n this.params = e;\n }\n /**\n * Item name if exists\n */\n get name() {\n if (this.params !== void 0 && \"name\" in this.params)\n return this.params.name;\n }\n /**\n * Destroys the instance\n */\n destroy() {\n Ne();\n }\n /**\n * Called when children popover is opened (if exists)\n */\n onChildrenOpen() {\n var e;\n this.params !== void 0 && \"children\" in this.params && typeof ((e = this.params.children) == null ? void 0 : e.onOpen) == \"function\" && this.params.children.onOpen();\n }\n /**\n * Called when children popover is closed (if exists)\n */\n onChildrenClose() {\n var e;\n this.params !== void 0 && \"children\" in this.params && typeof ((e = this.params.children) == null ? void 0 : e.onClose) == \"function\" && this.params.children.onClose();\n }\n /**\n * Called on popover item click\n */\n handleClick() {\n var e, t;\n this.params !== void 0 && \"onActivate\" in this.params && ((t = (e = this.params).onActivate) == null || t.call(e, this.params));\n }\n /**\n * Adds hint to the item element if hint data is provided\n *\n * @param itemElement - popover item root element to add hint to\n * @param hintData - hint data\n */\n addHint(e, t) {\n const o = new Li(t);\n Pe(e, o.getElement(), {\n placement: t.position,\n hidingDelay: 100\n });\n }\n /**\n * Returns item children that are represented as popover items\n */\n get children() {\n var e;\n return this.params !== void 0 && \"children\" in this.params && ((e = this.params.children) == null ? void 0 : e.items) !== void 0 ? this.params.children.items : [];\n }\n /**\n * Returns true if item has any type of children\n */\n get hasChildren() {\n return this.children.length > 0;\n }\n /**\n * Returns true if item children should be open instantly after popover is opened and not on item click/hover\n */\n get isChildrenOpen() {\n var e;\n return this.params !== void 0 && \"children\" in this.params && ((e = this.params.children) == null ? void 0 : e.isOpen) === !0;\n }\n /**\n * True if item children items should be navigatable via keyboard\n */\n get isChildrenFlippable() {\n var e;\n return !(this.params === void 0 || !(\"children\" in this.params) || ((e = this.params.children) == null ? void 0 : e.isFlippable) === !1);\n }\n /**\n * Returns true if item has children that should be searchable\n */\n get isChildrenSearchable() {\n var e;\n return this.params !== void 0 && \"children\" in this.params && ((e = this.params.children) == null ? void 0 : e.searchable) === !0;\n }\n /**\n * True if popover should close once item is activated\n */\n get closeOnActivate() {\n return this.params !== void 0 && \"closeOnActivate\" in this.params && this.params.closeOnActivate;\n }\n /**\n * True if item is active\n */\n get isActive() {\n return this.params === void 0 || !(\"isActive\" in this.params) ? !1 : typeof this.params.isActive == \"function\" ? this.params.isActive() : this.params.isActive === !0;\n }\n}\nconst W = te(\"ce-popover-item\"), L = {\n container: W(),\n active: W(null, \"active\"),\n disabled: W(null, \"disabled\"),\n focused: W(null, \"focused\"),\n hidden: W(null, \"hidden\"),\n confirmationState: W(null, \"confirmation\"),\n noHover: W(null, \"no-hover\"),\n noFocus: W(null, \"no-focus\"),\n title: W(\"title\"),\n secondaryTitle: W(\"secondary-title\"),\n icon: W(\"icon\"),\n iconTool: W(\"icon\", \"tool\"),\n iconChevronRight: W(\"icon\", \"chevron-right\"),\n wobbleAnimation: te(\"wobble\")()\n};\nclass se extends rt {\n /**\n * Constructs popover item instance\n *\n * @param params - popover item construction params\n * @param renderParams - popover item render params.\n * The parameters that are not set by user via popover api but rather depend on technical implementation\n */\n constructor(e, t) {\n super(e), this.params = e, this.nodes = {\n root: null,\n icon: null\n }, this.confirmationState = null, this.removeSpecialFocusBehavior = () => {\n var o;\n (o = this.nodes.root) == null || o.classList.remove(L.noFocus);\n }, this.removeSpecialHoverBehavior = () => {\n var o;\n (o = this.nodes.root) == null || o.classList.remove(L.noHover);\n }, this.onErrorAnimationEnd = () => {\n var o, i;\n (o = this.nodes.icon) == null || o.classList.remove(L.wobbleAnimation), (i = this.nodes.icon) == null || i.removeEventListener(\"animationend\", this.onErrorAnimationEnd);\n }, this.nodes.root = this.make(e, t);\n }\n /**\n * True if item is disabled and hence not clickable\n */\n get isDisabled() {\n return this.params.isDisabled === !0;\n }\n /**\n * Exposes popover item toggle parameter\n */\n get toggle() {\n return this.params.toggle;\n }\n /**\n * Item title\n */\n get title() {\n return this.params.title;\n }\n /**\n * True if confirmation state is enabled for popover item\n */\n get isConfirmationStateEnabled() {\n return this.confirmationState !== null;\n }\n /**\n * True if item is focused in keyboard navigation process\n */\n get isFocused() {\n return this.nodes.root === null ? !1 : this.nodes.root.classList.contains(L.focused);\n }\n /**\n * Returns popover item root element\n */\n getElement() {\n return this.nodes.root;\n }\n /**\n * Called on popover item click\n */\n handleClick() {\n if (this.isConfirmationStateEnabled && this.confirmationState !== null) {\n this.activateOrEnableConfirmationMode(this.confirmationState);\n return;\n }\n this.activateOrEnableConfirmationMode(this.params);\n }\n /**\n * Toggles item active state\n *\n * @param isActive - true if item should strictly should become active\n */\n toggleActive(e) {\n var t;\n (t = this.nodes.root) == null || t.classList.toggle(L.active, e);\n }\n /**\n * Toggles item hidden state\n *\n * @param isHidden - true if item should be hidden\n */\n toggleHidden(e) {\n var t;\n (t = this.nodes.root) == null || t.classList.toggle(L.hidden, e);\n }\n /**\n * Resets popover item to its original state\n */\n reset() {\n this.isConfirmationStateEnabled && this.disableConfirmationMode();\n }\n /**\n * Method called once item becomes focused during keyboard navigation\n */\n onFocus() {\n this.disableSpecialHoverAndFocusBehavior();\n }\n /**\n * Constructs HTML element corresponding to popover item params\n *\n * @param params - item construction params\n * @param renderParams - popover item render params\n */\n make(e, t) {\n var s, r;\n const o = (t == null ? void 0 : t.wrapperTag) || \"div\", i = d.make(o, L.container, {\n type: o === \"button\" ? \"button\" : void 0\n });\n return e.name && (i.dataset.itemName = e.name), this.nodes.icon = d.make(\"div\", [L.icon, L.iconTool], {\n innerHTML: e.icon || Ei\n }), i.appendChild(this.nodes.icon), e.title !== void 0 && i.appendChild(d.make(\"div\", L.title, {\n innerHTML: e.title || \"\"\n })), e.secondaryLabel && i.appendChild(d.make(\"div\", L.secondaryTitle, {\n textContent: e.secondaryLabel\n })), this.hasChildren && i.appendChild(d.make(\"div\", [L.icon, L.iconChevronRight], {\n innerHTML: wi\n })), this.isActive && i.classList.add(L.active), e.isDisabled && i.classList.add(L.disabled), e.hint !== void 0 && ((s = t == null ? void 0 : t.hint) == null ? void 0 : s.enabled) !== !1 && this.addHint(i, {\n ...e.hint,\n position: ((r = t == null ? void 0 : t.hint) == null ? void 0 : r.position) || \"right\"\n }), i;\n }\n /**\n * Activates confirmation mode for the item.\n *\n * @param newState - new popover item params that should be applied\n */\n enableConfirmationMode(e) {\n if (this.nodes.root === null)\n return;\n const t = {\n ...this.params,\n ...e,\n confirmation: \"confirmation\" in e ? e.confirmation : void 0\n }, o = this.make(t);\n this.nodes.root.innerHTML = o.innerHTML, this.nodes.root.classList.add(L.confirmationState), this.confirmationState = e, this.enableSpecialHoverAndFocusBehavior();\n }\n /**\n * Returns item to its original state\n */\n disableConfirmationMode() {\n if (this.nodes.root === null)\n return;\n const e = this.make(this.params);\n this.nodes.root.innerHTML = e.innerHTML, this.nodes.root.classList.remove(L.confirmationState), this.confirmationState = null, this.disableSpecialHoverAndFocusBehavior();\n }\n /**\n * Enables special focus and hover behavior for item in confirmation state.\n * This is needed to prevent item from being highlighted as hovered/focused just after click.\n */\n enableSpecialHoverAndFocusBehavior() {\n var e, t, o;\n (e = this.nodes.root) == null || e.classList.add(L.noHover), (t = this.nodes.root) == null || t.classList.add(L.noFocus), (o = this.nodes.root) == null || o.addEventListener(\"mouseleave\", this.removeSpecialHoverBehavior, { once: !0 });\n }\n /**\n * Disables special focus and hover behavior\n */\n disableSpecialHoverAndFocusBehavior() {\n var e;\n this.removeSpecialFocusBehavior(), this.removeSpecialHoverBehavior(), (e = this.nodes.root) == null || e.removeEventListener(\"mouseleave\", this.removeSpecialHoverBehavior);\n }\n /**\n * Executes item's onActivate callback if the item has no confirmation configured\n *\n * @param item - item to activate or bring to confirmation mode\n */\n activateOrEnableConfirmationMode(e) {\n var t;\n if (!(\"confirmation\" in e) || e.confirmation === void 0)\n try {\n (t = e.onActivate) == null || t.call(e, e), this.disableConfirmationMode();\n } catch {\n this.animateError();\n }\n else\n this.enableConfirmationMode(e.confirmation);\n }\n /**\n * Animates item which symbolizes that error occured while executing 'onActivate()' callback\n */\n animateError() {\n var e, t, o;\n (e = this.nodes.icon) != null && e.classList.contains(L.wobbleAnimation) || ((t = this.nodes.icon) == null || t.classList.add(L.wobbleAnimation), (o = this.nodes.icon) == null || o.addEventListener(\"animationend\", this.onErrorAnimationEnd));\n }\n}\nconst Ue = te(\"ce-popover-item-separator\"), je = {\n container: Ue(),\n line: Ue(\"line\"),\n hidden: Ue(null, \"hidden\")\n};\nclass Xt extends rt {\n /**\n * Constructs the instance\n */\n constructor() {\n super(), this.nodes = {\n root: d.make(\"div\", je.container),\n line: d.make(\"div\", je.line)\n }, this.nodes.root.appendChild(this.nodes.line);\n }\n /**\n * Returns popover separator root element\n */\n getElement() {\n return this.nodes.root;\n }\n /**\n * Toggles item hidden state\n *\n * @param isHidden - true if item should be hidden\n */\n toggleHidden(e) {\n var t;\n (t = this.nodes.root) == null || t.classList.toggle(je.hidden, e);\n }\n}\nvar Z = /* @__PURE__ */ ((n) => (n.Closed = \"closed\", n.ClosedOnActivate = \"closed-on-activate\", n))(Z || {});\nconst H = te(\"ce-popover\"), N = {\n popover: H(),\n popoverContainer: H(\"container\"),\n popoverOpenTop: H(null, \"open-top\"),\n popoverOpenLeft: H(null, \"open-left\"),\n popoverOpened: H(null, \"opened\"),\n search: H(\"search\"),\n nothingFoundMessage: H(\"nothing-found-message\"),\n nothingFoundMessageDisplayed: H(\"nothing-found-message\", \"displayed\"),\n items: H(\"items\"),\n overlay: H(\"overlay\"),\n overlayHidden: H(\"overlay\", \"hidden\"),\n popoverNested: H(null, \"nested\"),\n getPopoverNestedClass: (n) => H(null, `nested-level-${n.toString()}`),\n popoverInline: H(null, \"inline\"),\n popoverHeader: H(\"header\")\n};\nvar de = /* @__PURE__ */ ((n) => (n.NestingLevel = \"--nesting-level\", n.PopoverHeight = \"--popover-height\", n.InlinePopoverWidth = \"--inline-popover-width\", n.TriggerItemLeft = \"--trigger-item-left\", n.TriggerItemTop = \"--trigger-item-top\", n))(de || {});\nconst Et = te(\"ce-popover-item-html\"), Bt = {\n root: Et(),\n hidden: Et(null, \"hidden\")\n};\nclass Ee extends rt {\n /**\n * Constructs the instance\n *\n * @param params – instance parameters\n * @param renderParams – popover item render params.\n * The parameters that are not set by user via popover api but rather depend on technical implementation\n */\n constructor(e, t) {\n var o, i;\n super(e), this.nodes = {\n root: d.make(\"div\", Bt.root)\n }, this.nodes.root.appendChild(e.element), e.name && (this.nodes.root.dataset.itemName = e.name), e.hint !== void 0 && ((o = t == null ? void 0 : t.hint) == null ? void 0 : o.enabled) !== !1 && this.addHint(this.nodes.root, {\n ...e.hint,\n position: ((i = t == null ? void 0 : t.hint) == null ? void 0 : i.position) || \"right\"\n });\n }\n /**\n * Returns popover item root element\n */\n getElement() {\n return this.nodes.root;\n }\n /**\n * Toggles item hidden state\n *\n * @param isHidden - true if item should be hidden\n */\n toggleHidden(e) {\n var t;\n (t = this.nodes.root) == null || t.classList.toggle(Bt.hidden, e);\n }\n /**\n * Returns list of buttons and inputs inside custom content\n */\n getControls() {\n const e = this.nodes.root.querySelectorAll(\n `button, ${d.allInputsSelector}`\n );\n return Array.from(e);\n }\n}\nclass Vt extends Te {\n /**\n * Constructs the instance\n *\n * @param params - popover construction params\n * @param itemsRenderParams - popover item render params.\n * The parameters that are not set by user via popover api but rather depend on technical implementation\n */\n constructor(e, t = {}) {\n super(), this.params = e, this.itemsRenderParams = t, this.listeners = new Ce(), this.messages = {\n nothingFound: \"Nothing found\",\n search: \"Search\"\n }, this.items = this.buildItems(e.items), e.messages && (this.messages = {\n ...this.messages,\n ...e.messages\n }), this.nodes = {}, this.nodes.popoverContainer = d.make(\"div\", [N.popoverContainer]), this.nodes.nothingFoundMessage = d.make(\"div\", [N.nothingFoundMessage], {\n textContent: this.messages.nothingFound\n }), this.nodes.popoverContainer.appendChild(this.nodes.nothingFoundMessage), this.nodes.items = d.make(\"div\", [N.items]), this.items.forEach((o) => {\n const i = o.getElement();\n i !== null && this.nodes.items.appendChild(i);\n }), this.nodes.popoverContainer.appendChild(this.nodes.items), this.listeners.on(this.nodes.popoverContainer, \"click\", (o) => this.handleClick(o)), this.nodes.popover = d.make(\"div\", [\n N.popover,\n this.params.class\n ]), this.nodes.popover.appendChild(this.nodes.popoverContainer);\n }\n /**\n * List of default popover items that are searchable and may have confirmation state\n */\n get itemsDefault() {\n return this.items.filter((e) => e instanceof se);\n }\n /**\n * Returns HTML element corresponding to the popover\n */\n getElement() {\n return this.nodes.popover;\n }\n /**\n * Open popover\n */\n show() {\n this.nodes.popover.classList.add(N.popoverOpened), this.search !== void 0 && this.search.focus();\n }\n /**\n * Closes popover\n */\n hide() {\n this.nodes.popover.classList.remove(N.popoverOpened), this.nodes.popover.classList.remove(N.popoverOpenTop), this.itemsDefault.forEach((e) => e.reset()), this.search !== void 0 && this.search.clear(), this.emit(Z.Closed);\n }\n /**\n * Clears memory\n */\n destroy() {\n var e;\n this.items.forEach((t) => t.destroy()), this.nodes.popover.remove(), this.listeners.removeAll(), (e = this.search) == null || e.destroy();\n }\n /**\n * Looks for the item by name and imitates click on it\n *\n * @param name - name of the item to activate\n */\n activateItemByName(e) {\n const t = this.items.find((o) => o.name === e);\n this.handleItemClick(t);\n }\n /**\n * Factory method for creating popover items\n *\n * @param items - list of items params\n */\n buildItems(e) {\n return e.map((t) => {\n switch (t.type) {\n case A.Separator:\n return new Xt();\n case A.Html:\n return new Ee(t, this.itemsRenderParams[A.Html]);\n default:\n return new se(t, this.itemsRenderParams[A.Default]);\n }\n });\n }\n /**\n * Retrieves popover item that is the target of the specified event\n *\n * @param event - event to retrieve popover item from\n */\n getTargetItem(e) {\n return this.items.filter((t) => t instanceof se || t instanceof Ee).find((t) => {\n const o = t.getElement();\n return o === null ? !1 : e.composedPath().includes(o);\n });\n }\n /**\n * Handles popover item click\n *\n * @param item - item to handle click of\n */\n handleItemClick(e) {\n if (!(\"isDisabled\" in e && e.isDisabled)) {\n if (e.hasChildren) {\n this.showNestedItems(e), \"handleClick\" in e && typeof e.handleClick == \"function\" && e.handleClick();\n return;\n }\n this.itemsDefault.filter((t) => t !== e).forEach((t) => t.reset()), \"handleClick\" in e && typeof e.handleClick == \"function\" && e.handleClick(), this.toggleItemActivenessIfNeeded(e), e.closeOnActivate && (this.hide(), this.emit(Z.ClosedOnActivate));\n }\n }\n /**\n * Handles clicks inside popover\n *\n * @param event - item to handle click of\n */\n handleClick(e) {\n const t = this.getTargetItem(e);\n t !== void 0 && this.handleItemClick(t);\n }\n /**\n * - Toggles item active state, if clicked popover item has property 'toggle' set to true.\n *\n * - Performs radiobutton-like behavior if the item has property 'toggle' set to string key.\n * (All the other items with the same key get inactive, and the item gets active)\n *\n * @param clickedItem - popover item that was clicked\n */\n toggleItemActivenessIfNeeded(e) {\n if (e instanceof se && (e.toggle === !0 && e.toggleActive(), typeof e.toggle == \"string\")) {\n const t = this.itemsDefault.filter((o) => o.toggle === e.toggle);\n if (t.length === 1) {\n e.toggleActive();\n return;\n }\n t.forEach((o) => {\n o.toggleActive(o === e);\n });\n }\n }\n}\nvar De = /* @__PURE__ */ ((n) => (n.Search = \"search\", n))(De || {});\nconst $e = te(\"cdx-search-field\"), Ye = {\n wrapper: $e(),\n icon: $e(\"icon\"),\n input: $e(\"input\")\n};\nclass _i extends Te {\n /**\n * @param options - available config\n * @param options.items - searchable items list\n * @param options.placeholder - input placeholder\n */\n constructor({ items: e, placeholder: t }) {\n super(), this.listeners = new Ce(), this.items = e, this.wrapper = d.make(\"div\", Ye.wrapper);\n const o = d.make(\"div\", Ye.icon, {\n innerHTML: Si\n });\n this.input = d.make(\"input\", Ye.input, {\n placeholder: t,\n /**\n * Used to prevent focusing on the input by Tab key\n * (Popover in the Toolbar lays below the blocks,\n * so Tab in the last block will focus this hidden input if this property is not set)\n */\n tabIndex: -1\n }), this.wrapper.appendChild(o), this.wrapper.appendChild(this.input), this.listeners.on(this.input, \"input\", () => {\n this.searchQuery = this.input.value, this.emit(De.Search, {\n query: this.searchQuery,\n items: this.foundItems\n });\n });\n }\n /**\n * Returns search field element\n */\n getElement() {\n return this.wrapper;\n }\n /**\n * Sets focus to the input\n */\n focus() {\n this.input.focus();\n }\n /**\n * Clears search query and results\n */\n clear() {\n this.input.value = \"\", this.searchQuery = \"\", this.emit(De.Search, {\n query: \"\",\n items: this.foundItems\n });\n }\n /**\n * Clears memory\n */\n destroy() {\n this.listeners.removeAll();\n }\n /**\n * Returns list of found items for the current search query\n */\n get foundItems() {\n return this.items.filter((e) => this.checkItem(e));\n }\n /**\n * Contains logic for checking whether passed item conforms the search query\n *\n * @param item - item to be checked\n */\n checkItem(e) {\n var i, s;\n const t = ((i = e.title) == null ? void 0 : i.toLowerCase()) || \"\", o = (s = this.searchQuery) == null ? void 0 : s.toLowerCase();\n return o !== void 0 ? t.includes(o) : !1;\n }\n}\nvar Ni = Object.defineProperty, Pi = Object.getOwnPropertyDescriptor, Di = (n, e, t, o) => {\n for (var i = o > 1 ? void 0 : o ? Pi(e, t) : e, s = n.length - 1, r; s >= 0; s--)\n (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i);\n return o && i && Ni(e, t, i), i;\n};\nconst qt = class Zt extends Vt {\n /**\n * Construct the instance\n *\n * @param params - popover params\n * @param itemsRenderParams – popover item render params.\n * The parameters that are not set by user via popover api but rather depend on technical implementation\n */\n constructor(e, t) {\n super(e, t), this.nestingLevel = 0, this.nestedPopoverTriggerItem = null, this.previouslyHoveredItem = null, this.scopeElement = document.body, this.hide = () => {\n var o;\n super.hide(), this.destroyNestedPopoverIfExists(), (o = this.flipper) == null || o.deactivate(), this.previouslyHoveredItem = null;\n }, this.onFlip = () => {\n const o = this.itemsDefault.find((i) => i.isFocused);\n o == null || o.onFocus();\n }, this.onSearch = (o) => {\n var l;\n const i = o.query === \"\", s = o.items.length === 0;\n this.items.forEach((a) => {\n let c = !1;\n a instanceof se ? c = !o.items.includes(a) : (a instanceof Xt || a instanceof Ee) && (c = s || !i), a.toggleHidden(c);\n }), this.toggleNothingFoundMessage(s);\n const r = o.query === \"\" ? this.flippableElements : o.items.map((a) => a.getElement());\n (l = this.flipper) != null && l.isActivated && (this.flipper.deactivate(), this.flipper.activate(r));\n }, e.nestingLevel !== void 0 && (this.nestingLevel = e.nestingLevel), this.nestingLevel > 0 && this.nodes.popover.classList.add(N.popoverNested), e.scopeElement !== void 0 && (this.scopeElement = e.scopeElement), this.nodes.popoverContainer !== null && this.listeners.on(this.nodes.popoverContainer, \"mouseover\", (o) => this.handleHover(o)), e.searchable && this.addSearch(), e.flippable !== !1 && (this.flipper = new le({\n items: this.flippableElements,\n focusedItemClass: L.focused,\n allowedKeys: [\n w.TAB,\n w.UP,\n w.DOWN,\n w.ENTER\n ]\n }), this.flipper.onFlip(this.onFlip));\n }\n /**\n * Returns true if some item inside popover is focused\n */\n hasFocus() {\n return this.flipper === void 0 ? !1 : this.flipper.hasFocus();\n }\n /**\n * Scroll position inside items container of the popover\n */\n get scrollTop() {\n return this.nodes.items === null ? 0 : this.nodes.items.scrollTop;\n }\n /**\n * Returns visible element offset top\n */\n get offsetTop() {\n return this.nodes.popoverContainer === null ? 0 : this.nodes.popoverContainer.offsetTop;\n }\n /**\n * Open popover\n */\n show() {\n var e;\n this.nodes.popover.style.setProperty(de.PopoverHeight, this.size.height + \"px\"), this.shouldOpenBottom || this.nodes.popover.classList.add(N.popoverOpenTop), this.shouldOpenRight || this.nodes.popover.classList.add(N.popoverOpenLeft), super.show(), (e = this.flipper) == null || e.activate(this.flippableElements);\n }\n /**\n * Clears memory\n */\n destroy() {\n this.hide(), super.destroy();\n }\n /**\n * Handles displaying nested items for the item.\n *\n * @param item – item to show nested popover for\n */\n showNestedItems(e) {\n this.nestedPopover !== null && this.nestedPopover !== void 0 || (this.nestedPopoverTriggerItem = e, this.showNestedPopoverForItem(e));\n }\n /**\n * Handles hover events inside popover items container\n *\n * @param event - hover event data\n */\n handleHover(e) {\n const t = this.getTargetItem(e);\n t !== void 0 && this.previouslyHoveredItem !== t && (this.destroyNestedPopoverIfExists(), this.previouslyHoveredItem = t, t.hasChildren && this.showNestedPopoverForItem(t));\n }\n /**\n * Sets CSS variable with position of item near which nested popover should be displayed.\n * Is used for correct positioning of the nested popover\n *\n * @param nestedPopoverEl - nested popover element\n * @param item – item near which nested popover should be displayed\n */\n setTriggerItemPosition(e, t) {\n const o = t.getElement(), i = (o ? o.offsetTop : 0) - this.scrollTop, s = this.offsetTop + i;\n e.style.setProperty(de.TriggerItemTop, s + \"px\");\n }\n /**\n * Destroys existing nested popover\n */\n destroyNestedPopoverIfExists() {\n var e, t;\n this.nestedPopover === void 0 || this.nestedPopover === null || (this.nestedPopover.off(Z.ClosedOnActivate, this.hide), this.nestedPopover.hide(), this.nestedPopover.destroy(), this.nestedPopover.getElement().remove(), this.nestedPopover = null, (e = this.flipper) == null || e.activate(this.flippableElements), (t = this.nestedPopoverTriggerItem) == null || t.onChildrenClose());\n }\n /**\n * Creates and displays nested popover for specified item.\n * Is used only on desktop\n *\n * @param item - item to display nested popover by\n */\n showNestedPopoverForItem(e) {\n var o;\n this.nestedPopover = new Zt({\n searchable: e.isChildrenSearchable,\n items: e.children,\n nestingLevel: this.nestingLevel + 1,\n flippable: e.isChildrenFlippable,\n messages: this.messages\n }), e.onChildrenOpen(), this.nestedPopover.on(Z.ClosedOnActivate, this.hide);\n const t = this.nestedPopover.getElement();\n return this.nodes.popover.appendChild(t), this.setTriggerItemPosition(t, e), t.style.setProperty(de.NestingLevel, this.nestedPopover.nestingLevel.toString()), this.nestedPopover.show(), (o = this.flipper) == null || o.deactivate(), this.nestedPopover;\n }\n /**\n * Checks if popover should be opened bottom.\n * It should happen when there is enough space below or not enough space above\n */\n get shouldOpenBottom() {\n if (this.nodes.popover === void 0 || this.nodes.popover === null)\n return !1;\n const e = this.nodes.popoverContainer.getBoundingClientRect(), t = this.scopeElement.getBoundingClientRect(), o = this.size.height, i = e.top + o, s = e.top - o, r = Math.min(window.innerHeight, t.bottom);\n return s < t.top || i <= r;\n }\n /**\n * Checks if popover should be opened left.\n * It should happen when there is enough space in the right or not enough space in the left\n */\n get shouldOpenRight() {\n if (this.nodes.popover === void 0 || this.nodes.popover === null)\n return !1;\n const e = this.nodes.popover.getBoundingClientRect(), t = this.scopeElement.getBoundingClientRect(), o = this.size.width, i = e.right + o, s = e.left - o, r = Math.min(window.innerWidth, t.right);\n return s < t.left || i <= r;\n }\n get size() {\n var i;\n const e = {\n height: 0,\n width: 0\n };\n if (this.nodes.popover === null)\n return e;\n const t = this.nodes.popover.cloneNode(!0);\n t.style.visibility = \"hidden\", t.style.position = \"absolute\", t.style.top = \"-1000px\", t.classList.add(N.popoverOpened), (i = t.querySelector(\".\" + N.popoverNested)) == null || i.remove(), document.body.appendChild(t);\n const o = t.querySelector(\".\" + N.popoverContainer);\n return e.height = o.offsetHeight, e.width = o.offsetWidth, t.remove(), e;\n }\n /**\n * Returns list of elements available for keyboard navigation.\n */\n get flippableElements() {\n return this.items.map((t) => {\n if (t instanceof se)\n return t.getElement();\n if (t instanceof Ee)\n return t.getControls();\n }).flat().filter((t) => t != null);\n }\n /**\n * Adds search to the popover\n */\n addSearch() {\n this.search = new _i({\n items: this.itemsDefault,\n placeholder: this.messages.search\n }), this.search.on(De.Search, this.onSearch);\n const e = this.search.getElement();\n e.classList.add(N.search), this.nodes.popoverContainer.insertBefore(e, this.nodes.popoverContainer.firstChild);\n }\n /**\n * Toggles nothing found message visibility\n *\n * @param isDisplayed - true if the message should be displayed\n */\n toggleNothingFoundMessage(e) {\n this.nodes.nothingFoundMessage.classList.toggle(N.nothingFoundMessageDisplayed, e);\n }\n};\nDi([\n ue\n], qt.prototype, \"size\", 1);\nlet lt = qt;\nclass Ri extends lt {\n /**\n * Constructs the instance\n *\n * @param params - instance parameters\n */\n constructor(e) {\n const t = !pe();\n super(\n {\n ...e,\n class: N.popoverInline\n },\n {\n [A.Default]: {\n /**\n * We use button instead of div here to fix bug associated with focus loss (which leads to selection change) on click in safari\n *\n * @todo figure out better way to solve the issue\n */\n wrapperTag: \"button\",\n hint: {\n position: \"top\",\n alignment: \"center\",\n enabled: t\n }\n },\n [A.Html]: {\n hint: {\n position: \"top\",\n alignment: \"center\",\n enabled: t\n }\n }\n }\n ), this.items.forEach((o) => {\n !(o instanceof se) && !(o instanceof Ee) || o.hasChildren && o.isChildrenOpen && this.showNestedItems(o);\n });\n }\n /**\n * Returns visible element offset top\n */\n get offsetLeft() {\n return this.nodes.popoverContainer === null ? 0 : this.nodes.popoverContainer.offsetLeft;\n }\n /**\n * Open popover\n */\n show() {\n this.nestingLevel === 0 && this.nodes.popover.style.setProperty(\n de.InlinePopoverWidth,\n this.size.width + \"px\"\n ), super.show();\n }\n /**\n * Disable hover event handling.\n * Overrides parent's class behavior\n */\n handleHover() {\n }\n /**\n * Sets CSS variable with position of item near which nested popover should be displayed.\n * Is used to position nested popover right below clicked item\n *\n * @param nestedPopoverEl - nested popover element\n * @param item – item near which nested popover should be displayed\n */\n setTriggerItemPosition(e, t) {\n const o = t.getElement(), i = o ? o.offsetLeft : 0, s = this.offsetLeft + i;\n e.style.setProperty(\n de.TriggerItemLeft,\n s + \"px\"\n );\n }\n /**\n * Handles displaying nested items for the item.\n * Overriding in order to add toggling behaviour\n *\n * @param item – item to toggle nested popover for\n */\n showNestedItems(e) {\n if (this.nestedPopoverTriggerItem === e) {\n this.destroyNestedPopoverIfExists(), this.nestedPopoverTriggerItem = null;\n return;\n }\n super.showNestedItems(e);\n }\n /**\n * Creates and displays nested popover for specified item.\n * Is used only on desktop\n *\n * @param item - item to display nested popover by\n */\n showNestedPopoverForItem(e) {\n const t = super.showNestedPopoverForItem(e);\n return t.getElement().classList.add(N.getPopoverNestedClass(t.nestingLevel)), t;\n }\n /**\n * Overrides default item click handling.\n * Helps to close nested popover once other item is clicked.\n *\n * @param item - clicked item\n */\n handleItemClick(e) {\n var t;\n e !== this.nestedPopoverTriggerItem && ((t = this.nestedPopoverTriggerItem) == null || t.handleClick(), super.destroyNestedPopoverIfExists()), super.handleItemClick(e);\n }\n}\nconst Gt = class we {\n constructor() {\n this.scrollPosition = null;\n }\n /**\n * Locks body element scroll\n */\n lock() {\n Ge ? this.lockHard() : document.body.classList.add(we.CSS.scrollLocked);\n }\n /**\n * Unlocks body element scroll\n */\n unlock() {\n Ge ? this.unlockHard() : document.body.classList.remove(we.CSS.scrollLocked);\n }\n /**\n * Locks scroll in a hard way (via setting fixed position to body element)\n */\n lockHard() {\n this.scrollPosition = window.pageYOffset, document.documentElement.style.setProperty(\n \"--window-scroll-offset\",\n `${this.scrollPosition}px`\n ), document.body.classList.add(we.CSS.scrollLockedHard);\n }\n /**\n * Unlocks hard scroll lock\n */\n unlockHard() {\n document.body.classList.remove(we.CSS.scrollLockedHard), this.scrollPosition !== null && window.scrollTo(0, this.scrollPosition), this.scrollPosition = null;\n }\n};\nGt.CSS = {\n scrollLocked: \"ce-scroll-locked\",\n scrollLockedHard: \"ce-scroll-locked--hard\"\n};\nlet Fi = Gt;\nconst We = te(\"ce-popover-header\"), Ke = {\n root: We(),\n text: We(\"text\"),\n backButton: We(\"back-button\")\n};\nclass Hi {\n /**\n * Constructs the instance\n *\n * @param params - popover header params\n */\n constructor({ text: e, onBackButtonClick: t }) {\n this.listeners = new Ce(), this.text = e, this.onBackButtonClick = t, this.nodes = {\n root: d.make(\"div\", [Ke.root]),\n backButton: d.make(\"button\", [Ke.backButton]),\n text: d.make(\"div\", [Ke.text])\n }, this.nodes.backButton.innerHTML = vi, this.nodes.root.appendChild(this.nodes.backButton), this.listeners.on(this.nodes.backButton, \"click\", this.onBackButtonClick), this.nodes.text.innerText = this.text, this.nodes.root.appendChild(this.nodes.text);\n }\n /**\n * Returns popover header root html element\n */\n getElement() {\n return this.nodes.root;\n }\n /**\n * Destroys the instance\n */\n destroy() {\n this.nodes.root.remove(), this.listeners.destroy();\n }\n}\nclass zi {\n constructor() {\n this.history = [];\n }\n /**\n * Push new popover state\n *\n * @param state - new state\n */\n push(e) {\n this.history.push(e);\n }\n /**\n * Pop last popover state\n */\n pop() {\n return this.history.pop();\n }\n /**\n * Title retrieved from the current state\n */\n get currentTitle() {\n return this.history.length === 0 ? \"\" : this.history[this.history.length - 1].title;\n }\n /**\n * Items list retrieved from the current state\n */\n get currentItems() {\n return this.history.length === 0 ? [] : this.history[this.history.length - 1].items;\n }\n /**\n * Returns history to initial popover state\n */\n reset() {\n for (; this.history.length > 1; )\n this.pop();\n }\n}\nclass Jt extends Vt {\n /**\n * Construct the instance\n *\n * @param params - popover params\n */\n constructor(e) {\n super(e, {\n [A.Default]: {\n hint: {\n enabled: !1\n }\n },\n [A.Html]: {\n hint: {\n enabled: !1\n }\n }\n }), this.scrollLocker = new Fi(), this.history = new zi(), this.isHidden = !0, this.nodes.overlay = d.make(\"div\", [N.overlay, N.overlayHidden]), this.nodes.popover.insertBefore(this.nodes.overlay, this.nodes.popover.firstChild), this.listeners.on(this.nodes.overlay, \"click\", () => {\n this.hide();\n }), this.history.push({ items: e.items });\n }\n /**\n * Open popover\n */\n show() {\n this.nodes.overlay.classList.remove(N.overlayHidden), super.show(), this.scrollLocker.lock(), this.isHidden = !1;\n }\n /**\n * Closes popover\n */\n hide() {\n this.isHidden || (super.hide(), this.nodes.overlay.classList.add(N.overlayHidden), this.scrollLocker.unlock(), this.history.reset(), this.isHidden = !0);\n }\n /**\n * Clears memory\n */\n destroy() {\n super.destroy(), this.scrollLocker.unlock();\n }\n /**\n * Handles displaying nested items for the item\n *\n * @param item – item to show nested popover for\n */\n showNestedItems(e) {\n this.updateItemsAndHeader(e.children, e.title), this.history.push({\n title: e.title,\n items: e.children\n });\n }\n /**\n * Removes rendered popover items and header and displays new ones\n *\n * @param items - new popover items\n * @param title - new popover header text\n */\n updateItemsAndHeader(e, t) {\n if (this.header !== null && this.header !== void 0 && (this.header.destroy(), this.header = null), t !== void 0) {\n this.header = new Hi({\n text: t,\n onBackButtonClick: () => {\n this.history.pop(), this.updateItemsAndHeader(this.history.currentItems, this.history.currentTitle);\n }\n });\n const o = this.header.getElement();\n o !== null && this.nodes.popoverContainer.insertBefore(o, this.nodes.popoverContainer.firstChild);\n }\n this.items.forEach((o) => {\n var i;\n return (i = o.getElement()) == null ? void 0 : i.remove();\n }), this.items = this.buildItems(e), this.items.forEach((o) => {\n var s;\n const i = o.getElement();\n i !== null && ((s = this.nodes.items) == null || s.appendChild(i));\n });\n }\n}\nclass Ui extends y {\n constructor() {\n super(...arguments), this.opened = !1, this.selection = new b(), this.popover = null, this.close = () => {\n this.opened && (this.opened = !1, b.isAtEditor || this.selection.restore(), this.selection.clearSaved(), !this.Editor.CrossBlockSelection.isCrossBlockSelectionStarted && this.Editor.BlockManager.currentBlock && this.Editor.BlockSelection.unselectBlock(this.Editor.BlockManager.currentBlock), this.eventsDispatcher.emit(this.events.closed), this.popover && (this.popover.off(Z.Closed, this.onPopoverClose), this.popover.destroy(), this.popover.getElement().remove(), this.popover = null));\n }, this.onPopoverClose = () => {\n this.close();\n };\n }\n /**\n * Module Events\n */\n get events() {\n return {\n opened: \"block-settings-opened\",\n closed: \"block-settings-closed\"\n };\n }\n /**\n * Block Settings CSS\n */\n get CSS() {\n return {\n settings: \"ce-settings\"\n };\n }\n /**\n * Getter for inner popover's flipper instance\n *\n * @todo remove once BlockSettings becomes standalone non-module class\n */\n get flipper() {\n var e;\n if (this.popover !== null)\n return \"flipper\" in this.popover ? (e = this.popover) == null ? void 0 : e.flipper : void 0;\n }\n /**\n * Panel with block settings with 2 sections:\n * - Tool's Settings\n * - Default Settings [Move, Remove, etc]\n */\n make() {\n this.nodes.wrapper = d.make(\"div\", [this.CSS.settings]), this.eventsDispatcher.on(ye, this.close);\n }\n /**\n * Destroys module\n */\n destroy() {\n this.removeAllNodes(), this.listeners.destroy(), this.eventsDispatcher.off(ye, this.close);\n }\n /**\n * Open Block Settings pane\n *\n * @param targetBlock - near which Block we should open BlockSettings\n */\n async open(e = this.Editor.BlockManager.currentBlock) {\n var s;\n this.opened = !0, this.selection.save(), this.Editor.BlockSelection.selectBlock(e), this.Editor.BlockSelection.clearCache();\n const { toolTunes: t, commonTunes: o } = e.getTunes();\n this.eventsDispatcher.emit(this.events.opened);\n const i = pe() ? Jt : lt;\n this.popover = new i({\n searchable: !0,\n items: await this.getTunesItems(e, o, t),\n scopeElement: this.Editor.API.methods.ui.nodes.redactor,\n messages: {\n nothingFound: z.ui(K.ui.popover, \"Nothing found\"),\n search: z.ui(K.ui.popover, \"Filter\")\n }\n }), this.popover.on(Z.Closed, this.onPopoverClose), (s = this.nodes.wrapper) == null || s.append(this.popover.getElement()), this.popover.show();\n }\n /**\n * Returns root block settings element\n */\n getElement() {\n return this.nodes.wrapper;\n }\n /**\n * Returns list of items to be displayed in block tunes menu.\n * Merges tool specific tunes, conversion menu and common tunes in one list in predefined order\n *\n * @param currentBlock – block we are about to open block tunes for\n * @param commonTunes – common tunes\n * @param toolTunes - tool specific tunes\n */\n async getTunesItems(e, t, o) {\n const i = [];\n o !== void 0 && o.length > 0 && (i.push(...o), i.push({\n type: A.Separator\n }));\n const s = Array.from(this.Editor.Tools.blockTools.values()), l = (await zt(e, s)).reduce((a, c) => (c.toolbox.forEach((u) => {\n a.push({\n icon: u.icon,\n title: z.t(K.toolNames, u.title),\n name: c.name,\n closeOnActivate: !0,\n onActivate: async () => {\n const { BlockManager: h, Caret: p, Toolbar: g } = this.Editor, f = await h.convert(e, c.name, u.data);\n g.close(), p.setToBlock(f, p.positions.END);\n }\n });\n }), a), []);\n return l.length > 0 && (i.push({\n icon: Kt,\n name: \"convert-to\",\n title: z.ui(K.ui.popover, \"Convert to\"),\n children: {\n searchable: !0,\n items: l\n }\n }), i.push({\n type: A.Separator\n })), i.push(...t), i.map((a) => this.resolveTuneAliases(a));\n }\n /**\n * Resolves aliases in tunes menu items\n *\n * @param item - item with resolved aliases\n */\n resolveTuneAliases(e) {\n if (e.type === A.Separator || e.type === A.Html)\n return e;\n const t = mi(e, { label: \"title\" });\n return e.confirmation && (t.confirmation = this.resolveTuneAliases(e.confirmation)), t;\n }\n}\nvar Qt = { exports: {} };\n/*!\n * Library for handling keyboard shortcuts\n * @copyright CodeX (https://codex.so)\n * @license MIT\n * @author CodeX (https://codex.so)\n * @version 1.2.0\n */\n(function(n, e) {\n (function(t, o) {\n n.exports = o();\n })(window, function() {\n return function(t) {\n var o = {};\n function i(s) {\n if (o[s])\n return o[s].exports;\n var r = o[s] = { i: s, l: !1, exports: {} };\n return t[s].call(r.exports, r, r.exports, i), r.l = !0, r.exports;\n }\n return i.m = t, i.c = o, i.d = function(s, r, l) {\n i.o(s, r) || Object.defineProperty(s, r, { enumerable: !0, get: l });\n }, i.r = function(s) {\n typeof Symbol < \"u\" && Symbol.toStringTag && Object.defineProperty(s, Symbol.toStringTag, { value: \"Module\" }), Object.defineProperty(s, \"__esModule\", { value: !0 });\n }, i.t = function(s, r) {\n if (1 & r && (s = i(s)), 8 & r || 4 & r && typeof s == \"object\" && s && s.__esModule)\n return s;\n var l = /* @__PURE__ */ Object.create(null);\n if (i.r(l), Object.defineProperty(l, \"default\", { enumerable: !0, value: s }), 2 & r && typeof s != \"string\")\n for (var a in s)\n i.d(l, a, (function(c) {\n return s[c];\n }).bind(null, a));\n return l;\n }, i.n = function(s) {\n var r = s && s.__esModule ? function() {\n return s.default;\n } : function() {\n return s;\n };\n return i.d(r, \"a\", r), r;\n }, i.o = function(s, r) {\n return Object.prototype.hasOwnProperty.call(s, r);\n }, i.p = \"\", i(i.s = 0);\n }([function(t, o, i) {\n function s(a, c) {\n for (var u = 0; u < c.length; u++) {\n var h = c[u];\n h.enumerable = h.enumerable || !1, h.configurable = !0, \"value\" in h && (h.writable = !0), Object.defineProperty(a, h.key, h);\n }\n }\n function r(a, c, u) {\n return c && s(a.prototype, c), u && s(a, u), a;\n }\n i.r(o);\n var l = function() {\n function a(c) {\n var u = this;\n (function(h, p) {\n if (!(h instanceof p))\n throw new TypeError(\"Cannot call a class as a function\");\n })(this, a), this.commands = {}, this.keys = {}, this.name = c.name, this.parseShortcutName(c.name), this.element = c.on, this.callback = c.callback, this.executeShortcut = function(h) {\n u.execute(h);\n }, this.element.addEventListener(\"keydown\", this.executeShortcut, !1);\n }\n return r(a, null, [{ key: \"supportedCommands\", get: function() {\n return { SHIFT: [\"SHIFT\"], CMD: [\"CMD\", \"CONTROL\", \"COMMAND\", \"WINDOWS\", \"CTRL\"], ALT: [\"ALT\", \"OPTION\"] };\n } }, { key: \"keyCodes\", get: function() {\n return { 0: 48, 1: 49, 2: 50, 3: 51, 4: 52, 5: 53, 6: 54, 7: 55, 8: 56, 9: 57, A: 65, B: 66, C: 67, D: 68, E: 69, F: 70, G: 71, H: 72, I: 73, J: 74, K: 75, L: 76, M: 77, N: 78, O: 79, P: 80, Q: 81, R: 82, S: 83, T: 84, U: 85, V: 86, W: 87, X: 88, Y: 89, Z: 90, BACKSPACE: 8, ENTER: 13, ESCAPE: 27, LEFT: 37, UP: 38, RIGHT: 39, DOWN: 40, INSERT: 45, DELETE: 46, \".\": 190 };\n } }]), r(a, [{ key: \"parseShortcutName\", value: function(c) {\n c = c.split(\"+\");\n for (var u = 0; u < c.length; u++) {\n c[u] = c[u].toUpperCase();\n var h = !1;\n for (var p in a.supportedCommands)\n if (a.supportedCommands[p].includes(c[u])) {\n h = this.commands[p] = !0;\n break;\n }\n h || (this.keys[c[u]] = !0);\n }\n for (var g in a.supportedCommands)\n this.commands[g] || (this.commands[g] = !1);\n } }, { key: \"execute\", value: function(c) {\n var u, h = { CMD: c.ctrlKey || c.metaKey, SHIFT: c.shiftKey, ALT: c.altKey }, p = !0;\n for (u in this.commands)\n this.commands[u] !== h[u] && (p = !1);\n var g, f = !0;\n for (g in this.keys)\n f = f && c.keyCode === a.keyCodes[g];\n p && f && this.callback(c);\n } }, { key: \"remove\", value: function() {\n this.element.removeEventListener(\"keydown\", this.executeShortcut);\n } }]), a;\n }();\n o.default = l;\n }]).default;\n });\n})(Qt);\nvar ji = Qt.exports;\nconst $i = /* @__PURE__ */ Fe(ji);\nclass Yi {\n constructor() {\n this.registeredShortcuts = /* @__PURE__ */ new Map();\n }\n /**\n * Register shortcut\n *\n * @param shortcut - shortcut options\n */\n add(e) {\n if (this.findShortcut(e.on, e.name))\n throw Error(\n `Shortcut ${e.name} is already registered for ${e.on}. Please remove it before add a new handler.`\n );\n const o = new $i({\n name: e.name,\n on: e.on,\n callback: e.handler\n }), i = this.registeredShortcuts.get(e.on) || [];\n this.registeredShortcuts.set(e.on, [...i, o]);\n }\n /**\n * Remove shortcut\n *\n * @param element - Element shortcut is set for\n * @param name - shortcut name\n */\n remove(e, t) {\n const o = this.findShortcut(e, t);\n if (!o)\n return;\n o.remove();\n const i = this.registeredShortcuts.get(e);\n this.registeredShortcuts.set(e, i.filter((s) => s !== o));\n }\n /**\n * Get Shortcut instance if exist\n *\n * @param element - Element shorcut is set for\n * @param shortcut - shortcut name\n * @returns {number} index - shortcut index if exist\n */\n findShortcut(e, t) {\n return (this.registeredShortcuts.get(e) || []).find(({ name: i }) => i === t);\n }\n}\nconst he = new Yi();\nvar Wi = Object.defineProperty, Ki = Object.getOwnPropertyDescriptor, eo = (n, e, t, o) => {\n for (var i = o > 1 ? void 0 : o ? Ki(e, t) : e, s = n.length - 1, r; s >= 0; s--)\n (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i);\n return o && i && Wi(e, t, i), i;\n}, Se = /* @__PURE__ */ ((n) => (n.Opened = \"toolbox-opened\", n.Closed = \"toolbox-closed\", n.BlockAdded = \"toolbox-block-added\", n))(Se || {});\nconst at = class to extends Te {\n /**\n * Toolbox constructor\n *\n * @param options - available parameters\n * @param options.api - Editor API methods\n * @param options.tools - Tools available to check whether some of them should be displayed at the Toolbox or not\n */\n constructor({ api: e, tools: t, i18nLabels: o }) {\n super(), this.opened = !1, this.listeners = new Ce(), this.popover = null, this.handleMobileLayoutToggle = () => {\n this.destroyPopover(), this.initPopover();\n }, this.onPopoverClose = () => {\n this.opened = !1, this.emit(\n \"toolbox-closed\"\n /* Closed */\n );\n }, this.api = e, this.tools = t, this.i18nLabels = o, this.enableShortcuts(), this.nodes = {\n toolbox: d.make(\"div\", to.CSS.toolbox)\n }, this.initPopover(), this.api.events.on(ye, this.handleMobileLayoutToggle);\n }\n /**\n * Returns True if Toolbox is Empty and nothing to show\n *\n * @returns {boolean}\n */\n get isEmpty() {\n return this.toolsToBeDisplayed.length === 0;\n }\n /**\n * CSS styles\n */\n static get CSS() {\n return {\n toolbox: \"ce-toolbox\"\n };\n }\n /**\n * Returns root block settings element\n */\n getElement() {\n return this.nodes.toolbox;\n }\n /**\n * Returns true if the Toolbox has the Flipper activated and the Flipper has selected button\n */\n hasFocus() {\n if (this.popover !== null)\n return \"hasFocus\" in this.popover ? this.popover.hasFocus() : void 0;\n }\n /**\n * Destroy Module\n */\n destroy() {\n var e;\n super.destroy(), this.nodes && this.nodes.toolbox && this.nodes.toolbox.remove(), this.removeAllShortcuts(), (e = this.popover) == null || e.off(Z.Closed, this.onPopoverClose), this.listeners.destroy(), this.api.events.off(ye, this.handleMobileLayoutToggle);\n }\n /**\n * Toolbox Tool's button click handler\n *\n * @param toolName - tool type to be activated\n * @param blockDataOverrides - Block data predefined by the activated Toolbox item\n */\n toolButtonActivated(e, t) {\n this.insertNewBlock(e, t);\n }\n /**\n * Open Toolbox with Tools\n */\n open() {\n var e;\n this.isEmpty || ((e = this.popover) == null || e.show(), this.opened = !0, this.emit(\n \"toolbox-opened\"\n /* Opened */\n ));\n }\n /**\n * Close Toolbox\n */\n close() {\n var e;\n (e = this.popover) == null || e.hide(), this.opened = !1, this.emit(\n \"toolbox-closed\"\n /* Closed */\n );\n }\n /**\n * Close Toolbox\n */\n toggle() {\n this.opened ? this.close() : this.open();\n }\n /**\n * Creates toolbox popover and appends it inside wrapper element\n */\n initPopover() {\n var t;\n const e = pe() ? Jt : lt;\n this.popover = new e({\n scopeElement: this.api.ui.nodes.redactor,\n searchable: !0,\n messages: {\n nothingFound: this.i18nLabels.nothingFound,\n search: this.i18nLabels.filter\n },\n items: this.toolboxItemsToBeDisplayed\n }), this.popover.on(Z.Closed, this.onPopoverClose), (t = this.nodes.toolbox) == null || t.append(this.popover.getElement());\n }\n /**\n * Destroys popover instance and removes it from DOM\n */\n destroyPopover() {\n this.popover !== null && (this.popover.hide(), this.popover.off(Z.Closed, this.onPopoverClose), this.popover.destroy(), this.popover = null), this.nodes.toolbox !== null && (this.nodes.toolbox.innerHTML = \"\");\n }\n get toolsToBeDisplayed() {\n const e = [];\n return this.tools.forEach((t) => {\n t.toolbox && e.push(t);\n }), e;\n }\n get toolboxItemsToBeDisplayed() {\n const e = (t, o) => ({\n icon: t.icon,\n title: z.t(K.toolNames, t.title || Le(o.name)),\n name: o.name,\n onActivate: () => {\n this.toolButtonActivated(o.name, t.data);\n },\n secondaryLabel: o.shortcut ? tt(o.shortcut) : \"\"\n });\n return this.toolsToBeDisplayed.reduce((t, o) => (Array.isArray(o.toolbox) ? o.toolbox.forEach((i) => {\n t.push(e(i, o));\n }) : o.toolbox !== void 0 && t.push(e(o.toolbox, o)), t), []);\n }\n /**\n * Iterate all tools and enable theirs shortcuts if specified\n */\n enableShortcuts() {\n this.toolsToBeDisplayed.forEach((e) => {\n const t = e.shortcut;\n t && this.enableShortcutForTool(e.name, t);\n });\n }\n /**\n * Enable shortcut Block Tool implemented shortcut\n *\n * @param {string} toolName - Tool name\n * @param {string} shortcut - shortcut according to the ShortcutData Module format\n */\n enableShortcutForTool(e, t) {\n he.add({\n name: t,\n on: this.api.ui.nodes.redactor,\n handler: async (o) => {\n o.preventDefault();\n const i = this.api.blocks.getCurrentBlockIndex(), s = this.api.blocks.getBlockByIndex(i);\n if (s)\n try {\n const r = await this.api.blocks.convert(s.id, e);\n this.api.caret.setToBlock(r, \"end\");\n return;\n } catch {\n }\n this.insertNewBlock(e);\n }\n });\n }\n /**\n * Removes all added shortcuts\n * Fired when the Read-Only mode is activated\n */\n removeAllShortcuts() {\n this.toolsToBeDisplayed.forEach((e) => {\n const t = e.shortcut;\n t && he.remove(this.api.ui.nodes.redactor, t);\n });\n }\n /**\n * Inserts new block\n * Can be called when button clicked on Toolbox or by ShortcutData\n *\n * @param {string} toolName - Tool name\n * @param blockDataOverrides - predefined Block data\n */\n async insertNewBlock(e, t) {\n const o = this.api.blocks.getCurrentBlockIndex(), i = this.api.blocks.getBlockByIndex(o);\n if (!i)\n return;\n const s = i.isEmpty ? o : o + 1;\n let r;\n if (t) {\n const a = await this.api.blocks.composeBlockData(e);\n r = Object.assign(a, t);\n }\n const l = this.api.blocks.insert(\n e,\n r,\n void 0,\n s,\n void 0,\n i.isEmpty\n );\n l.call(J.APPEND_CALLBACK), this.api.caret.setToBlock(s), this.emit(\"toolbox-block-added\", {\n block: l\n }), this.api.toolbar.close();\n }\n};\neo([\n ue\n], at.prototype, \"toolsToBeDisplayed\", 1);\neo([\n ue\n], at.prototype, \"toolboxItemsToBeDisplayed\", 1);\nlet Xi = at;\nconst oo = \"block hovered\";\nasync function Vi(n, e) {\n const t = navigator.keyboard;\n if (!t)\n return e;\n try {\n return (await t.getLayoutMap()).get(n) || e;\n } catch (o) {\n return console.error(o), e;\n }\n}\nclass qi extends y {\n /**\n * @class\n * @param moduleConfiguration - Module Configuration\n * @param moduleConfiguration.config - Editor's config\n * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher\n */\n constructor({ config: e, eventsDispatcher: t }) {\n super({\n config: e,\n eventsDispatcher: t\n }), this.toolboxInstance = null;\n }\n /**\n * CSS styles\n *\n * @returns {object}\n */\n get CSS() {\n return {\n toolbar: \"ce-toolbar\",\n content: \"ce-toolbar__content\",\n actions: \"ce-toolbar__actions\",\n actionsOpened: \"ce-toolbar__actions--opened\",\n toolbarOpened: \"ce-toolbar--opened\",\n openedToolboxHolderModifier: \"codex-editor--toolbox-opened\",\n plusButton: \"ce-toolbar__plus\",\n plusButtonShortcut: \"ce-toolbar__plus-shortcut\",\n settingsToggler: \"ce-toolbar__settings-btn\",\n settingsTogglerHidden: \"ce-toolbar__settings-btn--hidden\"\n };\n }\n /**\n * Returns the Toolbar opening state\n *\n * @returns {boolean}\n */\n get opened() {\n return this.nodes.wrapper.classList.contains(this.CSS.toolbarOpened);\n }\n /**\n * Public interface for accessing the Toolbox\n */\n get toolbox() {\n var e;\n return {\n opened: (e = this.toolboxInstance) == null ? void 0 : e.opened,\n close: () => {\n var t;\n (t = this.toolboxInstance) == null || t.close();\n },\n open: () => {\n if (this.toolboxInstance === null) {\n I(\"toolbox.open() called before initialization is finished\", \"warn\");\n return;\n }\n this.Editor.BlockManager.currentBlock = this.hoveredBlock, this.toolboxInstance.open();\n },\n toggle: () => {\n if (this.toolboxInstance === null) {\n I(\"toolbox.toggle() called before initialization is finished\", \"warn\");\n return;\n }\n this.toolboxInstance.toggle();\n },\n hasFocus: () => {\n var t;\n return (t = this.toolboxInstance) == null ? void 0 : t.hasFocus();\n }\n };\n }\n /**\n * Block actions appearance manipulations\n */\n get blockActions() {\n return {\n hide: () => {\n this.nodes.actions.classList.remove(this.CSS.actionsOpened);\n },\n show: () => {\n this.nodes.actions.classList.add(this.CSS.actionsOpened);\n }\n };\n }\n /**\n * Methods for working with Block Tunes toggler\n */\n get blockTunesToggler() {\n return {\n hide: () => this.nodes.settingsToggler.classList.add(this.CSS.settingsTogglerHidden),\n show: () => this.nodes.settingsToggler.classList.remove(this.CSS.settingsTogglerHidden)\n };\n }\n /**\n * Toggles read-only mode\n *\n * @param {boolean} readOnlyEnabled - read-only mode\n */\n toggleReadOnly(e) {\n e ? (this.destroy(), this.Editor.BlockSettings.destroy(), this.disableModuleBindings()) : window.requestIdleCallback(() => {\n this.drawUI(), this.enableModuleBindings();\n }, { timeout: 2e3 });\n }\n /**\n * Move Toolbar to the passed (or current) Block\n *\n * @param block - block to move Toolbar near it\n */\n moveAndOpen(e = this.Editor.BlockManager.currentBlock) {\n if (this.toolboxInstance === null) {\n I(\"Can't open Toolbar since Editor initialization is not finished yet\", \"warn\");\n return;\n }\n if (this.toolboxInstance.opened && this.toolboxInstance.close(), this.Editor.BlockSettings.opened && this.Editor.BlockSettings.close(), !e)\n return;\n this.hoveredBlock = e;\n const t = e.holder, { isMobile: o } = this.Editor.UI;\n let i;\n const s = 20, r = e.firstInput, l = t.getBoundingClientRect(), a = r !== void 0 ? r.getBoundingClientRect() : null, c = a !== null ? a.top - l.top : null, u = c !== null ? c > s : void 0;\n if (o)\n i = t.offsetTop + t.offsetHeight;\n else if (r === void 0 || u) {\n const h = parseInt(window.getComputedStyle(e.pluginsContent).paddingTop);\n i = t.offsetTop + h;\n } else {\n const h = _o(r), p = parseInt(window.getComputedStyle(this.nodes.plusButton).height, 10), g = 8;\n i = t.offsetTop + h - p + g + c;\n }\n this.nodes.wrapper.style.top = `${Math.floor(i)}px`, this.Editor.BlockManager.blocks.length === 1 && e.isEmpty ? this.blockTunesToggler.hide() : this.blockTunesToggler.show(), this.open();\n }\n /**\n * Close the Toolbar\n */\n close() {\n var e, t;\n this.Editor.ReadOnly.isEnabled || ((e = this.nodes.wrapper) == null || e.classList.remove(this.CSS.toolbarOpened), this.blockActions.hide(), (t = this.toolboxInstance) == null || t.close(), this.Editor.BlockSettings.close(), this.reset());\n }\n /**\n * Reset the Toolbar position to prevent DOM height growth, for example after blocks deletion\n */\n reset() {\n this.nodes.wrapper.style.top = \"unset\";\n }\n /**\n * Open Toolbar with Plus Button and Actions\n *\n * @param {boolean} withBlockActions - by default, Toolbar opens with Block Actions.\n * This flag allows to open Toolbar without Actions.\n */\n open(e = !0) {\n this.nodes.wrapper.classList.add(this.CSS.toolbarOpened), e ? this.blockActions.show() : this.blockActions.hide();\n }\n /**\n * Draws Toolbar elements\n */\n async make() {\n this.nodes.wrapper = d.make(\"div\", this.CSS.toolbar), [\"content\", \"actions\"].forEach((s) => {\n this.nodes[s] = d.make(\"div\", this.CSS[s]);\n }), d.append(this.nodes.wrapper, this.nodes.content), d.append(this.nodes.content, this.nodes.actions), this.nodes.plusButton = d.make(\"div\", this.CSS.plusButton, {\n innerHTML: Ci\n }), d.append(this.nodes.actions, this.nodes.plusButton), this.readOnlyMutableListeners.on(this.nodes.plusButton, \"click\", () => {\n Ne(!0), this.plusButtonClicked();\n }, !1);\n const e = d.make(\"div\");\n e.appendChild(document.createTextNode(z.ui(K.ui.toolbar.toolbox, \"Add\"))), e.appendChild(d.make(\"div\", this.CSS.plusButtonShortcut, {\n textContent: \"/\"\n })), Pe(this.nodes.plusButton, e, {\n hidingDelay: 400\n }), this.nodes.settingsToggler = d.make(\"span\", this.CSS.settingsToggler, {\n innerHTML: Ti\n }), d.append(this.nodes.actions, this.nodes.settingsToggler);\n const t = d.make(\"div\"), o = d.text(z.ui(K.ui.blockTunes.toggler, \"Click to tune\")), i = await Vi(\"Slash\", \"/\");\n t.appendChild(o), t.appendChild(d.make(\"div\", this.CSS.plusButtonShortcut, {\n textContent: tt(`CMD + ${i}`)\n })), Pe(this.nodes.settingsToggler, t, {\n hidingDelay: 400\n }), d.append(this.nodes.actions, this.makeToolbox()), d.append(this.nodes.actions, this.Editor.BlockSettings.getElement()), d.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\n }\n /**\n * Creates the Toolbox instance and return it's rendered element\n */\n makeToolbox() {\n return this.toolboxInstance = new Xi({\n api: this.Editor.API.methods,\n tools: this.Editor.Tools.blockTools,\n i18nLabels: {\n filter: z.ui(K.ui.popover, \"Filter\"),\n nothingFound: z.ui(K.ui.popover, \"Nothing found\")\n }\n }), this.toolboxInstance.on(Se.Opened, () => {\n this.Editor.UI.nodes.wrapper.classList.add(this.CSS.openedToolboxHolderModifier);\n }), this.toolboxInstance.on(Se.Closed, () => {\n this.Editor.UI.nodes.wrapper.classList.remove(this.CSS.openedToolboxHolderModifier);\n }), this.toolboxInstance.on(Se.BlockAdded, ({ block: e }) => {\n const { BlockManager: t, Caret: o } = this.Editor, i = t.getBlockById(e.id);\n i.inputs.length === 0 && (i === t.lastBlock ? (t.insertAtEnd(), o.setToBlock(t.lastBlock)) : o.setToBlock(t.nextBlock));\n }), this.toolboxInstance.getElement();\n }\n /**\n * Handler for Plus Button\n */\n plusButtonClicked() {\n var e;\n this.Editor.BlockManager.currentBlock = this.hoveredBlock, (e = this.toolboxInstance) == null || e.toggle();\n }\n /**\n * Enable bindings\n */\n enableModuleBindings() {\n this.readOnlyMutableListeners.on(this.nodes.settingsToggler, \"mousedown\", (e) => {\n var t;\n e.stopPropagation(), this.settingsTogglerClicked(), (t = this.toolboxInstance) != null && t.opened && this.toolboxInstance.close(), Ne(!0);\n }, !0), pe() || this.eventsDispatcher.on(oo, (e) => {\n var t;\n this.Editor.BlockSettings.opened || (t = this.toolboxInstance) != null && t.opened || this.moveAndOpen(e.block);\n });\n }\n /**\n * Disable bindings\n */\n disableModuleBindings() {\n this.readOnlyMutableListeners.clearAll();\n }\n /**\n * Clicks on the Block Settings toggler\n */\n settingsTogglerClicked() {\n this.Editor.BlockManager.currentBlock = this.hoveredBlock, this.Editor.BlockSettings.opened ? this.Editor.BlockSettings.close() : this.Editor.BlockSettings.open(this.hoveredBlock);\n }\n /**\n * Draws Toolbar UI\n *\n * Toolbar contains BlockSettings and Toolbox.\n * That's why at first we draw its components and then Toolbar itself\n *\n * Steps:\n * - Make Toolbar dependent components like BlockSettings, Toolbox and so on\n * - Make itself and append dependent nodes to itself\n *\n */\n drawUI() {\n this.Editor.BlockSettings.make(), this.make();\n }\n /**\n * Removes all created and saved HTMLElements\n * It is used in Read-Only mode\n */\n destroy() {\n this.removeAllNodes(), this.toolboxInstance && this.toolboxInstance.destroy();\n }\n}\nvar ne = /* @__PURE__ */ ((n) => (n[n.Block = 0] = \"Block\", n[n.Inline = 1] = \"Inline\", n[n.Tune = 2] = \"Tune\", n))(ne || {}), Ie = /* @__PURE__ */ ((n) => (n.Shortcut = \"shortcut\", n.Toolbox = \"toolbox\", n.EnabledInlineTools = \"inlineToolbar\", n.EnabledBlockTunes = \"tunes\", n.Config = \"config\", n))(Ie || {}), io = /* @__PURE__ */ ((n) => (n.Shortcut = \"shortcut\", n.SanitizeConfig = \"sanitize\", n))(io || {}), ce = /* @__PURE__ */ ((n) => (n.IsEnabledLineBreaks = \"enableLineBreaks\", n.Toolbox = \"toolbox\", n.ConversionConfig = \"conversionConfig\", n.IsReadOnlySupported = \"isReadOnlySupported\", n.PasteConfig = \"pasteConfig\", n))(ce || {}), ct = /* @__PURE__ */ ((n) => (n.IsInline = \"isInline\", n.Title = \"title\", n))(ct || {}), et = /* @__PURE__ */ ((n) => (n.IsTune = \"isTune\", n))(et || {});\nclass dt {\n /**\n * @class\n * @param {ConstructorOptions} options - Constructor options\n */\n constructor({\n name: e,\n constructable: t,\n config: o,\n api: i,\n isDefault: s,\n isInternal: r = !1,\n defaultPlaceholder: l\n }) {\n this.api = i, this.name = e, this.constructable = t, this.config = o, this.isDefault = s, this.isInternal = r, this.defaultPlaceholder = l;\n }\n /**\n * Returns Tool user configuration\n */\n get settings() {\n const e = this.config.config || {};\n return this.isDefault && !(\"placeholder\" in e) && this.defaultPlaceholder && (e.placeholder = this.defaultPlaceholder), e;\n }\n /**\n * Calls Tool's reset method\n */\n reset() {\n if (O(this.constructable.reset))\n return this.constructable.reset();\n }\n /**\n * Calls Tool's prepare method\n */\n prepare() {\n if (O(this.constructable.prepare))\n return this.constructable.prepare({\n toolName: this.name,\n config: this.settings\n });\n }\n /**\n * Returns shortcut for Tool (internal or specified by user)\n */\n get shortcut() {\n const e = this.constructable.shortcut;\n return this.config.shortcut || e;\n }\n /**\n * Returns Tool's sanitizer configuration\n */\n get sanitizeConfig() {\n return this.constructable.sanitize || {};\n }\n /**\n * Returns true if Tools is inline\n */\n isInline() {\n return this.type === ne.Inline;\n }\n /**\n * Returns true if Tools is block\n */\n isBlock() {\n return this.type === ne.Block;\n }\n /**\n * Returns true if Tools is tune\n */\n isTune() {\n return this.type === ne.Tune;\n }\n}\nclass Zi extends y {\n /**\n * @param moduleConfiguration - Module Configuration\n * @param moduleConfiguration.config - Editor's config\n * @param moduleConfiguration.eventsDispatcher - Editor's event dispatcher\n */\n constructor({ config: e, eventsDispatcher: t }) {\n super({\n config: e,\n eventsDispatcher: t\n }), this.CSS = {\n inlineToolbar: \"ce-inline-toolbar\"\n }, this.opened = !1, this.popover = null, this.toolbarVerticalMargin = pe() ? 20 : 6, this.toolsInstances = /* @__PURE__ */ new Map();\n }\n /**\n * Toggles read-only mode\n *\n * @param {boolean} readOnlyEnabled - read-only mode\n */\n toggleReadOnly(e) {\n e ? this.destroy() : window.requestIdleCallback(() => {\n this.make();\n }, { timeout: 2e3 });\n }\n /**\n * Moving / appearance\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n */\n /**\n * Shows Inline Toolbar if something is selected\n *\n * @param [needToClose] - pass true to close toolbar if it is not allowed.\n * Avoid to use it just for closing IT, better call .close() clearly.\n */\n async tryToShow(e = !1) {\n e && this.close(), this.allowedToShow() && (await this.open(), this.Editor.Toolbar.close());\n }\n /**\n * Hides Inline Toolbar\n */\n close() {\n var e, t;\n this.opened && (this.Editor.ReadOnly.isEnabled || (Array.from(this.toolsInstances.entries()).forEach(([o, i]) => {\n const s = this.getToolShortcut(o);\n s && he.remove(this.Editor.UI.nodes.redactor, s), O(i.clear) && i.clear();\n }), this.toolsInstances = null, this.reset(), this.opened = !1, (e = this.popover) == null || e.hide(), (t = this.popover) == null || t.destroy(), this.popover = null));\n }\n /**\n * Check if node is contained by Inline Toolbar\n *\n * @param {Node} node — node to check\n */\n containsNode(e) {\n return this.nodes.wrapper === void 0 ? !1 : this.nodes.wrapper.contains(e);\n }\n /**\n * Removes UI and its components\n */\n destroy() {\n var e;\n this.removeAllNodes(), (e = this.popover) == null || e.destroy(), this.popover = null;\n }\n /**\n * Making DOM\n */\n make() {\n this.nodes.wrapper = d.make(\"div\", [\n this.CSS.inlineToolbar,\n ...this.isRtl ? [this.Editor.UI.CSS.editorRtlFix] : []\n ]), d.append(this.Editor.UI.nodes.wrapper, this.nodes.wrapper);\n }\n /**\n * Shows Inline Toolbar\n */\n async open() {\n var t;\n if (this.opened)\n return;\n this.opened = !0, this.popover !== null && this.popover.destroy();\n const e = await this.getInlineTools();\n this.popover = new Ri({\n items: e,\n scopeElement: this.Editor.API.methods.ui.nodes.redactor,\n messages: {\n nothingFound: z.ui(K.ui.popover, \"Nothing found\"),\n search: z.ui(K.ui.popover, \"Filter\")\n }\n }), this.move(this.popover.size.width), (t = this.nodes.wrapper) == null || t.append(this.popover.getElement()), this.popover.show();\n }\n /**\n * Move Toolbar to the selected text\n *\n * @param popoverWidth - width of the toolbar popover\n */\n move(e) {\n const t = b.rect, o = this.Editor.UI.nodes.wrapper.getBoundingClientRect(), i = {\n x: t.x - o.x,\n y: t.y + t.height - // + window.scrollY\n o.top + this.toolbarVerticalMargin\n };\n i.x + e + o.x > this.Editor.UI.contentRect.right && (i.x = this.Editor.UI.contentRect.right - e - o.x), this.nodes.wrapper.style.left = Math.floor(i.x) + \"px\", this.nodes.wrapper.style.top = Math.floor(i.y) + \"px\";\n }\n /**\n * Clear orientation classes and reset position\n */\n reset() {\n this.nodes.wrapper.style.left = \"0\", this.nodes.wrapper.style.top = \"0\";\n }\n /**\n * Need to show Inline Toolbar or not\n */\n allowedToShow() {\n const e = [\"IMG\", \"INPUT\"], t = b.get(), o = b.text;\n if (!t || !t.anchorNode || t.isCollapsed || o.length < 1)\n return !1;\n const i = d.isElement(t.anchorNode) ? t.anchorNode : t.anchorNode.parentElement;\n if (i === null || t && e.includes(i.tagName) || i.closest('[contenteditable=\"true\"]') === null)\n return !1;\n const r = this.Editor.BlockManager.getBlock(t.anchorNode);\n return r ? r.tool.inlineTools.size !== 0 : !1;\n }\n /**\n * Working with Tools\n * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n */\n /**\n * Returns Inline Tools segregated by their appearance type: popover items and custom html elements.\n * Sets this.toolsInstances map\n */\n async getInlineTools() {\n const e = b.get(), t = this.Editor.BlockManager.getBlock(e.anchorNode), o = Array.from(t.tool.inlineTools.values()), i = [];\n this.toolsInstances === null && (this.toolsInstances = /* @__PURE__ */ new Map());\n for (let s = 0; s < o.length; s++) {\n const r = o[s], l = r.create(), a = await l.render();\n this.toolsInstances.set(r.name, l);\n const c = this.getToolShortcut(r.name);\n if (c)\n try {\n this.enableShortcuts(r.name, c);\n } catch {\n }\n const u = c !== void 0 ? tt(c) : void 0, h = z.t(\n K.toolNames,\n r.title || Le(r.name)\n );\n [a].flat().forEach((p) => {\n var f, k;\n const g = {\n name: r.name,\n onActivate: () => {\n this.toolClicked(l);\n },\n hint: {\n title: h,\n description: u\n }\n };\n if (d.isElement(p)) {\n const C = {\n ...g,\n element: p,\n type: A.Html\n };\n if (O(l.renderActions)) {\n const S = l.renderActions();\n C.children = {\n isOpen: (f = l.checkState) == null ? void 0 : f.call(l, b.get()),\n /** Disable keyboard navigation in actions, as it might conflict with enter press handling */\n isFlippable: !1,\n items: [\n {\n type: A.Html,\n element: S\n }\n ]\n };\n } else\n (k = l.checkState) == null || k.call(l, b.get());\n i.push(C);\n } else if (p.type === A.Html)\n i.push({\n ...g,\n ...p,\n type: A.Html\n });\n else if (p.type === A.Separator)\n i.push({\n type: A.Separator\n });\n else {\n const C = {\n ...g,\n ...p,\n type: A.Default\n };\n \"children\" in C && s !== 0 && i.push({\n type: A.Separator\n }), i.push(C), \"children\" in C && s < o.length - 1 && i.push({\n type: A.Separator\n });\n }\n });\n }\n return i;\n }\n /**\n * Get shortcut name for tool\n *\n * @param toolName — Tool name\n */\n getToolShortcut(e) {\n const { Tools: t } = this.Editor, o = t.inlineTools.get(e), i = t.internal.inlineTools;\n return Array.from(i.keys()).includes(e) ? this.inlineTools[e][io.Shortcut] : o == null ? void 0 : o.shortcut;\n }\n /**\n * Enable Tool shortcut with Editor Shortcuts Module\n *\n * @param toolName - tool name\n * @param shortcut - shortcut according to the ShortcutData Module format\n */\n enableShortcuts(e, t) {\n he.add({\n name: t,\n handler: (o) => {\n var s;\n const { currentBlock: i } = this.Editor.BlockManager;\n i && i.tool.enabledInlineTools && (o.preventDefault(), (s = this.popover) == null || s.activateItemByName(e));\n },\n on: this.Editor.UI.nodes.redactor\n });\n }\n /**\n * Inline Tool button clicks\n *\n * @param tool - Tool's instance\n */\n toolClicked(e) {\n var o;\n const t = b.range;\n (o = e.surround) == null || o.call(e, t), this.checkToolsState();\n }\n /**\n * Check Tools` state by selection\n */\n checkToolsState() {\n var e;\n (e = this.toolsInstances) == null || e.forEach((t) => {\n var o;\n (o = t.checkState) == null || o.call(t, b.get());\n });\n }\n /**\n * Get inline tools tools\n * Tools that has isInline is true\n */\n get inlineTools() {\n const e = {};\n return Array.from(this.Editor.Tools.inlineTools.entries()).forEach(([t, o]) => {\n e[t] = o.create();\n }), e;\n }\n}\nfunction so() {\n const n = window.getSelection();\n if (n === null)\n return [null, 0];\n let e = n.focusNode, t = n.focusOffset;\n return e === null ? [null, 0] : (e.nodeType !== Node.TEXT_NODE && e.childNodes.length > 0 && (e.childNodes[t] ? (e = e.childNodes[t], t = 0) : (e = e.childNodes[t - 1], t = e.textContent.length)), [e, t]);\n}\nfunction no(n, e, t, o) {\n const i = document.createRange();\n o === \"left\" ? (i.setStart(n, 0), i.setEnd(e, t)) : (i.setStart(e, t), i.setEnd(n, n.childNodes.length));\n const s = i.cloneContents(), r = document.createElement(\"div\");\n r.appendChild(s);\n const l = r.textContent || \"\";\n return Lo(l);\n}\nfunction Me(n) {\n const e = d.getDeepestNode(n);\n if (e === null || d.isEmpty(n))\n return !0;\n if (d.isNativeInput(e))\n return e.selectionEnd === 0;\n if (d.isEmpty(n))\n return !0;\n const [t, o] = so();\n return t === null ? !1 : no(n, t, o, \"left\");\n}\nfunction Ae(n) {\n const e = d.getDeepestNode(n, !0);\n if (e === null)\n return !0;\n if (d.isNativeInput(e))\n return e.selectionEnd === e.value.length;\n const [t, o] = so();\n return t === null ? !1 : no(n, t, o, \"right\");\n}\nclass Gi extends y {\n /**\n * All keydowns on Block\n *\n * @param {KeyboardEvent} event - keydown\n */\n keydown(e) {\n switch (this.beforeKeydownProcessing(e), e.keyCode) {\n case w.BACKSPACE:\n this.backspace(e);\n break;\n case w.DELETE:\n this.delete(e);\n break;\n case w.ENTER:\n this.enter(e);\n break;\n case w.DOWN:\n case w.RIGHT:\n this.arrowRightAndDown(e);\n break;\n case w.UP:\n case w.LEFT:\n this.arrowLeftAndUp(e);\n break;\n case w.TAB:\n this.tabPressed(e);\n break;\n }\n e.key === \"/\" && !e.ctrlKey && !e.metaKey && this.slashPressed(e), e.code === \"Slash\" && (e.ctrlKey || e.metaKey) && (e.preventDefault(), this.commandSlashPressed());\n }\n /**\n * Fires on keydown before event processing\n *\n * @param {KeyboardEvent} event - keydown\n */\n beforeKeydownProcessing(e) {\n this.needToolbarClosing(e) && Mt(e.keyCode) && (this.Editor.Toolbar.close(), e.ctrlKey || e.metaKey || e.altKey || e.shiftKey || this.Editor.BlockSelection.clearSelection(e));\n }\n /**\n * Key up on Block:\n * - shows Inline Toolbar if something selected\n * - shows conversion toolbar with 85% of block selection\n *\n * @param {KeyboardEvent} event - keyup event\n */\n keyup(e) {\n e.shiftKey || this.Editor.UI.checkEmptiness();\n }\n /**\n * Add drop target styles\n *\n * @param {DragEvent} event - drag over event\n */\n dragOver(e) {\n const t = this.Editor.BlockManager.getBlockByChildNode(e.target);\n t.dropTarget = !0;\n }\n /**\n * Remove drop target style\n *\n * @param {DragEvent} event - drag leave event\n */\n dragLeave(e) {\n const t = this.Editor.BlockManager.getBlockByChildNode(e.target);\n t.dropTarget = !1;\n }\n /**\n * Copying selected blocks\n * Before putting to the clipboard we sanitize all blocks and then copy to the clipboard\n *\n * @param {ClipboardEvent} event - clipboard event\n */\n handleCommandC(e) {\n const { BlockSelection: t } = this.Editor;\n t.anyBlockSelected && t.copySelectedBlocks(e);\n }\n /**\n * Copy and Delete selected Blocks\n *\n * @param {ClipboardEvent} event - clipboard event\n */\n handleCommandX(e) {\n const { BlockSelection: t, BlockManager: o, Caret: i } = this.Editor;\n t.anyBlockSelected && t.copySelectedBlocks(e).then(() => {\n const s = o.removeSelectedBlocks(), r = o.insertDefaultBlockAtIndex(s, !0);\n i.setToBlock(r, i.positions.START), t.clearSelection(e);\n });\n }\n /**\n * Tab pressed inside a Block.\n *\n * @param {KeyboardEvent} event - keydown\n */\n tabPressed(e) {\n const { InlineToolbar: t, Caret: o } = this.Editor;\n if (t.opened)\n return;\n (e.shiftKey ? o.navigatePrevious(!0) : o.navigateNext(!0)) && e.preventDefault();\n }\n /**\n * '/' + 'command' keydown inside a Block\n */\n commandSlashPressed() {\n this.Editor.BlockSelection.selectedBlocks.length > 1 || this.activateBlockSettings();\n }\n /**\n * '/' keydown inside a Block\n *\n * @param event - keydown\n */\n slashPressed(e) {\n this.Editor.BlockManager.currentBlock.isEmpty && (e.preventDefault(), this.Editor.Caret.insertContentAtCaretPosition(\"/\"), this.activateToolbox());\n }\n /**\n * ENTER pressed on block\n *\n * @param {KeyboardEvent} event - keydown\n */\n enter(e) {\n const { BlockManager: t, UI: o } = this.Editor, i = t.currentBlock;\n if (i === void 0 || i.tool.isLineBreaksEnabled || o.someToolbarOpened && o.someFlipperButtonFocused || e.shiftKey && !Ge)\n return;\n let s = i;\n i.currentInput !== void 0 && Me(i.currentInput) && !i.hasMedia ? this.Editor.BlockManager.insertDefaultBlockAtIndex(this.Editor.BlockManager.currentBlockIndex) : i.currentInput && Ae(i.currentInput) ? s = this.Editor.BlockManager.insertDefaultBlockAtIndex(this.Editor.BlockManager.currentBlockIndex + 1) : s = this.Editor.BlockManager.split(), this.Editor.Caret.setToBlock(s), this.Editor.Toolbar.moveAndOpen(s), e.preventDefault();\n }\n /**\n * Handle backspace keydown on Block\n *\n * @param {KeyboardEvent} event - keydown\n */\n backspace(e) {\n const { BlockManager: t, Caret: o } = this.Editor, { currentBlock: i, previousBlock: s } = t;\n if (i === void 0 || !b.isCollapsed || !i.currentInput || !Me(i.currentInput))\n return;\n if (e.preventDefault(), this.Editor.Toolbar.close(), !(i.currentInput === i.firstInput)) {\n o.navigatePrevious();\n return;\n }\n if (s === null)\n return;\n if (s.isEmpty) {\n t.removeBlock(s);\n return;\n }\n if (i.isEmpty) {\n t.removeBlock(i);\n const a = t.currentBlock;\n o.setToBlock(a, o.positions.END);\n return;\n }\n wt(s, i) ? this.mergeBlocks(s, i) : o.setToBlock(s, o.positions.END);\n }\n /**\n * Handles delete keydown on Block\n * Removes char after the caret.\n * If caret is at the end of the block, merge next block with current\n *\n * @param {KeyboardEvent} event - keydown\n */\n delete(e) {\n const { BlockManager: t, Caret: o } = this.Editor, { currentBlock: i, nextBlock: s } = t;\n if (!b.isCollapsed || !Ae(i.currentInput))\n return;\n if (e.preventDefault(), this.Editor.Toolbar.close(), !(i.currentInput === i.lastInput)) {\n o.navigateNext();\n return;\n }\n if (s === null)\n return;\n if (s.isEmpty) {\n t.removeBlock(s);\n return;\n }\n if (i.isEmpty) {\n t.removeBlock(i), o.setToBlock(s, o.positions.START);\n return;\n }\n wt(i, s) ? this.mergeBlocks(i, s) : o.setToBlock(s, o.positions.START);\n }\n /**\n * Merge passed Blocks\n *\n * @param targetBlock - to which Block we want to merge\n * @param blockToMerge - what Block we want to merge\n */\n mergeBlocks(e, t) {\n const { BlockManager: o, Caret: i, Toolbar: s } = this.Editor;\n i.createShadow(e.lastInput), o.mergeBlocks(e, t).then(() => {\n i.restoreCaret(e.pluginsContent), s.close();\n });\n }\n /**\n * Handle right and down keyboard keys\n *\n * @param {KeyboardEvent} event - keyboard event\n */\n arrowRightAndDown(e) {\n const t = le.usedKeys.includes(e.keyCode) && (!e.shiftKey || e.keyCode === w.TAB);\n if (this.Editor.UI.someToolbarOpened && t)\n return;\n this.Editor.Toolbar.close();\n const { currentBlock: o } = this.Editor.BlockManager, s = ((o == null ? void 0 : o.currentInput) !== void 0 ? Ae(o.currentInput) : void 0) || this.Editor.BlockSelection.anyBlockSelected;\n if (e.shiftKey && e.keyCode === w.DOWN && s) {\n this.Editor.CrossBlockSelection.toggleBlockSelectedState();\n return;\n }\n if (e.keyCode === w.DOWN || e.keyCode === w.RIGHT && !this.isRtl ? this.Editor.Caret.navigateNext() : this.Editor.Caret.navigatePrevious()) {\n e.preventDefault();\n return;\n }\n Oe(() => {\n this.Editor.BlockManager.currentBlock && this.Editor.BlockManager.currentBlock.updateCurrentInput();\n }, 20)(), this.Editor.BlockSelection.clearSelection(e);\n }\n /**\n * Handle left and up keyboard keys\n *\n * @param {KeyboardEvent} event - keyboard event\n */\n arrowLeftAndUp(e) {\n if (this.Editor.UI.someToolbarOpened) {\n if (le.usedKeys.includes(e.keyCode) && (!e.shiftKey || e.keyCode === w.TAB))\n return;\n this.Editor.UI.closeAllToolbars();\n }\n this.Editor.Toolbar.close();\n const { currentBlock: t } = this.Editor.BlockManager, i = ((t == null ? void 0 : t.currentInput) !== void 0 ? Me(t.currentInput) : void 0) || this.Editor.BlockSelection.anyBlockSelected;\n if (e.shiftKey && e.keyCode === w.UP && i) {\n this.Editor.CrossBlockSelection.toggleBlockSelectedState(!1);\n return;\n }\n if (e.keyCode === w.UP || e.keyCode === w.LEFT && !this.isRtl ? this.Editor.Caret.navigatePrevious() : this.Editor.Caret.navigateNext()) {\n e.preventDefault();\n return;\n }\n Oe(() => {\n this.Editor.BlockManager.currentBlock && this.Editor.BlockManager.currentBlock.updateCurrentInput();\n }, 20)(), this.Editor.BlockSelection.clearSelection(e);\n }\n /**\n * Cases when we need to close Toolbar\n *\n * @param {KeyboardEvent} event - keyboard event\n */\n needToolbarClosing(e) {\n const t = e.keyCode === w.ENTER && this.Editor.Toolbar.toolbox.opened, o = e.keyCode === w.ENTER && this.Editor.BlockSettings.opened, i = e.keyCode === w.ENTER && this.Editor.InlineToolbar.opened, s = e.keyCode === w.TAB;\n return !(e.shiftKey || s || t || o || i);\n }\n /**\n * If Toolbox is not open, then just open it and show plus button\n */\n activateToolbox() {\n this.Editor.Toolbar.opened || this.Editor.Toolbar.moveAndOpen(), this.Editor.Toolbar.toolbox.open();\n }\n /**\n * Open Toolbar and show BlockSettings before flipping Tools\n */\n activateBlockSettings() {\n this.Editor.Toolbar.opened || this.Editor.Toolbar.moveAndOpen(), this.Editor.BlockSettings.opened || this.Editor.BlockSettings.open();\n }\n}\nclass Xe {\n /**\n * @class\n * @param {HTMLElement} workingArea — editor`s working node\n */\n constructor(e) {\n this.blocks = [], this.workingArea = e;\n }\n /**\n * Get length of Block instances array\n *\n * @returns {number}\n */\n get length() {\n return this.blocks.length;\n }\n /**\n * Get Block instances array\n *\n * @returns {Block[]}\n */\n get array() {\n return this.blocks;\n }\n /**\n * Get blocks html elements array\n *\n * @returns {HTMLElement[]}\n */\n get nodes() {\n return At(this.workingArea.children);\n }\n /**\n * Proxy trap to implement array-like setter\n *\n * @example\n * blocks[0] = new Block(...)\n * @param {Blocks} instance — Blocks instance\n * @param {PropertyKey} property — block index or any Blocks class property key to set\n * @param {Block} value — value to set\n * @returns {boolean}\n */\n static set(e, t, o) {\n return isNaN(Number(t)) ? (Reflect.set(e, t, o), !0) : (e.insert(+t, o), !0);\n }\n /**\n * Proxy trap to implement array-like getter\n *\n * @param {Blocks} instance — Blocks instance\n * @param {PropertyKey} property — Blocks class property key\n * @returns {Block|*}\n */\n static get(e, t) {\n return isNaN(Number(t)) ? Reflect.get(e, t) : e.get(+t);\n }\n /**\n * Push new Block to the blocks array and append it to working area\n *\n * @param {Block} block - Block to add\n */\n push(e) {\n this.blocks.push(e), this.insertToDOM(e);\n }\n /**\n * Swaps blocks with indexes first and second\n *\n * @param {number} first - first block index\n * @param {number} second - second block index\n * @deprecated — use 'move' instead\n */\n swap(e, t) {\n const o = this.blocks[t];\n d.swap(this.blocks[e].holder, o.holder), this.blocks[t] = this.blocks[e], this.blocks[e] = o;\n }\n /**\n * Move a block from one to another index\n *\n * @param {number} toIndex - new index of the block\n * @param {number} fromIndex - block to move\n */\n move(e, t) {\n const o = this.blocks.splice(t, 1)[0], i = e - 1, s = Math.max(0, i), r = this.blocks[s];\n e > 0 ? this.insertToDOM(o, \"afterend\", r) : this.insertToDOM(o, \"beforebegin\", r), this.blocks.splice(e, 0, o);\n const l = this.composeBlockEvent(\"move\", {\n fromIndex: t,\n toIndex: e\n });\n o.call(J.MOVED, l);\n }\n /**\n * Insert new Block at passed index\n *\n * @param {number} index — index to insert Block\n * @param {Block} block — Block to insert\n * @param {boolean} replace — it true, replace block on given index\n */\n insert(e, t, o = !1) {\n if (!this.length) {\n this.push(t);\n return;\n }\n e > this.length && (e = this.length), o && (this.blocks[e].holder.remove(), this.blocks[e].call(J.REMOVED));\n const i = o ? 1 : 0;\n if (this.blocks.splice(e, i, t), e > 0) {\n const s = this.blocks[e - 1];\n this.insertToDOM(t, \"afterend\", s);\n } else {\n const s = this.blocks[e + 1];\n s ? this.insertToDOM(t, \"beforebegin\", s) : this.insertToDOM(t);\n }\n }\n /**\n * Replaces block under passed index with passed block\n *\n * @param index - index of existed block\n * @param block - new block\n */\n replace(e, t) {\n if (this.blocks[e] === void 0)\n throw Error(\"Incorrect index\");\n this.blocks[e].holder.replaceWith(t.holder), this.blocks[e] = t;\n }\n /**\n * Inserts several blocks at once\n *\n * @param blocks - blocks to insert\n * @param index - index to insert blocks at\n */\n insertMany(e, t) {\n const o = new DocumentFragment();\n for (const i of e)\n o.appendChild(i.holder);\n if (this.length > 0) {\n if (t > 0) {\n const i = Math.min(t - 1, this.length - 1);\n this.blocks[i].holder.after(o);\n } else\n t === 0 && this.workingArea.prepend(o);\n this.blocks.splice(t, 0, ...e);\n } else\n this.blocks.push(...e), this.workingArea.appendChild(o);\n e.forEach((i) => i.call(J.RENDERED));\n }\n /**\n * Remove block\n *\n * @param {number} index - index of Block to remove\n */\n remove(e) {\n isNaN(e) && (e = this.length - 1), this.blocks[e].holder.remove(), this.blocks[e].call(J.REMOVED), this.blocks.splice(e, 1);\n }\n /**\n * Remove all blocks\n */\n removeAll() {\n this.workingArea.innerHTML = \"\", this.blocks.forEach((e) => e.call(J.REMOVED)), this.blocks.length = 0;\n }\n /**\n * Insert Block after passed target\n *\n * @todo decide if this method is necessary\n * @param {Block} targetBlock — target after which Block should be inserted\n * @param {Block} newBlock — Block to insert\n */\n insertAfter(e, t) {\n const o = this.blocks.indexOf(e);\n this.insert(o + 1, t);\n }\n /**\n * Get Block by index\n *\n * @param {number} index — Block index\n * @returns {Block}\n */\n get(e) {\n return this.blocks[e];\n }\n /**\n * Return index of passed Block\n *\n * @param {Block} block - Block to find\n * @returns {number}\n */\n indexOf(e) {\n return this.blocks.indexOf(e);\n }\n /**\n * Insert new Block into DOM\n *\n * @param {Block} block - Block to insert\n * @param {InsertPosition} position — insert position (if set, will use insertAdjacentElement)\n * @param {Block} target — Block related to position\n */\n insertToDOM(e, t, o) {\n t ? o.holder.insertAdjacentElement(t, e.holder) : this.workingArea.appendChild(e.holder), e.call(J.RENDERED);\n }\n /**\n * Composes Block event with passed type and details\n *\n * @param {string} type - event type\n * @param {object} detail - event detail\n */\n composeBlockEvent(e, t) {\n return new CustomEvent(e, {\n detail: t\n });\n }\n}\nconst Tt = \"block-removed\", Ct = \"block-added\", Ji = \"block-moved\", St = \"block-changed\";\nclass Qi {\n constructor() {\n this.completed = Promise.resolve();\n }\n /**\n * Add new promise to queue\n *\n * @param operation - promise should be added to queue\n */\n add(e) {\n return new Promise((t, o) => {\n this.completed = this.completed.then(e).then(t).catch(o);\n });\n }\n}\nclass es extends y {\n constructor() {\n super(...arguments), this._currentBlockIndex = -1, this._blocks = null;\n }\n /**\n * Returns current Block index\n *\n * @returns {number}\n */\n get currentBlockIndex() {\n return this._currentBlockIndex;\n }\n /**\n * Set current Block index and fire Block lifecycle callbacks\n *\n * @param {number} newIndex - index of Block to set as current\n */\n set currentBlockIndex(e) {\n this._currentBlockIndex = e;\n }\n /**\n * returns first Block\n *\n * @returns {Block}\n */\n get firstBlock() {\n return this._blocks[0];\n }\n /**\n * returns last Block\n *\n * @returns {Block}\n */\n get lastBlock() {\n return this._blocks[this._blocks.length - 1];\n }\n /**\n * Get current Block instance\n *\n * @returns {Block}\n */\n get currentBlock() {\n return this._blocks[this.currentBlockIndex];\n }\n /**\n * Set passed Block as a current\n *\n * @param block - block to set as a current\n */\n set currentBlock(e) {\n this.currentBlockIndex = this.getBlockIndex(e);\n }\n /**\n * Returns next Block instance\n *\n * @returns {Block|null}\n */\n get nextBlock() {\n return this.currentBlockIndex === this._blocks.length - 1 ? null : this._blocks[this.currentBlockIndex + 1];\n }\n /**\n * Return first Block with inputs after current Block\n *\n * @returns {Block | undefined}\n */\n get nextContentfulBlock() {\n return this.blocks.slice(this.currentBlockIndex + 1).find((t) => !!t.inputs.length);\n }\n /**\n * Return first Block with inputs before current Block\n *\n * @returns {Block | undefined}\n */\n get previousContentfulBlock() {\n return this.blocks.slice(0, this.currentBlockIndex).reverse().find((t) => !!t.inputs.length);\n }\n /**\n * Returns previous Block instance\n *\n * @returns {Block|null}\n */\n get previousBlock() {\n return this.currentBlockIndex === 0 ? null : this._blocks[this.currentBlockIndex - 1];\n }\n /**\n * Get array of Block instances\n *\n * @returns {Block[]} {@link Blocks#array}\n */\n get blocks() {\n return this._blocks.array;\n }\n /**\n * Check if each Block is empty\n *\n * @returns {boolean}\n */\n get isEditorEmpty() {\n return this.blocks.every((e) => e.isEmpty);\n }\n /**\n * Should be called after Editor.UI preparation\n * Define this._blocks property\n */\n prepare() {\n const e = new Xe(this.Editor.UI.nodes.redactor);\n this._blocks = new Proxy(e, {\n set: Xe.set,\n get: Xe.get\n }), this.listeners.on(\n document,\n \"copy\",\n (t) => this.Editor.BlockEvents.handleCommandC(t)\n );\n }\n /**\n * Toggle read-only state\n *\n * If readOnly is true:\n * - Unbind event handlers from created Blocks\n *\n * if readOnly is false:\n * - Bind event handlers to all existing Blocks\n *\n * @param {boolean} readOnlyEnabled - \"read only\" state\n */\n toggleReadOnly(e) {\n e ? this.disableModuleBindings() : this.enableModuleBindings();\n }\n /**\n * Creates Block instance by tool name\n *\n * @param {object} options - block creation options\n * @param {string} options.tool - tools passed in editor config {@link EditorConfig#tools}\n * @param {string} [options.id] - unique id for this block\n * @param {BlockToolData} [options.data] - constructor params\n * @returns {Block}\n */\n composeBlock({\n tool: e,\n data: t = {},\n id: o = void 0,\n tunes: i = {}\n }) {\n const s = this.Editor.ReadOnly.isEnabled, r = this.Editor.Tools.blockTools.get(e), l = new D({\n id: o,\n data: t,\n tool: r,\n api: this.Editor.API,\n readOnly: s,\n tunesData: i\n }, this.eventsDispatcher);\n return s || window.requestIdleCallback(() => {\n this.bindBlockEvents(l);\n }, { timeout: 2e3 }), l;\n }\n /**\n * Insert new block into _blocks\n *\n * @param {object} options - insert options\n * @param {string} [options.id] - block's unique id\n * @param {string} [options.tool] - plugin name, by default method inserts the default block type\n * @param {object} [options.data] - plugin data\n * @param {number} [options.index] - index where to insert new Block\n * @param {boolean} [options.needToFocus] - flag shows if needed to update current Block index\n * @param {boolean} [options.replace] - flag shows if block by passed index should be replaced with inserted one\n * @returns {Block}\n */\n insert({\n id: e = void 0,\n tool: t = this.config.defaultBlock,\n data: o = {},\n index: i,\n needToFocus: s = !0,\n replace: r = !1,\n tunes: l = {}\n } = {}) {\n let a = i;\n a === void 0 && (a = this.currentBlockIndex + (r ? 0 : 1));\n const c = this.composeBlock({\n id: e,\n tool: t,\n data: o,\n tunes: l\n });\n return r && this.blockDidMutated(Tt, this.getBlockByIndex(a), {\n index: a\n }), this._blocks.insert(a, c, r), this.blockDidMutated(Ct, c, {\n index: a\n }), s ? this.currentBlockIndex = a : a <= this.currentBlockIndex && this.currentBlockIndex++, c;\n }\n /**\n * Inserts several blocks at once\n *\n * @param blocks - blocks to insert\n * @param index - index where to insert\n */\n insertMany(e, t = 0) {\n this._blocks.insertMany(e, t);\n }\n /**\n * Update Block data.\n *\n * Currently we don't have an 'update' method in the Tools API, so we just create a new block with the same id and type\n * Should not trigger 'block-removed' or 'block-added' events.\n *\n * If neither data nor tunes is provided, return the provided block instead.\n *\n * @param block - block to update\n * @param data - (optional) new data\n * @param tunes - (optional) tune data\n */\n async update(e, t, o) {\n if (!t && !o)\n return e;\n const i = await e.data, s = this.composeBlock({\n id: e.id,\n tool: e.name,\n data: Object.assign({}, i, t ?? {}),\n tunes: o ?? e.tunes\n }), r = this.getBlockIndex(e);\n return this._blocks.replace(r, s), this.blockDidMutated(St, s, {\n index: r\n }), s;\n }\n /**\n * Replace passed Block with the new one with specified Tool and data\n *\n * @param block - block to replace\n * @param newTool - new Tool name\n * @param data - new Tool data\n */\n replace(e, t, o) {\n const i = this.getBlockIndex(e);\n return this.insert({\n tool: t,\n data: o,\n index: i,\n replace: !0\n });\n }\n /**\n * Insert pasted content. Call onPaste callback after insert.\n *\n * @param {string} toolName - name of Tool to insert\n * @param {PasteEvent} pasteEvent - pasted data\n * @param {boolean} replace - should replace current block\n */\n paste(e, t, o = !1) {\n const i = this.insert({\n tool: e,\n replace: o\n });\n try {\n window.requestIdleCallback(() => {\n i.call(J.ON_PASTE, t);\n });\n } catch (s) {\n I(`${e}: onPaste callback call is failed`, \"error\", s);\n }\n return i;\n }\n /**\n * Insert new default block at passed index\n *\n * @param {number} index - index where Block should be inserted\n * @param {boolean} needToFocus - if true, updates current Block index\n *\n * TODO: Remove method and use insert() with index instead (?)\n * @returns {Block} inserted Block\n */\n insertDefaultBlockAtIndex(e, t = !1) {\n const o = this.composeBlock({ tool: this.config.defaultBlock });\n return this._blocks[e] = o, this.blockDidMutated(Ct, o, {\n index: e\n }), t ? this.currentBlockIndex = e : e <= this.currentBlockIndex && this.currentBlockIndex++, o;\n }\n /**\n * Always inserts at the end\n *\n * @returns {Block}\n */\n insertAtEnd() {\n return this.currentBlockIndex = this.blocks.length - 1, this.insert();\n }\n /**\n * Merge two blocks\n *\n * @param {Block} targetBlock - previous block will be append to this block\n * @param {Block} blockToMerge - block that will be merged with target block\n * @returns {Promise} - the sequence that can be continued\n */\n async mergeBlocks(e, t) {\n let o;\n if (e.name === t.name && e.mergeable) {\n const i = await t.data;\n if (V(i)) {\n console.error(\"Could not merge Block. Failed to extract original Block data.\");\n return;\n }\n const [s] = it([i], e.tool.sanitizeConfig);\n o = s;\n } else if (e.mergeable && _e(t, \"export\") && _e(e, \"import\")) {\n const i = await t.exportDataAsString(), s = q(i, e.tool.sanitizeConfig);\n o = xt(s, e.tool.conversionConfig);\n }\n o !== void 0 && (await e.mergeWith(o), this.removeBlock(t), this.currentBlockIndex = this._blocks.indexOf(e));\n }\n /**\n * Remove passed Block\n *\n * @param block - Block to remove\n * @param addLastBlock - if true, adds new default block at the end. @todo remove this logic and use event-bus instead\n */\n removeBlock(e, t = !0) {\n return new Promise((o) => {\n const i = this._blocks.indexOf(e);\n if (!this.validateIndex(i))\n throw new Error(\"Can't find a Block to remove\");\n e.destroy(), this._blocks.remove(i), this.blockDidMutated(Tt, e, {\n index: i\n }), this.currentBlockIndex >= i && this.currentBlockIndex--, this.blocks.length ? i === 0 && (this.currentBlockIndex = 0) : (this.unsetCurrentBlock(), t && this.insert()), o();\n });\n }\n /**\n * Remove only selected Blocks\n * and returns first Block index where started removing...\n *\n * @returns {number|undefined}\n */\n removeSelectedBlocks() {\n let e;\n for (let t = this.blocks.length - 1; t >= 0; t--)\n this.blocks[t].selected && (this.removeBlock(this.blocks[t]), e = t);\n return e;\n }\n /**\n * Attention!\n * After removing insert the new default typed Block and focus on it\n * Removes all blocks\n */\n removeAllBlocks() {\n for (let e = this.blocks.length - 1; e >= 0; e--)\n this._blocks.remove(e);\n this.unsetCurrentBlock(), this.insert(), this.currentBlock.firstInput.focus();\n }\n /**\n * Split current Block\n * 1. Extract content from Caret position to the Block`s end\n * 2. Insert a new Block below current one with extracted content\n *\n * @returns {Block}\n */\n split() {\n const e = this.Editor.Caret.extractFragmentFromCaretPosition(), t = d.make(\"div\");\n t.appendChild(e);\n const o = {\n text: d.isEmpty(t) ? \"\" : t.innerHTML\n };\n return this.insert({ data: o });\n }\n /**\n * Returns Block by passed index\n *\n * @param {number} index - index to get. -1 to get last\n * @returns {Block}\n */\n getBlockByIndex(e) {\n return e === -1 && (e = this._blocks.length - 1), this._blocks[e];\n }\n /**\n * Returns an index for passed Block\n *\n * @param block - block to find index\n */\n getBlockIndex(e) {\n return this._blocks.indexOf(e);\n }\n /**\n * Returns the Block by passed id\n *\n * @param id - id of block to get\n * @returns {Block}\n */\n getBlockById(e) {\n return this._blocks.array.find((t) => t.id === e);\n }\n /**\n * Get Block instance by html element\n *\n * @param {Node} element - html element to get Block by\n */\n getBlock(e) {\n d.isElement(e) || (e = e.parentNode);\n const t = this._blocks.nodes, o = e.closest(`.${D.CSS.wrapper}`), i = t.indexOf(o);\n if (i >= 0)\n return this._blocks[i];\n }\n /**\n * 1) Find first-level Block from passed child Node\n * 2) Mark it as current\n *\n * @param {Node} childNode - look ahead from this node.\n * @returns {Block | undefined} can return undefined in case when the passed child note is not a part of the current editor instance\n */\n setCurrentBlockByChildNode(e) {\n d.isElement(e) || (e = e.parentNode);\n const t = e.closest(`.${D.CSS.wrapper}`);\n if (!t)\n return;\n const o = t.closest(`.${this.Editor.UI.CSS.editorWrapper}`);\n if (o != null && o.isEqualNode(this.Editor.UI.nodes.wrapper))\n return this.currentBlockIndex = this._blocks.nodes.indexOf(t), this.currentBlock.updateCurrentInput(), this.currentBlock;\n }\n /**\n * Return block which contents passed node\n *\n * @param {Node} childNode - node to get Block by\n * @returns {Block}\n */\n getBlockByChildNode(e) {\n if (!e || !(e instanceof Node))\n return;\n d.isElement(e) || (e = e.parentNode);\n const t = e.closest(`.${D.CSS.wrapper}`);\n return this.blocks.find((o) => o.holder === t);\n }\n /**\n * Swap Blocks Position\n *\n * @param {number} fromIndex - index of first block\n * @param {number} toIndex - index of second block\n * @deprecated — use 'move' instead\n */\n swap(e, t) {\n this._blocks.swap(e, t), this.currentBlockIndex = t;\n }\n /**\n * Move a block to a new index\n *\n * @param {number} toIndex - index where to move Block\n * @param {number} fromIndex - index of Block to move\n */\n move(e, t = this.currentBlockIndex) {\n if (isNaN(e) || isNaN(t)) {\n I(\"Warning during 'move' call: incorrect indices provided.\", \"warn\");\n return;\n }\n if (!this.validateIndex(e) || !this.validateIndex(t)) {\n I(\"Warning during 'move' call: indices cannot be lower than 0 or greater than the amount of blocks.\", \"warn\");\n return;\n }\n this._blocks.move(e, t), this.currentBlockIndex = e, this.blockDidMutated(Ji, this.currentBlock, {\n fromIndex: t,\n toIndex: e\n });\n }\n /**\n * Converts passed Block to the new Tool\n * Uses Conversion Config\n *\n * @param blockToConvert - Block that should be converted\n * @param targetToolName - name of the Tool to convert to\n * @param blockDataOverrides - optional new Block data overrides\n */\n async convert(e, t, o) {\n if (!await e.save())\n throw new Error(\"Could not convert Block. Failed to extract original Block data.\");\n const s = this.Editor.Tools.blockTools.get(t);\n if (!s)\n throw new Error(`Could not convert Block. Tool «${t}» not found.`);\n const r = await e.exportDataAsString(), l = q(\n r,\n s.sanitizeConfig\n );\n let a = xt(l, s.conversionConfig);\n return o && (a = Object.assign(a, o)), this.replace(e, s.name, a);\n }\n /**\n * Sets current Block Index -1 which means unknown\n * and clear highlights\n */\n unsetCurrentBlock() {\n this.currentBlockIndex = -1;\n }\n /**\n * Clears Editor\n *\n * @param {boolean} needToAddDefaultBlock - 1) in internal calls (for example, in api.blocks.render)\n * we don't need to add an empty default block\n * 2) in api.blocks.clear we should add empty block\n */\n async clear(e = !1) {\n const t = new Qi();\n this.blocks.forEach((o) => {\n t.add(async () => {\n await this.removeBlock(o, !1);\n });\n }), await t.completed, this.unsetCurrentBlock(), e && this.insert(), this.Editor.UI.checkEmptiness();\n }\n /**\n * Cleans up all the block tools' resources\n * This is called when editor is destroyed\n */\n async destroy() {\n await Promise.all(this.blocks.map((e) => e.destroy()));\n }\n /**\n * Bind Block events\n *\n * @param {Block} block - Block to which event should be bound\n */\n bindBlockEvents(e) {\n const { BlockEvents: t } = this.Editor;\n this.readOnlyMutableListeners.on(e.holder, \"keydown\", (o) => {\n t.keydown(o);\n }), this.readOnlyMutableListeners.on(e.holder, \"keyup\", (o) => {\n t.keyup(o);\n }), this.readOnlyMutableListeners.on(e.holder, \"dragover\", (o) => {\n t.dragOver(o);\n }), this.readOnlyMutableListeners.on(e.holder, \"dragleave\", (o) => {\n t.dragLeave(o);\n }), e.on(\"didMutated\", (o) => this.blockDidMutated(St, o, {\n index: this.getBlockIndex(o)\n }));\n }\n /**\n * Disable mutable handlers and bindings\n */\n disableModuleBindings() {\n this.readOnlyMutableListeners.clearAll();\n }\n /**\n * Enables all module handlers and bindings for all Blocks\n */\n enableModuleBindings() {\n this.readOnlyMutableListeners.on(\n document,\n \"cut\",\n (e) => this.Editor.BlockEvents.handleCommandX(e)\n ), this.blocks.forEach((e) => {\n this.bindBlockEvents(e);\n });\n }\n /**\n * Validates that the given index is not lower than 0 or higher than the amount of blocks\n *\n * @param {number} index - index of blocks array to validate\n * @returns {boolean}\n */\n validateIndex(e) {\n return !(e < 0 || e >= this._blocks.length);\n }\n /**\n * Block mutation callback\n *\n * @param mutationType - what happened with block\n * @param block - mutated block\n * @param detailData - additional data to pass with change event\n */\n blockDidMutated(e, t, o) {\n const i = new CustomEvent(e, {\n detail: {\n target: new G(t),\n ...o\n }\n });\n return this.eventsDispatcher.emit(Dt, {\n event: i\n }), t;\n }\n}\nclass ts extends y {\n constructor() {\n super(...arguments), this.anyBlockSelectedCache = null, this.needToSelectAll = !1, this.nativeInputSelected = !1, this.readyToBlockSelection = !1;\n }\n /**\n * Sanitizer Config\n *\n * @returns {SanitizerConfig}\n */\n get sanitizerConfig() {\n return {\n p: {},\n h1: {},\n h2: {},\n h3: {},\n h4: {},\n h5: {},\n h6: {},\n ol: {},\n ul: {},\n li: {},\n br: !0,\n img: {\n src: !0,\n width: !0,\n height: !0\n },\n a: {\n href: !0\n },\n b: {},\n i: {},\n u: {}\n };\n }\n /**\n * Flag that identifies all Blocks selection\n *\n * @returns {boolean}\n */\n get allBlocksSelected() {\n const { BlockManager: e } = this.Editor;\n return e.blocks.every((t) => t.selected === !0);\n }\n /**\n * Set selected all blocks\n *\n * @param {boolean} state - state to set\n */\n set allBlocksSelected(e) {\n const { BlockManager: t } = this.Editor;\n t.blocks.forEach((o) => {\n o.selected = e;\n }), this.clearCache();\n }\n /**\n * Flag that identifies any Block selection\n *\n * @returns {boolean}\n */\n get anyBlockSelected() {\n const { BlockManager: e } = this.Editor;\n return this.anyBlockSelectedCache === null && (this.anyBlockSelectedCache = e.blocks.some((t) => t.selected === !0)), this.anyBlockSelectedCache;\n }\n /**\n * Return selected Blocks array\n *\n * @returns {Block[]}\n */\n get selectedBlocks() {\n return this.Editor.BlockManager.blocks.filter((e) => e.selected);\n }\n /**\n * Module Preparation\n * Registers Shortcuts CMD+A and CMD+C\n * to select all and copy them\n */\n prepare() {\n this.selection = new b(), he.add({\n name: \"CMD+A\",\n handler: (e) => {\n const { BlockManager: t, ReadOnly: o } = this.Editor;\n if (o.isEnabled) {\n e.preventDefault(), this.selectAllBlocks();\n return;\n }\n t.currentBlock && this.handleCommandA(e);\n },\n on: this.Editor.UI.nodes.redactor\n });\n }\n /**\n * Toggle read-only state\n *\n * - Remove all ranges\n * - Unselect all Blocks\n */\n toggleReadOnly() {\n b.get().removeAllRanges(), this.allBlocksSelected = !1;\n }\n /**\n * Remove selection of Block\n *\n * @param {number?} index - Block index according to the BlockManager's indexes\n */\n unSelectBlockByIndex(e) {\n const { BlockManager: t } = this.Editor;\n let o;\n isNaN(e) ? o = t.currentBlock : o = t.getBlockByIndex(e), o.selected = !1, this.clearCache();\n }\n /**\n * Clear selection from Blocks\n *\n * @param {Event} reason - event caused clear of selection\n * @param {boolean} restoreSelection - if true, restore saved selection\n */\n clearSelection(e, t = !1) {\n const { BlockManager: o, Caret: i, RectangleSelection: s } = this.Editor;\n this.needToSelectAll = !1, this.nativeInputSelected = !1, this.readyToBlockSelection = !1;\n const r = e && e instanceof KeyboardEvent, l = r && Mt(e.keyCode);\n if (this.anyBlockSelected && r && l && !b.isSelectionExists) {\n const a = o.removeSelectedBlocks();\n o.insertDefaultBlockAtIndex(a, !0), i.setToBlock(o.currentBlock), Oe(() => {\n const c = e.key;\n i.insertContentAtCaretPosition(c.length > 1 ? \"\" : c);\n }, 20)();\n }\n if (this.Editor.CrossBlockSelection.clear(e), !this.anyBlockSelected || s.isRectActivated()) {\n this.Editor.RectangleSelection.clearSelection();\n return;\n }\n t && this.selection.restore(), this.allBlocksSelected = !1;\n }\n /**\n * Reduce each Block and copy its content\n *\n * @param {ClipboardEvent} e - copy/cut event\n * @returns {Promise}\n */\n copySelectedBlocks(e) {\n e.preventDefault();\n const t = d.make(\"div\");\n this.selectedBlocks.forEach((s) => {\n const r = q(s.holder.innerHTML, this.sanitizerConfig), l = d.make(\"p\");\n l.innerHTML = r, t.appendChild(l);\n });\n const o = Array.from(t.childNodes).map((s) => s.textContent).join(`\n\n`), i = t.innerHTML;\n return e.clipboardData.setData(\"text/plain\", o), e.clipboardData.setData(\"text/html\", i), Promise.all(this.selectedBlocks.map((s) => s.save())).then((s) => {\n try {\n e.clipboardData.setData(this.Editor.Paste.MIME_TYPE, JSON.stringify(s));\n } catch {\n }\n });\n }\n /**\n * Select Block by its index\n *\n * @param {number?} index - Block index according to the BlockManager's indexes\n */\n selectBlockByIndex(e) {\n const { BlockManager: t } = this.Editor, o = t.getBlockByIndex(e);\n o !== void 0 && this.selectBlock(o);\n }\n /**\n * Select passed Block\n *\n * @param {Block} block - Block to select\n */\n selectBlock(e) {\n this.selection.save(), b.get().removeAllRanges(), e.selected = !0, this.clearCache(), this.Editor.InlineToolbar.close();\n }\n /**\n * Remove selection from passed Block\n *\n * @param {Block} block - Block to unselect\n */\n unselectBlock(e) {\n e.selected = !1, this.clearCache();\n }\n /**\n * Clear anyBlockSelected cache\n */\n clearCache() {\n this.anyBlockSelectedCache = null;\n }\n /**\n * Module destruction\n * De-registers Shortcut CMD+A\n */\n destroy() {\n he.remove(this.Editor.UI.nodes.redactor, \"CMD+A\");\n }\n /**\n * First CMD+A selects all input content by native behaviour,\n * next CMD+A keypress selects all blocks\n *\n * @param {KeyboardEvent} event - keyboard event\n */\n handleCommandA(e) {\n if (this.Editor.RectangleSelection.clearSelection(), d.isNativeInput(e.target) && !this.readyToBlockSelection) {\n this.readyToBlockSelection = !0;\n return;\n }\n const t = this.Editor.BlockManager.getBlock(e.target), o = t.inputs;\n if (o.length > 1 && !this.readyToBlockSelection) {\n this.readyToBlockSelection = !0;\n return;\n }\n if (o.length === 1 && !this.needToSelectAll) {\n this.needToSelectAll = !0;\n return;\n }\n this.needToSelectAll ? (e.preventDefault(), this.selectAllBlocks(), this.needToSelectAll = !1, this.readyToBlockSelection = !1) : this.readyToBlockSelection && (e.preventDefault(), this.selectBlock(t), this.needToSelectAll = !0);\n }\n /**\n * Select All Blocks\n * Each Block has selected setter that makes Block copyable\n */\n selectAllBlocks() {\n this.selection.save(), b.get().removeAllRanges(), this.allBlocksSelected = !0, this.Editor.InlineToolbar.close();\n }\n}\nclass Re extends y {\n /**\n * Allowed caret positions in input\n *\n * @static\n * @returns {{START: string, END: string, DEFAULT: string}}\n */\n get positions() {\n return {\n START: \"start\",\n END: \"end\",\n DEFAULT: \"default\"\n };\n }\n /**\n * Elements styles that can be useful for Caret Module\n */\n static get CSS() {\n return {\n shadowCaret: \"cdx-shadow-caret\"\n };\n }\n /**\n * Method gets Block instance and puts caret to the text node with offset\n * There two ways that method applies caret position:\n * - first found text node: sets at the beginning, but you can pass an offset\n * - last found text node: sets at the end of the node. Also, you can customize the behaviour\n *\n * @param {Block} block - Block class\n * @param {string} position - position where to set caret.\n * If default - leave default behaviour and apply offset if it's passed\n * @param {number} offset - caret offset regarding to the text node\n */\n setToBlock(e, t = this.positions.DEFAULT, o = 0) {\n var c;\n const { BlockManager: i, BlockSelection: s } = this.Editor;\n if (s.clearSelection(), !e.focusable) {\n (c = window.getSelection()) == null || c.removeAllRanges(), s.selectBlock(e), i.currentBlock = e;\n return;\n }\n let r;\n switch (t) {\n case this.positions.START:\n r = e.firstInput;\n break;\n case this.positions.END:\n r = e.lastInput;\n break;\n default:\n r = e.currentInput;\n }\n if (!r)\n return;\n const l = d.getDeepestNode(r, t === this.positions.END), a = d.getContentLength(l);\n switch (!0) {\n case t === this.positions.START:\n o = 0;\n break;\n case t === this.positions.END:\n case o > a:\n o = a;\n break;\n }\n this.set(l, o), i.setCurrentBlockByChildNode(e.holder), i.currentBlock.currentInput = r;\n }\n /**\n * Set caret to the current input of current Block.\n *\n * @param {HTMLElement} input - input where caret should be set\n * @param {string} position - position of the caret.\n * If default - leave default behaviour and apply offset if it's passed\n * @param {number} offset - caret offset regarding to the text node\n */\n setToInput(e, t = this.positions.DEFAULT, o = 0) {\n const { currentBlock: i } = this.Editor.BlockManager, s = d.getDeepestNode(e);\n switch (t) {\n case this.positions.START:\n this.set(s, 0);\n break;\n case this.positions.END:\n this.set(s, d.getContentLength(s));\n break;\n default:\n o && this.set(s, o);\n }\n i.currentInput = e;\n }\n /**\n * Creates Document Range and sets caret to the element with offset\n *\n * @param {HTMLElement} element - target node.\n * @param {number} offset - offset\n */\n set(e, t = 0) {\n const { top: i, bottom: s } = b.setCursor(e, t), { innerHeight: r } = window;\n i < 0 ? window.scrollBy(0, i - 30) : s > r && window.scrollBy(0, s - r + 30);\n }\n /**\n * Set Caret to the last Block\n * If last block is not empty, append another empty block\n */\n setToTheLastBlock() {\n const e = this.Editor.BlockManager.lastBlock;\n if (e)\n if (e.tool.isDefault && e.isEmpty)\n this.setToBlock(e);\n else {\n const t = this.Editor.BlockManager.insertAtEnd();\n this.setToBlock(t);\n }\n }\n /**\n * Extract content fragment of current Block from Caret position to the end of the Block\n */\n extractFragmentFromCaretPosition() {\n const e = b.get();\n if (e.rangeCount) {\n const t = e.getRangeAt(0), o = this.Editor.BlockManager.currentBlock.currentInput;\n if (t.deleteContents(), o)\n if (d.isNativeInput(o)) {\n const i = o, s = document.createDocumentFragment(), r = i.value.substring(0, i.selectionStart), l = i.value.substring(i.selectionStart);\n return s.textContent = l, i.value = r, s;\n } else {\n const i = t.cloneRange();\n return i.selectNodeContents(o), i.setStart(t.endContainer, t.endOffset), i.extractContents();\n }\n }\n }\n /**\n * Set's caret to the next Block or Tool`s input\n * Before moving caret, we should check if caret position is at the end of Plugins node\n * Using {@link Dom#getDeepestNode} to get a last node and match with current selection\n *\n * @param {boolean} force - pass true to skip check for caret position\n */\n navigateNext(e = !1) {\n const { BlockManager: t } = this.Editor, { currentBlock: o, nextBlock: i } = t;\n if (o === void 0)\n return !1;\n const { nextInput: s, currentInput: r } = o, l = r !== void 0 ? Ae(r) : void 0;\n let a = i;\n const c = e || l || !o.focusable;\n if (s && c)\n return this.setToInput(s, this.positions.START), !0;\n if (a === null) {\n if (o.tool.isDefault || !c)\n return !1;\n a = t.insertAtEnd();\n }\n return c ? (this.setToBlock(a, this.positions.START), !0) : !1;\n }\n /**\n * Set's caret to the previous Tool`s input or Block\n * Before moving caret, we should check if caret position is start of the Plugins node\n * Using {@link Dom#getDeepestNode} to get a last node and match with current selection\n *\n * @param {boolean} force - pass true to skip check for caret position\n */\n navigatePrevious(e = !1) {\n const { currentBlock: t, previousBlock: o } = this.Editor.BlockManager;\n if (!t)\n return !1;\n const { previousInput: i, currentInput: s } = t, r = s !== void 0 ? Me(s) : void 0, l = e || r || !t.focusable;\n return i && l ? (this.setToInput(i, this.positions.END), !0) : o !== null && l ? (this.setToBlock(o, this.positions.END), !0) : !1;\n }\n /**\n * Inserts shadow element after passed element where caret can be placed\n *\n * @param {Element} element - element after which shadow caret should be inserted\n */\n createShadow(e) {\n const t = document.createElement(\"span\");\n t.classList.add(Re.CSS.shadowCaret), e.insertAdjacentElement(\"beforeend\", t);\n }\n /**\n * Restores caret position\n *\n * @param {HTMLElement} element - element where caret should be restored\n */\n restoreCaret(e) {\n const t = e.querySelector(`.${Re.CSS.shadowCaret}`);\n if (!t)\n return;\n new b().expandToTag(t);\n const i = document.createRange();\n i.selectNode(t), i.extractContents();\n }\n /**\n * Inserts passed content at caret position\n *\n * @param {string} content - content to insert\n */\n insertContentAtCaretPosition(e) {\n const t = document.createDocumentFragment(), o = document.createElement(\"div\"), i = b.get(), s = b.range;\n o.innerHTML = e, Array.from(o.childNodes).forEach((c) => t.appendChild(c)), t.childNodes.length === 0 && t.appendChild(new Text());\n const r = t.lastChild;\n s.deleteContents(), s.insertNode(t);\n const l = document.createRange(), a = r.nodeType === Node.TEXT_NODE ? r : r.firstChild;\n a !== null && a.textContent !== null && l.setStart(a, a.textContent.length), i.removeAllRanges(), i.addRange(l);\n }\n}\nclass os extends y {\n constructor() {\n super(...arguments), this.onMouseUp = () => {\n this.listeners.off(document, \"mouseover\", this.onMouseOver), this.listeners.off(document, \"mouseup\", this.onMouseUp);\n }, this.onMouseOver = (e) => {\n const { BlockManager: t, BlockSelection: o } = this.Editor;\n if (e.relatedTarget === null && e.target === null)\n return;\n const i = t.getBlockByChildNode(e.relatedTarget) || this.lastSelectedBlock, s = t.getBlockByChildNode(e.target);\n if (!(!i || !s) && s !== i) {\n if (i === this.firstSelectedBlock) {\n b.get().removeAllRanges(), i.selected = !0, s.selected = !0, o.clearCache();\n return;\n }\n if (s === this.firstSelectedBlock) {\n i.selected = !1, s.selected = !1, o.clearCache();\n return;\n }\n this.Editor.InlineToolbar.close(), this.toggleBlocksSelectedState(i, s), this.lastSelectedBlock = s;\n }\n };\n }\n /**\n * Module preparation\n *\n * @returns {Promise}\n */\n async prepare() {\n this.listeners.on(document, \"mousedown\", (e) => {\n this.enableCrossBlockSelection(e);\n });\n }\n /**\n * Sets up listeners\n *\n * @param {MouseEvent} event - mouse down event\n */\n watchSelection(e) {\n if (e.button !== wo.LEFT)\n return;\n const { BlockManager: t } = this.Editor;\n this.firstSelectedBlock = t.getBlock(e.target), this.lastSelectedBlock = this.firstSelectedBlock, this.listeners.on(document, \"mouseover\", this.onMouseOver), this.listeners.on(document, \"mouseup\", this.onMouseUp);\n }\n /**\n * Return boolean is cross block selection started:\n * there should be at least 2 selected blocks\n */\n get isCrossBlockSelectionStarted() {\n return !!this.firstSelectedBlock && !!this.lastSelectedBlock && this.firstSelectedBlock !== this.lastSelectedBlock;\n }\n /**\n * Change selection state of the next Block\n * Used for CBS via Shift + arrow keys\n *\n * @param {boolean} next - if true, toggle next block. Previous otherwise\n */\n toggleBlockSelectedState(e = !0) {\n const { BlockManager: t, BlockSelection: o } = this.Editor;\n this.lastSelectedBlock || (this.lastSelectedBlock = this.firstSelectedBlock = t.currentBlock), this.firstSelectedBlock === this.lastSelectedBlock && (this.firstSelectedBlock.selected = !0, o.clearCache(), b.get().removeAllRanges());\n const i = t.blocks.indexOf(this.lastSelectedBlock) + (e ? 1 : -1), s = t.blocks[i];\n s && (this.lastSelectedBlock.selected !== s.selected ? (s.selected = !0, o.clearCache()) : (this.lastSelectedBlock.selected = !1, o.clearCache()), this.lastSelectedBlock = s, this.Editor.InlineToolbar.close(), s.holder.scrollIntoView({\n block: \"nearest\"\n }));\n }\n /**\n * Clear saved state\n *\n * @param {Event} reason - event caused clear of selection\n */\n clear(e) {\n const { BlockManager: t, BlockSelection: o, Caret: i } = this.Editor, s = t.blocks.indexOf(this.firstSelectedBlock), r = t.blocks.indexOf(this.lastSelectedBlock);\n if (o.anyBlockSelected && s > -1 && r > -1 && e && e instanceof KeyboardEvent)\n switch (e.keyCode) {\n case w.DOWN:\n case w.RIGHT:\n i.setToBlock(t.blocks[Math.max(s, r)], i.positions.END);\n break;\n case w.UP:\n case w.LEFT:\n i.setToBlock(t.blocks[Math.min(s, r)], i.positions.START);\n break;\n default:\n i.setToBlock(t.blocks[Math.max(s, r)], i.positions.END);\n }\n this.firstSelectedBlock = this.lastSelectedBlock = null;\n }\n /**\n * Enables Cross Block Selection\n *\n * @param {MouseEvent} event - mouse down event\n */\n enableCrossBlockSelection(e) {\n const { UI: t } = this.Editor;\n b.isCollapsed || this.Editor.BlockSelection.clearSelection(e), t.nodes.redactor.contains(e.target) ? this.watchSelection(e) : this.Editor.BlockSelection.clearSelection(e);\n }\n /**\n * Change blocks selection state between passed two blocks.\n *\n * @param {Block} firstBlock - first block in range\n * @param {Block} lastBlock - last block in range\n */\n toggleBlocksSelectedState(e, t) {\n const { BlockManager: o, BlockSelection: i } = this.Editor, s = o.blocks.indexOf(e), r = o.blocks.indexOf(t), l = e.selected !== t.selected;\n for (let a = Math.min(s, r); a <= Math.max(s, r); a++) {\n const c = o.blocks[a];\n c !== this.firstSelectedBlock && c !== (l ? e : t) && (o.blocks[a].selected = !o.blocks[a].selected, i.clearCache());\n }\n }\n}\nclass is extends y {\n constructor() {\n super(...arguments), this.isStartedAtEditor = !1;\n }\n /**\n * Toggle read-only state\n *\n * if state is true:\n * - disable all drag-n-drop event handlers\n *\n * if state is false:\n * - restore drag-n-drop event handlers\n *\n * @param {boolean} readOnlyEnabled - \"read only\" state\n */\n toggleReadOnly(e) {\n e ? this.disableModuleBindings() : this.enableModuleBindings();\n }\n /**\n * Add drag events listeners to editor zone\n */\n enableModuleBindings() {\n const { UI: e } = this.Editor;\n this.readOnlyMutableListeners.on(e.nodes.holder, \"drop\", async (t) => {\n await this.processDrop(t);\n }, !0), this.readOnlyMutableListeners.on(e.nodes.holder, \"dragstart\", () => {\n this.processDragStart();\n }), this.readOnlyMutableListeners.on(e.nodes.holder, \"dragover\", (t) => {\n this.processDragOver(t);\n }, !0);\n }\n /**\n * Unbind drag-n-drop event handlers\n */\n disableModuleBindings() {\n this.readOnlyMutableListeners.clearAll();\n }\n /**\n * Handle drop event\n *\n * @param {DragEvent} dropEvent - drop event\n */\n async processDrop(e) {\n const {\n BlockManager: t,\n Paste: o,\n Caret: i\n } = this.Editor;\n e.preventDefault(), t.blocks.forEach((r) => {\n r.dropTarget = !1;\n }), b.isAtEditor && !b.isCollapsed && this.isStartedAtEditor && document.execCommand(\"delete\"), this.isStartedAtEditor = !1;\n const s = t.setCurrentBlockByChildNode(e.target);\n if (s)\n this.Editor.Caret.setToBlock(s, i.positions.END);\n else {\n const r = t.setCurrentBlockByChildNode(t.lastBlock.holder);\n this.Editor.Caret.setToBlock(r, i.positions.END);\n }\n await o.processDataTransfer(e.dataTransfer, !0);\n }\n /**\n * Handle drag start event\n */\n processDragStart() {\n b.isAtEditor && !b.isCollapsed && (this.isStartedAtEditor = !0), this.Editor.InlineToolbar.close();\n }\n /**\n * @param {DragEvent} dragEvent - drag event\n */\n processDragOver(e) {\n e.preventDefault();\n }\n}\nconst ss = 180, ns = 400;\nclass rs extends y {\n /**\n * Prepare the module\n *\n * @param options - options used by the modification observer module\n * @param options.config - Editor configuration object\n * @param options.eventsDispatcher - common Editor event bus\n */\n constructor({ config: e, eventsDispatcher: t }) {\n super({\n config: e,\n eventsDispatcher: t\n }), this.disabled = !1, this.batchingTimeout = null, this.batchingOnChangeQueue = /* @__PURE__ */ new Map(), this.batchTime = ns, this.mutationObserver = new MutationObserver((o) => {\n this.redactorChanged(o);\n }), this.eventsDispatcher.on(Dt, (o) => {\n this.particularBlockChanged(o.event);\n }), this.eventsDispatcher.on(Rt, () => {\n this.disable();\n }), this.eventsDispatcher.on(Ft, () => {\n this.enable();\n });\n }\n /**\n * Enables onChange event\n */\n enable() {\n this.mutationObserver.observe(\n this.Editor.UI.nodes.redactor,\n {\n childList: !0,\n subtree: !0,\n characterData: !0,\n attributes: !0\n }\n ), this.disabled = !1;\n }\n /**\n * Disables onChange event\n */\n disable() {\n this.mutationObserver.disconnect(), this.disabled = !0;\n }\n /**\n * Call onChange event passed to Editor.js configuration\n *\n * @param event - some of our custom change events\n */\n particularBlockChanged(e) {\n this.disabled || !O(this.config.onChange) || (this.batchingOnChangeQueue.set(`block:${e.detail.target.id}:event:${e.type}`, e), this.batchingTimeout && clearTimeout(this.batchingTimeout), this.batchingTimeout = setTimeout(() => {\n let t;\n this.batchingOnChangeQueue.size === 1 ? t = this.batchingOnChangeQueue.values().next().value : t = Array.from(this.batchingOnChangeQueue.values()), this.config.onChange && this.config.onChange(this.Editor.API.methods, t), this.batchingOnChangeQueue.clear();\n }, this.batchTime));\n }\n /**\n * Fired on every blocks wrapper dom change\n *\n * @param mutations - mutations happened\n */\n redactorChanged(e) {\n this.eventsDispatcher.emit(Je, {\n mutations: e\n });\n }\n}\nconst ro = class lo extends y {\n constructor() {\n super(...arguments), this.MIME_TYPE = \"application/x-editor-js\", this.toolsTags = {}, this.tagsByTool = {}, this.toolsPatterns = [], this.toolsFiles = {}, this.exceptionList = [], this.processTool = (e) => {\n try {\n const t = e.create({}, {}, !1);\n if (e.pasteConfig === !1) {\n this.exceptionList.push(e.name);\n return;\n }\n if (!O(t.onPaste))\n return;\n this.getTagsConfig(e), this.getFilesConfig(e), this.getPatternsConfig(e);\n } catch (t) {\n I(\n `Paste handling for «${e.name}» Tool hasn't been set up because of the error`,\n \"warn\",\n t\n );\n }\n }, this.handlePasteEvent = async (e) => {\n const { BlockManager: t, Toolbar: o } = this.Editor, i = t.setCurrentBlockByChildNode(e.target);\n !i || this.isNativeBehaviour(e.target) && !e.clipboardData.types.includes(\"Files\") || i && this.exceptionList.includes(i.name) || (e.preventDefault(), this.processDataTransfer(e.clipboardData), o.close());\n };\n }\n /**\n * Set onPaste callback and collect tools` paste configurations\n */\n async prepare() {\n this.processTools();\n }\n /**\n * Set read-only state\n *\n * @param {boolean} readOnlyEnabled - read only flag value\n */\n toggleReadOnly(e) {\n e ? this.unsetCallback() : this.setCallback();\n }\n /**\n * Handle pasted or dropped data transfer object\n *\n * @param {DataTransfer} dataTransfer - pasted or dropped data transfer object\n * @param {boolean} isDragNDrop - true if data transfer comes from drag'n'drop events\n */\n async processDataTransfer(e, t = !1) {\n const { Tools: o } = this.Editor, i = e.types;\n if ((i.includes ? i.includes(\"Files\") : i.contains(\"Files\")) && !V(this.toolsFiles)) {\n await this.processFiles(e.files);\n return;\n }\n const r = e.getData(this.MIME_TYPE), l = e.getData(\"text/plain\");\n let a = e.getData(\"text/html\");\n if (r)\n try {\n this.insertEditorJSData(JSON.parse(r));\n return;\n } catch {\n }\n t && l.trim() && a.trim() && (a = \"

\" + (a.trim() ? a : l) + \"

\");\n const c = Object.keys(this.toolsTags).reduce((p, g) => (p[g.toLowerCase()] = this.toolsTags[g].sanitizationConfig ?? {}, p), {}), u = Object.assign({}, c, o.getAllInlineToolsSanitizeConfig(), { br: {} }), h = q(a, u);\n !h.trim() || h.trim() === l || !d.isHTMLString(h) ? await this.processText(l) : await this.processText(h, !0);\n }\n /**\n * Process pasted text and divide them into Blocks\n *\n * @param {string} data - text to process. Can be HTML or plain.\n * @param {boolean} isHTML - if passed string is HTML, this parameter should be true\n */\n async processText(e, t = !1) {\n const { Caret: o, BlockManager: i } = this.Editor, s = t ? this.processHTML(e) : this.processPlain(e);\n if (!s.length)\n return;\n if (s.length === 1) {\n s[0].isBlock ? this.processSingleBlock(s.pop()) : this.processInlinePaste(s.pop());\n return;\n }\n const l = i.currentBlock && i.currentBlock.tool.isDefault && i.currentBlock.isEmpty;\n s.map(\n async (a, c) => this.insertBlock(a, c === 0 && l)\n ), i.currentBlock && o.setToBlock(i.currentBlock, o.positions.END);\n }\n /**\n * Set onPaste callback handler\n */\n setCallback() {\n this.listeners.on(this.Editor.UI.nodes.holder, \"paste\", this.handlePasteEvent);\n }\n /**\n * Unset onPaste callback handler\n */\n unsetCallback() {\n this.listeners.off(this.Editor.UI.nodes.holder, \"paste\", this.handlePasteEvent);\n }\n /**\n * Get and process tool`s paste configs\n */\n processTools() {\n const e = this.Editor.Tools.blockTools;\n Array.from(e.values()).forEach(this.processTool);\n }\n /**\n * Get tags name list from either tag name or sanitization config.\n *\n * @param {string | object} tagOrSanitizeConfig - tag name or sanitize config object.\n * @returns {string[]} array of tags.\n */\n collectTagNames(e) {\n return Q(e) ? [e] : R(e) ? Object.keys(e) : [];\n }\n /**\n * Get tags to substitute by Tool\n *\n * @param tool - BlockTool object\n */\n getTagsConfig(e) {\n if (e.pasteConfig === !1)\n return;\n const t = e.pasteConfig.tags || [], o = [];\n t.forEach((i) => {\n const s = this.collectTagNames(i);\n o.push(...s), s.forEach((r) => {\n if (Object.prototype.hasOwnProperty.call(this.toolsTags, r)) {\n I(\n `Paste handler for «${e.name}» Tool on «${r}» tag is skipped because it is already used by «${this.toolsTags[r].tool.name}» Tool.`,\n \"warn\"\n );\n return;\n }\n const l = R(i) ? i[r] : null;\n this.toolsTags[r.toUpperCase()] = {\n tool: e,\n sanitizationConfig: l\n };\n });\n }), this.tagsByTool[e.name] = o.map((i) => i.toUpperCase());\n }\n /**\n * Get files` types and extensions to substitute by Tool\n *\n * @param tool - BlockTool object\n */\n getFilesConfig(e) {\n if (e.pasteConfig === !1)\n return;\n const { files: t = {} } = e.pasteConfig;\n let { extensions: o, mimeTypes: i } = t;\n !o && !i || (o && !Array.isArray(o) && (I(`«extensions» property of the onDrop config for «${e.name}» Tool should be an array`), o = []), i && !Array.isArray(i) && (I(`«mimeTypes» property of the onDrop config for «${e.name}» Tool should be an array`), i = []), i && (i = i.filter((s) => To(s) ? !0 : (I(`MIME type value «${s}» for the «${e.name}» Tool is not a valid MIME type`, \"warn\"), !1))), this.toolsFiles[e.name] = {\n extensions: o || [],\n mimeTypes: i || []\n });\n }\n /**\n * Get RegExp patterns to substitute by Tool\n *\n * @param tool - BlockTool object\n */\n getPatternsConfig(e) {\n e.pasteConfig === !1 || !e.pasteConfig.patterns || V(e.pasteConfig.patterns) || Object.entries(e.pasteConfig.patterns).forEach(([t, o]) => {\n o instanceof RegExp || I(\n `Pattern ${o} for «${e.name}» Tool is skipped because it should be a Regexp instance.`,\n \"warn\"\n ), this.toolsPatterns.push({\n key: t,\n pattern: o,\n tool: e\n });\n });\n }\n /**\n * Check if browser behavior suits better\n *\n * @param {EventTarget} element - element where content has been pasted\n * @returns {boolean}\n */\n isNativeBehaviour(e) {\n return d.isNativeInput(e);\n }\n /**\n * Get files from data transfer object and insert related Tools\n *\n * @param {FileList} items - pasted or dropped items\n */\n async processFiles(e) {\n const { BlockManager: t } = this.Editor;\n let o;\n o = await Promise.all(\n Array.from(e).map((r) => this.processFile(r))\n ), o = o.filter((r) => !!r);\n const s = t.currentBlock.tool.isDefault && t.currentBlock.isEmpty;\n o.forEach(\n (r, l) => {\n t.paste(r.type, r.event, l === 0 && s);\n }\n );\n }\n /**\n * Get information about file and find Tool to handle it\n *\n * @param {File} file - file to process\n */\n async processFile(e) {\n const t = Bo(e), o = Object.entries(this.toolsFiles).find(([r, { mimeTypes: l, extensions: a }]) => {\n const [c, u] = e.type.split(\"/\"), h = a.find((g) => g.toLowerCase() === t.toLowerCase()), p = l.find((g) => {\n const [f, k] = g.split(\"/\");\n return f === c && (k === u || k === \"*\");\n });\n return !!h || !!p;\n });\n if (!o)\n return;\n const [i] = o;\n return {\n event: this.composePasteEvent(\"file\", {\n file: e\n }),\n type: i\n };\n }\n /**\n * Split HTML string to blocks and return it as array of Block data\n *\n * @param {string} innerHTML - html string to process\n * @returns {PasteData[]}\n */\n processHTML(e) {\n const { Tools: t } = this.Editor, o = d.make(\"DIV\");\n return o.innerHTML = e, this.getNodes(o).map((s) => {\n let r, l = t.defaultTool, a = !1;\n switch (s.nodeType) {\n case Node.DOCUMENT_FRAGMENT_NODE:\n r = d.make(\"div\"), r.appendChild(s);\n break;\n case Node.ELEMENT_NODE:\n r = s, a = !0, this.toolsTags[r.tagName] && (l = this.toolsTags[r.tagName].tool);\n break;\n }\n const { tags: c } = l.pasteConfig || { tags: [] }, u = c.reduce((g, f) => (this.collectTagNames(f).forEach((C) => {\n const S = R(f) ? f[C] : null;\n g[C.toLowerCase()] = S || {};\n }), g), {}), h = Object.assign({}, u, l.baseSanitizeConfig);\n if (r.tagName.toLowerCase() === \"table\") {\n const g = q(r.outerHTML, h);\n r = d.make(\"div\", void 0, {\n innerHTML: g\n }).firstChild;\n } else\n r.innerHTML = q(r.innerHTML, h);\n const p = this.composePasteEvent(\"tag\", {\n data: r\n });\n return {\n content: r,\n isBlock: a,\n tool: l.name,\n event: p\n };\n }).filter((s) => {\n const r = d.isEmpty(s.content), l = d.isSingleTag(s.content);\n return !r || l;\n });\n }\n /**\n * Split plain text by new line symbols and return it as array of Block data\n *\n * @param {string} plain - string to process\n * @returns {PasteData[]}\n */\n processPlain(e) {\n const { defaultBlock: t } = this.config;\n if (!e)\n return [];\n const o = t;\n return e.split(/\\r?\\n/).filter((i) => i.trim()).map((i) => {\n const s = d.make(\"div\");\n s.textContent = i;\n const r = this.composePasteEvent(\"tag\", {\n data: s\n });\n return {\n content: s,\n tool: o,\n isBlock: !1,\n event: r\n };\n });\n }\n /**\n * Process paste of single Block tool content\n *\n * @param {PasteData} dataToInsert - data of Block to insert\n */\n async processSingleBlock(e) {\n const { Caret: t, BlockManager: o } = this.Editor, { currentBlock: i } = o;\n if (!i || e.tool !== i.name || !d.containsOnlyInlineElements(e.content.innerHTML)) {\n this.insertBlock(e, (i == null ? void 0 : i.tool.isDefault) && i.isEmpty);\n return;\n }\n t.insertContentAtCaretPosition(e.content.innerHTML);\n }\n /**\n * Process paste to single Block:\n * 1. Find patterns` matches\n * 2. Insert new block if it is not the same type as current one\n * 3. Just insert text if there is no substitutions\n *\n * @param {PasteData} dataToInsert - data of Block to insert\n */\n async processInlinePaste(e) {\n const { BlockManager: t, Caret: o } = this.Editor, { content: i } = e;\n if (t.currentBlock && t.currentBlock.tool.isDefault && i.textContent.length < lo.PATTERN_PROCESSING_MAX_LENGTH) {\n const r = await this.processPattern(i.textContent);\n if (r) {\n const l = t.currentBlock && t.currentBlock.tool.isDefault && t.currentBlock.isEmpty, a = t.paste(r.tool, r.event, l);\n o.setToBlock(a, o.positions.END);\n return;\n }\n }\n if (t.currentBlock && t.currentBlock.currentInput) {\n const r = t.currentBlock.tool.baseSanitizeConfig;\n document.execCommand(\n \"insertHTML\",\n !1,\n q(i.innerHTML, r)\n );\n } else\n this.insertBlock(e);\n }\n /**\n * Get patterns` matches\n *\n * @param {string} text - text to process\n * @returns {Promise<{event: PasteEvent, tool: string}>}\n */\n async processPattern(e) {\n const t = this.toolsPatterns.find((i) => {\n const s = i.pattern.exec(e);\n return s ? e === s.shift() : !1;\n });\n return t ? {\n event: this.composePasteEvent(\"pattern\", {\n key: t.key,\n data: e\n }),\n tool: t.tool.name\n } : void 0;\n }\n /**\n * Insert pasted Block content to Editor\n *\n * @param {PasteData} data - data to insert\n * @param {boolean} canReplaceCurrentBlock - if true and is current Block is empty, will replace current Block\n * @returns {void}\n */\n insertBlock(e, t = !1) {\n const { BlockManager: o, Caret: i } = this.Editor, { currentBlock: s } = o;\n let r;\n if (t && s && s.isEmpty) {\n r = o.paste(e.tool, e.event, !0), i.setToBlock(r, i.positions.END);\n return;\n }\n r = o.paste(e.tool, e.event), i.setToBlock(r, i.positions.END);\n }\n /**\n * Insert data passed as application/x-editor-js JSON\n *\n * @param {Array} blocks — Blocks' data to insert\n * @returns {void}\n */\n insertEditorJSData(e) {\n const { BlockManager: t, Caret: o, Tools: i } = this.Editor;\n it(\n e,\n (r) => i.blockTools.get(r).sanitizeConfig\n ).forEach(({ tool: r, data: l }, a) => {\n let c = !1;\n a === 0 && (c = t.currentBlock && t.currentBlock.tool.isDefault && t.currentBlock.isEmpty);\n const u = t.insert({\n tool: r,\n data: l,\n replace: c\n });\n o.setToBlock(u, o.positions.END);\n });\n }\n /**\n * Fetch nodes from Element node\n *\n * @param {Node} node - current node\n * @param {Node[]} nodes - processed nodes\n * @param {Node} destNode - destination node\n */\n processElementNode(e, t, o) {\n const i = Object.keys(this.toolsTags), s = e, { tool: r } = this.toolsTags[s.tagName] || {}, l = this.tagsByTool[r == null ? void 0 : r.name] || [], a = i.includes(s.tagName), c = d.blockElements.includes(s.tagName.toLowerCase()), u = Array.from(s.children).some(\n ({ tagName: p }) => i.includes(p) && !l.includes(p)\n ), h = Array.from(s.children).some(\n ({ tagName: p }) => d.blockElements.includes(p.toLowerCase())\n );\n if (!c && !a && !u)\n return o.appendChild(s), [...t, o];\n if (a && !u || c && !h && !u)\n return [...t, o, s];\n }\n /**\n * Recursively divide HTML string to two types of nodes:\n * 1. Block element\n * 2. Document Fragments contained text and markup tags like a, b, i etc.\n *\n * @param {Node} wrapper - wrapper of paster HTML content\n * @returns {Node[]}\n */\n getNodes(e) {\n const t = Array.from(e.childNodes);\n let o;\n const i = (s, r) => {\n if (d.isEmpty(r) && !d.isSingleTag(r))\n return s;\n const l = s[s.length - 1];\n let a = new DocumentFragment();\n switch (l && d.isFragment(l) && (a = s.pop()), r.nodeType) {\n case Node.ELEMENT_NODE:\n if (o = this.processElementNode(r, s, a), o)\n return o;\n break;\n case Node.TEXT_NODE:\n return a.appendChild(r), [...s, a];\n default:\n return [...s, a];\n }\n return [...s, ...Array.from(r.childNodes).reduce(i, [])];\n };\n return t.reduce(i, []);\n }\n /**\n * Compose paste event with passed type and detail\n *\n * @param {string} type - event type\n * @param {PasteEventDetail} detail - event detail\n */\n composePasteEvent(e, t) {\n return new CustomEvent(e, {\n detail: t\n });\n }\n};\nro.PATTERN_PROCESSING_MAX_LENGTH = 450;\nlet ls = ro;\nclass as extends y {\n constructor() {\n super(...arguments), this.toolsDontSupportReadOnly = [], this.readOnlyEnabled = !1;\n }\n /**\n * Returns state of read only mode\n */\n get isEnabled() {\n return this.readOnlyEnabled;\n }\n /**\n * Set initial state\n */\n async prepare() {\n const { Tools: e } = this.Editor, { blockTools: t } = e, o = [];\n Array.from(t.entries()).forEach(([i, s]) => {\n s.isReadOnlySupported || o.push(i);\n }), this.toolsDontSupportReadOnly = o, this.config.readOnly && o.length > 0 && this.throwCriticalError(), this.toggle(this.config.readOnly, !0);\n }\n /**\n * Set read-only mode or toggle current state\n * Call all Modules `toggleReadOnly` method and re-render Editor\n *\n * @param state - (optional) read-only state or toggle\n * @param isInitial - (optional) true when editor is initializing\n */\n async toggle(e = !this.readOnlyEnabled, t = !1) {\n e && this.toolsDontSupportReadOnly.length > 0 && this.throwCriticalError();\n const o = this.readOnlyEnabled;\n this.readOnlyEnabled = e;\n for (const s in this.Editor)\n this.Editor[s].toggleReadOnly && this.Editor[s].toggleReadOnly(e);\n if (o === e)\n return this.readOnlyEnabled;\n if (t)\n return this.readOnlyEnabled;\n this.Editor.ModificationsObserver.disable();\n const i = await this.Editor.Saver.save();\n return await this.Editor.BlockManager.clear(), await this.Editor.Renderer.render(i.blocks), this.Editor.ModificationsObserver.enable(), this.readOnlyEnabled;\n }\n /**\n * Throws an error about tools which don't support read-only mode\n */\n throwCriticalError() {\n throw new Pt(\n `To enable read-only mode all connected tools should support it. Tools ${this.toolsDontSupportReadOnly.join(\", \")} don't support read-only mode.`\n );\n }\n}\nclass xe extends y {\n constructor() {\n super(...arguments), this.isRectSelectionActivated = !1, this.SCROLL_SPEED = 3, this.HEIGHT_OF_SCROLL_ZONE = 40, this.BOTTOM_SCROLL_ZONE = 1, this.TOP_SCROLL_ZONE = 2, this.MAIN_MOUSE_BUTTON = 0, this.mousedown = !1, this.isScrolling = !1, this.inScrollZone = null, this.startX = 0, this.startY = 0, this.mouseX = 0, this.mouseY = 0, this.stackOfSelected = [], this.listenerIds = [];\n }\n /**\n * CSS classes for the Block\n *\n * @returns {{wrapper: string, content: string}}\n */\n static get CSS() {\n return {\n overlay: \"codex-editor-overlay\",\n overlayContainer: \"codex-editor-overlay__container\",\n rect: \"codex-editor-overlay__rectangle\",\n topScrollZone: \"codex-editor-overlay__scroll-zone--top\",\n bottomScrollZone: \"codex-editor-overlay__scroll-zone--bottom\"\n };\n }\n /**\n * Module Preparation\n * Creating rect and hang handlers\n */\n prepare() {\n this.enableModuleBindings();\n }\n /**\n * Init rect params\n *\n * @param {number} pageX - X coord of mouse\n * @param {number} pageY - Y coord of mouse\n */\n startSelection(e, t) {\n const o = document.elementFromPoint(e - window.pageXOffset, t - window.pageYOffset);\n o.closest(`.${this.Editor.Toolbar.CSS.toolbar}`) || (this.Editor.BlockSelection.allBlocksSelected = !1, this.clearSelection(), this.stackOfSelected = []);\n const s = [\n `.${D.CSS.content}`,\n `.${this.Editor.Toolbar.CSS.toolbar}`,\n `.${this.Editor.InlineToolbar.CSS.inlineToolbar}`\n ], r = o.closest(\".\" + this.Editor.UI.CSS.editorWrapper), l = s.some((a) => !!o.closest(a));\n !r || l || (this.mousedown = !0, this.startX = e, this.startY = t);\n }\n /**\n * Clear all params to end selection\n */\n endSelection() {\n this.mousedown = !1, this.startX = 0, this.startY = 0, this.overlayRectangle.style.display = \"none\";\n }\n /**\n * is RectSelection Activated\n */\n isRectActivated() {\n return this.isRectSelectionActivated;\n }\n /**\n * Mark that selection is end\n */\n clearSelection() {\n this.isRectSelectionActivated = !1;\n }\n /**\n * Sets Module necessary event handlers\n */\n enableModuleBindings() {\n const { container: e } = this.genHTML();\n this.listeners.on(e, \"mousedown\", (t) => {\n this.processMouseDown(t);\n }, !1), this.listeners.on(document.body, \"mousemove\", Ve((t) => {\n this.processMouseMove(t);\n }, 10), {\n passive: !0\n }), this.listeners.on(document.body, \"mouseleave\", () => {\n this.processMouseLeave();\n }), this.listeners.on(window, \"scroll\", Ve((t) => {\n this.processScroll(t);\n }, 10), {\n passive: !0\n }), this.listeners.on(document.body, \"mouseup\", () => {\n this.processMouseUp();\n }, !1);\n }\n /**\n * Handle mouse down events\n *\n * @param {MouseEvent} mouseEvent - mouse event payload\n */\n processMouseDown(e) {\n if (e.button !== this.MAIN_MOUSE_BUTTON)\n return;\n e.target.closest(d.allInputsSelector) !== null || this.startSelection(e.pageX, e.pageY);\n }\n /**\n * Handle mouse move events\n *\n * @param {MouseEvent} mouseEvent - mouse event payload\n */\n processMouseMove(e) {\n this.changingRectangle(e), this.scrollByZones(e.clientY);\n }\n /**\n * Handle mouse leave\n */\n processMouseLeave() {\n this.clearSelection(), this.endSelection();\n }\n /**\n * @param {MouseEvent} mouseEvent - mouse event payload\n */\n processScroll(e) {\n this.changingRectangle(e);\n }\n /**\n * Handle mouse up\n */\n processMouseUp() {\n this.clearSelection(), this.endSelection();\n }\n /**\n * Scroll If mouse in scroll zone\n *\n * @param {number} clientY - Y coord of mouse\n */\n scrollByZones(e) {\n if (this.inScrollZone = null, e <= this.HEIGHT_OF_SCROLL_ZONE && (this.inScrollZone = this.TOP_SCROLL_ZONE), document.documentElement.clientHeight - e <= this.HEIGHT_OF_SCROLL_ZONE && (this.inScrollZone = this.BOTTOM_SCROLL_ZONE), !this.inScrollZone) {\n this.isScrolling = !1;\n return;\n }\n this.isScrolling || (this.scrollVertical(this.inScrollZone === this.TOP_SCROLL_ZONE ? -this.SCROLL_SPEED : this.SCROLL_SPEED), this.isScrolling = !0);\n }\n /**\n * Generates required HTML elements\n *\n * @returns {Object}\n */\n genHTML() {\n const { UI: e } = this.Editor, t = e.nodes.holder.querySelector(\".\" + e.CSS.editorWrapper), o = d.make(\"div\", xe.CSS.overlay, {}), i = d.make(\"div\", xe.CSS.overlayContainer, {}), s = d.make(\"div\", xe.CSS.rect, {});\n return i.appendChild(s), o.appendChild(i), t.appendChild(o), this.overlayRectangle = s, {\n container: t,\n overlay: o\n };\n }\n /**\n * Activates scrolling if blockSelection is active and mouse is in scroll zone\n *\n * @param {number} speed - speed of scrolling\n */\n scrollVertical(e) {\n if (!(this.inScrollZone && this.mousedown))\n return;\n const t = window.pageYOffset;\n window.scrollBy(0, e), this.mouseY += window.pageYOffset - t, setTimeout(() => {\n this.scrollVertical(e);\n }, 0);\n }\n /**\n * Handles the change in the rectangle and its effect\n *\n * @param {MouseEvent} event - mouse event\n */\n changingRectangle(e) {\n if (!this.mousedown)\n return;\n e.pageY !== void 0 && (this.mouseX = e.pageX, this.mouseY = e.pageY);\n const { rightPos: t, leftPos: o, index: i } = this.genInfoForMouseSelection(), s = this.startX > t && this.mouseX > t, r = this.startX < o && this.mouseX < o;\n this.rectCrossesBlocks = !(s || r), this.isRectSelectionActivated || (this.rectCrossesBlocks = !1, this.isRectSelectionActivated = !0, this.shrinkRectangleToPoint(), this.overlayRectangle.style.display = \"block\"), this.updateRectangleSize(), this.Editor.Toolbar.close(), i !== void 0 && (this.trySelectNextBlock(i), this.inverseSelection(), b.get().removeAllRanges());\n }\n /**\n * Shrink rect to singular point\n */\n shrinkRectangleToPoint() {\n this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`, this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`;\n }\n /**\n * Select or unselect all of blocks in array if rect is out or in selectable area\n */\n inverseSelection() {\n const t = this.Editor.BlockManager.getBlockByIndex(this.stackOfSelected[0]).selected;\n if (this.rectCrossesBlocks && !t)\n for (const o of this.stackOfSelected)\n this.Editor.BlockSelection.selectBlockByIndex(o);\n if (!this.rectCrossesBlocks && t)\n for (const o of this.stackOfSelected)\n this.Editor.BlockSelection.unSelectBlockByIndex(o);\n }\n /**\n * Updates size of rectangle\n */\n updateRectangleSize() {\n this.mouseY >= this.startY ? (this.overlayRectangle.style.top = `${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.bottom = `calc(100% - ${this.mouseY - window.pageYOffset}px`) : (this.overlayRectangle.style.bottom = `calc(100% - ${this.startY - window.pageYOffset}px`, this.overlayRectangle.style.top = `${this.mouseY - window.pageYOffset}px`), this.mouseX >= this.startX ? (this.overlayRectangle.style.left = `${this.startX - window.pageXOffset}px`, this.overlayRectangle.style.right = `calc(100% - ${this.mouseX - window.pageXOffset}px`) : (this.overlayRectangle.style.right = `calc(100% - ${this.startX - window.pageXOffset}px`, this.overlayRectangle.style.left = `${this.mouseX - window.pageXOffset}px`);\n }\n /**\n * Collects information needed to determine the behavior of the rectangle\n *\n * @returns {object} index - index next Block, leftPos - start of left border of Block, rightPos - right border\n */\n genInfoForMouseSelection() {\n const t = document.body.offsetWidth / 2, o = this.mouseY - window.pageYOffset, i = document.elementFromPoint(t, o), s = this.Editor.BlockManager.getBlockByChildNode(i);\n let r;\n s !== void 0 && (r = this.Editor.BlockManager.blocks.findIndex((h) => h.holder === s.holder));\n const l = this.Editor.BlockManager.lastBlock.holder.querySelector(\".\" + D.CSS.content), a = Number.parseInt(window.getComputedStyle(l).width, 10) / 2, c = t - a, u = t + a;\n return {\n index: r,\n leftPos: c,\n rightPos: u\n };\n }\n /**\n * Select block with index index\n *\n * @param index - index of block in redactor\n */\n addBlockInSelection(e) {\n this.rectCrossesBlocks && this.Editor.BlockSelection.selectBlockByIndex(e), this.stackOfSelected.push(e);\n }\n /**\n * Adds a block to the selection and determines which blocks should be selected\n *\n * @param {object} index - index of new block in the reactor\n */\n trySelectNextBlock(e) {\n const t = this.stackOfSelected[this.stackOfSelected.length - 1] === e, o = this.stackOfSelected.length, i = 1, s = -1, r = 0;\n if (t)\n return;\n const l = this.stackOfSelected[o - 1] - this.stackOfSelected[o - 2] > 0;\n let a = r;\n o > 1 && (a = l ? i : s);\n const c = e > this.stackOfSelected[o - 1] && a === i, u = e < this.stackOfSelected[o - 1] && a === s, p = !(c || u || a === r);\n if (!p && (e > this.stackOfSelected[o - 1] || this.stackOfSelected[o - 1] === void 0)) {\n let k = this.stackOfSelected[o - 1] + 1 || e;\n for (k; k <= e; k++)\n this.addBlockInSelection(k);\n return;\n }\n if (!p && e < this.stackOfSelected[o - 1]) {\n for (let k = this.stackOfSelected[o - 1] - 1; k >= e; k--)\n this.addBlockInSelection(k);\n return;\n }\n if (!p)\n return;\n let g = o - 1, f;\n for (e > this.stackOfSelected[o - 1] ? f = () => e > this.stackOfSelected[g] : f = () => e < this.stackOfSelected[g]; f(); )\n this.rectCrossesBlocks && this.Editor.BlockSelection.unSelectBlockByIndex(this.stackOfSelected[g]), this.stackOfSelected.pop(), g--;\n }\n}\nclass cs extends y {\n /**\n * Renders passed blocks as one batch\n *\n * @param blocksData - blocks to render\n */\n async render(e) {\n return new Promise((t) => {\n const { Tools: o, BlockManager: i } = this.Editor;\n if (e.length === 0)\n i.insert();\n else {\n const s = e.map(({ type: r, data: l, tunes: a, id: c }) => {\n o.available.has(r) === !1 && (X(`Tool «${r}» is not found. Check 'tools' property at the Editor.js config.`, \"warn\"), l = this.composeStubDataForTool(r, l, c), r = o.stubTool);\n let u;\n try {\n u = i.composeBlock({\n id: c,\n tool: r,\n data: l,\n tunes: a\n });\n } catch (h) {\n I(`Block «${r}» skipped because of plugins error`, \"error\", {\n data: l,\n error: h\n }), l = this.composeStubDataForTool(r, l, c), r = o.stubTool, u = i.composeBlock({\n id: c,\n tool: r,\n data: l,\n tunes: a\n });\n }\n return u;\n });\n i.insertMany(s);\n }\n window.requestIdleCallback(() => {\n t();\n }, { timeout: 2e3 });\n });\n }\n /**\n * Create data for the Stub Tool that will be used instead of unavailable tool\n *\n * @param tool - unavailable tool name to stub\n * @param data - data of unavailable block\n * @param [id] - id of unavailable block\n */\n composeStubDataForTool(e, t, o) {\n const { Tools: i } = this.Editor;\n let s = e;\n if (i.unavailable.has(e)) {\n const r = i.unavailable.get(e).toolbox;\n r !== void 0 && r[0].title !== void 0 && (s = r[0].title);\n }\n return {\n savedData: {\n id: o,\n type: e,\n data: t\n },\n title: s\n };\n }\n}\nclass ds extends y {\n /**\n * Composes new chain of Promises to fire them alternatelly\n *\n * @returns {OutputData}\n */\n async save() {\n const { BlockManager: e, Tools: t } = this.Editor, o = e.blocks, i = [];\n try {\n o.forEach((l) => {\n i.push(this.getSavedData(l));\n });\n const s = await Promise.all(i), r = await it(s, (l) => t.blockTools.get(l).sanitizeConfig);\n return this.makeOutput(r);\n } catch (s) {\n X(\"Saving failed due to the Error %o\", \"error\", s);\n }\n }\n /**\n * Saves and validates\n *\n * @param {Block} block - Editor's Tool\n * @returns {ValidatedData} - Tool's validated data\n */\n async getSavedData(e) {\n const t = await e.save(), o = t && await e.validate(t.data);\n return {\n ...t,\n isValid: o\n };\n }\n /**\n * Creates output object with saved data, time and version of editor\n *\n * @param {ValidatedData} allExtractedData - data extracted from Blocks\n * @returns {OutputData}\n */\n makeOutput(e) {\n const t = [];\n return e.forEach(({ id: o, tool: i, data: s, tunes: r, isValid: l }) => {\n if (!l) {\n I(`Block «${i}» skipped because saved data is invalid`);\n return;\n }\n if (i === this.Editor.Tools.stubTool) {\n t.push(s);\n return;\n }\n const a = {\n id: o,\n type: i,\n data: s,\n ...!V(r) && {\n tunes: r\n }\n };\n t.push(a);\n }), {\n time: +/* @__PURE__ */ new Date(),\n blocks: t,\n version: \"2.30.7\"\n };\n }\n}\n(function() {\n try {\n if (typeof document < \"u\") {\n var n = document.createElement(\"style\");\n n.appendChild(document.createTextNode(\".ce-paragraph{line-height:1.6em;outline:none}.ce-block:only-of-type .ce-paragraph[data-placeholder-active]:empty:before,.ce-block:only-of-type .ce-paragraph[data-placeholder-active][data-empty=true]:before{content:attr(data-placeholder-active)}.ce-paragraph p:first-of-type{margin-top:0}.ce-paragraph p:last-of-type{margin-bottom:0}\")), document.head.appendChild(n);\n }\n } catch (e) {\n console.error(\"vite-plugin-css-injected-by-js\", e);\n }\n})();\nconst hs = '';\nfunction us(n) {\n const e = document.createElement(\"div\");\n e.innerHTML = n.trim();\n const t = document.createDocumentFragment();\n return t.append(...Array.from(e.childNodes)), t;\n}\n/**\n * Base Paragraph Block for the Editor.js.\n * Represents a regular text block\n *\n * @author CodeX (team@codex.so)\n * @copyright CodeX 2018\n * @license The MIT License (MIT)\n */\nclass ht {\n /**\n * Default placeholder for Paragraph Tool\n *\n * @returns {string}\n * @class\n */\n static get DEFAULT_PLACEHOLDER() {\n return \"\";\n }\n /**\n * Render plugin`s main Element and fill it with saved data\n *\n * @param {object} params - constructor params\n * @param {ParagraphData} params.data - previously saved data\n * @param {ParagraphConfig} params.config - user config for Tool\n * @param {object} params.api - editor.js api\n * @param {boolean} readOnly - read only mode flag\n */\n constructor({ data: e, config: t, api: o, readOnly: i }) {\n this.api = o, this.readOnly = i, this._CSS = {\n block: this.api.styles.block,\n wrapper: \"ce-paragraph\"\n }, this.readOnly || (this.onKeyUp = this.onKeyUp.bind(this)), this._placeholder = t.placeholder ? t.placeholder : ht.DEFAULT_PLACEHOLDER, this._data = e ?? {}, this._element = null, this._preserveBlank = t.preserveBlank ?? !1;\n }\n /**\n * Check if text content is empty and set empty string to inner html.\n * We need this because some browsers (e.g. Safari) insert
into empty contenteditanle elements\n *\n * @param {KeyboardEvent} e - key up event\n */\n onKeyUp(e) {\n if (e.code !== \"Backspace\" && e.code !== \"Delete\" || !this._element)\n return;\n const { textContent: t } = this._element;\n t === \"\" && (this._element.innerHTML = \"\");\n }\n /**\n * Create Tool's view\n *\n * @returns {HTMLDivElement}\n * @private\n */\n drawView() {\n const e = document.createElement(\"DIV\");\n return e.classList.add(this._CSS.wrapper, this._CSS.block), e.contentEditable = \"false\", e.dataset.placeholderActive = this.api.i18n.t(this._placeholder), this._data.text && (e.innerHTML = this._data.text), this.readOnly || (e.contentEditable = \"true\", e.addEventListener(\"keyup\", this.onKeyUp)), e;\n }\n /**\n * Return Tool's view\n *\n * @returns {HTMLDivElement}\n */\n render() {\n return this._element = this.drawView(), this._element;\n }\n /**\n * Method that specified how to merge two Text blocks.\n * Called by Editor.js by backspace at the beginning of the Block\n *\n * @param {ParagraphData} data\n * @public\n */\n merge(e) {\n if (!this._element)\n return;\n this._data.text += e.text;\n const t = us(e.text);\n this._element.appendChild(t), this._element.normalize();\n }\n /**\n * Validate Paragraph block data:\n * - check for emptiness\n *\n * @param {ParagraphData} savedData — data received after saving\n * @returns {boolean} false if saved data is not correct, otherwise true\n * @public\n */\n validate(e) {\n return !(e.text.trim() === \"\" && !this._preserveBlank);\n }\n /**\n * Extract Tool's data from the view\n *\n * @param {HTMLDivElement} toolsContent - Paragraph tools rendered view\n * @returns {ParagraphData} - saved data\n * @public\n */\n save(e) {\n return {\n text: e.innerHTML\n };\n }\n /**\n * On paste callback fired from Editor.\n *\n * @param {HTMLPasteEvent} event - event with pasted data\n */\n onPaste(e) {\n const t = {\n text: e.detail.data.innerHTML\n };\n this._data = t, window.requestAnimationFrame(() => {\n this._element && (this._element.innerHTML = this._data.text || \"\");\n });\n }\n /**\n * Enable Conversion Toolbar. Paragraph can be converted to/from other tools\n * @returns {ConversionConfig}\n */\n static get conversionConfig() {\n return {\n export: \"text\",\n // to convert Paragraph to other block, use 'text' property of saved data\n import: \"text\"\n // to covert other block's exported string to Paragraph, fill 'text' property of tool data\n };\n }\n /**\n * Sanitizer rules\n * @returns {SanitizerConfig} - Edtior.js sanitizer config\n */\n static get sanitize() {\n return {\n text: {\n br: !0\n }\n };\n }\n /**\n * Returns true to notify the core that read-only mode is supported\n *\n * @returns {boolean}\n */\n static get isReadOnlySupported() {\n return !0;\n }\n /**\n * Used by Editor paste handling API.\n * Provides configuration to handle P tags.\n *\n * @returns {PasteConfig} - Paragraph Paste Setting\n */\n static get pasteConfig() {\n return {\n tags: [\"P\"]\n };\n }\n /**\n * Icon and title for displaying at the Toolbox\n *\n * @returns {ToolboxConfig} - Paragraph Toolbox Setting\n */\n static get toolbox() {\n return {\n icon: hs,\n title: \"Text\"\n };\n }\n}\nclass ut {\n constructor() {\n this.commandName = \"bold\";\n }\n /**\n * Sanitizer Rule\n * Leave tags\n *\n * @returns {object}\n */\n static get sanitize() {\n return {\n b: {}\n };\n }\n /**\n * Create button for Inline Toolbar\n */\n render() {\n return {\n icon: bi,\n name: \"bold\",\n onActivate: () => {\n document.execCommand(this.commandName);\n },\n isActive: () => document.queryCommandState(this.commandName)\n };\n }\n /**\n * Set a shortcut\n *\n * @returns {boolean}\n */\n get shortcut() {\n return \"CMD+B\";\n }\n}\nut.isInline = !0;\nut.title = \"Bold\";\nclass pt {\n constructor() {\n this.commandName = \"italic\", this.CSS = {\n button: \"ce-inline-tool\",\n buttonActive: \"ce-inline-tool--active\",\n buttonModifier: \"ce-inline-tool--italic\"\n }, this.nodes = {\n button: null\n };\n }\n /**\n * Sanitizer Rule\n * Leave tags\n *\n * @returns {object}\n */\n static get sanitize() {\n return {\n i: {}\n };\n }\n /**\n * Create button for Inline Toolbar\n */\n render() {\n return this.nodes.button = document.createElement(\"button\"), this.nodes.button.type = \"button\", this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier), this.nodes.button.innerHTML = Bi, this.nodes.button;\n }\n /**\n * Wrap range with tag\n */\n surround() {\n document.execCommand(this.commandName);\n }\n /**\n * Check selection and set activated state to button if there are tag\n */\n checkState() {\n const e = document.queryCommandState(this.commandName);\n return this.nodes.button.classList.toggle(this.CSS.buttonActive, e), e;\n }\n /**\n * Set a shortcut\n */\n get shortcut() {\n return \"CMD+I\";\n }\n}\npt.isInline = !0;\npt.title = \"Italic\";\nclass ft {\n /**\n * @param api - Editor.js API\n */\n constructor({ api: e }) {\n this.commandLink = \"createLink\", this.commandUnlink = \"unlink\", this.ENTER_KEY = 13, this.CSS = {\n button: \"ce-inline-tool\",\n buttonActive: \"ce-inline-tool--active\",\n buttonModifier: \"ce-inline-tool--link\",\n buttonUnlink: \"ce-inline-tool--unlink\",\n input: \"ce-inline-tool-input\",\n inputShowed: \"ce-inline-tool-input--showed\"\n }, this.nodes = {\n button: null,\n input: null\n }, this.inputOpened = !1, this.toolbar = e.toolbar, this.inlineToolbar = e.inlineToolbar, this.notifier = e.notifier, this.i18n = e.i18n, this.selection = new b();\n }\n /**\n * Sanitizer Rule\n * Leave tags\n *\n * @returns {object}\n */\n static get sanitize() {\n return {\n a: {\n href: !0,\n target: \"_blank\",\n rel: \"nofollow\"\n }\n };\n }\n /**\n * Create button for Inline Toolbar\n */\n render() {\n return this.nodes.button = document.createElement(\"button\"), this.nodes.button.type = \"button\", this.nodes.button.classList.add(this.CSS.button, this.CSS.buttonModifier), this.nodes.button.innerHTML = yt, this.nodes.button;\n }\n /**\n * Input for the link\n */\n renderActions() {\n return this.nodes.input = document.createElement(\"input\"), this.nodes.input.placeholder = this.i18n.t(\"Add a link\"), this.nodes.input.enterKeyHint = \"done\", this.nodes.input.classList.add(this.CSS.input), this.nodes.input.addEventListener(\"keydown\", (e) => {\n e.keyCode === this.ENTER_KEY && this.enterPressed(e);\n }), this.nodes.input;\n }\n /**\n * Handle clicks on the Inline Toolbar icon\n *\n * @param {Range} range - range to wrap with link\n */\n surround(e) {\n if (e) {\n this.inputOpened ? (this.selection.restore(), this.selection.removeFakeBackground()) : (this.selection.setFakeBackground(), this.selection.save());\n const t = this.selection.findParentTag(\"A\");\n if (t) {\n this.selection.expandToTag(t), this.unlink(), this.closeActions(), this.checkState(), this.toolbar.close();\n return;\n }\n }\n this.toggleActions();\n }\n /**\n * Check selection and set activated state to button if there are tag\n */\n checkState() {\n const e = this.selection.findParentTag(\"A\");\n if (e) {\n this.nodes.button.innerHTML = Ii, this.nodes.button.classList.add(this.CSS.buttonUnlink), this.nodes.button.classList.add(this.CSS.buttonActive), this.openActions();\n const t = e.getAttribute(\"href\");\n this.nodes.input.value = t !== \"null\" ? t : \"\", this.selection.save();\n } else\n this.nodes.button.innerHTML = yt, this.nodes.button.classList.remove(this.CSS.buttonUnlink), this.nodes.button.classList.remove(this.CSS.buttonActive);\n return !!e;\n }\n /**\n * Function called with Inline Toolbar closing\n */\n clear() {\n this.closeActions();\n }\n /**\n * Set a shortcut\n */\n get shortcut() {\n return \"CMD+K\";\n }\n /**\n * Show/close link input\n */\n toggleActions() {\n this.inputOpened ? this.closeActions(!1) : this.openActions(!0);\n }\n /**\n * @param {boolean} needFocus - on link creation we need to focus input. On editing - nope.\n */\n openActions(e = !1) {\n this.nodes.input.classList.add(this.CSS.inputShowed), e && this.nodes.input.focus(), this.inputOpened = !0;\n }\n /**\n * Close input\n *\n * @param {boolean} clearSavedSelection — we don't need to clear saved selection\n * on toggle-clicks on the icon of opened Toolbar\n */\n closeActions(e = !0) {\n if (this.selection.isFakeBackgroundEnabled) {\n const t = new b();\n t.save(), this.selection.restore(), this.selection.removeFakeBackground(), t.restore();\n }\n this.nodes.input.classList.remove(this.CSS.inputShowed), this.nodes.input.value = \"\", e && this.selection.clearSaved(), this.inputOpened = !1;\n }\n /**\n * Enter pressed on input\n *\n * @param {KeyboardEvent} event - enter keydown event\n */\n enterPressed(e) {\n let t = this.nodes.input.value || \"\";\n if (!t.trim()) {\n this.selection.restore(), this.unlink(), e.preventDefault(), this.closeActions();\n return;\n }\n if (!this.validateURL(t)) {\n this.notifier.show({\n message: \"Pasted link is not valid.\",\n style: \"error\"\n }), I(\"Incorrect Link pasted\", \"warn\", t);\n return;\n }\n t = this.prepareLink(t), this.selection.restore(), this.selection.removeFakeBackground(), this.insertLink(t), e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation(), this.selection.collapseToEnd(), this.inlineToolbar.close();\n }\n /**\n * Detects if passed string is URL\n *\n * @param {string} str - string to validate\n * @returns {boolean}\n */\n validateURL(e) {\n return !/\\s/.test(e);\n }\n /**\n * Process link before injection\n * - sanitize\n * - add protocol for links like 'google.com'\n *\n * @param {string} link - raw user input\n */\n prepareLink(e) {\n return e = e.trim(), e = this.addProtocol(e), e;\n }\n /**\n * Add 'http' protocol to the links like 'vc.ru', 'google.com'\n *\n * @param {string} link - string to process\n */\n addProtocol(e) {\n if (/^(\\w+):(\\/\\/)?/.test(e))\n return e;\n const t = /^\\/[^/\\s]/.test(e), o = e.substring(0, 1) === \"#\", i = /^\\/\\/[^/\\s]/.test(e);\n return !t && !o && !i && (e = \"http://\" + e), e;\n }\n /**\n * Inserts tag with \"href\"\n *\n * @param {string} link - \"href\" value\n */\n insertLink(e) {\n const t = this.selection.findParentTag(\"A\");\n t && this.selection.expandToTag(t), document.execCommand(this.commandLink, !1, e);\n }\n /**\n * Removes tag\n */\n unlink() {\n document.execCommand(this.commandUnlink);\n }\n}\nft.isInline = !0;\nft.title = \"Link\";\nclass ao {\n /**\n * @param api - Editor.js API\n */\n constructor({ api: e }) {\n this.i18nAPI = e.i18n, this.blocksAPI = e.blocks, this.selectionAPI = e.selection, this.toolsAPI = e.tools, this.caretAPI = e.caret;\n }\n /**\n * Returns tool's UI config\n */\n async render() {\n const e = b.get(), t = this.blocksAPI.getBlockByElement(e.anchorNode);\n if (t === void 0)\n return [];\n const o = this.toolsAPI.getBlockTools(), i = await zt(t, o);\n if (i.length === 0)\n return [];\n const s = i.reduce((c, u) => {\n var h;\n return (h = u.toolbox) == null || h.forEach((p) => {\n c.push({\n icon: p.icon,\n title: z.t(K.toolNames, p.title),\n name: u.name,\n closeOnActivate: !0,\n onActivate: async () => {\n const g = await this.blocksAPI.convert(t.id, u.name, p.data);\n this.caretAPI.setToBlock(g, \"end\");\n }\n });\n }), c;\n }, []), r = await t.getActiveToolboxEntry(), l = r !== void 0 ? r.icon : Kt, a = !pe();\n return {\n icon: l,\n name: \"convert-to\",\n hint: {\n title: this.i18nAPI.t(\"Convert to\")\n },\n children: {\n searchable: a,\n items: s,\n onOpen: () => {\n a && (this.selectionAPI.setFakeBackground(), this.selectionAPI.save());\n },\n onClose: () => {\n a && (this.selectionAPI.restore(), this.selectionAPI.removeFakeBackground());\n }\n }\n };\n }\n}\nao.isInline = !0;\nclass co {\n /**\n * @param options - constructor options\n * @param options.data - stub tool data\n * @param options.api - Editor.js API\n */\n constructor({ data: e, api: t }) {\n this.CSS = {\n wrapper: \"ce-stub\",\n info: \"ce-stub__info\",\n title: \"ce-stub__title\",\n subtitle: \"ce-stub__subtitle\"\n }, this.api = t, this.title = e.title || this.api.i18n.t(\"Error\"), this.subtitle = this.api.i18n.t(\"The block can not be displayed correctly.\"), this.savedData = e.savedData, this.wrapper = this.make();\n }\n /**\n * Returns stub holder\n *\n * @returns {HTMLElement}\n */\n render() {\n return this.wrapper;\n }\n /**\n * Return original Tool data\n *\n * @returns {BlockToolData}\n */\n save() {\n return this.savedData;\n }\n /**\n * Create Tool html markup\n *\n * @returns {HTMLElement}\n */\n make() {\n const e = d.make(\"div\", this.CSS.wrapper), t = Mi, o = d.make(\"div\", this.CSS.info), i = d.make(\"div\", this.CSS.title, {\n textContent: this.title\n }), s = d.make(\"div\", this.CSS.subtitle, {\n textContent: this.subtitle\n });\n return e.innerHTML = t, o.appendChild(i), o.appendChild(s), e.appendChild(o), e;\n }\n}\nco.isReadOnlySupported = !0;\nclass ps extends dt {\n constructor() {\n super(...arguments), this.type = ne.Inline;\n }\n /**\n * Returns title for Inline Tool if specified by user\n */\n get title() {\n return this.constructable[ct.Title];\n }\n /**\n * Constructs new InlineTool instance from constructable\n */\n create() {\n return new this.constructable({\n api: this.api,\n config: this.settings\n });\n }\n}\nclass fs extends dt {\n constructor() {\n super(...arguments), this.type = ne.Tune;\n }\n /**\n * Constructs new BlockTune instance from constructable\n *\n * @param data - Tune data\n * @param block - Block API object\n */\n create(e, t) {\n return new this.constructable({\n api: this.api,\n config: this.settings,\n block: t,\n data: e\n });\n }\n}\nclass F extends Map {\n /**\n * Returns Block Tools collection\n */\n get blockTools() {\n const e = Array.from(this.entries()).filter(([, t]) => t.isBlock());\n return new F(e);\n }\n /**\n * Returns Inline Tools collection\n */\n get inlineTools() {\n const e = Array.from(this.entries()).filter(([, t]) => t.isInline());\n return new F(e);\n }\n /**\n * Returns Block Tunes collection\n */\n get blockTunes() {\n const e = Array.from(this.entries()).filter(([, t]) => t.isTune());\n return new F(e);\n }\n /**\n * Returns internal Tools collection\n */\n get internalTools() {\n const e = Array.from(this.entries()).filter(([, t]) => t.isInternal);\n return new F(e);\n }\n /**\n * Returns Tools collection provided by user\n */\n get externalTools() {\n const e = Array.from(this.entries()).filter(([, t]) => !t.isInternal);\n return new F(e);\n }\n}\nvar gs = Object.defineProperty, ms = Object.getOwnPropertyDescriptor, ho = (n, e, t, o) => {\n for (var i = o > 1 ? void 0 : o ? ms(e, t) : e, s = n.length - 1, r; s >= 0; s--)\n (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i);\n return o && i && gs(e, t, i), i;\n};\nclass gt extends dt {\n constructor() {\n super(...arguments), this.type = ne.Block, this.inlineTools = new F(), this.tunes = new F();\n }\n /**\n * Creates new Tool instance\n *\n * @param data - Tool data\n * @param block - BlockAPI for current Block\n * @param readOnly - True if Editor is in read-only mode\n */\n create(e, t, o) {\n return new this.constructable({\n data: e,\n block: t,\n readOnly: o,\n api: this.api,\n config: this.settings\n });\n }\n /**\n * Returns true if read-only mode is supported by Tool\n */\n get isReadOnlySupported() {\n return this.constructable[ce.IsReadOnlySupported] === !0;\n }\n /**\n * Returns true if Tool supports linebreaks\n */\n get isLineBreaksEnabled() {\n return this.constructable[ce.IsEnabledLineBreaks];\n }\n /**\n * Returns Tool toolbox configuration (internal or user-specified).\n *\n * Merges internal and user-defined toolbox configs based on the following rules:\n *\n * - If both internal and user-defined toolbox configs are arrays their items are merged.\n * Length of the second one is kept.\n *\n * - If both are objects their properties are merged.\n *\n * - If one is an object and another is an array than internal config is replaced with user-defined\n * config. This is made to allow user to override default tool's toolbox representation (single/multiple entries)\n */\n get toolbox() {\n const e = this.constructable[ce.Toolbox], t = this.config[Ie.Toolbox];\n if (!V(e) && t !== !1)\n return t ? Array.isArray(e) ? Array.isArray(t) ? t.map((o, i) => {\n const s = e[i];\n return s ? {\n ...s,\n ...o\n } : o;\n }) : [t] : Array.isArray(t) ? t : [\n {\n ...e,\n ...t\n }\n ] : Array.isArray(e) ? e : [e];\n }\n /**\n * Returns Tool conversion configuration\n */\n get conversionConfig() {\n return this.constructable[ce.ConversionConfig];\n }\n /**\n * Returns enabled inline tools for Tool\n */\n get enabledInlineTools() {\n return this.config[Ie.EnabledInlineTools] || !1;\n }\n /**\n * Returns enabled tunes for Tool\n */\n get enabledBlockTunes() {\n return this.config[Ie.EnabledBlockTunes];\n }\n /**\n * Returns Tool paste configuration\n */\n get pasteConfig() {\n return this.constructable[ce.PasteConfig] ?? {};\n }\n get sanitizeConfig() {\n const e = super.sanitizeConfig, t = this.baseSanitizeConfig;\n if (V(e))\n return t;\n const o = {};\n for (const i in e)\n if (Object.prototype.hasOwnProperty.call(e, i)) {\n const s = e[i];\n R(s) ? o[i] = Object.assign({}, t, s) : o[i] = s;\n }\n return o;\n }\n get baseSanitizeConfig() {\n const e = {};\n return Array.from(this.inlineTools.values()).forEach((t) => Object.assign(e, t.sanitizeConfig)), Array.from(this.tunes.values()).forEach((t) => Object.assign(e, t.sanitizeConfig)), e;\n }\n}\nho([\n ue\n], gt.prototype, \"sanitizeConfig\", 1);\nho([\n ue\n], gt.prototype, \"baseSanitizeConfig\", 1);\nclass bs {\n /**\n * @class\n * @param config - tools config\n * @param editorConfig - EditorJS config\n * @param api - EditorJS API module\n */\n constructor(e, t, o) {\n this.api = o, this.config = e, this.editorConfig = t;\n }\n /**\n * Returns Tool object based on it's type\n *\n * @param name - tool name\n */\n get(e) {\n const { class: t, isInternal: o = !1, ...i } = this.config[e], s = this.getConstructor(t), r = t[et.IsTune];\n return new s({\n name: e,\n constructable: t,\n config: i,\n api: this.api.getMethodsForTool(e, r),\n isDefault: e === this.editorConfig.defaultBlock,\n defaultPlaceholder: this.editorConfig.placeholder,\n isInternal: o\n });\n }\n /**\n * Find appropriate Tool object constructor for Tool constructable\n *\n * @param constructable - Tools constructable\n */\n getConstructor(e) {\n switch (!0) {\n case e[ct.IsInline]:\n return ps;\n case e[et.IsTune]:\n return fs;\n default:\n return gt;\n }\n }\n}\nclass uo {\n /**\n * MoveDownTune constructor\n *\n * @param {API} api — Editor's API\n */\n constructor({ api: e }) {\n this.CSS = {\n animation: \"wobble\"\n }, this.api = e;\n }\n /**\n * Tune's appearance in block settings menu\n */\n render() {\n return {\n icon: ki,\n title: this.api.i18n.t(\"Move down\"),\n onActivate: () => this.handleClick(),\n name: \"move-down\"\n };\n }\n /**\n * Handle clicks on 'move down' button\n */\n handleClick() {\n const e = this.api.blocks.getCurrentBlockIndex(), t = this.api.blocks.getBlockByIndex(e + 1);\n if (!t)\n throw new Error(\"Unable to move Block down since it is already the last\");\n const o = t.holder, i = o.getBoundingClientRect();\n let s = Math.abs(window.innerHeight - o.offsetHeight);\n i.top < window.innerHeight && (s = window.scrollY + o.offsetHeight), window.scrollTo(0, s), this.api.blocks.move(e + 1), this.api.toolbar.toggleBlockSettings(!0);\n }\n}\nuo.isTune = !0;\nclass po {\n /**\n * DeleteTune constructor\n *\n * @param {API} api - Editor's API\n */\n constructor({ api: e }) {\n this.api = e;\n }\n /**\n * Tune's appearance in block settings menu\n */\n render() {\n return {\n icon: yi,\n title: this.api.i18n.t(\"Delete\"),\n name: \"delete\",\n confirmation: {\n title: this.api.i18n.t(\"Click to delete\"),\n onActivate: () => this.handleClick()\n }\n };\n }\n /**\n * Delete block conditions passed\n */\n handleClick() {\n this.api.blocks.delete();\n }\n}\npo.isTune = !0;\nclass fo {\n /**\n * MoveUpTune constructor\n *\n * @param {API} api - Editor's API\n */\n constructor({ api: e }) {\n this.CSS = {\n animation: \"wobble\"\n }, this.api = e;\n }\n /**\n * Tune's appearance in block settings menu\n */\n render() {\n return {\n icon: xi,\n title: this.api.i18n.t(\"Move up\"),\n onActivate: () => this.handleClick(),\n name: \"move-up\"\n };\n }\n /**\n * Move current block up\n */\n handleClick() {\n const e = this.api.blocks.getCurrentBlockIndex(), t = this.api.blocks.getBlockByIndex(e), o = this.api.blocks.getBlockByIndex(e - 1);\n if (e === 0 || !t || !o)\n throw new Error(\"Unable to move Block up since it is already the first\");\n const i = t.holder, s = o.holder, r = i.getBoundingClientRect(), l = s.getBoundingClientRect();\n let a;\n l.top > 0 ? a = Math.abs(r.top) - Math.abs(l.top) : a = Math.abs(r.top) + l.height, window.scrollBy(0, -1 * a), this.api.blocks.move(e - 1), this.api.toolbar.toggleBlockSettings(!0);\n }\n}\nfo.isTune = !0;\nvar ks = Object.defineProperty, vs = Object.getOwnPropertyDescriptor, ws = (n, e, t, o) => {\n for (var i = o > 1 ? void 0 : o ? vs(e, t) : e, s = n.length - 1, r; s >= 0; s--)\n (r = n[s]) && (i = (o ? r(e, t, i) : r(i)) || i);\n return o && i && ks(e, t, i), i;\n};\nclass go extends y {\n constructor() {\n super(...arguments), this.stubTool = \"stub\", this.toolsAvailable = new F(), this.toolsUnavailable = new F();\n }\n /**\n * Returns available Tools\n */\n get available() {\n return this.toolsAvailable;\n }\n /**\n * Returns unavailable Tools\n */\n get unavailable() {\n return this.toolsUnavailable;\n }\n /**\n * Return Tools for the Inline Toolbar\n */\n get inlineTools() {\n return this.available.inlineTools;\n }\n /**\n * Return editor block tools\n */\n get blockTools() {\n return this.available.blockTools;\n }\n /**\n * Return available Block Tunes\n *\n * @returns {object} - object of Inline Tool's classes\n */\n get blockTunes() {\n return this.available.blockTunes;\n }\n /**\n * Returns default Tool object\n */\n get defaultTool() {\n return this.blockTools.get(this.config.defaultBlock);\n }\n /**\n * Returns internal tools\n */\n get internal() {\n return this.available.internalTools;\n }\n /**\n * Creates instances via passed or default configuration\n *\n * @returns {Promise}\n */\n async prepare() {\n if (this.validateTools(), this.config.tools = qe({}, this.internalTools, this.config.tools), !Object.prototype.hasOwnProperty.call(this.config, \"tools\") || Object.keys(this.config.tools).length === 0)\n throw Error(\"Can't start without tools\");\n const e = this.prepareConfig();\n this.factory = new bs(e, this.config, this.Editor.API);\n const t = this.getListOfPrepareFunctions(e);\n if (t.length === 0)\n return Promise.resolve();\n await Eo(t, (o) => {\n this.toolPrepareMethodSuccess(o);\n }, (o) => {\n this.toolPrepareMethodFallback(o);\n }), this.prepareBlockTools();\n }\n getAllInlineToolsSanitizeConfig() {\n const e = {};\n return Array.from(this.inlineTools.values()).forEach((t) => {\n Object.assign(e, t.sanitizeConfig);\n }), e;\n }\n /**\n * Calls each Tool reset method to clean up anything set by Tool\n */\n destroy() {\n Object.values(this.available).forEach(async (e) => {\n O(e.reset) && await e.reset();\n });\n }\n /**\n * Returns internal tools\n * Includes Bold, Italic, Link and Paragraph\n */\n get internalTools() {\n return {\n convertTo: {\n class: ao,\n isInternal: !0\n },\n link: {\n class: ft,\n isInternal: !0\n },\n bold: {\n class: ut,\n isInternal: !0\n },\n italic: {\n class: pt,\n isInternal: !0\n },\n paragraph: {\n class: ht,\n inlineToolbar: !0,\n isInternal: !0\n },\n stub: {\n class: co,\n isInternal: !0\n },\n moveUp: {\n class: fo,\n isInternal: !0\n },\n delete: {\n class: po,\n isInternal: !0\n },\n moveDown: {\n class: uo,\n isInternal: !0\n }\n };\n }\n /**\n * Tool prepare method success callback\n *\n * @param {object} data - append tool to available list\n */\n toolPrepareMethodSuccess(e) {\n const t = this.factory.get(e.toolName);\n if (t.isInline()) {\n const i = [\"render\"].filter((s) => !t.create()[s]);\n if (i.length) {\n I(\n `Incorrect Inline Tool: ${t.name}. Some of required methods is not implemented %o`,\n \"warn\",\n i\n ), this.toolsUnavailable.set(t.name, t);\n return;\n }\n }\n this.toolsAvailable.set(t.name, t);\n }\n /**\n * Tool prepare method fail callback\n *\n * @param {object} data - append tool to unavailable list\n */\n toolPrepareMethodFallback(e) {\n this.toolsUnavailable.set(e.toolName, this.factory.get(e.toolName));\n }\n /**\n * Binds prepare function of plugins with user or default config\n *\n * @returns {Array} list of functions that needs to be fired sequentially\n * @param config - tools config\n */\n getListOfPrepareFunctions(e) {\n const t = [];\n return Object.entries(e).forEach(([o, i]) => {\n t.push({\n // eslint-disable-next-line @typescript-eslint/no-empty-function\n function: O(i.class.prepare) ? i.class.prepare : () => {\n },\n data: {\n toolName: o,\n config: i.config\n }\n });\n }), t;\n }\n /**\n * Assign enabled Inline Tools and Block Tunes for Block Tool\n */\n prepareBlockTools() {\n Array.from(this.blockTools.values()).forEach((e) => {\n this.assignInlineToolsToBlockTool(e), this.assignBlockTunesToBlockTool(e);\n });\n }\n /**\n * Assign enabled Inline Tools for Block Tool\n *\n * @param tool - Block Tool\n */\n assignInlineToolsToBlockTool(e) {\n if (this.config.inlineToolbar !== !1) {\n if (e.enabledInlineTools === !0) {\n e.inlineTools = new F(\n Array.isArray(this.config.inlineToolbar) ? this.config.inlineToolbar.map((t) => [t, this.inlineTools.get(t)]) : Array.from(this.inlineTools.entries())\n );\n return;\n }\n Array.isArray(e.enabledInlineTools) && (e.inlineTools = new F(\n /** Prepend ConvertTo Inline Tool */\n [\"convertTo\", ...e.enabledInlineTools].map((t) => [t, this.inlineTools.get(t)])\n ));\n }\n }\n /**\n * Assign enabled Block Tunes for Block Tool\n *\n * @param tool — Block Tool\n */\n assignBlockTunesToBlockTool(e) {\n if (e.enabledBlockTunes !== !1) {\n if (Array.isArray(e.enabledBlockTunes)) {\n const t = new F(\n e.enabledBlockTunes.map((o) => [o, this.blockTunes.get(o)])\n );\n e.tunes = new F([...t, ...this.blockTunes.internalTools]);\n return;\n }\n if (Array.isArray(this.config.tunes)) {\n const t = new F(\n this.config.tunes.map((o) => [o, this.blockTunes.get(o)])\n );\n e.tunes = new F([...t, ...this.blockTunes.internalTools]);\n return;\n }\n e.tunes = this.blockTunes.internalTools;\n }\n }\n /**\n * Validate Tools configuration objects and throw Error for user if it is invalid\n */\n validateTools() {\n for (const e in this.config.tools)\n if (Object.prototype.hasOwnProperty.call(this.config.tools, e)) {\n if (e in this.internalTools)\n return;\n const t = this.config.tools[e];\n if (!O(t) && !O(t.class))\n throw Error(\n `Tool «${e}» must be a constructor function or an object with function in the «class» property`\n );\n }\n }\n /**\n * Unify tools config\n */\n prepareConfig() {\n const e = {};\n for (const t in this.config.tools)\n R(this.config.tools[t]) ? e[t] = this.config.tools[t] : e[t] = { class: this.config.tools[t] };\n return e;\n }\n}\nws([\n ue\n], go.prototype, \"getAllInlineToolsSanitizeConfig\", 1);\nconst xs = `:root{--selectionColor: #e1f2ff;--inlineSelectionColor: #d4ecff;--bg-light: #eff2f5;--grayText: #707684;--color-dark: #1D202B;--color-active-icon: #388AE5;--color-gray-border: rgba(201, 201, 204, .48);--content-width: 650px;--narrow-mode-right-padding: 50px;--toolbox-buttons-size: 26px;--toolbox-buttons-size--mobile: 36px;--icon-size: 20px;--icon-size--mobile: 28px;--block-padding-vertical: .4em;--color-line-gray: #EFF0F1 }.codex-editor{position:relative;-webkit-box-sizing:border-box;box-sizing:border-box;z-index:1}.codex-editor .hide{display:none}.codex-editor__redactor [contenteditable]:empty:after{content:\"\\\\feff\"}@media (min-width: 651px){.codex-editor--narrow .codex-editor__redactor{margin-right:50px}}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .codex-editor__redactor{margin-left:50px;margin-right:0}}@media (min-width: 651px){.codex-editor--narrow .ce-toolbar__actions{right:-5px}}.codex-editor-copyable{position:absolute;height:1px;width:1px;top:-400%;opacity:.001}.codex-editor-overlay{position:fixed;top:0;left:0;right:0;bottom:0;z-index:999;pointer-events:none;overflow:hidden}.codex-editor-overlay__container{position:relative;pointer-events:auto;z-index:0}.codex-editor-overlay__rectangle{position:absolute;pointer-events:none;background-color:#2eaadc33;border:1px solid transparent}.codex-editor svg{max-height:100%}.codex-editor path{stroke:currentColor}.codex-editor ::-moz-selection{background-color:#d4ecff}.codex-editor ::selection{background-color:#d4ecff}.codex-editor--toolbox-opened [contentEditable=true][data-placeholder]:focus:before{opacity:0!important}.ce-scroll-locked{overflow:hidden}.ce-scroll-locked--hard{overflow:hidden;top:calc(-1 * var(--window-scroll-offset));position:fixed;width:100%}.ce-toolbar{position:absolute;left:0;right:0;top:0;-webkit-transition:opacity .1s ease;transition:opacity .1s ease;will-change:opacity,top;display:none}.ce-toolbar--opened{display:block}.ce-toolbar__content{max-width:650px;margin:0 auto;position:relative}.ce-toolbar__plus{color:#1d202b;cursor:pointer;width:26px;height:26px;border-radius:7px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-flex-negative:0;flex-shrink:0}@media (max-width: 650px){.ce-toolbar__plus{width:36px;height:36px}}@media (hover: hover){.ce-toolbar__plus:hover{background-color:#eff2f5}}.ce-toolbar__plus--active{background-color:#eff2f5;-webkit-animation:bounceIn .75s 1;animation:bounceIn .75s 1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}.ce-toolbar__plus-shortcut{opacity:.6;word-spacing:-2px;margin-top:5px}@media (max-width: 650px){.ce-toolbar__plus{position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;position:static}.ce-toolbar__plus--left-oriented:before{left:15px;margin-left:0}.ce-toolbar__plus--right-oriented:before{left:auto;right:15px;margin-left:0}}.ce-toolbar__actions{position:absolute;right:100%;opacity:0;display:-webkit-box;display:-ms-flexbox;display:flex;padding-right:5px}.ce-toolbar__actions--opened{opacity:1}@media (max-width: 650px){.ce-toolbar__actions{right:auto}}.ce-toolbar__settings-btn{color:#1d202b;width:26px;height:26px;border-radius:7px;display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;margin-left:3px;cursor:pointer;user-select:none}@media (max-width: 650px){.ce-toolbar__settings-btn{width:36px;height:36px}}@media (hover: hover){.ce-toolbar__settings-btn:hover{background-color:#eff2f5}}.ce-toolbar__settings-btn--active{background-color:#eff2f5;-webkit-animation:bounceIn .75s 1;animation:bounceIn .75s 1;-webkit-animation-fill-mode:forwards;animation-fill-mode:forwards}@media (min-width: 651px){.ce-toolbar__settings-btn{width:24px}}.ce-toolbar__settings-btn--hidden{display:none}@media (max-width: 650px){.ce-toolbar__settings-btn{position:absolute;background-color:#fff;border:1px solid #E8E8EB;-webkit-box-shadow:0 3px 15px -3px rgba(13,20,33,.13);box-shadow:0 3px 15px -3px #0d142121;border-radius:6px;z-index:2;position:static}.ce-toolbar__settings-btn--left-oriented:before{left:15px;margin-left:0}.ce-toolbar__settings-btn--right-oriented:before{left:auto;right:15px;margin-left:0}}.ce-toolbar__plus svg,.ce-toolbar__settings-btn svg{width:24px;height:24px}@media (min-width: 651px){.codex-editor--narrow .ce-toolbar__plus{left:5px}}@media (min-width: 651px){.codex-editor--narrow .ce-toolbox .ce-popover{right:0;left:auto;left:initial}}.ce-inline-toolbar{--y-offset: 8px;--color-background-icon-active: rgba(56, 138, 229, .1);--color-text-icon-active: #388AE5;--color-text-primary: black;position:absolute;visibility:hidden;-webkit-transition:opacity .25s ease;transition:opacity .25s ease;will-change:opacity,left,top;top:0;left:0;z-index:3;opacity:1;visibility:visible}.ce-inline-toolbar [hidden]{display:none!important}.ce-inline-toolbar__toggler-and-button-wrapper{display:-webkit-box;display:-ms-flexbox;display:flex;width:100%;padding:0 6px}.ce-inline-toolbar__buttons{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-inline-toolbar__dropdown{display:-webkit-box;display:-ms-flexbox;display:flex;padding:6px;margin:0 6px 0 -6px;-webkit-box-align:center;-ms-flex-align:center;align-items:center;cursor:pointer;border-right:1px solid rgba(201,201,204,.48);-webkit-box-sizing:border-box;box-sizing:border-box}@media (hover: hover){.ce-inline-toolbar__dropdown:hover{background:#eff2f5}}.ce-inline-toolbar__dropdown--hidden{display:none}.ce-inline-toolbar__dropdown-content,.ce-inline-toolbar__dropdown-arrow{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-inline-toolbar__dropdown-content svg,.ce-inline-toolbar__dropdown-arrow svg{width:20px;height:20px}.ce-inline-toolbar__shortcut{opacity:.6;word-spacing:-3px;margin-top:3px}.ce-inline-tool{color:var(--color-text-primary);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;border:0;border-radius:4px;line-height:normal;height:100%;padding:0;width:28px;background-color:transparent;cursor:pointer}@media (max-width: 650px){.ce-inline-tool{width:36px;height:36px}}@media (hover: hover){.ce-inline-tool:hover{background-color:#f8f8f8}}.ce-inline-tool svg{display:block;width:20px;height:20px}@media (max-width: 650px){.ce-inline-tool svg{width:28px;height:28px}}.ce-inline-tool--link .icon--unlink,.ce-inline-tool--unlink .icon--link{display:none}.ce-inline-tool--unlink .icon--unlink{display:inline-block;margin-bottom:-1px}.ce-inline-tool-input{background:#F8F8F8;border:1px solid rgba(226,226,229,.2);border-radius:6px;padding:4px 8px;font-size:14px;line-height:22px;outline:none;margin:0;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box;display:none;font-weight:500;-webkit-appearance:none;font-family:inherit}@media (max-width: 650px){.ce-inline-tool-input{font-size:15px;font-weight:500}}.ce-inline-tool-input::-webkit-input-placeholder{color:#707684}.ce-inline-tool-input::-moz-placeholder{color:#707684}.ce-inline-tool-input:-ms-input-placeholder{color:#707684}.ce-inline-tool-input::-ms-input-placeholder{color:#707684}.ce-inline-tool-input::placeholder{color:#707684}.ce-inline-tool-input--showed{display:block}.ce-inline-tool--active{background:var(--color-background-icon-active);color:var(--color-text-icon-active)}@-webkit-keyframes fade-in{0%{opacity:0}to{opacity:1}}@keyframes fade-in{0%{opacity:0}to{opacity:1}}.ce-block{-webkit-animation:fade-in .3s ease;animation:fade-in .3s ease;-webkit-animation-fill-mode:none;animation-fill-mode:none;-webkit-animation-fill-mode:initial;animation-fill-mode:initial}.ce-block:first-of-type{margin-top:0}.ce-block--selected .ce-block__content{background:#e1f2ff}.ce-block--selected .ce-block__content [contenteditable]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.ce-block--selected .ce-block__content img,.ce-block--selected .ce-block__content .ce-stub{opacity:.55}.ce-block--stretched .ce-block__content{max-width:none}.ce-block__content{position:relative;max-width:650px;margin:0 auto;-webkit-transition:background-color .15s ease;transition:background-color .15s ease}.ce-block--drop-target .ce-block__content:before{content:\"\";position:absolute;top:100%;left:-20px;margin-top:-1px;height:8px;width:8px;border:solid #388AE5;border-width:1px 1px 0 0;-webkit-transform-origin:right;transform-origin:right;-webkit-transform:rotate(45deg);transform:rotate(45deg)}.ce-block--drop-target .ce-block__content:after{content:\"\";position:absolute;top:100%;height:1px;width:100%;color:#388ae5;background:repeating-linear-gradient(90deg,#388AE5,#388AE5 1px,#fff 1px,#fff 6px)}.ce-block a{cursor:pointer;-webkit-text-decoration:underline;text-decoration:underline}.ce-block b{font-weight:700}.ce-block i{font-style:italic}@-webkit-keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}20%{-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}60%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes bounceIn{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.9,.9,.9);transform:scale3d(.9,.9,.9)}20%{-webkit-transform:scale3d(1.03,1.03,1.03);transform:scale3d(1.03,1.03,1.03)}60%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@-webkit-keyframes selectionBounce{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}50%{-webkit-transform:scale3d(1.01,1.01,1.01);transform:scale3d(1.01,1.01,1.01)}70%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes selectionBounce{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}50%{-webkit-transform:scale3d(1.01,1.01,1.01);transform:scale3d(1.01,1.01,1.01)}70%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@-webkit-keyframes buttonClicked{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.95,.95,.95);transform:scale3d(.95,.95,.95)}60%{-webkit-transform:scale3d(1.02,1.02,1.02);transform:scale3d(1.02,1.02,1.02)}80%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}@keyframes buttonClicked{0%,20%,40%,60%,80%,to{-webkit-animation-timing-function:cubic-bezier(.215,.61,.355,1);animation-timing-function:cubic-bezier(.215,.61,.355,1)}0%{-webkit-transform:scale3d(.95,.95,.95);transform:scale3d(.95,.95,.95)}60%{-webkit-transform:scale3d(1.02,1.02,1.02);transform:scale3d(1.02,1.02,1.02)}80%{-webkit-transform:scale3d(1,1,1);transform:scaleZ(1)}}.cdx-block{padding:.4em 0}.cdx-block::-webkit-input-placeholder{line-height:normal!important}.cdx-input{border:1px solid rgba(201,201,204,.48);-webkit-box-shadow:inset 0 1px 2px 0 rgba(35,44,72,.06);box-shadow:inset 0 1px 2px #232c480f;border-radius:3px;padding:10px 12px;outline:none;width:100%;-webkit-box-sizing:border-box;box-sizing:border-box}.cdx-input[data-placeholder]:before{position:static!important}.cdx-input[data-placeholder]:before{display:inline-block;width:0;white-space:nowrap;pointer-events:none}.cdx-settings-button{display:-webkit-inline-box;display:-ms-inline-flexbox;display:inline-flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;border-radius:3px;cursor:pointer;border:0;outline:none;background-color:transparent;vertical-align:bottom;color:inherit;margin:0;min-width:26px;min-height:26px}.cdx-settings-button--focused{background:rgba(34,186,255,.08)!important}.cdx-settings-button--focused{-webkit-box-shadow:inset 0 0 0px 1px rgba(7,161,227,.08);box-shadow:inset 0 0 0 1px #07a1e314}.cdx-settings-button--focused-animated{-webkit-animation-name:buttonClicked;animation-name:buttonClicked;-webkit-animation-duration:.25s;animation-duration:.25s}.cdx-settings-button--active{color:#388ae5}.cdx-settings-button svg{width:auto;height:auto}@media (max-width: 650px){.cdx-settings-button svg{width:28px;height:28px}}@media (max-width: 650px){.cdx-settings-button{width:36px;height:36px;border-radius:8px}}@media (hover: hover){.cdx-settings-button:hover{background-color:#eff2f5}}.cdx-loader{position:relative;border:1px solid rgba(201,201,204,.48)}.cdx-loader:before{content:\"\";position:absolute;left:50%;top:50%;width:18px;height:18px;margin:-11px 0 0 -11px;border:2px solid rgba(201,201,204,.48);border-left-color:#388ae5;border-radius:50%;-webkit-animation:cdxRotation 1.2s infinite linear;animation:cdxRotation 1.2s infinite linear}@-webkit-keyframes cdxRotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes cdxRotation{0%{-webkit-transform:rotate(0deg);transform:rotate(0)}to{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.cdx-button{padding:13px;border-radius:3px;border:1px solid rgba(201,201,204,.48);font-size:14.9px;background:#fff;-webkit-box-shadow:0 2px 2px 0 rgba(18,30,57,.04);box-shadow:0 2px 2px #121e390a;color:#707684;text-align:center;cursor:pointer}@media (hover: hover){.cdx-button:hover{background:#FBFCFE;-webkit-box-shadow:0 1px 3px 0 rgba(18,30,57,.08);box-shadow:0 1px 3px #121e3914}}.cdx-button svg{height:20px;margin-right:.2em;margin-top:-2px}.ce-stub{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:12px 18px;margin:10px 0;border-radius:10px;background:#eff2f5;border:1px solid #EFF0F1;color:#707684;font-size:14px}.ce-stub svg{width:20px;height:20px}.ce-stub__info{margin-left:14px}.ce-stub__title{font-weight:500;text-transform:capitalize}.codex-editor.codex-editor--rtl{direction:rtl}.codex-editor.codex-editor--rtl .cdx-list{padding-left:0;padding-right:40px}.codex-editor.codex-editor--rtl .ce-toolbar__plus{right:-26px;left:auto}.codex-editor.codex-editor--rtl .ce-toolbar__actions{right:auto;left:-26px}@media (max-width: 650px){.codex-editor.codex-editor--rtl .ce-toolbar__actions{margin-left:0;margin-right:auto;padding-right:0;padding-left:10px}}.codex-editor.codex-editor--rtl .ce-settings{left:5px;right:auto}.codex-editor.codex-editor--rtl .ce-settings:before{right:auto;left:25px}.codex-editor.codex-editor--rtl .ce-settings__button:not(:nth-child(3n+3)){margin-left:3px;margin-right:0}.codex-editor.codex-editor--rtl .ce-conversion-tool__icon{margin-right:0;margin-left:10px}.codex-editor.codex-editor--rtl .ce-inline-toolbar__dropdown{border-right:0px solid transparent;border-left:1px solid rgba(201,201,204,.48);margin:0 -6px 0 6px}.codex-editor.codex-editor--rtl .ce-inline-toolbar__dropdown .icon--toggler-down{margin-left:0;margin-right:4px}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .ce-toolbar__plus{left:0;right:5px}}@media (min-width: 651px){.codex-editor--narrow.codex-editor--rtl .ce-toolbar__actions{left:-5px}}.cdx-search-field{--icon-margin-right: 10px;background:#F8F8F8;border:1px solid rgba(226,226,229,.2);border-radius:6px;padding:2px;display:grid;grid-template-columns:auto auto 1fr;grid-template-rows:auto}.cdx-search-field__icon{width:26px;height:26px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center;margin-right:var(--icon-margin-right)}.cdx-search-field__icon svg{width:20px;height:20px;color:#707684}.cdx-search-field__input{font-size:14px;outline:none;font-weight:500;font-family:inherit;border:0;background:transparent;margin:0;padding:0;line-height:22px;min-width:calc(100% - 26px - var(--icon-margin-right))}.cdx-search-field__input::-webkit-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::-moz-placeholder{color:#707684;font-weight:500}.cdx-search-field__input:-ms-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::-ms-input-placeholder{color:#707684;font-weight:500}.cdx-search-field__input::placeholder{color:#707684;font-weight:500}.ce-popover{--border-radius: 6px;--width: 200px;--max-height: 270px;--padding: 6px;--offset-from-target: 8px;--color-border: #EFF0F1;--color-shadow: rgba(13, 20, 33, .1);--color-background: white;--color-text-primary: black;--color-text-secondary: #707684;--color-border-icon: rgba(201, 201, 204, .48);--color-border-icon-disabled: #EFF0F1;--color-text-icon-active: #388AE5;--color-background-icon-active: rgba(56, 138, 229, .1);--color-background-item-focus: rgba(34, 186, 255, .08);--color-shadow-item-focus: rgba(7, 161, 227, .08);--color-background-item-hover: #F8F8F8;--color-background-item-confirm: #E24A4A;--color-background-item-confirm-hover: #CE4343;--popover-top: calc(100% + var(--offset-from-target));--popover-left: 0;--nested-popover-overlap: 4px;--icon-size: 20px;--item-padding: 3px;--item-height: calc(var(--icon-size) + 2 * var(--item-padding))}.ce-popover__container{min-width:var(--width);width:var(--width);max-height:var(--max-height);border-radius:var(--border-radius);overflow:hidden;-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-box-shadow:0px 3px 15px -3px var(--color-shadow);box-shadow:0 3px 15px -3px var(--color-shadow);position:absolute;left:var(--popover-left);top:var(--popover-top);background:var(--color-background);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;z-index:4;opacity:0;max-height:0;pointer-events:none;padding:0;border:none}.ce-popover--opened>.ce-popover__container{opacity:1;padding:var(--padding);max-height:var(--max-height);pointer-events:auto;-webkit-animation:panelShowing .1s ease;animation:panelShowing .1s ease;border:1px solid var(--color-border)}@media (max-width: 650px){.ce-popover--opened>.ce-popover__container{-webkit-animation:panelShowingMobile .25s ease;animation:panelShowingMobile .25s ease}}.ce-popover--open-top .ce-popover__container{--popover-top: calc(-1 * (var(--offset-from-target) + var(--popover-height)))}.ce-popover--open-left .ce-popover__container{--popover-left: calc(-1 * var(--width) + 100%)}.ce-popover__items{overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:contain}@media (max-width: 650px){.ce-popover__overlay{position:fixed;top:0;bottom:0;left:0;right:0;background:#1D202B;z-index:3;opacity:.5;-webkit-transition:opacity .12s ease-in;transition:opacity .12s ease-in;will-change:opacity;visibility:visible}}.ce-popover__overlay--hidden{display:none}@media (max-width: 650px){.ce-popover .ce-popover__container{--offset: 5px;position:fixed;max-width:none;min-width:calc(100% - var(--offset) * 2);left:var(--offset);right:var(--offset);bottom:calc(var(--offset) + env(safe-area-inset-bottom));top:auto;border-radius:10px}}.ce-popover__search{margin-bottom:5px}.ce-popover__nothing-found-message{color:#707684;display:none;cursor:default;padding:3px;font-size:14px;line-height:20px;font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ce-popover__nothing-found-message--displayed{display:block}.ce-popover--nested .ce-popover__container{--popover-left: calc(var(--nesting-level) * (var(--width) - var(--nested-popover-overlap)));top:calc(var(--trigger-item-top) - var(--nested-popover-overlap));position:absolute}.ce-popover--open-top.ce-popover--nested .ce-popover__container{top:calc(var(--trigger-item-top) - var(--popover-height) + var(--item-height) + var(--offset-from-target) + var(--nested-popover-overlap))}.ce-popover--open-left .ce-popover--nested .ce-popover__container{--popover-left: calc(-1 * (var(--nesting-level) + 1) * var(--width) + 100%)}.ce-popover-item-separator{padding:4px 3px}.ce-popover-item-separator--hidden{display:none}.ce-popover-item-separator__line{height:1px;background:var(--color-border);width:100%}.ce-popover-item-html--hidden{display:none}.ce-popover-item{--border-radius: 6px;border-radius:var(--border-radius);display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;padding:var(--item-padding);color:var(--color-text-primary);-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;background:transparent}@media (max-width: 650px){.ce-popover-item{padding:4px}}.ce-popover-item:not(:last-of-type){margin-bottom:1px}.ce-popover-item__icon{width:26px;height:26px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center;-webkit-box-pack:center;-ms-flex-pack:center;justify-content:center}.ce-popover-item__icon svg{width:20px;height:20px}@media (max-width: 650px){.ce-popover-item__icon{width:36px;height:36px;border-radius:8px}.ce-popover-item__icon svg{width:28px;height:28px}}.ce-popover-item__icon--tool{margin-right:4px}.ce-popover-item__title{font-size:14px;line-height:20px;font-weight:500;overflow:hidden;white-space:nowrap;text-overflow:ellipsis;margin-right:auto}@media (max-width: 650px){.ce-popover-item__title{font-size:16px}}.ce-popover-item__secondary-title{color:var(--color-text-secondary);font-size:12px;white-space:nowrap;letter-spacing:-.1em;padding-right:5px;opacity:.6}@media (max-width: 650px){.ce-popover-item__secondary-title{display:none}}.ce-popover-item--active{background:var(--color-background-icon-active);color:var(--color-text-icon-active)}.ce-popover-item--disabled{color:var(--color-text-secondary);cursor:default;pointer-events:none}.ce-popover-item--focused:not(.ce-popover-item--no-focus){background:var(--color-background-item-focus)!important}.ce-popover-item--hidden{display:none}@media (hover: hover){.ce-popover-item:hover{cursor:pointer}.ce-popover-item:hover:not(.ce-popover-item--no-hover){background-color:var(--color-background-item-hover)}}.ce-popover-item--confirmation{background:var(--color-background-item-confirm)}.ce-popover-item--confirmation .ce-popover-item__title,.ce-popover-item--confirmation .ce-popover-item__icon{color:#fff}@media (hover: hover){.ce-popover-item--confirmation:not(.ce-popover-item--no-hover):hover{background:var(--color-background-item-confirm-hover)}}.ce-popover-item--confirmation:not(.ce-popover-item--no-focus).ce-popover-item--focused{background:var(--color-background-item-confirm-hover)!important}@-webkit-keyframes panelShowing{0%{opacity:0;-webkit-transform:translateY(-8px) scale(.9);transform:translateY(-8px) scale(.9)}70%{opacity:1;-webkit-transform:translateY(2px);transform:translateY(2px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes panelShowing{0%{opacity:0;-webkit-transform:translateY(-8px) scale(.9);transform:translateY(-8px) scale(.9)}70%{opacity:1;-webkit-transform:translateY(2px);transform:translateY(2px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@-webkit-keyframes panelShowingMobile{0%{opacity:0;-webkit-transform:translateY(14px) scale(.98);transform:translateY(14px) scale(.98)}70%{opacity:1;-webkit-transform:translateY(-4px);transform:translateY(-4px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}@keyframes panelShowingMobile{0%{opacity:0;-webkit-transform:translateY(14px) scale(.98);transform:translateY(14px) scale(.98)}70%{opacity:1;-webkit-transform:translateY(-4px);transform:translateY(-4px)}to{-webkit-transform:translateY(0);transform:translateY(0)}}.wobble{-webkit-animation-name:wobble;animation-name:wobble;-webkit-animation-duration:.4s;animation-duration:.4s}@-webkit-keyframes wobble{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-9%,0,0);transform:translate3d(-9%,0,0)}30%{-webkit-transform:translate3d(9%,0,0);transform:translate3d(9%,0,0)}45%{-webkit-transform:translate3d(-4%,0,0);transform:translate3d(-4%,0,0)}60%{-webkit-transform:translate3d(4%,0,0);transform:translate3d(4%,0,0)}75%{-webkit-transform:translate3d(-1%,0,0);transform:translate3d(-1%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}@keyframes wobble{0%{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}15%{-webkit-transform:translate3d(-9%,0,0);transform:translate3d(-9%,0,0)}30%{-webkit-transform:translate3d(9%,0,0);transform:translate3d(9%,0,0)}45%{-webkit-transform:translate3d(-4%,0,0);transform:translate3d(-4%,0,0)}60%{-webkit-transform:translate3d(4%,0,0);transform:translate3d(4%,0,0)}75%{-webkit-transform:translate3d(-1%,0,0);transform:translate3d(-1%,0,0)}to{-webkit-transform:translate3d(0,0,0);transform:translateZ(0)}}.ce-popover-header{margin-bottom:8px;margin-top:4px;display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ce-popover-header__text{font-size:18px;font-weight:600}.ce-popover-header__back-button{border:0;background:transparent;width:36px;height:36px;color:var(--color-text-primary)}.ce-popover-header__back-button svg{display:block;width:28px;height:28px}.ce-popover--inline{--height: 38px;--height-mobile: 46px;--container-padding: 4px;position:relative}.ce-popover--inline .ce-popover__custom-content{margin-bottom:0}.ce-popover--inline .ce-popover__items{display:-webkit-box;display:-ms-flexbox;display:flex}.ce-popover--inline .ce-popover__container{-webkit-box-orient:horizontal;-webkit-box-direction:normal;-ms-flex-direction:row;flex-direction:row;padding:var(--container-padding);height:var(--height);top:0;min-width:-webkit-max-content;min-width:-moz-max-content;min-width:max-content;width:-webkit-max-content;width:-moz-max-content;width:max-content;-webkit-animation:none;animation:none}@media (max-width: 650px){.ce-popover--inline .ce-popover__container{height:var(--height-mobile);position:absolute}}.ce-popover--inline .ce-popover-item-separator{padding:0 4px}.ce-popover--inline .ce-popover-item-separator__line{height:100%;width:1px}.ce-popover--inline .ce-popover-item{border-radius:4px;padding:4px}.ce-popover--inline .ce-popover-item__icon--tool{-webkit-box-shadow:none;box-shadow:none;background:transparent;margin-right:0}.ce-popover--inline .ce-popover-item__icon{width:auto;width:initial;height:auto;height:initial}.ce-popover--inline .ce-popover-item__icon svg{width:20px;height:20px}@media (max-width: 650px){.ce-popover--inline .ce-popover-item__icon svg{width:28px;height:28px}}.ce-popover--inline .ce-popover-item:not(:last-of-type){margin-bottom:0;margin-bottom:initial}.ce-popover--inline .ce-popover-item-html{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-align:center;-ms-flex-align:center;align-items:center}.ce-popover--inline .ce-popover-item__icon--chevron-right{-webkit-transform:rotate(90deg);transform:rotate(90deg)}.ce-popover--inline .ce-popover--nested-level-1 .ce-popover__container{--offset: 3px;left:0;top:calc(var(--height) + var(--offset))}@media (max-width: 650px){.ce-popover--inline .ce-popover--nested-level-1 .ce-popover__container{top:calc(var(--height-mobile) + var(--offset))}}.ce-popover--inline .ce-popover--nested .ce-popover__container{min-width:var(--width);width:var(--width);height:-webkit-fit-content;height:-moz-fit-content;height:fit-content;padding:6px;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column}.ce-popover--inline .ce-popover--nested .ce-popover__items{display:block;width:100%}.ce-popover--inline .ce-popover--nested .ce-popover-item{border-radius:6px;padding:3px}@media (max-width: 650px){.ce-popover--inline .ce-popover--nested .ce-popover-item{padding:4px}}.ce-popover--inline .ce-popover--nested .ce-popover-item__icon--tool{margin-right:4px}.ce-popover--inline .ce-popover--nested .ce-popover-item__icon{width:26px;height:26px}.ce-popover--inline .ce-popover--nested .ce-popover-item-separator{padding:4px 3px}.ce-popover--inline .ce-popover--nested .ce-popover-item-separator__line{width:100%;height:1px}.codex-editor [data-placeholder]:empty:before,.codex-editor [data-placeholder][data-empty=true]:before{pointer-events:none;color:#707684;cursor:text;content:attr(data-placeholder)}.codex-editor [data-placeholder-active]:empty:before,.codex-editor [data-placeholder-active][data-empty=true]:before{pointer-events:none;color:#707684;cursor:text}.codex-editor [data-placeholder-active]:empty:focus:before,.codex-editor [data-placeholder-active][data-empty=true]:focus:before{content:attr(data-placeholder-active)}\n`;\nclass ys extends y {\n constructor() {\n super(...arguments), this.isMobile = !1, this.contentRectCache = void 0, this.resizeDebouncer = vt(() => {\n this.windowResize();\n }, 200);\n }\n /**\n * Editor.js UI CSS class names\n *\n * @returns {{editorWrapper: string, editorZone: string}}\n */\n get CSS() {\n return {\n editorWrapper: \"codex-editor\",\n editorWrapperNarrow: \"codex-editor--narrow\",\n editorZone: \"codex-editor__redactor\",\n editorZoneHidden: \"codex-editor__redactor--hidden\",\n editorEmpty: \"codex-editor--empty\",\n editorRtlFix: \"codex-editor--rtl\"\n };\n }\n /**\n * Return Width of center column of Editor\n *\n * @returns {DOMRect}\n */\n get contentRect() {\n if (this.contentRectCache)\n return this.contentRectCache;\n const e = this.nodes.wrapper.querySelector(`.${D.CSS.content}`);\n return e ? (this.contentRectCache = e.getBoundingClientRect(), this.contentRectCache) : {\n width: 650,\n left: 0,\n right: 0\n };\n }\n /**\n * Making main interface\n */\n async prepare() {\n this.setIsMobile(), this.make(), this.loadStyles();\n }\n /**\n * Toggle read-only state\n *\n * If readOnly is true:\n * - removes all listeners from main UI module elements\n *\n * if readOnly is false:\n * - enables all listeners to UI module elements\n *\n * @param {boolean} readOnlyEnabled - \"read only\" state\n */\n toggleReadOnly(e) {\n e ? this.disableModuleBindings() : window.requestIdleCallback(() => {\n this.enableModuleBindings();\n }, {\n timeout: 2e3\n });\n }\n /**\n * Check if Editor is empty and set CSS class to wrapper\n */\n checkEmptiness() {\n const { BlockManager: e } = this.Editor;\n this.nodes.wrapper.classList.toggle(this.CSS.editorEmpty, e.isEditorEmpty);\n }\n /**\n * Check if one of Toolbar is opened\n * Used to prevent global keydowns (for example, Enter) conflicts with Enter-on-toolbar\n *\n * @returns {boolean}\n */\n get someToolbarOpened() {\n const { Toolbar: e, BlockSettings: t, InlineToolbar: o } = this.Editor;\n return !!(t.opened || o.opened || e.toolbox.opened);\n }\n /**\n * Check for some Flipper-buttons is under focus\n */\n get someFlipperButtonFocused() {\n return this.Editor.Toolbar.toolbox.hasFocus() ? !0 : Object.entries(this.Editor).filter(([e, t]) => t.flipper instanceof le).some(([e, t]) => t.flipper.hasFocus());\n }\n /**\n * Clean editor`s UI\n */\n destroy() {\n this.nodes.holder.innerHTML = \"\";\n }\n /**\n * Close all Editor's toolbars\n */\n closeAllToolbars() {\n const { Toolbar: e, BlockSettings: t, InlineToolbar: o } = this.Editor;\n t.close(), o.close(), e.toolbox.close();\n }\n /**\n * Check for mobile mode and save the result\n */\n setIsMobile() {\n const e = window.innerWidth < Ot;\n e !== this.isMobile && this.eventsDispatcher.emit(ye, {\n isEnabled: this.isMobile\n }), this.isMobile = e;\n }\n /**\n * Makes Editor.js interface\n */\n make() {\n this.nodes.holder = d.getHolder(this.config.holder), this.nodes.wrapper = d.make(\"div\", [\n this.CSS.editorWrapper,\n ...this.isRtl ? [this.CSS.editorRtlFix] : []\n ]), this.nodes.redactor = d.make(\"div\", this.CSS.editorZone), this.nodes.holder.offsetWidth < this.contentRect.width && this.nodes.wrapper.classList.add(this.CSS.editorWrapperNarrow), this.nodes.redactor.style.paddingBottom = this.config.minHeight + \"px\", this.nodes.wrapper.appendChild(this.nodes.redactor), this.nodes.holder.appendChild(this.nodes.wrapper);\n }\n /**\n * Appends CSS\n */\n loadStyles() {\n const e = \"editor-js-styles\";\n if (d.get(e))\n return;\n const t = d.make(\"style\", null, {\n id: e,\n textContent: xs.toString()\n });\n this.config.style && !V(this.config.style) && this.config.style.nonce && t.setAttribute(\"nonce\", this.config.style.nonce), d.prepend(document.head, t);\n }\n /**\n * Bind events on the Editor.js interface\n */\n enableModuleBindings() {\n this.readOnlyMutableListeners.on(this.nodes.redactor, \"click\", (t) => {\n this.redactorClicked(t);\n }, !1), this.readOnlyMutableListeners.on(this.nodes.redactor, \"mousedown\", (t) => {\n this.documentTouched(t);\n }, {\n capture: !0,\n passive: !0\n }), this.readOnlyMutableListeners.on(this.nodes.redactor, \"touchstart\", (t) => {\n this.documentTouched(t);\n }, {\n capture: !0,\n passive: !0\n }), this.readOnlyMutableListeners.on(document, \"keydown\", (t) => {\n this.documentKeydown(t);\n }, !0), this.readOnlyMutableListeners.on(document, \"mousedown\", (t) => {\n this.documentClicked(t);\n }, !0);\n const e = vt(() => {\n this.selectionChanged();\n }, ss);\n this.readOnlyMutableListeners.on(document, \"selectionchange\", e, !0), this.readOnlyMutableListeners.on(window, \"resize\", () => {\n this.resizeDebouncer();\n }, {\n passive: !0\n }), this.watchBlockHoveredEvents(), this.enableInputsEmptyMark();\n }\n /**\n * Listen redactor mousemove to emit 'block-hovered' event\n */\n watchBlockHoveredEvents() {\n let e;\n this.readOnlyMutableListeners.on(this.nodes.redactor, \"mousemove\", Ve((t) => {\n const o = t.target.closest(\".ce-block\");\n this.Editor.BlockSelection.anyBlockSelected || o && e !== o && (e = o, this.eventsDispatcher.emit(oo, {\n block: this.Editor.BlockManager.getBlockByChildNode(o)\n }));\n }, 20), {\n passive: !0\n });\n }\n /**\n * Unbind events on the Editor.js interface\n */\n disableModuleBindings() {\n this.readOnlyMutableListeners.clearAll();\n }\n /**\n * Resize window handler\n */\n windowResize() {\n this.contentRectCache = null, this.setIsMobile();\n }\n /**\n * All keydowns on document\n *\n * @param {KeyboardEvent} event - keyboard event\n */\n documentKeydown(e) {\n switch (e.keyCode) {\n case w.ENTER:\n this.enterPressed(e);\n break;\n case w.BACKSPACE:\n case w.DELETE:\n this.backspacePressed(e);\n break;\n case w.ESC:\n this.escapePressed(e);\n break;\n default:\n this.defaultBehaviour(e);\n break;\n }\n }\n /**\n * Ignore all other document's keydown events\n *\n * @param {KeyboardEvent} event - keyboard event\n */\n defaultBehaviour(e) {\n const { currentBlock: t } = this.Editor.BlockManager, o = e.target.closest(`.${this.CSS.editorWrapper}`), i = e.altKey || e.ctrlKey || e.metaKey || e.shiftKey;\n if (t !== void 0 && o === null) {\n this.Editor.BlockEvents.keydown(e);\n return;\n }\n o || t && i || (this.Editor.BlockManager.unsetCurrentBlock(), this.Editor.Toolbar.close());\n }\n /**\n * @param {KeyboardEvent} event - keyboard event\n */\n backspacePressed(e) {\n const { BlockManager: t, BlockSelection: o, Caret: i } = this.Editor;\n if (o.anyBlockSelected && !b.isSelectionExists) {\n const s = t.removeSelectedBlocks(), r = t.insertDefaultBlockAtIndex(s, !0);\n i.setToBlock(r, i.positions.START), o.clearSelection(e), e.preventDefault(), e.stopPropagation(), e.stopImmediatePropagation();\n }\n }\n /**\n * Escape pressed\n * If some of Toolbar components are opened, then close it otherwise close Toolbar\n *\n * @param {Event} event - escape keydown event\n */\n escapePressed(e) {\n this.Editor.BlockSelection.clearSelection(e), this.Editor.Toolbar.toolbox.opened ? (this.Editor.Toolbar.toolbox.close(), this.Editor.Caret.setToBlock(this.Editor.BlockManager.currentBlock, this.Editor.Caret.positions.END)) : this.Editor.BlockSettings.opened ? this.Editor.BlockSettings.close() : this.Editor.InlineToolbar.opened ? this.Editor.InlineToolbar.close() : this.Editor.Toolbar.close();\n }\n /**\n * Enter pressed on document\n *\n * @param {KeyboardEvent} event - keyboard event\n */\n enterPressed(e) {\n const { BlockManager: t, BlockSelection: o } = this.Editor;\n if (this.someToolbarOpened)\n return;\n const i = t.currentBlockIndex >= 0;\n if (o.anyBlockSelected && !b.isSelectionExists) {\n o.clearSelection(e), e.preventDefault(), e.stopImmediatePropagation(), e.stopPropagation();\n return;\n }\n if (!this.someToolbarOpened && i && e.target.tagName === \"BODY\") {\n const s = this.Editor.BlockManager.insert();\n e.preventDefault(), this.Editor.Caret.setToBlock(s), this.Editor.Toolbar.moveAndOpen(s);\n }\n this.Editor.BlockSelection.clearSelection(e);\n }\n /**\n * All clicks on document\n *\n * @param {MouseEvent} event - Click event\n */\n documentClicked(e) {\n var l, a;\n if (!e.isTrusted)\n return;\n const t = e.target;\n this.nodes.holder.contains(t) || b.isAtEditor || (this.Editor.BlockManager.unsetCurrentBlock(), this.Editor.Toolbar.close());\n const i = (l = this.Editor.BlockSettings.nodes.wrapper) == null ? void 0 : l.contains(t), s = (a = this.Editor.Toolbar.nodes.settingsToggler) == null ? void 0 : a.contains(t), r = i || s;\n if (this.Editor.BlockSettings.opened && !r) {\n this.Editor.BlockSettings.close();\n const c = this.Editor.BlockManager.getBlockByChildNode(t);\n this.Editor.Toolbar.moveAndOpen(c);\n }\n this.Editor.BlockSelection.clearSelection(e);\n }\n /**\n * First touch on editor\n * Fired before click\n *\n * Used to change current block — we need to do it before 'selectionChange' event.\n * Also:\n * - Move and show the Toolbar\n * - Set a Caret\n *\n * @param {MouseEvent | TouchEvent} event - touch or mouse event\n */\n documentTouched(e) {\n let t = e.target;\n if (t === this.nodes.redactor) {\n const o = e instanceof MouseEvent ? e.clientX : e.touches[0].clientX, i = e instanceof MouseEvent ? e.clientY : e.touches[0].clientY;\n t = document.elementFromPoint(o, i);\n }\n try {\n this.Editor.BlockManager.setCurrentBlockByChildNode(t);\n } catch {\n this.Editor.RectangleSelection.isRectActivated() || this.Editor.Caret.setToTheLastBlock();\n }\n this.Editor.Toolbar.moveAndOpen();\n }\n /**\n * All clicks on the redactor zone\n *\n * @param {MouseEvent} event - click event\n * @description\n * - By clicks on the Editor's bottom zone:\n * - if last Block is empty, set a Caret to this\n * - otherwise, add a new empty Block and set a Caret to that\n */\n redactorClicked(e) {\n if (!b.isCollapsed)\n return;\n const t = e.target, o = e.metaKey || e.ctrlKey;\n if (d.isAnchor(t) && o) {\n e.stopImmediatePropagation(), e.stopPropagation();\n const i = t.getAttribute(\"href\"), s = So(i);\n Mo(s);\n return;\n }\n this.processBottomZoneClick(e);\n }\n /**\n * Check if user clicks on the Editor's bottom zone:\n * - set caret to the last block\n * - or add new empty block\n *\n * @param event - click event\n */\n processBottomZoneClick(e) {\n const t = this.Editor.BlockManager.getBlockByIndex(-1), o = d.offset(t.holder).bottom, i = e.pageY, { BlockSelection: s } = this.Editor;\n if (e.target instanceof Element && e.target.isEqualNode(this.nodes.redactor) && /**\n * If there is cross block selection started, target will be equal to redactor so we need additional check\n */\n !s.anyBlockSelected && /**\n * Prevent caret jumping (to last block) when clicking between blocks\n */\n o < i) {\n e.stopImmediatePropagation(), e.stopPropagation();\n const { BlockManager: l, Caret: a, Toolbar: c } = this.Editor;\n (!l.lastBlock.tool.isDefault || !l.lastBlock.isEmpty) && l.insertAtEnd(), a.setToTheLastBlock(), c.moveAndOpen(l.lastBlock);\n }\n }\n /**\n * Handle selection changes on mobile devices\n * Uses for showing the Inline Toolbar\n */\n selectionChanged() {\n const { CrossBlockSelection: e, BlockSelection: t } = this.Editor, o = b.anchorElement;\n if (e.isCrossBlockSelectionStarted && t.anyBlockSelected && b.get().removeAllRanges(), !o) {\n b.range || this.Editor.InlineToolbar.close();\n return;\n }\n const i = o.closest(`.${D.CSS.content}`);\n (i === null || i.closest(`.${b.CSS.editorWrapper}`) !== this.nodes.wrapper) && (this.Editor.InlineToolbar.containsNode(o) || this.Editor.InlineToolbar.close(), !(o.dataset.inlineToolbar === \"true\")) || (this.Editor.BlockManager.currentBlock || this.Editor.BlockManager.setCurrentBlockByChildNode(o), this.Editor.InlineToolbar.tryToShow(!0));\n }\n /**\n * Editor.js provides and ability to show placeholders for empty contenteditable elements\n *\n * This method watches for input and focus events and toggles 'data-empty' attribute\n * to workaroud the case, when inputs contains only
s and has no visible content\n * Then, CSS could rely on this attribute to show placeholders\n */\n enableInputsEmptyMark() {\n function e(t) {\n const o = t.target;\n Lt(o);\n }\n this.readOnlyMutableListeners.on(this.nodes.wrapper, \"input\", e), this.readOnlyMutableListeners.on(this.nodes.wrapper, \"focusin\", e), this.readOnlyMutableListeners.on(this.nodes.wrapper, \"focusout\", e);\n }\n}\nconst Es = {\n // API Modules\n BlocksAPI: zo,\n CaretAPI: jo,\n EventsAPI: $o,\n I18nAPI: ot,\n API: Yo,\n InlineToolbarAPI: Wo,\n ListenersAPI: Ko,\n NotifierAPI: Zo,\n ReadOnlyAPI: Go,\n SanitizerAPI: si,\n SaverAPI: ni,\n SelectionAPI: ri,\n ToolsAPI: li,\n StylesAPI: ai,\n ToolbarAPI: ci,\n TooltipAPI: fi,\n UiAPI: gi,\n // Toolbar Modules\n BlockSettings: Ui,\n Toolbar: qi,\n InlineToolbar: Zi,\n // Modules\n BlockEvents: Gi,\n BlockManager: es,\n BlockSelection: ts,\n Caret: Re,\n CrossBlockSelection: os,\n DragNDrop: is,\n ModificationsObserver: rs,\n Paste: ls,\n ReadOnly: as,\n RectangleSelection: xe,\n Renderer: cs,\n Saver: ds,\n Tools: go,\n UI: ys\n};\nclass Bs {\n /**\n * @param {EditorConfig} config - user configuration\n */\n constructor(e) {\n this.moduleInstances = {}, this.eventsDispatcher = new Te();\n let t, o;\n this.isReady = new Promise((i, s) => {\n t = i, o = s;\n }), Promise.resolve().then(async () => {\n this.configuration = e, this.validate(), this.init(), await this.start(), await this.render();\n const { BlockManager: i, Caret: s, UI: r, ModificationsObserver: l } = this.moduleInstances;\n r.checkEmptiness(), l.enable(), this.configuration.autofocus && s.setToBlock(i.blocks[0], s.positions.START), t();\n }).catch((i) => {\n I(`Editor.js is not ready because of ${i}`, \"error\"), o(i);\n });\n }\n /**\n * Setting for configuration\n *\n * @param {EditorConfig|string} config - Editor's config to set\n */\n set configuration(e) {\n var o, i;\n R(e) ? this.config = {\n ...e\n } : this.config = {\n holder: e\n }, Ze(!!this.config.holderId, \"config.holderId\", \"config.holder\"), this.config.holderId && !this.config.holder && (this.config.holder = this.config.holderId, this.config.holderId = null), this.config.holder == null && (this.config.holder = \"editorjs\"), this.config.logLevel || (this.config.logLevel = It.VERBOSE), xo(this.config.logLevel), Ze(!!this.config.initialBlock, \"config.initialBlock\", \"config.defaultBlock\"), this.config.defaultBlock = this.config.defaultBlock || this.config.initialBlock || \"paragraph\", this.config.minHeight = this.config.minHeight !== void 0 ? this.config.minHeight : 300;\n const t = {\n type: this.config.defaultBlock,\n data: {}\n };\n this.config.placeholder = this.config.placeholder || !1, this.config.sanitizer = this.config.sanitizer || {\n p: !0,\n b: !0,\n a: !0\n }, this.config.hideToolbar = this.config.hideToolbar ? this.config.hideToolbar : !1, this.config.tools = this.config.tools || {}, this.config.i18n = this.config.i18n || {}, this.config.data = this.config.data || { blocks: [] }, this.config.onReady = this.config.onReady || (() => {\n }), this.config.onChange = this.config.onChange || (() => {\n }), this.config.inlineToolbar = this.config.inlineToolbar !== void 0 ? this.config.inlineToolbar : !0, (V(this.config.data) || !this.config.data.blocks || this.config.data.blocks.length === 0) && (this.config.data = { blocks: [t] }), this.config.readOnly = this.config.readOnly || !1, (o = this.config.i18n) != null && o.messages && z.setDictionary(this.config.i18n.messages), this.config.i18n.direction = ((i = this.config.i18n) == null ? void 0 : i.direction) || \"ltr\";\n }\n /**\n * Returns private property\n *\n * @returns {EditorConfig}\n */\n get configuration() {\n return this.config;\n }\n /**\n * Checks for required fields in Editor's config\n */\n validate() {\n const { holderId: e, holder: t } = this.config;\n if (e && t)\n throw Error(\"«holderId» and «holder» param can't assign at the same time.\");\n if (Q(t) && !d.get(t))\n throw Error(`element with ID «${t}» is missing. Pass correct holder's ID.`);\n if (t && R(t) && !d.isElement(t))\n throw Error(\"«holder» value must be an Element node\");\n }\n /**\n * Initializes modules:\n * - make and save instances\n * - configure\n */\n init() {\n this.constructModules(), this.configureModules();\n }\n /**\n * Start Editor!\n *\n * Get list of modules that needs to be prepared and return a sequence (Promise)\n *\n * @returns {Promise}\n */\n async start() {\n await [\n \"Tools\",\n \"UI\",\n \"BlockManager\",\n \"Paste\",\n \"BlockSelection\",\n \"RectangleSelection\",\n \"CrossBlockSelection\",\n \"ReadOnly\"\n ].reduce(\n (t, o) => t.then(async () => {\n try {\n await this.moduleInstances[o].prepare();\n } catch (i) {\n if (i instanceof Pt)\n throw new Error(i.message);\n I(`Module ${o} was skipped because of %o`, \"warn\", i);\n }\n }),\n Promise.resolve()\n );\n }\n /**\n * Render initial data\n */\n render() {\n return this.moduleInstances.Renderer.render(this.config.data.blocks);\n }\n /**\n * Make modules instances and save it to the @property this.moduleInstances\n */\n constructModules() {\n Object.entries(Es).forEach(([e, t]) => {\n try {\n this.moduleInstances[e] = new t({\n config: this.configuration,\n eventsDispatcher: this.eventsDispatcher\n });\n } catch (o) {\n I(\"[constructModules]\", `Module ${e} skipped because`, \"error\", o);\n }\n });\n }\n /**\n * Modules instances configuration:\n * - pass other modules to the 'state' property\n * - ...\n */\n configureModules() {\n for (const e in this.moduleInstances)\n Object.prototype.hasOwnProperty.call(this.moduleInstances, e) && (this.moduleInstances[e].state = this.getModulesDiff(e));\n }\n /**\n * Return modules without passed name\n *\n * @param {string} name - module for witch modules difference should be calculated\n */\n getModulesDiff(e) {\n const t = {};\n for (const o in this.moduleInstances)\n o !== e && (t[o] = this.moduleInstances[o]);\n return t;\n }\n}\n/**\n * Editor.js\n *\n * @license Apache-2.0\n * @see Editor.js \n * @author CodeX Team \n */\nclass Ts {\n /** Editor version */\n static get version() {\n return \"2.30.7\";\n }\n /**\n * @param {EditorConfig|string|undefined} [configuration] - user configuration\n */\n constructor(e) {\n let t = () => {\n };\n R(e) && O(e.onReady) && (t = e.onReady);\n const o = new Bs(e);\n this.isReady = o.isReady.then(() => {\n this.exportAPI(o), t();\n });\n }\n /**\n * Export external API methods\n *\n * @param {Core} editor — Editor's instance\n */\n exportAPI(e) {\n const t = [\"configuration\"], o = () => {\n Object.values(e.moduleInstances).forEach((s) => {\n O(s.destroy) && s.destroy(), s.listeners.removeAll();\n }), pi(), e = null;\n for (const s in this)\n Object.prototype.hasOwnProperty.call(this, s) && delete this[s];\n Object.setPrototypeOf(this, null);\n };\n t.forEach((s) => {\n this[s] = e[s];\n }), this.destroy = o, Object.setPrototypeOf(this, e.moduleInstances.API.methods), delete this.exportAPI, Object.entries({\n blocks: {\n clear: \"clear\",\n render: \"render\"\n },\n caret: {\n focus: \"focus\"\n },\n events: {\n on: \"on\",\n off: \"off\",\n emit: \"emit\"\n },\n saver: {\n save: \"save\"\n }\n }).forEach(([s, r]) => {\n Object.entries(r).forEach(([l, a]) => {\n this[a] = e.moduleInstances.API.methods[s][l];\n });\n });\n }\n}\nexport {\n Ts as default\n};\n","(function(){\"use strict\";try{if(typeof document<\"u\"){var e=document.createElement(\"style\");e.appendChild(document.createTextNode(\".cdx-underline{text-decoration:underline}\")),document.head.appendChild(e)}}catch(n){console.error(\"vite-plugin-css-injected-by-js\",n)}})();\nconst r = '', s = class s {\n /**\n * @param options InlineToolConstructorOptions\n */\n constructor(e) {\n this.tag = \"U\", this.api = e.api, this.iconClasses = {\n base: this.api.styles.inlineToolButton,\n active: this.api.styles.inlineToolButtonActive\n };\n }\n /**\n * Class name for term-tag\n *\n * @type {string}\n */\n static get CSS() {\n return \"cdx-underline\";\n }\n /**\n * Create button element for Toolbar\n *\n * @returns {HTMLElement}\n */\n render() {\n return this.button = document.createElement(\"button\"), this.button.type = \"button\", this.button.classList.add(this.iconClasses.base), this.button.innerHTML = this.toolboxIcon, this.button;\n }\n /**\n * Wrap/Unwrap selected fragment\n *\n * @param {Range} range - selected fragment\n */\n surround(e) {\n if (!e)\n return;\n const t = this.api.selection.findParentTag(this.tag, s.CSS);\n t ? this.unwrap(t) : this.wrap(e);\n }\n /**\n * Wrap selection with term-tag\n *\n * @param {Range} range - selected fragment\n */\n wrap(e) {\n const t = document.createElement(this.tag);\n t.classList.add(s.CSS), t.appendChild(e.extractContents()), e.insertNode(t), this.api.selection.expandToTag(t);\n }\n /**\n * Unwrap term-tag\n *\n * @param {HTMLElement} termWrapper - term wrapper tag\n */\n unwrap(e) {\n var o;\n this.api.selection.expandToTag(e);\n const t = window.getSelection();\n if (!t)\n return;\n const n = t.getRangeAt(0);\n if (!n)\n return;\n const i = n.extractContents();\n i && ((o = e.parentNode) == null || o.removeChild(e), n.insertNode(i), t.removeAllRanges(), t.addRange(n));\n }\n /**\n * Check and change Term's state for current selection\n */\n checkState() {\n var t;\n const e = this.api.selection.findParentTag(this.tag, s.CSS);\n return (t = this.button) == null || t.classList.toggle(this.iconClasses.active, !!e), !!e;\n }\n /**\n * Get Tool icon's SVG\n *\n * @returns {string}\n */\n get toolboxIcon() {\n return r;\n }\n /**\n * Sanitizer rule\n *\n * @returns {{u: {class: string}}}\n */\n static get sanitize() {\n return {\n u: {\n class: s.CSS\n }\n };\n }\n};\ns.isInline = !0;\nlet a = s;\nexport {\n a as default\n};\n","(function(){\"use strict\";try{if(typeof document<\"u\"){var e=document.createElement(\"style\");e.appendChild(document.createTextNode(\".cdx-list{margin:0;padding-left:40px;outline:none}.cdx-list__item{padding:5.5px 0 5.5px 3px;line-height:1.6em}.cdx-list--unordered{list-style:disc}.cdx-list--ordered{list-style:decimal}.cdx-list-settings{display:flex}.cdx-list-settings .cdx-settings-button{width:50%}\")),document.head.appendChild(e)}}catch(t){console.error(\"vite-plugin-css-injected-by-js\",t)}})();\nconst a = '', o = '';\nclass d {\n /**\n * Notify core that read-only mode is supported\n *\n * @returns {boolean}\n */\n static get isReadOnlySupported() {\n return !0;\n }\n /**\n * Allow to use native Enter behaviour\n *\n * @returns {boolean}\n * @public\n */\n static get enableLineBreaks() {\n return !0;\n }\n /**\n * Get Tool toolbox settings\n * icon - Tool icon's SVG\n * title - title to show in toolbox\n *\n * @returns {{icon: string, title: string}}\n */\n static get toolbox() {\n return {\n icon: a,\n title: \"List\"\n };\n }\n /**\n * Render plugin`s main Element and fill it with saved data\n *\n * @param {object} params - tool constructor options\n * @param {ListData} params.data - previously saved data\n * @param {object} params.config - user config for Tool\n * @param {object} params.api - Editor.js API\n * @param {boolean} params.readOnly - read-only mode flag\n */\n constructor({ data: e, config: t, api: r, readOnly: s }) {\n this._elements = {\n wrapper: null\n }, this.api = r, this.readOnly = s, this.settings = [\n {\n name: \"unordered\",\n label: this.api.i18n.t(\"Unordered\"),\n icon: a,\n default: t.defaultStyle === \"unordered\" || !1\n },\n {\n name: \"ordered\",\n label: this.api.i18n.t(\"Ordered\"),\n icon: o,\n default: t.defaultStyle === \"ordered\" || !0\n }\n ], this._data = {\n style: this.settings.find((i) => i.default === !0).name,\n items: []\n }, this.data = e;\n }\n /**\n * Returns list tag with items\n *\n * @returns {Element}\n * @public\n */\n render() {\n return this._elements.wrapper = this.makeMainTag(this._data.style), this._data.items.length ? this._data.items.forEach((e) => {\n this._elements.wrapper.appendChild(this._make(\"li\", this.CSS.item, {\n innerHTML: e\n }));\n }) : this._elements.wrapper.appendChild(this._make(\"li\", this.CSS.item)), this.readOnly || this._elements.wrapper.addEventListener(\"keydown\", (e) => {\n const [t, r] = [13, 8];\n switch (e.keyCode) {\n case t:\n this.getOutofList(e);\n break;\n case r:\n this.backspace(e);\n break;\n }\n }, !1), this._elements.wrapper;\n }\n /**\n * @returns {ListData}\n * @public\n */\n save() {\n return this.data;\n }\n /**\n * Allow List Tool to be converted to/from other block\n *\n * @returns {{export: Function, import: Function}}\n */\n static get conversionConfig() {\n return {\n /**\n * To create exported string from list, concatenate items by dot-symbol.\n *\n * @param {ListData} data - list data to create a string from thats\n * @returns {string}\n */\n export: (e) => e.items.join(\". \"),\n /**\n * To create a list from other block's string, just put it at the first item\n *\n * @param {string} string - string to create list tool data from that\n * @returns {ListData}\n */\n import: (e) => ({\n items: [e],\n style: \"unordered\"\n })\n };\n }\n /**\n * Sanitizer rules\n *\n * @returns {object}\n */\n static get sanitize() {\n return {\n style: {},\n items: {\n br: !0\n }\n };\n }\n /**\n * Settings\n *\n * @public\n * @returns {Array}\n */\n renderSettings() {\n return this.settings.map((e) => ({\n ...e,\n isActive: this._data.style === e.name,\n closeOnActivate: !0,\n onActivate: () => this.toggleTune(e.name)\n }));\n }\n /**\n * On paste callback that is fired from Editor\n *\n * @param {PasteEvent} event - event with pasted data\n */\n onPaste(e) {\n const t = e.detail.data;\n this.data = this.pasteHandler(t);\n }\n /**\n * List Tool on paste configuration\n *\n * @public\n */\n static get pasteConfig() {\n return {\n tags: [\"OL\", \"UL\", \"LI\"]\n };\n }\n /**\n * Creates main
    or
      tag depended on style\n *\n * @param {string} style - 'ordered' or 'unordered'\n * @returns {HTMLOListElement|HTMLUListElement}\n */\n makeMainTag(e) {\n const t = e === \"ordered\" ? this.CSS.wrapperOrdered : this.CSS.wrapperUnordered, r = e === \"ordered\" ? \"ol\" : \"ul\";\n return this._make(r, [this.CSS.baseBlock, this.CSS.wrapper, t], {\n contentEditable: !this.readOnly\n });\n }\n /**\n * Toggles List style\n *\n * @param {string} style - 'ordered'|'unordered'\n */\n toggleTune(e) {\n const t = this.makeMainTag(e);\n for (; this._elements.wrapper.hasChildNodes(); )\n t.appendChild(this._elements.wrapper.firstChild);\n this._elements.wrapper.replaceWith(t), this._elements.wrapper = t, this._data.style = e;\n }\n /**\n * Styles\n *\n * @private\n */\n get CSS() {\n return {\n baseBlock: this.api.styles.block,\n wrapper: \"cdx-list\",\n wrapperOrdered: \"cdx-list--ordered\",\n wrapperUnordered: \"cdx-list--unordered\",\n item: \"cdx-list__item\"\n };\n }\n /**\n * List data setter\n *\n * @param {ListData} listData\n */\n set data(e) {\n e || (e = {}), this._data.style = e.style || this.settings.find((r) => r.default === !0).name, this._data.items = e.items || [];\n const t = this._elements.wrapper;\n t && t.parentNode.replaceChild(this.render(), t);\n }\n /**\n * Return List data\n *\n * @returns {ListData}\n */\n get data() {\n this._data.items = [];\n const e = this._elements.wrapper.querySelectorAll(`.${this.CSS.item}`);\n for (let t = 0; t < e.length; t++)\n e[t].innerHTML.replace(\"
      \", \" \").trim() && this._data.items.push(e[t].innerHTML);\n return this._data;\n }\n /**\n * Helper for making Elements with attributes\n *\n * @param {string} tagName - new Element tag name\n * @param {Array|string} classNames - list or name of CSS classname(s)\n * @param {object} attributes - any attributes\n * @returns {Element}\n */\n _make(e, t = null, r = {}) {\n const s = document.createElement(e);\n Array.isArray(t) ? s.classList.add(...t) : t && s.classList.add(t);\n for (const i in r)\n s[i] = r[i];\n return s;\n }\n /**\n * Returns current List item by the caret position\n *\n * @returns {Element}\n */\n get currentItem() {\n let e = window.getSelection().anchorNode;\n return e.nodeType !== Node.ELEMENT_NODE && (e = e.parentNode), e.closest(`.${this.CSS.item}`);\n }\n /**\n * Get out from List Tool\n * by Enter on the empty last item\n *\n * @param {KeyboardEvent} event\n */\n getOutofList(e) {\n const t = this._elements.wrapper.querySelectorAll(\".\" + this.CSS.item);\n if (t.length < 2)\n return;\n const r = t[t.length - 1], s = this.currentItem;\n s === r && !r.textContent.trim().length && (s.parentElement.removeChild(s), this.api.blocks.insert(), this.api.caret.setToBlock(this.api.blocks.getCurrentBlockIndex()), e.preventDefault(), e.stopPropagation());\n }\n /**\n * Handle backspace\n *\n * @param {KeyboardEvent} event\n */\n backspace(e) {\n const t = this._elements.wrapper.querySelectorAll(\".\" + this.CSS.item), r = t[0];\n r && t.length < 2 && !r.innerHTML.replace(\"
      \", \" \").trim() && e.preventDefault();\n }\n /**\n * Select LI content by CMD+A\n *\n * @param {KeyboardEvent} event\n */\n selectItem(e) {\n e.preventDefault();\n const t = window.getSelection(), r = t.anchorNode.parentNode, s = r.closest(\".\" + this.CSS.item), i = new Range();\n i.selectNodeContents(s), t.removeAllRanges(), t.addRange(i);\n }\n /**\n * Handle UL, OL and LI tags paste and returns List data\n *\n * @param {HTMLUListElement|HTMLOListElement|HTMLLIElement} element\n * @returns {ListData}\n */\n pasteHandler(e) {\n const { tagName: t } = e;\n let r;\n switch (t) {\n case \"OL\":\n r = \"ordered\";\n break;\n case \"UL\":\n case \"LI\":\n r = \"unordered\";\n }\n const s = {\n style: r,\n items: []\n };\n if (t === \"LI\")\n s.items = [e.innerHTML];\n else {\n const i = Array.from(e.querySelectorAll(\"LI\"));\n s.items = i.map((n) => n.innerHTML).filter((n) => !!n.trim());\n }\n return s;\n }\n}\nexport {\n d as default\n};\n","(function(){\"use strict\";try{if(typeof document<\"u\"){var e=document.createElement(\"style\");e.appendChild(document.createTextNode(\".ce-paragraph{line-height:1.6em;outline:none}.ce-block:only-of-type .ce-paragraph[data-placeholder-active]:empty:before,.ce-block:only-of-type .ce-paragraph[data-placeholder-active][data-empty=true]:before{content:attr(data-placeholder-active)}.ce-paragraph p:first-of-type{margin-top:0}.ce-paragraph p:last-of-type{margin-bottom:0}\")),document.head.appendChild(e)}}catch(a){console.error(\"vite-plugin-css-injected-by-js\",a)}})();\nconst a = '';\nfunction l(r) {\n const t = document.createElement(\"div\");\n t.innerHTML = r.trim();\n const e = document.createDocumentFragment();\n return e.append(...Array.from(t.childNodes)), e;\n}\n/**\n * Base Paragraph Block for the Editor.js.\n * Represents a regular text block\n *\n * @author CodeX (team@codex.so)\n * @copyright CodeX 2018\n * @license The MIT License (MIT)\n */\nclass n {\n /**\n * Default placeholder for Paragraph Tool\n *\n * @returns {string}\n * @class\n */\n static get DEFAULT_PLACEHOLDER() {\n return \"\";\n }\n /**\n * Render plugin`s main Element and fill it with saved data\n *\n * @param {object} params - constructor params\n * @param {ParagraphData} params.data - previously saved data\n * @param {ParagraphConfig} params.config - user config for Tool\n * @param {object} params.api - editor.js api\n * @param {boolean} readOnly - read only mode flag\n */\n constructor({ data: t, config: e, api: i, readOnly: s }) {\n this.api = i, this.readOnly = s, this._CSS = {\n block: this.api.styles.block,\n wrapper: \"ce-paragraph\"\n }, this.readOnly || (this.onKeyUp = this.onKeyUp.bind(this)), this._placeholder = e.placeholder ? e.placeholder : n.DEFAULT_PLACEHOLDER, this._data = t ?? {}, this._element = null, this._preserveBlank = e.preserveBlank ?? !1;\n }\n /**\n * Check if text content is empty and set empty string to inner html.\n * We need this because some browsers (e.g. Safari) insert
      into empty contenteditanle elements\n *\n * @param {KeyboardEvent} e - key up event\n */\n onKeyUp(t) {\n if (t.code !== \"Backspace\" && t.code !== \"Delete\" || !this._element)\n return;\n const { textContent: e } = this._element;\n e === \"\" && (this._element.innerHTML = \"\");\n }\n /**\n * Create Tool's view\n *\n * @returns {HTMLDivElement}\n * @private\n */\n drawView() {\n const t = document.createElement(\"DIV\");\n return t.classList.add(this._CSS.wrapper, this._CSS.block), t.contentEditable = \"false\", t.dataset.placeholderActive = this.api.i18n.t(this._placeholder), this._data.text && (t.innerHTML = this._data.text), this.readOnly || (t.contentEditable = \"true\", t.addEventListener(\"keyup\", this.onKeyUp)), t;\n }\n /**\n * Return Tool's view\n *\n * @returns {HTMLDivElement}\n */\n render() {\n return this._element = this.drawView(), this._element;\n }\n /**\n * Method that specified how to merge two Text blocks.\n * Called by Editor.js by backspace at the beginning of the Block\n *\n * @param {ParagraphData} data\n * @public\n */\n merge(t) {\n if (!this._element)\n return;\n this._data.text += t.text;\n const e = l(t.text);\n this._element.appendChild(e), this._element.normalize();\n }\n /**\n * Validate Paragraph block data:\n * - check for emptiness\n *\n * @param {ParagraphData} savedData — data received after saving\n * @returns {boolean} false if saved data is not correct, otherwise true\n * @public\n */\n validate(t) {\n return !(t.text.trim() === \"\" && !this._preserveBlank);\n }\n /**\n * Extract Tool's data from the view\n *\n * @param {HTMLDivElement} toolsContent - Paragraph tools rendered view\n * @returns {ParagraphData} - saved data\n * @public\n */\n save(t) {\n return {\n text: t.innerHTML\n };\n }\n /**\n * On paste callback fired from Editor.\n *\n * @param {HTMLPasteEvent} event - event with pasted data\n */\n onPaste(t) {\n const e = {\n text: t.detail.data.innerHTML\n };\n this._data = e, window.requestAnimationFrame(() => {\n this._element && (this._element.innerHTML = this._data.text || \"\");\n });\n }\n /**\n * Enable Conversion Toolbar. Paragraph can be converted to/from other tools\n * @returns {ConversionConfig}\n */\n static get conversionConfig() {\n return {\n export: \"text\",\n // to convert Paragraph to other block, use 'text' property of saved data\n import: \"text\"\n // to covert other block's exported string to Paragraph, fill 'text' property of tool data\n };\n }\n /**\n * Sanitizer rules\n * @returns {SanitizerConfig} - Edtior.js sanitizer config\n */\n static get sanitize() {\n return {\n text: {\n br: !0\n }\n };\n }\n /**\n * Returns true to notify the core that read-only mode is supported\n *\n * @returns {boolean}\n */\n static get isReadOnlySupported() {\n return !0;\n }\n /**\n * Used by Editor paste handling API.\n * Provides configuration to handle P tags.\n *\n * @returns {PasteConfig} - Paragraph Paste Setting\n */\n static get pasteConfig() {\n return {\n tags: [\"P\"]\n };\n }\n /**\n * Icon and title for displaying at the Toolbox\n *\n * @returns {ToolboxConfig} - Paragraph Toolbox Setting\n */\n static get toolbox() {\n return {\n icon: a,\n title: \"Text\"\n };\n }\n}\nexport {\n n as default\n};\n","export class MergeTag {\n static get isInline() {\n return true\n }\n\n static get sanitize() {\n return {\n span: {\n class: 'vendor_category_merge_tag',\n contenteditable: true\n }\n }\n }\n\n render() {}\n\n surround(range) {}\n\n checkState(selection) {}\n}\n","/*!\n * Vue.js v2.7.16\n * (c) 2014-2023 Evan You\n * Released under the MIT License.\n */\nvar emptyObject = Object.freeze({});\nvar isArray = Array.isArray;\n// These helpers produce better VM code in JS engines due to their\n// explicitness and function inlining.\nfunction isUndef(v) {\n return v === undefined || v === null;\n}\nfunction isDef(v) {\n return v !== undefined && v !== null;\n}\nfunction isTrue(v) {\n return v === true;\n}\nfunction isFalse(v) {\n return v === false;\n}\n/**\n * Check if value is primitive.\n */\nfunction isPrimitive(value) {\n return (typeof value === 'string' ||\n typeof value === 'number' ||\n // $flow-disable-line\n typeof value === 'symbol' ||\n typeof value === 'boolean');\n}\nfunction isFunction(value) {\n return typeof value === 'function';\n}\n/**\n * Quick object check - this is primarily used to tell\n * objects from primitive values when we know the value\n * is a JSON-compliant type.\n */\nfunction isObject(obj) {\n return obj !== null && typeof obj === 'object';\n}\n/**\n * Get the raw type string of a value, e.g., [object Object].\n */\nvar _toString = Object.prototype.toString;\nfunction toRawType(value) {\n return _toString.call(value).slice(8, -1);\n}\n/**\n * Strict object type check. Only returns true\n * for plain JavaScript objects.\n */\nfunction isPlainObject(obj) {\n return _toString.call(obj) === '[object Object]';\n}\nfunction isRegExp(v) {\n return _toString.call(v) === '[object RegExp]';\n}\n/**\n * Check if val is a valid array index.\n */\nfunction isValidArrayIndex(val) {\n var n = parseFloat(String(val));\n return n >= 0 && Math.floor(n) === n && isFinite(val);\n}\nfunction isPromise(val) {\n return (isDef(val) &&\n typeof val.then === 'function' &&\n typeof val.catch === 'function');\n}\n/**\n * Convert a value to a string that is actually rendered.\n */\nfunction toString(val) {\n return val == null\n ? ''\n : Array.isArray(val) || (isPlainObject(val) && val.toString === _toString)\n ? JSON.stringify(val, replacer, 2)\n : String(val);\n}\nfunction replacer(_key, val) {\n // avoid circular deps from v3\n if (val && val.__v_isRef) {\n return val.value;\n }\n return val;\n}\n/**\n * Convert an input value to a number for persistence.\n * If the conversion fails, return original string.\n */\nfunction toNumber(val) {\n var n = parseFloat(val);\n return isNaN(n) ? val : n;\n}\n/**\n * Make a map and return a function for checking if a key\n * is in that map.\n */\nfunction makeMap(str, expectsLowerCase) {\n var map = Object.create(null);\n var list = str.split(',');\n for (var i = 0; i < list.length; i++) {\n map[list[i]] = true;\n }\n return expectsLowerCase ? function (val) { return map[val.toLowerCase()]; } : function (val) { return map[val]; };\n}\n/**\n * Check if a tag is a built-in tag.\n */\nvar isBuiltInTag = makeMap('slot,component', true);\n/**\n * Check if an attribute is a reserved attribute.\n */\nvar isReservedAttribute = makeMap('key,ref,slot,slot-scope,is');\n/**\n * Remove an item from an array.\n */\nfunction remove$2(arr, item) {\n var len = arr.length;\n if (len) {\n // fast path for the only / last item\n if (item === arr[len - 1]) {\n arr.length = len - 1;\n return;\n }\n var index = arr.indexOf(item);\n if (index > -1) {\n return arr.splice(index, 1);\n }\n }\n}\n/**\n * Check whether an object has the property.\n */\nvar hasOwnProperty = Object.prototype.hasOwnProperty;\nfunction hasOwn(obj, key) {\n return hasOwnProperty.call(obj, key);\n}\n/**\n * Create a cached version of a pure function.\n */\nfunction cached(fn) {\n var cache = Object.create(null);\n return function cachedFn(str) {\n var hit = cache[str];\n return hit || (cache[str] = fn(str));\n };\n}\n/**\n * Camelize a hyphen-delimited string.\n */\nvar camelizeRE = /-(\\w)/g;\nvar camelize = cached(function (str) {\n return str.replace(camelizeRE, function (_, c) { return (c ? c.toUpperCase() : ''); });\n});\n/**\n * Capitalize a string.\n */\nvar capitalize = cached(function (str) {\n return str.charAt(0).toUpperCase() + str.slice(1);\n});\n/**\n * Hyphenate a camelCase string.\n */\nvar hyphenateRE = /\\B([A-Z])/g;\nvar hyphenate = cached(function (str) {\n return str.replace(hyphenateRE, '-$1').toLowerCase();\n});\n/**\n * Simple bind polyfill for environments that do not support it,\n * e.g., PhantomJS 1.x. Technically, we don't need this anymore\n * since native bind is now performant enough in most browsers.\n * But removing it would mean breaking code that was able to run in\n * PhantomJS 1.x, so this must be kept for backward compatibility.\n */\n/* istanbul ignore next */\nfunction polyfillBind(fn, ctx) {\n function boundFn(a) {\n var l = arguments.length;\n return l\n ? l > 1\n ? fn.apply(ctx, arguments)\n : fn.call(ctx, a)\n : fn.call(ctx);\n }\n boundFn._length = fn.length;\n return boundFn;\n}\nfunction nativeBind(fn, ctx) {\n return fn.bind(ctx);\n}\n// @ts-expect-error bind cannot be `undefined`\nvar bind = Function.prototype.bind ? nativeBind : polyfillBind;\n/**\n * Convert an Array-like object to a real Array.\n */\nfunction toArray(list, start) {\n start = start || 0;\n var i = list.length - start;\n var ret = new Array(i);\n while (i--) {\n ret[i] = list[i + start];\n }\n return ret;\n}\n/**\n * Mix properties into target object.\n */\nfunction extend(to, _from) {\n for (var key in _from) {\n to[key] = _from[key];\n }\n return to;\n}\n/**\n * Merge an Array of Objects into a single Object.\n */\nfunction toObject(arr) {\n var res = {};\n for (var i = 0; i < arr.length; i++) {\n if (arr[i]) {\n extend(res, arr[i]);\n }\n }\n return res;\n}\n/* eslint-disable no-unused-vars */\n/**\n * Perform no operation.\n * Stubbing args to make Flow happy without leaving useless transpiled code\n * with ...rest (https://flow.org/blog/2017/05/07/Strict-Function-Call-Arity/).\n */\nfunction noop(a, b, c) { }\n/**\n * Always return false.\n */\nvar no = function (a, b, c) { return false; };\n/* eslint-enable no-unused-vars */\n/**\n * Return the same value.\n */\nvar identity = function (_) { return _; };\n/**\n * Check if two values are loosely equal - that is,\n * if they are plain objects, do they have the same shape?\n */\nfunction looseEqual(a, b) {\n if (a === b)\n return true;\n var isObjectA = isObject(a);\n var isObjectB = isObject(b);\n if (isObjectA && isObjectB) {\n try {\n var isArrayA = Array.isArray(a);\n var isArrayB = Array.isArray(b);\n if (isArrayA && isArrayB) {\n return (a.length === b.length &&\n a.every(function (e, i) {\n return looseEqual(e, b[i]);\n }));\n }\n else if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime();\n }\n else if (!isArrayA && !isArrayB) {\n var keysA = Object.keys(a);\n var keysB = Object.keys(b);\n return (keysA.length === keysB.length &&\n keysA.every(function (key) {\n return looseEqual(a[key], b[key]);\n }));\n }\n else {\n /* istanbul ignore next */\n return false;\n }\n }\n catch (e) {\n /* istanbul ignore next */\n return false;\n }\n }\n else if (!isObjectA && !isObjectB) {\n return String(a) === String(b);\n }\n else {\n return false;\n }\n}\n/**\n * Return the first index at which a loosely equal value can be\n * found in the array (if value is a plain object, the array must\n * contain an object of the same shape), or -1 if it is not present.\n */\nfunction looseIndexOf(arr, val) {\n for (var i = 0; i < arr.length; i++) {\n if (looseEqual(arr[i], val))\n return i;\n }\n return -1;\n}\n/**\n * Ensure a function is called only once.\n */\nfunction once(fn) {\n var called = false;\n return function () {\n if (!called) {\n called = true;\n fn.apply(this, arguments);\n }\n };\n}\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is#polyfill\nfunction hasChanged(x, y) {\n if (x === y) {\n return x === 0 && 1 / x !== 1 / y;\n }\n else {\n return x === x || y === y;\n }\n}\n\nvar SSR_ATTR = 'data-server-rendered';\nvar ASSET_TYPES = ['component', 'directive', 'filter'];\nvar LIFECYCLE_HOOKS = [\n 'beforeCreate',\n 'created',\n 'beforeMount',\n 'mounted',\n 'beforeUpdate',\n 'updated',\n 'beforeDestroy',\n 'destroyed',\n 'activated',\n 'deactivated',\n 'errorCaptured',\n 'serverPrefetch',\n 'renderTracked',\n 'renderTriggered'\n];\n\nvar config = {\n /**\n * Option merge strategies (used in core/util/options)\n */\n // $flow-disable-line\n optionMergeStrategies: Object.create(null),\n /**\n * Whether to suppress warnings.\n */\n silent: false,\n /**\n * Show production mode tip message on boot?\n */\n productionTip: process.env.NODE_ENV !== 'production',\n /**\n * Whether to enable devtools\n */\n devtools: process.env.NODE_ENV !== 'production',\n /**\n * Whether to record perf\n */\n performance: false,\n /**\n * Error handler for watcher errors\n */\n errorHandler: null,\n /**\n * Warn handler for watcher warns\n */\n warnHandler: null,\n /**\n * Ignore certain custom elements\n */\n ignoredElements: [],\n /**\n * Custom user key aliases for v-on\n */\n // $flow-disable-line\n keyCodes: Object.create(null),\n /**\n * Check if a tag is reserved so that it cannot be registered as a\n * component. This is platform-dependent and may be overwritten.\n */\n isReservedTag: no,\n /**\n * Check if an attribute is reserved so that it cannot be used as a component\n * prop. This is platform-dependent and may be overwritten.\n */\n isReservedAttr: no,\n /**\n * Check if a tag is an unknown element.\n * Platform-dependent.\n */\n isUnknownElement: no,\n /**\n * Get the namespace of an element\n */\n getTagNamespace: noop,\n /**\n * Parse the real tag name for the specific platform.\n */\n parsePlatformTagName: identity,\n /**\n * Check if an attribute must be bound using property, e.g. value\n * Platform-dependent.\n */\n mustUseProp: no,\n /**\n * Perform updates asynchronously. Intended to be used by Vue Test Utils\n * This will significantly reduce performance if set to false.\n */\n async: true,\n /**\n * Exposed for legacy reasons\n */\n _lifecycleHooks: LIFECYCLE_HOOKS\n};\n\n/**\n * unicode letters used for parsing html tags, component names and property paths.\n * using https://www.w3.org/TR/html53/semantics-scripting.html#potentialcustomelementname\n * skipping \\u10000-\\uEFFFF due to it freezing up PhantomJS\n */\nvar unicodeRegExp = /a-zA-Z\\u00B7\\u00C0-\\u00D6\\u00D8-\\u00F6\\u00F8-\\u037D\\u037F-\\u1FFF\\u200C-\\u200D\\u203F-\\u2040\\u2070-\\u218F\\u2C00-\\u2FEF\\u3001-\\uD7FF\\uF900-\\uFDCF\\uFDF0-\\uFFFD/;\n/**\n * Check if a string starts with $ or _\n */\nfunction isReserved(str) {\n var c = (str + '').charCodeAt(0);\n return c === 0x24 || c === 0x5f;\n}\n/**\n * Define a property.\n */\nfunction def(obj, key, val, enumerable) {\n Object.defineProperty(obj, key, {\n value: val,\n enumerable: !!enumerable,\n writable: true,\n configurable: true\n });\n}\n/**\n * Parse simple path.\n */\nvar bailRE = new RegExp(\"[^\".concat(unicodeRegExp.source, \".$_\\\\d]\"));\nfunction parsePath(path) {\n if (bailRE.test(path)) {\n return;\n }\n var segments = path.split('.');\n return function (obj) {\n for (var i = 0; i < segments.length; i++) {\n if (!obj)\n return;\n obj = obj[segments[i]];\n }\n return obj;\n };\n}\n\n// can we use __proto__?\nvar hasProto = '__proto__' in {};\n// Browser environment sniffing\nvar inBrowser = typeof window !== 'undefined';\nvar UA = inBrowser && window.navigator.userAgent.toLowerCase();\nvar isIE = UA && /msie|trident/.test(UA);\nvar isIE9 = UA && UA.indexOf('msie 9.0') > 0;\nvar isEdge = UA && UA.indexOf('edge/') > 0;\nUA && UA.indexOf('android') > 0;\nvar isIOS = UA && /iphone|ipad|ipod|ios/.test(UA);\nUA && /chrome\\/\\d+/.test(UA) && !isEdge;\nUA && /phantomjs/.test(UA);\nvar isFF = UA && UA.match(/firefox\\/(\\d+)/);\n// Firefox has a \"watch\" function on Object.prototype...\n// @ts-expect-error firebox support\nvar nativeWatch = {}.watch;\nvar supportsPassive = false;\nif (inBrowser) {\n try {\n var opts = {};\n Object.defineProperty(opts, 'passive', {\n get: function () {\n /* istanbul ignore next */\n supportsPassive = true;\n }\n }); // https://github.com/facebook/flow/issues/285\n window.addEventListener('test-passive', null, opts);\n }\n catch (e) { }\n}\n// this needs to be lazy-evaled because vue may be required before\n// vue-server-renderer can set VUE_ENV\nvar _isServer;\nvar isServerRendering = function () {\n if (_isServer === undefined) {\n /* istanbul ignore if */\n if (!inBrowser && typeof global !== 'undefined') {\n // detect presence of vue-server-renderer and avoid\n // Webpack shimming the process\n _isServer =\n global['process'] && global['process'].env.VUE_ENV === 'server';\n }\n else {\n _isServer = false;\n }\n }\n return _isServer;\n};\n// detect devtools\nvar devtools = inBrowser && window.__VUE_DEVTOOLS_GLOBAL_HOOK__;\n/* istanbul ignore next */\nfunction isNative(Ctor) {\n return typeof Ctor === 'function' && /native code/.test(Ctor.toString());\n}\nvar hasSymbol = typeof Symbol !== 'undefined' &&\n isNative(Symbol) &&\n typeof Reflect !== 'undefined' &&\n isNative(Reflect.ownKeys);\nvar _Set; // $flow-disable-line\n/* istanbul ignore if */ if (typeof Set !== 'undefined' && isNative(Set)) {\n // use native Set when available.\n _Set = Set;\n}\nelse {\n // a non-standard Set polyfill that only works with primitive keys.\n _Set = /** @class */ (function () {\n function Set() {\n this.set = Object.create(null);\n }\n Set.prototype.has = function (key) {\n return this.set[key] === true;\n };\n Set.prototype.add = function (key) {\n this.set[key] = true;\n };\n Set.prototype.clear = function () {\n this.set = Object.create(null);\n };\n return Set;\n }());\n}\n\nvar currentInstance = null;\n/**\n * This is exposed for compatibility with v3 (e.g. some functions in VueUse\n * relies on it). Do not use this internally, just use `currentInstance`.\n *\n * @internal this function needs manual type declaration because it relies\n * on previously manually authored types from Vue 2\n */\nfunction getCurrentInstance() {\n return currentInstance && { proxy: currentInstance };\n}\n/**\n * @internal\n */\nfunction setCurrentInstance(vm) {\n if (vm === void 0) { vm = null; }\n if (!vm)\n currentInstance && currentInstance._scope.off();\n currentInstance = vm;\n vm && vm._scope.on();\n}\n\n/**\n * @internal\n */\nvar VNode = /** @class */ (function () {\n function VNode(tag, data, children, text, elm, context, componentOptions, asyncFactory) {\n this.tag = tag;\n this.data = data;\n this.children = children;\n this.text = text;\n this.elm = elm;\n this.ns = undefined;\n this.context = context;\n this.fnContext = undefined;\n this.fnOptions = undefined;\n this.fnScopeId = undefined;\n this.key = data && data.key;\n this.componentOptions = componentOptions;\n this.componentInstance = undefined;\n this.parent = undefined;\n this.raw = false;\n this.isStatic = false;\n this.isRootInsert = true;\n this.isComment = false;\n this.isCloned = false;\n this.isOnce = false;\n this.asyncFactory = asyncFactory;\n this.asyncMeta = undefined;\n this.isAsyncPlaceholder = false;\n }\n Object.defineProperty(VNode.prototype, \"child\", {\n // DEPRECATED: alias for componentInstance for backwards compat.\n /* istanbul ignore next */\n get: function () {\n return this.componentInstance;\n },\n enumerable: false,\n configurable: true\n });\n return VNode;\n}());\nvar createEmptyVNode = function (text) {\n if (text === void 0) { text = ''; }\n var node = new VNode();\n node.text = text;\n node.isComment = true;\n return node;\n};\nfunction createTextVNode(val) {\n return new VNode(undefined, undefined, undefined, String(val));\n}\n// optimized shallow clone\n// used for static nodes and slot nodes because they may be reused across\n// multiple renders, cloning them avoids errors when DOM manipulations rely\n// on their elm reference.\nfunction cloneVNode(vnode) {\n var cloned = new VNode(vnode.tag, vnode.data, \n // #7975\n // clone children array to avoid mutating original in case of cloning\n // a child.\n vnode.children && vnode.children.slice(), vnode.text, vnode.elm, vnode.context, vnode.componentOptions, vnode.asyncFactory);\n cloned.ns = vnode.ns;\n cloned.isStatic = vnode.isStatic;\n cloned.key = vnode.key;\n cloned.isComment = vnode.isComment;\n cloned.fnContext = vnode.fnContext;\n cloned.fnOptions = vnode.fnOptions;\n cloned.fnScopeId = vnode.fnScopeId;\n cloned.asyncMeta = vnode.asyncMeta;\n cloned.isCloned = true;\n return cloned;\n}\n\n/******************************************************************************\r\nCopyright (c) Microsoft Corporation.\r\n\r\nPermission to use, copy, modify, and/or distribute this software for any\r\npurpose with or without fee is hereby granted.\r\n\r\nTHE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH\r\nREGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY\r\nAND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,\r\nINDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM\r\nLOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR\r\nOTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR\r\nPERFORMANCE OF THIS SOFTWARE.\r\n***************************************************************************** */\r\n\r\nvar __assign = function() {\r\n __assign = Object.assign || function __assign(t) {\r\n for (var s, i = 1, n = arguments.length; i < n; i++) {\r\n s = arguments[i];\r\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];\r\n }\r\n return t;\r\n };\r\n return __assign.apply(this, arguments);\r\n};\r\n\r\ntypeof SuppressedError === \"function\" ? SuppressedError : function (error, suppressed, message) {\r\n var e = new Error(message);\r\n return e.name = \"SuppressedError\", e.error = error, e.suppressed = suppressed, e;\r\n};\n\nvar uid$2 = 0;\nvar pendingCleanupDeps = [];\nvar cleanupDeps = function () {\n for (var i = 0; i < pendingCleanupDeps.length; i++) {\n var dep = pendingCleanupDeps[i];\n dep.subs = dep.subs.filter(function (s) { return s; });\n dep._pending = false;\n }\n pendingCleanupDeps.length = 0;\n};\n/**\n * A dep is an observable that can have multiple\n * directives subscribing to it.\n * @internal\n */\nvar Dep = /** @class */ (function () {\n function Dep() {\n // pending subs cleanup\n this._pending = false;\n this.id = uid$2++;\n this.subs = [];\n }\n Dep.prototype.addSub = function (sub) {\n this.subs.push(sub);\n };\n Dep.prototype.removeSub = function (sub) {\n // #12696 deps with massive amount of subscribers are extremely slow to\n // clean up in Chromium\n // to workaround this, we unset the sub for now, and clear them on\n // next scheduler flush.\n this.subs[this.subs.indexOf(sub)] = null;\n if (!this._pending) {\n this._pending = true;\n pendingCleanupDeps.push(this);\n }\n };\n Dep.prototype.depend = function (info) {\n if (Dep.target) {\n Dep.target.addDep(this);\n if (process.env.NODE_ENV !== 'production' && info && Dep.target.onTrack) {\n Dep.target.onTrack(__assign({ effect: Dep.target }, info));\n }\n }\n };\n Dep.prototype.notify = function (info) {\n // stabilize the subscriber list first\n var subs = this.subs.filter(function (s) { return s; });\n if (process.env.NODE_ENV !== 'production' && !config.async) {\n // subs aren't sorted in scheduler if not running async\n // we need to sort them now to make sure they fire in correct\n // order\n subs.sort(function (a, b) { return a.id - b.id; });\n }\n for (var i = 0, l = subs.length; i < l; i++) {\n var sub = subs[i];\n if (process.env.NODE_ENV !== 'production' && info) {\n sub.onTrigger &&\n sub.onTrigger(__assign({ effect: subs[i] }, info));\n }\n sub.update();\n }\n };\n return Dep;\n}());\n// The current target watcher being evaluated.\n// This is globally unique because only one watcher\n// can be evaluated at a time.\nDep.target = null;\nvar targetStack = [];\nfunction pushTarget(target) {\n targetStack.push(target);\n Dep.target = target;\n}\nfunction popTarget() {\n targetStack.pop();\n Dep.target = targetStack[targetStack.length - 1];\n}\n\n/*\n * not type checking this file because flow doesn't play well with\n * dynamically accessing methods on Array prototype\n */\nvar arrayProto = Array.prototype;\nvar arrayMethods = Object.create(arrayProto);\nvar methodsToPatch = [\n 'push',\n 'pop',\n 'shift',\n 'unshift',\n 'splice',\n 'sort',\n 'reverse'\n];\n/**\n * Intercept mutating methods and emit events\n */\nmethodsToPatch.forEach(function (method) {\n // cache original method\n var original = arrayProto[method];\n def(arrayMethods, method, function mutator() {\n var args = [];\n for (var _i = 0; _i < arguments.length; _i++) {\n args[_i] = arguments[_i];\n }\n var result = original.apply(this, args);\n var ob = this.__ob__;\n var inserted;\n switch (method) {\n case 'push':\n case 'unshift':\n inserted = args;\n break;\n case 'splice':\n inserted = args.slice(2);\n break;\n }\n if (inserted)\n ob.observeArray(inserted);\n // notify change\n if (process.env.NODE_ENV !== 'production') {\n ob.dep.notify({\n type: \"array mutation\" /* TriggerOpTypes.ARRAY_MUTATION */,\n target: this,\n key: method\n });\n }\n else {\n ob.dep.notify();\n }\n return result;\n });\n});\n\nvar arrayKeys = Object.getOwnPropertyNames(arrayMethods);\nvar NO_INITIAL_VALUE = {};\n/**\n * In some cases we may want to disable observation inside a component's\n * update computation.\n */\nvar shouldObserve = true;\nfunction toggleObserving(value) {\n shouldObserve = value;\n}\n// ssr mock dep\nvar mockDep = {\n notify: noop,\n depend: noop,\n addSub: noop,\n removeSub: noop\n};\n/**\n * Observer class that is attached to each observed\n * object. Once attached, the observer converts the target\n * object's property keys into getter/setters that\n * collect dependencies and dispatch updates.\n */\nvar Observer = /** @class */ (function () {\n function Observer(value, shallow, mock) {\n if (shallow === void 0) { shallow = false; }\n if (mock === void 0) { mock = false; }\n this.value = value;\n this.shallow = shallow;\n this.mock = mock;\n // this.value = value\n this.dep = mock ? mockDep : new Dep();\n this.vmCount = 0;\n def(value, '__ob__', this);\n if (isArray(value)) {\n if (!mock) {\n if (hasProto) {\n value.__proto__ = arrayMethods;\n /* eslint-enable no-proto */\n }\n else {\n for (var i = 0, l = arrayKeys.length; i < l; i++) {\n var key = arrayKeys[i];\n def(value, key, arrayMethods[key]);\n }\n }\n }\n if (!shallow) {\n this.observeArray(value);\n }\n }\n else {\n /**\n * Walk through all properties and convert them into\n * getter/setters. This method should only be called when\n * value type is Object.\n */\n var keys = Object.keys(value);\n for (var i = 0; i < keys.length; i++) {\n var key = keys[i];\n defineReactive(value, key, NO_INITIAL_VALUE, undefined, shallow, mock);\n }\n }\n }\n /**\n * Observe a list of Array items.\n */\n Observer.prototype.observeArray = function (value) {\n for (var i = 0, l = value.length; i < l; i++) {\n observe(value[i], false, this.mock);\n }\n };\n return Observer;\n}());\n// helpers\n/**\n * Attempt to create an observer instance for a value,\n * returns the new observer if successfully observed,\n * or the existing observer if the value already has one.\n */\nfunction observe(value, shallow, ssrMockReactivity) {\n if (value && hasOwn(value, '__ob__') && value.__ob__ instanceof Observer) {\n return value.__ob__;\n }\n if (shouldObserve &&\n (ssrMockReactivity || !isServerRendering()) &&\n (isArray(value) || isPlainObject(value)) &&\n Object.isExtensible(value) &&\n !value.__v_skip /* ReactiveFlags.SKIP */ &&\n !isRef(value) &&\n !(value instanceof VNode)) {\n return new Observer(value, shallow, ssrMockReactivity);\n }\n}\n/**\n * Define a reactive property on an Object.\n */\nfunction defineReactive(obj, key, val, customSetter, shallow, mock, observeEvenIfShallow) {\n if (observeEvenIfShallow === void 0) { observeEvenIfShallow = false; }\n var dep = new Dep();\n var property = Object.getOwnPropertyDescriptor(obj, key);\n if (property && property.configurable === false) {\n return;\n }\n // cater for pre-defined getter/setters\n var getter = property && property.get;\n var setter = property && property.set;\n if ((!getter || setter) &&\n (val === NO_INITIAL_VALUE || arguments.length === 2)) {\n val = obj[key];\n }\n var childOb = shallow ? val && val.__ob__ : observe(val, false, mock);\n Object.defineProperty(obj, key, {\n enumerable: true,\n configurable: true,\n get: function reactiveGetter() {\n var value = getter ? getter.call(obj) : val;\n if (Dep.target) {\n if (process.env.NODE_ENV !== 'production') {\n dep.depend({\n target: obj,\n type: \"get\" /* TrackOpTypes.GET */,\n key: key\n });\n }\n else {\n dep.depend();\n }\n if (childOb) {\n childOb.dep.depend();\n if (isArray(value)) {\n dependArray(value);\n }\n }\n }\n return isRef(value) && !shallow ? value.value : value;\n },\n set: function reactiveSetter(newVal) {\n var value = getter ? getter.call(obj) : val;\n if (!hasChanged(value, newVal)) {\n return;\n }\n if (process.env.NODE_ENV !== 'production' && customSetter) {\n customSetter();\n }\n if (setter) {\n setter.call(obj, newVal);\n }\n else if (getter) {\n // #7981: for accessor properties without setter\n return;\n }\n else if (!shallow && isRef(value) && !isRef(newVal)) {\n value.value = newVal;\n return;\n }\n else {\n val = newVal;\n }\n childOb = shallow ? newVal && newVal.__ob__ : observe(newVal, false, mock);\n if (process.env.NODE_ENV !== 'production') {\n dep.notify({\n type: \"set\" /* TriggerOpTypes.SET */,\n target: obj,\n key: key,\n newValue: newVal,\n oldValue: value\n });\n }\n else {\n dep.notify();\n }\n }\n });\n return dep;\n}\nfunction set(target, key, val) {\n if (process.env.NODE_ENV !== 'production' && (isUndef(target) || isPrimitive(target))) {\n warn(\"Cannot set reactive property on undefined, null, or primitive value: \".concat(target));\n }\n if (isReadonly(target)) {\n process.env.NODE_ENV !== 'production' && warn(\"Set operation on key \\\"\".concat(key, \"\\\" failed: target is readonly.\"));\n return;\n }\n var ob = target.__ob__;\n if (isArray(target) && isValidArrayIndex(key)) {\n target.length = Math.max(target.length, key);\n target.splice(key, 1, val);\n // when mocking for SSR, array methods are not hijacked\n if (ob && !ob.shallow && ob.mock) {\n observe(val, false, true);\n }\n return val;\n }\n if (key in target && !(key in Object.prototype)) {\n target[key] = val;\n return val;\n }\n if (target._isVue || (ob && ob.vmCount)) {\n process.env.NODE_ENV !== 'production' &&\n warn('Avoid adding reactive properties to a Vue instance or its root $data ' +\n 'at runtime - declare it upfront in the data option.');\n return val;\n }\n if (!ob) {\n target[key] = val;\n return val;\n }\n defineReactive(ob.value, key, val, undefined, ob.shallow, ob.mock);\n if (process.env.NODE_ENV !== 'production') {\n ob.dep.notify({\n type: \"add\" /* TriggerOpTypes.ADD */,\n target: target,\n key: key,\n newValue: val,\n oldValue: undefined\n });\n }\n else {\n ob.dep.notify();\n }\n return val;\n}\nfunction del(target, key) {\n if (process.env.NODE_ENV !== 'production' && (isUndef(target) || isPrimitive(target))) {\n warn(\"Cannot delete reactive property on undefined, null, or primitive value: \".concat(target));\n }\n if (isArray(target) && isValidArrayIndex(key)) {\n target.splice(key, 1);\n return;\n }\n var ob = target.__ob__;\n if (target._isVue || (ob && ob.vmCount)) {\n process.env.NODE_ENV !== 'production' &&\n warn('Avoid deleting properties on a Vue instance or its root $data ' +\n '- just set it to null.');\n return;\n }\n if (isReadonly(target)) {\n process.env.NODE_ENV !== 'production' &&\n warn(\"Delete operation on key \\\"\".concat(key, \"\\\" failed: target is readonly.\"));\n return;\n }\n if (!hasOwn(target, key)) {\n return;\n }\n delete target[key];\n if (!ob) {\n return;\n }\n if (process.env.NODE_ENV !== 'production') {\n ob.dep.notify({\n type: \"delete\" /* TriggerOpTypes.DELETE */,\n target: target,\n key: key\n });\n }\n else {\n ob.dep.notify();\n }\n}\n/**\n * Collect dependencies on array elements when the array is touched, since\n * we cannot intercept array element access like property getters.\n */\nfunction dependArray(value) {\n for (var e = void 0, i = 0, l = value.length; i < l; i++) {\n e = value[i];\n if (e && e.__ob__) {\n e.__ob__.dep.depend();\n }\n if (isArray(e)) {\n dependArray(e);\n }\n }\n}\n\nfunction reactive(target) {\n makeReactive(target, false);\n return target;\n}\n/**\n * Return a shallowly-reactive copy of the original object, where only the root\n * level properties are reactive. It also does not auto-unwrap refs (even at the\n * root level).\n */\nfunction shallowReactive(target) {\n makeReactive(target, true);\n def(target, \"__v_isShallow\" /* ReactiveFlags.IS_SHALLOW */, true);\n return target;\n}\nfunction makeReactive(target, shallow) {\n // if trying to observe a readonly proxy, return the readonly version.\n if (!isReadonly(target)) {\n if (process.env.NODE_ENV !== 'production') {\n if (isArray(target)) {\n warn(\"Avoid using Array as root value for \".concat(shallow ? \"shallowReactive()\" : \"reactive()\", \" as it cannot be tracked in watch() or watchEffect(). Use \").concat(shallow ? \"shallowRef()\" : \"ref()\", \" instead. This is a Vue-2-only limitation.\"));\n }\n var existingOb = target && target.__ob__;\n if (existingOb && existingOb.shallow !== shallow) {\n warn(\"Target is already a \".concat(existingOb.shallow ? \"\" : \"non-\", \"shallow reactive object, and cannot be converted to \").concat(shallow ? \"\" : \"non-\", \"shallow.\"));\n }\n }\n var ob = observe(target, shallow, isServerRendering() /* ssr mock reactivity */);\n if (process.env.NODE_ENV !== 'production' && !ob) {\n if (target == null || isPrimitive(target)) {\n warn(\"value cannot be made reactive: \".concat(String(target)));\n }\n if (isCollectionType(target)) {\n warn(\"Vue 2 does not support reactive collection types such as Map or Set.\");\n }\n }\n }\n}\nfunction isReactive(value) {\n if (isReadonly(value)) {\n return isReactive(value[\"__v_raw\" /* ReactiveFlags.RAW */]);\n }\n return !!(value && value.__ob__);\n}\nfunction isShallow(value) {\n return !!(value && value.__v_isShallow);\n}\nfunction isReadonly(value) {\n return !!(value && value.__v_isReadonly);\n}\nfunction isProxy(value) {\n return isReactive(value) || isReadonly(value);\n}\nfunction toRaw(observed) {\n var raw = observed && observed[\"__v_raw\" /* ReactiveFlags.RAW */];\n return raw ? toRaw(raw) : observed;\n}\nfunction markRaw(value) {\n // non-extensible objects won't be observed anyway\n if (Object.isExtensible(value)) {\n def(value, \"__v_skip\" /* ReactiveFlags.SKIP */, true);\n }\n return value;\n}\n/**\n * @internal\n */\nfunction isCollectionType(value) {\n var type = toRawType(value);\n return (type === 'Map' || type === 'WeakMap' || type === 'Set' || type === 'WeakSet');\n}\n\n/**\n * @internal\n */\nvar RefFlag = \"__v_isRef\";\nfunction isRef(r) {\n return !!(r && r.__v_isRef === true);\n}\nfunction ref$1(value) {\n return createRef(value, false);\n}\nfunction shallowRef(value) {\n return createRef(value, true);\n}\nfunction createRef(rawValue, shallow) {\n if (isRef(rawValue)) {\n return rawValue;\n }\n var ref = {};\n def(ref, RefFlag, true);\n def(ref, \"__v_isShallow\" /* ReactiveFlags.IS_SHALLOW */, shallow);\n def(ref, 'dep', defineReactive(ref, 'value', rawValue, null, shallow, isServerRendering()));\n return ref;\n}\nfunction triggerRef(ref) {\n if (process.env.NODE_ENV !== 'production' && !ref.dep) {\n warn(\"received object is not a triggerable ref.\");\n }\n if (process.env.NODE_ENV !== 'production') {\n ref.dep &&\n ref.dep.notify({\n type: \"set\" /* TriggerOpTypes.SET */,\n target: ref,\n key: 'value'\n });\n }\n else {\n ref.dep && ref.dep.notify();\n }\n}\nfunction unref(ref) {\n return isRef(ref) ? ref.value : ref;\n}\nfunction proxyRefs(objectWithRefs) {\n if (isReactive(objectWithRefs)) {\n return objectWithRefs;\n }\n var proxy = {};\n var keys = Object.keys(objectWithRefs);\n for (var i = 0; i < keys.length; i++) {\n proxyWithRefUnwrap(proxy, objectWithRefs, keys[i]);\n }\n return proxy;\n}\nfunction proxyWithRefUnwrap(target, source, key) {\n Object.defineProperty(target, key, {\n enumerable: true,\n configurable: true,\n get: function () {\n var val = source[key];\n if (isRef(val)) {\n return val.value;\n }\n else {\n var ob = val && val.__ob__;\n if (ob)\n ob.dep.depend();\n return val;\n }\n },\n set: function (value) {\n var oldValue = source[key];\n if (isRef(oldValue) && !isRef(value)) {\n oldValue.value = value;\n }\n else {\n source[key] = value;\n }\n }\n });\n}\nfunction customRef(factory) {\n var dep = new Dep();\n var _a = factory(function () {\n if (process.env.NODE_ENV !== 'production') {\n dep.depend({\n target: ref,\n type: \"get\" /* TrackOpTypes.GET */,\n key: 'value'\n });\n }\n else {\n dep.depend();\n }\n }, function () {\n if (process.env.NODE_ENV !== 'production') {\n dep.notify({\n target: ref,\n type: \"set\" /* TriggerOpTypes.SET */,\n key: 'value'\n });\n }\n else {\n dep.notify();\n }\n }), get = _a.get, set = _a.set;\n var ref = {\n get value() {\n return get();\n },\n set value(newVal) {\n set(newVal);\n }\n };\n def(ref, RefFlag, true);\n return ref;\n}\nfunction toRefs(object) {\n if (process.env.NODE_ENV !== 'production' && !isReactive(object)) {\n warn(\"toRefs() expects a reactive object but received a plain one.\");\n }\n var ret = isArray(object) ? new Array(object.length) : {};\n for (var key in object) {\n ret[key] = toRef(object, key);\n }\n return ret;\n}\nfunction toRef(object, key, defaultValue) {\n var val = object[key];\n if (isRef(val)) {\n return val;\n }\n var ref = {\n get value() {\n var val = object[key];\n return val === undefined ? defaultValue : val;\n },\n set value(newVal) {\n object[key] = newVal;\n }\n };\n def(ref, RefFlag, true);\n return ref;\n}\n\nvar rawToReadonlyFlag = \"__v_rawToReadonly\";\nvar rawToShallowReadonlyFlag = \"__v_rawToShallowReadonly\";\nfunction readonly(target) {\n return createReadonly(target, false);\n}\nfunction createReadonly(target, shallow) {\n if (!isPlainObject(target)) {\n if (process.env.NODE_ENV !== 'production') {\n if (isArray(target)) {\n warn(\"Vue 2 does not support readonly arrays.\");\n }\n else if (isCollectionType(target)) {\n warn(\"Vue 2 does not support readonly collection types such as Map or Set.\");\n }\n else {\n warn(\"value cannot be made readonly: \".concat(typeof target));\n }\n }\n return target;\n }\n if (process.env.NODE_ENV !== 'production' && !Object.isExtensible(target)) {\n warn(\"Vue 2 does not support creating readonly proxy for non-extensible object.\");\n }\n // already a readonly object\n if (isReadonly(target)) {\n return target;\n }\n // already has a readonly proxy\n var existingFlag = shallow ? rawToShallowReadonlyFlag : rawToReadonlyFlag;\n var existingProxy = target[existingFlag];\n if (existingProxy) {\n return existingProxy;\n }\n var proxy = Object.create(Object.getPrototypeOf(target));\n def(target, existingFlag, proxy);\n def(proxy, \"__v_isReadonly\" /* ReactiveFlags.IS_READONLY */, true);\n def(proxy, \"__v_raw\" /* ReactiveFlags.RAW */, target);\n if (isRef(target)) {\n def(proxy, RefFlag, true);\n }\n if (shallow || isShallow(target)) {\n def(proxy, \"__v_isShallow\" /* ReactiveFlags.IS_SHALLOW */, true);\n }\n var keys = Object.keys(target);\n for (var i = 0; i < keys.length; i++) {\n defineReadonlyProperty(proxy, target, keys[i], shallow);\n }\n return proxy;\n}\nfunction defineReadonlyProperty(proxy, target, key, shallow) {\n Object.defineProperty(proxy, key, {\n enumerable: true,\n configurable: true,\n get: function () {\n var val = target[key];\n return shallow || !isPlainObject(val) ? val : readonly(val);\n },\n set: function () {\n process.env.NODE_ENV !== 'production' &&\n warn(\"Set operation on key \\\"\".concat(key, \"\\\" failed: target is readonly.\"));\n }\n });\n}\n/**\n * Returns a reactive-copy of the original object, where only the root level\n * properties are readonly, and does NOT unwrap refs nor recursively convert\n * returned properties.\n * This is used for creating the props proxy object for stateful components.\n */\nfunction shallowReadonly(target) {\n return createReadonly(target, true);\n}\n\nfunction computed(getterOrOptions, debugOptions) {\n var getter;\n var setter;\n var onlyGetter = isFunction(getterOrOptions);\n if (onlyGetter) {\n getter = getterOrOptions;\n setter = process.env.NODE_ENV !== 'production'\n ? function () {\n warn('Write operation failed: computed value is readonly');\n }\n : noop;\n }\n else {\n getter = getterOrOptions.get;\n setter = getterOrOptions.set;\n }\n var watcher = isServerRendering()\n ? null\n : new Watcher(currentInstance, getter, noop, { lazy: true });\n if (process.env.NODE_ENV !== 'production' && watcher && debugOptions) {\n watcher.onTrack = debugOptions.onTrack;\n watcher.onTrigger = debugOptions.onTrigger;\n }\n var ref = {\n // some libs rely on the presence effect for checking computed refs\n // from normal refs, but the implementation doesn't matter\n effect: watcher,\n get value() {\n if (watcher) {\n if (watcher.dirty) {\n watcher.evaluate();\n }\n if (Dep.target) {\n if (process.env.NODE_ENV !== 'production' && Dep.target.onTrack) {\n Dep.target.onTrack({\n effect: Dep.target,\n target: ref,\n type: \"get\" /* TrackOpTypes.GET */,\n key: 'value'\n });\n }\n watcher.depend();\n }\n return watcher.value;\n }\n else {\n return getter();\n }\n },\n set value(newVal) {\n setter(newVal);\n }\n };\n def(ref, RefFlag, true);\n def(ref, \"__v_isReadonly\" /* ReactiveFlags.IS_READONLY */, onlyGetter);\n return ref;\n}\n\nvar WATCHER = \"watcher\";\nvar WATCHER_CB = \"\".concat(WATCHER, \" callback\");\nvar WATCHER_GETTER = \"\".concat(WATCHER, \" getter\");\nvar WATCHER_CLEANUP = \"\".concat(WATCHER, \" cleanup\");\n// Simple effect.\nfunction watchEffect(effect, options) {\n return doWatch(effect, null, options);\n}\nfunction watchPostEffect(effect, options) {\n return doWatch(effect, null, (process.env.NODE_ENV !== 'production'\n ? __assign(__assign({}, options), { flush: 'post' }) : { flush: 'post' }));\n}\nfunction watchSyncEffect(effect, options) {\n return doWatch(effect, null, (process.env.NODE_ENV !== 'production'\n ? __assign(__assign({}, options), { flush: 'sync' }) : { flush: 'sync' }));\n}\n// initial value for watchers to trigger on undefined initial values\nvar INITIAL_WATCHER_VALUE = {};\n// implementation\nfunction watch(source, cb, options) {\n if (process.env.NODE_ENV !== 'production' && typeof cb !== 'function') {\n warn(\"`watch(fn, options?)` signature has been moved to a separate API. \" +\n \"Use `watchEffect(fn, options?)` instead. `watch` now only \" +\n \"supports `watch(source, cb, options?) signature.\");\n }\n return doWatch(source, cb, options);\n}\nfunction doWatch(source, cb, _a) {\n var _b = _a === void 0 ? emptyObject : _a, immediate = _b.immediate, deep = _b.deep, _c = _b.flush, flush = _c === void 0 ? 'pre' : _c, onTrack = _b.onTrack, onTrigger = _b.onTrigger;\n if (process.env.NODE_ENV !== 'production' && !cb) {\n if (immediate !== undefined) {\n warn(\"watch() \\\"immediate\\\" option is only respected when using the \" +\n \"watch(source, callback, options?) signature.\");\n }\n if (deep !== undefined) {\n warn(\"watch() \\\"deep\\\" option is only respected when using the \" +\n \"watch(source, callback, options?) signature.\");\n }\n }\n var warnInvalidSource = function (s) {\n warn(\"Invalid watch source: \".concat(s, \". A watch source can only be a getter/effect \") +\n \"function, a ref, a reactive object, or an array of these types.\");\n };\n var instance = currentInstance;\n var call = function (fn, type, args) {\n if (args === void 0) { args = null; }\n var res = invokeWithErrorHandling(fn, null, args, instance, type);\n if (deep && res && res.__ob__)\n res.__ob__.dep.depend();\n return res;\n };\n var getter;\n var forceTrigger = false;\n var isMultiSource = false;\n if (isRef(source)) {\n getter = function () { return source.value; };\n forceTrigger = isShallow(source);\n }\n else if (isReactive(source)) {\n getter = function () {\n source.__ob__.dep.depend();\n return source;\n };\n deep = true;\n }\n else if (isArray(source)) {\n isMultiSource = true;\n forceTrigger = source.some(function (s) { return isReactive(s) || isShallow(s); });\n getter = function () {\n return source.map(function (s) {\n if (isRef(s)) {\n return s.value;\n }\n else if (isReactive(s)) {\n s.__ob__.dep.depend();\n return traverse(s);\n }\n else if (isFunction(s)) {\n return call(s, WATCHER_GETTER);\n }\n else {\n process.env.NODE_ENV !== 'production' && warnInvalidSource(s);\n }\n });\n };\n }\n else if (isFunction(source)) {\n if (cb) {\n // getter with cb\n getter = function () { return call(source, WATCHER_GETTER); };\n }\n else {\n // no cb -> simple effect\n getter = function () {\n if (instance && instance._isDestroyed) {\n return;\n }\n if (cleanup) {\n cleanup();\n }\n return call(source, WATCHER, [onCleanup]);\n };\n }\n }\n else {\n getter = noop;\n process.env.NODE_ENV !== 'production' && warnInvalidSource(source);\n }\n if (cb && deep) {\n var baseGetter_1 = getter;\n getter = function () { return traverse(baseGetter_1()); };\n }\n var cleanup;\n var onCleanup = function (fn) {\n cleanup = watcher.onStop = function () {\n call(fn, WATCHER_CLEANUP);\n };\n };\n // in SSR there is no need to setup an actual effect, and it should be noop\n // unless it's eager\n if (isServerRendering()) {\n // we will also not call the invalidate callback (+ runner is not set up)\n onCleanup = noop;\n if (!cb) {\n getter();\n }\n else if (immediate) {\n call(cb, WATCHER_CB, [\n getter(),\n isMultiSource ? [] : undefined,\n onCleanup\n ]);\n }\n return noop;\n }\n var watcher = new Watcher(currentInstance, getter, noop, {\n lazy: true\n });\n watcher.noRecurse = !cb;\n var oldValue = isMultiSource ? [] : INITIAL_WATCHER_VALUE;\n // overwrite default run\n watcher.run = function () {\n if (!watcher.active) {\n return;\n }\n if (cb) {\n // watch(source, cb)\n var newValue = watcher.get();\n if (deep ||\n forceTrigger ||\n (isMultiSource\n ? newValue.some(function (v, i) {\n return hasChanged(v, oldValue[i]);\n })\n : hasChanged(newValue, oldValue))) {\n // cleanup before running cb again\n if (cleanup) {\n cleanup();\n }\n call(cb, WATCHER_CB, [\n newValue,\n // pass undefined as the old value when it's changed for the first time\n oldValue === INITIAL_WATCHER_VALUE ? undefined : oldValue,\n onCleanup\n ]);\n oldValue = newValue;\n }\n }\n else {\n // watchEffect\n watcher.get();\n }\n };\n if (flush === 'sync') {\n watcher.update = watcher.run;\n }\n else if (flush === 'post') {\n watcher.post = true;\n watcher.update = function () { return queueWatcher(watcher); };\n }\n else {\n // pre\n watcher.update = function () {\n if (instance && instance === currentInstance && !instance._isMounted) {\n // pre-watcher triggered before\n var buffer = instance._preWatchers || (instance._preWatchers = []);\n if (buffer.indexOf(watcher) < 0)\n buffer.push(watcher);\n }\n else {\n queueWatcher(watcher);\n }\n };\n }\n if (process.env.NODE_ENV !== 'production') {\n watcher.onTrack = onTrack;\n watcher.onTrigger = onTrigger;\n }\n // initial run\n if (cb) {\n if (immediate) {\n watcher.run();\n }\n else {\n oldValue = watcher.get();\n }\n }\n else if (flush === 'post' && instance) {\n instance.$once('hook:mounted', function () { return watcher.get(); });\n }\n else {\n watcher.get();\n }\n return function () {\n watcher.teardown();\n };\n}\n\nvar activeEffectScope;\nvar EffectScope = /** @class */ (function () {\n function EffectScope(detached) {\n if (detached === void 0) { detached = false; }\n this.detached = detached;\n /**\n * @internal\n */\n this.active = true;\n /**\n * @internal\n */\n this.effects = [];\n /**\n * @internal\n */\n this.cleanups = [];\n this.parent = activeEffectScope;\n if (!detached && activeEffectScope) {\n this.index =\n (activeEffectScope.scopes || (activeEffectScope.scopes = [])).push(this) - 1;\n }\n }\n EffectScope.prototype.run = function (fn) {\n if (this.active) {\n var currentEffectScope = activeEffectScope;\n try {\n activeEffectScope = this;\n return fn();\n }\n finally {\n activeEffectScope = currentEffectScope;\n }\n }\n else if (process.env.NODE_ENV !== 'production') {\n warn(\"cannot run an inactive effect scope.\");\n }\n };\n /**\n * This should only be called on non-detached scopes\n * @internal\n */\n EffectScope.prototype.on = function () {\n activeEffectScope = this;\n };\n /**\n * This should only be called on non-detached scopes\n * @internal\n */\n EffectScope.prototype.off = function () {\n activeEffectScope = this.parent;\n };\n EffectScope.prototype.stop = function (fromParent) {\n if (this.active) {\n var i = void 0, l = void 0;\n for (i = 0, l = this.effects.length; i < l; i++) {\n this.effects[i].teardown();\n }\n for (i = 0, l = this.cleanups.length; i < l; i++) {\n this.cleanups[i]();\n }\n if (this.scopes) {\n for (i = 0, l = this.scopes.length; i < l; i++) {\n this.scopes[i].stop(true);\n }\n }\n // nested scope, dereference from parent to avoid memory leaks\n if (!this.detached && this.parent && !fromParent) {\n // optimized O(1) removal\n var last = this.parent.scopes.pop();\n if (last && last !== this) {\n this.parent.scopes[this.index] = last;\n last.index = this.index;\n }\n }\n this.parent = undefined;\n this.active = false;\n }\n };\n return EffectScope;\n}());\nfunction effectScope(detached) {\n return new EffectScope(detached);\n}\n/**\n * @internal\n */\nfunction recordEffectScope(effect, scope) {\n if (scope === void 0) { scope = activeEffectScope; }\n if (scope && scope.active) {\n scope.effects.push(effect);\n }\n}\nfunction getCurrentScope() {\n return activeEffectScope;\n}\nfunction onScopeDispose(fn) {\n if (activeEffectScope) {\n activeEffectScope.cleanups.push(fn);\n }\n else if (process.env.NODE_ENV !== 'production') {\n warn(\"onScopeDispose() is called when there is no active effect scope\" +\n \" to be associated with.\");\n }\n}\n\nfunction provide(key, value) {\n if (!currentInstance) {\n if (process.env.NODE_ENV !== 'production') {\n warn(\"provide() can only be used inside setup().\");\n }\n }\n else {\n // TS doesn't allow symbol as index type\n resolveProvided(currentInstance)[key] = value;\n }\n}\nfunction resolveProvided(vm) {\n // by default an instance inherits its parent's provides object\n // but when it needs to provide values of its own, it creates its\n // own provides object using parent provides object as prototype.\n // this way in `inject` we can simply look up injections from direct\n // parent and let the prototype chain do the work.\n var existing = vm._provided;\n var parentProvides = vm.$parent && vm.$parent._provided;\n if (parentProvides === existing) {\n return (vm._provided = Object.create(parentProvides));\n }\n else {\n return existing;\n }\n}\nfunction inject(key, defaultValue, treatDefaultAsFactory) {\n if (treatDefaultAsFactory === void 0) { treatDefaultAsFactory = false; }\n // fallback to `currentRenderingInstance` so that this can be called in\n // a functional component\n var instance = currentInstance;\n if (instance) {\n // #2400\n // to support `app.use` plugins,\n // fallback to appContext's `provides` if the instance is at root\n var provides = instance.$parent && instance.$parent._provided;\n if (provides && key in provides) {\n // TS doesn't allow symbol as index type\n return provides[key];\n }\n else if (arguments.length > 1) {\n return treatDefaultAsFactory && isFunction(defaultValue)\n ? defaultValue.call(instance)\n : defaultValue;\n }\n else if (process.env.NODE_ENV !== 'production') {\n warn(\"injection \\\"\".concat(String(key), \"\\\" not found.\"));\n }\n }\n else if (process.env.NODE_ENV !== 'production') {\n warn(\"inject() can only be used inside setup() or functional components.\");\n }\n}\n\nvar normalizeEvent = cached(function (name) {\n var passive = name.charAt(0) === '&';\n name = passive ? name.slice(1) : name;\n var once = name.charAt(0) === '~'; // Prefixed last, checked first\n name = once ? name.slice(1) : name;\n var capture = name.charAt(0) === '!';\n name = capture ? name.slice(1) : name;\n return {\n name: name,\n once: once,\n capture: capture,\n passive: passive\n };\n});\nfunction createFnInvoker(fns, vm) {\n function invoker() {\n var fns = invoker.fns;\n if (isArray(fns)) {\n var cloned = fns.slice();\n for (var i = 0; i < cloned.length; i++) {\n invokeWithErrorHandling(cloned[i], null, arguments, vm, \"v-on handler\");\n }\n }\n else {\n // return handler return value for single handlers\n return invokeWithErrorHandling(fns, null, arguments, vm, \"v-on handler\");\n }\n }\n invoker.fns = fns;\n return invoker;\n}\nfunction updateListeners(on, oldOn, add, remove, createOnceHandler, vm) {\n var name, cur, old, event;\n for (name in on) {\n cur = on[name];\n old = oldOn[name];\n event = normalizeEvent(name);\n if (isUndef(cur)) {\n process.env.NODE_ENV !== 'production' &&\n warn(\"Invalid handler for event \\\"\".concat(event.name, \"\\\": got \") + String(cur), vm);\n }\n else if (isUndef(old)) {\n if (isUndef(cur.fns)) {\n cur = on[name] = createFnInvoker(cur, vm);\n }\n if (isTrue(event.once)) {\n cur = on[name] = createOnceHandler(event.name, cur, event.capture);\n }\n add(event.name, cur, event.capture, event.passive, event.params);\n }\n else if (cur !== old) {\n old.fns = cur;\n on[name] = old;\n }\n }\n for (name in oldOn) {\n if (isUndef(on[name])) {\n event = normalizeEvent(name);\n remove(event.name, oldOn[name], event.capture);\n }\n }\n}\n\nfunction mergeVNodeHook(def, hookKey, hook) {\n if (def instanceof VNode) {\n def = def.data.hook || (def.data.hook = {});\n }\n var invoker;\n var oldHook = def[hookKey];\n function wrappedHook() {\n hook.apply(this, arguments);\n // important: remove merged hook to ensure it's called only once\n // and prevent memory leak\n remove$2(invoker.fns, wrappedHook);\n }\n if (isUndef(oldHook)) {\n // no existing hook\n invoker = createFnInvoker([wrappedHook]);\n }\n else {\n /* istanbul ignore if */\n if (isDef(oldHook.fns) && isTrue(oldHook.merged)) {\n // already a merged invoker\n invoker = oldHook;\n invoker.fns.push(wrappedHook);\n }\n else {\n // existing plain hook\n invoker = createFnInvoker([oldHook, wrappedHook]);\n }\n }\n invoker.merged = true;\n def[hookKey] = invoker;\n}\n\nfunction extractPropsFromVNodeData(data, Ctor, tag) {\n // we are only extracting raw values here.\n // validation and default values are handled in the child\n // component itself.\n var propOptions = Ctor.options.props;\n if (isUndef(propOptions)) {\n return;\n }\n var res = {};\n var attrs = data.attrs, props = data.props;\n if (isDef(attrs) || isDef(props)) {\n for (var key in propOptions) {\n var altKey = hyphenate(key);\n if (process.env.NODE_ENV !== 'production') {\n var keyInLowerCase = key.toLowerCase();\n if (key !== keyInLowerCase && attrs && hasOwn(attrs, keyInLowerCase)) {\n tip(\"Prop \\\"\".concat(keyInLowerCase, \"\\\" is passed to component \") +\n \"\".concat(formatComponentName(\n // @ts-expect-error tag is string\n tag || Ctor), \", but the declared prop name is\") +\n \" \\\"\".concat(key, \"\\\". \") +\n \"Note that HTML attributes are case-insensitive and camelCased \" +\n \"props need to use their kebab-case equivalents when using in-DOM \" +\n \"templates. You should probably use \\\"\".concat(altKey, \"\\\" instead of \\\"\").concat(key, \"\\\".\"));\n }\n }\n checkProp(res, props, key, altKey, true) ||\n checkProp(res, attrs, key, altKey, false);\n }\n }\n return res;\n}\nfunction checkProp(res, hash, key, altKey, preserve) {\n if (isDef(hash)) {\n if (hasOwn(hash, key)) {\n res[key] = hash[key];\n if (!preserve) {\n delete hash[key];\n }\n return true;\n }\n else if (hasOwn(hash, altKey)) {\n res[key] = hash[altKey];\n if (!preserve) {\n delete hash[altKey];\n }\n return true;\n }\n }\n return false;\n}\n\n// The template compiler attempts to minimize the need for normalization by\n// statically analyzing the template at compile time.\n//\n// For plain HTML markup, normalization can be completely skipped because the\n// generated render function is guaranteed to return Array. There are\n// two cases where extra normalization is needed:\n// 1. When the children contains components - because a functional component\n// may return an Array instead of a single root. In this case, just a simple\n// normalization is needed - if any child is an Array, we flatten the whole\n// thing with Array.prototype.concat. It is guaranteed to be only 1-level deep\n// because functional components already normalize their own children.\nfunction simpleNormalizeChildren(children) {\n for (var i = 0; i < children.length; i++) {\n if (isArray(children[i])) {\n return Array.prototype.concat.apply([], children);\n }\n }\n return children;\n}\n// 2. When the children contains constructs that always generated nested Arrays,\n// e.g.