@mikedown/web-component 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -66,7 +66,8 @@ unpkg works the same way:
66
66
 
67
67
  About the bundle:
68
68
 
69
- - It is about 780 kB gzipped (the budget is 850 kB). Most of that is syntax highlighting for every language highlight.js knows.
69
+ - It is about 815 kB gzipped up front (the budget is 850 kB). Most of that is syntax highlighting for every language highlight.js knows.
70
+ - It is split into a few files next to each other in `dist/`: the entry, a chunk it imports at once, and the AI UI (about 56 kB gzipped), which loads only when an element gets an `ai` host. The one `<script>` tag above is all a page needs; the browser fetches the chunks from the same folder. To self-host, copy every `dist/mikedown-editor.*.js` file, not only the entry.
70
71
  - The stylesheet goes into one `<style id="mikedown-styles">` at the start of `<head>`, once per page, so your own stylesheets come later and win. Don't also load `@mikedown/core/styles.css`.
71
72
  - KaTeX and Mermaid are not bundled. The first formula loads KaTeX (and one `<link>` to its CSS) from jsDelivr, the first diagram loads Mermaid, both pinned to the versions the bundle was built with. Turn either off with `features='{"math":false}'` or `features='{"mermaid":false}'` and nothing is fetched.
72
73
  - To use the module's exports (`MikeDownElement`, `defineMikeDownElement`), import the same URL: `import { MikeDownElement } from 'https://cdn.jsdelivr.net/npm/@mikedown/web-component@0.2.0/dist/mikedown-editor.standalone.js'`.
@@ -107,11 +108,14 @@ Every attribute has a matching property; setting either updates the other.
107
108
  | `value` | `string` | The current markdown, updated on every keystroke. Setting it loads the text as the clean baseline and fires no `change`. |
108
109
  | `settings` | `Partial<MikeDownSettings>` | Core settings (`fontFamily`, `fontSize`, `contentWidth`, `spellCheckLanguage`, ...), applied live. |
109
110
  | `host` | `Partial<MikeDownHost>` | Host methods: `uploadImage`, `openLink`, `resolveImageSrc`, `pickImage`, `getLinkSuggestions`, ... Core turns a feature on only when its method is present. Setting it rebuilds the editor. |
111
+ | `ai` | `MikeDownAiHost` | The AI host group (`complete`, and for tier 2 `listEngines`, ...), passed to the core untouched. A property only, no attribute; `host.ai` works too. Setting it rebuilds the editor. See [Bring your own AI](https://github.com/mikejoseph23/mikedown/tree/main/packages/core#bring-your-own-ai). |
110
112
  | `handle` | `MikeDownEditorHandle \| null` | Read only. The core editor handle while connected (`command`, `getHtml`, `insertImage`, ...). |
111
113
  | `form`, `labels`, `validity`, `validationMessage`, `willValidate` | | As on native form controls. |
112
114
 
113
115
  Methods: `focus()`, `checkValidity()`, `reportValidity()`.
114
116
 
117
+ **Toolbar layout.** Users can reorder, remove and add toolbar buttons in the editor (Settings, then Toolbar). The result is one JSON value, `settings.toolbarLayout` (`{ version, items, seen }`, typed `ToolbarLayout`). Pass it in `settings` to preset or restore a layout, and store the value your `host.saveSettings` receives; `null` means Reset to Default, and an absent or invalid value shows the default toolbar. Set `features.customizeToolbar: false` to hide the customize controls; a `toolbarLayout` you pass still applies. `ToolbarLayout`, `ToolbarItemId`, `TOOLBAR_ITEM_IDS`, `DEFAULT_TOOLBAR_LAYOUT` and `normalizeToolbarLayout` are exported from `@mikedown/core`.
118
+
115
119
  Function-valued options (`host`) and objects (`settings`) are properties only:
116
120
 
117
121
  ```js
@@ -1,6 +1,6 @@
1
1
  # Third-party notices
2
2
 
3
- `dist/mikedown-editor.standalone.js` in @mikedown/web-component bundles the packages below. Their licenses are reproduced here as they require.
3
+ `dist/mikedown-editor.standalone.js` and its chunks (`dist/mikedown-editor.*.js`) in @mikedown/web-component bundle the packages below. Their licenses are reproduced here as they require.
4
4
 
5
5
  Generated by `scripts/build-standalone.mjs` from the bundle's inputs: 81 packages (78 MIT, 1 BSD-2-Clause, 1 BSD-3-Clause, 1 ISC).
6
6
 
@@ -89,7 +89,7 @@ function dedentScriptText(text) {
89
89
  function parseTheme(value) {
90
90
  return value === "light" || value === "dark" ? value : "auto";
91
91
  }
92
- var _internals, _binding, _value, _defaultValue, _valueSetByProperty, _initialized, _featuresAttrCache, _settings, _host, _formDisabled, _rebuildQueued, _fallbackInput, _fallbackForm, _MikeDownElement_instances, upgradeProperty_fn, readInitialValue_fn, create_fn, destroy_fn, scheduleRebuild_fn, setValue_fn, accessibleName_fn, isDisabled_fn, applyDisabled_fn, applyMinHeight_fn, setOrRemove_fn, hasFormInternals_fn, valueMissing_fn, syncForm_fn, syncValidity_fn, attachFallbackForm_fn, detachFallbackForm_fn, _onFallbackReset;
92
+ var _internals, _binding, _value, _defaultValue, _valueSetByProperty, _initialized, _featuresAttrCache, _settings, _host, _ai, _formDisabled, _rebuildQueued, _fallbackInput, _fallbackForm, _MikeDownElement_instances, upgradeProperty_fn, readInitialValue_fn, create_fn, destroy_fn, scheduleRebuild_fn, setValue_fn, accessibleName_fn, isDisabled_fn, applyDisabled_fn, applyMinHeight_fn, setOrRemove_fn, hasFormInternals_fn, valueMissing_fn, syncForm_fn, syncValidity_fn, attachFallbackForm_fn, detachFallbackForm_fn, _onFallbackReset;
93
93
  var MikeDownElement = class extends Base {
94
94
  constructor() {
95
95
  super();
@@ -105,6 +105,7 @@ var MikeDownElement = class extends Base {
105
105
  __privateAdd(this, _featuresAttrCache, { raw: null, parsed: null });
106
106
  __privateAdd(this, _settings, {});
107
107
  __privateAdd(this, _host, {});
108
+ __privateAdd(this, _ai);
108
109
  __privateAdd(this, _formDisabled, false);
109
110
  __privateAdd(this, _rebuildQueued, false);
110
111
  __privateAdd(this, _fallbackInput, null);
@@ -338,6 +339,18 @@ var MikeDownElement = class extends Base {
338
339
  __privateSet(this, _host, host ?? {});
339
340
  __privateMethod(this, _MikeDownElement_instances, scheduleRebuild_fn).call(this);
340
341
  }
342
+ /**
343
+ * The AI host group (`complete`, and for tier 2 `listEngines`, `testEngine`, ...). A property only: it holds
344
+ * functions, so there is no attribute. Wins over `host.ai`. Core turns the AI features on when it is present,
345
+ * so a change rebuilds the editor. Core ships no provider SDK; the page supplies the transport.
346
+ */
347
+ get ai() {
348
+ return __privateGet(this, _ai) ?? __privateGet(this, _host).ai;
349
+ }
350
+ set ai(ai) {
351
+ __privateSet(this, _ai, ai ?? void 0);
352
+ __privateMethod(this, _MikeDownElement_instances, scheduleRebuild_fn).call(this);
353
+ }
341
354
  /** The editor handle while connected, else null. */
342
355
  get handle() {
343
356
  return __privateGet(this, _binding)?.handle ?? null;
@@ -409,6 +422,7 @@ _initialized = new WeakMap();
409
422
  _featuresAttrCache = new WeakMap();
410
423
  _settings = new WeakMap();
411
424
  _host = new WeakMap();
425
+ _ai = new WeakMap();
412
426
  _formDisabled = new WeakMap();
413
427
  _rebuildQueued = new WeakMap();
414
428
  _fallbackInput = new WeakMap();
@@ -459,6 +473,7 @@ create_fn = function() {
459
473
  }
460
474
  const { ariaLabel, ariaLabelledBy } = __privateMethod(this, _MikeDownElement_instances, accessibleName_fn).call(this);
461
475
  const userHost = __privateGet(this, _host);
476
+ const ai = __privateGet(this, _ai) ?? userHost.ai;
462
477
  const binding = bindMikeDownValue(this, {
463
478
  initialValue: __privateGet(this, _value),
464
479
  debounceMs: this.debounce,
@@ -474,6 +489,7 @@ create_fn = function() {
474
489
  ariaLabelledBy,
475
490
  host: {
476
491
  ...userHost,
492
+ ...ai ? { ai } : {},
477
493
  // Every keystroke keeps `value`, the form value and validity current;
478
494
  // the debounced `change` event comes from onValue below.
479
495
  onChange: (markdown, meta) => {
@@ -665,4 +681,4 @@ export {
665
681
  DEFAULT_TAG,
666
682
  defineMikeDownElement
667
683
  };
668
- //# sourceMappingURL=chunk-E72SZEON.js.map
684
+ //# sourceMappingURL=chunk-WZVZGW65.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/element.ts","../src/hooks.ts","../src/index.ts"],"sourcesContent":["/**\n * <mikedown-editor>: the MikeDown editor as a form-associated custom element.\n *\n * Light DOM on purpose: core's menus and dialogs mount in a `.mikedown-portal`\n * on <body>, its stylesheet is scoped to `.mikedown-root` / `.mikedown-portal`\n * in the document, and ProseMirror's selection handling is unreliable inside a\n * shadow root. Value glue (debounce, blur flush, pristine loads, theme `auto`)\n * comes from core's `bindMikeDownValue`.\n */\n\nimport { bindMikeDownValue } from '@mikedown/core';\nimport type {\n BindingTheme,\n MikeDownAiHost,\n MikeDownBinding,\n MikeDownEditorHandle,\n MikeDownFeatures,\n MikeDownHost,\n MikeDownSettings,\n} from '@mikedown/core';\nimport { ensureDisplayStyle, runConnectHook } from './hooks';\n\n/** Detail of the `change` event. */\nexport interface MikeDownChangeEventDetail {\n value: string;\n}\n\n/** Detail of the `ready` event. */\nexport interface MikeDownReadyEventDetail {\n handle: MikeDownEditorHandle;\n}\n\nexport type MikeDownElementTheme = BindingTheme;\n\n/** Host methods the element accepts. `onChange` runs before the element's own handling. */\nexport type MikeDownElementHost = Partial<MikeDownHost>;\n\nconst OBSERVED = [\n 'value',\n 'theme',\n 'readonly',\n 'disabled',\n 'placeholder',\n 'name',\n 'required',\n 'min-height',\n 'dark-selector',\n 'spellcheck-dictionary-url',\n 'features',\n 'debounce',\n 'aria-label',\n 'aria-labelledby',\n] as const;\n\n/** Attributes read only when the editor is created: a change rebuilds it (the value is kept). */\nconst REBUILD_ON = new Set(['placeholder', 'spellcheck-dictionary-url', 'features', 'dark-selector', 'debounce', 'aria-label', 'aria-labelledby']);\n\n/** Properties a framework may set before the element is upgraded. */\nconst UPGRADE_PROPS = [\n 'value',\n 'defaultValue',\n 'theme',\n 'readOnly',\n 'disabled',\n 'placeholder',\n 'name',\n 'required',\n 'minHeight',\n 'darkSelector',\n 'spellcheckDictionaryUrl',\n 'features',\n 'settings',\n 'host',\n] as const;\n\nconst VALUE_MISSING_MESSAGE = 'Please fill out this field.';\n\n/** SSR-safe base: importing the module on a server must not throw. */\nconst Base = (typeof HTMLElement === 'undefined' ? class {} : HTMLElement) as typeof HTMLElement;\n\n/** Drop one leading newline and the common indentation of a server-rendered <script> body. */\nexport function dedentScriptText(text: string): string {\n const lines = text.replace(/^\\r?\\n/, '').replace(/\\s+$/, '').split(/\\r?\\n/);\n const indents = lines.filter((l) => l.trim()).map((l) => /^[ \\t]*/.exec(l)![0].length);\n const cut = indents.length ? Math.min(...indents) : 0;\n return lines.map((l) => l.slice(cut)).join('\\n') + (lines.length && lines.some((l) => l.trim()) ? '\\n' : '');\n}\n\nfunction parseTheme(value: string | null): BindingTheme {\n return value === 'light' || value === 'dark' ? value : 'auto';\n}\n\nexport class MikeDownElement extends Base {\n static formAssociated = true;\n\n static get observedAttributes(): string[] {\n return [...OBSERVED];\n }\n\n readonly #internals: ElementInternals | null;\n #binding: MikeDownBinding | null = null;\n /** Current value: the last text the editor reported, or the last one set. */\n #value = '';\n /** Reset target: the `value` attribute, else the child source's text at first connect. */\n #defaultValue = '';\n #valueSetByProperty = false;\n #initialized = false;\n #featuresAttrCache: { raw: string | null; parsed: Partial<MikeDownFeatures> | null } = { raw: null, parsed: null };\n #settings: Partial<MikeDownSettings> = {};\n #host: MikeDownElementHost = {};\n #ai: MikeDownAiHost | undefined;\n #formDisabled = false;\n #rebuildQueued = false;\n #fallbackInput: HTMLInputElement | null = null;\n #fallbackForm: HTMLFormElement | null = null;\n\n constructor() {\n super();\n let internals: ElementInternals | null = null;\n try {\n internals = typeof this.attachInternals === 'function' ? this.attachInternals() : null;\n } catch {\n internals = null;\n }\n this.#internals = internals;\n\n // A click whose target is the element itself comes from a <label for> (or\n // the element's own padding): move focus into the editor.\n this.addEventListener('click', (event) => {\n if (event.target !== this) {return;}\n const active = this.ownerDocument.activeElement;\n if (active && this.contains(active)) {return;}\n this.focus();\n });\n\n // Native `change` events from inputs inside the editor (find bar, dialogs)\n // would bubble out looking like the element's own. Registered first, so it\n // runs before any listener a page adds to the element.\n this.addEventListener('change', (event) => {\n if (event.target !== this) {event.stopImmediatePropagation();}\n });\n }\n\n // ── Lifecycle ─────────────────────────────────────────────────────────────\n\n connectedCallback(): void {\n if (!this.#initialized) {\n this.#initialized = true;\n for (const prop of UPGRADE_PROPS) {this.#upgradeProperty(prop);}\n this.#readInitialValue();\n }\n ensureDisplayStyle(this.ownerDocument, this.localName);\n this.#applyMinHeight();\n this.#attachFallbackForm();\n runConnectHook(this as unknown as HTMLElement & { features: Record<string, unknown> });\n this.#create();\n }\n\n disconnectedCallback(): void {\n this.#destroy();\n this.#detachFallbackForm();\n }\n\n attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void {\n if (oldValue === newValue) {return;}\n switch (name) {\n case 'value':\n this.#defaultValue = newValue ?? '';\n if (this.#initialized) {this.#setValue(newValue ?? '');}\n break;\n case 'theme':\n this.#binding?.setTheme(parseTheme(newValue));\n break;\n case 'readonly':\n this.#binding?.setReadOnly(newValue !== null);\n break;\n case 'disabled':\n this.#applyDisabled();\n break;\n case 'required':\n this.#syncValidity();\n break;\n case 'name':\n if (this.#fallbackInput) {this.#fallbackInput.name = newValue ?? '';}\n break;\n case 'min-height':\n this.#applyMinHeight();\n break;\n default:\n if (REBUILD_ON.has(name)) {this.#scheduleRebuild();}\n }\n }\n\n // ── Form-associated callbacks ─────────────────────────────────────────────\n\n formResetCallback(): void {\n this.#setValue(this.#defaultValue);\n this.#valueSetByProperty = false;\n }\n\n formDisabledCallback(disabled: boolean): void {\n this.#formDisabled = disabled;\n this.#applyDisabled();\n }\n\n formStateRestoreCallback(state: unknown): void {\n if (typeof state === 'string') {this.#setValue(state);}\n }\n\n // ── Value ─────────────────────────────────────────────────────────────────\n\n /** The markdown. Setting it loads the text as the pristine baseline and fires no `change`. */\n get value(): string {\n return this.#value;\n }\n set value(markdown: string) {\n this.#valueSetByProperty = true;\n this.#setValue(markdown == null ? '' : String(markdown));\n }\n\n /** The `value` attribute: the initial value and the target of a form reset. */\n get defaultValue(): string {\n return this.getAttribute('value') ?? this.#defaultValue;\n }\n set defaultValue(markdown: string) {\n this.setAttribute('value', markdown == null ? '' : String(markdown));\n }\n\n // ── Reflected attributes ──────────────────────────────────────────────────\n\n get theme(): BindingTheme {\n return parseTheme(this.getAttribute('theme'));\n }\n set theme(theme: BindingTheme) {\n this.setAttribute('theme', parseTheme(theme));\n }\n\n get readOnly(): boolean {\n return this.hasAttribute('readonly');\n }\n set readOnly(on: boolean) {\n this.toggleAttribute('readonly', !!on);\n }\n\n get disabled(): boolean {\n return this.hasAttribute('disabled');\n }\n set disabled(on: boolean) {\n this.toggleAttribute('disabled', !!on);\n }\n\n get required(): boolean {\n return this.hasAttribute('required');\n }\n set required(on: boolean) {\n this.toggleAttribute('required', !!on);\n }\n\n get placeholder(): string {\n return this.getAttribute('placeholder') ?? '';\n }\n set placeholder(text: string) {\n this.#setOrRemove('placeholder', text);\n }\n\n get name(): string {\n return this.getAttribute('name') ?? '';\n }\n set name(name: string) {\n this.#setOrRemove('name', name);\n }\n\n /** CSS length for the editor's minimum height (`--mikedown-min-height`). Default 240px. */\n get minHeight(): string {\n return this.getAttribute('min-height') ?? '';\n }\n set minHeight(value: string) {\n this.#setOrRemove('min-height', value);\n }\n\n /** With `theme=\"auto\"`: dark when `element.closest(selector)` matches, else light. */\n get darkSelector(): string {\n return this.getAttribute('dark-selector') ?? '';\n }\n set darkSelector(selector: string) {\n this.#setOrRemove('dark-selector', selector);\n }\n\n /** Folder base of the spell-check dictionaries (core appends `/en/` or `/en-GB/`). */\n get spellcheckDictionaryUrl(): string {\n return this.getAttribute('spellcheck-dictionary-url') ?? '';\n }\n set spellcheckDictionaryUrl(url: string) {\n this.#setOrRemove('spellcheck-dictionary-url', url);\n }\n\n /** Milliseconds of quiet before `change` fires. Default 150. */\n get debounce(): number {\n const n = Number(this.getAttribute('debounce'));\n return this.hasAttribute('debounce') && Number.isFinite(n) && n >= 0 ? n : 150;\n }\n set debounce(ms: number) {\n this.setAttribute('debounce', String(ms));\n }\n\n /** Feature switches. The `features` attribute takes the same object as JSON. Changing them rebuilds the editor. */\n get features(): Partial<MikeDownFeatures> {\n const raw = this.getAttribute('features');\n if (raw !== this.#featuresAttrCache.raw) {\n let parsed: Partial<MikeDownFeatures> | null = null;\n if (raw) {\n try {\n const json: unknown = JSON.parse(raw);\n if (json && typeof json === 'object' && !Array.isArray(json)) {parsed = json as Partial<MikeDownFeatures>;}\n else {console.warn('<mikedown-editor>: the features attribute must be a JSON object.');}\n } catch {\n console.warn('<mikedown-editor>: the features attribute is not valid JSON.');\n }\n }\n this.#featuresAttrCache = { raw, parsed };\n }\n return { ...(this.#featuresAttrCache.parsed ?? {}) };\n }\n set features(features: Partial<MikeDownFeatures> | null) {\n // Reflected as JSON (every flag is a boolean); the attribute change schedules the rebuild.\n if (features) {this.setAttribute('features', JSON.stringify(features));}\n else {this.removeAttribute('features');}\n }\n\n // ── Properties only ───────────────────────────────────────────────────────\n\n /** Core settings (fonts, content width, ...). Applied live through `handle.updateSettings`. */\n get settings(): Partial<MikeDownSettings> {\n return { ...this.#settings };\n }\n set settings(settings: Partial<MikeDownSettings> | null) {\n this.#settings = { ...(settings ?? {}) };\n this.#binding?.handle.updateSettings(this.#settings);\n }\n\n /**\n * Host methods (`uploadImage`, `openLink`, `resolveImageSrc`, ...). Core turns a\n * feature on only when its method is present, so a change rebuilds the editor.\n */\n get host(): MikeDownElementHost {\n return this.#host;\n }\n set host(host: MikeDownElementHost | null) {\n this.#host = host ?? {};\n this.#scheduleRebuild();\n }\n\n /**\n * The AI host group (`complete`, and for tier 2 `listEngines`, `testEngine`, ...). A property only: it holds\n * functions, so there is no attribute. Wins over `host.ai`. Core turns the AI features on when it is present,\n * so a change rebuilds the editor. Core ships no provider SDK; the page supplies the transport.\n */\n get ai(): MikeDownAiHost | undefined {\n return this.#ai ?? this.#host.ai;\n }\n set ai(ai: MikeDownAiHost | null | undefined) {\n this.#ai = ai ?? undefined;\n this.#scheduleRebuild();\n }\n\n /** The editor handle while connected, else null. */\n get handle(): MikeDownEditorHandle | null {\n return this.#binding?.handle ?? null;\n }\n\n // ── Form and validity ─────────────────────────────────────────────────────\n\n get form(): HTMLFormElement | null {\n return this.#internals && 'form' in this.#internals ? this.#internals.form : this.closest('form');\n }\n\n get labels(): NodeList | HTMLLabelElement[] {\n return this.#internals?.labels ?? [];\n }\n\n get type(): string {\n return this.localName;\n }\n\n get validity(): ValidityState {\n if (this.#hasFormInternals()) {return this.#internals!.validity;}\n const valueMissing = this.#valueMissing();\n return { valueMissing, valid: !valueMissing } as ValidityState;\n }\n\n get validationMessage(): string {\n if (this.#hasFormInternals()) {return this.#internals!.validationMessage;}\n return this.#valueMissing() ? VALUE_MISSING_MESSAGE : '';\n }\n\n get willValidate(): boolean {\n if (this.#hasFormInternals()) {return this.#internals!.willValidate;}\n return !this.#isDisabled() && !this.readOnly;\n }\n\n checkValidity(): boolean {\n if (this.#hasFormInternals()) {return this.#internals!.checkValidity();}\n if (!this.willValidate || !this.#valueMissing()) {return true;}\n this.dispatchEvent(new Event('invalid', { cancelable: true }));\n return false;\n }\n\n reportValidity(): boolean {\n if (this.#hasFormInternals()) {return this.#internals!.reportValidity();}\n const ok = this.checkValidity();\n if (!ok) {this.focus();}\n return ok;\n }\n\n /** Focus the editable surface. */\n override focus(options?: FocusOptions): void {\n if (this.#binding) {this.#binding.focus();}\n else {super.focus(options);}\n }\n\n // ── Internals ─────────────────────────────────────────────────────────────\n\n #upgradeProperty(prop: (typeof UPGRADE_PROPS)[number]): void {\n if (Object.prototype.hasOwnProperty.call(this, prop)) {\n const value = (this as Record<string, unknown>)[prop];\n delete (this as Record<string, unknown>)[prop];\n (this as Record<string, unknown>)[prop] = value;\n }\n }\n\n /** `value` attribute, else a child <textarea> or <script type=\"text/markdown\">, which is then hidden. */\n #readInitialValue(): void {\n const source = this.querySelector<HTMLTextAreaElement | HTMLScriptElement>(\n ':scope > textarea, :scope > script[type=\"text/markdown\"]',\n );\n let sourceText: string | null = null;\n if (source && source.localName === 'textarea') {\n const textarea = source as HTMLTextAreaElement;\n sourceText = textarea.value;\n // Server-rendered pages put name/required/placeholder on the textarea.\n if (!this.hasAttribute('name') && textarea.name) {this.setAttribute('name', textarea.name);}\n if (!this.hasAttribute('required') && textarea.required) {this.setAttribute('required', '');}\n if (!this.hasAttribute('placeholder') && textarea.placeholder) {this.setAttribute('placeholder', textarea.placeholder);}\n // Hidden and disabled, so it neither shows nor submits a second value.\n textarea.hidden = true;\n textarea.style.display = 'none';\n textarea.disabled = true;\n textarea.setAttribute('aria-hidden', 'true');\n } else if (source) {\n sourceText = dedentScriptText(source.textContent ?? '');\n }\n\n const attr = this.getAttribute('value');\n this.#defaultValue = attr ?? sourceText ?? '';\n if (!this.#valueSetByProperty) {this.#value = this.#defaultValue;}\n }\n\n #create(): void {\n if (this.#binding || !this.isConnected) {return;}\n const { ariaLabel, ariaLabelledBy } = this.#accessibleName();\n const userHost = this.#host;\n const ai = this.#ai ?? userHost.ai;\n const binding = bindMikeDownValue(this, {\n initialValue: this.#value,\n debounceMs: this.debounce,\n theme: this.theme,\n darkSelector: this.darkSelector || undefined,\n readOnly: this.readOnly,\n disabled: this.#isDisabled(),\n placeholder: this.getAttribute('placeholder') ?? undefined,\n spellcheckDictionaryUrl: this.spellcheckDictionaryUrl || undefined,\n features: this.features,\n settings: this.#settings,\n ariaLabel,\n ariaLabelledBy,\n host: {\n ...userHost,\n ...(ai ? { ai } : {}),\n // Every keystroke keeps `value`, the form value and validity current;\n // the debounced `change` event comes from onValue below.\n onChange: (markdown: string, meta: { pristine: boolean }) => {\n userHost.onChange?.(markdown, meta);\n this.#value = markdown;\n this.#syncForm();\n },\n },\n onValue: (markdown: string) => {\n this.#value = markdown;\n this.#syncForm();\n this.dispatchEvent(\n new CustomEvent<MikeDownChangeEventDetail>('change', { detail: { value: markdown }, bubbles: true, composed: true }),\n );\n },\n });\n this.#binding = binding;\n this.#syncForm();\n // A microtask later, so a listener added right after appendChild (or\n // after the define script ran on parsed markup) still hears it.\n queueMicrotask(() => {\n if (this.#binding !== binding) {return;}\n this.dispatchEvent(\n new CustomEvent<MikeDownReadyEventDetail>('ready', { detail: { handle: binding.handle }, bubbles: true, composed: true }),\n );\n });\n }\n\n #destroy(): void {\n const binding = this.#binding;\n if (!binding) {return;}\n // destroy() flushes a pending change first (onValue keeps #value current).\n binding.destroy();\n this.#binding = null;\n }\n\n #scheduleRebuild(): void {\n if (!this.#binding || this.#rebuildQueued) {return;}\n this.#rebuildQueued = true;\n queueMicrotask(() => {\n this.#rebuildQueued = false;\n if (!this.#binding || !this.isConnected) {return;}\n const hadFocus = this.contains(this.ownerDocument.activeElement);\n this.#destroy();\n this.#create();\n if (hadFocus) {this.#binding?.focus();}\n });\n }\n\n #setValue(markdown: string): void {\n this.#value = markdown;\n this.#binding?.setValue(markdown);\n this.#syncForm();\n }\n\n #accessibleName(): { ariaLabel?: string; ariaLabelledBy?: string } {\n // ARIA precedence: aria-labelledby, then aria-label, then <label> elements.\n const labelledBy = this.getAttribute('aria-labelledby');\n if (labelledBy) {return { ariaLabelledBy: labelledBy };}\n const label = this.getAttribute('aria-label');\n if (label) {return { ariaLabel: label };}\n const labels = Array.from((this.#internals?.labels ?? []) as ArrayLike<HTMLElement>);\n if (!labels.length) {return {};}\n const ids = labels.map((el, i) => {\n if (!el.id) {el.id = `${this.id || 'mikedown-editor'}-label${labels.length > 1 ? `-${i + 1}` : ''}`;}\n return el.id;\n });\n return { ariaLabelledBy: ids.join(' ') };\n }\n\n #isDisabled(): boolean {\n return this.hasAttribute('disabled') || this.#formDisabled;\n }\n\n #applyDisabled(): void {\n this.#binding?.setDisabled(this.#isDisabled());\n if (this.#fallbackInput) {this.#fallbackInput.disabled = this.#isDisabled();}\n this.#syncValidity();\n }\n\n #applyMinHeight(): void {\n const value = this.getAttribute('min-height');\n if (value) {this.style.setProperty('--mikedown-min-height', /^\\d+(\\.\\d+)?$/.test(value) ? `${value}px` : value);}\n else {this.style.removeProperty('--mikedown-min-height');}\n }\n\n #setOrRemove(attr: string, value: string | null | undefined): void {\n if (value == null || value === '') {this.removeAttribute(attr);}\n else {this.setAttribute(attr, String(value));}\n }\n\n #hasFormInternals(): boolean {\n return !!this.#internals && typeof this.#internals.setFormValue === 'function';\n }\n\n #valueMissing(): boolean {\n return this.required && !this.#isDisabled() && this.#value.trim() === '';\n }\n\n #syncForm(): void {\n if (this.#hasFormInternals()) {\n this.#internals!.setFormValue(this.#value, this.#value);\n } else if (this.#fallbackInput) {\n this.#fallbackInput.value = this.#value;\n }\n this.#syncValidity();\n }\n\n #syncValidity(): void {\n if (!this.#hasFormInternals() || typeof this.#internals!.setValidity !== 'function') {return;}\n if (this.#valueMissing()) {\n const anchor = this.querySelector<HTMLElement>('.ProseMirror') ?? undefined;\n this.#internals!.setValidity({ valueMissing: true }, VALUE_MISSING_MESSAGE, anchor);\n } else {\n this.#internals!.setValidity({});\n }\n }\n\n /**\n * Without ElementInternals form support (jsdom, very old browsers) a hidden\n * <input> carries the value, and the form's reset event resets it.\n */\n #attachFallbackForm(): void {\n if (this.#hasFormInternals()) {return;}\n if (!this.#fallbackInput) {\n const input = this.ownerDocument.createElement('input');\n input.type = 'hidden';\n input.setAttribute('data-mikedown-form-value', '');\n this.#fallbackInput = input;\n }\n this.#fallbackInput.name = this.name;\n this.#fallbackInput.disabled = this.#isDisabled();\n this.#fallbackInput.value = this.#value;\n if (this.#fallbackInput.parentNode !== this) {this.appendChild(this.#fallbackInput);}\n const form = this.closest('form');\n if (form !== this.#fallbackForm) {\n this.#fallbackForm?.removeEventListener('reset', this.#onFallbackReset);\n form?.addEventListener('reset', this.#onFallbackReset);\n this.#fallbackForm = form;\n }\n }\n\n #detachFallbackForm(): void {\n this.#fallbackForm?.removeEventListener('reset', this.#onFallbackReset);\n this.#fallbackForm = null;\n }\n\n #onFallbackReset = (): void => {\n this.formResetCallback();\n };\n}\n","/**\n * Internal hooks shared by the element and the CDN entry. Not part of the\n * public API: the standalone bundle registers a connect hook that injects the\n * core stylesheet and KaTeX CSS; npm users import `@mikedown/core/styles.css`\n * themselves, so nothing is registered there.\n */\n\nexport type ConnectHook = (element: HTMLElement & { features: Record<string, unknown> }) => void;\n\nlet connectHook: ConnectHook | null = null;\n\nexport function setConnectHook(hook: ConnectHook | null): void {\n connectHook = hook;\n}\n\nexport function runConnectHook(element: HTMLElement & { features: Record<string, unknown> }): void {\n connectHook?.(element);\n}\n\nconst styledTags = new WeakMap<Document, Set<string>>();\n\n/**\n * `display: block` for the tag, at zero specificity so any page rule wins.\n * Uses a constructed stylesheet where supported (no inline <style>, so a\n * strict `style-src` CSP is fine), else one guarded <style> per tag.\n */\nexport function ensureDisplayStyle(doc: Document, tag: string): void {\n let tags = styledTags.get(doc);\n if (!tags) {\n tags = new Set();\n styledTags.set(doc, tags);\n }\n if (tags.has(tag)) {return;}\n tags.add(tag);\n const css = `:where(${tag}) { display: block; }`;\n const view = doc.defaultView as (Window & typeof globalThis) | null;\n try {\n if (view && 'adoptedStyleSheets' in doc && typeof view.CSSStyleSheet?.prototype.replaceSync === 'function') {\n const sheet = new view.CSSStyleSheet();\n sheet.replaceSync(css);\n doc.adoptedStyleSheets = [...doc.adoptedStyleSheets, sheet];\n return;\n }\n } catch {\n // Fall through to a <style> element.\n }\n const style = doc.createElement('style');\n style.setAttribute('data-mikedown-element', tag);\n style.textContent = css;\n doc.head.appendChild(style);\n}\n","/**\n * @mikedown/web-component: <mikedown-editor>, a form-associated custom element\n * around @mikedown/core.\n *\n * import { defineMikeDownElement } from '@mikedown/web-component';\n * import '@mikedown/core/styles.css';\n * defineMikeDownElement(); // registers <mikedown-editor>\n *\n * or, for the side effect alone: `import '@mikedown/web-component/define'`.\n */\n\nimport { MikeDownElement } from './element';\n\nexport { MikeDownElement, dedentScriptText } from './element';\nexport type {\n MikeDownChangeEventDetail,\n MikeDownReadyEventDetail,\n MikeDownElementTheme,\n MikeDownElementHost,\n} from './element';\n\nexport const DEFAULT_TAG = 'mikedown-editor';\n\n/**\n * Register the element under `tag` (default `mikedown-editor`) and return its\n * constructor. Safe to call more than once: a tag that is already defined is\n * left alone and its existing constructor returned. A second tag gets its own\n * subclass, since one class can only be registered once.\n */\nexport function defineMikeDownElement(tag: string = DEFAULT_TAG): CustomElementConstructor {\n if (typeof customElements === 'undefined') {return MikeDownElement;}\n const existing = customElements.get(tag);\n if (existing) {return existing;}\n const registry = customElements as CustomElementRegistry & { getName?(ctor: CustomElementConstructor): string | null };\n const baseTaken = baseDefined || !!registry.getName?.(MikeDownElement);\n const ctor = baseTaken ? class extends MikeDownElement {} : MikeDownElement;\n customElements.define(tag, ctor);\n if (ctor === MikeDownElement) {baseDefined = true;}\n return ctor;\n}\n\nlet baseDefined = false;\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'mikedown-editor': MikeDownElement;\n }\n}\n"],"mappings":";;;;;;;;;;AAUA,SAAS,yBAAyB;;;ACDlC,IAAI,cAAkC;AAM/B,SAAS,eAAe,SAAoE;AACjG,gBAAc,OAAO;AACvB;AAEA,IAAM,aAAa,oBAAI,QAA+B;AAO/C,SAAS,mBAAmB,KAAe,KAAmB;AACnE,MAAI,OAAO,WAAW,IAAI,GAAG;AAC7B,MAAI,CAAC,MAAM;AACT,WAAO,oBAAI,IAAI;AACf,eAAW,IAAI,KAAK,IAAI;AAAA,EAC1B;AACA,MAAI,KAAK,IAAI,GAAG,GAAG;AAAC;AAAA,EAAO;AAC3B,OAAK,IAAI,GAAG;AACZ,QAAM,MAAM,UAAU,GAAG;AACzB,QAAM,OAAO,IAAI;AACjB,MAAI;AACF,QAAI,QAAQ,wBAAwB,OAAO,OAAO,KAAK,eAAe,UAAU,gBAAgB,YAAY;AAC1G,YAAM,QAAQ,IAAI,KAAK,cAAc;AACrC,YAAM,YAAY,GAAG;AACrB,UAAI,qBAAqB,CAAC,GAAG,IAAI,oBAAoB,KAAK;AAC1D;AAAA,IACF;AAAA,EACF,QAAQ;AAAA,EAER;AACA,QAAM,QAAQ,IAAI,cAAc,OAAO;AACvC,QAAM,aAAa,yBAAyB,GAAG;AAC/C,QAAM,cAAc;AACpB,MAAI,KAAK,YAAY,KAAK;AAC5B;;;ADbA,IAAM,WAAW;AAAA,EACf;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGA,IAAM,aAAa,oBAAI,IAAI,CAAC,eAAe,6BAA6B,YAAY,iBAAiB,YAAY,cAAc,iBAAiB,CAAC;AAGjJ,IAAM,gBAAgB;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,wBAAwB;AAG9B,IAAM,OAAQ,OAAO,gBAAgB,cAAc,MAAM;AAAC,IAAI;AAGvD,SAAS,iBAAiB,MAAsB;AACrD,QAAM,QAAQ,KAAK,QAAQ,UAAU,EAAE,EAAE,QAAQ,QAAQ,EAAE,EAAE,MAAM,OAAO;AAC1E,QAAM,UAAU,MAAM,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,IAAI,CAAC,MAAM,UAAU,KAAK,CAAC,EAAG,CAAC,EAAE,MAAM;AACrF,QAAM,MAAM,QAAQ,SAAS,KAAK,IAAI,GAAG,OAAO,IAAI;AACpD,SAAO,MAAM,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,KAAK,MAAM,UAAU,MAAM,KAAK,CAAC,MAAM,EAAE,KAAK,CAAC,IAAI,OAAO;AAC3G;AAEA,SAAS,WAAW,OAAoC;AACtD,SAAO,UAAU,WAAW,UAAU,SAAS,QAAQ;AACzD;AA1FA;AA4FO,IAAM,kBAAN,cAA8B,KAAK;AAAA,EAwBxC,cAAc;AACZ,UAAM;AAzBH;AAOL,uBAAS;AACT,iCAAmC;AAEnC;AAAA,+BAAS;AAET;AAAA,sCAAgB;AAChB,4CAAsB;AACtB,qCAAe;AACf,2CAAuF,EAAE,KAAK,MAAM,QAAQ,KAAK;AACjH,kCAAuC,CAAC;AACxC,8BAA6B,CAAC;AAC9B;AACA,sCAAgB;AAChB,uCAAiB;AACjB,uCAA0C;AAC1C,sCAAwC;AA+fxC,yCAAmB,MAAY;AAC7B,WAAK,kBAAkB;AAAA,IACzB;AA7fE,QAAI,YAAqC;AACzC,QAAI;AACF,kBAAY,OAAO,KAAK,oBAAoB,aAAa,KAAK,gBAAgB,IAAI;AAAA,IACpF,QAAQ;AACN,kBAAY;AAAA,IACd;AACA,uBAAK,YAAa;AAIlB,SAAK,iBAAiB,SAAS,CAAC,UAAU;AACxC,UAAI,MAAM,WAAW,MAAM;AAAC;AAAA,MAAO;AACnC,YAAM,SAAS,KAAK,cAAc;AAClC,UAAI,UAAU,KAAK,SAAS,MAAM,GAAG;AAAC;AAAA,MAAO;AAC7C,WAAK,MAAM;AAAA,IACb,CAAC;AAKD,SAAK,iBAAiB,UAAU,CAAC,UAAU;AACzC,UAAI,MAAM,WAAW,MAAM;AAAC,cAAM,yBAAyB;AAAA,MAAE;AAAA,IAC/D,CAAC;AAAA,EACH;AAAA,EA9CA,WAAW,qBAA+B;AACxC,WAAO,CAAC,GAAG,QAAQ;AAAA,EACrB;AAAA;AAAA,EAgDA,oBAA0B;AACxB,QAAI,CAAC,mBAAK,eAAc;AACtB,yBAAK,cAAe;AACpB,iBAAW,QAAQ,eAAe;AAAC,8BAAK,gDAAL,WAAsB;AAAA,MAAM;AAC/D,4BAAK,iDAAL;AAAA,IACF;AACA,uBAAmB,KAAK,eAAe,KAAK,SAAS;AACrD,0BAAK,+CAAL;AACA,0BAAK,mDAAL;AACA,mBAAe,IAAsE;AACrF,0BAAK,uCAAL;AAAA,EACF;AAAA,EAEA,uBAA6B;AAC3B,0BAAK,wCAAL;AACA,0BAAK,mDAAL;AAAA,EACF;AAAA,EAEA,yBAAyB,MAAc,UAAyB,UAA+B;AAC7F,QAAI,aAAa,UAAU;AAAC;AAAA,IAAO;AACnC,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,2BAAK,eAAgB,YAAY;AACjC,YAAI,mBAAK,eAAc;AAAC,gCAAK,yCAAL,WAAe,YAAY;AAAA,QAAI;AACvD;AAAA,MACF,KAAK;AACH,2BAAK,WAAU,SAAS,WAAW,QAAQ,CAAC;AAC5C;AAAA,MACF,KAAK;AACH,2BAAK,WAAU,YAAY,aAAa,IAAI;AAC5C;AAAA,MACF,KAAK;AACH,8BAAK,8CAAL;AACA;AAAA,MACF,KAAK;AACH,8BAAK,6CAAL;AACA;AAAA,MACF,KAAK;AACH,YAAI,mBAAK,iBAAgB;AAAC,6BAAK,gBAAe,OAAO,YAAY;AAAA,QAAG;AACpE;AAAA,MACF,KAAK;AACH,8BAAK,+CAAL;AACA;AAAA,MACF;AACE,YAAI,WAAW,IAAI,IAAI,GAAG;AAAC,gCAAK,gDAAL;AAAA,QAAwB;AAAA,IACvD;AAAA,EACF;AAAA;AAAA,EAIA,oBAA0B;AACxB,0BAAK,yCAAL,WAAe,mBAAK;AACpB,uBAAK,qBAAsB;AAAA,EAC7B;AAAA,EAEA,qBAAqB,UAAyB;AAC5C,uBAAK,eAAgB;AACrB,0BAAK,8CAAL;AAAA,EACF;AAAA,EAEA,yBAAyB,OAAsB;AAC7C,QAAI,OAAO,UAAU,UAAU;AAAC,4BAAK,yCAAL,WAAe;AAAA,IAAO;AAAA,EACxD;AAAA;AAAA;AAAA,EAKA,IAAI,QAAgB;AAClB,WAAO,mBAAK;AAAA,EACd;AAAA,EACA,IAAI,MAAM,UAAkB;AAC1B,uBAAK,qBAAsB;AAC3B,0BAAK,yCAAL,WAAe,YAAY,OAAO,KAAK,OAAO,QAAQ;AAAA,EACxD;AAAA;AAAA,EAGA,IAAI,eAAuB;AACzB,WAAO,KAAK,aAAa,OAAO,KAAK,mBAAK;AAAA,EAC5C;AAAA,EACA,IAAI,aAAa,UAAkB;AACjC,SAAK,aAAa,SAAS,YAAY,OAAO,KAAK,OAAO,QAAQ,CAAC;AAAA,EACrE;AAAA;AAAA,EAIA,IAAI,QAAsB;AACxB,WAAO,WAAW,KAAK,aAAa,OAAO,CAAC;AAAA,EAC9C;AAAA,EACA,IAAI,MAAM,OAAqB;AAC7B,SAAK,aAAa,SAAS,WAAW,KAAK,CAAC;AAAA,EAC9C;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO,KAAK,aAAa,UAAU;AAAA,EACrC;AAAA,EACA,IAAI,SAAS,IAAa;AACxB,SAAK,gBAAgB,YAAY,CAAC,CAAC,EAAE;AAAA,EACvC;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO,KAAK,aAAa,UAAU;AAAA,EACrC;AAAA,EACA,IAAI,SAAS,IAAa;AACxB,SAAK,gBAAgB,YAAY,CAAC,CAAC,EAAE;AAAA,EACvC;AAAA,EAEA,IAAI,WAAoB;AACtB,WAAO,KAAK,aAAa,UAAU;AAAA,EACrC;AAAA,EACA,IAAI,SAAS,IAAa;AACxB,SAAK,gBAAgB,YAAY,CAAC,CAAC,EAAE;AAAA,EACvC;AAAA,EAEA,IAAI,cAAsB;AACxB,WAAO,KAAK,aAAa,aAAa,KAAK;AAAA,EAC7C;AAAA,EACA,IAAI,YAAY,MAAc;AAC5B,0BAAK,4CAAL,WAAkB,eAAe;AAAA,EACnC;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK,aAAa,MAAM,KAAK;AAAA,EACtC;AAAA,EACA,IAAI,KAAK,MAAc;AACrB,0BAAK,4CAAL,WAAkB,QAAQ;AAAA,EAC5B;AAAA;AAAA,EAGA,IAAI,YAAoB;AACtB,WAAO,KAAK,aAAa,YAAY,KAAK;AAAA,EAC5C;AAAA,EACA,IAAI,UAAU,OAAe;AAC3B,0BAAK,4CAAL,WAAkB,cAAc;AAAA,EAClC;AAAA;AAAA,EAGA,IAAI,eAAuB;AACzB,WAAO,KAAK,aAAa,eAAe,KAAK;AAAA,EAC/C;AAAA,EACA,IAAI,aAAa,UAAkB;AACjC,0BAAK,4CAAL,WAAkB,iBAAiB;AAAA,EACrC;AAAA;AAAA,EAGA,IAAI,0BAAkC;AACpC,WAAO,KAAK,aAAa,2BAA2B,KAAK;AAAA,EAC3D;AAAA,EACA,IAAI,wBAAwB,KAAa;AACvC,0BAAK,4CAAL,WAAkB,6BAA6B;AAAA,EACjD;AAAA;AAAA,EAGA,IAAI,WAAmB;AACrB,UAAM,IAAI,OAAO,KAAK,aAAa,UAAU,CAAC;AAC9C,WAAO,KAAK,aAAa,UAAU,KAAK,OAAO,SAAS,CAAC,KAAK,KAAK,IAAI,IAAI;AAAA,EAC7E;AAAA,EACA,IAAI,SAAS,IAAY;AACvB,SAAK,aAAa,YAAY,OAAO,EAAE,CAAC;AAAA,EAC1C;AAAA;AAAA,EAGA,IAAI,WAAsC;AACxC,UAAM,MAAM,KAAK,aAAa,UAAU;AACxC,QAAI,QAAQ,mBAAK,oBAAmB,KAAK;AACvC,UAAI,SAA2C;AAC/C,UAAI,KAAK;AACP,YAAI;AACF,gBAAM,OAAgB,KAAK,MAAM,GAAG;AACpC,cAAI,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,GAAG;AAAC,qBAAS;AAAA,UAAkC,OACrG;AAAC,oBAAQ,KAAK,kEAAkE;AAAA,UAAE;AAAA,QACzF,QAAQ;AACN,kBAAQ,KAAK,8DAA8D;AAAA,QAC7E;AAAA,MACF;AACA,yBAAK,oBAAqB,EAAE,KAAK,OAAO;AAAA,IAC1C;AACA,WAAO,EAAE,GAAI,mBAAK,oBAAmB,UAAU,CAAC,EAAG;AAAA,EACrD;AAAA,EACA,IAAI,SAAS,UAA4C;AAEvD,QAAI,UAAU;AAAC,WAAK,aAAa,YAAY,KAAK,UAAU,QAAQ,CAAC;AAAA,IAAE,OAClE;AAAC,WAAK,gBAAgB,UAAU;AAAA,IAAE;AAAA,EACzC;AAAA;AAAA;AAAA,EAKA,IAAI,WAAsC;AACxC,WAAO,EAAE,GAAG,mBAAK,WAAU;AAAA,EAC7B;AAAA,EACA,IAAI,SAAS,UAA4C;AACvD,uBAAK,WAAY,EAAE,GAAI,YAAY,CAAC,EAAG;AACvC,uBAAK,WAAU,OAAO,eAAe,mBAAK,UAAS;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,OAA4B;AAC9B,WAAO,mBAAK;AAAA,EACd;AAAA,EACA,IAAI,KAAK,MAAkC;AACzC,uBAAK,OAAQ,QAAQ,CAAC;AACtB,0BAAK,gDAAL;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,KAAiC;AACnC,WAAO,mBAAK,QAAO,mBAAK,OAAM;AAAA,EAChC;AAAA,EACA,IAAI,GAAG,IAAuC;AAC5C,uBAAK,KAAM,MAAM;AACjB,0BAAK,gDAAL;AAAA,EACF;AAAA;AAAA,EAGA,IAAI,SAAsC;AACxC,WAAO,mBAAK,WAAU,UAAU;AAAA,EAClC;AAAA;AAAA,EAIA,IAAI,OAA+B;AACjC,WAAO,mBAAK,eAAc,UAAU,mBAAK,cAAa,mBAAK,YAAW,OAAO,KAAK,QAAQ,MAAM;AAAA,EAClG;AAAA,EAEA,IAAI,SAAwC;AAC1C,WAAO,mBAAK,aAAY,UAAU,CAAC;AAAA,EACrC;AAAA,EAEA,IAAI,OAAe;AACjB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,IAAI,WAA0B;AAC5B,QAAI,sBAAK,iDAAL,YAA0B;AAAC,aAAO,mBAAK,YAAY;AAAA,IAAS;AAChE,UAAM,eAAe,sBAAK,6CAAL;AACrB,WAAO,EAAE,cAAc,OAAO,CAAC,aAAa;AAAA,EAC9C;AAAA,EAEA,IAAI,oBAA4B;AAC9B,QAAI,sBAAK,iDAAL,YAA0B;AAAC,aAAO,mBAAK,YAAY;AAAA,IAAkB;AACzE,WAAO,sBAAK,6CAAL,aAAuB,wBAAwB;AAAA,EACxD;AAAA,EAEA,IAAI,eAAwB;AAC1B,QAAI,sBAAK,iDAAL,YAA0B;AAAC,aAAO,mBAAK,YAAY;AAAA,IAAa;AACpE,WAAO,CAAC,sBAAK,2CAAL,cAAsB,CAAC,KAAK;AAAA,EACtC;AAAA,EAEA,gBAAyB;AACvB,QAAI,sBAAK,iDAAL,YAA0B;AAAC,aAAO,mBAAK,YAAY,cAAc;AAAA,IAAE;AACvE,QAAI,CAAC,KAAK,gBAAgB,CAAC,sBAAK,6CAAL,YAAsB;AAAC,aAAO;AAAA,IAAK;AAC9D,SAAK,cAAc,IAAI,MAAM,WAAW,EAAE,YAAY,KAAK,CAAC,CAAC;AAC7D,WAAO;AAAA,EACT;AAAA,EAEA,iBAA0B;AACxB,QAAI,sBAAK,iDAAL,YAA0B;AAAC,aAAO,mBAAK,YAAY,eAAe;AAAA,IAAE;AACxE,UAAM,KAAK,KAAK,cAAc;AAC9B,QAAI,CAAC,IAAI;AAAC,WAAK,MAAM;AAAA,IAAE;AACvB,WAAO;AAAA,EACT;AAAA;AAAA,EAGS,MAAM,SAA8B;AAC3C,QAAI,mBAAK,WAAU;AAAC,yBAAK,UAAS,MAAM;AAAA,IAAE,OACrC;AAAC,YAAM,MAAM,OAAO;AAAA,IAAE;AAAA,EAC7B;AAkNF;AAjhBW;AACT;AAEA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAtBK;AAAA;AA0UL,qBAAgB,SAAC,MAA4C;AAC3D,MAAI,OAAO,UAAU,eAAe,KAAK,MAAM,IAAI,GAAG;AACpD,UAAM,QAAS,KAAiC,IAAI;AACpD,WAAQ,KAAiC,IAAI;AAC7C,IAAC,KAAiC,IAAI,IAAI;AAAA,EAC5C;AACF;AAAA;AAGA,sBAAiB,WAAS;AACxB,QAAM,SAAS,KAAK;AAAA,IAClB;AAAA,EACF;AACA,MAAI,aAA4B;AAChC,MAAI,UAAU,OAAO,cAAc,YAAY;AAC7C,UAAM,WAAW;AACjB,iBAAa,SAAS;AAEtB,QAAI,CAAC,KAAK,aAAa,MAAM,KAAK,SAAS,MAAM;AAAC,WAAK,aAAa,QAAQ,SAAS,IAAI;AAAA,IAAE;AAC3F,QAAI,CAAC,KAAK,aAAa,UAAU,KAAK,SAAS,UAAU;AAAC,WAAK,aAAa,YAAY,EAAE;AAAA,IAAE;AAC5F,QAAI,CAAC,KAAK,aAAa,aAAa,KAAK,SAAS,aAAa;AAAC,WAAK,aAAa,eAAe,SAAS,WAAW;AAAA,IAAE;AAEvH,aAAS,SAAS;AAClB,aAAS,MAAM,UAAU;AACzB,aAAS,WAAW;AACpB,aAAS,aAAa,eAAe,MAAM;AAAA,EAC7C,WAAW,QAAQ;AACjB,iBAAa,iBAAiB,OAAO,eAAe,EAAE;AAAA,EACxD;AAEA,QAAM,OAAO,KAAK,aAAa,OAAO;AACtC,qBAAK,eAAgB,QAAQ,cAAc;AAC3C,MAAI,CAAC,mBAAK,sBAAqB;AAAC,uBAAK,QAAS,mBAAK;AAAA,EAAc;AACnE;AAEA,YAAO,WAAS;AACd,MAAI,mBAAK,aAAY,CAAC,KAAK,aAAa;AAAC;AAAA,EAAO;AAChD,QAAM,EAAE,WAAW,eAAe,IAAI,sBAAK,+CAAL;AACtC,QAAM,WAAW,mBAAK;AACtB,QAAM,KAAK,mBAAK,QAAO,SAAS;AAChC,QAAM,UAAU,kBAAkB,MAAM;AAAA,IACtC,cAAc,mBAAK;AAAA,IACnB,YAAY,KAAK;AAAA,IACjB,OAAO,KAAK;AAAA,IACZ,cAAc,KAAK,gBAAgB;AAAA,IACnC,UAAU,KAAK;AAAA,IACf,UAAU,sBAAK,2CAAL;AAAA,IACV,aAAa,KAAK,aAAa,aAAa,KAAK;AAAA,IACjD,yBAAyB,KAAK,2BAA2B;AAAA,IACzD,UAAU,KAAK;AAAA,IACf,UAAU,mBAAK;AAAA,IACf;AAAA,IACA;AAAA,IACA,MAAM;AAAA,MACJ,GAAG;AAAA,MACH,GAAI,KAAK,EAAE,GAAG,IAAI,CAAC;AAAA;AAAA;AAAA,MAGnB,UAAU,CAAC,UAAkB,SAAgC;AAC3D,iBAAS,WAAW,UAAU,IAAI;AAClC,2BAAK,QAAS;AACd,8BAAK,yCAAL;AAAA,MACF;AAAA,IACF;AAAA,IACA,SAAS,CAAC,aAAqB;AAC7B,yBAAK,QAAS;AACd,4BAAK,yCAAL;AACA,WAAK;AAAA,QACH,IAAI,YAAuC,UAAU,EAAE,QAAQ,EAAE,OAAO,SAAS,GAAG,SAAS,MAAM,UAAU,KAAK,CAAC;AAAA,MACrH;AAAA,IACF;AAAA,EACF,CAAC;AACD,qBAAK,UAAW;AAChB,wBAAK,yCAAL;AAGA,iBAAe,MAAM;AACnB,QAAI,mBAAK,cAAa,SAAS;AAAC;AAAA,IAAO;AACvC,SAAK;AAAA,MACH,IAAI,YAAsC,SAAS,EAAE,QAAQ,EAAE,QAAQ,QAAQ,OAAO,GAAG,SAAS,MAAM,UAAU,KAAK,CAAC;AAAA,IAC1H;AAAA,EACF,CAAC;AACH;AAEA,aAAQ,WAAS;AACf,QAAM,UAAU,mBAAK;AACrB,MAAI,CAAC,SAAS;AAAC;AAAA,EAAO;AAEtB,UAAQ,QAAQ;AAChB,qBAAK,UAAW;AAClB;AAEA,qBAAgB,WAAS;AACvB,MAAI,CAAC,mBAAK,aAAY,mBAAK,iBAAgB;AAAC;AAAA,EAAO;AACnD,qBAAK,gBAAiB;AACtB,iBAAe,MAAM;AACnB,uBAAK,gBAAiB;AACtB,QAAI,CAAC,mBAAK,aAAY,CAAC,KAAK,aAAa;AAAC;AAAA,IAAO;AACjD,UAAM,WAAW,KAAK,SAAS,KAAK,cAAc,aAAa;AAC/D,0BAAK,wCAAL;AACA,0BAAK,uCAAL;AACA,QAAI,UAAU;AAAC,yBAAK,WAAU,MAAM;AAAA,IAAE;AAAA,EACxC,CAAC;AACH;AAEA,cAAS,SAAC,UAAwB;AAChC,qBAAK,QAAS;AACd,qBAAK,WAAU,SAAS,QAAQ;AAChC,wBAAK,yCAAL;AACF;AAEA,oBAAe,WAAoD;AAEjE,QAAM,aAAa,KAAK,aAAa,iBAAiB;AACtD,MAAI,YAAY;AAAC,WAAO,EAAE,gBAAgB,WAAW;AAAA,EAAE;AACvD,QAAM,QAAQ,KAAK,aAAa,YAAY;AAC5C,MAAI,OAAO;AAAC,WAAO,EAAE,WAAW,MAAM;AAAA,EAAE;AACxC,QAAM,SAAS,MAAM,KAAM,mBAAK,aAAY,UAAU,CAAC,CAA4B;AACnF,MAAI,CAAC,OAAO,QAAQ;AAAC,WAAO,CAAC;AAAA,EAAE;AAC/B,QAAM,MAAM,OAAO,IAAI,CAAC,IAAI,MAAM;AAChC,QAAI,CAAC,GAAG,IAAI;AAAC,SAAG,KAAK,GAAG,KAAK,MAAM,iBAAiB,SAAS,OAAO,SAAS,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE;AAAA,IAAG;AACpG,WAAO,GAAG;AAAA,EACZ,CAAC;AACD,SAAO,EAAE,gBAAgB,IAAI,KAAK,GAAG,EAAE;AACzC;AAEA,gBAAW,WAAY;AACrB,SAAO,KAAK,aAAa,UAAU,KAAK,mBAAK;AAC/C;AAEA,mBAAc,WAAS;AACrB,qBAAK,WAAU,YAAY,sBAAK,2CAAL,UAAkB;AAC7C,MAAI,mBAAK,iBAAgB;AAAC,uBAAK,gBAAe,WAAW,sBAAK,2CAAL;AAAA,EAAmB;AAC5E,wBAAK,6CAAL;AACF;AAEA,oBAAe,WAAS;AACtB,QAAM,QAAQ,KAAK,aAAa,YAAY;AAC5C,MAAI,OAAO;AAAC,SAAK,MAAM,YAAY,yBAAyB,gBAAgB,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,KAAK;AAAA,EAAE,OAC3G;AAAC,SAAK,MAAM,eAAe,uBAAuB;AAAA,EAAE;AAC3D;AAEA,iBAAY,SAAC,MAAc,OAAwC;AACjE,MAAI,SAAS,QAAQ,UAAU,IAAI;AAAC,SAAK,gBAAgB,IAAI;AAAA,EAAE,OAC1D;AAAC,SAAK,aAAa,MAAM,OAAO,KAAK,CAAC;AAAA,EAAE;AAC/C;AAEA,sBAAiB,WAAY;AAC3B,SAAO,CAAC,CAAC,mBAAK,eAAc,OAAO,mBAAK,YAAW,iBAAiB;AACtE;AAEA,kBAAa,WAAY;AACvB,SAAO,KAAK,YAAY,CAAC,sBAAK,2CAAL,cAAsB,mBAAK,QAAO,KAAK,MAAM;AACxE;AAEA,cAAS,WAAS;AAChB,MAAI,sBAAK,iDAAL,YAA0B;AAC5B,uBAAK,YAAY,aAAa,mBAAK,SAAQ,mBAAK,OAAM;AAAA,EACxD,WAAW,mBAAK,iBAAgB;AAC9B,uBAAK,gBAAe,QAAQ,mBAAK;AAAA,EACnC;AACA,wBAAK,6CAAL;AACF;AAEA,kBAAa,WAAS;AACpB,MAAI,CAAC,sBAAK,iDAAL,cAA4B,OAAO,mBAAK,YAAY,gBAAgB,YAAY;AAAC;AAAA,EAAO;AAC7F,MAAI,sBAAK,6CAAL,YAAsB;AACxB,UAAM,SAAS,KAAK,cAA2B,cAAc,KAAK;AAClE,uBAAK,YAAY,YAAY,EAAE,cAAc,KAAK,GAAG,uBAAuB,MAAM;AAAA,EACpF,OAAO;AACL,uBAAK,YAAY,YAAY,CAAC,CAAC;AAAA,EACjC;AACF;AAAA;AAAA;AAAA;AAAA;AAMA,wBAAmB,WAAS;AAC1B,MAAI,sBAAK,iDAAL,YAA0B;AAAC;AAAA,EAAO;AACtC,MAAI,CAAC,mBAAK,iBAAgB;AACxB,UAAM,QAAQ,KAAK,cAAc,cAAc,OAAO;AACtD,UAAM,OAAO;AACb,UAAM,aAAa,4BAA4B,EAAE;AACjD,uBAAK,gBAAiB;AAAA,EACxB;AACA,qBAAK,gBAAe,OAAO,KAAK;AAChC,qBAAK,gBAAe,WAAW,sBAAK,2CAAL;AAC/B,qBAAK,gBAAe,QAAQ,mBAAK;AACjC,MAAI,mBAAK,gBAAe,eAAe,MAAM;AAAC,SAAK,YAAY,mBAAK,eAAc;AAAA,EAAE;AACpF,QAAM,OAAO,KAAK,QAAQ,MAAM;AAChC,MAAI,SAAS,mBAAK,gBAAe;AAC/B,uBAAK,gBAAe,oBAAoB,SAAS,mBAAK,iBAAgB;AACtE,UAAM,iBAAiB,SAAS,mBAAK,iBAAgB;AACrD,uBAAK,eAAgB;AAAA,EACvB;AACF;AAEA,wBAAmB,WAAS;AAC1B,qBAAK,gBAAe,oBAAoB,SAAS,mBAAK,iBAAgB;AACtE,qBAAK,eAAgB;AACvB;AAEA;AArhBW,gBACJ,iBAAiB;;;AExEnB,IAAM,cAAc;AAQpB,SAAS,sBAAsB,MAAc,aAAuC;AACzF,MAAI,OAAO,mBAAmB,aAAa;AAAC,WAAO;AAAA,EAAgB;AACnE,QAAM,WAAW,eAAe,IAAI,GAAG;AACvC,MAAI,UAAU;AAAC,WAAO;AAAA,EAAS;AAC/B,QAAM,WAAW;AACjB,QAAM,YAAY,eAAe,CAAC,CAAC,SAAS,UAAU,eAAe;AACrE,QAAM,OAAO,YAAY,cAAc,gBAAgB;AAAA,EAAC,IAAI;AAC5D,iBAAe,OAAO,KAAK,IAAI;AAC/B,MAAI,SAAS,iBAAiB;AAAC,kBAAc;AAAA,EAAK;AAClD,SAAO;AACT;AAEA,IAAI,cAAc;","names":[]}
@@ -1,4 +1,4 @@
1
- import { BindingTheme, MikeDownFeatures, MikeDownSettings, MikeDownHost, MikeDownEditorHandle } from '@mikedown/core';
1
+ import { BindingTheme, MikeDownFeatures, MikeDownSettings, MikeDownHost, MikeDownAiHost, MikeDownEditorHandle } from '@mikedown/core';
2
2
 
3
3
  /**
4
4
  * <mikedown-editor>: the MikeDown editor as a form-associated custom element.
@@ -78,6 +78,13 @@ declare class MikeDownElement extends Base {
78
78
  */
79
79
  get host(): MikeDownElementHost;
80
80
  set host(host: MikeDownElementHost | null);
81
+ /**
82
+ * The AI host group (`complete`, and for tier 2 `listEngines`, `testEngine`, ...). A property only: it holds
83
+ * functions, so there is no attribute. Wins over `host.ai`. Core turns the AI features on when it is present,
84
+ * so a change rebuilds the editor. Core ships no provider SDK; the page supplies the transport.
85
+ */
86
+ get ai(): MikeDownAiHost | undefined;
87
+ set ai(ai: MikeDownAiHost | null | undefined);
81
88
  /** The editor handle while connected, else null. */
82
89
  get handle(): MikeDownEditorHandle | null;
83
90
  get form(): HTMLFormElement | null;
package/dist/define.d.ts CHANGED
@@ -1,2 +1,2 @@
1
- export { M as MikeDownElement } from './define-BYCiu-_6.js';
1
+ export { M as MikeDownElement } from './define-DazuAdp-.js';
2
2
  import '@mikedown/core';
package/dist/define.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MikeDownElement,
3
3
  defineMikeDownElement
4
- } from "./chunk-E72SZEON.js";
4
+ } from "./chunk-WZVZGW65.js";
5
5
 
6
6
  // src/define.ts
7
7
  defineMikeDownElement();
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { M as MikeDownElement } from './define-BYCiu-_6.js';
2
- export { a as MikeDownChangeEventDetail, b as MikeDownElementHost, c as MikeDownElementTheme, d as MikeDownReadyEventDetail, e as dedentScriptText } from './define-BYCiu-_6.js';
1
+ import { M as MikeDownElement } from './define-DazuAdp-.js';
2
+ export { a as MikeDownChangeEventDetail, b as MikeDownElementHost, c as MikeDownElementTheme, d as MikeDownReadyEventDetail, e as dedentScriptText } from './define-DazuAdp-.js';
3
3
  import '@mikedown/core';
4
4
 
5
5
  /**
package/dist/index.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  MikeDownElement,
4
4
  dedentScriptText,
5
5
  defineMikeDownElement
6
- } from "./chunk-E72SZEON.js";
6
+ } from "./chunk-WZVZGW65.js";
7
7
  export {
8
8
  DEFAULT_TAG,
9
9
  MikeDownElement,