Files
nuqloud-ai/js/educai-bot-picker.mjs.map
T
Pascal Kienast 0739d3da6a Initial open-source release of Talk AI
Talk AI is a multi-bot AI assistant manager for Nextcloud Talk:
per-bot prompts and models, agentic tool calling (MCP + built-in
tools), RAG over Nextcloud files, room-document search, vision and
speech-to-text attachments, persistent bot wikis, approval workflows,
rate limiting, and multi-provider LLM support (any OpenAI-compatible
endpoint).

Developed within EDUC - the European Digital UniverCity
(https://educalliance.eu), where it runs as the 'EDUC AI' assistant on
the alliance-wide Nextcloud portal. This public repository is the
upstream point of truth; deployment-specific tools plug in via the
tool-provider extension point (docs/TOOL_PROVIDERS.md).

License: AGPL-3.0-or-later.
2026-07-08 21:13:13 +02:00

1 line
232 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"version":3,"file":"educai-bot-picker.mjs","sources":["../node_modules/@nextcloud/vue/dist/Components/NcNoteCard.mjs","../node_modules/@nextcloud/vue/dist/chunks/customPickerElements-DLFtgReB.mjs","../node_modules/@nextcloud/vue/dist/chunks/referencePickerModal-B69WouiU.mjs","../node_modules/@nextcloud/vue/dist/chunks/useCopy-DDDe5RYH.mjs","../node_modules/@nextcloud/vue/dist/chunks/NcRichText-ByLPwUvM.mjs","../node_modules/@nextcloud/vue/dist/Components/NcChip.mjs","../node_modules/vue-material-design-icons/Robot.vue","../node_modules/vue-material-design-icons/Close.vue","../node_modules/vue-material-design-icons/BookOpenVariant.vue","../src/components/BotPickerModal.vue","../src/components/BotPickerElement.vue","../src/bot-picker.js"],"sourcesContent":["import '../assets/NcNoteCard-CwNXZ4vV.css';\nimport { n as normalizeComponent } from \"../chunks/_plugin-vue2_normalizer-DU4iP6Vu.mjs\";\nimport { a as isLegacy32 } from \"../chunks/legacy-DV3mGZdh.mjs\";\nconst _sfc_main$4 = {\n name: \"AlertIcon\",\n emits: [\"click\"],\n props: {\n title: {\n type: String\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n};\nvar _sfc_render$4 = function render() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"span\", _vm._b({ staticClass: \"material-design-icon alert-icon\", attrs: { \"aria-hidden\": _vm.title ? null : \"true\", \"aria-label\": _vm.title, \"role\": \"img\" }, on: { \"click\": function($event) {\n return _vm.$emit(\"click\", $event);\n } } }, \"span\", _vm.$attrs, false), [_c(\"svg\", { staticClass: \"material-design-icon__svg\", attrs: { \"fill\": _vm.fillColor, \"width\": _vm.size, \"height\": _vm.size, \"viewBox\": \"0 0 24 24\" } }, [_c(\"path\", { attrs: { \"d\": \"M13 14H11V9H13M13 18H11V16H13M1 21H23L12 2L1 21Z\" } }, [_vm.title ? _c(\"title\", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);\n};\nvar _sfc_staticRenderFns$4 = [];\nvar __component__$4 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$4,\n _sfc_render$4,\n _sfc_staticRenderFns$4,\n false,\n null,\n null\n);\nconst Alert = __component__$4.exports;\nconst _sfc_main$3 = {\n name: \"AlertDecagramIcon\",\n emits: [\"click\"],\n props: {\n title: {\n type: String\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n};\nvar _sfc_render$3 = function render2() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"span\", _vm._b({ staticClass: \"material-design-icon alert-decagram-icon\", attrs: { \"aria-hidden\": _vm.title ? null : \"true\", \"aria-label\": _vm.title, \"role\": \"img\" }, on: { \"click\": function($event) {\n return _vm.$emit(\"click\", $event);\n } } }, \"span\", _vm.$attrs, false), [_c(\"svg\", { staticClass: \"material-design-icon__svg\", attrs: { \"fill\": _vm.fillColor, \"width\": _vm.size, \"height\": _vm.size, \"viewBox\": \"0 0 24 24\" } }, [_c(\"path\", { attrs: { \"d\": \"M23,12L20.56,9.22L20.9,5.54L17.29,4.72L15.4,1.54L12,3L8.6,1.54L6.71,4.72L3.1,5.53L3.44,9.21L1,12L3.44,14.78L3.1,18.47L6.71,19.29L8.6,22.47L12,21L15.4,22.46L17.29,19.28L20.9,18.46L20.56,14.78L23,12M13,17H11V15H13V17M13,13H11V7H13V13Z\" } }, [_vm.title ? _c(\"title\", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);\n};\nvar _sfc_staticRenderFns$3 = [];\nvar __component__$3 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$3,\n _sfc_render$3,\n _sfc_staticRenderFns$3,\n false,\n null,\n null\n);\nconst AlertDecagram = __component__$3.exports;\nconst _sfc_main$2 = {\n name: \"CheckboxMarkedCircleIcon\",\n emits: [\"click\"],\n props: {\n title: {\n type: String\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n};\nvar _sfc_render$2 = function render3() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"span\", _vm._b({ staticClass: \"material-design-icon checkbox-marked-circle-icon\", attrs: { \"aria-hidden\": _vm.title ? null : \"true\", \"aria-label\": _vm.title, \"role\": \"img\" }, on: { \"click\": function($event) {\n return _vm.$emit(\"click\", $event);\n } } }, \"span\", _vm.$attrs, false), [_c(\"svg\", { staticClass: \"material-design-icon__svg\", attrs: { \"fill\": _vm.fillColor, \"width\": _vm.size, \"height\": _vm.size, \"viewBox\": \"0 0 24 24\" } }, [_c(\"path\", { attrs: { \"d\": \"M10,17L5,12L6.41,10.58L10,14.17L17.59,6.58L19,8M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\" } }, [_vm.title ? _c(\"title\", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);\n};\nvar _sfc_staticRenderFns$2 = [];\nvar __component__$2 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$2,\n _sfc_render$2,\n _sfc_staticRenderFns$2,\n false,\n null,\n null\n);\nconst CheckboxMarkedCircle = __component__$2.exports;\nconst _sfc_main$1 = {\n name: \"InformationIcon\",\n emits: [\"click\"],\n props: {\n title: {\n type: String\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n};\nvar _sfc_render$1 = function render4() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"span\", _vm._b({ staticClass: \"material-design-icon information-icon\", attrs: { \"aria-hidden\": _vm.title ? null : \"true\", \"aria-label\": _vm.title, \"role\": \"img\" }, on: { \"click\": function($event) {\n return _vm.$emit(\"click\", $event);\n } } }, \"span\", _vm.$attrs, false), [_c(\"svg\", { staticClass: \"material-design-icon__svg\", attrs: { \"fill\": _vm.fillColor, \"width\": _vm.size, \"height\": _vm.size, \"viewBox\": \"0 0 24 24\" } }, [_c(\"path\", { attrs: { \"d\": \"M13,9H11V7H13M13,17H11V11H13M12,2A10,10 0 0,0 2,12A10,10 0 0,0 12,22A10,10 0 0,0 22,12A10,10 0 0,0 12,2Z\" } }, [_vm.title ? _c(\"title\", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);\n};\nvar _sfc_staticRenderFns$1 = [];\nvar __component__$1 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$1,\n _sfc_render$1,\n _sfc_staticRenderFns$1,\n false,\n null,\n null\n);\nconst Information = __component__$1.exports;\nconst _sfc_main = {\n name: \"NcNoteCard\",\n props: {\n /**\n * Type or severity of the message\n */\n type: {\n type: String,\n default: \"warning\",\n validator: (type) => [\"success\", \"info\", \"warning\", \"error\"].includes(type)\n },\n /**\n * Enforce the `alert` role on the note card.\n *\n * The [`alert` role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/alert_role)\n * should only be used for information that requires the user's immediate attention.\n */\n showAlert: {\n type: Boolean,\n default: false\n },\n /**\n * Optional text to show as a heading of the note card\n */\n heading: {\n type: String,\n default: \"\"\n },\n /**\n * The message text of the note card\n */\n text: {\n type: String,\n default: \"\"\n }\n },\n setup() {\n return {\n isLegacy32\n };\n },\n computed: {\n shouldShowAlert() {\n return this.showAlert || this.type === \"error\";\n },\n icon() {\n switch (this.type) {\n case \"error\":\n return AlertDecagram;\n case \"success\":\n return CheckboxMarkedCircle;\n case \"info\":\n return Information;\n case \"warning\":\n return Alert;\n default:\n return Alert;\n }\n }\n }\n};\nvar _sfc_render = function render5() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"div\", { staticClass: \"notecard\", class: {\n [`notecard--${_vm.type}`]: _vm.type,\n \"notecard--legacy\": _vm.isLegacy32\n }, attrs: { \"role\": _vm.shouldShowAlert ? \"alert\" : \"note\" } }, [_vm._t(\"icon\", function() {\n return [_c(_vm.icon, { tag: \"component\", staticClass: \"notecard__icon\", class: { \"notecard__icon--heading\": _vm.heading }, attrs: { \"fill-color\": \"var(--note-theme)\", \"size\": 20 } })];\n }), _c(\"div\", [_vm.heading ? _c(\"p\", { staticClass: \"notecard__heading\" }, [_vm._v(\" \" + _vm._s(_vm.heading) + \" \")]) : _vm._e(), _vm._t(\"default\", function() {\n return [_c(\"p\", { staticClass: \"notecard__text\" }, [_vm._v(\" \" + _vm._s(_vm.text) + \" \")])];\n })], 2)], 2);\n};\nvar _sfc_staticRenderFns = [];\nvar __component__ = /* @__PURE__ */ normalizeComponent(\n _sfc_main,\n _sfc_render,\n _sfc_staticRenderFns,\n false,\n null,\n \"f656e861\"\n);\nconst NcNoteCard = __component__.exports;\nexport {\n NcNoteCard as default\n};\n//# sourceMappingURL=NcNoteCard.mjs.map\n","import { l as logger } from \"./logger-D3RVzcfQ.mjs\";\nwindow._vue_richtext_widgets ??= {};\nwindow._registerWidget ??= (id, callback, onDestroy, props) => {\n registerWidget(id, callback, onDestroy, props);\n};\nfunction registerWidget(id, callback, onDestroy = () => {\n}, props) {\n const propsWithDefaults = {\n hasInteractiveView: true,\n fullWidth: false,\n ...props\n };\n if (window._vue_richtext_widgets[id]) {\n logger.error(`[ReferencePicker]: Widget for id ${id} already registered`);\n return;\n }\n window._vue_richtext_widgets[id] = {\n id,\n callback,\n onDestroy,\n ...propsWithDefaults\n };\n}\nfunction renderWidget(el, options) {\n const { richObjectType, richObject, accessible, interactive } = options;\n if (richObjectType === \"open-graph\") {\n return;\n }\n if (!window._vue_richtext_widgets[richObjectType]) {\n logger.error(\"Widget for rich object type \" + richObjectType + \" not registered\");\n return;\n }\n window._vue_richtext_widgets[richObjectType].callback(el, { richObjectType, richObject, accessible, interactive });\n}\nfunction destroyWidget(richObjectType, el) {\n if (richObjectType === \"open-graph\") {\n return;\n }\n if (!window._vue_richtext_widgets[richObjectType]) {\n return;\n }\n window._vue_richtext_widgets[richObjectType].onDestroy(el);\n}\nfunction isWidgetRegistered(id) {\n return !!window._vue_richtext_widgets[id];\n}\nfunction hasInteractiveView(id) {\n return !!window._vue_richtext_widgets[id]?.hasInteractiveView;\n}\nfunction hasFullWidth(id) {\n return !!window._vue_richtext_widgets[id]?.fullWidth;\n}\nwindow._vue_richtext_custom_picker_elements ??= {};\nwindow._registerCustomPickerElement ??= registerCustomPickerElement;\nclass NcCustomPickerRenderResult {\n element;\n object;\n /**\n * @param element - The HTML element\n * @param object - The object\n */\n constructor(element, object) {\n this.element = element;\n this.object = object;\n }\n}\nfunction isCustomPickerElementRegistered(id) {\n return !!window._vue_richtext_custom_picker_elements[id];\n}\nfunction getCustomPickerElementSize(id) {\n const size = window._vue_richtext_custom_picker_elements[id]?.size;\n if ([\"small\", \"normal\", \"large\", \"full\"].includes(size)) {\n return size;\n }\n return null;\n}\nfunction registerCustomPickerElement(id, callback, onDestroy = () => {\n}, size = \"large\") {\n if (window._vue_richtext_custom_picker_elements[id]) {\n logger.error(`Custom reference picker element for id ${id} already registered`);\n return;\n }\n window._vue_richtext_custom_picker_elements[id] = {\n id,\n callback,\n onDestroy,\n size\n };\n}\nfunction renderCustomPickerElement(el, options) {\n const { providerId, accessible } = options;\n if (!window._vue_richtext_custom_picker_elements[providerId]) {\n logger.error(`Custom reference picker element for reference provider ID ${providerId} not registered`);\n return;\n }\n return window._vue_richtext_custom_picker_elements[providerId].callback(el, { providerId, accessible });\n}\nfunction destroyCustomPickerElement(providerId, el, renderResult) {\n if (!window._vue_richtext_custom_picker_elements[providerId]) {\n return;\n }\n window._vue_richtext_custom_picker_elements[providerId].onDestroy(el, renderResult);\n}\nexport {\n NcCustomPickerRenderResult as N,\n renderWidget as a,\n destroyCustomPickerElement as b,\n isCustomPickerElementRegistered as c,\n destroyWidget as d,\n registerCustomPickerElement as e,\n renderCustomPickerElement as f,\n getCustomPickerElementSize as g,\n hasInteractiveView as h,\n isWidgetRegistered as i,\n hasFullWidth as j,\n registerWidget as r\n};\n//# sourceMappingURL=customPickerElements-DLFtgReB.mjs.map\n","import '../assets/referencePickerModal-CGtNx7ew.css';\nimport Vue, { ref, nextTick } from \"vue\";\nimport { emit } from \"@nextcloud/event-bus\";\nimport { A as ArrowLeft } from \"./ArrowLeft-DuT2LZOm.mjs\";\nimport { C as Close } from \"./Close-BtLPUSdO.mjs\";\nimport { d as destroyWidget, a as renderWidget, i as isWidgetRegistered, h as hasInteractiveView, j as hasFullWidth, f as renderCustomPickerElement, b as destroyCustomPickerElement, c as isCustomPickerElementRegistered, g as getCustomPickerElementSize } from \"./customPickerElements-DLFtgReB.mjs\";\nimport { n as normalizeComponent } from \"./_plugin-vue2_normalizer-DU4iP6Vu.mjs\";\nimport axios from \"@nextcloud/axios\";\nimport { loadState } from \"@nextcloud/initial-state\";\nimport { imagePath, generateOcsUrl } from \"@nextcloud/router\";\nimport { r as register, Y as t23, a as t, Z as t8, _ as t47, $ as t41, a0 as t24, z as t43, a1 as t31, m as t18, a2 as t12 } from \"./_l10n-DVz9Qdzk.mjs\";\nimport { l as logger } from \"./logger-D3RVzcfQ.mjs\";\nimport NcEmptyContent from \"../Components/NcEmptyContent.mjs\";\nimport { N as NcHighlight } from \"./index-CxTT94_h.mjs\";\nimport { N as NcSelect } from \"./NcSelect-CHc1QupB.mjs\";\nimport { useElementSize, useIntersectionObserver } from \"@vueuse/core\";\nimport { RouterLink } from \"vue-router\";\nimport { N as NcButton } from \"./NcButton-CCWEL9Ci.mjs\";\nimport { g as getRoute } from \"./autolink-CeB9uxD9.mjs\";\nimport NcLoadingIcon from \"../Components/NcLoadingIcon.mjs\";\nimport { N as NcTextField } from \"./NcTextField-Czr9S6YO.mjs\";\nimport { D as DotsHorizontalIcon } from \"./NcActions-DbPerbGE.mjs\";\nimport NcModal from \"../Components/NcModal.mjs\";\nregister(t23);\nconst IDLE_TIMEOUT = 3 * 60 * 1e3;\nconst _sfc_main$8 = {\n name: \"NcReferenceWidget\",\n components: {\n NcButton\n },\n /* eslint vue/require-prop-comment: warn -- TODO: Add a proper doc block about what this props do */\n props: {\n reference: {\n type: Object,\n required: true\n },\n interactive: {\n type: Boolean,\n // eslint-disable-next-line vue/no-boolean-default\n default: true\n },\n interactiveOptIn: {\n type: Boolean,\n default: false\n }\n },\n setup() {\n const isVisible = ref(false);\n const widgetRoot = ref();\n const { width } = useElementSize(widgetRoot);\n useIntersectionObserver(widgetRoot, ([entry]) => {\n nextTick(() => {\n isVisible.value = entry.isIntersecting;\n });\n });\n return {\n width,\n isVisible,\n widgetRoot\n };\n },\n data() {\n return {\n showInteractive: false,\n rendered: false,\n idleTimeout: null\n };\n },\n computed: {\n isInteractive() {\n return !this.interactiveOptIn && this.interactive || this.showInteractive;\n },\n hasFullWidth() {\n return hasFullWidth(this.reference.richObjectType);\n },\n hasCustomWidget() {\n return isWidgetRegistered(this.reference.richObjectType);\n },\n hasInteractiveView() {\n return isWidgetRegistered(this.reference.richObjectType) && hasInteractiveView(this.reference.richObjectType);\n },\n noAccess() {\n return this.reference && !this.reference.accessible;\n },\n descriptionStyle() {\n if (this.numberOfLines === 0) {\n return {\n display: \"none\"\n };\n }\n const lineClamp = this.numberOfLines;\n return {\n lineClamp,\n webkitLineClamp: lineClamp\n };\n },\n numberOfLines() {\n const lineCountOffsets = [450, 550, 650, Infinity];\n return lineCountOffsets.findIndex((max) => this.width < max);\n },\n compactLink() {\n const link = this.reference.openGraphObject.link;\n if (!link) {\n return \"\";\n }\n if (link.startsWith(\"https://\")) {\n return link.substring(8);\n }\n if (link.startsWith(\"http://\")) {\n return link.substring(7);\n }\n return link;\n },\n route() {\n return getRoute(this.$router, this.reference.openGraphObject.link);\n },\n referenceWidgetLinkComponent() {\n return this.route ? RouterLink : \"a\";\n },\n referenceWidgetLinkProps() {\n return this.route ? { to: this.route } : { href: this.reference.openGraphObject.link, target: \"_blank\" };\n }\n },\n watch: {\n isVisible: {\n handler(val) {\n if (!val) {\n this.idleTimeout = setTimeout(() => {\n if (!this.isVisible) {\n this.destroyWidget();\n }\n }, IDLE_TIMEOUT);\n return;\n }\n if (this.idleTimeout) {\n clearTimeout(this.idleTimeout);\n this.idleTimeout = null;\n }\n if (!this.rendered) {\n this.renderWidget();\n }\n },\n immediate: true\n }\n },\n beforeDestroy() {\n this.destroyWidget();\n },\n methods: {\n t,\n enableInteractive() {\n this.showInteractive = true;\n this.renderWidget();\n },\n renderWidget() {\n if (!this.$refs.customWidget) {\n return;\n }\n if (this?.reference?.richObjectType === \"open-graph\") {\n return;\n }\n this.$refs.customWidget.innerHTML = \"\";\n const widget = document.createElement(\"div\");\n widget.style = \"width: 100%;\";\n this.$refs.customWidget.appendChild(widget);\n this.$nextTick(() => {\n renderWidget(widget, {\n ...this.reference,\n interactive: this.isInteractive\n });\n this.rendered = true;\n });\n },\n destroyWidget() {\n if (this.rendered) {\n destroyWidget(this.reference.richObjectType, this.$el);\n this.rendered = false;\n }\n }\n }\n};\nvar _sfc_render$8 = function render() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"div\", { ref: \"widgetRoot\", class: { \"toggle-interactive\": _vm.hasInteractiveView && !_vm.isInteractive } }, [_vm.reference && _vm.hasCustomWidget ? _c(\"div\", { ref: \"customWidget\", staticClass: \"widget-custom\", class: { \"full-width\": _vm.hasFullWidth } }) : !_vm.noAccess && _vm.reference && _vm.reference.openGraphObject && !_vm.hasCustomWidget ? _c(_vm.referenceWidgetLinkComponent, _vm._b({ tag: \"component\", staticClass: \"widget-default\", attrs: { \"rel\": \"noopener noreferrer\" } }, \"component\", _vm.referenceWidgetLinkProps, false), [_vm.reference.openGraphObject.thumb ? _c(\"img\", { staticClass: \"widget-default--image\", attrs: { \"src\": _vm.reference.openGraphObject.thumb } }) : _vm._e(), _c(\"div\", { staticClass: \"widget-default--details\" }, [_c(\"p\", { staticClass: \"widget-default--name\" }, [_vm._v(\" \" + _vm._s(_vm.reference.openGraphObject.name) + \" \")]), _c(\"p\", { staticClass: \"widget-default--description\", style: _vm.descriptionStyle }, [_vm._v(\" \" + _vm._s(_vm.reference.openGraphObject.description) + \" \")]), _c(\"p\", { staticClass: \"widget-default--link\" }, [_vm._v(\" \" + _vm._s(_vm.compactLink) + \" \")])])]) : _vm._e(), _vm.interactiveOptIn && _vm.hasInteractiveView && !_vm.isInteractive ? _c(\"NcButton\", { staticClass: \"toggle-interactive--button\", on: { \"click\": _vm.enableInteractive } }, [_vm._v(\" \" + _vm._s(_vm.t(\"Enable interactive view\")) + \" \")]) : _vm._e()], 1);\n};\nvar _sfc_staticRenderFns$8 = [];\nvar __component__$8 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$8,\n _sfc_render$8,\n _sfc_staticRenderFns$8,\n false,\n null,\n \"f05dd81b\"\n);\nconst NcReferenceWidget = __component__$8.exports;\nconst _sfc_main$7 = {\n name: \"NcCustomPickerElement\",\n props: {\n /**\n * The reference provider\n */\n provider: {\n type: Object,\n required: true\n }\n },\n emits: [\n \"cancel\",\n \"submit\"\n ],\n data() {\n return {\n isRegistered: isCustomPickerElementRegistered(this.provider.id),\n renderResult: null\n };\n },\n mounted() {\n if (this.isRegistered) {\n this.renderElement();\n }\n },\n beforeDestroy() {\n if (this.isRegistered) {\n destroyCustomPickerElement(this.provider.id, this.$el, this.renderResult);\n }\n },\n methods: {\n renderElement() {\n if (this.$refs.domElement) {\n this.$refs.domElement.innerHTML = \"\";\n }\n const renderFunctionResult = renderCustomPickerElement(this.$refs.domElement, { providerId: this.provider.id, accessible: false });\n Promise.resolve(renderFunctionResult).then((result) => {\n this.renderResult = result;\n if (this.renderResult.object?._isVue && this.renderResult.object?.$on) {\n this.renderResult.object.$on(\"submit\", this.onSubmit);\n this.renderResult.object.$on(\"cancel\", this.onCancel);\n }\n this.renderResult.element.addEventListener(\"submit\", (e) => {\n this.onSubmit(e.detail);\n });\n this.renderResult.element.addEventListener(\"cancel\", this.onCancel);\n });\n },\n onSubmit(value) {\n this.$emit(\"submit\", value);\n },\n onCancel() {\n this.$emit(\"cancel\");\n }\n }\n};\nvar _sfc_render$7 = function render2() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"div\", { ref: \"domElement\" });\n};\nvar _sfc_staticRenderFns$7 = [];\nvar __component__$7 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$7,\n _sfc_render$7,\n _sfc_staticRenderFns$7,\n false,\n null,\n \"0547d92f\"\n);\nconst NcCustomPickerElement = __component__$7.exports;\nconst _sfc_main$6 = {\n name: \"LinkVariantIcon\",\n emits: [\"click\"],\n props: {\n title: {\n type: String\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n};\nvar _sfc_render$6 = function render3() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"span\", _vm._b({ staticClass: \"material-design-icon link-variant-icon\", attrs: { \"aria-hidden\": _vm.title ? null : \"true\", \"aria-label\": _vm.title, \"role\": \"img\" }, on: { \"click\": function($event) {\n return _vm.$emit(\"click\", $event);\n } } }, \"span\", _vm.$attrs, false), [_c(\"svg\", { staticClass: \"material-design-icon__svg\", attrs: { \"fill\": _vm.fillColor, \"width\": _vm.size, \"height\": _vm.size, \"viewBox\": \"0 0 24 24\" } }, [_c(\"path\", { attrs: { \"d\": \"M10.59,13.41C11,13.8 11,14.44 10.59,14.83C10.2,15.22 9.56,15.22 9.17,14.83C7.22,12.88 7.22,9.71 9.17,7.76V7.76L12.71,4.22C14.66,2.27 17.83,2.27 19.78,4.22C21.73,6.17 21.73,9.34 19.78,11.29L18.29,12.78C18.3,11.96 18.17,11.14 17.89,10.36L18.36,9.88C19.54,8.71 19.54,6.81 18.36,5.64C17.19,4.46 15.29,4.46 14.12,5.64L10.59,9.17C9.41,10.34 9.41,12.24 10.59,13.41M13.41,9.17C13.8,8.78 14.44,8.78 14.83,9.17C16.78,11.12 16.78,14.29 14.83,16.24V16.24L11.29,19.78C9.34,21.73 6.17,21.73 4.22,19.78C2.27,17.83 2.27,14.66 4.22,12.71L5.71,11.22C5.7,12.04 5.83,12.86 6.11,13.65L5.64,14.12C4.46,15.29 4.46,17.19 5.64,18.36C6.81,19.54 8.71,19.54 9.88,18.36L13.41,14.83C14.59,13.66 14.59,11.76 13.41,10.59C13,10.2 13,9.56 13.41,9.17Z\" } }, [_vm.title ? _c(\"title\", [_vm._v(_vm._s(_vm.title))]) : _vm._e()])])]);\n};\nvar _sfc_staticRenderFns$6 = [];\nvar __component__$6 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$6,\n _sfc_render$6,\n _sfc_staticRenderFns$6,\n false,\n null,\n null\n);\nconst LinkVariantIcon = __component__$6.exports;\nregister(t8);\nconst anyLinkProviderId = \"any-link\";\nconst anyLinkProvider = {\n id: anyLinkProviderId,\n title: t(\"Any link\"),\n order: 0,\n icon_url: imagePath(\"core\", \"filetypes/link.svg\")\n};\nwindow._vue_richtext_reference_providers ??= loadState(\"core\", \"reference-provider-list\", []);\nwindow._vue_richtext_reference_provider_timestamps ??= loadState(\"core\", \"reference-provider-timestamps\", {});\nfunction getProvider(providerId) {\n if (providerId === anyLinkProviderId) {\n return anyLinkProvider;\n }\n return getProviders().find((p) => p.id === providerId);\n}\nfunction getProviders() {\n return window._vue_richtext_reference_providers.filter((p) => {\n const keep = !!p.search_providers_ids && p.search_providers_ids.length > 0 || isCustomPickerElementRegistered(p.id);\n if (!keep) {\n logger.debug(`[smart picker] ${p.id} reference provider is discoverable but does not have any related search provider or custom picker component registered`);\n }\n return keep;\n });\n}\nfunction sortProviders(providerList) {\n const timestamps = window._vue_richtext_reference_provider_timestamps;\n return providerList.sort((a, b) => {\n return a.order === b.order ? 0 : a.order > b.order ? 1 : -1;\n }).sort((a, b) => {\n const ta = timestamps[a.id];\n const tb = timestamps[b.id];\n return ta === tb ? 0 : tb === void 0 ? -1 : ta === void 0 ? 1 : ta > tb ? -1 : 1;\n });\n}\nfunction searchProvider(query, limit) {\n const providers = getProviders();\n const escapedQuery = query.replace(/[/\\-\\\\^$*+?.()|[\\]{}]/g, \"\\\\$&\");\n const regexp = new RegExp(escapedQuery, \"i\");\n const sortedProviders = sortProviders(providers);\n const filteredSortedProviders = sortedProviders.filter((p) => {\n return p.title.match(regexp);\n });\n const searchResult = limit ? filteredSortedProviders.slice(0, limit) : filteredSortedProviders;\n if (query === \"\" || searchResult.length === 0) {\n searchResult.push(anyLinkProvider);\n }\n return searchResult;\n}\nasync function touchProvider(providerId) {\n const timestamp = Math.floor(Date.now() / 1e3);\n const url = generateOcsUrl(\"references/provider/{providerId}\", { providerId });\n await axios.put(url, { timestamp });\n window._vue_richtext_reference_provider_timestamps[providerId] = timestamp;\n}\nregister(t41, t47);\nlet mytimer = 0;\nfunction delay(callback, ms) {\n return function() {\n const context = this;\n const args = arguments;\n clearTimeout(mytimer);\n mytimer = setTimeout(function() {\n callback.apply(context, args);\n }, ms);\n };\n}\nfunction isUrl(str) {\n try {\n return Boolean(new URL(str));\n } catch {\n return false;\n }\n}\nconst _sfc_main$5 = {\n name: \"NcProviderList\",\n components: {\n NcSelect,\n NcHighlight,\n NcEmptyContent,\n LinkVariantIcon\n },\n emits: [\n \"select-provider\",\n \"submit\"\n ],\n data() {\n return {\n selectedProvider: null,\n query: \"\",\n multiselectPlaceholder: t(\"Select provider\"),\n providerIconAlt: t(\"Provider icon\")\n };\n },\n computed: {\n options() {\n const result = [];\n if (this.query !== \"\" && isUrl(this.query)) {\n result.push({\n id: this.query,\n title: this.query,\n isLink: true\n });\n }\n result.push(...searchProvider(this.query));\n return result;\n }\n },\n methods: {\n focus() {\n setTimeout(() => {\n this.$refs[\"provider-select\"]?.$el?.querySelector(\"#provider-select-input\")?.focus();\n }, 300);\n },\n onProviderSelected(p) {\n if (p !== null) {\n if (p.isLink) {\n this.$emit(\"submit\", p.title);\n } else {\n this.$emit(\"select-provider\", p);\n }\n this.selectedProvider = null;\n }\n },\n onSearch(query) {\n this.query = query;\n }\n }\n};\nvar _sfc_render$5 = function render4() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"div\", { staticClass: \"provider-list\" }, [_c(\"NcSelect\", { ref: \"provider-select\", staticClass: \"provider-list--select\", attrs: { \"input-id\": \"provider-select-input\", \"label\": \"title\", \"placeholder\": _vm.multiselectPlaceholder, \"options\": _vm.options, \"append-to-body\": false, \"clear-search-on-select\": true, \"clear-search-on-blur\": () => false, \"filterable\": false }, on: { \"search\": _vm.onSearch, \"input\": _vm.onProviderSelected }, scopedSlots: _vm._u([{ key: \"option\", fn: function(option) {\n return [option.isLink ? _c(\"div\", { staticClass: \"provider\" }, [_c(\"LinkVariantIcon\", { staticClass: \"link-icon\", attrs: { \"size\": 20 } }), _c(\"span\", [_vm._v(_vm._s(option.title))])], 1) : _c(\"div\", { staticClass: \"provider\" }, [_c(\"img\", { staticClass: \"provider-icon\", attrs: { \"src\": option.icon_url, \"alt\": _vm.providerIconAlt } }), _c(\"NcHighlight\", { staticClass: \"option-text\", attrs: { \"search\": _vm.query, \"text\": option.title } })], 1)];\n } }]), model: { value: _vm.selectedProvider, callback: function($$v) {\n _vm.selectedProvider = $$v;\n }, expression: \"selectedProvider\" } }), _c(\"NcEmptyContent\", { staticClass: \"provider-list--empty-content\", scopedSlots: _vm._u([{ key: \"icon\", fn: function() {\n return [_c(\"LinkVariantIcon\")];\n }, proxy: true }]) })], 1);\n};\nvar _sfc_staticRenderFns$5 = [];\nvar __component__$5 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$5,\n _sfc_render$5,\n _sfc_staticRenderFns$5,\n false,\n null,\n \"f39d58d9\"\n);\nconst NcProviderList = __component__$5.exports;\nregister(t24);\nconst _sfc_main$4 = {\n name: \"NcRawLinkInput\",\n components: {\n LinkVariantIcon,\n NcEmptyContent,\n NcLoadingIcon,\n NcReferenceWidget,\n NcTextField\n },\n props: {\n /**\n * The reference provider\n */\n provider: {\n type: Object,\n required: true\n }\n },\n emits: [\n \"submit\"\n ],\n data() {\n return {\n inputValue: \"\",\n loading: false,\n reference: null,\n abortController: null,\n inputPlaceholder: t(\"Enter link\")\n };\n },\n computed: {\n isLinkValid() {\n return isUrl(this.inputValue);\n }\n },\n methods: {\n focus() {\n this.$refs[\"url-input\"].$el.getElementsByTagName(\"input\")[0]?.focus();\n },\n onSubmit(e) {\n const value = e.target.value;\n if (this.isLinkValid) {\n this.$emit(\"submit\", value);\n }\n },\n onClear() {\n this.inputValue = \"\";\n this.reference = null;\n },\n onInput() {\n this.reference = null;\n if (this.abortController) {\n this.abortController.abort();\n }\n if (this.isLinkValid) {\n delay(() => {\n this.updateReference();\n }, 500)();\n }\n },\n updateReference() {\n this.loading = true;\n this.abortController = new AbortController();\n axios.get(generateOcsUrl(\"references/resolve\", 2) + \"?reference=\" + encodeURIComponent(this.inputValue), {\n signal: this.abortController.signal\n }).then((response) => {\n this.reference = response.data.ocs.data.references[this.inputValue];\n }).catch((error) => {\n logger.error(\"Could not update reference\", { error });\n }).then(() => {\n this.loading = false;\n });\n }\n }\n};\nvar _sfc_render$4 = function render5() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"div\", { staticClass: \"raw-link\" }, [_c(\"div\", { staticClass: \"input-wrapper\" }, [_c(\"NcTextField\", { ref: \"url-input\", attrs: { \"value\": _vm.inputValue, \"show-trailing-button\": _vm.inputValue !== \"\", \"label\": _vm.inputPlaceholder }, on: { \"update:value\": [function($event) {\n _vm.inputValue = $event;\n }, _vm.onInput], \"trailing-button-click\": _vm.onClear }, nativeOn: { \"keyup\": function($event) {\n if (!$event.type.indexOf(\"key\") && _vm._k($event.keyCode, \"enter\", 13, $event.key, \"Enter\")) return null;\n return _vm.onSubmit.apply(null, arguments);\n } } }, [_vm.loading ? _c(\"NcLoadingIcon\", { attrs: { \"size\": 16 } }) : _c(\"LinkVariantIcon\", { attrs: { \"size\": 16 } })], 1)], 1), _vm.reference !== null ? _c(\"NcReferenceWidget\", { staticClass: \"reference-widget\", attrs: { \"reference\": _vm.reference } }) : _c(\"NcEmptyContent\", { staticClass: \"raw-link--empty-content\", scopedSlots: _vm._u([{ key: \"icon\", fn: function() {\n return [_vm.provider.icon_url ? _c(\"img\", { staticClass: \"provider-icon\", attrs: { \"src\": _vm.provider.icon_url } }) : _c(\"LinkVariantIcon\")];\n }, proxy: true }]) })], 1);\n};\nvar _sfc_staticRenderFns$4 = [];\nvar __component__$4 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$4,\n _sfc_render$4,\n _sfc_staticRenderFns$4,\n false,\n null,\n \"be630586\"\n);\nconst NcRawLinkInput = __component__$4.exports;\nconst _sfc_main$3 = {\n name: \"NcSearchResult\",\n components: {\n NcHighlight\n },\n props: {\n /**\n * Unified search result entry\n */\n entry: {\n type: Object,\n required: true\n },\n /**\n * The query that led to getting this result\n * Used to highlight the entry text\n */\n query: {\n type: String,\n required: true\n }\n }\n};\nvar _sfc_render$3 = function render6() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"div\", { staticClass: \"result\" }, [_vm.entry.icon ? _c(\"div\", { staticClass: \"result--icon-class\", class: { [_vm.entry.icon]: true, rounded: _vm.entry.rounded } }) : _c(\"img\", { staticClass: \"result--image\", class: { rounded: _vm.entry.rounded }, attrs: { \"src\": _vm.entry.thumbnailUrl } }), _c(\"div\", { staticClass: \"result--content\" }, [_c(\"span\", { staticClass: \"result--content--name\" }, [_c(\"NcHighlight\", { attrs: { \"search\": _vm.query, \"text\": _vm.entry.title } })], 1), _c(\"span\", { staticClass: \"result--content--subline\" }, [_c(\"NcHighlight\", { attrs: { \"search\": _vm.query, \"text\": _vm.entry.subline } })], 1)])]);\n};\nvar _sfc_staticRenderFns$3 = [];\nvar __component__$3 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$3,\n _sfc_render$3,\n _sfc_staticRenderFns$3,\n false,\n null,\n \"995c2758\"\n);\nconst NcSearchResult = __component__$3.exports;\nregister(t31, t41, t43);\nconst LIMIT = 5;\nconst _sfc_main$2 = {\n name: \"NcSearch\",\n components: {\n LinkVariantIcon,\n DotsHorizontalIcon,\n NcEmptyContent,\n NcSelect,\n NcSearchResult\n },\n /* eslint vue/require-prop-comment: warn -- TODO: Add a proper doc block about what this props do */\n props: {\n /**\n * The selected reference provider\n */\n provider: {\n type: Object,\n required: true\n },\n showEmptyContent: {\n type: Boolean,\n // eslint-disable-next-line vue/no-boolean-default\n default: true\n },\n /**\n * Placeholder of the search\n */\n searchPlaceholder: {\n type: String,\n default: null\n }\n },\n emits: [\n \"submit\"\n ],\n data() {\n return {\n searchQuery: \"\",\n selectedResult: null,\n resultsBySearchProvider: {},\n searching: false,\n searchingMoreOf: null,\n abortController: null,\n noOptionsText: t(\"Start typing to search\"),\n providerIconAlt: t(\"Provider icon\")\n };\n },\n computed: {\n mySearchPlaceholder() {\n return this.searchPlaceholder || t(\"Search\");\n },\n searchProviderIds() {\n return this.provider.search_providers_ids;\n },\n options() {\n if (this.searchQuery === \"\") {\n return [];\n }\n const options = [];\n if (isUrl(this.searchQuery)) {\n options.push(this.rawLinkEntry);\n }\n options.push(...this.formattedSearchResults);\n return options;\n },\n rawLinkEntry() {\n return {\n id: \"rawLinkEntry\",\n resourceUrl: this.searchQuery,\n isRawLink: true\n };\n },\n formattedSearchResults() {\n const results = [];\n this.searchProviderIds.forEach((pid) => {\n if (this.resultsBySearchProvider[pid].entries.length > 0) {\n if (this.searchProviderIds.length > 1 || this.resultsBySearchProvider[pid].entries.length > 1) {\n results.push({\n id: \"groupTitle-\" + pid,\n name: this.resultsBySearchProvider[pid].name,\n isCustomGroupTitle: true,\n providerId: pid\n });\n }\n const providerEntriesWithId = this.resultsBySearchProvider[pid].entries.map((entry, index) => {\n return {\n id: \"provider-\" + pid + \"-entry-\" + index,\n ...entry\n };\n });\n results.push(...providerEntriesWithId);\n if (this.resultsBySearchProvider[pid].isPaginated) {\n results.push({\n id: \"moreOf-\" + pid,\n name: this.resultsBySearchProvider[pid].name,\n isMore: true,\n providerId: pid,\n isLoading: this.searchingMoreOf === pid\n });\n }\n }\n });\n return results;\n }\n },\n mounted() {\n this.resetResults();\n },\n beforeDestroy() {\n this.cancelSearchRequests();\n },\n methods: {\n t,\n resetResults() {\n const resultsBySearchProvider = {};\n this.searchProviderIds.forEach((pid) => {\n resultsBySearchProvider[pid] = {\n entries: []\n };\n });\n this.resultsBySearchProvider = resultsBySearchProvider;\n },\n focus() {\n setTimeout(() => {\n this.$refs[\"search-select\"]?.$el?.querySelector(\"#search-select-input\")?.focus();\n }, 300);\n },\n cancelSearchRequests() {\n if (this.abortController) {\n this.abortController.abort();\n }\n },\n onSearchInput(query) {\n this.searchQuery = query;\n delay(() => {\n this.updateSearch();\n }, 500)();\n },\n onSelectResultSelected(item) {\n if (item !== null) {\n if (item.resourceUrl) {\n this.cancelSearchRequests();\n this.$emit(\"submit\", item.resourceUrl);\n } else if (item.isMore) {\n this.searchMoreOf(item.providerId).then(() => {\n this.selectedResult = null;\n });\n }\n }\n },\n searchMoreOf(searchProviderId) {\n this.searchingMoreOf = searchProviderId;\n this.cancelSearchRequests();\n return this.searchProviders(searchProviderId);\n },\n updateSearch() {\n this.cancelSearchRequests();\n this.resetResults();\n if (this.searchQuery === \"\") {\n this.searching = false;\n return;\n }\n return this.searchProviders();\n },\n searchProviders(searchProviderId = null) {\n this.abortController = new AbortController();\n this.searching = true;\n const searchPromises = searchProviderId === null ? [...this.searchProviderIds].map((pid) => {\n return this.searchOneProvider(pid);\n }) : [this.searchOneProvider(searchProviderId, this.resultsBySearchProvider[searchProviderId]?.cursor ?? null)];\n return Promise.allSettled(searchPromises).then((promises) => {\n const isOneCanceled = !!promises.find((p) => {\n return p.status === \"rejected\" && (p.reason.name === \"CanceledError\" || p.reason.code === \"ERR_CANCELED\");\n });\n if (!isOneCanceled) {\n this.searching = false;\n this.searchingMoreOf = null;\n }\n });\n },\n searchOneProvider(providerId, cursor = null) {\n const url = cursor === null ? generateOcsUrl(\"search/providers/{providerId}/search?term={term}&limit={limit}\", { providerId, term: this.searchQuery, limit: LIMIT }) : generateOcsUrl(\"search/providers/{providerId}/search?term={term}&limit={limit}&cursor={cursor}\", { providerId, term: this.searchQuery, limit: LIMIT, cursor });\n return axios.get(url, {\n signal: this.abortController.signal\n }).then((response) => {\n const data = response.data.ocs.data;\n this.resultsBySearchProvider[providerId].name = data.name;\n this.resultsBySearchProvider[providerId].cursor = data.cursor;\n this.resultsBySearchProvider[providerId].isPaginated = data.isPaginated;\n this.resultsBySearchProvider[providerId].entries.push(...data.entries);\n });\n }\n }\n};\nvar _sfc_render$2 = function render7() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"div\", { staticClass: \"smart-picker-search\", class: { \"with-empty-content\": _vm.showEmptyContent } }, [_c(\"NcSelect\", { ref: \"search-select\", staticClass: \"smart-picker-search--select\", attrs: { \"input-id\": \"search-select-input\", \"label\": \"name\", \"placeholder\": _vm.mySearchPlaceholder, \"options\": _vm.options, \"append-to-body\": false, \"close-on-select\": false, \"clear-search-on-select\": false, \"clear-search-on-blur\": () => false, \"reset-focus-on-options-change\": false, \"filterable\": false, \"autoscroll\": true, \"reset-on-options-change\": false, \"loading\": _vm.searching }, on: { \"search\": _vm.onSearchInput, \"input\": _vm.onSelectResultSelected }, scopedSlots: _vm._u([{ key: \"option\", fn: function(option) {\n return [option.isRawLink ? _c(\"div\", { staticClass: \"custom-option\" }, [_c(\"LinkVariantIcon\", { staticClass: \"option-simple-icon\", attrs: { \"size\": 20 } }), _c(\"span\", { staticClass: \"option-text\" }, [_vm._v(\" \" + _vm._s(_vm.t(\"Raw link {options}\", { options: option.resourceUrl })) + \" \")])], 1) : option.resourceUrl ? _c(\"NcSearchResult\", { staticClass: \"search-result\", attrs: { \"entry\": option, \"query\": _vm.searchQuery } }) : option.isCustomGroupTitle ? _c(\"span\", { staticClass: \"custom-option group-name\" }, [_vm.provider.icon_url ? _c(\"img\", { staticClass: \"provider-icon group-name-icon\", attrs: { \"src\": _vm.provider.icon_url } }) : _vm._e(), _c(\"span\", { staticClass: \"option-text\" }, [_c(\"strong\", [_vm._v(_vm._s(option.name))])])]) : option.isMore ? _c(\"span\", { staticClass: \"custom-option\" }, [option.isLoading ? _c(\"span\", { staticClass: \"option-simple-icon icon-loading-small\" }) : _c(\"DotsHorizontalIcon\", { staticClass: \"option-simple-icon\", attrs: { \"size\": 20 } }), _c(\"span\", { staticClass: \"option-text\" }, [_vm._v(\" \" + _vm._s(_vm.t('Load more \"{options}\"', { options: option.name })) + \" \")])], 1) : _vm._e()];\n } }, { key: \"no-options\", fn: function() {\n return [_vm._v(\" \" + _vm._s(_vm.noOptionsText) + \" \")];\n }, proxy: true }]), model: { value: _vm.selectedResult, callback: function($$v) {\n _vm.selectedResult = $$v;\n }, expression: \"selectedResult\" } }), _vm.showEmptyContent ? _c(\"NcEmptyContent\", { staticClass: \"smart-picker-search--empty-content\", scopedSlots: _vm._u([{ key: \"icon\", fn: function() {\n return [_vm.provider.icon_url ? _c(\"img\", { staticClass: \"provider-icon\", attrs: { \"alt\": _vm.providerIconAlt, \"src\": _vm.provider.icon_url } }) : _c(\"LinkVariantIcon\")];\n }, proxy: true }], null, false, 2922132592) }) : _vm._e()], 1);\n};\nvar _sfc_staticRenderFns$2 = [];\nvar __component__$2 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$2,\n _sfc_render$2,\n _sfc_staticRenderFns$2,\n false,\n null,\n \"e61f71e3\"\n);\nconst NcSearch = __component__$2.exports;\nconst MODES = {\n providerList: 1,\n standardLinkInput: 2,\n searchInput: 3,\n customElement: 4\n};\nconst _sfc_main$1 = {\n name: \"NcReferencePicker\",\n components: {\n NcCustomPickerElement,\n NcProviderList,\n NcRawLinkInput,\n NcSearch\n },\n props: {\n /**\n * Provider to select on creation\n * Default: null. Show the provider list\n */\n initialProvider: {\n type: Object,\n default: () => null\n },\n /**\n * Optional width in pixels\n * Default: 100%\n */\n width: {\n type: Number,\n default: null\n },\n /**\n * Focus on the provider list select input on creation\n * Default: true\n */\n focusOnCreate: {\n type: Boolean,\n // eslint-disable-next-line vue/no-boolean-default\n default: true\n }\n },\n emits: [\n \"cancel\",\n \"cancel-raw-link\",\n \"cancel-search\",\n \"provider-selected\",\n \"submit\"\n ],\n data() {\n return {\n MODES,\n selectedProvider: this.initialProvider\n };\n },\n computed: {\n mode() {\n return this.selectedProvider === null ? MODES.providerList : isCustomPickerElementRegistered(this.selectedProvider.id) ? MODES.customElement : this.selectedProvider.search_providers_ids ? MODES.searchInput : MODES.standardLinkInput;\n },\n pickerWrapperStyle() {\n return {\n width: this.width ? this.width + \"px\" : void 0\n };\n }\n },\n mounted() {\n if (this.focusOnCreate) {\n if (this.initialProvider) {\n setTimeout(() => {\n this.$refs[\"url-input\"]?.focus();\n }, 300);\n } else {\n this.$nextTick(() => {\n this.$refs[\"provider-list\"]?.focus();\n });\n }\n }\n },\n methods: {\n onEscapePressed() {\n if (this.selectedProvider !== null) {\n this.deselectProvider();\n } else {\n this.cancelProviderSelection();\n }\n },\n onProviderSelected(provider) {\n this.selectedProvider = provider;\n this.$emit(\"provider-selected\", provider);\n this.$nextTick(() => {\n this.$refs[\"url-input\"]?.focus();\n });\n },\n cancelCustomElement() {\n this.deselectProvider();\n },\n cancelSearch() {\n this.$emit(\"cancel-search\", this.selectedProvider?.title);\n this.deselectProvider();\n },\n cancelRawLinkInput() {\n this.$emit(\"cancel-raw-link\", this.selectedProvider?.title);\n this.deselectProvider();\n },\n cancelProviderSelection() {\n this.$emit(\"cancel\");\n },\n submitLink(link) {\n if (this.selectedProvider !== null) {\n touchProvider(this.selectedProvider.id);\n }\n this.$emit(\"submit\", link);\n this.deselectProvider();\n },\n deselectProvider() {\n this.selectedProvider = null;\n this.$emit(\"provider-selected\", null);\n setTimeout(() => {\n this.$refs[\"provider-list\"]?.focus();\n }, 300);\n }\n }\n};\nvar _sfc_render$1 = function render8() {\n var _vm = this, _c = _vm._self._c;\n return _c(\"div\", { staticClass: \"reference-picker\", style: _vm.pickerWrapperStyle, attrs: { \"tabindex\": \"-1\" }, on: { \"keydown\": function($event) {\n if (!$event.type.indexOf(\"key\") && _vm._k($event.keyCode, \"esc\", 27, $event.key, [\"Esc\", \"Escape\"])) return null;\n $event.stopPropagation();\n $event.preventDefault();\n return _vm.onEscapePressed.apply(null, arguments);\n } } }, [_vm.mode === _vm.MODES.providerList ? _c(\"NcProviderList\", { ref: \"provider-list\", on: { \"select-provider\": _vm.onProviderSelected, \"submit\": _vm.submitLink, \"cancel\": _vm.cancelProviderSelection } }) : _vm.mode === _vm.MODES.standardLinkInput ? _c(\"NcRawLinkInput\", { ref: \"url-input\", attrs: { \"provider\": _vm.selectedProvider }, on: { \"submit\": _vm.submitLink, \"cancel\": _vm.cancelRawLinkInput } }) : _vm.mode === _vm.MODES.searchInput ? _c(\"NcSearch\", { ref: \"url-input\", attrs: { \"provider\": _vm.selectedProvider }, on: { \"cancel\": _vm.cancelSearch, \"submit\": _vm.submitLink } }) : _vm.mode === _vm.MODES.customElement ? _c(\"div\", { staticClass: \"custom-element-wrapper\" }, [_c(\"NcCustomPickerElement\", { staticClass: \"custom-element\", attrs: { \"provider\": _vm.selectedProvider }, on: { \"submit\": _vm.submitLink, \"cancel\": _vm.cancelCustomElement } })], 1) : _vm._e()], 1);\n};\nvar _sfc_staticRenderFns$1 = [];\nvar __component__$1 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$1,\n _sfc_render$1,\n _sfc_staticRenderFns$1,\n false,\n null,\n \"646d5538\"\n);\nconst NcReferencePicker = __component__$1.exports;\nregister(t12, t18);\nconst _sfc_main = {\n name: \"NcReferencePickerModal\",\n components: {\n NcReferencePicker,\n NcModal,\n NcButton,\n ArrowLeftIcon: ArrowLeft,\n CloseIcon: Close\n },\n props: {\n /**\n * Provider to select on creation\n * Show the provider list if no initial one is provided\n */\n initialProvider: {\n type: Object,\n default: () => null\n },\n /**\n * Focus on the input item on create\n */\n focusOnCreate: {\n type: Boolean,\n // eslint-disable-next-line vue/no-boolean-default\n default: true\n },\n /**\n * If true, add the modal content to the Viewer trap elements via the event-bus\n */\n isInsideViewer: {\n type: Boolean,\n default: false\n }\n },\n emits: [\n \"cancel\",\n \"submit\"\n ],\n data() {\n return {\n show: true,\n selectedProvider: this.initialProvider,\n backButtonTitle: t(\"Back to provider selection\"),\n closeButtonTitle: t(\"Close\"),\n closeButtonLabel: t(\"Close Smart Picker\")\n };\n },\n computed: {\n isProviderSelected() {\n return this.selectedProvider !== null;\n },\n showBackButton() {\n return this.initialProvider === null && this.isProviderSelected;\n },\n modalSize() {\n return this.isProviderSelected && isCustomPickerElementRegistered(this.selectedProvider.id) ? getCustomPickerElementSize(this.selectedProvider.id) ?? \"large\" : \"normal\";\n },\n showModalName() {\n return !this.isProviderSelected || !isCustomPickerElementRegistered(this.selectedProvider.id);\n },\n modalName() {\n return this.isProviderSelected ? this.selectedProvider.title : t(\"Smart Picker\");\n }\n },\n mounted() {\n if (this.isInsideViewer) {\n const elem = this.$refs.modal_content;\n emit(\"viewer:trapElements:changed\", elem);\n }\n },\n methods: {\n onCancel() {\n this.show = false;\n this.$emit(\"cancel\");\n },\n onSubmit(value) {\n this.show = false;\n this.$emit(\"submit\", value);\n },\n onProviderSelect(provider) {\n this.selectedProvider = provider;\n if (provider === null && this.initialProvider !== null) {\n this.onCancel();\n }\n },\n onBackClicked() {\n this.$refs.referencePicker.deselectProvider();\n }\n }\n};\nvar _sfc_render = function render9() {\n var _vm = this, _c = _vm._self._c;\n return _vm.show ? _c(\"NcModal\", { staticClass: \"reference-picker-modal\", attrs: { \"size\": _vm.modalSize, \"can-close\": true }, on: { \"close\": _vm.onCancel } }, [_c(\"div\", { ref: \"modal_content\", staticClass: \"reference-picker-modal--content\" }, [_vm.showBackButton ? _c(\"NcButton\", { staticClass: \"back-button\", attrs: { \"aria-label\": _vm.backButtonTitle, \"title\": _vm.backButtonTitle }, on: { \"click\": _vm.onBackClicked }, scopedSlots: _vm._u([{ key: \"icon\", fn: function() {\n return [_c(\"ArrowLeftIcon\")];\n }, proxy: true }], null, false, 3001860362) }) : _vm._e(), _c(\"NcButton\", { staticClass: \"close-button\", attrs: { \"aria-label\": _vm.closeButtonLabel, \"title\": _vm.closeButtonTitle, \"variant\": \"tertiary\" }, on: { \"click\": _vm.onCancel }, scopedSlots: _vm._u([{ key: \"icon\", fn: function() {\n return [_c(\"CloseIcon\")];\n }, proxy: true }], null, false, 2491825086) }), _vm.showModalName ? _c(\"h2\", [_vm._v(\" \" + _vm._s(_vm.modalName) + \" \")]) : _vm._e(), _c(\"NcReferencePicker\", { ref: \"referencePicker\", attrs: { \"initial-provider\": _vm.initialProvider, \"focus-on-create\": _vm.focusOnCreate }, on: { \"provider-selected\": _vm.onProviderSelect, \"submit\": _vm.onSubmit, \"cancel\": _vm.onCancel } })], 1)]) : _vm._e();\n};\nvar _sfc_staticRenderFns = [];\nvar __component__ = /* @__PURE__ */ normalizeComponent(\n _sfc_main,\n _sfc_render,\n _sfc_staticRenderFns,\n false,\n null,\n \"00990f2a\"\n);\nconst NcReferencePickerModal = __component__.exports;\nasync function getLinkWithPicker(providerId, isInsideViewer) {\n const modalId = \"referencePickerModal\";\n const modalElement = document.createElement(\"div\");\n modalElement.id = modalId;\n document.body.append(modalElement);\n const { promise, reject, resolve } = Promise.withResolvers();\n const initialProvider = providerId && getProvider(providerId) || null;\n const View = Vue.extend(NcReferencePickerModal);\n const view = new View({\n propsData: {\n initialProvider,\n isInsideViewer\n }\n }).$mount(modalElement);\n view.$on(\"cancel\", () => {\n view.$destroy();\n reject(new Error(\"User cancellation\"));\n });\n view.$on(\"submit\", (link) => {\n view.$destroy();\n resolve(link);\n });\n return promise;\n}\nexport {\n NcReferencePicker as N,\n anyLinkProviderId as a,\n getProvider as b,\n getProviders as c,\n sortProviders as d,\n NcReferencePickerModal as e,\n NcReferenceWidget as f,\n getLinkWithPicker as g,\n NcSearch as h,\n searchProvider as s\n};\n//# sourceMappingURL=referencePickerModal-B69WouiU.mjs.map\n","import { a as mdiCheck, e as mdiContentCopy } from \"./mdi-DkJglNiS.mjs\";\nimport { toValue } from \"@vueuse/core\";\nimport { ref, computed } from \"vue\";\nimport { r as register, d as t21, a as t } from \"./_l10n-DVz9Qdzk.mjs\";\nregister(t21);\n/*!\n * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nconst DELAY = 2e3;\nfunction useCopy(content) {\n const isCopied = ref(false);\n const icon = computed(() => isCopied.value ? mdiCheck : mdiContentCopy);\n const altText = computed(() => isCopied.value ? t(\"Copied\") : t(\"Copy to clipboard\"));\n async function copy() {\n if (isCopied.value) {\n return;\n }\n const value = toValue(content);\n try {\n await navigator.clipboard.writeText(value);\n } catch {\n prompt(\"\", value);\n }\n isCopied.value = true;\n setTimeout(() => {\n isCopied.value = false;\n }, DELAY);\n }\n return {\n isCopied,\n copy,\n icon,\n altText\n };\n}\nexport {\n useCopy as u\n};\n//# sourceMappingURL=useCopy-DDDe5RYH.mjs.map\n","import '../assets/NcRichText-Cp_5tfBy.css';\nimport { toString } from \"mdast-util-to-string\";\nimport rehypeExternalLinks from \"rehype-external-links\";\nimport rehype2react from \"rehype-react\";\nimport breaks from \"remark-breaks\";\nimport remarkParse from \"remark-parse\";\nimport remark2rehype from \"remark-rehype\";\nimport remarkUnlinkProtocols from \"remark-unlink-protocols\";\nimport { unified } from \"unified\";\nimport { defineComponent, ref } from \"vue\";\nimport { RouterLink } from \"vue-router\";\nimport { N as NcCheckboxRadioSwitch } from \"./NcCheckboxRadioSwitch-D4IV4zWy.mjs\";\nimport { getCurrentUser } from \"@nextcloud/auth\";\nimport axios from \"@nextcloud/axios\";\nimport { generateOcsUrl } from \"@nextcloud/router\";\nimport { getSharingToken } from \"@nextcloud/sharing/public\";\nimport { f as NcReferenceWidget } from \"./referencePickerModal-B69WouiU.mjs\";\nimport { l as logger } from \"./logger-D3RVzcfQ.mjs\";\nimport { U as URL_PATTERN, p as parseUrl, r as remarkAutolink, g as getRoute, N as NcRichTextExternalLink } from \"./autolink-CeB9uxD9.mjs\";\nimport { n as normalizeComponent } from \"./_plugin-vue2_normalizer-DU4iP6Vu.mjs\";\nimport { N as NcButton } from \"./NcButton-CCWEL9Ci.mjs\";\nimport { N as NcIconSvgWrapper } from \"./NcIconSvgWrapper-Bui9PhAS.mjs\";\nimport { u as useCopy } from \"./useCopy-DDDe5RYH.mjs\";\nimport { G as GenRandomId } from \"./GenRandomId-F5ebeBB_.mjs\";\nimport { u } from \"unist-builder\";\nimport { visitParents, EXIT, SKIP } from \"unist-util-visit-parents\";\nconst _sfc_main$2 = {\n name: \"NcReferenceList\",\n components: {\n NcReferenceWidget\n },\n /* eslint vue/require-prop-comment: warn -- TODO: Add a proper doc block about what this props do */\n props: {\n text: {\n type: String,\n default: \"\"\n },\n referenceData: {\n type: Array,\n default: null\n },\n limit: {\n type: Number,\n default: 1\n },\n displayFallback: {\n type: Boolean,\n default: false\n },\n interactive: {\n type: Boolean,\n // eslint-disable-next-line vue/no-boolean-default\n default: true\n },\n interactiveOptIn: {\n type: Boolean,\n default: false\n }\n },\n data() {\n return {\n references: null,\n loading: true\n };\n },\n computed: {\n isVisible() {\n return this.loading || this.displayedReferences.length !== 0;\n },\n values() {\n if (this.referenceData) {\n return this.referenceData;\n }\n if (this.displayFallback && !this.loading && !this.references) {\n return [this.fallbackReference];\n }\n return this.references ? Object.values(this.references) : [];\n },\n firstReference() {\n return this.values[0] ?? null;\n },\n displayedReferences() {\n return this.values.filter(Boolean).slice(0, this.limit);\n },\n fallbackReference() {\n return {\n accessible: true,\n openGraphObject: {\n id: this.text,\n link: this.text,\n name: this.text\n },\n richObjectType: \"open-graph\"\n };\n }\n },\n watch: {\n text: \"fetch\"\n },\n mounted() {\n this.fetch();\n },\n methods: {\n fetch() {\n this.loading = true;\n if (this.referenceData) {\n this.references = null;\n this.loading = false;\n return;\n }\n if (!new RegExp(URL_PATTERN).exec(this.text)) {\n this.references = null;\n this.loading = false;\n return;\n }\n this.resolve().then((response) => {\n this.references = response.data.ocs.data.references;\n this.loading = false;\n this.$emit(\"loaded\");\n }).catch((error) => {\n logger.error(\"Failed to extract references\", { error });\n this.loading = false;\n this.$emit(\"loaded\");\n });\n },\n resolve() {\n const match = new RegExp(URL_PATTERN).exec(this.text.trim());\n const isPublic = getCurrentUser() === null;\n if (this.limit === 1 && match) {\n return isPublic ? axios.get(generateOcsUrl(\"references/resolvePublic\") + `?reference=${encodeURIComponent(match[0])}&sharingToken=${getSharingToken()}`) : axios.get(generateOcsUrl(\"references/resolve\") + `?reference=${encodeURIComponent(match[0])}`);\n }\n return isPublic ? axios.post(generateOcsUrl(\"references/extractPublic\"), {\n text: this.text,\n resolve: true,\n limit: this.limit,\n sharingToken: getSharingToken()\n }) : axios.post(generateOcsUrl(\"references/extract\"), {\n text: this.text,\n resolve: true,\n limit: this.limit\n });\n }\n }\n};\nvar _sfc_render$2 = function render() {\n var _vm = this, _c = _vm._self._c;\n return _vm.isVisible ? _c(\"div\", { staticClass: \"widgets--list\", class: { \"icon-loading\": _vm.loading } }, _vm._l(_vm.displayedReferences, function(reference) {\n return _c(\"NcReferenceWidget\", { key: reference.openGraphObject?.id, attrs: { \"reference\": reference, \"interactive\": _vm.interactive, \"interactive-opt-in\": _vm.interactiveOptIn } });\n }), 1) : _vm._e();\n};\nvar _sfc_staticRenderFns$2 = [];\nvar __component__$2 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$2,\n _sfc_render$2,\n _sfc_staticRenderFns$2,\n false,\n null,\n \"a50e616b\"\n);\nconst NcReferenceList = __component__$2.exports;\nfunction ccount(value, character) {\n const source = String(value);\n if (typeof character !== \"string\") {\n throw new TypeError(\"Expected character\");\n }\n let count = 0;\n let index = source.indexOf(character);\n while (index !== -1) {\n count++;\n index = source.indexOf(character, index + character.length);\n }\n return count;\n}\nfunction ok$1() {\n}\nconst asciiAlpha = regexCheck(/[A-Za-z]/);\nconst asciiAlphanumeric = regexCheck(/[\\dA-Za-z]/);\nfunction asciiControl(code2) {\n return (\n // Special whitespace codes (which have negative values), C0 and Control\n // character DEL\n code2 !== null && (code2 < 32 || code2 === 127)\n );\n}\nfunction markdownLineEnding(code2) {\n return code2 !== null && code2 < -2;\n}\nfunction markdownLineEndingOrSpace(code2) {\n return code2 !== null && (code2 < 0 || code2 === 32);\n}\nfunction markdownSpace(code2) {\n return code2 === -2 || code2 === -1 || code2 === 32;\n}\nconst unicodePunctuation = regexCheck(new RegExp(\"\\\\p{P}|\\\\p{S}\", \"u\"));\nconst unicodeWhitespace = regexCheck(/\\s/);\nfunction regexCheck(regex) {\n return check;\n function check(code2) {\n return code2 !== null && code2 > -1 && regex.test(String.fromCharCode(code2));\n }\n}\nfunction escapeStringRegexp(string) {\n if (typeof string !== \"string\") {\n throw new TypeError(\"Expected a string\");\n }\n return string.replace(/[|\\\\{}()[\\]^$+*?.]/g, \"\\\\$&\").replace(/-/g, \"\\\\x2d\");\n}\nconst convert = (\n // Note: overloads in JSDoc cant yet use different `@template`s.\n /**\n * @type {(\n * (<Condition extends string>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & {type: Condition}) &\n * (<Condition extends Props>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Condition) &\n * (<Condition extends TestFunction>(test: Condition) => (node: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node & Predicate<Condition, Node>) &\n * ((test?: null | undefined) => (node?: unknown, index?: number | null | undefined, parent?: Parent | null | undefined, context?: unknown) => node is Node) &\n * ((test?: Test) => Check)\n * )}\n */\n /**\n * @param {Test} [test]\n * @returns {Check}\n */\n (function(test) {\n if (test === null || test === void 0) {\n return ok;\n }\n if (typeof test === \"function\") {\n return castFactory(test);\n }\n if (typeof test === \"object\") {\n return Array.isArray(test) ? anyFactory(test) : (\n // Cast because `ReadonlyArray` goes into the above but `isArray`\n // narrows to `Array`.\n propertiesFactory(\n /** @type {Props} */\n test\n )\n );\n }\n if (typeof test === \"string\") {\n return typeFactory(test);\n }\n throw new Error(\"Expected function, string, or object as test\");\n })\n);\nfunction anyFactory(tests) {\n const checks = [];\n let index = -1;\n while (++index < tests.length) {\n checks[index] = convert(tests[index]);\n }\n return castFactory(any);\n function any(...parameters) {\n let index2 = -1;\n while (++index2 < checks.length) {\n if (checks[index2].apply(this, parameters)) return true;\n }\n return false;\n }\n}\nfunction propertiesFactory(check) {\n const checkAsRecord = (\n /** @type {Record<string, unknown>} */\n check\n );\n return castFactory(all);\n function all(node) {\n const nodeAsRecord = (\n /** @type {Record<string, unknown>} */\n /** @type {unknown} */\n node\n );\n let key;\n for (key in check) {\n if (nodeAsRecord[key] !== checkAsRecord[key]) return false;\n }\n return true;\n }\n}\nfunction typeFactory(check) {\n return castFactory(type);\n function type(node) {\n return node && node.type === check;\n }\n}\nfunction castFactory(testFunction) {\n return check;\n function check(value, index, parent) {\n return Boolean(\n looksLikeANode(value) && testFunction.call(\n this,\n value,\n typeof index === \"number\" ? index : void 0,\n parent || void 0\n )\n );\n }\n}\nfunction ok() {\n return true;\n}\nfunction looksLikeANode(value) {\n return value !== null && typeof value === \"object\" && \"type\" in value;\n}\nfunction findAndReplace(tree, list2, options) {\n const settings = options || {};\n const ignored = convert(settings.ignore || []);\n const pairs = toPairs(list2);\n let pairIndex = -1;\n while (++pairIndex < pairs.length) {\n visitParents(tree, \"text\", visitor);\n }\n function visitor(node, parents) {\n let index = -1;\n let grandparent;\n while (++index < parents.length) {\n const parent = parents[index];\n const siblings = grandparent ? grandparent.children : void 0;\n if (ignored(\n parent,\n siblings ? siblings.indexOf(parent) : void 0,\n grandparent\n )) {\n return;\n }\n grandparent = parent;\n }\n if (grandparent) {\n return handler(node, parents);\n }\n }\n function handler(node, parents) {\n const parent = parents[parents.length - 1];\n const find = pairs[pairIndex][0];\n const replace2 = pairs[pairIndex][1];\n let start = 0;\n const siblings = parent.children;\n const index = siblings.indexOf(node);\n let change = false;\n let nodes = [];\n find.lastIndex = 0;\n let match = find.exec(node.value);\n while (match) {\n const position = match.index;\n const matchObject = {\n index: match.index,\n input: match.input,\n stack: [...parents, node]\n };\n let value = replace2(...match, matchObject);\n if (typeof value === \"string\") {\n value = value.length > 0 ? { type: \"text\", value } : void 0;\n }\n if (value === false) {\n find.lastIndex = position + 1;\n } else {\n if (start !== position) {\n nodes.push({\n type: \"text\",\n value: node.value.slice(start, position)\n });\n }\n if (Array.isArray(value)) {\n nodes.push(...value);\n } else if (value) {\n nodes.push(value);\n }\n start = position + match[0].length;\n change = true;\n }\n if (!find.global) {\n break;\n }\n match = find.exec(node.value);\n }\n if (change) {\n if (start < node.value.length) {\n nodes.push({ type: \"text\", value: node.value.slice(start) });\n }\n parent.children.splice(index, 1, ...nodes);\n } else {\n nodes = [node];\n }\n return index + nodes.length;\n }\n}\nfunction toPairs(tupleOrList) {\n const result = [];\n if (!Array.isArray(tupleOrList)) {\n throw new TypeError(\"Expected find and replace tuple or list of tuples\");\n }\n const list2 = !tupleOrList[0] || Array.isArray(tupleOrList[0]) ? tupleOrList : [tupleOrList];\n let index = -1;\n while (++index < list2.length) {\n const tuple = list2[index];\n result.push([toExpression(tuple[0]), toFunction(tuple[1])]);\n }\n return result;\n}\nfunction toExpression(find) {\n return typeof find === \"string\" ? new RegExp(escapeStringRegexp(find), \"g\") : find;\n}\nfunction toFunction(replace2) {\n return typeof replace2 === \"function\" ? replace2 : function() {\n return replace2;\n };\n}\nconst inConstruct = \"phrasing\";\nconst notInConstruct = [\"autolink\", \"link\", \"image\", \"label\"];\nfunction gfmAutolinkLiteralFromMarkdown() {\n return {\n transforms: [transformGfmAutolinkLiterals],\n enter: {\n literalAutolink: enterLiteralAutolink,\n literalAutolinkEmail: enterLiteralAutolinkValue,\n literalAutolinkHttp: enterLiteralAutolinkValue,\n literalAutolinkWww: enterLiteralAutolinkValue\n },\n exit: {\n literalAutolink: exitLiteralAutolink,\n literalAutolinkEmail: exitLiteralAutolinkEmail,\n literalAutolinkHttp: exitLiteralAutolinkHttp,\n literalAutolinkWww: exitLiteralAutolinkWww\n }\n };\n}\nfunction gfmAutolinkLiteralToMarkdown() {\n return {\n unsafe: [\n {\n character: \"@\",\n before: \"[+\\\\-.\\\\w]\",\n after: \"[\\\\-.\\\\w]\",\n inConstruct,\n notInConstruct\n },\n {\n character: \".\",\n before: \"[Ww]\",\n after: \"[\\\\-.\\\\w]\",\n inConstruct,\n notInConstruct\n },\n {\n character: \":\",\n before: \"[ps]\",\n after: \"\\\\/\",\n inConstruct,\n notInConstruct\n }\n ]\n };\n}\nfunction enterLiteralAutolink(token) {\n this.enter({ type: \"link\", title: null, url: \"\", children: [] }, token);\n}\nfunction enterLiteralAutolinkValue(token) {\n this.config.enter.autolinkProtocol.call(this, token);\n}\nfunction exitLiteralAutolinkHttp(token) {\n this.config.exit.autolinkProtocol.call(this, token);\n}\nfunction exitLiteralAutolinkWww(token) {\n this.config.exit.data.call(this, token);\n const node = this.stack[this.stack.length - 1];\n ok$1(node.type === \"link\");\n node.url = \"http://\" + this.sliceSerialize(token);\n}\nfunction exitLiteralAutolinkEmail(token) {\n this.config.exit.autolinkEmail.call(this, token);\n}\nfunction exitLiteralAutolink(token) {\n this.exit(token);\n}\nfunction transformGfmAutolinkLiterals(tree) {\n findAndReplace(\n tree,\n [\n [/(https?:\\/\\/|www(?=\\.))([-.\\w]+)([^ \\t\\r\\n]*)/gi, findUrl],\n [/([-.\\w+]+)@([-\\w]+(?:\\.[-\\w]+)+)/g, findEmail]\n ],\n { ignore: [\"link\", \"linkReference\"] }\n );\n}\nfunction findUrl(_, protocol, domain2, path2, match) {\n let prefix = \"\";\n if (!previous(match)) {\n return false;\n }\n if (/^w/i.test(protocol)) {\n domain2 = protocol + domain2;\n protocol = \"\";\n prefix = \"http://\";\n }\n if (!isCorrectDomain(domain2)) {\n return false;\n }\n const parts = splitUrl(domain2 + path2);\n if (!parts[0]) return false;\n const result = {\n type: \"link\",\n title: null,\n url: prefix + protocol + parts[0],\n children: [{ type: \"text\", value: protocol + parts[0] }]\n };\n if (parts[1]) {\n return [result, { type: \"text\", value: parts[1] }];\n }\n return result;\n}\nfunction findEmail(_, atext, label, match) {\n if (\n // Not an expected previous character.\n !previous(match, true) || // Label ends in not allowed character.\n /[-\\d_]$/.test(label)\n ) {\n return false;\n }\n return {\n type: \"link\",\n title: null,\n url: \"mailto:\" + atext + \"@\" + label,\n children: [{ type: \"text\", value: atext + \"@\" + label }]\n };\n}\nfunction isCorrectDomain(domain2) {\n const parts = domain2.split(\".\");\n if (parts.length < 2 || parts[parts.length - 1] && (/_/.test(parts[parts.length - 1]) || !/[a-zA-Z\\d]/.test(parts[parts.length - 1])) || parts[parts.length - 2] && (/_/.test(parts[parts.length - 2]) || !/[a-zA-Z\\d]/.test(parts[parts.length - 2]))) {\n return false;\n }\n return true;\n}\nfunction splitUrl(url) {\n const trailExec = /[!\"&'),.:;<>?\\]}]+$/.exec(url);\n if (!trailExec) {\n return [url, void 0];\n }\n url = url.slice(0, trailExec.index);\n let trail2 = trailExec[0];\n let closingParenIndex = trail2.indexOf(\")\");\n const openingParens = ccount(url, \"(\");\n let closingParens = ccount(url, \")\");\n while (closingParenIndex !== -1 && openingParens > closingParens) {\n url += trail2.slice(0, closingParenIndex + 1);\n trail2 = trail2.slice(closingParenIndex + 1);\n closingParenIndex = trail2.indexOf(\")\");\n closingParens++;\n }\n return [url, trail2];\n}\nfunction previous(match, email) {\n const code2 = match.input.charCodeAt(match.index - 1);\n return (match.index === 0 || unicodeWhitespace(code2) || unicodePunctuation(code2)) && (!email || code2 !== 47);\n}\nfunction normalizeIdentifier(value) {\n return value.replace(/[\\t\\n\\r ]+/g, \" \").replace(/^ | $/g, \"\").toLowerCase().toUpperCase();\n}\nfootnoteReference.peek = footnoteReferencePeek;\nfunction gfmFootnoteFromMarkdown() {\n return {\n enter: {\n gfmFootnoteDefinition: enterFootnoteDefinition,\n gfmFootnoteDefinitionLabelString: enterFootnoteDefinitionLabelString,\n gfmFootnoteCall: enterFootnoteCall,\n gfmFootnoteCallString: enterFootnoteCallString\n },\n exit: {\n gfmFootnoteDefinition: exitFootnoteDefinition,\n gfmFootnoteDefinitionLabelString: exitFootnoteDefinitionLabelString,\n gfmFootnoteCall: exitFootnoteCall,\n gfmFootnoteCallString: exitFootnoteCallString\n }\n };\n}\nfunction gfmFootnoteToMarkdown() {\n return {\n // This is on by default already.\n unsafe: [{ character: \"[\", inConstruct: [\"phrasing\", \"label\", \"reference\"] }],\n handlers: { footnoteDefinition, footnoteReference }\n };\n}\nfunction enterFootnoteDefinition(token) {\n this.enter(\n { type: \"footnoteDefinition\", identifier: \"\", label: \"\", children: [] },\n token\n );\n}\nfunction enterFootnoteDefinitionLabelString() {\n this.buffer();\n}\nfunction exitFootnoteDefinitionLabelString(token) {\n const label = this.resume();\n const node = this.stack[this.stack.length - 1];\n ok$1(node.type === \"footnoteDefinition\");\n node.label = label;\n node.identifier = normalizeIdentifier(\n this.sliceSerialize(token)\n ).toLowerCase();\n}\nfunction exitFootnoteDefinition(token) {\n this.exit(token);\n}\nfunction enterFootnoteCall(token) {\n this.enter({ type: \"footnoteReference\", identifier: \"\", label: \"\" }, token);\n}\nfunction enterFootnoteCallString() {\n this.buffer();\n}\nfunction exitFootnoteCallString(token) {\n const label = this.resume();\n const node = this.stack[this.stack.length - 1];\n ok$1(node.type === \"footnoteReference\");\n node.label = label;\n node.identifier = normalizeIdentifier(\n this.sliceSerialize(token)\n ).toLowerCase();\n}\nfunction exitFootnoteCall(token) {\n this.exit(token);\n}\nfunction footnoteReference(node, _, state, info) {\n const tracker = state.createTracker(info);\n let value = tracker.move(\"[^\");\n const exit2 = state.enter(\"footnoteReference\");\n const subexit = state.enter(\"reference\");\n value += tracker.move(\n state.safe(state.associationId(node), {\n ...tracker.current(),\n before: value,\n after: \"]\"\n })\n );\n subexit();\n exit2();\n value += tracker.move(\"]\");\n return value;\n}\nfunction footnoteReferencePeek() {\n return \"[\";\n}\nfunction footnoteDefinition(node, _, state, info) {\n const tracker = state.createTracker(info);\n let value = tracker.move(\"[^\");\n const exit2 = state.enter(\"footnoteDefinition\");\n const subexit = state.enter(\"label\");\n value += tracker.move(\n state.safe(state.associationId(node), {\n ...tracker.current(),\n before: value,\n after: \"]\"\n })\n );\n subexit();\n value += tracker.move(\n \"]:\" + (node.children && node.children.length > 0 ? \" \" : \"\")\n );\n tracker.shift(4);\n value += tracker.move(\n state.indentLines(state.containerFlow(node, tracker.current()), map$2)\n );\n exit2();\n return value;\n}\nfunction map$2(line, index, blank) {\n if (index === 0) {\n return line;\n }\n return (blank ? \"\" : \" \") + line;\n}\nconst constructsWithoutStrikethrough = [\n \"autolink\",\n \"destinationLiteral\",\n \"destinationRaw\",\n \"reference\",\n \"titleQuote\",\n \"titleApostrophe\"\n];\nhandleDelete.peek = peekDelete;\nfunction gfmStrikethroughFromMarkdown() {\n return {\n canContainEols: [\"delete\"],\n enter: { strikethrough: enterStrikethrough },\n exit: { strikethrough: exitStrikethrough }\n };\n}\nfunction gfmStrikethroughToMarkdown() {\n return {\n unsafe: [\n {\n character: \"~\",\n inConstruct: \"phrasing\",\n notInConstruct: constructsWithoutStrikethrough\n }\n ],\n handlers: { delete: handleDelete }\n };\n}\nfunction enterStrikethrough(token) {\n this.enter({ type: \"delete\", children: [] }, token);\n}\nfunction exitStrikethrough(token) {\n this.exit(token);\n}\nfunction handleDelete(node, _, state, info) {\n const tracker = state.createTracker(info);\n const exit2 = state.enter(\"strikethrough\");\n let value = tracker.move(\"~~\");\n value += state.containerPhrasing(node, {\n ...tracker.current(),\n before: value,\n after: \"~\"\n });\n value += tracker.move(\"~~\");\n exit2();\n return value;\n}\nfunction peekDelete() {\n return \"~\";\n}\nfunction markdownTable(table, options = {}) {\n const align = (options.align || []).concat();\n const stringLength = options.stringLength || defaultStringLength;\n const alignments = [];\n const cellMatrix = [];\n const sizeMatrix = [];\n const longestCellByColumn = [];\n let mostCellsPerRow = 0;\n let rowIndex = -1;\n while (++rowIndex < table.length) {\n const row2 = [];\n const sizes2 = [];\n let columnIndex2 = -1;\n if (table[rowIndex].length > mostCellsPerRow) {\n mostCellsPerRow = table[rowIndex].length;\n }\n while (++columnIndex2 < table[rowIndex].length) {\n const cell = serialize(table[rowIndex][columnIndex2]);\n if (options.alignDelimiters !== false) {\n const size = stringLength(cell);\n sizes2[columnIndex2] = size;\n if (longestCellByColumn[columnIndex2] === void 0 || size > longestCellByColumn[columnIndex2]) {\n longestCellByColumn[columnIndex2] = size;\n }\n }\n row2.push(cell);\n }\n cellMatrix[rowIndex] = row2;\n sizeMatrix[rowIndex] = sizes2;\n }\n let columnIndex = -1;\n if (typeof align === \"object\" && \"length\" in align) {\n while (++columnIndex < mostCellsPerRow) {\n alignments[columnIndex] = toAlignment(align[columnIndex]);\n }\n } else {\n const code2 = toAlignment(align);\n while (++columnIndex < mostCellsPerRow) {\n alignments[columnIndex] = code2;\n }\n }\n columnIndex = -1;\n const row = [];\n const sizes = [];\n while (++columnIndex < mostCellsPerRow) {\n const code2 = alignments[columnIndex];\n let before = \"\";\n let after = \"\";\n if (code2 === 99) {\n before = \":\";\n after = \":\";\n } else if (code2 === 108) {\n before = \":\";\n } else if (code2 === 114) {\n after = \":\";\n }\n let size = options.alignDelimiters === false ? 1 : Math.max(\n 1,\n longestCellByColumn[columnIndex] - before.length - after.length\n );\n const cell = before + \"-\".repeat(size) + after;\n if (options.alignDelimiters !== false) {\n size = before.length + size + after.length;\n if (size > longestCellByColumn[columnIndex]) {\n longestCellByColumn[columnIndex] = size;\n }\n sizes[columnIndex] = size;\n }\n row[columnIndex] = cell;\n }\n cellMatrix.splice(1, 0, row);\n sizeMatrix.splice(1, 0, sizes);\n rowIndex = -1;\n const lines = [];\n while (++rowIndex < cellMatrix.length) {\n const row2 = cellMatrix[rowIndex];\n const sizes2 = sizeMatrix[rowIndex];\n columnIndex = -1;\n const line = [];\n while (++columnIndex < mostCellsPerRow) {\n const cell = row2[columnIndex] || \"\";\n let before = \"\";\n let after = \"\";\n if (options.alignDelimiters !== false) {\n const size = longestCellByColumn[columnIndex] - (sizes2[columnIndex] || 0);\n const code2 = alignments[columnIndex];\n if (code2 === 114) {\n before = \" \".repeat(size);\n } else if (code2 === 99) {\n if (size % 2) {\n before = \" \".repeat(size / 2 + 0.5);\n after = \" \".repeat(size / 2 - 0.5);\n } else {\n before = \" \".repeat(size / 2);\n after = before;\n }\n } else {\n after = \" \".repeat(size);\n }\n }\n if (options.delimiterStart !== false && !columnIndex) {\n line.push(\"|\");\n }\n if (options.padding !== false && // Dont add the opening space if were not aligning and the cell is\n // empty: there will be a closing space.\n !(options.alignDelimiters === false && cell === \"\") && (options.delimiterStart !== false || columnIndex)) {\n line.push(\" \");\n }\n if (options.alignDelimiters !== false) {\n line.push(before);\n }\n line.push(cell);\n if (options.alignDelimiters !== false) {\n line.push(after);\n }\n if (options.padding !== false) {\n line.push(\" \");\n }\n if (options.delimiterEnd !== false || columnIndex !== mostCellsPerRow - 1) {\n line.push(\"|\");\n }\n }\n lines.push(\n options.delimiterEnd === false ? line.join(\"\").replace(/ +$/, \"\") : line.join(\"\")\n );\n }\n return lines.join(\"\\n\");\n}\nfunction serialize(value) {\n return value === null || value === void 0 ? \"\" : String(value);\n}\nfunction defaultStringLength(value) {\n return value.length;\n}\nfunction toAlignment(value) {\n const code2 = typeof value === \"string\" ? value.codePointAt(0) : 0;\n return code2 === 67 || code2 === 99 ? 99 : code2 === 76 || code2 === 108 ? 108 : code2 === 82 || code2 === 114 ? 114 : 0;\n}\nfunction blockquote(node, _, state, info) {\n const exit2 = state.enter(\"blockquote\");\n const tracker = state.createTracker(info);\n tracker.move(\"> \");\n tracker.shift(2);\n const value = state.indentLines(\n state.containerFlow(node, tracker.current()),\n map$1\n );\n exit2();\n return value;\n}\nfunction map$1(line, _, blank) {\n return \">\" + (blank ? \"\" : \" \") + line;\n}\nfunction patternInScope(stack, pattern) {\n return listInScope(stack, pattern.inConstruct, true) && !listInScope(stack, pattern.notInConstruct, false);\n}\nfunction listInScope(stack, list2, none) {\n if (typeof list2 === \"string\") {\n list2 = [list2];\n }\n if (!list2 || list2.length === 0) {\n return none;\n }\n let index = -1;\n while (++index < list2.length) {\n if (stack.includes(list2[index])) {\n return true;\n }\n }\n return false;\n}\nfunction hardBreak(_, _1, state, info) {\n let index = -1;\n while (++index < state.unsafe.length) {\n if (state.unsafe[index].character === \"\\n\" && patternInScope(state.stack, state.unsafe[index])) {\n return /[ \\t]/.test(info.before) ? \"\" : \" \";\n }\n }\n return \"\\\\\\n\";\n}\nfunction longestStreak(value, substring) {\n const source = String(value);\n let index = source.indexOf(substring);\n let expected = index;\n let count = 0;\n let max = 0;\n if (typeof substring !== \"string\") {\n throw new TypeError(\"Expected substring\");\n }\n while (index !== -1) {\n if (index === expected) {\n if (++count > max) {\n max = count;\n }\n } else {\n count = 1;\n }\n expected = index + substring.length;\n index = source.indexOf(substring, expected);\n }\n return max;\n}\nfunction formatCodeAsIndented(node, state) {\n return Boolean(\n state.options.fences === false && node.value && // If theres no info…\n !node.lang && // And theres a non-whitespace character…\n /[^ \\r\\n]/.test(node.value) && // And the value doesnt start or end in a blank…\n !/^[\\t ]*(?:[\\r\\n]|$)|(?:^|[\\r\\n])[\\t ]*$/.test(node.value)\n );\n}\nfunction checkFence(state) {\n const marker = state.options.fence || \"`\";\n if (marker !== \"`\" && marker !== \"~\") {\n throw new Error(\n \"Cannot serialize code with `\" + marker + \"` for `options.fence`, expected `` ` `` or `~`\"\n );\n }\n return marker;\n}\nfunction code$1(node, _, state, info) {\n const marker = checkFence(state);\n const raw = node.value || \"\";\n const suffix = marker === \"`\" ? \"GraveAccent\" : \"Tilde\";\n if (formatCodeAsIndented(node, state)) {\n const exit3 = state.enter(\"codeIndented\");\n const value2 = state.indentLines(raw, map);\n exit3();\n return value2;\n }\n const tracker = state.createTracker(info);\n const sequence = marker.repeat(Math.max(longestStreak(raw, marker) + 1, 3));\n const exit2 = state.enter(\"codeFenced\");\n let value = tracker.move(sequence);\n if (node.lang) {\n const subexit = state.enter(`codeFencedLang${suffix}`);\n value += tracker.move(\n state.safe(node.lang, {\n before: value,\n after: \" \",\n encode: [\"`\"],\n ...tracker.current()\n })\n );\n subexit();\n }\n if (node.lang && node.meta) {\n const subexit = state.enter(`codeFencedMeta${suffix}`);\n value += tracker.move(\" \");\n value += tracker.move(\n state.safe(node.meta, {\n before: value,\n after: \"\\n\",\n encode: [\"`\"],\n ...tracker.current()\n })\n );\n subexit();\n }\n value += tracker.move(\"\\n\");\n if (raw) {\n value += tracker.move(raw + \"\\n\");\n }\n value += tracker.move(sequence);\n exit2();\n return value;\n}\nfunction map(line, _, blank) {\n return (blank ? \"\" : \" \") + line;\n}\nfunction checkQuote(state) {\n const marker = state.options.quote || '\"';\n if (marker !== '\"' && marker !== \"'\") {\n throw new Error(\n \"Cannot serialize title with `\" + marker + \"` for `options.quote`, expected `\\\"`, or `'`\"\n );\n }\n return marker;\n}\nfunction definition(node, _, state, info) {\n const quote = checkQuote(state);\n const suffix = quote === '\"' ? \"Quote\" : \"Apostrophe\";\n const exit2 = state.enter(\"definition\");\n let subexit = state.enter(\"label\");\n const tracker = state.createTracker(info);\n let value = tracker.move(\"[\");\n value += tracker.move(\n state.safe(state.associationId(node), {\n before: value,\n after: \"]\",\n ...tracker.current()\n })\n );\n value += tracker.move(\"]: \");\n subexit();\n if (\n // If theres no url, or…\n !node.url || // If there are control characters or whitespace.\n /[\\0- \\u007F]/.test(node.url)\n ) {\n subexit = state.enter(\"destinationLiteral\");\n value += tracker.move(\"<\");\n value += tracker.move(\n state.safe(node.url, { before: value, after: \">\", ...tracker.current() })\n );\n value += tracker.move(\">\");\n } else {\n subexit = state.enter(\"destinationRaw\");\n value += tracker.move(\n state.safe(node.url, {\n before: value,\n after: node.title ? \" \" : \"\\n\",\n ...tracker.current()\n })\n );\n }\n subexit();\n if (node.title) {\n subexit = state.enter(`title${suffix}`);\n value += tracker.move(\" \" + quote);\n value += tracker.move(\n state.safe(node.title, {\n before: value,\n after: quote,\n ...tracker.current()\n })\n );\n value += tracker.move(quote);\n subexit();\n }\n exit2();\n return value;\n}\nfunction checkEmphasis(state) {\n const marker = state.options.emphasis || \"*\";\n if (marker !== \"*\" && marker !== \"_\") {\n throw new Error(\n \"Cannot serialize emphasis with `\" + marker + \"` for `options.emphasis`, expected `*`, or `_`\"\n );\n }\n return marker;\n}\nfunction encodeCharacterReference(code2) {\n return \"&#x\" + code2.toString(16).toUpperCase() + \";\";\n}\nfunction classifyCharacter(code2) {\n if (code2 === null || markdownLineEndingOrSpace(code2) || unicodeWhitespace(code2)) {\n return 1;\n }\n if (unicodePunctuation(code2)) {\n return 2;\n }\n}\nfunction encodeInfo(outside, inside, marker) {\n const outsideKind = classifyCharacter(outside);\n const insideKind = classifyCharacter(inside);\n if (outsideKind === void 0) {\n return insideKind === void 0 ? (\n // Letter inside:\n // we have to encode *both* letters for `_` as it is looser.\n // it already forms for `*` (and GFMs `~`).\n marker === \"_\" ? { inside: true, outside: true } : { inside: false, outside: false }\n ) : insideKind === 1 ? (\n // Whitespace inside: encode both (letter, whitespace).\n { inside: true, outside: true }\n ) : (\n // Punctuation inside: encode outer (letter)\n { inside: false, outside: true }\n );\n }\n if (outsideKind === 1) {\n return insideKind === void 0 ? (\n // Letter inside: already forms.\n { inside: false, outside: false }\n ) : insideKind === 1 ? (\n // Whitespace inside: encode both (whitespace).\n { inside: true, outside: true }\n ) : (\n // Punctuation inside: already forms.\n { inside: false, outside: false }\n );\n }\n return insideKind === void 0 ? (\n // Letter inside: already forms.\n { inside: false, outside: false }\n ) : insideKind === 1 ? (\n // Whitespace inside: encode inner (whitespace).\n { inside: true, outside: false }\n ) : (\n // Punctuation inside: already forms.\n { inside: false, outside: false }\n );\n}\nemphasis.peek = emphasisPeek;\nfunction emphasis(node, _, state, info) {\n const marker = checkEmphasis(state);\n const exit2 = state.enter(\"emphasis\");\n const tracker = state.createTracker(info);\n const before = tracker.move(marker);\n let between = tracker.move(\n state.containerPhrasing(node, {\n after: marker,\n before,\n ...tracker.current()\n })\n );\n const betweenHead = between.charCodeAt(0);\n const open = encodeInfo(\n info.before.charCodeAt(info.before.length - 1),\n betweenHead,\n marker\n );\n if (open.inside) {\n between = encodeCharacterReference(betweenHead) + between.slice(1);\n }\n const betweenTail = between.charCodeAt(between.length - 1);\n const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker);\n if (close.inside) {\n between = between.slice(0, -1) + encodeCharacterReference(betweenTail);\n }\n const after = tracker.move(marker);\n exit2();\n state.attentionEncodeSurroundingInfo = {\n after: close.outside,\n before: open.outside\n };\n return before + between + after;\n}\nfunction emphasisPeek(_, _1, state) {\n return state.options.emphasis || \"*\";\n}\nfunction visit(tree, testOrVisitor, visitorOrReverse, maybeReverse) {\n let reverse;\n let test;\n let visitor;\n if (typeof testOrVisitor === \"function\" && typeof visitorOrReverse !== \"function\") {\n test = void 0;\n visitor = testOrVisitor;\n reverse = visitorOrReverse;\n } else {\n test = testOrVisitor;\n visitor = visitorOrReverse;\n reverse = maybeReverse;\n }\n visitParents(tree, test, overload, reverse);\n function overload(node, parents) {\n const parent = parents[parents.length - 1];\n const index = parent ? parent.children.indexOf(node) : void 0;\n return visitor(node, index, parent);\n }\n}\nfunction formatHeadingAsSetext(node, state) {\n let literalWithBreak = false;\n visit(node, function(node2) {\n if (\"value\" in node2 && /\\r?\\n|\\r/.test(node2.value) || node2.type === \"break\") {\n literalWithBreak = true;\n return EXIT;\n }\n });\n return Boolean(\n (!node.depth || node.depth < 3) && toString(node) && (state.options.setext || literalWithBreak)\n );\n}\nfunction heading(node, _, state, info) {\n const rank = Math.max(Math.min(6, node.depth || 1), 1);\n const tracker = state.createTracker(info);\n if (formatHeadingAsSetext(node, state)) {\n const exit3 = state.enter(\"headingSetext\");\n const subexit2 = state.enter(\"phrasing\");\n const value2 = state.containerPhrasing(node, {\n ...tracker.current(),\n before: \"\\n\",\n after: \"\\n\"\n });\n subexit2();\n exit3();\n return value2 + \"\\n\" + (rank === 1 ? \"=\" : \"-\").repeat(\n // The whole size…\n value2.length - // Minus the position of the character after the last EOL (or\n // 0 if there is none)…\n (Math.max(value2.lastIndexOf(\"\\r\"), value2.lastIndexOf(\"\\n\")) + 1)\n );\n }\n const sequence = \"#\".repeat(rank);\n const exit2 = state.enter(\"headingAtx\");\n const subexit = state.enter(\"phrasing\");\n tracker.move(sequence + \" \");\n let value = state.containerPhrasing(node, {\n before: \"# \",\n after: \"\\n\",\n ...tracker.current()\n });\n if (/^[\\t ]/.test(value)) {\n value = encodeCharacterReference(value.charCodeAt(0)) + value.slice(1);\n }\n value = value ? sequence + \" \" + value : sequence;\n if (state.options.closeAtx) {\n value += \" \" + sequence;\n }\n subexit();\n exit2();\n return value;\n}\nhtml.peek = htmlPeek;\nfunction html(node) {\n return node.value || \"\";\n}\nfunction htmlPeek() {\n return \"<\";\n}\nimage.peek = imagePeek;\nfunction image(node, _, state, info) {\n const quote = checkQuote(state);\n const suffix = quote === '\"' ? \"Quote\" : \"Apostrophe\";\n const exit2 = state.enter(\"image\");\n let subexit = state.enter(\"label\");\n const tracker = state.createTracker(info);\n let value = tracker.move(\"![\");\n value += tracker.move(\n state.safe(node.alt, { before: value, after: \"]\", ...tracker.current() })\n );\n value += tracker.move(\"](\");\n subexit();\n if (\n // If theres no url but there is a title…\n !node.url && node.title || // If there are control characters or whitespace.\n /[\\0- \\u007F]/.test(node.url)\n ) {\n subexit = state.enter(\"destinationLiteral\");\n value += tracker.move(\"<\");\n value += tracker.move(\n state.safe(node.url, { before: value, after: \">\", ...tracker.current() })\n );\n value += tracker.move(\">\");\n } else {\n subexit = state.enter(\"destinationRaw\");\n value += tracker.move(\n state.safe(node.url, {\n before: value,\n after: node.title ? \" \" : \")\",\n ...tracker.current()\n })\n );\n }\n subexit();\n if (node.title) {\n subexit = state.enter(`title${suffix}`);\n value += tracker.move(\" \" + quote);\n value += tracker.move(\n state.safe(node.title, {\n before: value,\n after: quote,\n ...tracker.current()\n })\n );\n value += tracker.move(quote);\n subexit();\n }\n value += tracker.move(\")\");\n exit2();\n return value;\n}\nfunction imagePeek() {\n return \"!\";\n}\nimageReference.peek = imageReferencePeek;\nfunction imageReference(node, _, state, info) {\n const type = node.referenceType;\n const exit2 = state.enter(\"imageReference\");\n let subexit = state.enter(\"label\");\n const tracker = state.createTracker(info);\n let value = tracker.move(\"![\");\n const alt = state.safe(node.alt, {\n before: value,\n after: \"]\",\n ...tracker.current()\n });\n value += tracker.move(alt + \"][\");\n subexit();\n const stack = state.stack;\n state.stack = [];\n subexit = state.enter(\"reference\");\n const reference = state.safe(state.associationId(node), {\n before: value,\n after: \"]\",\n ...tracker.current()\n });\n subexit();\n state.stack = stack;\n exit2();\n if (type === \"full\" || !alt || alt !== reference) {\n value += tracker.move(reference + \"]\");\n } else if (type === \"shortcut\") {\n value = value.slice(0, -1);\n } else {\n value += tracker.move(\"]\");\n }\n return value;\n}\nfunction imageReferencePeek() {\n return \"!\";\n}\ninlineCode.peek = inlineCodePeek;\nfunction inlineCode(node, _, state) {\n let value = node.value || \"\";\n let sequence = \"`\";\n let index = -1;\n while (new RegExp(\"(^|[^`])\" + sequence + \"([^`]|$)\").test(value)) {\n sequence += \"`\";\n }\n if (/[^ \\r\\n]/.test(value) && (/^[ \\r\\n]/.test(value) && /[ \\r\\n]$/.test(value) || /^`|`$/.test(value))) {\n value = \" \" + value + \" \";\n }\n while (++index < state.unsafe.length) {\n const pattern = state.unsafe[index];\n const expression = state.compilePattern(pattern);\n let match;\n if (!pattern.atBreak) continue;\n while (match = expression.exec(value)) {\n let position = match.index;\n if (value.charCodeAt(position) === 10 && value.charCodeAt(position - 1) === 13) {\n position--;\n }\n value = value.slice(0, position) + \" \" + value.slice(match.index + 1);\n }\n }\n return sequence + value + sequence;\n}\nfunction inlineCodePeek() {\n return \"`\";\n}\nfunction formatLinkAsAutolink(node, state) {\n const raw = toString(node);\n return Boolean(\n !state.options.resourceLink && // If theres a url…\n node.url && // And theres a no title…\n !node.title && // And the content of `node` is a single text node…\n node.children && node.children.length === 1 && node.children[0].type === \"text\" && // And if the url is the same as the content…\n (raw === node.url || \"mailto:\" + raw === node.url) && // And that starts w/ a protocol…\n /^[a-z][a-z+.-]+:/i.test(node.url) && // And that doesnt contain ASCII control codes (character escapes and\n // references dont work), space, or angle brackets…\n !/[\\0- <>\\u007F]/.test(node.url)\n );\n}\nlink.peek = linkPeek;\nfunction link(node, _, state, info) {\n const quote = checkQuote(state);\n const suffix = quote === '\"' ? \"Quote\" : \"Apostrophe\";\n const tracker = state.createTracker(info);\n let exit2;\n let subexit;\n if (formatLinkAsAutolink(node, state)) {\n const stack = state.stack;\n state.stack = [];\n exit2 = state.enter(\"autolink\");\n let value2 = tracker.move(\"<\");\n value2 += tracker.move(\n state.containerPhrasing(node, {\n before: value2,\n after: \">\",\n ...tracker.current()\n })\n );\n value2 += tracker.move(\">\");\n exit2();\n state.stack = stack;\n return value2;\n }\n exit2 = state.enter(\"link\");\n subexit = state.enter(\"label\");\n let value = tracker.move(\"[\");\n value += tracker.move(\n state.containerPhrasing(node, {\n before: value,\n after: \"](\",\n ...tracker.current()\n })\n );\n value += tracker.move(\"](\");\n subexit();\n if (\n // If theres no url but there is a title…\n !node.url && node.title || // If there are control characters or whitespace.\n /[\\0- \\u007F]/.test(node.url)\n ) {\n subexit = state.enter(\"destinationLiteral\");\n value += tracker.move(\"<\");\n value += tracker.move(\n state.safe(node.url, { before: value, after: \">\", ...tracker.current() })\n );\n value += tracker.move(\">\");\n } else {\n subexit = state.enter(\"destinationRaw\");\n value += tracker.move(\n state.safe(node.url, {\n before: value,\n after: node.title ? \" \" : \")\",\n ...tracker.current()\n })\n );\n }\n subexit();\n if (node.title) {\n subexit = state.enter(`title${suffix}`);\n value += tracker.move(\" \" + quote);\n value += tracker.move(\n state.safe(node.title, {\n before: value,\n after: quote,\n ...tracker.current()\n })\n );\n value += tracker.move(quote);\n subexit();\n }\n value += tracker.move(\")\");\n exit2();\n return value;\n}\nfunction linkPeek(node, _, state) {\n return formatLinkAsAutolink(node, state) ? \"<\" : \"[\";\n}\nlinkReference.peek = linkReferencePeek;\nfunction linkReference(node, _, state, info) {\n const type = node.referenceType;\n const exit2 = state.enter(\"linkReference\");\n let subexit = state.enter(\"label\");\n const tracker = state.createTracker(info);\n let value = tracker.move(\"[\");\n const text2 = state.containerPhrasing(node, {\n before: value,\n after: \"]\",\n ...tracker.current()\n });\n value += tracker.move(text2 + \"][\");\n subexit();\n const stack = state.stack;\n state.stack = [];\n subexit = state.enter(\"reference\");\n const reference = state.safe(state.associationId(node), {\n before: value,\n after: \"]\",\n ...tracker.current()\n });\n subexit();\n state.stack = stack;\n exit2();\n if (type === \"full\" || !text2 || text2 !== reference) {\n value += tracker.move(reference + \"]\");\n } else if (type === \"shortcut\") {\n value = value.slice(0, -1);\n } else {\n value += tracker.move(\"]\");\n }\n return value;\n}\nfunction linkReferencePeek() {\n return \"[\";\n}\nfunction checkBullet(state) {\n const marker = state.options.bullet || \"*\";\n if (marker !== \"*\" && marker !== \"+\" && marker !== \"-\") {\n throw new Error(\n \"Cannot serialize items with `\" + marker + \"` for `options.bullet`, expected `*`, `+`, or `-`\"\n );\n }\n return marker;\n}\nfunction checkBulletOther(state) {\n const bullet = checkBullet(state);\n const bulletOther = state.options.bulletOther;\n if (!bulletOther) {\n return bullet === \"*\" ? \"-\" : \"*\";\n }\n if (bulletOther !== \"*\" && bulletOther !== \"+\" && bulletOther !== \"-\") {\n throw new Error(\n \"Cannot serialize items with `\" + bulletOther + \"` for `options.bulletOther`, expected `*`, `+`, or `-`\"\n );\n }\n if (bulletOther === bullet) {\n throw new Error(\n \"Expected `bullet` (`\" + bullet + \"`) and `bulletOther` (`\" + bulletOther + \"`) to be different\"\n );\n }\n return bulletOther;\n}\nfunction checkBulletOrdered(state) {\n const marker = state.options.bulletOrdered || \".\";\n if (marker !== \".\" && marker !== \")\") {\n throw new Error(\n \"Cannot serialize items with `\" + marker + \"` for `options.bulletOrdered`, expected `.` or `)`\"\n );\n }\n return marker;\n}\nfunction checkRule(state) {\n const marker = state.options.rule || \"*\";\n if (marker !== \"*\" && marker !== \"-\" && marker !== \"_\") {\n throw new Error(\n \"Cannot serialize rules with `\" + marker + \"` for `options.rule`, expected `*`, `-`, or `_`\"\n );\n }\n return marker;\n}\nfunction list(node, parent, state, info) {\n const exit2 = state.enter(\"list\");\n const bulletCurrent = state.bulletCurrent;\n let bullet = node.ordered ? checkBulletOrdered(state) : checkBullet(state);\n const bulletOther = node.ordered ? bullet === \".\" ? \")\" : \".\" : checkBulletOther(state);\n let useDifferentMarker = parent && state.bulletLastUsed ? bullet === state.bulletLastUsed : false;\n if (!node.ordered) {\n const firstListItem = node.children ? node.children[0] : void 0;\n if (\n // Bullet could be used as a thematic break marker:\n (bullet === \"*\" || bullet === \"-\") && // Empty first list item:\n firstListItem && (!firstListItem.children || !firstListItem.children[0]) && // Directly in two other list items:\n state.stack[state.stack.length - 1] === \"list\" && state.stack[state.stack.length - 2] === \"listItem\" && state.stack[state.stack.length - 3] === \"list\" && state.stack[state.stack.length - 4] === \"listItem\" && // That are each the first child.\n state.indexStack[state.indexStack.length - 1] === 0 && state.indexStack[state.indexStack.length - 2] === 0 && state.indexStack[state.indexStack.length - 3] === 0\n ) {\n useDifferentMarker = true;\n }\n if (checkRule(state) === bullet && firstListItem) {\n let index = -1;\n while (++index < node.children.length) {\n const item = node.children[index];\n if (item && item.type === \"listItem\" && item.children && item.children[0] && item.children[0].type === \"thematicBreak\") {\n useDifferentMarker = true;\n break;\n }\n }\n }\n }\n if (useDifferentMarker) {\n bullet = bulletOther;\n }\n state.bulletCurrent = bullet;\n const value = state.containerFlow(node, info);\n state.bulletLastUsed = bullet;\n state.bulletCurrent = bulletCurrent;\n exit2();\n return value;\n}\nfunction checkListItemIndent(state) {\n const style = state.options.listItemIndent || \"one\";\n if (style !== \"tab\" && style !== \"one\" && style !== \"mixed\") {\n throw new Error(\n \"Cannot serialize items with `\" + style + \"` for `options.listItemIndent`, expected `tab`, `one`, or `mixed`\"\n );\n }\n return style;\n}\nfunction listItem(node, parent, state, info) {\n const listItemIndent = checkListItemIndent(state);\n let bullet = state.bulletCurrent || checkBullet(state);\n if (parent && parent.type === \"list\" && parent.ordered) {\n bullet = (typeof parent.start === \"number\" && parent.start > -1 ? parent.start : 1) + (state.options.incrementListMarker === false ? 0 : parent.children.indexOf(node)) + bullet;\n }\n let size = bullet.length + 1;\n if (listItemIndent === \"tab\" || listItemIndent === \"mixed\" && (parent && parent.type === \"list\" && parent.spread || node.spread)) {\n size = Math.ceil(size / 4) * 4;\n }\n const tracker = state.createTracker(info);\n tracker.move(bullet + \" \".repeat(size - bullet.length));\n tracker.shift(size);\n const exit2 = state.enter(\"listItem\");\n const value = state.indentLines(\n state.containerFlow(node, tracker.current()),\n map2\n );\n exit2();\n return value;\n function map2(line, index, blank) {\n if (index) {\n return (blank ? \"\" : \" \".repeat(size)) + line;\n }\n return (blank ? bullet : bullet + \" \".repeat(size - bullet.length)) + line;\n }\n}\nfunction paragraph(node, _, state, info) {\n const exit2 = state.enter(\"paragraph\");\n const subexit = state.enter(\"phrasing\");\n const value = state.containerPhrasing(node, info);\n subexit();\n exit2();\n return value;\n}\nconst phrasing = (\n /** @type {(node?: unknown) => node is Exclude<PhrasingContent, Html>} */\n convert([\n \"break\",\n \"delete\",\n \"emphasis\",\n // To do: next major: removed since footnotes were added to GFM.\n \"footnote\",\n \"footnoteReference\",\n \"image\",\n \"imageReference\",\n \"inlineCode\",\n // Enabled by `mdast-util-math`:\n \"inlineMath\",\n \"link\",\n \"linkReference\",\n // Enabled by `mdast-util-mdx`:\n \"mdxJsxTextElement\",\n // Enabled by `mdast-util-mdx`:\n \"mdxTextExpression\",\n \"strong\",\n \"text\",\n // Enabled by `mdast-util-directive`:\n \"textDirective\"\n ])\n);\nfunction root(node, _, state, info) {\n const hasPhrasing = node.children.some(function(d) {\n return phrasing(d);\n });\n const container = hasPhrasing ? state.containerPhrasing : state.containerFlow;\n return container.call(state, node, info);\n}\nfunction checkStrong(state) {\n const marker = state.options.strong || \"*\";\n if (marker !== \"*\" && marker !== \"_\") {\n throw new Error(\n \"Cannot serialize strong with `\" + marker + \"` for `options.strong`, expected `*`, or `_`\"\n );\n }\n return marker;\n}\nstrong.peek = strongPeek;\nfunction strong(node, _, state, info) {\n const marker = checkStrong(state);\n const exit2 = state.enter(\"strong\");\n const tracker = state.createTracker(info);\n const before = tracker.move(marker + marker);\n let between = tracker.move(\n state.containerPhrasing(node, {\n after: marker,\n before,\n ...tracker.current()\n })\n );\n const betweenHead = between.charCodeAt(0);\n const open = encodeInfo(\n info.before.charCodeAt(info.before.length - 1),\n betweenHead,\n marker\n );\n if (open.inside) {\n between = encodeCharacterReference(betweenHead) + between.slice(1);\n }\n const betweenTail = between.charCodeAt(between.length - 1);\n const close = encodeInfo(info.after.charCodeAt(0), betweenTail, marker);\n if (close.inside) {\n between = between.slice(0, -1) + encodeCharacterReference(betweenTail);\n }\n const after = tracker.move(marker + marker);\n exit2();\n state.attentionEncodeSurroundingInfo = {\n after: close.outside,\n before: open.outside\n };\n return before + between + after;\n}\nfunction strongPeek(_, _1, state) {\n return state.options.strong || \"*\";\n}\nfunction text$1(node, _, state, info) {\n return state.safe(node.value, info);\n}\nfunction checkRuleRepetition(state) {\n const repetition = state.options.ruleRepetition || 3;\n if (repetition < 3) {\n throw new Error(\n \"Cannot serialize rules with repetition `\" + repetition + \"` for `options.ruleRepetition`, expected `3` or more\"\n );\n }\n return repetition;\n}\nfunction thematicBreak(_, _1, state) {\n const value = (checkRule(state) + (state.options.ruleSpaces ? \" \" : \"\")).repeat(checkRuleRepetition(state));\n return state.options.ruleSpaces ? value.slice(0, -1) : value;\n}\nconst handle = {\n blockquote,\n break: hardBreak,\n code: code$1,\n definition,\n emphasis,\n hardBreak,\n heading,\n html,\n image,\n imageReference,\n inlineCode,\n link,\n linkReference,\n list,\n listItem,\n paragraph,\n root,\n strong,\n text: text$1,\n thematicBreak\n};\nfunction gfmTableFromMarkdown() {\n return {\n enter: {\n table: enterTable,\n tableData: enterCell,\n tableHeader: enterCell,\n tableRow: enterRow\n },\n exit: {\n codeText: exitCodeText,\n table: exitTable,\n tableData: exit,\n tableHeader: exit,\n tableRow: exit\n }\n };\n}\nfunction enterTable(token) {\n const align = token._align;\n this.enter(\n {\n type: \"table\",\n align: align.map(function(d) {\n return d === \"none\" ? null : d;\n }),\n children: []\n },\n token\n );\n this.data.inTable = true;\n}\nfunction exitTable(token) {\n this.exit(token);\n this.data.inTable = void 0;\n}\nfunction enterRow(token) {\n this.enter({ type: \"tableRow\", children: [] }, token);\n}\nfunction exit(token) {\n this.exit(token);\n}\nfunction enterCell(token) {\n this.enter({ type: \"tableCell\", children: [] }, token);\n}\nfunction exitCodeText(token) {\n let value = this.resume();\n if (this.data.inTable) {\n value = value.replace(/\\\\([\\\\|])/g, replace);\n }\n const node = this.stack[this.stack.length - 1];\n ok$1(node.type === \"inlineCode\");\n node.value = value;\n this.exit(token);\n}\nfunction replace($0, $1) {\n return $1 === \"|\" ? $1 : $0;\n}\nfunction gfmTableToMarkdown(options) {\n const settings = options || {};\n const padding = settings.tableCellPadding;\n const alignDelimiters = settings.tablePipeAlign;\n const stringLength = settings.stringLength;\n const around = padding ? \" \" : \"|\";\n return {\n unsafe: [\n { character: \"\\r\", inConstruct: \"tableCell\" },\n { character: \"\\n\", inConstruct: \"tableCell\" },\n // A pipe, when followed by a tab or space (padding), or a dash or colon\n // (unpadded delimiter row), could result in a table.\n { atBreak: true, character: \"|\", after: \"[\t :-]\" },\n // A pipe in a cell must be encoded.\n { character: \"|\", inConstruct: \"tableCell\" },\n // A colon must be followed by a dash, in which case it could start a\n // delimiter row.\n { atBreak: true, character: \":\", after: \"-\" },\n // A delimiter row can also start with a dash, when followed by more\n // dashes, a colon, or a pipe.\n // This is a stricter version than the built in check for lists, thematic\n // breaks, and setex heading underlines though:\n // <https://github.com/syntax-tree/mdast-util-to-markdown/blob/51a2038/lib/unsafe.js#L57>\n { atBreak: true, character: \"-\", after: \"[:|-]\" }\n ],\n handlers: {\n inlineCode: inlineCodeWithTable,\n table: handleTable,\n tableCell: handleTableCell,\n tableRow: handleTableRow\n }\n };\n function handleTable(node, _, state, info) {\n return serializeData(handleTableAsData(node, state, info), node.align);\n }\n function handleTableRow(node, _, state, info) {\n const row = handleTableRowAsData(node, state, info);\n const value = serializeData([row]);\n return value.slice(0, value.indexOf(\"\\n\"));\n }\n function handleTableCell(node, _, state, info) {\n const exit2 = state.enter(\"tableCell\");\n const subexit = state.enter(\"phrasing\");\n const value = state.containerPhrasing(node, {\n ...info,\n before: around,\n after: around\n });\n subexit();\n exit2();\n return value;\n }\n function serializeData(matrix, align) {\n return markdownTable(matrix, {\n align,\n // @ts-expect-error: `markdown-table` types should support `null`.\n alignDelimiters,\n // @ts-expect-error: `markdown-table` types should support `null`.\n padding,\n // @ts-expect-error: `markdown-table` types should support `null`.\n stringLength\n });\n }\n function handleTableAsData(node, state, info) {\n const children = node.children;\n let index = -1;\n const result = [];\n const subexit = state.enter(\"table\");\n while (++index < children.length) {\n result[index] = handleTableRowAsData(children[index], state, info);\n }\n subexit();\n return result;\n }\n function handleTableRowAsData(node, state, info) {\n const children = node.children;\n let index = -1;\n const result = [];\n const subexit = state.enter(\"tableRow\");\n while (++index < children.length) {\n result[index] = handleTableCell(children[index], node, state, info);\n }\n subexit();\n return result;\n }\n function inlineCodeWithTable(node, parent, state) {\n let value = handle.inlineCode(node, parent, state);\n if (state.stack.includes(\"tableCell\")) {\n value = value.replace(/\\|/g, \"\\\\$&\");\n }\n return value;\n }\n}\nfunction gfmTaskListItemFromMarkdown() {\n return {\n exit: {\n taskListCheckValueChecked: exitCheck,\n taskListCheckValueUnchecked: exitCheck,\n paragraph: exitParagraphWithTaskListItem\n }\n };\n}\nfunction gfmTaskListItemToMarkdown() {\n return {\n unsafe: [{ atBreak: true, character: \"-\", after: \"[:|-]\" }],\n handlers: { listItem: listItemWithTaskListItem }\n };\n}\nfunction exitCheck(token) {\n const node = this.stack[this.stack.length - 2];\n ok$1(node.type === \"listItem\");\n node.checked = token.type === \"taskListCheckValueChecked\";\n}\nfunction exitParagraphWithTaskListItem(token) {\n const parent = this.stack[this.stack.length - 2];\n if (parent && parent.type === \"listItem\" && typeof parent.checked === \"boolean\") {\n const node = this.stack[this.stack.length - 1];\n ok$1(node.type === \"paragraph\");\n const head = node.children[0];\n if (head && head.type === \"text\") {\n const siblings = parent.children;\n let index = -1;\n let firstParaghraph;\n while (++index < siblings.length) {\n const sibling = siblings[index];\n if (sibling.type === \"paragraph\") {\n firstParaghraph = sibling;\n break;\n }\n }\n if (firstParaghraph === node) {\n head.value = head.value.slice(1);\n if (head.value.length === 0) {\n node.children.shift();\n } else if (node.position && head.position && typeof head.position.start.offset === \"number\") {\n head.position.start.column++;\n head.position.start.offset++;\n node.position.start = Object.assign({}, head.position.start);\n }\n }\n }\n }\n this.exit(token);\n}\nfunction listItemWithTaskListItem(node, parent, state, info) {\n const head = node.children[0];\n const checkable = typeof node.checked === \"boolean\" && head && head.type === \"paragraph\";\n const checkbox = \"[\" + (node.checked ? \"x\" : \" \") + \"] \";\n const tracker = state.createTracker(info);\n if (checkable) {\n tracker.move(checkbox);\n }\n let value = handle.listItem(node, parent, state, {\n ...info,\n ...tracker.current()\n });\n if (checkable) {\n value = value.replace(/^(?:[*+-]|\\d+\\.)([\\r\\n]| {1,3})/, check);\n }\n return value;\n function check($0) {\n return $0 + checkbox;\n }\n}\nfunction gfmFromMarkdown() {\n return [\n gfmAutolinkLiteralFromMarkdown(),\n gfmFootnoteFromMarkdown(),\n gfmStrikethroughFromMarkdown(),\n gfmTableFromMarkdown(),\n gfmTaskListItemFromMarkdown()\n ];\n}\nfunction gfmToMarkdown(options) {\n return {\n extensions: [\n gfmAutolinkLiteralToMarkdown(),\n gfmFootnoteToMarkdown(),\n gfmStrikethroughToMarkdown(),\n gfmTableToMarkdown(options),\n gfmTaskListItemToMarkdown()\n ]\n };\n}\nfunction splice(list2, start, remove, items) {\n const end = list2.length;\n let chunkStart = 0;\n let parameters;\n if (start < 0) {\n start = -start > end ? 0 : end + start;\n } else {\n start = start > end ? end : start;\n }\n remove = remove > 0 ? remove : 0;\n if (items.length < 1e4) {\n parameters = Array.from(items);\n parameters.unshift(start, remove);\n list2.splice(...parameters);\n } else {\n if (remove) list2.splice(start, remove);\n while (chunkStart < items.length) {\n parameters = items.slice(chunkStart, chunkStart + 1e4);\n parameters.unshift(start, 0);\n list2.splice(...parameters);\n chunkStart += 1e4;\n start += 1e4;\n }\n }\n}\nconst hasOwnProperty = {}.hasOwnProperty;\nfunction combineExtensions(extensions) {\n const all = {};\n let index = -1;\n while (++index < extensions.length) {\n syntaxExtension(all, extensions[index]);\n }\n return all;\n}\nfunction syntaxExtension(all, extension) {\n let hook;\n for (hook in extension) {\n const maybe = hasOwnProperty.call(all, hook) ? all[hook] : void 0;\n const left = maybe || (all[hook] = {});\n const right = extension[hook];\n let code2;\n if (right) {\n for (code2 in right) {\n if (!hasOwnProperty.call(left, code2)) left[code2] = [];\n const value = right[code2];\n constructs(\n // @ts-expect-error Looks like a list.\n left[code2],\n Array.isArray(value) ? value : value ? [value] : []\n );\n }\n }\n }\n}\nfunction constructs(existing, list2) {\n let index = -1;\n const before = [];\n while (++index < list2.length) {\n (list2[index].add === \"after\" ? existing : before).push(list2[index]);\n }\n splice(existing, 0, 0, before);\n}\nconst wwwPrefix = {\n tokenize: tokenizeWwwPrefix,\n partial: true\n};\nconst domain = {\n tokenize: tokenizeDomain,\n partial: true\n};\nconst path = {\n tokenize: tokenizePath,\n partial: true\n};\nconst trail = {\n tokenize: tokenizeTrail,\n partial: true\n};\nconst emailDomainDotTrail = {\n tokenize: tokenizeEmailDomainDotTrail,\n partial: true\n};\nconst wwwAutolink = {\n tokenize: tokenizeWwwAutolink,\n previous: previousWww\n};\nconst protocolAutolink = {\n tokenize: tokenizeProtocolAutolink,\n previous: previousProtocol\n};\nconst emailAutolink = {\n tokenize: tokenizeEmailAutolink,\n previous: previousEmail\n};\nconst text = {};\nfunction gfmAutolinkLiteral() {\n return {\n text\n };\n}\nlet code = 48;\nwhile (code < 123) {\n text[code] = emailAutolink;\n code++;\n if (code === 58) code = 65;\n else if (code === 91) code = 97;\n}\ntext[43] = emailAutolink;\ntext[45] = emailAutolink;\ntext[46] = emailAutolink;\ntext[95] = emailAutolink;\ntext[72] = [emailAutolink, protocolAutolink];\ntext[104] = [emailAutolink, protocolAutolink];\ntext[87] = [emailAutolink, wwwAutolink];\ntext[119] = [emailAutolink, wwwAutolink];\nfunction tokenizeEmailAutolink(effects, ok2, nok) {\n const self = this;\n let dot;\n let data;\n return start;\n function start(code2) {\n if (!gfmAtext(code2) || !previousEmail.call(self, self.previous) || previousUnbalanced(self.events)) {\n return nok(code2);\n }\n effects.enter(\"literalAutolink\");\n effects.enter(\"literalAutolinkEmail\");\n return atext(code2);\n }\n function atext(code2) {\n if (gfmAtext(code2)) {\n effects.consume(code2);\n return atext;\n }\n if (code2 === 64) {\n effects.consume(code2);\n return emailDomain;\n }\n return nok(code2);\n }\n function emailDomain(code2) {\n if (code2 === 46) {\n return effects.check(\n emailDomainDotTrail,\n emailDomainAfter,\n emailDomainDot\n )(code2);\n }\n if (code2 === 45 || code2 === 95 || asciiAlphanumeric(code2)) {\n data = true;\n effects.consume(code2);\n return emailDomain;\n }\n return emailDomainAfter(code2);\n }\n function emailDomainDot(code2) {\n effects.consume(code2);\n dot = true;\n return emailDomain;\n }\n function emailDomainAfter(code2) {\n if (data && dot && asciiAlpha(self.previous)) {\n effects.exit(\"literalAutolinkEmail\");\n effects.exit(\"literalAutolink\");\n return ok2(code2);\n }\n return nok(code2);\n }\n}\nfunction tokenizeWwwAutolink(effects, ok2, nok) {\n const self = this;\n return wwwStart;\n function wwwStart(code2) {\n if (code2 !== 87 && code2 !== 119 || !previousWww.call(self, self.previous) || previousUnbalanced(self.events)) {\n return nok(code2);\n }\n effects.enter(\"literalAutolink\");\n effects.enter(\"literalAutolinkWww\");\n return effects.check(\n wwwPrefix,\n effects.attempt(domain, effects.attempt(path, wwwAfter), nok),\n nok\n )(code2);\n }\n function wwwAfter(code2) {\n effects.exit(\"literalAutolinkWww\");\n effects.exit(\"literalAutolink\");\n return ok2(code2);\n }\n}\nfunction tokenizeProtocolAutolink(effects, ok2, nok) {\n const self = this;\n let buffer = \"\";\n let seen = false;\n return protocolStart;\n function protocolStart(code2) {\n if ((code2 === 72 || code2 === 104) && previousProtocol.call(self, self.previous) && !previousUnbalanced(self.events)) {\n effects.enter(\"literalAutolink\");\n effects.enter(\"literalAutolinkHttp\");\n buffer += String.fromCodePoint(code2);\n effects.consume(code2);\n return protocolPrefixInside;\n }\n return nok(code2);\n }\n function protocolPrefixInside(code2) {\n if (asciiAlpha(code2) && buffer.length < 5) {\n buffer += String.fromCodePoint(code2);\n effects.consume(code2);\n return protocolPrefixInside;\n }\n if (code2 === 58) {\n const protocol = buffer.toLowerCase();\n if (protocol === \"http\" || protocol === \"https\") {\n effects.consume(code2);\n return protocolSlashesInside;\n }\n }\n return nok(code2);\n }\n function protocolSlashesInside(code2) {\n if (code2 === 47) {\n effects.consume(code2);\n if (seen) {\n return afterProtocol;\n }\n seen = true;\n return protocolSlashesInside;\n }\n return nok(code2);\n }\n function afterProtocol(code2) {\n return code2 === null || asciiControl(code2) || markdownLineEndingOrSpace(code2) || unicodeWhitespace(code2) || unicodePunctuation(code2) ? nok(code2) : effects.attempt(domain, effects.attempt(path, protocolAfter), nok)(code2);\n }\n function protocolAfter(code2) {\n effects.exit(\"literalAutolinkHttp\");\n effects.exit(\"literalAutolink\");\n return ok2(code2);\n }\n}\nfunction tokenizeWwwPrefix(effects, ok2, nok) {\n let size = 0;\n return wwwPrefixInside;\n function wwwPrefixInside(code2) {\n if ((code2 === 87 || code2 === 119) && size < 3) {\n size++;\n effects.consume(code2);\n return wwwPrefixInside;\n }\n if (code2 === 46 && size === 3) {\n effects.consume(code2);\n return wwwPrefixAfter;\n }\n return nok(code2);\n }\n function wwwPrefixAfter(code2) {\n return code2 === null ? nok(code2) : ok2(code2);\n }\n}\nfunction tokenizeDomain(effects, ok2, nok) {\n let underscoreInLastSegment;\n let underscoreInLastLastSegment;\n let seen;\n return domainInside;\n function domainInside(code2) {\n if (code2 === 46 || code2 === 95) {\n return effects.check(trail, domainAfter, domainAtPunctuation)(code2);\n }\n if (code2 === null || markdownLineEndingOrSpace(code2) || unicodeWhitespace(code2) || code2 !== 45 && unicodePunctuation(code2)) {\n return domainAfter(code2);\n }\n seen = true;\n effects.consume(code2);\n return domainInside;\n }\n function domainAtPunctuation(code2) {\n if (code2 === 95) {\n underscoreInLastSegment = true;\n } else {\n underscoreInLastLastSegment = underscoreInLastSegment;\n underscoreInLastSegment = void 0;\n }\n effects.consume(code2);\n return domainInside;\n }\n function domainAfter(code2) {\n if (underscoreInLastLastSegment || underscoreInLastSegment || !seen) {\n return nok(code2);\n }\n return ok2(code2);\n }\n}\nfunction tokenizePath(effects, ok2) {\n let sizeOpen = 0;\n let sizeClose = 0;\n return pathInside;\n function pathInside(code2) {\n if (code2 === 40) {\n sizeOpen++;\n effects.consume(code2);\n return pathInside;\n }\n if (code2 === 41 && sizeClose < sizeOpen) {\n return pathAtPunctuation(code2);\n }\n if (code2 === 33 || code2 === 34 || code2 === 38 || code2 === 39 || code2 === 41 || code2 === 42 || code2 === 44 || code2 === 46 || code2 === 58 || code2 === 59 || code2 === 60 || code2 === 63 || code2 === 93 || code2 === 95 || code2 === 126) {\n return effects.check(trail, ok2, pathAtPunctuation)(code2);\n }\n if (code2 === null || markdownLineEndingOrSpace(code2) || unicodeWhitespace(code2)) {\n return ok2(code2);\n }\n effects.consume(code2);\n return pathInside;\n }\n function pathAtPunctuation(code2) {\n if (code2 === 41) {\n sizeClose++;\n }\n effects.consume(code2);\n return pathInside;\n }\n}\nfunction tokenizeTrail(effects, ok2, nok) {\n return trail2;\n function trail2(code2) {\n if (code2 === 33 || code2 === 34 || code2 === 39 || code2 === 41 || code2 === 42 || code2 === 44 || code2 === 46 || code2 === 58 || code2 === 59 || code2 === 63 || code2 === 95 || code2 === 126) {\n effects.consume(code2);\n return trail2;\n }\n if (code2 === 38) {\n effects.consume(code2);\n return trailCharRefStart;\n }\n if (code2 === 93) {\n effects.consume(code2);\n return trailBracketAfter;\n }\n if (\n // `<` is an end.\n code2 === 60 || // So is whitespace.\n code2 === null || markdownLineEndingOrSpace(code2) || unicodeWhitespace(code2)\n ) {\n return ok2(code2);\n }\n return nok(code2);\n }\n function trailBracketAfter(code2) {\n if (code2 === null || code2 === 40 || code2 === 91 || markdownLineEndingOrSpace(code2) || unicodeWhitespace(code2)) {\n return ok2(code2);\n }\n return trail2(code2);\n }\n function trailCharRefStart(code2) {\n return asciiAlpha(code2) ? trailCharRefInside(code2) : nok(code2);\n }\n function trailCharRefInside(code2) {\n if (code2 === 59) {\n effects.consume(code2);\n return trail2;\n }\n if (asciiAlpha(code2)) {\n effects.consume(code2);\n return trailCharRefInside;\n }\n return nok(code2);\n }\n}\nfunction tokenizeEmailDomainDotTrail(effects, ok2, nok) {\n return start;\n function start(code2) {\n effects.consume(code2);\n return after;\n }\n function after(code2) {\n return asciiAlphanumeric(code2) ? nok(code2) : ok2(code2);\n }\n}\nfunction previousWww(code2) {\n return code2 === null || code2 === 40 || code2 === 42 || code2 === 95 || code2 === 91 || code2 === 93 || code2 === 126 || markdownLineEndingOrSpace(code2);\n}\nfunction previousProtocol(code2) {\n return !asciiAlpha(code2);\n}\nfunction previousEmail(code2) {\n return !(code2 === 47 || gfmAtext(code2));\n}\nfunction gfmAtext(code2) {\n return code2 === 43 || code2 === 45 || code2 === 46 || code2 === 95 || asciiAlphanumeric(code2);\n}\nfunction previousUnbalanced(events) {\n let index = events.length;\n let result = false;\n while (index--) {\n const token = events[index][1];\n if ((token.type === \"labelLink\" || token.type === \"labelImage\") && !token._balanced) {\n result = true;\n break;\n }\n if (token._gfmAutolinkLiteralWalkedInto) {\n result = false;\n break;\n }\n }\n if (events.length > 0 && !result) {\n events[events.length - 1][1]._gfmAutolinkLiteralWalkedInto = true;\n }\n return result;\n}\nfunction resolveAll(constructs2, events, context) {\n const called = [];\n let index = -1;\n while (++index < constructs2.length) {\n const resolve = constructs2[index].resolveAll;\n if (resolve && !called.includes(resolve)) {\n events = resolve(events, context);\n called.push(resolve);\n }\n }\n return events;\n}\nfunction factorySpace(effects, ok2, type, max) {\n const limit = max ? max - 1 : Number.POSITIVE_INFINITY;\n let size = 0;\n return start;\n function start(code2) {\n if (markdownSpace(code2)) {\n effects.enter(type);\n return prefix(code2);\n }\n return ok2(code2);\n }\n function prefix(code2) {\n if (markdownSpace(code2) && size++ < limit) {\n effects.consume(code2);\n return prefix;\n }\n effects.exit(type);\n return ok2(code2);\n }\n}\nconst blankLine = {\n tokenize: tokenizeBlankLine,\n partial: true\n};\nfunction tokenizeBlankLine(effects, ok2, nok) {\n return start;\n function start(code2) {\n return markdownSpace(code2) ? factorySpace(effects, after, \"linePrefix\")(code2) : after(code2);\n }\n function after(code2) {\n return code2 === null || markdownLineEnding(code2) ? ok2(code2) : nok(code2);\n }\n}\nconst indent = {\n tokenize: tokenizeIndent,\n partial: true\n};\nfunction gfmFootnote() {\n return {\n document: {\n [91]: {\n tokenize: tokenizeDefinitionStart,\n continuation: {\n tokenize: tokenizeDefinitionContinuation\n },\n exit: gfmFootnoteDefinitionEnd\n }\n },\n text: {\n [91]: {\n tokenize: tokenizeGfmFootnoteCall\n },\n [93]: {\n add: \"after\",\n tokenize: tokenizePotentialGfmFootnoteCall,\n resolveTo: resolveToPotentialGfmFootnoteCall\n }\n }\n };\n}\nfunction tokenizePotentialGfmFootnoteCall(effects, ok2, nok) {\n const self = this;\n let index = self.events.length;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n let labelStart;\n while (index--) {\n const token = self.events[index][1];\n if (token.type === \"labelImage\") {\n labelStart = token;\n break;\n }\n if (token.type === \"gfmFootnoteCall\" || token.type === \"labelLink\" || token.type === \"label\" || token.type === \"image\" || token.type === \"link\") {\n break;\n }\n }\n return start;\n function start(code2) {\n if (!labelStart || !labelStart._balanced) {\n return nok(code2);\n }\n const id = normalizeIdentifier(\n self.sliceSerialize({\n start: labelStart.end,\n end: self.now()\n })\n );\n if (id.codePointAt(0) !== 94 || !defined.includes(id.slice(1))) {\n return nok(code2);\n }\n effects.enter(\"gfmFootnoteCallLabelMarker\");\n effects.consume(code2);\n effects.exit(\"gfmFootnoteCallLabelMarker\");\n return ok2(code2);\n }\n}\nfunction resolveToPotentialGfmFootnoteCall(events, context) {\n let index = events.length;\n while (index--) {\n if (events[index][1].type === \"labelImage\" && events[index][0] === \"enter\") {\n events[index][1];\n break;\n }\n }\n events[index + 1][1].type = \"data\";\n events[index + 3][1].type = \"gfmFootnoteCallLabelMarker\";\n const call = {\n type: \"gfmFootnoteCall\",\n start: Object.assign({}, events[index + 3][1].start),\n end: Object.assign({}, events[events.length - 1][1].end)\n };\n const marker = {\n type: \"gfmFootnoteCallMarker\",\n start: Object.assign({}, events[index + 3][1].end),\n end: Object.assign({}, events[index + 3][1].end)\n };\n marker.end.column++;\n marker.end.offset++;\n marker.end._bufferIndex++;\n const string = {\n type: \"gfmFootnoteCallString\",\n start: Object.assign({}, marker.end),\n end: Object.assign({}, events[events.length - 1][1].start)\n };\n const chunk = {\n type: \"chunkString\",\n contentType: \"string\",\n start: Object.assign({}, string.start),\n end: Object.assign({}, string.end)\n };\n const replacement = [\n // Take the `labelImageMarker` (now `data`, the `!`)\n events[index + 1],\n events[index + 2],\n [\"enter\", call, context],\n // The `[`\n events[index + 3],\n events[index + 4],\n // The `^`.\n [\"enter\", marker, context],\n [\"exit\", marker, context],\n // Everything in between.\n [\"enter\", string, context],\n [\"enter\", chunk, context],\n [\"exit\", chunk, context],\n [\"exit\", string, context],\n // The ending (`]`, properly parsed and labelled).\n events[events.length - 2],\n events[events.length - 1],\n [\"exit\", call, context]\n ];\n events.splice(index, events.length - index + 1, ...replacement);\n return events;\n}\nfunction tokenizeGfmFootnoteCall(effects, ok2, nok) {\n const self = this;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n let size = 0;\n let data;\n return start;\n function start(code2) {\n effects.enter(\"gfmFootnoteCall\");\n effects.enter(\"gfmFootnoteCallLabelMarker\");\n effects.consume(code2);\n effects.exit(\"gfmFootnoteCallLabelMarker\");\n return callStart;\n }\n function callStart(code2) {\n if (code2 !== 94) return nok(code2);\n effects.enter(\"gfmFootnoteCallMarker\");\n effects.consume(code2);\n effects.exit(\"gfmFootnoteCallMarker\");\n effects.enter(\"gfmFootnoteCallString\");\n effects.enter(\"chunkString\").contentType = \"string\";\n return callData;\n }\n function callData(code2) {\n if (\n // Too long.\n size > 999 || // Closing brace with nothing.\n code2 === 93 && !data || // Space or tab is not supported by GFM for some reason.\n // `\\n` and `[` not being supported makes sense.\n code2 === null || code2 === 91 || markdownLineEndingOrSpace(code2)\n ) {\n return nok(code2);\n }\n if (code2 === 93) {\n effects.exit(\"chunkString\");\n const token = effects.exit(\"gfmFootnoteCallString\");\n if (!defined.includes(normalizeIdentifier(self.sliceSerialize(token)))) {\n return nok(code2);\n }\n effects.enter(\"gfmFootnoteCallLabelMarker\");\n effects.consume(code2);\n effects.exit(\"gfmFootnoteCallLabelMarker\");\n effects.exit(\"gfmFootnoteCall\");\n return ok2;\n }\n if (!markdownLineEndingOrSpace(code2)) {\n data = true;\n }\n size++;\n effects.consume(code2);\n return code2 === 92 ? callEscape : callData;\n }\n function callEscape(code2) {\n if (code2 === 91 || code2 === 92 || code2 === 93) {\n effects.consume(code2);\n size++;\n return callData;\n }\n return callData(code2);\n }\n}\nfunction tokenizeDefinitionStart(effects, ok2, nok) {\n const self = this;\n const defined = self.parser.gfmFootnotes || (self.parser.gfmFootnotes = []);\n let identifier;\n let size = 0;\n let data;\n return start;\n function start(code2) {\n effects.enter(\"gfmFootnoteDefinition\")._container = true;\n effects.enter(\"gfmFootnoteDefinitionLabel\");\n effects.enter(\"gfmFootnoteDefinitionLabelMarker\");\n effects.consume(code2);\n effects.exit(\"gfmFootnoteDefinitionLabelMarker\");\n return labelAtMarker;\n }\n function labelAtMarker(code2) {\n if (code2 === 94) {\n effects.enter(\"gfmFootnoteDefinitionMarker\");\n effects.consume(code2);\n effects.exit(\"gfmFootnoteDefinitionMarker\");\n effects.enter(\"gfmFootnoteDefinitionLabelString\");\n effects.enter(\"chunkString\").contentType = \"string\";\n return labelInside;\n }\n return nok(code2);\n }\n function labelInside(code2) {\n if (\n // Too long.\n size > 999 || // Closing brace with nothing.\n code2 === 93 && !data || // Space or tab is not supported by GFM for some reason.\n // `\\n` and `[` not being supported makes sense.\n code2 === null || code2 === 91 || markdownLineEndingOrSpace(code2)\n ) {\n return nok(code2);\n }\n if (code2 === 93) {\n effects.exit(\"chunkString\");\n const token = effects.exit(\"gfmFootnoteDefinitionLabelString\");\n identifier = normalizeIdentifier(self.sliceSerialize(token));\n effects.enter(\"gfmFootnoteDefinitionLabelMarker\");\n effects.consume(code2);\n effects.exit(\"gfmFootnoteDefinitionLabelMarker\");\n effects.exit(\"gfmFootnoteDefinitionLabel\");\n return labelAfter;\n }\n if (!markdownLineEndingOrSpace(code2)) {\n data = true;\n }\n size++;\n effects.consume(code2);\n return code2 === 92 ? labelEscape : labelInside;\n }\n function labelEscape(code2) {\n if (code2 === 91 || code2 === 92 || code2 === 93) {\n effects.consume(code2);\n size++;\n return labelInside;\n }\n return labelInside(code2);\n }\n function labelAfter(code2) {\n if (code2 === 58) {\n effects.enter(\"definitionMarker\");\n effects.consume(code2);\n effects.exit(\"definitionMarker\");\n if (!defined.includes(identifier)) {\n defined.push(identifier);\n }\n return factorySpace(\n effects,\n whitespaceAfter,\n \"gfmFootnoteDefinitionWhitespace\"\n );\n }\n return nok(code2);\n }\n function whitespaceAfter(code2) {\n return ok2(code2);\n }\n}\nfunction tokenizeDefinitionContinuation(effects, ok2, nok) {\n return effects.check(blankLine, ok2, effects.attempt(indent, ok2, nok));\n}\nfunction gfmFootnoteDefinitionEnd(effects) {\n effects.exit(\"gfmFootnoteDefinition\");\n}\nfunction tokenizeIndent(effects, ok2, nok) {\n const self = this;\n return factorySpace(\n effects,\n afterPrefix,\n \"gfmFootnoteDefinitionIndent\",\n 4 + 1\n );\n function afterPrefix(code2) {\n const tail = self.events[self.events.length - 1];\n return tail && tail[1].type === \"gfmFootnoteDefinitionIndent\" && tail[2].sliceSerialize(tail[1], true).length === 4 ? ok2(code2) : nok(code2);\n }\n}\nfunction gfmStrikethrough(options) {\n const options_ = options || {};\n let single = options_.singleTilde;\n const tokenizer = {\n tokenize: tokenizeStrikethrough,\n resolveAll: resolveAllStrikethrough\n };\n if (single === null || single === void 0) {\n single = true;\n }\n return {\n text: {\n [126]: tokenizer\n },\n insideSpan: {\n null: [tokenizer]\n },\n attentionMarkers: {\n null: [126]\n }\n };\n function resolveAllStrikethrough(events, context) {\n let index = -1;\n while (++index < events.length) {\n if (events[index][0] === \"enter\" && events[index][1].type === \"strikethroughSequenceTemporary\" && events[index][1]._close) {\n let open = index;\n while (open--) {\n if (events[open][0] === \"exit\" && events[open][1].type === \"strikethroughSequenceTemporary\" && events[open][1]._open && // If the sizes are the same:\n events[index][1].end.offset - events[index][1].start.offset === events[open][1].end.offset - events[open][1].start.offset) {\n events[index][1].type = \"strikethroughSequence\";\n events[open][1].type = \"strikethroughSequence\";\n const strikethrough = {\n type: \"strikethrough\",\n start: Object.assign({}, events[open][1].start),\n end: Object.assign({}, events[index][1].end)\n };\n const text2 = {\n type: \"strikethroughText\",\n start: Object.assign({}, events[open][1].end),\n end: Object.assign({}, events[index][1].start)\n };\n const nextEvents = [\n [\"enter\", strikethrough, context],\n [\"enter\", events[open][1], context],\n [\"exit\", events[open][1], context],\n [\"enter\", text2, context]\n ];\n const insideSpan = context.parser.constructs.insideSpan.null;\n if (insideSpan) {\n splice(\n nextEvents,\n nextEvents.length,\n 0,\n resolveAll(insideSpan, events.slice(open + 1, index), context)\n );\n }\n splice(nextEvents, nextEvents.length, 0, [\n [\"exit\", text2, context],\n [\"enter\", events[index][1], context],\n [\"exit\", events[index][1], context],\n [\"exit\", strikethrough, context]\n ]);\n splice(events, open - 1, index - open + 3, nextEvents);\n index = open + nextEvents.length - 2;\n break;\n }\n }\n }\n }\n index = -1;\n while (++index < events.length) {\n if (events[index][1].type === \"strikethroughSequenceTemporary\") {\n events[index][1].type = \"data\";\n }\n }\n return events;\n }\n function tokenizeStrikethrough(effects, ok2, nok) {\n const previous2 = this.previous;\n const events = this.events;\n let size = 0;\n return start;\n function start(code2) {\n if (previous2 === 126 && events[events.length - 1][1].type !== \"characterEscape\") {\n return nok(code2);\n }\n effects.enter(\"strikethroughSequenceTemporary\");\n return more(code2);\n }\n function more(code2) {\n const before = classifyCharacter(previous2);\n if (code2 === 126) {\n if (size > 1) return nok(code2);\n effects.consume(code2);\n size++;\n return more;\n }\n if (size < 2 && !single) return nok(code2);\n const token = effects.exit(\"strikethroughSequenceTemporary\");\n const after = classifyCharacter(code2);\n token._open = !after || after === 2 && Boolean(before);\n token._close = !before || before === 2 && Boolean(after);\n return ok2(code2);\n }\n }\n}\nclass EditMap {\n /**\n * Create a new edit map.\n */\n constructor() {\n this.map = [];\n }\n /**\n * Create an edit: a remove and/or add at a certain place.\n *\n * @param {number} index\n * @param {number} remove\n * @param {Array<Event>} add\n * @returns {undefined}\n */\n add(index, remove, add) {\n addImpl(this, index, remove, add);\n }\n // To do: add this when moving to `micromark`.\n // /**\n // * Create an edit: but insert `add` before existing additions.\n // *\n // * @param {number} index\n // * @param {number} remove\n // * @param {Array<Event>} add\n // * @returns {undefined}\n // */\n // addBefore(index, remove, add) {\n // addImpl(this, index, remove, add, true)\n // }\n /**\n * Done, change the events.\n *\n * @param {Array<Event>} events\n * @returns {undefined}\n */\n consume(events) {\n this.map.sort(function(a, b) {\n return a[0] - b[0];\n });\n if (this.map.length === 0) {\n return;\n }\n let index = this.map.length;\n const vecs = [];\n while (index > 0) {\n index -= 1;\n vecs.push(\n events.slice(this.map[index][0] + this.map[index][1]),\n this.map[index][2]\n );\n events.length = this.map[index][0];\n }\n vecs.push([...events]);\n events.length = 0;\n let slice = vecs.pop();\n while (slice) {\n events.push(...slice);\n slice = vecs.pop();\n }\n this.map.length = 0;\n }\n}\nfunction addImpl(editMap, at, remove, add) {\n let index = 0;\n if (remove === 0 && add.length === 0) {\n return;\n }\n while (index < editMap.map.length) {\n if (editMap.map[index][0] === at) {\n editMap.map[index][1] += remove;\n editMap.map[index][2].push(...add);\n return;\n }\n index += 1;\n }\n editMap.map.push([at, remove, add]);\n}\nfunction gfmTableAlign(events, index) {\n let inDelimiterRow = false;\n const align = [];\n while (index < events.length) {\n const event = events[index];\n if (inDelimiterRow) {\n if (event[0] === \"enter\") {\n if (event[1].type === \"tableContent\") {\n align.push(\n events[index + 1][1].type === \"tableDelimiterMarker\" ? \"left\" : \"none\"\n );\n }\n } else if (event[1].type === \"tableContent\") {\n if (events[index - 1][1].type === \"tableDelimiterMarker\") {\n const alignIndex = align.length - 1;\n align[alignIndex] = align[alignIndex] === \"left\" ? \"center\" : \"right\";\n }\n } else if (event[1].type === \"tableDelimiterRow\") {\n break;\n }\n } else if (event[0] === \"enter\" && event[1].type === \"tableDelimiterRow\") {\n inDelimiterRow = true;\n }\n index += 1;\n }\n return align;\n}\nfunction gfmTable() {\n return {\n flow: {\n null: {\n tokenize: tokenizeTable,\n resolveAll: resolveTable\n }\n }\n };\n}\nfunction tokenizeTable(effects, ok2, nok) {\n const self = this;\n let size = 0;\n let sizeB = 0;\n let seen;\n return start;\n function start(code2) {\n let index = self.events.length - 1;\n while (index > -1) {\n const type = self.events[index][1].type;\n if (type === \"lineEnding\" || // Note: markdown-rs uses `whitespace` instead of `linePrefix`\n type === \"linePrefix\")\n index--;\n else break;\n }\n const tail = index > -1 ? self.events[index][1].type : null;\n const next = tail === \"tableHead\" || tail === \"tableRow\" ? bodyRowStart : headRowBefore;\n if (next === bodyRowStart && self.parser.lazy[self.now().line]) {\n return nok(code2);\n }\n return next(code2);\n }\n function headRowBefore(code2) {\n effects.enter(\"tableHead\");\n effects.enter(\"tableRow\");\n return headRowStart(code2);\n }\n function headRowStart(code2) {\n if (code2 === 124) {\n return headRowBreak(code2);\n }\n seen = true;\n sizeB += 1;\n return headRowBreak(code2);\n }\n function headRowBreak(code2) {\n if (code2 === null) {\n return nok(code2);\n }\n if (markdownLineEnding(code2)) {\n if (sizeB > 1) {\n sizeB = 0;\n self.interrupt = true;\n effects.exit(\"tableRow\");\n effects.enter(\"lineEnding\");\n effects.consume(code2);\n effects.exit(\"lineEnding\");\n return headDelimiterStart;\n }\n return nok(code2);\n }\n if (markdownSpace(code2)) {\n return factorySpace(effects, headRowBreak, \"whitespace\")(code2);\n }\n sizeB += 1;\n if (seen) {\n seen = false;\n size += 1;\n }\n if (code2 === 124) {\n effects.enter(\"tableCellDivider\");\n effects.consume(code2);\n effects.exit(\"tableCellDivider\");\n seen = true;\n return headRowBreak;\n }\n effects.enter(\"data\");\n return headRowData(code2);\n }\n function headRowData(code2) {\n if (code2 === null || code2 === 124 || markdownLineEndingOrSpace(code2)) {\n effects.exit(\"data\");\n return headRowBreak(code2);\n }\n effects.consume(code2);\n return code2 === 92 ? headRowEscape : headRowData;\n }\n function headRowEscape(code2) {\n if (code2 === 92 || code2 === 124) {\n effects.consume(code2);\n return headRowData;\n }\n return headRowData(code2);\n }\n function headDelimiterStart(code2) {\n self.interrupt = false;\n if (self.parser.lazy[self.now().line]) {\n return nok(code2);\n }\n effects.enter(\"tableDelimiterRow\");\n seen = false;\n if (markdownSpace(code2)) {\n return factorySpace(\n effects,\n headDelimiterBefore,\n \"linePrefix\",\n self.parser.constructs.disable.null.includes(\"codeIndented\") ? void 0 : 4\n )(code2);\n }\n return headDelimiterBefore(code2);\n }\n function headDelimiterBefore(code2) {\n if (code2 === 45 || code2 === 58) {\n return headDelimiterValueBefore(code2);\n }\n if (code2 === 124) {\n seen = true;\n effects.enter(\"tableCellDivider\");\n effects.consume(code2);\n effects.exit(\"tableCellDivider\");\n return headDelimiterCellBefore;\n }\n return headDelimiterNok(code2);\n }\n function headDelimiterCellBefore(code2) {\n if (markdownSpace(code2)) {\n return factorySpace(effects, headDelimiterValueBefore, \"whitespace\")(code2);\n }\n return headDelimiterValueBefore(code2);\n }\n function headDelimiterValueBefore(code2) {\n if (code2 === 58) {\n sizeB += 1;\n seen = true;\n effects.enter(\"tableDelimiterMarker\");\n effects.consume(code2);\n effects.exit(\"tableDelimiterMarker\");\n return headDelimiterLeftAlignmentAfter;\n }\n if (code2 === 45) {\n sizeB += 1;\n return headDelimiterLeftAlignmentAfter(code2);\n }\n if (code2 === null || markdownLineEnding(code2)) {\n return headDelimiterCellAfter(code2);\n }\n return headDelimiterNok(code2);\n }\n function headDelimiterLeftAlignmentAfter(code2) {\n if (code2 === 45) {\n effects.enter(\"tableDelimiterFiller\");\n return headDelimiterFiller(code2);\n }\n return headDelimiterNok(code2);\n }\n function headDelimiterFiller(code2) {\n if (code2 === 45) {\n effects.consume(code2);\n return headDelimiterFiller;\n }\n if (code2 === 58) {\n seen = true;\n effects.exit(\"tableDelimiterFiller\");\n effects.enter(\"tableDelimiterMarker\");\n effects.consume(code2);\n effects.exit(\"tableDelimiterMarker\");\n return headDelimiterRightAlignmentAfter;\n }\n effects.exit(\"tableDelimiterFiller\");\n return headDelimiterRightAlignmentAfter(code2);\n }\n function headDelimiterRightAlignmentAfter(code2) {\n if (markdownSpace(code2)) {\n return factorySpace(effects, headDelimiterCellAfter, \"whitespace\")(code2);\n }\n return headDelimiterCellAfter(code2);\n }\n function headDelimiterCellAfter(code2) {\n if (code2 === 124) {\n return headDelimiterBefore(code2);\n }\n if (code2 === null || markdownLineEnding(code2)) {\n if (!seen || size !== sizeB) {\n return headDelimiterNok(code2);\n }\n effects.exit(\"tableDelimiterRow\");\n effects.exit(\"tableHead\");\n return ok2(code2);\n }\n return headDelimiterNok(code2);\n }\n function headDelimiterNok(code2) {\n return nok(code2);\n }\n function bodyRowStart(code2) {\n effects.enter(\"tableRow\");\n return bodyRowBreak(code2);\n }\n function bodyRowBreak(code2) {\n if (code2 === 124) {\n effects.enter(\"tableCellDivider\");\n effects.consume(code2);\n effects.exit(\"tableCellDivider\");\n return bodyRowBreak;\n }\n if (code2 === null || markdownLineEnding(code2)) {\n effects.exit(\"tableRow\");\n return ok2(code2);\n }\n if (markdownSpace(code2)) {\n return factorySpace(effects, bodyRowBreak, \"whitespace\")(code2);\n }\n effects.enter(\"data\");\n return bodyRowData(code2);\n }\n function bodyRowData(code2) {\n if (code2 === null || code2 === 124 || markdownLineEndingOrSpace(code2)) {\n effects.exit(\"data\");\n return bodyRowBreak(code2);\n }\n effects.consume(code2);\n return code2 === 92 ? bodyRowEscape : bodyRowData;\n }\n function bodyRowEscape(code2) {\n if (code2 === 92 || code2 === 124) {\n effects.consume(code2);\n return bodyRowData;\n }\n return bodyRowData(code2);\n }\n}\nfunction resolveTable(events, context) {\n let index = -1;\n let inFirstCellAwaitingPipe = true;\n let rowKind = 0;\n let lastCell = [0, 0, 0, 0];\n let cell = [0, 0, 0, 0];\n let afterHeadAwaitingFirstBodyRow = false;\n let lastTableEnd = 0;\n let currentTable;\n let currentBody;\n let currentCell;\n const map2 = new EditMap();\n while (++index < events.length) {\n const event = events[index];\n const token = event[1];\n if (event[0] === \"enter\") {\n if (token.type === \"tableHead\") {\n afterHeadAwaitingFirstBodyRow = false;\n if (lastTableEnd !== 0) {\n flushTableEnd(map2, context, lastTableEnd, currentTable, currentBody);\n currentBody = void 0;\n lastTableEnd = 0;\n }\n currentTable = {\n type: \"table\",\n start: Object.assign({}, token.start),\n // Note: correct end is set later.\n end: Object.assign({}, token.end)\n };\n map2.add(index, 0, [[\"enter\", currentTable, context]]);\n } else if (token.type === \"tableRow\" || token.type === \"tableDelimiterRow\") {\n inFirstCellAwaitingPipe = true;\n currentCell = void 0;\n lastCell = [0, 0, 0, 0];\n cell = [0, index + 1, 0, 0];\n if (afterHeadAwaitingFirstBodyRow) {\n afterHeadAwaitingFirstBodyRow = false;\n currentBody = {\n type: \"tableBody\",\n start: Object.assign({}, token.start),\n // Note: correct end is set later.\n end: Object.assign({}, token.end)\n };\n map2.add(index, 0, [[\"enter\", currentBody, context]]);\n }\n rowKind = token.type === \"tableDelimiterRow\" ? 2 : currentBody ? 3 : 1;\n } else if (rowKind && (token.type === \"data\" || token.type === \"tableDelimiterMarker\" || token.type === \"tableDelimiterFiller\")) {\n inFirstCellAwaitingPipe = false;\n if (cell[2] === 0) {\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(\n map2,\n context,\n lastCell,\n rowKind,\n void 0,\n currentCell\n );\n lastCell = [0, 0, 0, 0];\n }\n cell[2] = index;\n }\n } else if (token.type === \"tableCellDivider\") {\n if (inFirstCellAwaitingPipe) {\n inFirstCellAwaitingPipe = false;\n } else {\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(\n map2,\n context,\n lastCell,\n rowKind,\n void 0,\n currentCell\n );\n }\n lastCell = cell;\n cell = [lastCell[1], index, 0, 0];\n }\n }\n } else if (token.type === \"tableHead\") {\n afterHeadAwaitingFirstBodyRow = true;\n lastTableEnd = index;\n } else if (token.type === \"tableRow\" || token.type === \"tableDelimiterRow\") {\n lastTableEnd = index;\n if (lastCell[1] !== 0) {\n cell[0] = cell[1];\n currentCell = flushCell(\n map2,\n context,\n lastCell,\n rowKind,\n index,\n currentCell\n );\n } else if (cell[1] !== 0) {\n currentCell = flushCell(map2, context, cell, rowKind, index, currentCell);\n }\n rowKind = 0;\n } else if (rowKind && (token.type === \"data\" || token.type === \"tableDelimiterMarker\" || token.type === \"tableDelimiterFiller\")) {\n cell[3] = index;\n }\n }\n if (lastTableEnd !== 0) {\n flushTableEnd(map2, context, lastTableEnd, currentTable, currentBody);\n }\n map2.consume(context.events);\n index = -1;\n while (++index < context.events.length) {\n const event = context.events[index];\n if (event[0] === \"enter\" && event[1].type === \"table\") {\n event[1]._align = gfmTableAlign(context.events, index);\n }\n }\n return events;\n}\nfunction flushCell(map2, context, range, rowKind, rowEnd, previousCell) {\n const groupName = rowKind === 1 ? \"tableHeader\" : rowKind === 2 ? \"tableDelimiter\" : \"tableData\";\n const valueName = \"tableContent\";\n if (range[0] !== 0) {\n previousCell.end = Object.assign({}, getPoint(context.events, range[0]));\n map2.add(range[0], 0, [[\"exit\", previousCell, context]]);\n }\n const now = getPoint(context.events, range[1]);\n previousCell = {\n type: groupName,\n start: Object.assign({}, now),\n // Note: correct end is set later.\n end: Object.assign({}, now)\n };\n map2.add(range[1], 0, [[\"enter\", previousCell, context]]);\n if (range[2] !== 0) {\n const relatedStart = getPoint(context.events, range[2]);\n const relatedEnd = getPoint(context.events, range[3]);\n const valueToken = {\n type: valueName,\n start: Object.assign({}, relatedStart),\n end: Object.assign({}, relatedEnd)\n };\n map2.add(range[2], 0, [[\"enter\", valueToken, context]]);\n if (rowKind !== 2) {\n const start = context.events[range[2]];\n const end = context.events[range[3]];\n start[1].end = Object.assign({}, end[1].end);\n start[1].type = \"chunkText\";\n start[1].contentType = \"text\";\n if (range[3] > range[2] + 1) {\n const a = range[2] + 1;\n const b = range[3] - range[2] - 1;\n map2.add(a, b, []);\n }\n }\n map2.add(range[3] + 1, 0, [[\"exit\", valueToken, context]]);\n }\n if (rowEnd !== void 0) {\n previousCell.end = Object.assign({}, getPoint(context.events, rowEnd));\n map2.add(rowEnd, 0, [[\"exit\", previousCell, context]]);\n previousCell = void 0;\n }\n return previousCell;\n}\nfunction flushTableEnd(map2, context, index, table, tableBody) {\n const exits = [];\n const related = getPoint(context.events, index);\n if (tableBody) {\n tableBody.end = Object.assign({}, related);\n exits.push([\"exit\", tableBody, context]);\n }\n table.end = Object.assign({}, related);\n exits.push([\"exit\", table, context]);\n map2.add(index + 1, 0, exits);\n}\nfunction getPoint(events, index) {\n const event = events[index];\n const side = event[0] === \"enter\" ? \"start\" : \"end\";\n return event[1][side];\n}\nconst tasklistCheck = {\n tokenize: tokenizeTasklistCheck\n};\nfunction gfmTaskListItem() {\n return {\n text: {\n [91]: tasklistCheck\n }\n };\n}\nfunction tokenizeTasklistCheck(effects, ok2, nok) {\n const self = this;\n return open;\n function open(code2) {\n if (\n // Exit if theres stuff before.\n self.previous !== null || // Exit if not in the first content that is the first child of a list\n // item.\n !self._gfmTasklistFirstContentOfListItem\n ) {\n return nok(code2);\n }\n effects.enter(\"taskListCheck\");\n effects.enter(\"taskListCheckMarker\");\n effects.consume(code2);\n effects.exit(\"taskListCheckMarker\");\n return inside;\n }\n function inside(code2) {\n if (markdownLineEndingOrSpace(code2)) {\n effects.enter(\"taskListCheckValueUnchecked\");\n effects.consume(code2);\n effects.exit(\"taskListCheckValueUnchecked\");\n return close;\n }\n if (code2 === 88 || code2 === 120) {\n effects.enter(\"taskListCheckValueChecked\");\n effects.consume(code2);\n effects.exit(\"taskListCheckValueChecked\");\n return close;\n }\n return nok(code2);\n }\n function close(code2) {\n if (code2 === 93) {\n effects.enter(\"taskListCheckMarker\");\n effects.consume(code2);\n effects.exit(\"taskListCheckMarker\");\n effects.exit(\"taskListCheck\");\n return after;\n }\n return nok(code2);\n }\n function after(code2) {\n if (markdownLineEnding(code2)) {\n return ok2(code2);\n }\n if (markdownSpace(code2)) {\n return effects.check(\n {\n tokenize: spaceThenNonSpace\n },\n ok2,\n nok\n )(code2);\n }\n return nok(code2);\n }\n}\nfunction spaceThenNonSpace(effects, ok2, nok) {\n return factorySpace(effects, after, \"whitespace\");\n function after(code2) {\n return code2 === null ? nok(code2) : ok2(code2);\n }\n}\nfunction gfm(options) {\n return combineExtensions([\n gfmAutolinkLiteral(),\n gfmFootnote(),\n gfmStrikethrough(options),\n gfmTable(),\n gfmTaskListItem()\n ]);\n}\nconst emptyOptions = {};\nfunction remarkGfm(options) {\n const self = (\n /** @type {Processor<Root>} */\n this\n );\n const settings = options || emptyOptions;\n const data = self.data();\n const micromarkExtensions = data.micromarkExtensions || (data.micromarkExtensions = []);\n const fromMarkdownExtensions = data.fromMarkdownExtensions || (data.fromMarkdownExtensions = []);\n const toMarkdownExtensions = data.toMarkdownExtensions || (data.toMarkdownExtensions = []);\n micromarkExtensions.push(gfm(settings));\n fromMarkdownExtensions.push(gfmFromMarkdown());\n toMarkdownExtensions.push(gfmToMarkdown(settings));\n}\nconst _sfc_main$1 = /* @__PURE__ */ defineComponent({\n __name: \"NcRichTextCopyButton\",\n props: {\n contentId: null\n },\n setup(__props) {\n const props = __props;\n const { copy, icon, altText } = useCopy(() => document.getElementById(props.contentId).textContent);\n return { __sfc: true, props, copy, icon, altText, NcButton, NcIconSvgWrapper };\n }\n});\nvar _sfc_render$1 = function render2() {\n var _vm = this, _c = _vm._self._c, _setup = _vm._self._setupProxy;\n return _c(_setup.NcButton, { attrs: { \"variant\": \"tertiary\", \"size\": \"small\", \"aria-label\": _setup.altText, \"title\": _setup.altText }, on: { \"click\": _setup.copy }, scopedSlots: _vm._u([{ key: \"icon\", fn: function() {\n return [_c(_setup.NcIconSvgWrapper, { attrs: { \"path\": _setup.icon, \"inline\": \"\" } })];\n }, proxy: true }]) });\n};\nvar _sfc_staticRenderFns$1 = [];\nvar __component__$1 = /* @__PURE__ */ normalizeComponent(\n _sfc_main$1,\n _sfc_render$1,\n _sfc_staticRenderFns$1,\n false,\n null,\n null\n);\nconst NcRichTextCopyButton = __component__$1.exports;\nfunction remarkPlaceholder() {\n return function(ast) {\n visitParents(ast, (node) => node.type === \"text\", visitor);\n function visitor(node, ancestors) {\n const parent = ancestors.at(-1);\n const index = parent.children.indexOf(node);\n const placeholders = node.value.split(/(\\{[a-z\\-_.0-9]+\\})/ig).map((entry) => {\n const matches = entry.match(/^\\{([a-z\\-_.0-9]+)\\}$/i);\n if (!matches) {\n return u(\"text\", entry);\n }\n const [, component] = matches;\n return u(\"element\", {\n tagName: `#${component}`\n });\n });\n parent.children.splice(index, 1, ...placeholders);\n }\n };\n}\nfunction prepareTextNode({ h, context }, text2) {\n if (context.autolink) {\n text2 = parseUrl(text2);\n }\n if (Array.isArray(text2)) {\n return text2.map((entry) => {\n if (typeof entry === \"string\") {\n return entry;\n }\n const { component, props } = entry;\n return h(component, {\n props,\n class: \"rich-text--component\"\n });\n });\n }\n return text2;\n}\n/*!\n * SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\nfunction isCodeNode(node) {\n return [\"code\", \"inlineCode\"].includes(node.type);\n}\nconst remarkStripCode = function() {\n return function(tree) {\n visitParents(tree, isCodeNode, (node, ancestors) => {\n const parent = ancestors.at(-1);\n const index = parent.children.indexOf(node);\n parent.children.splice(index, 1, {\n ...node,\n value: \"\"\n });\n return [SKIP, index + 1];\n });\n };\n};\nfunction remarkUnescape() {\n return function(tree) {\n visitParents(tree, (node) => [\"text\", \"code\", \"inlineCode\"].includes(node.type), (node, ancestors) => {\n const parent = ancestors.at(-1);\n const index = parent.children.indexOf(node);\n parent.children.splice(index, 1, {\n ...node,\n value: node.value.replace(/&lt;/gmi, \"<\").replace(/&gt;/gmi, \">\")\n });\n return [SKIP, index + 1];\n });\n };\n}\nconst LINK_PROTOCOLS = [\"http\", \"https\", \"mailto\", \"tel\"];\nconst rehypeHighlight = ref(null);\nasync function importRehypeHighlightLibrary() {\n const module = await import(\"rehype-highlight\");\n rehypeHighlight.value = module.default;\n}\nconst _sfc_main = {\n name: \"NcRichText\",\n components: {\n NcReferenceList\n },\n /* eslint vue/require-prop-comment: warn -- TODO: Add a proper doc block about what this props do */\n props: {\n text: {\n type: String,\n default: \"\"\n },\n arguments: {\n type: Object,\n default: () => {\n return {};\n }\n },\n referenceLimit: {\n type: Number,\n default: 0\n },\n referenceInteractive: {\n type: Boolean,\n // eslint-disable-next-line vue/no-boolean-default\n default: true\n },\n referenceInteractiveOptIn: {\n type: Boolean,\n default: false\n },\n /** Provide data upfront to avoid extra http request */\n references: {\n type: Array,\n default: null\n },\n /** Provide basic Markdown syntax */\n useMarkdown: {\n type: Boolean,\n default: false\n },\n /** Provide GitHub Flavored Markdown syntax */\n useExtendedMarkdown: {\n type: Boolean,\n default: false\n },\n /** Provide event from rendered markdown inputs */\n interactive: {\n type: Boolean,\n default: false\n },\n autolink: {\n type: Boolean,\n // eslint-disable-next-line vue/no-boolean-default\n default: true\n }\n },\n emits: [\n \"interact-todo\",\n \"interact:todo\"\n ],\n data() {\n return {\n parentId: GenRandomId(5)\n };\n },\n methods: {\n renderPlaintext(h) {\n const placeholders = this.text.split(/(\\{[a-z\\-_.0-9]+\\})/ig).map((entry) => {\n const matches = entry.match(/^\\{([a-z\\-_.0-9]+)\\}$/i);\n if (!matches) {\n return prepareTextNode({ h, context: this }, entry);\n }\n const argumentId = matches[1];\n const argument = this.arguments[argumentId];\n if (typeof argument === \"object\") {\n const { component, props } = argument;\n return h(component, {\n props,\n class: \"rich-text--component\"\n });\n }\n if (argument) {\n return h(\"span\", { class: \"rich-text--fallback\" }, argument);\n }\n return entry;\n });\n return h(\"div\", { class: \"rich-text--wrapper\" }, [\n h(\"div\", {}, placeholders.flat()),\n this.referenceLimit > 0 ? h(\"div\", { class: \"rich-text--reference-widget\" }, [\n h(NcReferenceList, {\n props: {\n text: this.text,\n referenceData: this.references,\n interactive: this.referenceInteractive,\n interactiveOptIn: this.referenceInteractiveOptIn\n }\n })\n ]) : null\n ]);\n },\n renderMarkdown(h) {\n const renderedMarkdown = unified().use(remarkParse).use(remarkAutolink, {\n autolink: this.autolink,\n useMarkdown: this.useMarkdown,\n useExtendedMarkdown: this.useExtendedMarkdown\n }).use(remarkUnescape).use(this.useExtendedMarkdown ? remarkGfm : void 0).use(breaks).use(remarkUnlinkProtocols, { except: LINK_PROTOCOLS }).use(remark2rehype, {\n handlers: {\n component(toHast, node) {\n return toHast(node, node.component, { value: node.value });\n }\n }\n }).use(this.useExtendedMarkdown ? rehypeHighlight.value : void 0).use(remarkPlaceholder).use(rehypeExternalLinks, {\n target: \"_blank\",\n rel: [\"noopener noreferrer\"]\n }).use(rehype2react, {\n createElement: (tag, attrs, children) => {\n if (!tag.startsWith(\"#\")) {\n if ([\"h1\", \"h2\", \"h3\", \"h4\", \"h5\", \"h6\"].includes(tag)) {\n tag = `h${Math.min(+String(tag)[1] + 3, 6)}`;\n }\n if (this.useExtendedMarkdown) {\n if (tag === \"code\" && !rehypeHighlight.value && attrs?.attrs?.class?.includes(\"language\")) {\n importRehypeHighlightLibrary();\n }\n if (tag === \"pre\" && Array.isArray(children) && children[0].tag === \"code\") {\n const id = this.parentId + \"-code-block-\" + GenRandomId(5);\n return h(\"p\", { class: \"rich-text__code-block\" }, [\n h(tag, { attrs: { ...attrs, id } }, children),\n h(NcRichTextCopyButton, {\n props: { contentId: id },\n class: \"rich-text__code-block-button\"\n })\n ]);\n }\n let nestedNode = null;\n if (tag === \"li\" && Array.isArray(children) && children[0].tag === \"input\" && children[0].data.attrs.type === \"checkbox\") {\n const [inputNode, ...labelParts] = children;\n const nestedNodeIndex = labelParts.findIndex((child) => [\"ul\", \"ol\", \"li\", \"blockquote\", \"pre\"].includes(child.tag));\n if (nestedNodeIndex !== -1) {\n nestedNode = labelParts[nestedNodeIndex];\n labelParts.splice(nestedNodeIndex);\n }\n const id = this.parentId + \"-markdown-input-\" + GenRandomId(5);\n const inputComponent = h(NcCheckboxRadioSwitch, {\n attrs: {\n ...inputNode.data.attrs,\n id,\n disabled: !this.interactive\n },\n on: {\n \"update:checked\": () => {\n this.$emit(\"interact-todo\", id);\n this.$emit(\"interact:todo\", id);\n }\n }\n }, labelParts);\n return h(tag, attrs, [inputComponent, nestedNode]);\n }\n }\n if (tag === \"a\") {\n const route = getRoute(this.$router, attrs.attrs.href);\n if (route) {\n delete attrs.attrs.href;\n delete attrs.attrs.target;\n return h(RouterLink, {\n ...attrs,\n props: {\n to: route\n }\n }, children);\n }\n const isAllowedScheme = /^(https?:\\/\\/|tel:|mailto:)/.test(attrs.attrs.href);\n if (isAllowedScheme) {\n attrs.attrs.href = attrs.attrs.href.trim();\n return h(NcRichTextExternalLink, attrs, children);\n } else {\n delete attrs.attrs.href;\n delete attrs.attrs.target;\n return h(\"span\", attrs, children);\n }\n }\n return h(tag, attrs, children);\n }\n const placeholder = this.arguments[tag.slice(1)];\n if (!placeholder) {\n return h(\"span\", { ...{ attrs }, ...{ class: \"rich-text--fallback\" } }, [`{${tag.slice(1)}}`]);\n }\n if (!placeholder.component) {\n return h(\"span\", attrs, [placeholder]);\n }\n return h(\n placeholder.component,\n {\n attrs,\n props: placeholder.props,\n class: \"rich-text--component\"\n },\n children\n );\n },\n prefix: false\n }).processSync(this.text.replace(/<[^>]+>/g, (match) => match.replace(/</g, \"&lt;\")).replace(/&gt;/gmi, \">\")).result;\n return h(\"div\", { class: \"rich-text--wrapper rich-text--wrapper-markdown\" }, [\n renderedMarkdown,\n this.referenceLimit > 0 ? h(\"div\", { class: \"rich-text--reference-widget\" }, [\n h(NcReferenceList, {\n props: {\n text: this.prepareReferenceSource(this.text),\n referenceData: this.references,\n interactive: this.referenceInteractive,\n interactiveOptIn: this.referenceInteractiveOptIn\n }\n })\n ]) : null\n ]);\n },\n /**\n * Strip content of inline code and code blocks for reference widgets\n * (e.g. ignore fenced links from being added as reference)\n *\n * @param {string} text - Content of the node\n */\n prepareReferenceSource(text2) {\n if (!this.useMarkdown && !this.useExtendedMarkdown) {\n return text2;\n }\n const processor = unified();\n processor.compiler = (tree) => toString(tree);\n return processor.use(remarkParse).use(remarkStripCode).processSync(text2).value;\n }\n },\n render(h) {\n return this.useMarkdown || this.useExtendedMarkdown ? this.renderMarkdown(h) : this.renderPlaintext(h);\n }\n};\nconst _sfc_render = null;\nconst _sfc_staticRenderFns = null;\nvar __component__ = /* @__PURE__ */ normalizeComponent(\n _sfc_main,\n _sfc_render,\n _sfc_staticRenderFns,\n false,\n null,\n \"177dd7c0\"\n);\nconst NcRichText = __component__.exports;\nexport {\n NcRichText as N,\n NcReferenceList as a\n};\n//# sourceMappingURL=NcRichText-ByLPwUvM.mjs.map\n","import '../assets/NcChip-DLfUzq07.css';\nimport { c as mdiClose } from \"../chunks/mdi-DkJglNiS.mjs\";\nimport { useSlots, computed } from \"vue\";\nimport { N as NcActionButton } from \"../chunks/NcActionButton-K4jUGMlW.mjs\";\nimport { N as NcActions } from \"../chunks/NcActions-DbPerbGE.mjs\";\nimport { N as NcIconSvgWrapper } from \"../chunks/NcIconSvgWrapper-Bui9PhAS.mjs\";\nimport { r as register, m as t18, a as t } from \"../chunks/_l10n-DVz9Qdzk.mjs\";\nimport { n as normalizeComponent } from \"../chunks/_plugin-vue2_normalizer-DU4iP6Vu.mjs\";\nregister(t18);\nconst _sfc_main = {\n __name: \"NcChip\",\n props: {\n /**\n * aria label to set on the close button\n *\n * @default 'Close'\n */\n ariaLabelClose: {\n type: String,\n default: t(\"Close\")\n },\n /**\n * Container for the actions\n */\n actionsContainer: {\n type: String,\n default: \"body\"\n },\n /**\n * Main text of the chip.\n */\n text: {\n type: String,\n default: \"\"\n },\n /**\n * Set the chips design variant-\n *\n * This sets the background style of the chip, similar to NcButton's `variant`.\n *\n * @deprecated will be removed with v9 - use `variant` instead.\n */\n type: {\n type: String,\n default: \"secondary\",\n validator: (value) => [\"primary\", \"secondary\", \"tertiary\", \"error\", \"warning\", \"success\"].includes(value)\n },\n /**\n * SVG path of the icon to use, this takes precedence over `iconSVG`.\n * For example icon paths from `@mdi/js` can be used.\n */\n iconPath: {\n type: String,\n default: null\n },\n /**\n * Inline SVG to use as the icon\n */\n iconSvg: {\n type: String,\n default: null\n },\n /**\n * Set to true to prevent the close button to be shown\n */\n noClose: {\n type: Boolean,\n default: false\n },\n /**\n * Set the chips design variant-\n *\n * This sets the background style of the chip, similar to NcButton's `variant`.\n *\n * @since 8.24.0\n */\n variant: {\n type: String,\n default: \"secondary\",\n validator: (value) => [\"primary\", \"secondary\", \"tertiary\", \"error\", \"warning\", \"success\"].includes(value)\n }\n },\n emits: [\"close\"],\n setup(__props, { emit }) {\n const props = __props;\n const slots = useSlots();\n const realVariant = computed(() => props.type !== \"secondary\" ? props.type : props.variant);\n const canClose = computed(() => !props.noClose);\n const hasActions = () => Boolean(slots.actions?.());\n const hasIcon = () => Boolean(props.iconPath || props.iconSvg || !!slots.icon?.());\n return { __sfc: true, props, emit, slots, realVariant, canClose, hasActions, hasIcon, mdiClose, NcActionButton, NcActions, NcIconSvgWrapper };\n }\n};\nvar _sfc_render = function render() {\n var _vm = this, _c = _vm._self._c, _setup = _vm._self._setupProxy;\n return _c(\"div\", { staticClass: \"nc-chip\", class: {\n [`nc-chip--${_setup.realVariant}`]: true,\n \"nc-chip--no-actions\": _vm.noClose && !_setup.hasActions(),\n \"nc-chip--no-icon\": !_setup.hasIcon()\n } }, [_setup.hasIcon() ? _c(\"span\", { staticClass: \"nc-chip__icon\" }, [_vm._t(\"icon\", function() {\n return [_vm.iconPath || _vm.iconSvg ? _c(_setup.NcIconSvgWrapper, { attrs: { \"inline\": \"\", \"path\": _vm.iconPath, \"svg\": _vm.iconPath ? void 0 : _vm.iconSvg, \"size\": 18 } }) : _vm._e()];\n })], 2) : _vm._e(), _c(\"span\", { staticClass: \"nc-chip__text\" }, [_vm._t(\"default\", function() {\n return [_vm._v(_vm._s(_vm.text))];\n })], 2), _setup.canClose || _setup.hasActions() ? _c(_setup.NcActions, { staticClass: \"nc-chip__actions\", attrs: { \"container\": _vm.actionsContainer, \"force-menu\": !_setup.canClose, \"variant\": \"tertiary-no-background\" } }, [_setup.canClose ? _c(_setup.NcActionButton, { attrs: { \"close-after-click\": \"\" }, on: { \"click\": function($event) {\n return _setup.emit(\"close\");\n } }, scopedSlots: _vm._u([{ key: \"icon\", fn: function() {\n return [_c(_setup.NcIconSvgWrapper, { attrs: { \"path\": _setup.mdiClose, \"size\": 20 } })];\n }, proxy: true }], null, false, 2547223506) }, [_vm._v(\" \" + _vm._s(_vm.ariaLabelClose) + \" \")]) : _vm._e(), _vm._t(\"actions\")], 2) : _vm._e()], 1);\n};\nvar _sfc_staticRenderFns = [];\nvar __component__ = /* @__PURE__ */ normalizeComponent(\n _sfc_main,\n _sfc_render,\n _sfc_staticRenderFns,\n false,\n null,\n \"c8e429a5\"\n);\nconst NcChip = __component__.exports;\nexport {\n NcChip as default\n};\n//# sourceMappingURL=NcChip.mjs.map\n","<template>\n <span v-bind=\"$attrs\"\n :aria-hidden=\"title ? null : 'true'\"\n :aria-label=\"title\"\n class=\"material-design-icon robot-icon\"\n role=\"img\"\n @click=\"$emit('click', $event)\">\n <svg :fill=\"fillColor\"\n class=\"material-design-icon__svg\"\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\">\n <path d=\"M12,2A2,2 0 0,1 14,4C14,4.74 13.6,5.39 13,5.73V7H14A7,7 0 0,1 21,14H22A1,1 0 0,1 23,15V18A1,1 0 0,1 22,19H21V20A2,2 0 0,1 19,22H5A2,2 0 0,1 3,20V19H2A1,1 0 0,1 1,18V15A1,1 0 0,1 2,14H3A7,7 0 0,1 10,7H11V5.73C10.4,5.39 10,4.74 10,4A2,2 0 0,1 12,2M7.5,13A2.5,2.5 0 0,0 5,15.5A2.5,2.5 0 0,0 7.5,18A2.5,2.5 0 0,0 10,15.5A2.5,2.5 0 0,0 7.5,13M16.5,13A2.5,2.5 0 0,0 14,15.5A2.5,2.5 0 0,0 16.5,18A2.5,2.5 0 0,0 19,15.5A2.5,2.5 0 0,0 16.5,13Z\">\n <title v-if=\"title\">{{ title }}</title>\n </path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: \"RobotIcon\",\n emits: ['click'],\n props: {\n title: {\n type: String,\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n}\n</script>","<template>\n <span v-bind=\"$attrs\"\n :aria-hidden=\"title ? null : 'true'\"\n :aria-label=\"title\"\n class=\"material-design-icon close-icon\"\n role=\"img\"\n @click=\"$emit('click', $event)\">\n <svg :fill=\"fillColor\"\n class=\"material-design-icon__svg\"\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\">\n <path d=\"M19,6.41L17.59,5L12,10.59L6.41,5L5,6.41L10.59,12L5,17.59L6.41,19L12,13.41L17.59,19L19,17.59L13.41,12L19,6.41Z\">\n <title v-if=\"title\">{{ title }}</title>\n </path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: \"CloseIcon\",\n emits: ['click'],\n props: {\n title: {\n type: String,\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n}\n</script>","<template>\n <span v-bind=\"$attrs\"\n :aria-hidden=\"title ? null : 'true'\"\n :aria-label=\"title\"\n class=\"material-design-icon book-open-variant-icon\"\n role=\"img\"\n @click=\"$emit('click', $event)\">\n <svg :fill=\"fillColor\"\n class=\"material-design-icon__svg\"\n :width=\"size\"\n :height=\"size\"\n viewBox=\"0 0 24 24\">\n <path d=\"M12 21.5C10.65 20.65 8.2 20 6.5 20C4.85 20 3.15 20.3 1.75 21.05C1.65 21.1 1.6 21.1 1.5 21.1C1.25 21.1 1 20.85 1 20.6V6C1.6 5.55 2.25 5.25 3 5C4.11 4.65 5.33 4.5 6.5 4.5C8.45 4.5 10.55 4.9 12 6C13.45 4.9 15.55 4.5 17.5 4.5C18.67 4.5 19.89 4.65 21 5C21.75 5.25 22.4 5.55 23 6V20.6C23 20.85 22.75 21.1 22.5 21.1C22.4 21.1 22.35 21.1 22.25 21.05C20.85 20.3 19.15 20 17.5 20C15.8 20 13.35 20.65 12 21.5M12 8V19.5C13.35 18.65 15.8 18 17.5 18C18.7 18 19.9 18.15 21 18.5V7C19.9 6.65 18.7 6.5 17.5 6.5C15.8 6.5 13.35 7.15 12 8M13 11.5C14.11 10.82 15.6 10.5 17.5 10.5C18.41 10.5 19.26 10.59 20 10.78V9.23C19.13 9.08 18.29 9 17.5 9C15.73 9 14.23 9.28 13 9.84V11.5M17.5 11.67C15.79 11.67 14.29 11.93 13 12.46V14.15C14.11 13.5 15.6 13.16 17.5 13.16C18.54 13.16 19.38 13.24 20 13.4V11.9C19.13 11.74 18.29 11.67 17.5 11.67M20 14.57C19.13 14.41 18.29 14.33 17.5 14.33C15.67 14.33 14.17 14.6 13 15.13V16.82C14.11 16.16 15.6 15.83 17.5 15.83C18.54 15.83 19.38 15.91 20 16.07V14.57Z\">\n <title v-if=\"title\">{{ title }}</title>\n </path>\n </svg>\n </span>\n</template>\n\n<script>\nexport default {\n name: \"BookOpenVariantIcon\",\n emits: ['click'],\n props: {\n title: {\n type: String,\n },\n fillColor: {\n type: String,\n default: \"currentColor\"\n },\n size: {\n type: Number,\n default: 24\n }\n }\n}\n</script>","<template>\n\t<div class=\"bot-picker-modal-overlay\" @click.self=\"$emit('close')\">\n\t\t<div class=\"bot-picker-modal\">\n\t\t\t<div class=\"modal-header\">\n\t\t\t\t<div class=\"header-content\">\n\t\t\t\t\t<div class=\"bot-icon\">\n\t\t\t\t\t\t<IconRobot :size=\"28\" />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div class=\"header-text\">\n\t\t\t\t\t\t<h2>{{ bot.bot_name }}</h2>\n\t\t\t\t\t\t<span class=\"mention-badge\">{{ formatMention(bot.mention_name) }}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<NcButton type=\"tertiary\" @click=\"$emit('close')\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<IconClose :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\n\t\t\t<div class=\"modal-body\">\n\t\t\t\t<!-- Description -->\n\t\t\t\t<div v-if=\"bot.description\" class=\"detail-section\">\n\t\t\t\t\t<p class=\"description\">\n\t\t\t\t\t\t{{ bot.description }}\n\t\t\t\t\t</p>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Visibility & Access -->\n\t\t\t\t<div class=\"detail-section meta-info\">\n\t\t\t\t\t<div class=\"meta-item\">\n\t\t\t\t\t\t<span class=\"meta-label\">{{ t('educai', 'Visibility') }}</span>\n\t\t\t\t\t\t<NcChip\n\t\t\t\t\t\t\t:type=\"visibilityChipType\"\n\t\t\t\t\t\t\t:text=\"visibilityLabel\"\n\t\t\t\t\t\t\tno-close />\n\t\t\t\t\t</div>\n\t\t\t\t\t<div v-if=\"bot.owner_display_name\" class=\"meta-item\">\n\t\t\t\t\t\t<span class=\"meta-label\">{{ t('educai', 'Created by') }}</span>\n\t\t\t\t\t\t<span class=\"meta-value\">{{ bot.owner_display_name }}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Access Reason -->\n\t\t\t\t<div v-if=\"accessReasonText\" class=\"detail-section\">\n\t\t\t\t\t<NcNoteCard type=\"info\">\n\t\t\t\t\t\t{{ accessReasonText }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Tools Section -->\n\t\t\t\t<div v-if=\"bot.tools && bot.tools.length > 0\" class=\"detail-section\">\n\t\t\t\t\t<h3>{{ t('educai', 'Capabilities') }}</h3>\n\t\t\t\t\t<ul class=\"tools-list\">\n\t\t\t\t\t\t<li v-for=\"(tool, index) in bot.tools\" :key=\"index\" class=\"tool-item\">\n\t\t\t\t\t\t\t<span class=\"tool-name\">{{ tool.name }}</span>\n\t\t\t\t\t\t\t<NcChip\n\t\t\t\t\t\t\t\tv-if=\"tool.is_builtin\"\n\t\t\t\t\t\t\t\ttype=\"tertiary\"\n\t\t\t\t\t\t\t\t:text=\"t('educai', 'Built-in')\"\n\t\t\t\t\t\t\t\tno-close />\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- RAG Status -->\n\t\t\t\t<div v-if=\"bot.rag_enabled && bot.rag_source_count > 0\" class=\"detail-section\">\n\t\t\t\t\t<div class=\"rag-info\">\n\t\t\t\t\t\t<IconBookOpenVariant :size=\"18\" />\n\t\t\t\t\t\t<span>{{ t('educai', 'Has access to {count} knowledge source(s)', { count: bot.rag_source_count }) }}</span>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\n\t\t\t\t<!-- Warning for non-moderator when bot not enabled -->\n\t\t\t\t<div v-if=\"!canUseBot\" class=\"detail-section\">\n\t\t\t\t\t<NcNoteCard type=\"warning\">\n\t\t\t\t\t\t{{ unavailableMessage }}\n\t\t\t\t\t</NcNoteCard>\n\t\t\t\t</div>\n\t\t\t</div>\n\n\t\t\t<div class=\"modal-footer\">\n\t\t\t\t<NcButton type=\"secondary\" @click=\"$emit('close')\">\n\t\t\t\t\t{{ t('educai', 'Cancel') }}\n\t\t\t\t</NcButton>\n\t\t\t\t<NcButton\n\t\t\t\t\tv-if=\"canUseBot\"\n\t\t\t\t\ttype=\"primary\"\n\t\t\t\t\t:disabled=\"enabling\"\n\t\t\t\t\t@click=\"handleUseBot\">\n\t\t\t\t\t<template v-if=\"enabling\" #icon>\n\t\t\t\t\t\t<NcLoadingIcon :size=\"20\" />\n\t\t\t\t\t</template>\n\t\t\t\t\t{{ useButtonLabel }}\n\t\t\t\t</NcButton>\n\t\t\t</div>\n\t\t</div>\n\t</div>\n</template>\n\n<script>\nimport axios from '@nextcloud/axios'\nimport { APP_DISPLAY_NAME } from '../branding.js'\nimport { generateUrl } from '@nextcloud/router'\nimport { showError, showSuccess } from '@nextcloud/dialogs'\n\nimport NcButton from '@nextcloud/vue/dist/Components/NcButton.js'\nimport NcChip from '@nextcloud/vue/dist/Components/NcChip.js'\nimport NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'\nimport NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'\nimport IconRobot from 'vue-material-design-icons/Robot.vue'\nimport IconClose from 'vue-material-design-icons/Close.vue'\nimport IconBookOpenVariant from 'vue-material-design-icons/BookOpenVariant.vue'\n\nexport default {\n\tname: 'BotPickerModal',\n\n\tcomponents: {\n\t\tNcButton,\n\t\tNcChip,\n\t\tNcNoteCard,\n\t\tNcLoadingIcon,\n\t\tIconRobot,\n\t\tIconClose,\n\t\tIconBookOpenVariant,\n\t},\n\n\tprops: {\n\t\tbot: {\n\t\t\ttype: Object,\n\t\t\trequired: true,\n\t\t},\n\t\troomToken: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\t\tisModerator: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\tbotEnabled: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\troomStatusLoaded: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\troomStatusError: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\temits: ['close', 'use-bot', 'bot-enabled'],\n\n\tdata() {\n\t\treturn {\n\t\t\tenabling: false,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tvisibilityLabel() {\n\t\t\tconst v = this.bot.visibility || (this.bot.is_public ? 'global' : 'groups')\n\t\t\tif (v === 'global') return t('educai', 'Global')\n\t\t\tif (v === 'teams') return t('educai', 'Team')\n\t\t\tif (v === 'personal') return t('educai', 'Personal')\n\t\t\treturn t('educai', 'Group')\n\t\t},\n\n\t\tvisibilityChipType() {\n\t\t\tconst v = this.bot.visibility || (this.bot.is_public ? 'global' : 'groups')\n\t\t\tif (v === 'global') return 'success'\n\t\t\tif (v === 'personal') return 'tertiary'\n\t\t\treturn 'primary'\n\t\t},\n\n\t\taccessReasonText() {\n\t\t\tconst reason = this.bot.access_reason\n\t\t\tif (!reason) return null\n\t\t\tif (reason.type === 'global') return null\n\t\t\tif (reason.type === 'owner') return t('educai', 'You are the owner of this bot')\n\t\t\tif (reason.type === 'group' && reason.names?.length > 0) {\n\t\t\t\treturn t('educai', 'Access via group: {groups}', { groups: reason.names.join(', ') })\n\t\t\t}\n\t\t\tif (reason.type === 'team' && reason.names?.length > 0) {\n\t\t\t\treturn t('educai', 'Access via team: {teams}', { teams: reason.names.join(', ') })\n\t\t\t}\n\t\t\treturn null\n\t\t},\n\n\t\tcanUseBot() {\n\t\t\tif (this.botEnabled) {\n\t\t\t\treturn true\n\t\t\t}\n\n\t\t\tif (this.roomStatusError) {\n\t\t\t\treturn false\n\t\t\t}\n\n\t\t\treturn this.roomStatusLoaded && this.isModerator\n\t\t},\n\n\t\tuseButtonLabel() {\n\t\t\tif (this.enabling) {\n\t\t\t\treturn t('educai', 'Enabling...')\n\t\t\t}\n\t\t\tif (!this.botEnabled && this.isModerator) {\n\t\t\t\treturn t('educai', 'Enable & Use Bot')\n\t\t\t}\n\t\t\treturn t('educai', 'Use Bot')\n\t\t},\n\n\t\tunavailableMessage() {\n\t\t\tif (this.roomStatusLoaded && !this.botEnabled && !this.isModerator) {\n\t\t\t\treturn t('educai', 'In this chat room, only moderators can activate an {name} bot. Please ask a moderator to activate it first.', { name: APP_DISPLAY_NAME })\n\t\t\t}\n\n\t\t\tif (this.roomStatusError) {\n\t\t\t\treturn this.roomStatusError\n\t\t\t}\n\n\t\t\treturn t('educai', 'The {name} bot is not activated in this conversation. Please ask a moderator to activate it first.', { name: APP_DISPLAY_NAME })\n\t\t},\n\t},\n\n\tmethods: {\n\t\tformatMention(mentionName) {\n\t\t\tconst name = mentionName.startsWith('@') ? mentionName.substring(1) : mentionName\n\t\t\treturn `@${name}`\n\t\t},\n\n\t\tasync handleUseBot() {\n\t\t\tif (!this.canUseBot) {\n\t\t\t\tshowError(this.unavailableMessage)\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\t// If bot is not enabled and user is moderator, enable it first\n\t\t\tif (!this.botEnabled && this.isModerator && this.roomToken) {\n\t\t\t\tthis.enabling = true\n\t\t\t\ttry {\n\t\t\t\t\tawait axios.post(generateUrl(`/apps/educai/api/v1/talk/enable-bot/${this.roomToken}`))\n\t\t\t\t\tshowSuccess(t('educai', '{name} bot has been enabled in this conversation', { name: APP_DISPLAY_NAME }))\n\t\t\t\t\tthis.$emit('bot-enabled')\n\t\t\t\t} catch (error) {\n\t\t\t\t\tconsole.error('Failed to enable bot:', error)\n\t\t\t\t\tconst errorMessage = error.response?.data?.error\n\t\t\t\t\t\t?? t('educai', 'Failed to enable {name} bot', { name: APP_DISPLAY_NAME })\n\t\t\t\t\tshowError(errorMessage)\n\t\t\t\t\tthis.enabling = false\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.enabling = false\n\t\t\t}\n\n\t\t\t// Emit the use-bot event with the mention\n\t\t\tconst mentionName = this.bot.mention_name.startsWith('@')\n\t\t\t\t? this.bot.mention_name.substring(1)\n\t\t\t\t: this.bot.mention_name\n\n\t\t\tthis.$emit('use-bot', `@${mentionName}`)\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.bot-picker-modal-overlay {\n\tposition: fixed;\n\tz-index: 10000;\n\ttop: 0;\n\tleft: 0;\n\twidth: 100%;\n\theight: 100%;\n\tbackground: rgba(0, 0, 0, 0.5);\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tbackdrop-filter: blur(2px);\n}\n\n.bot-picker-modal {\n\tbackground: var(--color-main-background);\n\tborder-radius: var(--border-radius-large);\n\tbox-shadow: 0 8px 32px rgba(0, 0, 0, 0.24);\n\tmax-width: 500px;\n\twidth: 90%;\n\tmax-height: 80vh;\n\tdisplay: flex;\n\tflex-direction: column;\n\toverflow: hidden;\n}\n\n.modal-header {\n\tpadding: 16px 20px;\n\tborder-bottom: 1px solid var(--color-border);\n\tdisplay: flex;\n\tjustify-content: space-between;\n\talign-items: center;\n}\n\n.header-content {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 12px;\n}\n\n.bot-icon {\n\twidth: 44px;\n\theight: 44px;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\tborder-radius: 50%;\n\tbackground: var(--color-primary-element-light);\n\tcolor: var(--color-primary-element);\n}\n\n.header-text {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.header-text h2 {\n\tmargin: 0;\n\tfont-size: 18px;\n\tfont-weight: 600;\n\tline-height: 1.2;\n}\n\n.mention-badge {\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n\tfont-family: var(--font-monospace);\n}\n\n.modal-body {\n\tpadding: 20px;\n\toverflow-y: auto;\n\tflex: 1;\n}\n\n.detail-section {\n\tmargin-bottom: 16px;\n\n\t&:last-child {\n\t\tmargin-bottom: 0;\n\t}\n\n\th3 {\n\t\tmargin: 0 0 8px 0;\n\t\tfont-size: 13px;\n\t\tfont-weight: 600;\n\t\tcolor: var(--color-text-maxcontrast);\n\t\ttext-transform: uppercase;\n\t\tletter-spacing: 0.3px;\n\t}\n}\n\n.description {\n\tmargin: 0;\n\tfont-size: 15px;\n\tline-height: 1.5;\n\tcolor: var(--color-main-text);\n}\n\n.meta-info {\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 16px;\n}\n\n.meta-item {\n\tdisplay: flex;\n\tflex-direction: column;\n\tgap: 4px;\n}\n\n.meta-label {\n\tfont-size: 12px;\n\tcolor: var(--color-text-maxcontrast);\n\ttext-transform: uppercase;\n\tletter-spacing: 0.3px;\n}\n\n.meta-value {\n\tfont-size: 14px;\n\tcolor: var(--color-main-text);\n}\n\n.tools-list {\n\tlist-style: none;\n\tmargin: 0;\n\tpadding: 0;\n\tdisplay: flex;\n\tflex-wrap: wrap;\n\tgap: 8px;\n}\n\n.tool-item {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 6px;\n\tpadding: 6px 12px;\n\tbackground: var(--color-background-dark);\n\tborder-radius: var(--border-radius-pill);\n\tfont-size: 13px;\n}\n\n.tool-name {\n\tfont-weight: 500;\n}\n\n.rag-info {\n\tdisplay: flex;\n\talign-items: center;\n\tgap: 8px;\n\tpadding: 10px 14px;\n\tbackground: var(--color-background-dark);\n\tborder-radius: var(--border-radius);\n\tfont-size: 13px;\n\tcolor: var(--color-text-maxcontrast);\n}\n\n.modal-footer {\n\tpadding: 16px 20px;\n\tborder-top: 1px solid var(--color-border);\n\tdisplay: flex;\n\tjustify-content: flex-end;\n\tgap: 8px;\n}\n</style>\n","<template>\n\t<div class=\"bot-picker\">\n\t\t<div class=\"bot-picker__header\">\n\t\t\t<NcTextField\n\t\t\t\tref=\"searchInput\"\n\t\t\t\tv-model=\"searchQuery\"\n\t\t\t\t:label=\"t('educai', 'Search bots...')\"\n\t\t\t\t:placeholder=\"t('educai', 'Type to search')\"\n\t\t\t\t:show-trailing-button=\"searchQuery !== ''\"\n\t\t\t\ttrailing-button-icon=\"close\"\n\t\t\t\t@trailing-button-click=\"searchQuery = ''\"\n\t\t\t\t@keydown.enter=\"selectFirstBot\"\n\t\t\t\t@keydown.arrow-down=\"focusNextBot\"\n\t\t\t\t@keydown.arrow-up=\"focusPreviousBot\" />\n\t\t</div>\n\n\t\t<div class=\"bot-picker__content\">\n\t\t\t<div v-if=\"loading\" class=\"bot-picker__loading\">\n\t\t\t\t<NcLoadingIcon :size=\"32\" />\n\t\t\t\t<span>{{ t('educai', 'Loading bots...') }}</span>\n\t\t\t</div>\n\n\t\t\t<div v-else-if=\"error\" class=\"bot-picker__error\">\n\t\t\t\t<NcNoteCard type=\"error\">\n\t\t\t\t\t{{ error }}\n\t\t\t\t</NcNoteCard>\n\t\t\t</div>\n\n\t\t\t<div v-else-if=\"filteredBots.length === 0\" class=\"bot-picker__empty\">\n\t\t\t\t<NcEmptyContent\n\t\t\t\t\t:name=\"searchQuery ? t('educai', 'No bots found') : t('educai', 'No bots available')\"\n\t\t\t\t\t:description=\"searchQuery ? t('educai', 'Try a different search term') : t('educai', 'Create a bot in the EducAI settings')\">\n\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t<IconRobot />\n\t\t\t\t\t</template>\n\t\t\t\t</NcEmptyContent>\n\t\t\t</div>\n\n\t\t\t<ul v-else class=\"bot-picker__list\" role=\"listbox\">\n\t\t\t\t<li\n\t\t\t\t\tv-for=\"(bot, index) in filteredBots\"\n\t\t\t\t\t:key=\"bot.id\"\n\t\t\t\t\t:ref=\"`bot-${index}`\"\n\t\t\t\t\tclass=\"bot-picker__item\"\n\t\t\t\t\t:class=\"{ 'bot-picker__item--focused': focusedIndex === index }\"\n\t\t\t\t\trole=\"option\"\n\t\t\t\t\ttabindex=\"0\"\n\t\t\t\t\t@click=\"openBotModal(bot)\"\n\t\t\t\t\t@keydown.enter=\"openBotModal(bot)\"\n\t\t\t\t\t@keydown.space.prevent=\"openBotModal(bot)\"\n\t\t\t\t\t@focus=\"focusedIndex = index\">\n\t\t\t\t\t<div class=\"bot-picker__item-content\">\n\t\t\t\t\t\t<div class=\"bot-picker__item-header\">\n\t\t\t\t\t\t\t<span class=\"bot-picker__item-name\">{{ bot.bot_name }}</span>\n\t\t\t\t\t\t\t<span class=\"bot-picker__item-mention\">{{ formatMention(bot.mention_name) }}</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<span v-if=\"bot.description\" class=\"bot-picker__item-description\">\n\t\t\t\t\t\t\t{{ truncateDescription(bot.description) }}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t\t<div class=\"bot-picker__item-meta\">\n\t\t\t\t\t\t\t<NcChip\n\t\t\t\t\t\t\t\t:type=\"getVisibilityChipType(bot)\"\n\t\t\t\t\t\t\t\t:text=\"getVisibilityLabel(bot)\"\n\t\t\t\t\t\t\t\tno-close />\n\t\t\t\t\t\t\t<span v-if=\"bot.owner_display_name\" class=\"bot-picker__item-creator\">\n\t\t\t\t\t\t\t\t{{ t('educai', 'by {name}', { name: bot.owner_display_name }) }}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</li>\n\t\t\t</ul>\n\t\t</div>\n\n\t\t<div class=\"bot-picker__footer\">\n\t\t\t<span class=\"bot-picker__hint\">\n\t\t\t\t{{ t('educai', 'Select a bot to see details and use it') }}\n\t\t\t</span>\n\t\t</div>\n\n\t\t<!-- Bot Detail Modal -->\n\t\t<BotPickerModal\n\t\t\tv-if=\"showModal && selectedBot\"\n\t\t\t:bot=\"selectedBot\"\n\t\t\t:room-token=\"roomToken\"\n\t\t\t:is-moderator=\"isModerator\"\n\t\t\t:bot-enabled=\"botEnabled\"\n\t\t\t:room-status-loaded=\"roomStatusLoaded\"\n\t\t\t:room-status-error=\"roomStatusError\"\n\t\t\t@close=\"closeModal\"\n\t\t\t@bot-enabled=\"handleBotEnabled\"\n\t\t\t@use-bot=\"handleUseBot\" />\n\t</div>\n</template>\n\n<script>\nimport { generateUrl } from '@nextcloud/router'\nimport { APP_DISPLAY_NAME } from '../branding.js'\nimport axios from '@nextcloud/axios'\n\nimport NcTextField from '@nextcloud/vue/dist/Components/NcTextField.js'\nimport NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js'\nimport NcNoteCard from '@nextcloud/vue/dist/Components/NcNoteCard.js'\nimport NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js'\nimport NcChip from '@nextcloud/vue/dist/Components/NcChip.js'\nimport IconRobot from 'vue-material-design-icons/Robot.vue'\nimport BotPickerModal from './BotPickerModal.vue'\n\nexport default {\n\tname: 'BotPickerElement',\n\n\tcomponents: {\n\t\tNcTextField,\n\t\tNcLoadingIcon,\n\t\tNcNoteCard,\n\t\tNcEmptyContent,\n\t\tNcChip,\n\t\tIconRobot,\n\t\tBotPickerModal,\n\t},\n\n\tprops: {\n\t\tproviderId: {\n\t\t\ttype: String,\n\t\t\trequired: true,\n\t\t},\n\t\taccessible: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: true,\n\t\t},\n\t\troomToken: {\n\t\t\ttype: String,\n\t\t\tdefault: null,\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tbots: [],\n\t\t\tsearchQuery: '',\n\t\t\tloading: true,\n\t\t\terror: null,\n\t\t\tfocusedIndex: -1,\n\t\t\t// Use Nextcloud's global current user (available via OC object)\n\t\t\tcurrentUser: window.OC?.currentUser || null,\n\t\t\t// Modal state\n\t\t\tshowModal: false,\n\t\t\tselectedBot: null,\n\t\t\t// Talk room state\n\t\t\tisModerator: false,\n\t\t\tbotEnabled: false,\n\t\t\troomStatusLoaded: false,\n\t\t\troomStatusError: null,\n\t\t}\n\t},\n\n\tcomputed: {\n\t\tfilteredBots() {\n\t\t\tif (!this.searchQuery) {\n\t\t\t\treturn this.bots\n\t\t\t}\n\t\t\tconst query = this.searchQuery.toLowerCase()\n\t\t\treturn this.bots.filter(bot => {\n\t\t\t\treturn bot.bot_name.toLowerCase().includes(query)\n\t\t\t\t\t|| bot.mention_name.toLowerCase().includes(query)\n\t\t\t\t\t|| (bot.description && bot.description.toLowerCase().includes(query))\n\t\t\t})\n\t\t},\n\t},\n\n\tmounted() {\n\t\tthis.loadBots()\n\t\tthis.loadRoomStatus()\n\t\t// Focus search input when picker opens\n\t\tthis.$nextTick(() => {\n\t\t\tthis.$refs.searchInput?.$el?.querySelector('input')?.focus()\n\t\t})\n\t},\n\n\tmethods: {\n\t\tasync loadBots() {\n\t\t\tthis.loading = true\n\t\t\tthis.error = null\n\n\t\t\ttry {\n\t\t\t\t// Fetch available bots (public bots accessible to user)\n\t\t\t\tconst response = await axios.get(generateUrl('/apps/educai/api/v1/public-bots'))\n\t\t\t\tthis.bots = response.data || []\n\n\t\t\t\t// Also fetch user's personal bots\n\t\t\t\tconst personalResponse = await axios.get(generateUrl('/apps/educai/api/v1/bots'))\n\t\t\t\tconst personalBots = personalResponse.data || []\n\n\t\t\t\t// Merge and deduplicate by ID\n\t\t\t\tconst botMap = new Map()\n\t\t\t\tfor (const bot of this.bots) {\n\t\t\t\t\tbotMap.set(bot.id, bot)\n\t\t\t\t}\n\t\t\t\tfor (const bot of personalBots) {\n\t\t\t\t\tif (!botMap.has(bot.id)) {\n\t\t\t\t\t\tbotMap.set(bot.id, { ...bot, visibility: 'personal' })\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tthis.bots = Array.from(botMap.values()).sort((a, b) => {\n\t\t\t\t\t// Sort personal bots first, then by name\n\t\t\t\t\tif (a.visibility === 'personal' && b.visibility !== 'personal') return -1\n\t\t\t\t\tif (b.visibility === 'personal' && a.visibility !== 'personal') return 1\n\t\t\t\t\treturn a.bot_name.localeCompare(b.bot_name)\n\t\t\t\t})\n\t\t\t} catch (err) {\n\t\t\t\tconsole.error('[EducAI] Failed to load bots:', err)\n\t\t\t\tthis.error = t('educai', 'Failed to load bots. Please try again.')\n\t\t\t} finally {\n\t\t\t\tthis.loading = false\n\t\t\t}\n\t\t},\n\n\t\tasync loadRoomStatus() {\n\t\t\tif (!this.roomToken) {\n\t\t\t\tconsole.debug('[EducAI] Bot picker: No room token provided, skipping room status check')\n\t\t\t\tthis.roomStatusLoaded = true\n\t\t\t\tthis.roomStatusError = t('educai', 'Unable to determine the current chat room. Please refresh the page. In this chat room, only moderators can activate an {name} bot.', { name: APP_DISPLAY_NAME })\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\ttry {\n\t\t\t\tthis.roomStatusLoaded = false\n\t\t\t\tthis.roomStatusError = null\n\t\t\t\tconst response = await axios.get(generateUrl(`/apps/educai/api/v1/talk/bot-status/${this.roomToken}`))\n\t\t\t\tconst data = response.data\n\t\t\t\tthis.isModerator = data.isModerator ?? false\n\t\t\t\tthis.botEnabled = data.botEnabled ?? false\n\t\t\t\tthis.roomStatusLoaded = true\n\t\t\t\tconsole.debug('[EducAI] Bot picker: Room status loaded', {\n\t\t\t\t\troomToken: this.roomToken,\n\t\t\t\t\tisModerator: this.isModerator,\n\t\t\t\t\tbotEnabled: this.botEnabled,\n\t\t\t\t})\n\t\t\t} catch (err) {\n\t\t\t\tconsole.warn('[EducAI] Failed to load room status:', err)\n\t\t\t\tthis.isModerator = false\n\t\t\t\tthis.botEnabled = false\n\t\t\t\tthis.roomStatusLoaded = true\n\t\t\t\tthis.roomStatusError = t('educai', 'Unable to verify whether the {name} bot is active in this conversation. Please try again or ask a moderator to activate it.', { name: APP_DISPLAY_NAME })\n\t\t\t}\n\t\t},\n\n\t\topenBotModal(bot) {\n\t\t\tthis.selectedBot = bot\n\t\t\tthis.showModal = true\n\t\t},\n\n\t\tcloseModal() {\n\t\t\tthis.showModal = false\n\t\t\tthis.selectedBot = null\n\t\t},\n\n\t\thandleUseBot(mention) {\n\t\t\tthis.closeModal()\n\t\t\t// Dispatch the submit event that Smart Picker expects\n\t\t\tconst event = new CustomEvent('submit', {\n\t\t\t\tbubbles: true,\n\t\t\t\tdetail: mention,\n\t\t\t})\n\t\t\tthis.$el.dispatchEvent(event)\n\t\t},\n\n\t\thandleBotEnabled() {\n\t\t\tthis.botEnabled = true\n\t\t\tthis.roomStatusError = null\n\t\t},\n\n\t\tselectFirstBot() {\n\t\t\tif (this.filteredBots.length > 0) {\n\t\t\t\tthis.openBotModal(this.filteredBots[0])\n\t\t\t}\n\t\t},\n\n\t\tfocusNextBot() {\n\t\t\tif (this.focusedIndex < this.filteredBots.length - 1) {\n\t\t\t\tthis.focusedIndex++\n\t\t\t\tthis.focusBotAtIndex(this.focusedIndex)\n\t\t\t}\n\t\t},\n\n\t\tfocusPreviousBot() {\n\t\t\tif (this.focusedIndex > 0) {\n\t\t\t\tthis.focusedIndex--\n\t\t\t\tthis.focusBotAtIndex(this.focusedIndex)\n\t\t\t}\n\t\t},\n\n\t\tfocusBotAtIndex(index) {\n\t\t\tconst ref = this.$refs[`bot-${index}`]\n\t\t\tif (ref && ref[0]) {\n\t\t\t\tref[0].focus()\n\t\t\t}\n\t\t},\n\n\t\tformatMention(mentionName) {\n\t\t\t// Display as @mention format\n\t\t\tconst name = mentionName.startsWith('@') ? mentionName.substring(1) : mentionName\n\t\t\treturn `@${name}`\n\t\t},\n\n\t\ttruncateDescription(description, maxLength = 80) {\n\t\t\tif (description.length <= maxLength) {\n\t\t\t\treturn description\n\t\t\t}\n\t\t\treturn description.substring(0, maxLength).trim() + '...'\n\t\t},\n\n\t\tgetVisibilityLabel(bot) {\n\t\t\tconst v = bot.visibility || (bot.is_public ? 'global' : 'groups')\n\t\t\tif (v === 'global') return t('educai', 'Global')\n\t\t\tif (v === 'teams') return t('educai', 'Team')\n\t\t\tif (v === 'personal') return t('educai', 'Personal')\n\t\t\treturn t('educai', 'Group')\n\t\t},\n\n\t\tgetVisibilityChipType(bot) {\n\t\t\tconst v = bot.visibility || (bot.is_public ? 'global' : 'groups')\n\t\t\tif (v === 'global') return 'success'\n\t\t\tif (v === 'personal') return 'tertiary'\n\t\t\treturn 'primary'\n\t\t},\n\t},\n}\n</script>\n\n<style scoped lang=\"scss\">\n.bot-picker {\n\tdisplay: flex;\n\tflex-direction: column;\n\twidth: 100%;\n\theight: 100%;\n\tmin-width: 400px;\n\tmin-height: 300px;\n\n\t&__header {\n\t\tpadding: 12px;\n\t\tborder-bottom: 1px solid var(--color-border);\n\t}\n\n\t&__content {\n\t\tflex: 1;\n\t\toverflow-y: auto;\n\t\tmin-height: 200px;\n\t}\n\n\t&__loading,\n\t&__error,\n\t&__empty {\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\talign-items: center;\n\t\tjustify-content: center;\n\t\tpadding: 24px;\n\t\tgap: 12px;\n\t\tcolor: var(--color-text-maxcontrast);\n\t}\n\n\t&__list {\n\t\tlist-style: none;\n\t\tmargin: 0;\n\t\tpadding: 8px;\n\t}\n\n\t&__item {\n\t\tdisplay: flex;\n\t\talign-items: flex-start;\n\t\tpadding: 12px;\n\t\tborder-radius: var(--border-radius-large);\n\t\tcursor: pointer;\n\t\ttransition: background-color 0.1s ease;\n\n\t\t&:hover,\n\t\t&:focus,\n\t\t&--focused {\n\t\t\tbackground-color: var(--color-background-hover);\n\t\t\toutline: none;\n\t\t}\n\n\t\t&:focus-visible {\n\t\t\tbox-shadow: 0 0 0 2px var(--color-primary);\n\t\t}\n\t}\n\n\t&__item-content {\n\t\tflex: 1;\n\t\tmin-width: 0;\n\t\tdisplay: flex;\n\t\tflex-direction: column;\n\t\tgap: 4px;\n\t}\n\n\t&__item-header {\n\t\tdisplay: flex;\n\t\talign-items: baseline;\n\t\tgap: 8px;\n\t}\n\n\t&__item-name {\n\t\tfont-weight: 600;\n\t\tcolor: var(--color-main-text);\n\t}\n\n\t&__item-mention {\n\t\tfont-size: 13px;\n\t\tcolor: var(--color-text-maxcontrast);\n\t\tfont-family: var(--font-monospace);\n\t}\n\n\t&__item-description {\n\t\tfont-size: 13px;\n\t\tcolor: var(--color-text-lighter);\n\t\toverflow: hidden;\n\t\ttext-overflow: ellipsis;\n\t\twhite-space: nowrap;\n\t}\n\n\t&__item-meta {\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tgap: 8px;\n\t\tmargin-top: 2px;\n\t}\n\n\t&__item-creator {\n\t\tfont-size: 12px;\n\t\tcolor: var(--color-text-maxcontrast);\n\t}\n\n\t&__footer {\n\t\tpadding: 8px 12px;\n\t\tborder-top: 1px solid var(--color-border);\n\t}\n\n\t&__hint {\n\t\tfont-size: 12px;\n\t\tcolor: var(--color-text-maxcontrast);\n\t}\n}\n</style>\n","/**\n * Smart Picker Bot Provider - Entry Point\n *\n * This script is loaded when the Smart Picker is rendered (via RenderReferenceEvent).\n * It registers a custom picker component for bot mentions.\n *\n * Note: The Talk-only restriction is handled by checking context before registering.\n * If not in Talk, the picker simply won't be registered, making it invisible.\n */\n\nimport { registerCustomPickerElement, NcCustomPickerRenderResult } from '@nextcloud/vue/dist/Components/NcRichText.js'\nimport Vue from 'vue'\nimport BotPickerElement from './components/BotPickerElement.vue'\n\nVue.mixin({ methods: { t, n } })\n\n/**\n * Detect if we're currently in Nextcloud Talk context.\n *\n * Uses multiple heuristics to reliably detect Talk:\n * - OCA.Talk or OCA.Spreed objects (Talk's global namespace)\n * - DOM element with id=\"spreed\" (Talk's main container)\n * - URL patterns for Talk routes\n *\n * @return {boolean} True if in Talk context\n */\nfunction isTalkContext() {\n\t// Check for Talk's JavaScript namespace\n\tif (window.OCA?.Talk || window.OCA?.Spreed) {\n\t\tconsole.debug('[EducAI] Bot picker: Detected Talk via OCA namespace')\n\t\treturn true\n\t}\n\n\t// Check for Talk's main DOM container\n\tif (document.getElementById('spreed')) {\n\t\tconsole.debug('[EducAI] Bot picker: Detected Talk via DOM element')\n\t\treturn true\n\t}\n\n\t// Check URL patterns\n\tconst path = window.location.pathname\n\tif (path.includes('/apps/spreed') || path.includes('/call/')) {\n\t\tconsole.debug('[EducAI] Bot picker: Detected Talk via URL pattern')\n\t\treturn true\n\t}\n\n\t// Check if spreed app is in URL hash (for embedded Talk)\n\tif (window.location.hash.includes('spreed')) {\n\t\tconsole.debug('[EducAI] Bot picker: Detected Talk via URL hash')\n\t\treturn true\n\t}\n\n\treturn false\n}\n\n/**\n * Extract the room token from the current Talk URL.\n *\n * Handles various URL patterns:\n * - /call/{token}\n * - /apps/spreed/call/{token}\n * - /index.php/call/{token}\n * - /index.php/apps/spreed/call/{token}\n *\n * @return {string|null} The room token or null if not found\n */\nfunction extractRoomToken() {\n\tconst path = window.location.pathname\n\n\t// Pattern: /call/{token} or /apps/spreed/call/{token}\n\t// The token is the segment after /call/\n\tconst callMatch = path.match(/\\/call\\/([a-zA-Z0-9]+)/)\n\tif (callMatch) {\n\t\tconsole.debug('[EducAI] Bot picker: Extracted room token from URL:', callMatch[1])\n\t\treturn callMatch[1]\n\t}\n\n\t// Also check hash for embedded Talk (e.g., #/call/{token})\n\tconst hash = window.location.hash\n\tconst hashMatch = hash.match(/\\/call\\/([a-zA-Z0-9]+)/)\n\tif (hashMatch) {\n\t\tconsole.debug('[EducAI] Bot picker: Extracted room token from hash:', hashMatch[1])\n\t\treturn hashMatch[1]\n\t}\n\n\tconsole.debug('[EducAI] Bot picker: Could not extract room token from URL')\n\treturn null\n}\n\n/**\n * Register the bot picker component with the Smart Picker.\n */\nfunction registerBotPicker() {\n\tconsole.debug('[EducAI] Bot picker: Registering custom picker element')\n\n\ttry {\n\t\tregisterCustomPickerElement(\n\t\t\t'educai-bots',\n\t\t\t(el, { providerId, accessible }) => {\n\t\t\t\t// Extract room token from URL at render time\n\t\t\t\tconst roomToken = extractRoomToken()\n\t\t\t\tconsole.debug('[EducAI] Bot picker: Creating picker element', { providerId, accessible, roomToken })\n\n\t\t\t\tconst Element = Vue.extend(BotPickerElement)\n\t\t\t\tconst vueElement = new Element({\n\t\t\t\t\tpropsData: {\n\t\t\t\t\t\tproviderId,\n\t\t\t\t\t\taccessible,\n\t\t\t\t\t\troomToken,\n\t\t\t\t\t},\n\t\t\t\t}).$mount(el)\n\t\t\t\treturn new NcCustomPickerRenderResult(vueElement.$el, vueElement)\n\t\t\t},\n\t\t\t(el, renderResult) => {\n\t\t\t\t// Cleanup when picker is closed\n\t\t\t\tconsole.debug('[EducAI] Bot picker: Destroying picker element')\n\t\t\t\trenderResult.object.$destroy()\n\t\t\t},\n\t\t)\n\t\tconsole.debug('[EducAI] Bot picker: Successfully registered')\n\t} catch (error) {\n\t\tconsole.error('[EducAI] Bot picker: Failed to register', error)\n\t}\n}\n\n/**\n * Initialize the bot picker component.\n * Checks Talk context and registers the picker if appropriate.\n */\nfunction initBotPicker() {\n\tconsole.debug('[EducAI] Bot picker: Initializing...')\n\n\t// Check if we're in Talk context\n\tconst inTalk = isTalkContext()\n\tconsole.debug('[EducAI] Bot picker: Talk context detected:', inTalk)\n\n\tif (!inTalk) {\n\t\tconsole.debug('[EducAI] Bot picker: Not in Talk context, skipping registration')\n\t\treturn\n\t}\n\n\t// Register the picker\n\tregisterBotPicker()\n}\n\n// Initialize when DOM is ready\nif (document.readyState === 'loading') {\n\tdocument.addEventListener('DOMContentLoaded', initBotPicker)\n} else {\n\t// DOM already loaded, but Talk objects might not be ready yet\n\t// Use a small delay to allow Talk to initialize\n\tsetTimeout(initBotPicker, 100)\n}\n"],"names":["_sfc_main$4","_sfc_render$4","_vm","_c","$event","_sfc_staticRenderFns$4","__component__$4","normalizeComponent","Alert","_sfc_main$3","_sfc_render$3","_sfc_staticRenderFns$3","__component__$3","AlertDecagram","_sfc_main$2","_sfc_render$2","_sfc_staticRenderFns$2","__component__$2","CheckboxMarkedCircle","_sfc_main$1","_sfc_render$1","_sfc_staticRenderFns$1","__component__$1","Information","_sfc_main","type","isLegacy32","_sfc_render","_sfc_staticRenderFns","__component__","NcNoteCard","id","callback","onDestroy","props","registerWidget","propsWithDefaults","logger","registerCustomPickerElement","NcCustomPickerRenderResult","element","object","size","register","t23","t8","t","imagePath","loadState","t41","t47","t24","t31","t43","t12","t18","t21","asciiAlpha","regexCheck","asciiAlphanumeric","asciiControl","code2","markdownLineEndingOrSpace","unicodePunctuation","unicodeWhitespace","regex","check","convert","test","ok","castFactory","anyFactory","propertiesFactory","typeFactory","tests","checks","index","any","parameters","index2","checkAsRecord","all","node","nodeAsRecord","key","testFunction","value","parent","looksLikeANode","wwwPrefix","tokenizeWwwPrefix","domain","tokenizeDomain","path","tokenizePath","trail","tokenizeTrail","emailDomainDotTrail","tokenizeEmailDomainDotTrail","wwwAutolink","tokenizeWwwAutolink","previousWww","protocolAutolink","tokenizeProtocolAutolink","previousProtocol","emailAutolink","tokenizeEmailAutolink","previousEmail","text","code","effects","ok2","nok","self","dot","data","start","gfmAtext","previousUnbalanced","atext","emailDomain","emailDomainAfter","emailDomainDot","wwwStart","wwwAfter","buffer","seen","protocolStart","protocolPrefixInside","protocol","protocolSlashesInside","afterProtocol","protocolAfter","wwwPrefixInside","wwwPrefixAfter","underscoreInLastSegment","underscoreInLastLastSegment","domainInside","domainAfter","domainAtPunctuation","sizeOpen","sizeClose","pathInside","pathAtPunctuation","trail2","trailCharRefStart","trailBracketAfter","trailCharRefInside","after","events","result","token","ref","__props","emit","slots","useSlots","realVariant","computed","canClose","mdiClose","NcActionButton","NcActions","NcIconSvgWrapper","_setup","NcChip","NcButton","NcLoadingIcon","IconRobot","IconClose","IconBookOpenVariant","v","reason","APP_DISPLAY_NAME","mentionName","showError","axios","generateUrl","showSuccess","error","errorMessage","NcTextField","NcEmptyContent","BotPickerModal","query","bot","response","personalBots","botMap","a","b","err","mention","event","description","maxLength","Vue","isTalkContext","extractRoomToken","callMatch","hashMatch","registerBotPicker","el","providerId","accessible","roomToken","Element","BotPickerElement","vueElement","renderResult","initBotPicker","inTalk"],"mappings":"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","x_google_ignoreList":[0,1,2,3,4,5,6,7,8]}