@kubed.io/cdn 0.0.4 → 0.0.5

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.
@@ -1,10 +1,10 @@
1
1
  //#region src/kd/define.ts
2
- var e = "0.0.4";
2
+ var e = "0.0.5";
3
3
  function t(t, n, r = customElements) {
4
4
  let i = r.get(t);
5
- return i ? (i !== n && i.kdVersion !== "0.0.4" && console.warn(`@kubed.io/cdn ${e}: <${t}> is already defined by ${i.kdVersion ? `@kubed.io/cdn ${i.kdVersion}` : "another script"}; that definition stays until the page is reloaded.`), !1) : (Object.defineProperty(n, "kdVersion", { value: e }), r.define(t, n), !0);
5
+ return i ? (i !== n && i.kdVersion !== "0.0.5" && console.warn(`@kubed.io/cdn ${e}: <${t}> is already defined by ${i.kdVersion ? `@kubed.io/cdn ${i.kdVersion}` : "another script"}; that definition stays until the page is reloaded.`), !1) : (Object.defineProperty(n, "kdVersion", { value: e }), r.define(t, n), !0);
6
6
  }
7
7
  //#endregion
8
8
  export { t as n, e as t };
9
9
 
10
- //# sourceMappingURL=define-XzEniRJH.js.map
10
+ //# sourceMappingURL=define-BSZoKakE.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"define-XzEniRJH.js","names":["VERSION","define","existing","registry","name","element"],"sources":["../../src/kd/define.ts"],"sourcesContent":["/** This build's package version. */\nexport const VERSION: string = __KD_VERSION__;\n\n/**\n * Registers a custom element unless the name is taken, and says so when it is.\n *\n * Every panel on a page shares one registry, and a definition outlives SPA\n * navigation, so the first version of a tag loaded owns it until a full page\n * reload. A second define would throw; this keeps the first and warns when the\n * two builds differ.\n *\n * @returns whether this call defined the element\n */\nexport function define(\n name: string,\n element: CustomElementConstructor,\n registry: CustomElementRegistry = customElements,\n): boolean {\n const existing = registry.get(name) as (CustomElementConstructor & { kdVersion?: string }) | undefined;\n if (existing) {\n if (existing !== element && existing.kdVersion !== VERSION) {\n console.warn(\n `@kubed.io/cdn ${VERSION}: <${name}> is already defined by ${existing.kdVersion ? `@kubed.io/cdn ${existing.kdVersion}` : 'another script'}; ` +\n 'that definition stays until the page is reloaded.',\n );\n }\n return false;\n }\n Object.defineProperty(element, 'kdVersion', { value: VERSION });\n registry.define(name, element);\n return true;\n}\n"],"mappings":";AACA,IAAaA,IAAA;AAYb,SAAgBC,EACd,GACA,GACA,IAAkC,gBACzB;CACT,IAAMC,IAAWC,EAAS,IAAIC,CAAI;CAYlC,OAXIF,KACEA,MAAaG,KAAWH,EAAS,cAAA,WACnC,QAAQ,KACN,iBAAiBF,EAAQ,KAAKI,EAAK,0BAA0BF,EAAS,YAAY,iBAAiBA,EAAS,cAAc,iBAAiB,oDAE7I,GAEK,OAET,OAAO,eAAeG,GAAS,aAAa,EAAE,OAAOL,EAAQ,CAAC,GAC9DG,EAAS,OAAOC,GAAMC,CAAO,GACtB;AACT"}
1
+ {"version":3,"file":"define-BSZoKakE.js","names":["VERSION","define","existing","registry","name","element"],"sources":["../../src/kd/define.ts"],"sourcesContent":["/** This build's package version. */\nexport const VERSION: string = __KD_VERSION__;\n\n/**\n * Registers a custom element unless the name is taken, and says so when it is.\n *\n * Every panel on a page shares one registry, and a definition outlives SPA\n * navigation, so the first version of a tag loaded owns it until a full page\n * reload. A second define would throw; this keeps the first and warns when the\n * two builds differ.\n *\n * @returns whether this call defined the element\n */\nexport function define(\n name: string,\n element: CustomElementConstructor,\n registry: CustomElementRegistry = customElements,\n): boolean {\n const existing = registry.get(name) as (CustomElementConstructor & { kdVersion?: string }) | undefined;\n if (existing) {\n if (existing !== element && existing.kdVersion !== VERSION) {\n console.warn(\n `@kubed.io/cdn ${VERSION}: <${name}> is already defined by ${existing.kdVersion ? `@kubed.io/cdn ${existing.kdVersion}` : 'another script'}; ` +\n 'that definition stays until the page is reloaded.',\n );\n }\n return false;\n }\n Object.defineProperty(element, 'kdVersion', { value: VERSION });\n registry.define(name, element);\n return true;\n}\n"],"mappings":";AACA,IAAaA,IAAA;AAYb,SAAgBC,EACd,GACA,GACA,IAAkC,gBACzB;CACT,IAAMC,IAAWC,EAAS,IAAIC,CAAI;CAYlC,OAXIF,KACEA,MAAaG,KAAWH,EAAS,cAAA,WACnC,QAAQ,KACN,iBAAiBF,EAAQ,KAAKI,EAAK,0BAA0BF,EAAS,YAAY,iBAAiBA,EAAS,cAAc,iBAAiB,oDAE7I,GAEK,OAET,OAAO,eAAeG,GAAS,aAAa,EAAE,OAAOL,EAAQ,CAAC,GAC9DG,EAAS,OAAOC,GAAMC,CAAO,GACtB;AACT"}
@@ -1,5 +1,5 @@
1
1
  import { a as e, c as t, l as n, n as r, o as i, r as a, s as o, t as s } from "./element-ChNBLJ5X.js";
2
- import { n as c } from "./define-XzEniRJH.js";
2
+ import { n as c } from "./define-BSZoKakE.js";
3
3
  //#region src/kd/helpers.ts
4
4
  function l(e) {
5
5
  return JSON.stringify(e ?? null);
@@ -1146,4 +1146,4 @@ c("kd-tile", $);
1146
1146
  //#endregion
1147
1147
  export { b as C, u as E, m as S, l as T, w as _, J as a, C as b, z as c, F as d, N as f, D as g, j as h, Y as i, L as l, M as m, Q as n, q as o, P as p, X as r, B as s, $ as t, I as u, T as v, y as w, x, S as y };
1148
1148
 
1149
- //# sourceMappingURL=kd-Bbw0GeQ5.js.map
1149
+ //# sourceMappingURL=kd-BeZbw7cp.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"kd-Bbw0GeQ5.js","names":["o","t","nothing","nothing","ifDefined","nothing","ifDefined","nothing","nothing","i","r","t","s","nothing","styleMap","nothing","nothing","ifDefined","nothing","LitElement","nothing","ifDefined","i$3","b","i$2","base","A","json","E","KdElement","define","kdjson","value","registerHelpers","o$1","o","RESERVED","NUMBER","DATE","INDICATOR","CONTROL","needsQuotes","s","quote","token","isBlock","v","isLiteral","scalar","literal","chomp","lines","l","inline","gap","head","header","inner","block","item","sub","indent","out","key","yamlLines","toYaml","line","t","KdData","pre","i","n","summary","TONES","tone","fallback","tones","IMAGE","renderIcon","cls","safeHref","href","here","loc","win","m","linkUrl","link","at","cut","path","params","name","vars","k","query","runtimes","preload","rt","navigate","event","service","to","url","prefix","KdLink","d","body","title","#click","#refresh","KdPill","isEmpty","cell","renderCell","c","cellStyles","KdBar","chips","chain","group","groups","raw","data","g","a","jsonValue","parsed","CLIP","KdGroups","#tree","#pills","e","KdMask","changed","i$1","t$1","r","number","KdMeter","marks","unit","largest","scale","clamp","f","fill","KdSheet","rows","row","STATUS","glyph","KdSteps","steps","step","KdTable","cols","columns","align","col","label","pane","KdTabs","#observer","#storage","stored","selected","byLabel","panes","index","#panes","open","#index","count","#select","slots","KdTile","external"],"sources":["../../src/kd/helpers.ts","../../node_modules/lit-html/directives/if-defined.js","../../src/kd/yaml.ts","../../src/kd/elements/data.ts","../../src/kd/parts.ts","../../src/kd/elements/link.ts","../../src/kd/elements/pill.ts","../../src/kd/cell.ts","../../src/kd/elements/bar.ts","../../src/kd/elements/groups.ts","../../src/kd/elements/mask.ts","../../node_modules/lit-html/directive.js","../../node_modules/lit-html/directives/style-map.js","../../src/kd/elements/meter.ts","../../src/kd/elements/sheet.ts","../../src/kd/elements/steps.ts","../../src/kd/elements/table.ts","../../src/kd/elements/tabs.ts","../../src/kd/elements/tile.ts"],"sourcesContent":["/**\n * Data for a JSON attribute. Double-stash it so Handlebars escapes the quotes:\n * `<kd-table data=\"{{kdjson rows}}\">`. Never triple-stash JSON into an\n * attribute: one `'` in the data turns the whole tag into escaped text.\n */\nexport function kdjson(value: unknown): string {\n return JSON.stringify(value ?? null);\n}\n\ninterface Handlebars {\n registerHelper(name: string, helper: (...args: unknown[]) => unknown): void;\n}\n\n/** Registers `kdjson` on Business Text's `context.handlebars`. */\nexport function registerHelpers(handlebars: Handlebars): void {\n handlebars.registerHelper('kdjson', (value) => kdjson(value));\n}\n","import{nothing as t}from\"../lit-html.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o=o=>o??t;export{o as ifDefined};\n//# sourceMappingURL=if-defined.js.map\n","// A small YAML dumper for JSON values: block style, kubectl's layout (a list\n// sits at its key's indent), quotes only where a plain scalar would be misread.\n\n/** What a token is, for highlighting. Punctuation and indentation are `plain`. */\nexport type YamlKind = 'key' | 'str' | 'num' | 'bool' | 'null' | 'plain';\n\nexport interface YamlToken {\n kind: YamlKind;\n text: string;\n}\n\n/** One output line: its indentation (with any `- ` markers), then its tokens. */\nexport interface YamlLine {\n prefix: string;\n tokens: YamlToken[];\n}\n\nconst RESERVED = /^(~|null|true|false|yes|no|on|off|y|n)$/i;\nconst NUMBER =\n /^([-+]?(\\.\\d+|\\d[\\d_]*(\\.\\d*)?)([eE][-+]?\\d+)?|0x[0-9a-f]+|0o[0-7]+|[-+]?\\.(inf|nan)|[-+]?\\d+(:[0-5]?\\d)+(\\.\\d*)?)$/i;\nconst DATE = /^\\d{4}-\\d\\d?-\\d\\d?([Tt ]|$)/;\nconst INDICATOR = /^([,[\\]{}#&*!|>'\"%@`]|[-?:](\\s|$))/;\nconst CONTROL = /[\\u0000-\\u0008\\u000b-\\u001f\\u007f]/;\n\nfunction needsQuotes(s: string): boolean {\n return (\n s === '' ||\n RESERVED.test(s) ||\n NUMBER.test(s) ||\n DATE.test(s) ||\n INDICATOR.test(s) ||\n /^\\s|\\s$/.test(s) ||\n s.includes(': ') ||\n s.includes(' #') ||\n s.endsWith(':') ||\n s.includes('\\n') ||\n s.includes('\\t') ||\n CONTROL.test(s)\n );\n}\n\n/** A string as a YAML scalar, double-quoted (JSON's escapes are YAML's) only when it must be. */\nexport function quote(s: string): string {\n return needsQuotes(s) ? JSON.stringify(s) : s;\n}\n\nconst token = (kind: YamlKind, text: string): YamlToken => ({ kind, text });\n\nfunction isBlock(value: unknown): value is object {\n if (Array.isArray(value)) return value.length > 0;\n return value !== null && typeof value === 'object' && Object.values(value).some((v) => v !== undefined);\n}\n\nfunction isLiteral(value: unknown): value is string {\n return typeof value === 'string' && value.includes('\\n') && !CONTROL.test(value);\n}\n\nfunction scalar(value: unknown): YamlToken {\n if (value === null || value === undefined) return token('null', 'null');\n if (typeof value === 'boolean') return token('bool', String(value));\n if (typeof value === 'number' || typeof value === 'bigint') return token('num', String(value));\n if (Array.isArray(value)) return token('plain', '[]');\n if (typeof value === 'object') return token('plain', '{}');\n return token('str', quote(String(value)));\n}\n\n// A multi-line string as a literal block: `|` keeps one final newline, `|-`\n// none and `|+` all; a leading space on the first line needs the indent stated.\nfunction literal(s: string): { header: string; lines: string[] } {\n const chomp = s.endsWith('\\n') ? (s.endsWith('\\n\\n') ? '+' : '') : '-';\n const body = chomp === '-' ? s : s.slice(0, -1);\n const lines = body.split('\\n');\n const first = lines.find((l) => l !== '');\n return { header: `|${first?.startsWith(' ') ? '2' : ''}${chomp}`, lines };\n}\n\n// A scalar, an empty collection or a literal block after `head` (`key:` or nothing).\nfunction inline(prefix: string, head: YamlToken[], value: unknown, inner: string): YamlLine[] {\n const gap = head.length ? [token('plain', ' ')] : [];\n if (isLiteral(value)) {\n const { header, lines } = literal(value);\n return [\n { prefix, tokens: [...head, ...gap, token('plain', header)] },\n ...lines.map((l) => ({ prefix: l ? inner : '', tokens: [token('str', l)] })),\n ];\n }\n return [{ prefix, tokens: [...head, ...gap, scalar(value)] }];\n}\n\n// A non-empty object or array at `indent`.\nfunction block(value: object, indent: string, out: YamlLine[]): void {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (isBlock(item)) {\n const sub: YamlLine[] = [];\n block(item, `${indent} `, sub);\n sub[0].prefix = `${indent}- ${sub[0].prefix.slice(indent.length + 2)}`;\n out.push(...sub);\n } else {\n out.push(...inline(`${indent}- `, [], item, `${indent} `));\n }\n }\n return;\n }\n for (const [key, item] of Object.entries(value)) {\n if (item === undefined) continue;\n const head = [token('key', quote(key)), token('plain', ':')];\n if (isBlock(item)) {\n out.push({ prefix: indent, tokens: head });\n block(item, Array.isArray(item) ? indent : `${indent} `, out);\n } else {\n out.push(...inline(indent, head, item, `${indent} `));\n }\n }\n}\n\n/** A JSON value as YAML lines of tokens, for rendering with highlighting. */\nexport function yamlLines(value: unknown): YamlLine[] {\n const out: YamlLine[] = [];\n if (isBlock(value)) block(value, '', out);\n else out.push(...inline('', [], value, ' '));\n return out;\n}\n\n/** A JSON value as YAML text. */\nexport function toYaml(value: unknown): string {\n return yamlLines(value)\n .map((line) => line.prefix + line.tokens.map((t) => t.text).join(''))\n .join('\\n');\n}\n","import { css, html, nothing } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { yamlLines } from '../yaml';\n\n/**\n * Any JSON value as YAML. An object or array longer than `fold` lines (default\n * 10; 0 never folds) collapses under a \"{ } n keys\" / \"[ ] n items\" line.\n *\n * `<kd-data data=\"{{kdjson spec}}\" fold=\"20\">`\n */\nexport class KdData extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n fold: { type: Number },\n };\n static override styles = [\n base,\n css`\n pre {\n margin: 0;\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n line-height: 1.5;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n .key {\n color: color-mix(in srgb, var(--kd-info, currentColor) 75%, var(--kd-text, currentColor));\n }\n .str {\n color: color-mix(in srgb, var(--kd-success, currentColor) 70%, var(--kd-text, currentColor));\n }\n .num {\n color: color-mix(in srgb, var(--kd-warning, currentColor) 55%, var(--kd-text, currentColor));\n }\n .bool,\n .null {\n color: color-mix(in srgb, var(--kd-primary, currentColor) 70%, var(--kd-text, currentColor));\n }\n summary {\n width: max-content;\n color: var(--kd-text-2, inherit);\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n cursor: pointer;\n list-style: none;\n }\n summary::-webkit-details-marker {\n display: none;\n }\n summary::before {\n content: '▸ ';\n }\n details[open] > summary::before {\n content: '▾ ';\n }\n details > pre {\n margin-top: 2px;\n }\n `,\n ];\n\n declare data: unknown;\n declare fold: number;\n\n constructor() {\n super();\n this.fold = 10;\n }\n\n override render() {\n const value = this.data;\n if (value === undefined) return nothing;\n const lines = yamlLines(value);\n const pre = html`<pre>${lines.map(\n (line, i) =>\n html`${i ? '\\n' : ''}${line.prefix}${line.tokens.map((t) =>\n t.kind === 'plain' ? t.text : html`<span class=${t.kind}>${t.text}</span>`,\n )}`,\n )}</pre>`;\n if (!(this.fold > 0 && lines.length > this.fold && value !== null && typeof value === 'object')) return pre;\n const n = Object.keys(value).length;\n const summary = Array.isArray(value) ? `[ ] ${n} item${n === 1 ? '' : 's'}` : `{ } ${n} key${n === 1 ? '' : 's'}`;\n return html`<details><summary>${summary}</summary>${pre}</details>`;\n }\n}\n\ndefine('kd-data', KdData);\n","// Small pieces several elements share: tones, icons and link safety.\nimport { css, html, nothing, type TemplateResult } from 'lit';\n\n/** A semantic colour. Each maps to `--kd-<tone>`; neutral is the secondary text colour. */\nexport type Tone = 'primary' | 'success' | 'warning' | 'error' | 'info' | 'neutral';\n\nconst TONES = new Set<string>(['primary', 'success', 'warning', 'error', 'info', 'neutral']);\n\n/** `value` when it names a tone, else `fallback`. */\nexport function tone(value: unknown, fallback: Tone = 'neutral'): Tone {\n return typeof value === 'string' && TONES.has(value) ? (value as Tone) : fallback;\n}\n\n/**\n * Tone classes. Each sets `--tone` (the colour), `--tone-ink` (text in that\n * colour, pulled towards the text colour so it reads on either theme) and\n * `--tone-line` (a border in that colour).\n */\nexport const tones = css`\n .primary {\n --tone: var(--kd-primary, currentColor);\n }\n .success {\n --tone: var(--kd-success, currentColor);\n }\n .warning {\n --tone: var(--kd-warning, currentColor);\n }\n .error {\n --tone: var(--kd-error, currentColor);\n }\n .info {\n --tone: var(--kd-info, currentColor);\n }\n .primary,\n .success,\n .warning,\n .error,\n .info {\n --tone-ink: color-mix(in srgb, var(--tone) 75%, var(--kd-text, currentColor));\n --tone-line: color-mix(in srgb, var(--tone) 50%, transparent);\n }\n .neutral {\n --tone: var(--kd-text-2, currentColor);\n --tone-ink: var(--kd-text-2, currentColor);\n --tone-line: var(--kd-border-strong, currentColor);\n }\n`;\n\nconst IMAGE = /^(https?:|data:image\\/|\\/|\\.\\.?\\/)/i;\n\n/** An icon that is either an image URL or a short text such as an emoji. */\nexport function renderIcon(value: string | null | undefined, cls = 'icon'): TemplateResult | typeof nothing {\n if (!value) return nothing;\n return IMAGE.test(value) ? html`<img class=${cls} src=${value} alt=\"\" />` : html`<span class=${cls}>${value}</span>`;\n}\n\n/** `href` unless it is a script or data URL, which data must never smuggle into a link. */\nexport function safeHref(href: string | null | undefined): string | undefined {\n if (href == null || href === '') return undefined;\n return /^\\s*(javascript|vbscript|data):/i.test(href) ? undefined : href;\n}\n","import { css, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { renderIcon, safeHref } from '../parts';\n\n/** Dashboard variables, without the `var-` prefix (one is added when missing). A list repeats the variable. */\nexport type Vars = Record<string, string | number | boolean | null | undefined | readonly (string | number | boolean)[]>;\n\nexport interface LinkData {\n /** A dashboard uid (optionally `uid/slug`, optionally followed by `?query`, as a `back` value is). */\n dashboard?: string;\n /** A plain URL, used when there is no `dashboard`. */\n href?: string;\n vars?: Vars;\n text?: string;\n /** An image URL or an emoji. */\n icon?: string;\n /** Tooltip. */\n title?: string;\n /** Pass this dashboard and its variables as `var-back`, so the target can link back. */\n back?: boolean;\n}\n\ninterface Here {\n /** Grafana's sub-path, the part of the path before `/d/`. */\n prefix: string;\n uid?: string;\n params: URLSearchParams;\n}\n\n// The current dashboard, read from the page URL. Outside a dashboard (or\n// outside Grafana) there is no uid and no time range to keep.\nfunction here(win: Window | null | undefined): Here {\n try {\n const loc = win?.location;\n const m = /^(.*?)\\/d\\/([^/?#]+)/.exec(loc?.pathname ?? '');\n return {\n prefix: m?.[1] ?? '',\n uid: m ? decodeURIComponent(m[2]) : undefined,\n params: new URLSearchParams(loc?.search ?? ''),\n };\n } catch {\n return { prefix: '', params: new URLSearchParams() };\n }\n}\n\n/**\n * The URL a link goes to: `<sub-path>/d/<dashboard>?var-k=v…` keeping the\n * current `from`/`to`, plus `var-back=<this uid>?<this page's var-* query>`\n * when `back` is set; or the plain `href`. Undefined when there is neither.\n */\nexport function linkUrl(link: LinkData, win?: Window | null): string | undefined {\n if (!link.dashboard) return safeHref(link.href);\n const at = here(win);\n const cut = link.dashboard.indexOf('?');\n const path = cut < 0 ? link.dashboard : link.dashboard.slice(0, cut);\n const params = new URLSearchParams(cut < 0 ? '' : link.dashboard.slice(cut + 1));\n for (const [name, value] of Object.entries(link.vars ?? {})) {\n if (value === null || value === undefined) continue;\n const key = name.startsWith('var-') ? name : `var-${name}`;\n params.delete(key);\n for (const v of Array.isArray(value) ? value : [value]) params.append(key, String(v));\n }\n for (const name of ['from', 'to']) {\n const value = at.params.get(name);\n if (value !== null && !params.has(name)) params.set(name, value);\n }\n if (link.back && at.uid) {\n const vars = new URLSearchParams([...at.params].filter(([k]) => k.startsWith('var-'))).toString();\n params.set('var-back', vars ? `${at.uid}?${vars}` : at.uid);\n }\n const query = params.toString();\n return `${at.prefix}/d/${path}${query ? `?${query}` : ''}`;\n}\n\ninterface Runtime {\n locationService?: { push(to: string): void };\n}\ntype GrafanaWindow = Window & { System?: { import?(id: string): Promise<unknown> } };\n\nconst runtimes = new WeakMap<Window, Runtime | null>();\n\n// Grafana turns clicks on its own links into in-app navigation, but it finds\n// the anchor from the event target, which a shadow root retargets to the host.\n// So a kd-link does it itself, through the same location service; until the\n// runtime has loaded (or outside Grafana) the browser simply follows the link.\nfunction preload(win: GrafanaWindow | null | undefined): void {\n if (!win || runtimes.has(win) || !win.System?.import) return;\n runtimes.set(win, null);\n win.System.import('@grafana/runtime').then(\n (rt) => runtimes.set(win, rt as Runtime),\n () => {},\n );\n}\n\nfunction navigate(win: Window | null | undefined, url: string, event: MouseEvent): void {\n if (!win || event.defaultPrevented || event.button !== 0) return;\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n const service = runtimes.get(win)?.locationService;\n if (!service) return;\n const to = new URL(url, win.location.href);\n if (to.origin !== win.location.origin) return;\n const { prefix } = here(win);\n const path = prefix && to.pathname.startsWith(prefix) ? to.pathname.slice(prefix.length) : to.pathname;\n event.preventDefault();\n service.push(path + to.search + to.hash);\n}\n\n/**\n * A link to a dashboard (or any URL) with an optional icon. Set `data`, or the\n * attributes of the same names (`vars` as JSON, `back` as a boolean). Without\n * `text`, the slot is the label.\n *\n * `<kd-link dashboard=\"k8s-pod\" vars='{\"pod\":\"web-0\"}' back>web-0</kd-link>`\n */\nexport class KdLink extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n dashboard: {},\n href: {},\n vars: { converter: json },\n text: {},\n icon: {},\n back: { type: Boolean },\n };\n static override styles = [\n base,\n css`\n :host {\n display: inline;\n }\n /* One line: a long name ends in an ellipsis with the full text on hover.\n A table caps links with --kd-link-max, since 100% means nothing to an\n auto-layout column. */\n a,\n span.link {\n display: inline-flex;\n align-items: baseline;\n max-width: var(--kd-link-max, 100%);\n min-width: 0;\n vertical-align: bottom;\n }\n .text {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n a {\n color: var(--kd-link, inherit);\n text-decoration: none;\n }\n a:hover {\n text-decoration: underline;\n }\n .icon {\n width: 16px;\n height: 16px;\n margin-right: 4px;\n vertical-align: -3px;\n }\n `,\n ];\n\n declare data: LinkData | undefined;\n declare dashboard: string | undefined;\n declare href: string | undefined;\n declare vars: Vars | undefined;\n declare text: string | undefined;\n declare icon: string | undefined;\n declare back: boolean | undefined;\n\n /** The link, `data` taking precedence over the attributes field by field. */\n get link(): LinkData {\n const d = this.data ?? {};\n return {\n dashboard: d.dashboard ?? this.dashboard,\n href: d.href ?? this.href,\n vars: d.vars ?? this.vars,\n text: d.text ?? this.text,\n icon: d.icon ?? this.icon,\n title: d.title,\n back: d.back ?? this.back,\n };\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n preload(this.ownerDocument?.defaultView);\n }\n\n // Variables can change without the panel re-rendering this element, so the\n // URL is rebuilt when the pointer or focus arrives and again on the click.\n #refresh = () => this.requestUpdate();\n\n #click = (event: MouseEvent) => {\n const win = this.ownerDocument?.defaultView;\n const url = linkUrl(this.link, win);\n if (url === undefined) return;\n (event.currentTarget as HTMLAnchorElement).setAttribute('href', url);\n navigate(win, url, event);\n };\n\n override render() {\n const link = this.link;\n const url = linkUrl(link, this.ownerDocument?.defaultView);\n // The text carries its full self on hover (it may be cut short); the link's\n // own title (a kind, say) shows over the icon.\n const body = html`${renderIcon(link.icon)}<span class=\"text\" title=${ifDefined(link.text)}\n ><slot>${link.text ?? ''}</slot></span\n >`;\n const title = link.title ?? link.text;\n if (url === undefined) return html`<span class=\"link\" title=${ifDefined(title)}>${body}</span>`;\n return html`<a\n href=${url}\n title=${ifDefined(title)}\n @click=${this.#click}\n @mouseenter=${this.#refresh}\n @focus=${this.#refresh}\n >${body}</a\n >`;\n }\n}\n\ndefine('kd-link', KdLink);\n","import { css, html } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\nimport { tone, tones, type Tone } from '../parts';\n\n/**\n * A pill or badge. The slot is its text; `title` is the native tooltip.\n *\n * `<kd-pill tone=\"success\" title=\"all containers ready\">Running</kd-pill>`\n */\nexport class KdPill extends KdElement {\n static override properties = { tone: {} };\n static override styles = [\n base,\n tones,\n css`\n :host {\n display: inline-block;\n margin: 1px 4px 1px 0;\n vertical-align: baseline;\n }\n span {\n display: inline-block;\n padding: 0 8px;\n border: 1px solid var(--tone-line);\n border-radius: 10px;\n background: color-mix(in srgb, var(--tone) 14%, transparent);\n color: var(--tone-ink);\n font-size: 11px;\n line-height: 18px;\n white-space: nowrap;\n }\n `,\n ];\n\n declare tone: Tone | undefined;\n\n override render() {\n return html`<span class=${tone(this.tone)}><slot></slot></span>`;\n }\n}\n\ndefine('kd-pill', KdPill);\n","// What a sheet value or a table cell may be, and how each shape renders.\nimport { css, html, nothing, type TemplateResult } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport './elements/data';\nimport './elements/link';\nimport './elements/pill';\nimport type { Vars } from './elements/link';\nimport type { Tone } from './parts';\n\nexport type { Tone };\n\n/** A pill: `<kd-pill>`. */\nexport interface PillCell {\n text: string;\n tone?: Tone;\n title?: string;\n}\n\n/** A plain link: `<kd-link>` with an `href`. */\nexport interface HrefCell {\n href: string;\n text: string;\n icon?: string;\n title?: string;\n}\n\n/** A dashboard link: `<kd-link>`. */\nexport interface DashboardCell {\n dashboard: string;\n vars?: Vars;\n text: string;\n icon?: string;\n title?: string;\n back?: boolean;\n}\n\n/** Any JSON value as YAML: `<kd-data>`. */\nexport interface DataCell {\n data: unknown;\n}\n\n/** Monospace text. */\nexport interface CodeCell {\n code: string;\n}\n\n/** A scalar is text; an array renders its cells inline, wrapped. */\nexport type Cell =\n | string\n | number\n | boolean\n | null\n | undefined\n | PillCell\n | HrefCell\n | DashboardCell\n | DataCell\n | CodeCell\n | Cell[];\n\n/** Whether a cell has nothing to show. */\nexport function isEmpty(cell: Cell): boolean {\n return cell === null || cell === undefined || cell === '' || (Array.isArray(cell) && cell.every(isEmpty));\n}\n\n/** One cell. An object of no known shape is shown as data. */\nexport function renderCell(cell: Cell): TemplateResult | string | typeof nothing {\n if (cell === null || cell === undefined) return nothing;\n if (Array.isArray(cell)) {\n return html`<span class=\"cells\">${cell.filter((c) => !isEmpty(c)).map((c) => html`<span>${renderCell(c)}</span>`)}</span>`;\n }\n if (typeof cell !== 'object') return String(cell);\n if ('dashboard' in cell || 'href' in cell) return html`<kd-link .data=${cell}></kd-link>`;\n if ('data' in cell) return html`<kd-data .data=${cell.data}></kd-data>`;\n if ('code' in cell) return html`<code>${String(cell.code)}</code>`;\n if ('text' in cell) {\n return html`<kd-pill tone=${ifDefined(cell.tone)} title=${ifDefined(cell.title)}>${String(cell.text)}</kd-pill>`;\n }\n return html`<kd-data .data=${cell}></kd-data>`;\n}\n\n/** Styles an element that renders cells adds to its own. */\nexport const cellStyles = css`\n .cells {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 2px 6px;\n }\n code {\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n overflow-wrap: anywhere;\n }\n`;\n","import { css, html, nothing } from 'lit';\n\nimport { cellStyles, isEmpty, renderCell, type Cell } from '../cell';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { renderIcon } from '../parts';\n\nexport interface BarData {\n /** An image URL or an emoji. */\n icon?: string;\n /** The line above the title, e.g. the kind and namespace. */\n eyebrow?: Cell;\n title: string;\n /** Pills beside the title. */\n chips?: Cell[];\n /** A breadcrumb at the far end, e.g. the owner chain. */\n chain?: Cell[];\n}\n\n/**\n * A title bar or masthead.\n *\n * `el.data = { icon: '🐘', eyebrow: 'StatefulSet', title: 'postgresql', chips: [{ text: '1/1', tone: 'success' }] }`\n */\nexport class KdBar extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n cellStyles,\n css`\n .bar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 16px;\n padding: 0 4px;\n }\n img.icon {\n width: 42px;\n height: 42px;\n }\n span.icon {\n font-size: 34px;\n line-height: 1;\n }\n .eyebrow {\n color: var(--kd-text-2, inherit);\n font-size: 11px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n }\n .title {\n font-size: 22px;\n font-weight: 500;\n line-height: 1.2;\n overflow-wrap: anywhere;\n }\n .grow {\n flex: 1;\n }\n .chain {\n font-size: 13px;\n }\n .sep {\n margin: 0 6px;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: BarData | undefined;\n\n override render() {\n const d = this.data;\n if (!d) return nothing;\n const chips = (d.chips ?? []).filter((c) => !isEmpty(c));\n const chain = (d.chain ?? []).filter((c) => !isEmpty(c));\n return html`<div class=\"bar\">\n ${renderIcon(d.icon)}\n <div class=\"id\">\n ${isEmpty(d.eyebrow) ? nothing : html`<div class=\"eyebrow\">${renderCell(d.eyebrow)}</div>`}\n <div class=\"title\">${d.title ?? ''}</div>\n </div>\n ${chips.length ? html`<div class=\"chips\">${chips.map((c) => renderCell(c))}</div>` : nothing}\n <div class=\"grow\"></div>\n ${chain.length\n ? html`<nav class=\"chain\">\n ${chain.map((c, i) => html`${i ? html`<span class=\"sep\">›</span>` : nothing}${renderCell(c)}`)}\n </nav>`\n : nothing}\n </div>`;\n }\n}\n\ndefine('kd-bar', KdBar);\n","import { css, html, nothing } from 'lit';\n\nimport './data';\nimport './pill';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\n\n/** A string map, such as labels or annotations. */\nexport type GroupsData = Record<string, string>;\n\ninterface Group {\n prefix: string;\n entries: { key: string; name: string; value: string }[];\n}\n\n// Grouped by the prefix before \"/\"; unprefixed keys first, then by prefix.\nfunction group(data: GroupsData): Group[] {\n const groups = new Map<string, Group>();\n for (const [key, raw] of Object.entries(data)) {\n const cut = key.indexOf('/');\n const prefix = cut < 0 ? '' : key.slice(0, cut);\n const value = raw === null || raw === undefined ? '' : typeof raw === 'string' ? raw : JSON.stringify(raw);\n let g = groups.get(prefix);\n if (!g) groups.set(prefix, (g = { prefix, entries: [] }));\n g.entries.push({ key, name: key.slice(cut + 1), value });\n }\n return [...groups.values()].sort((a, b) => (a.prefix < b.prefix ? -1 : a.prefix > b.prefix ? 1 : 0));\n}\n\n/** A value that is a JSON object or array, parsed; undefined for anything else. */\nexport function jsonValue(value: string): object | undefined {\n if (!/^\\s*[[{]/.test(value)) return undefined;\n try {\n const parsed: unknown = JSON.parse(value);\n return parsed !== null && typeof parsed === 'object' ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\nconst CLIP = 600;\n\n/**\n * A string map grouped by key prefix: as pills (`mode=\"pills\"`, the default,\n * for labels) or as a key/value tree (`mode=\"tree\"`, for annotations, where a\n * value holding a JSON object or array is shown as folded YAML).\n *\n * `<kd-groups mode=\"tree\" data=\"{{kdjson metadata.annotations}}\">`\n */\nexport class KdGroups extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n mode: {},\n };\n static override styles = [\n base,\n css`\n .group + .group {\n margin-top: 12px;\n }\n div.head,\n tr.head td {\n padding-bottom: 3px;\n border-bottom: 1px solid var(--kd-border, transparent);\n color: var(--kd-text-2, inherit);\n font-family: var(--kd-font-mono, monospace);\n font-size: 11px;\n }\n div.head {\n margin-bottom: 6px;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n td {\n padding: 2px 12px 2px 0;\n vertical-align: top;\n }\n tr.head td {\n padding-top: 12px;\n }\n tr.head:first-child td {\n padding-top: 0;\n }\n tr.head + tr td {\n padding-top: 6px;\n }\n .k {\n white-space: nowrap;\n }\n code {\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n }\n .twig {\n margin: 0 8px 0 4px;\n color: var(--kd-text-dim, inherit);\n font-family: var(--kd-font-mono, monospace);\n }\n .v {\n width: 100%;\n color: color-mix(in srgb, var(--kd-success, currentColor) 70%, var(--kd-text, currentColor));\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n overflow-wrap: anywhere;\n word-break: break-word;\n }\n .none {\n padding: 8px 0;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: GroupsData | undefined;\n declare mode: 'pills' | 'tree' | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const groups = group(d);\n if (!groups.length) return html`<div class=\"none\">none</div>`;\n return this.mode === 'tree' ? this.#tree(groups) : this.#pills(groups);\n }\n\n #pills(groups: Group[]) {\n return groups.map(\n (g) => html`<div class=\"group\">\n ${g.prefix ? html`<div class=\"head\">${g.prefix}</div>` : nothing}\n <div>\n ${g.entries.map(\n (e) => html`<kd-pill tone=\"info\" title=${e.key}>${e.value === '' ? e.name : `${e.name}=${e.value}`}</kd-pill>`,\n )}\n </div>\n </div>`,\n );\n }\n\n #tree(groups: Group[]) {\n return html`<table>\n <tbody>\n ${groups.map(\n (g) => html`${g.prefix ? html`<tr class=\"head\"><td colspan=\"2\">${g.prefix}</td></tr>` : nothing}\n ${g.entries.map((e, i) => {\n const parsed = jsonValue(e.value);\n return html`<tr>\n <td class=\"k\">\n ${g.prefix ? html`<span class=\"twig\">${i === g.entries.length - 1 ? '└' : '├'}</span>` : nothing}<code\n >${e.name}</code\n >\n </td>\n <td class=\"v\">\n ${parsed\n ? html`<kd-data .data=${parsed}></kd-data>`\n : e.value.length > CLIP\n ? `${e.value.slice(0, CLIP)} …`\n : e.value}\n </td>\n </tr>`;\n })}`,\n )}\n </tbody>\n </table>`;\n }\n}\n\ndefine('kd-groups', KdGroups);\n","import { css, html, type PropertyValues } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\n\n/**\n * A secret value, hidden until clicked. The value never reaches a tooltip, the\n * console or any other attribute, and the dots do not give away its length.\n *\n * `<kd-mask value=\"{{password}}\"></kd-mask>`\n */\nexport class KdMask extends KdElement {\n static override properties = { value: {}, shown: { state: true } };\n static override styles = [\n base,\n css`\n :host {\n display: inline-block;\n }\n button {\n padding: 0;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n .dots {\n color: var(--kd-text-2, inherit);\n letter-spacing: 0.1em;\n }\n code {\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n user-select: all;\n }\n .hide {\n margin-left: 6px;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare value: string | undefined;\n declare shown: boolean;\n\n constructor() {\n super();\n this.shown = false;\n }\n\n // A new value starts hidden again.\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('value') && changed.get('value') !== undefined) this.shown = false;\n }\n\n override render() {\n if (!this.shown) {\n return html`<button type=\"button\" aria-label=\"show\" @click=${() => (this.shown = true)}>\n <span class=\"dots\">••••••••</span>\n </button>`;\n }\n return html`<code>${this.value ?? ''}</code\n ><button type=\"button\" class=\"hide\" aria-label=\"hide\" @click=${() => (this.shown = false)}>×</button>`;\n }\n}\n\ndefine('kd-mask', KdMask);\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e=t=>(...e)=>({_$litDirective$:t,values:e});class i{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}export{i as Directive,t as PartType,e as directive};\n//# sourceMappingURL=directive.js.map\n","import{noChange as t}from\"../lit-html.js\";import{directive as e,Directive as r,PartType as s}from\"../directive.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const n=\"important\",i=\" !\"+n,o=e(class extends r{constructor(t){if(super(t),t.type!==s.ATTRIBUTE||\"style\"!==t.name||t.strings?.length>2)throw Error(\"The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.\")}render(t){return Object.keys(t).reduce((e,r)=>{const s=t[r];return null==s?e:e+`${r=r.includes(\"-\")?r:r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,\"-$&\").toLowerCase()}:${s};`},\"\")}update(e,[r]){const{style:s}=e.element;if(void 0===this.ft)return this.ft=new Set(Object.keys(r)),this.render(r);for(const t of this.ft)null==r[t]&&(this.ft.delete(t),t.includes(\"-\")?s.removeProperty(t):s[t]=null);for(const t in r){const e=r[t];if(null!=e){this.ft.add(t);const r=\"string\"==typeof e&&e.endsWith(i);t.includes(\"-\")||r?s.setProperty(t,r?e.slice(0,-11):e,r?n:\"\"):s[t]=e}}return t}});export{o as styleMap};\n//# sourceMappingURL=style-map.js.map\n","import { css, html, nothing } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { tone, tones, type Tone } from '../parts';\n\nexport interface MeterMark {\n label: string;\n value: number;\n tone?: Tone;\n}\n\nexport interface MeterData {\n /** The measured value; null or missing shows only the marks. */\n value?: number | null;\n /** The full scale; defaults to the largest of the value and the marks. */\n max?: number;\n /** Appended to every number as is, e.g. `Mi`, `m` or ` cores`. */\n unit?: string;\n marks?: MeterMark[];\n}\n\nconst number = (n: number) => new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(n);\n\n/**\n * A value against request/limit-style marks. The fill takes the tone of the\n * highest toned mark it has reached, else primary.\n *\n * `el.data = { value: 412, unit: 'Mi', marks: [{ label: 'request', value: 256 }, { label: 'limit', value: 512, tone: 'error' }] }`\n */\nexport class KdMeter extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n tones,\n css`\n .track {\n position: relative;\n height: 8px;\n margin: 6px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--kd-border-strong, currentColor) 35%, transparent);\n }\n .fill {\n height: 100%;\n border-radius: 4px;\n background: var(--tone);\n }\n .mark {\n position: absolute;\n top: -3px;\n bottom: -3px;\n width: 2px;\n background: var(--tone);\n box-shadow: 0 0 0 1px var(--kd-bg, transparent);\n }\n .legend {\n display: flex;\n flex-wrap: wrap;\n gap: 2px 20px;\n font-size: 12px;\n }\n .value {\n font-family: var(--kd-font-mono, monospace);\n font-size: 14px;\n }\n .legend .mark-label {\n color: var(--kd-text-2, inherit);\n }\n .legend .num {\n color: var(--tone-ink);\n font-family: var(--kd-font-mono, monospace);\n }\n .none {\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: MeterData | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const value = typeof d.value === 'number' && Number.isFinite(d.value) ? d.value : undefined;\n const marks = (d.marks ?? []).filter((m) => m && Number.isFinite(m.value));\n const unit = d.unit ?? '';\n const largest = Math.max(value ?? 0, ...marks.map((m) => m.value));\n const scale = typeof d.max === 'number' && d.max > 0 ? d.max : largest > 0 ? largest : 1;\n // A mark's left edge moves from 0 to 100% - its width, so one at the maximum stays inside.\n const clamp = (f: number) => Math.min(1, Math.max(0, f));\n const at = (n: number) => `${Math.min(100, Math.max(0, (n / scale) * 100))}%`;\n const reached = value === undefined ? [] : marks.filter((m) => m.tone && value >= m.value);\n const fill = tone(reached.sort((a, b) => b.value - a.value)[0]?.tone, 'primary');\n return html`<div\n role=\"meter\"\n aria-valuemin=\"0\"\n aria-valuemax=${scale}\n aria-valuenow=${value ?? nothing}\n >\n <div class=\"track\">\n ${value === undefined ? nothing : html`<div class=\"fill ${fill}\" style=${styleMap({ width: at(value) })}></div>`}\n ${marks.map(\n (m) =>\n html`<div\n class=\"mark ${tone(m.tone)}\"\n style=${styleMap({ left: `calc(${at(m.value)} - ${clamp(m.value / scale) * 2}px)` })}\n title=\"${m.label} ${number(m.value)}${unit}\"\n ></div>`,\n )}\n </div>\n <div class=\"legend\">\n <span class=\"value ${value === undefined ? 'none' : ''}\">${value === undefined ? '–' : `${number(value)}${unit}`}</span>\n ${marks.map(\n (m) =>\n html`<span class=${tone(m.tone)}\n ><span class=\"mark-label\">${m.label}</span> <span class=\"num\">${number(m.value)}${unit}</span></span\n >`,\n )}\n </div>\n </div>`;\n }\n}\n\ndefine('kd-meter', KdMeter);\n","import { css, html, nothing } from 'lit';\n\nimport { cellStyles, isEmpty, renderCell, type Cell } from '../cell';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\n\nexport interface SheetRow {\n key: string;\n value: Cell;\n}\n\n/** Rows in order, or a plain object (its keys in order). */\nexport type SheetData = SheetRow[] | Record<string, Cell>;\n\n/**\n * A two-column property sheet. A row whose value is empty is left out.\n *\n * `el.data = [{ key: 'Node', value: 'node-1' }, { key: 'Phase', value: { text: 'Running', tone: 'success' } }]`\n */\nexport class KdSheet extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n cellStyles,\n css`\n dl {\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n margin: 0;\n font-size: 13px;\n }\n dt,\n dd {\n margin: 0;\n padding: 5px 12px 5px 0;\n border-bottom: 1px solid var(--kd-border, transparent);\n }\n dt {\n color: var(--kd-text-2, inherit);\n }\n dd {\n overflow-wrap: anywhere;\n }\n `,\n ];\n\n declare data: SheetData | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const rows = Array.isArray(d) ? d : Object.entries(d).map(([key, value]) => ({ key, value }));\n return html`<dl>\n ${rows\n .filter((row) => row && !isEmpty(row.value))\n .map((row) => html`<dt>${row.key}</dt><dd>${renderCell(row.value)}</dd>`)}\n </dl>`;\n }\n}\n\ndefine('kd-sheet', KdSheet);\n","import { css, html, nothing } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { tone, tones, type Tone } from '../parts';\n\nexport type StepStatus = 'done' | 'active' | 'failed' | 'pending' | Tone;\n\nexport interface Step {\n label: string;\n status: StepStatus;\n time?: string;\n detail?: string;\n}\n\nconst STATUS: Record<string, Tone> = { done: 'success', active: 'primary', failed: 'error', pending: 'neutral' };\n\nfunction glyph(t: Tone, n: number): string {\n if (t === 'success') return '✓';\n if (t === 'error') return '✗';\n if (t === 'warning') return '!';\n return String(n);\n}\n\n/**\n * A stepper or state stripe: ordered steps, each with a status (a lifecycle\n * word or a tone), an optional time and a detail line.\n *\n * `el.data = [{ label: 'Scheduled', status: 'done', time: '2m' }, { label: 'Ready', status: 'failed', detail: 'probe failed' }]`\n */\nexport class KdSteps extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n tones,\n css`\n ol {\n display: flex;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n li {\n position: relative;\n flex: 1;\n min-width: 0;\n text-align: center;\n }\n li + li::before {\n content: '';\n position: absolute;\n top: 12px;\n right: 50%;\n width: 100%;\n height: 2px;\n background: var(--kd-border-strong, currentColor);\n opacity: 0.6;\n }\n li.reached::before {\n background: var(--tone);\n opacity: 1;\n }\n .dot {\n position: relative;\n z-index: 1;\n width: 26px;\n height: 26px;\n margin: 0 auto;\n border-radius: 50%;\n background: var(--tone);\n color: var(--kd-bg, inherit);\n font-size: 13px;\n font-weight: 700;\n line-height: 26px;\n }\n .neutral .dot {\n border: 2px solid var(--tone-line);\n background: var(--kd-bg, transparent);\n color: var(--kd-text-2, inherit);\n line-height: 22px;\n }\n .active .dot {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--tone) 30%, transparent);\n }\n .label {\n margin-top: 4px;\n font-size: 12px;\n }\n .time,\n .detail {\n color: var(--kd-text-2, inherit);\n font-size: 11px;\n }\n .detail {\n display: -webkit-box;\n overflow: hidden;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow-wrap: anywhere;\n }\n `,\n ];\n\n declare data: Step[] | undefined;\n\n override render() {\n const steps = Array.isArray(this.data) ? this.data : [];\n if (!steps.length) return nothing;\n return html`<ol>\n ${steps.map((step, i) => {\n const t = tone(STATUS[step.status] ?? step.status);\n const reached = step.status === 'done' || step.status === 'success';\n const cls = `${t}${reached ? ' reached' : ''}${step.status === 'active' ? ' active' : ''}`;\n return html`<li class=${cls} title=${ifDefined(step.detail)}>\n <div class=\"dot\">${glyph(t, i + 1)}</div>\n <div class=\"label\">${step.label}</div>\n ${step.time ? html`<div class=\"time\">${step.time}</div>` : nothing}\n ${step.detail ? html`<div class=\"detail\">${step.detail}</div>` : nothing}\n </li>`;\n })}\n </ol>`;\n }\n}\n\ndefine('kd-steps', KdSteps);\n","import { css, html, nothing } from 'lit';\n\nimport { cellStyles, renderCell, type Cell } from '../cell';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\n\nexport interface TableColumn {\n key: string;\n /** Defaults to the key. */\n label?: string;\n align?: 'left' | 'center' | 'right';\n /** Keep the cell on one line (counts, times, short pills). */\n nowrap?: boolean;\n}\n\nexport interface TableData {\n /** Defaults to every key of the rows, in order of first appearance. */\n columns?: TableColumn[];\n rows: Record<string, Cell>[];\n}\n\n/**\n * A small table of cells. `data` may also be just the rows. With no rows it\n * shows `empty` (default \"none\").\n *\n * `el.data = { columns: [{ key: 'reason', label: 'Reason' }, { key: 'n', align: 'right' }], rows }`\n */\nexport class KdTable extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n empty: {},\n };\n static override styles = [\n base,\n cellStyles,\n css`\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n th,\n td {\n padding: 6px 12px 6px 0;\n border-bottom: 1px solid var(--kd-border, transparent);\n text-align: left;\n vertical-align: top;\n }\n th {\n color: var(--kd-text-2, inherit);\n font-size: 10px;\n font-weight: 500;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n }\n .center {\n text-align: center;\n }\n .right {\n text-align: right;\n }\n /* Prose breaks anywhere so one hash in a message cannot widen the table;\n links keep whole words and stop at 40ch with an ellipsis instead. */\n td {\n --kd-link-max: 40ch;\n overflow-wrap: anywhere;\n }\n .nowrap {\n white-space: nowrap;\n }\n .nowrap .cells {\n flex-wrap: nowrap;\n }\n .none {\n padding: 8px 0;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: TableData | TableData['rows'] | undefined;\n declare empty: string | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const { columns, rows = [] } = Array.isArray(d) ? { columns: undefined, rows: d } : d;\n if (!rows.length) return html`<div class=\"none\">${this.empty ?? 'none'}</div>`;\n const cols = columns ?? [...new Set(rows.flatMap((row) => Object.keys(row ?? {})))].map((key) => ({ key }) as TableColumn);\n const align = (col: TableColumn) => (col.align === 'right' || col.align === 'center' ? col.align : '');\n const cls = (col: TableColumn) => [align(col), col.nowrap ? 'nowrap' : ''].filter(Boolean).join(' ');\n return html`<table>\n <thead>\n <tr>\n ${cols.map((col) => html`<th class=${align(col)}>${col.label ?? col.key}</th>`)}\n </tr>\n </thead>\n <tbody>\n ${rows.map(\n (row) => html`<tr>\n ${cols.map((col) => html`<td class=${cls(col)}>${renderCell(row?.[col.key])}</td>`)}\n </tr>`,\n )}\n </tbody>\n </table>`;\n }\n}\n\ndefine('kd-table', KdTable);\n","import { LitElement, css, html, nothing, type PropertyValues } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\n\nconst label = (pane: Element, i: number) => pane.getAttribute('label') || `Tab ${i + 1}`;\n\n/**\n * Tabs over its child elements, any number of them: each child is a pane,\n * labelled by its `label` attribute, with an optional `count` beside it.\n * `selected` names the open pane by label (or by index). With a `key`, the\n * choice is kept in sessionStorage, so it survives the panel recreating the\n * element. A change dispatches `change` with `{ label, index }`.\n *\n * `<kd-tabs key=\"pod-tabs\"><section label=\"Events\" count=\"3\">…</section>…</kd-tabs>`\n */\nexport class KdTabs extends KdElement {\n static override properties = { selected: {}, key: {} };\n // Panes are assigned to slots by hand, so the light DOM is never touched.\n static override shadowRootOptions: ShadowRootInit = { ...LitElement.shadowRootOptions, slotAssignment: 'manual' };\n static override styles = [\n base,\n css`\n [role='tablist'] {\n display: flex;\n flex-wrap: wrap;\n gap: 0 22px;\n margin-bottom: 10px;\n border-bottom: 1px solid var(--kd-border, transparent);\n }\n button {\n margin: 0 0 -1px;\n padding: 6px 1px;\n border: none;\n border-bottom: 2px solid transparent;\n background: none;\n color: var(--kd-text-2, inherit);\n font: inherit;\n font-size: 13px;\n cursor: pointer;\n }\n button:hover {\n color: var(--kd-text, inherit);\n }\n /* Grafana's own active tab is underlined in this orange. */\n button[aria-selected='true'] {\n border-bottom-color: var(--kd-warning, currentColor);\n color: var(--kd-text, inherit);\n }\n .count {\n margin-left: 2px;\n color: var(--kd-text-dim, inherit);\n font-size: 11px;\n }\n `,\n ];\n\n declare selected: string | undefined;\n declare key: string | undefined;\n\n #observer: MutationObserver | undefined;\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Panes may arrive or be relabelled after the element is created.\n this.#observer ??= new MutationObserver(() => this.requestUpdate());\n this.#observer.observe(this, { childList: true, subtree: true, attributes: true, attributeFilter: ['label', 'count'] });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#observer?.disconnect();\n }\n\n get #storage(): Storage | undefined {\n try {\n return this.ownerDocument?.defaultView?.sessionStorage ?? undefined;\n } catch {\n return undefined;\n }\n }\n\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (!changed.has('key') || !this.key) return;\n try {\n const stored = this.#storage?.getItem(`kd-tabs:${this.key}`);\n if (stored !== null && stored !== undefined) this.selected = stored;\n } catch {\n // Storage can be blocked; the tab simply is not remembered.\n }\n }\n\n #panes(): Element[] {\n return [...this.children];\n }\n\n #index(panes: Element[]): number {\n const selected = this.selected;\n if (selected === undefined || selected === null || selected === '') return 0;\n const byLabel = panes.findIndex((pane, i) => label(pane, i) === selected);\n if (byLabel >= 0) return byLabel;\n const n = Number(selected);\n return Number.isInteger(n) && n >= 0 && n < panes.length ? n : 0;\n }\n\n #select(panes: Element[], index: number): void {\n const name = label(panes[index], index);\n if (this.key) {\n try {\n this.#storage?.setItem(`kd-tabs:${this.key}`, name);\n } catch {\n // as above\n }\n }\n if (name === this.selected) return;\n this.selected = name;\n this.dispatchEvent(new CustomEvent('change', { detail: { label: name, index }, bubbles: true, composed: true }));\n }\n\n override render() {\n const panes = this.#panes();\n if (!panes.length) return nothing;\n const open = this.#index(panes);\n return html`<div role=\"tablist\">\n ${panes.map((pane, i) => {\n const count = pane.getAttribute('count');\n return html`<button\n type=\"button\"\n role=\"tab\"\n aria-selected=${i === open ? 'true' : 'false'}\n @click=${() => this.#select(panes, i)}\n >\n ${label(pane, i)}${count ? html`<span class=\"count\">${count}</span>` : nothing}\n </button>`;\n })}\n </div>\n ${panes.map((_, i) => html`<div role=\"tabpanel\" ?hidden=${i !== open}><slot></slot></div>`)}`;\n }\n\n // One slot per pane, assigned by hand; switching tabs only hides the others.\n protected override updated(): void {\n const slots = this.renderRoot.querySelectorAll('slot');\n this.#panes().forEach((pane, i) => slots[i]?.assign(pane));\n }\n}\n\ndefine('kd-tabs', KdTabs);\n","import { css, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\nimport { renderIcon, safeHref } from '../parts';\n\n/**\n * The chat tile's header link: a large icon (an image URL or an emoji) over a\n * small label. An `http(s)` link opens in a new tab.\n *\n * `<kd-tile icon=\"🤖\" label=\"Ask\" href=\"https://…\"></kd-tile>`\n */\nexport class KdTile extends KdElement {\n static override properties = { icon: {}, label: {}, href: {} };\n static override styles = [\n base,\n css`\n a,\n div {\n display: block;\n padding-top: 6px;\n color: inherit;\n text-align: center;\n text-decoration: none;\n }\n .icon {\n display: block;\n height: 30px;\n margin: 0 auto;\n font-size: 30px;\n line-height: 1;\n }\n .label {\n display: block;\n margin-top: 6px;\n color: var(--kd-text-2, inherit);\n font-size: 12px;\n }\n `,\n ];\n\n declare icon: string | undefined;\n declare label: string | undefined;\n declare href: string | undefined;\n\n override render() {\n const body = html`${renderIcon(this.icon)}<span class=\"label\">${this.label ?? ''}</span>`;\n const href = safeHref(this.href);\n if (!href) return html`<div>${body}</div>`;\n const external = /^https?:/i.test(href);\n return html`<a\n href=${href}\n target=${ifDefined(external ? '_blank' : undefined)}\n rel=${ifDefined(external ? 'noopener' : undefined)}\n >${body}</a\n >`;\n }\n}\n\ndefine('kd-tile', KdTile);\n"],"ignoreList":[1,11,12],"mappings":"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"}
1
+ {"version":3,"file":"kd-BeZbw7cp.js","names":["o","t","nothing","nothing","ifDefined","nothing","ifDefined","nothing","nothing","i","r","t","s","nothing","styleMap","nothing","nothing","ifDefined","nothing","LitElement","nothing","ifDefined","i$3","b","i$2","base","A","json","E","KdElement","define","kdjson","value","registerHelpers","o$1","o","RESERVED","NUMBER","DATE","INDICATOR","CONTROL","needsQuotes","s","quote","token","isBlock","v","isLiteral","scalar","literal","chomp","lines","l","inline","gap","head","header","inner","block","item","sub","indent","out","key","yamlLines","toYaml","line","t","KdData","pre","i","n","summary","TONES","tone","fallback","tones","IMAGE","renderIcon","cls","safeHref","href","here","loc","win","m","linkUrl","link","at","cut","path","params","name","vars","k","query","runtimes","preload","rt","navigate","event","service","to","url","prefix","KdLink","d","body","title","#click","#refresh","KdPill","isEmpty","cell","renderCell","c","cellStyles","KdBar","chips","chain","group","groups","raw","data","g","a","jsonValue","parsed","CLIP","KdGroups","#tree","#pills","e","KdMask","changed","i$1","t$1","r","number","KdMeter","marks","unit","largest","scale","clamp","f","fill","KdSheet","rows","row","STATUS","glyph","KdSteps","steps","step","KdTable","cols","columns","align","col","label","pane","KdTabs","#observer","#storage","stored","selected","byLabel","panes","index","#panes","open","#index","count","#select","slots","KdTile","external"],"sources":["../../src/kd/helpers.ts","../../node_modules/lit-html/directives/if-defined.js","../../src/kd/yaml.ts","../../src/kd/elements/data.ts","../../src/kd/parts.ts","../../src/kd/elements/link.ts","../../src/kd/elements/pill.ts","../../src/kd/cell.ts","../../src/kd/elements/bar.ts","../../src/kd/elements/groups.ts","../../src/kd/elements/mask.ts","../../node_modules/lit-html/directive.js","../../node_modules/lit-html/directives/style-map.js","../../src/kd/elements/meter.ts","../../src/kd/elements/sheet.ts","../../src/kd/elements/steps.ts","../../src/kd/elements/table.ts","../../src/kd/elements/tabs.ts","../../src/kd/elements/tile.ts"],"sourcesContent":["/**\n * Data for a JSON attribute. Double-stash it so Handlebars escapes the quotes:\n * `<kd-table data=\"{{kdjson rows}}\">`. Never triple-stash JSON into an\n * attribute: one `'` in the data turns the whole tag into escaped text.\n */\nexport function kdjson(value: unknown): string {\n return JSON.stringify(value ?? null);\n}\n\ninterface Handlebars {\n registerHelper(name: string, helper: (...args: unknown[]) => unknown): void;\n}\n\n/** Registers `kdjson` on Business Text's `context.handlebars`. */\nexport function registerHelpers(handlebars: Handlebars): void {\n handlebars.registerHelper('kdjson', (value) => kdjson(value));\n}\n","import{nothing as t}from\"../lit-html.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const o=o=>o??t;export{o as ifDefined};\n//# sourceMappingURL=if-defined.js.map\n","// A small YAML dumper for JSON values: block style, kubectl's layout (a list\n// sits at its key's indent), quotes only where a plain scalar would be misread.\n\n/** What a token is, for highlighting. Punctuation and indentation are `plain`. */\nexport type YamlKind = 'key' | 'str' | 'num' | 'bool' | 'null' | 'plain';\n\nexport interface YamlToken {\n kind: YamlKind;\n text: string;\n}\n\n/** One output line: its indentation (with any `- ` markers), then its tokens. */\nexport interface YamlLine {\n prefix: string;\n tokens: YamlToken[];\n}\n\nconst RESERVED = /^(~|null|true|false|yes|no|on|off|y|n)$/i;\nconst NUMBER =\n /^([-+]?(\\.\\d+|\\d[\\d_]*(\\.\\d*)?)([eE][-+]?\\d+)?|0x[0-9a-f]+|0o[0-7]+|[-+]?\\.(inf|nan)|[-+]?\\d+(:[0-5]?\\d)+(\\.\\d*)?)$/i;\nconst DATE = /^\\d{4}-\\d\\d?-\\d\\d?([Tt ]|$)/;\nconst INDICATOR = /^([,[\\]{}#&*!|>'\"%@`]|[-?:](\\s|$))/;\nconst CONTROL = /[\\u0000-\\u0008\\u000b-\\u001f\\u007f]/;\n\nfunction needsQuotes(s: string): boolean {\n return (\n s === '' ||\n RESERVED.test(s) ||\n NUMBER.test(s) ||\n DATE.test(s) ||\n INDICATOR.test(s) ||\n /^\\s|\\s$/.test(s) ||\n s.includes(': ') ||\n s.includes(' #') ||\n s.endsWith(':') ||\n s.includes('\\n') ||\n s.includes('\\t') ||\n CONTROL.test(s)\n );\n}\n\n/** A string as a YAML scalar, double-quoted (JSON's escapes are YAML's) only when it must be. */\nexport function quote(s: string): string {\n return needsQuotes(s) ? JSON.stringify(s) : s;\n}\n\nconst token = (kind: YamlKind, text: string): YamlToken => ({ kind, text });\n\nfunction isBlock(value: unknown): value is object {\n if (Array.isArray(value)) return value.length > 0;\n return value !== null && typeof value === 'object' && Object.values(value).some((v) => v !== undefined);\n}\n\nfunction isLiteral(value: unknown): value is string {\n return typeof value === 'string' && value.includes('\\n') && !CONTROL.test(value);\n}\n\nfunction scalar(value: unknown): YamlToken {\n if (value === null || value === undefined) return token('null', 'null');\n if (typeof value === 'boolean') return token('bool', String(value));\n if (typeof value === 'number' || typeof value === 'bigint') return token('num', String(value));\n if (Array.isArray(value)) return token('plain', '[]');\n if (typeof value === 'object') return token('plain', '{}');\n return token('str', quote(String(value)));\n}\n\n// A multi-line string as a literal block: `|` keeps one final newline, `|-`\n// none and `|+` all; a leading space on the first line needs the indent stated.\nfunction literal(s: string): { header: string; lines: string[] } {\n const chomp = s.endsWith('\\n') ? (s.endsWith('\\n\\n') ? '+' : '') : '-';\n const body = chomp === '-' ? s : s.slice(0, -1);\n const lines = body.split('\\n');\n const first = lines.find((l) => l !== '');\n return { header: `|${first?.startsWith(' ') ? '2' : ''}${chomp}`, lines };\n}\n\n// A scalar, an empty collection or a literal block after `head` (`key:` or nothing).\nfunction inline(prefix: string, head: YamlToken[], value: unknown, inner: string): YamlLine[] {\n const gap = head.length ? [token('plain', ' ')] : [];\n if (isLiteral(value)) {\n const { header, lines } = literal(value);\n return [\n { prefix, tokens: [...head, ...gap, token('plain', header)] },\n ...lines.map((l) => ({ prefix: l ? inner : '', tokens: [token('str', l)] })),\n ];\n }\n return [{ prefix, tokens: [...head, ...gap, scalar(value)] }];\n}\n\n// A non-empty object or array at `indent`.\nfunction block(value: object, indent: string, out: YamlLine[]): void {\n if (Array.isArray(value)) {\n for (const item of value) {\n if (isBlock(item)) {\n const sub: YamlLine[] = [];\n block(item, `${indent} `, sub);\n sub[0].prefix = `${indent}- ${sub[0].prefix.slice(indent.length + 2)}`;\n out.push(...sub);\n } else {\n out.push(...inline(`${indent}- `, [], item, `${indent} `));\n }\n }\n return;\n }\n for (const [key, item] of Object.entries(value)) {\n if (item === undefined) continue;\n const head = [token('key', quote(key)), token('plain', ':')];\n if (isBlock(item)) {\n out.push({ prefix: indent, tokens: head });\n block(item, Array.isArray(item) ? indent : `${indent} `, out);\n } else {\n out.push(...inline(indent, head, item, `${indent} `));\n }\n }\n}\n\n/** A JSON value as YAML lines of tokens, for rendering with highlighting. */\nexport function yamlLines(value: unknown): YamlLine[] {\n const out: YamlLine[] = [];\n if (isBlock(value)) block(value, '', out);\n else out.push(...inline('', [], value, ' '));\n return out;\n}\n\n/** A JSON value as YAML text. */\nexport function toYaml(value: unknown): string {\n return yamlLines(value)\n .map((line) => line.prefix + line.tokens.map((t) => t.text).join(''))\n .join('\\n');\n}\n","import { css, html, nothing } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { yamlLines } from '../yaml';\n\n/**\n * Any JSON value as YAML. An object or array longer than `fold` lines (default\n * 10; 0 never folds) collapses under a \"{ } n keys\" / \"[ ] n items\" line.\n *\n * `<kd-data data=\"{{kdjson spec}}\" fold=\"20\">`\n */\nexport class KdData extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n fold: { type: Number },\n };\n static override styles = [\n base,\n css`\n pre {\n margin: 0;\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n line-height: 1.5;\n white-space: pre-wrap;\n overflow-wrap: anywhere;\n }\n .key {\n color: color-mix(in srgb, var(--kd-info, currentColor) 75%, var(--kd-text, currentColor));\n }\n .str {\n color: color-mix(in srgb, var(--kd-success, currentColor) 70%, var(--kd-text, currentColor));\n }\n .num {\n color: color-mix(in srgb, var(--kd-warning, currentColor) 55%, var(--kd-text, currentColor));\n }\n .bool,\n .null {\n color: color-mix(in srgb, var(--kd-primary, currentColor) 70%, var(--kd-text, currentColor));\n }\n summary {\n width: max-content;\n color: var(--kd-text-2, inherit);\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n cursor: pointer;\n list-style: none;\n }\n summary::-webkit-details-marker {\n display: none;\n }\n summary::before {\n content: '▸ ';\n }\n details[open] > summary::before {\n content: '▾ ';\n }\n details > pre {\n margin-top: 2px;\n }\n `,\n ];\n\n declare data: unknown;\n declare fold: number;\n\n constructor() {\n super();\n this.fold = 10;\n }\n\n override render() {\n const value = this.data;\n if (value === undefined) return nothing;\n const lines = yamlLines(value);\n const pre = html`<pre>${lines.map(\n (line, i) =>\n html`${i ? '\\n' : ''}${line.prefix}${line.tokens.map((t) =>\n t.kind === 'plain' ? t.text : html`<span class=${t.kind}>${t.text}</span>`,\n )}`,\n )}</pre>`;\n if (!(this.fold > 0 && lines.length > this.fold && value !== null && typeof value === 'object')) return pre;\n const n = Object.keys(value).length;\n const summary = Array.isArray(value) ? `[ ] ${n} item${n === 1 ? '' : 's'}` : `{ } ${n} key${n === 1 ? '' : 's'}`;\n return html`<details><summary>${summary}</summary>${pre}</details>`;\n }\n}\n\ndefine('kd-data', KdData);\n","// Small pieces several elements share: tones, icons and link safety.\nimport { css, html, nothing, type TemplateResult } from 'lit';\n\n/** A semantic colour. Each maps to `--kd-<tone>`; neutral is the secondary text colour. */\nexport type Tone = 'primary' | 'success' | 'warning' | 'error' | 'info' | 'neutral';\n\nconst TONES = new Set<string>(['primary', 'success', 'warning', 'error', 'info', 'neutral']);\n\n/** `value` when it names a tone, else `fallback`. */\nexport function tone(value: unknown, fallback: Tone = 'neutral'): Tone {\n return typeof value === 'string' && TONES.has(value) ? (value as Tone) : fallback;\n}\n\n/**\n * Tone classes. Each sets `--tone` (the colour), `--tone-ink` (text in that\n * colour, pulled towards the text colour so it reads on either theme) and\n * `--tone-line` (a border in that colour).\n */\nexport const tones = css`\n .primary {\n --tone: var(--kd-primary, currentColor);\n }\n .success {\n --tone: var(--kd-success, currentColor);\n }\n .warning {\n --tone: var(--kd-warning, currentColor);\n }\n .error {\n --tone: var(--kd-error, currentColor);\n }\n .info {\n --tone: var(--kd-info, currentColor);\n }\n .primary,\n .success,\n .warning,\n .error,\n .info {\n --tone-ink: color-mix(in srgb, var(--tone) 75%, var(--kd-text, currentColor));\n --tone-line: color-mix(in srgb, var(--tone) 50%, transparent);\n }\n .neutral {\n --tone: var(--kd-text-2, currentColor);\n --tone-ink: var(--kd-text-2, currentColor);\n --tone-line: var(--kd-border-strong, currentColor);\n }\n`;\n\nconst IMAGE = /^(https?:|data:image\\/|\\/|\\.\\.?\\/)/i;\n\n/** An icon that is either an image URL or a short text such as an emoji. */\nexport function renderIcon(value: string | null | undefined, cls = 'icon'): TemplateResult | typeof nothing {\n if (!value) return nothing;\n return IMAGE.test(value) ? html`<img class=${cls} src=${value} alt=\"\" />` : html`<span class=${cls}>${value}</span>`;\n}\n\n/** `href` unless it is a script or data URL, which data must never smuggle into a link. */\nexport function safeHref(href: string | null | undefined): string | undefined {\n if (href == null || href === '') return undefined;\n return /^\\s*(javascript|vbscript|data):/i.test(href) ? undefined : href;\n}\n","import { css, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { renderIcon, safeHref } from '../parts';\n\n/** Dashboard variables, without the `var-` prefix (one is added when missing). A list repeats the variable. */\nexport type Vars = Record<string, string | number | boolean | null | undefined | readonly (string | number | boolean)[]>;\n\nexport interface LinkData {\n /** A dashboard uid (optionally `uid/slug`, optionally followed by `?query`, as a `back` value is). */\n dashboard?: string;\n /** A plain URL, used when there is no `dashboard`. */\n href?: string;\n vars?: Vars;\n text?: string;\n /** An image URL or an emoji. */\n icon?: string;\n /** Tooltip. */\n title?: string;\n /** Pass this dashboard and its variables as `var-back`, so the target can link back. */\n back?: boolean;\n}\n\ninterface Here {\n /** Grafana's sub-path, the part of the path before `/d/`. */\n prefix: string;\n uid?: string;\n params: URLSearchParams;\n}\n\n// The current dashboard, read from the page URL. Outside a dashboard (or\n// outside Grafana) there is no uid and no time range to keep.\nfunction here(win: Window | null | undefined): Here {\n try {\n const loc = win?.location;\n const m = /^(.*?)\\/d\\/([^/?#]+)/.exec(loc?.pathname ?? '');\n return {\n prefix: m?.[1] ?? '',\n uid: m ? decodeURIComponent(m[2]) : undefined,\n params: new URLSearchParams(loc?.search ?? ''),\n };\n } catch {\n return { prefix: '', params: new URLSearchParams() };\n }\n}\n\n/**\n * The URL a link goes to: `<sub-path>/d/<dashboard>?var-k=v…` keeping the\n * current `from`/`to`, plus `var-back=<this uid>?<this page's var-* query>`\n * when `back` is set; or the plain `href`. Undefined when there is neither.\n */\nexport function linkUrl(link: LinkData, win?: Window | null): string | undefined {\n if (!link.dashboard) return safeHref(link.href);\n const at = here(win);\n const cut = link.dashboard.indexOf('?');\n const path = cut < 0 ? link.dashboard : link.dashboard.slice(0, cut);\n const params = new URLSearchParams(cut < 0 ? '' : link.dashboard.slice(cut + 1));\n for (const [name, value] of Object.entries(link.vars ?? {})) {\n if (value === null || value === undefined) continue;\n const key = name.startsWith('var-') ? name : `var-${name}`;\n params.delete(key);\n for (const v of Array.isArray(value) ? value : [value]) params.append(key, String(v));\n }\n for (const name of ['from', 'to']) {\n const value = at.params.get(name);\n if (value !== null && !params.has(name)) params.set(name, value);\n }\n if (link.back && at.uid) {\n const vars = new URLSearchParams([...at.params].filter(([k]) => k.startsWith('var-'))).toString();\n params.set('var-back', vars ? `${at.uid}?${vars}` : at.uid);\n }\n const query = params.toString();\n return `${at.prefix}/d/${path}${query ? `?${query}` : ''}`;\n}\n\ninterface Runtime {\n locationService?: { push(to: string): void };\n}\ntype GrafanaWindow = Window & { System?: { import?(id: string): Promise<unknown> } };\n\nconst runtimes = new WeakMap<Window, Runtime | null>();\n\n// Grafana turns clicks on its own links into in-app navigation, but it finds\n// the anchor from the event target, which a shadow root retargets to the host.\n// So a kd-link does it itself, through the same location service; until the\n// runtime has loaded (or outside Grafana) the browser simply follows the link.\nfunction preload(win: GrafanaWindow | null | undefined): void {\n if (!win || runtimes.has(win) || !win.System?.import) return;\n runtimes.set(win, null);\n win.System.import('@grafana/runtime').then(\n (rt) => runtimes.set(win, rt as Runtime),\n () => {},\n );\n}\n\nfunction navigate(win: Window | null | undefined, url: string, event: MouseEvent): void {\n if (!win || event.defaultPrevented || event.button !== 0) return;\n if (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey) return;\n const service = runtimes.get(win)?.locationService;\n if (!service) return;\n const to = new URL(url, win.location.href);\n if (to.origin !== win.location.origin) return;\n const { prefix } = here(win);\n const path = prefix && to.pathname.startsWith(prefix) ? to.pathname.slice(prefix.length) : to.pathname;\n event.preventDefault();\n service.push(path + to.search + to.hash);\n}\n\n/**\n * A link to a dashboard (or any URL) with an optional icon. Set `data`, or the\n * attributes of the same names (`vars` as JSON, `back` as a boolean). Without\n * `text`, the slot is the label.\n *\n * `<kd-link dashboard=\"k8s-pod\" vars='{\"pod\":\"web-0\"}' back>web-0</kd-link>`\n */\nexport class KdLink extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n dashboard: {},\n href: {},\n vars: { converter: json },\n text: {},\n icon: {},\n back: { type: Boolean },\n };\n static override styles = [\n base,\n css`\n :host {\n display: inline;\n }\n /* One line: a long name ends in an ellipsis with the full text on hover.\n A table caps links with --kd-link-max, since 100% means nothing to an\n auto-layout column. */\n a,\n span.link {\n display: inline-flex;\n align-items: baseline;\n max-width: var(--kd-link-max, 100%);\n min-width: 0;\n vertical-align: bottom;\n }\n .text {\n min-width: 0;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n }\n a {\n color: var(--kd-link, inherit);\n text-decoration: none;\n }\n a:hover {\n text-decoration: underline;\n }\n .icon {\n width: 16px;\n height: 16px;\n margin-right: 4px;\n vertical-align: -3px;\n }\n `,\n ];\n\n declare data: LinkData | undefined;\n declare dashboard: string | undefined;\n declare href: string | undefined;\n declare vars: Vars | undefined;\n declare text: string | undefined;\n declare icon: string | undefined;\n declare back: boolean | undefined;\n\n /** The link, `data` taking precedence over the attributes field by field. */\n get link(): LinkData {\n const d = this.data ?? {};\n return {\n dashboard: d.dashboard ?? this.dashboard,\n href: d.href ?? this.href,\n vars: d.vars ?? this.vars,\n text: d.text ?? this.text,\n icon: d.icon ?? this.icon,\n title: d.title,\n back: d.back ?? this.back,\n };\n }\n\n override connectedCallback(): void {\n super.connectedCallback();\n preload(this.ownerDocument?.defaultView);\n }\n\n // Variables can change without the panel re-rendering this element, so the\n // URL is rebuilt when the pointer or focus arrives and again on the click.\n #refresh = () => this.requestUpdate();\n\n #click = (event: MouseEvent) => {\n const win = this.ownerDocument?.defaultView;\n const url = linkUrl(this.link, win);\n if (url === undefined) return;\n (event.currentTarget as HTMLAnchorElement).setAttribute('href', url);\n navigate(win, url, event);\n };\n\n override render() {\n const link = this.link;\n const url = linkUrl(link, this.ownerDocument?.defaultView);\n // The text carries its full self on hover (it may be cut short); the link's\n // own title (a kind, say) shows over the icon.\n const body = html`${renderIcon(link.icon)}<span class=\"text\" title=${ifDefined(link.text)}\n ><slot>${link.text ?? ''}</slot></span\n >`;\n const title = link.title ?? link.text;\n if (url === undefined) return html`<span class=\"link\" title=${ifDefined(title)}>${body}</span>`;\n return html`<a\n href=${url}\n title=${ifDefined(title)}\n @click=${this.#click}\n @mouseenter=${this.#refresh}\n @focus=${this.#refresh}\n >${body}</a\n >`;\n }\n}\n\ndefine('kd-link', KdLink);\n","import { css, html } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\nimport { tone, tones, type Tone } from '../parts';\n\n/**\n * A pill or badge. The slot is its text; `title` is the native tooltip.\n *\n * `<kd-pill tone=\"success\" title=\"all containers ready\">Running</kd-pill>`\n */\nexport class KdPill extends KdElement {\n static override properties = { tone: {} };\n static override styles = [\n base,\n tones,\n css`\n :host {\n display: inline-block;\n margin: 1px 4px 1px 0;\n vertical-align: baseline;\n }\n span {\n display: inline-block;\n padding: 0 8px;\n border: 1px solid var(--tone-line);\n border-radius: 10px;\n background: color-mix(in srgb, var(--tone) 14%, transparent);\n color: var(--tone-ink);\n font-size: 11px;\n line-height: 18px;\n white-space: nowrap;\n }\n `,\n ];\n\n declare tone: Tone | undefined;\n\n override render() {\n return html`<span class=${tone(this.tone)}><slot></slot></span>`;\n }\n}\n\ndefine('kd-pill', KdPill);\n","// What a sheet value or a table cell may be, and how each shape renders.\nimport { css, html, nothing, type TemplateResult } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport './elements/data';\nimport './elements/link';\nimport './elements/pill';\nimport type { Vars } from './elements/link';\nimport type { Tone } from './parts';\n\nexport type { Tone };\n\n/** A pill: `<kd-pill>`. */\nexport interface PillCell {\n text: string;\n tone?: Tone;\n title?: string;\n}\n\n/** A plain link: `<kd-link>` with an `href`. */\nexport interface HrefCell {\n href: string;\n text: string;\n icon?: string;\n title?: string;\n}\n\n/** A dashboard link: `<kd-link>`. */\nexport interface DashboardCell {\n dashboard: string;\n vars?: Vars;\n text: string;\n icon?: string;\n title?: string;\n back?: boolean;\n}\n\n/** Any JSON value as YAML: `<kd-data>`. */\nexport interface DataCell {\n data: unknown;\n}\n\n/** Monospace text. */\nexport interface CodeCell {\n code: string;\n}\n\n/** A scalar is text; an array renders its cells inline, wrapped. */\nexport type Cell =\n | string\n | number\n | boolean\n | null\n | undefined\n | PillCell\n | HrefCell\n | DashboardCell\n | DataCell\n | CodeCell\n | Cell[];\n\n/** Whether a cell has nothing to show. */\nexport function isEmpty(cell: Cell): boolean {\n return cell === null || cell === undefined || cell === '' || (Array.isArray(cell) && cell.every(isEmpty));\n}\n\n/** One cell. An object of no known shape is shown as data. */\nexport function renderCell(cell: Cell): TemplateResult | string | typeof nothing {\n if (cell === null || cell === undefined) return nothing;\n if (Array.isArray(cell)) {\n return html`<span class=\"cells\">${cell.filter((c) => !isEmpty(c)).map((c) => html`<span>${renderCell(c)}</span>`)}</span>`;\n }\n if (typeof cell !== 'object') return String(cell);\n if ('dashboard' in cell || 'href' in cell) return html`<kd-link .data=${cell}></kd-link>`;\n if ('data' in cell) return html`<kd-data .data=${cell.data}></kd-data>`;\n if ('code' in cell) return html`<code>${String(cell.code)}</code>`;\n if ('text' in cell) {\n return html`<kd-pill tone=${ifDefined(cell.tone)} title=${ifDefined(cell.title)}>${String(cell.text)}</kd-pill>`;\n }\n return html`<kd-data .data=${cell}></kd-data>`;\n}\n\n/** Styles an element that renders cells adds to its own. */\nexport const cellStyles = css`\n .cells {\n display: inline-flex;\n flex-wrap: wrap;\n align-items: baseline;\n gap: 2px 6px;\n }\n code {\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n overflow-wrap: anywhere;\n }\n`;\n","import { css, html, nothing } from 'lit';\n\nimport { cellStyles, isEmpty, renderCell, type Cell } from '../cell';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { renderIcon } from '../parts';\n\nexport interface BarData {\n /** An image URL or an emoji. */\n icon?: string;\n /** The line above the title, e.g. the kind and namespace. */\n eyebrow?: Cell;\n title: string;\n /** Pills beside the title. */\n chips?: Cell[];\n /** A breadcrumb at the far end, e.g. the owner chain. */\n chain?: Cell[];\n}\n\n/**\n * A title bar or masthead.\n *\n * `el.data = { icon: '🐘', eyebrow: 'StatefulSet', title: 'postgresql', chips: [{ text: '1/1', tone: 'success' }] }`\n */\nexport class KdBar extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n cellStyles,\n css`\n .bar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: 8px 16px;\n padding: 0 4px;\n }\n img.icon {\n width: 42px;\n height: 42px;\n }\n span.icon {\n font-size: 34px;\n line-height: 1;\n }\n .eyebrow {\n color: var(--kd-text-2, inherit);\n font-size: 11px;\n letter-spacing: 0.1em;\n text-transform: uppercase;\n }\n .title {\n font-size: 22px;\n font-weight: 500;\n line-height: 1.2;\n overflow-wrap: anywhere;\n }\n .grow {\n flex: 1;\n }\n .chain {\n font-size: 13px;\n }\n .sep {\n margin: 0 6px;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: BarData | undefined;\n\n override render() {\n const d = this.data;\n if (!d) return nothing;\n const chips = (d.chips ?? []).filter((c) => !isEmpty(c));\n const chain = (d.chain ?? []).filter((c) => !isEmpty(c));\n return html`<div class=\"bar\">\n ${renderIcon(d.icon)}\n <div class=\"id\">\n ${isEmpty(d.eyebrow) ? nothing : html`<div class=\"eyebrow\">${renderCell(d.eyebrow)}</div>`}\n <div class=\"title\">${d.title ?? ''}</div>\n </div>\n ${chips.length ? html`<div class=\"chips\">${chips.map((c) => renderCell(c))}</div>` : nothing}\n <div class=\"grow\"></div>\n ${chain.length\n ? html`<nav class=\"chain\">\n ${chain.map((c, i) => html`${i ? html`<span class=\"sep\">›</span>` : nothing}${renderCell(c)}`)}\n </nav>`\n : nothing}\n </div>`;\n }\n}\n\ndefine('kd-bar', KdBar);\n","import { css, html, nothing } from 'lit';\n\nimport './data';\nimport './pill';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\n\n/** A string map, such as labels or annotations. */\nexport type GroupsData = Record<string, string>;\n\ninterface Group {\n prefix: string;\n entries: { key: string; name: string; value: string }[];\n}\n\n// Grouped by the prefix before \"/\"; unprefixed keys first, then by prefix.\nfunction group(data: GroupsData): Group[] {\n const groups = new Map<string, Group>();\n for (const [key, raw] of Object.entries(data)) {\n const cut = key.indexOf('/');\n const prefix = cut < 0 ? '' : key.slice(0, cut);\n const value = raw === null || raw === undefined ? '' : typeof raw === 'string' ? raw : JSON.stringify(raw);\n let g = groups.get(prefix);\n if (!g) groups.set(prefix, (g = { prefix, entries: [] }));\n g.entries.push({ key, name: key.slice(cut + 1), value });\n }\n return [...groups.values()].sort((a, b) => (a.prefix < b.prefix ? -1 : a.prefix > b.prefix ? 1 : 0));\n}\n\n/** A value that is a JSON object or array, parsed; undefined for anything else. */\nexport function jsonValue(value: string): object | undefined {\n if (!/^\\s*[[{]/.test(value)) return undefined;\n try {\n const parsed: unknown = JSON.parse(value);\n return parsed !== null && typeof parsed === 'object' ? parsed : undefined;\n } catch {\n return undefined;\n }\n}\n\nconst CLIP = 600;\n\n/**\n * A string map grouped by key prefix: as pills (`mode=\"pills\"`, the default,\n * for labels) or as a key/value tree (`mode=\"tree\"`, for annotations, where a\n * value holding a JSON object or array is shown as folded YAML).\n *\n * `<kd-groups mode=\"tree\" data=\"{{kdjson metadata.annotations}}\">`\n */\nexport class KdGroups extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n mode: {},\n };\n static override styles = [\n base,\n css`\n .group + .group {\n margin-top: 12px;\n }\n div.head,\n tr.head td {\n padding-bottom: 3px;\n border-bottom: 1px solid var(--kd-border, transparent);\n color: var(--kd-text-2, inherit);\n font-family: var(--kd-font-mono, monospace);\n font-size: 11px;\n }\n div.head {\n margin-bottom: 6px;\n }\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n td {\n padding: 2px 12px 2px 0;\n vertical-align: top;\n }\n tr.head td {\n padding-top: 12px;\n }\n tr.head:first-child td {\n padding-top: 0;\n }\n tr.head + tr td {\n padding-top: 6px;\n }\n .k {\n white-space: nowrap;\n }\n code {\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n }\n .twig {\n margin: 0 8px 0 4px;\n color: var(--kd-text-dim, inherit);\n font-family: var(--kd-font-mono, monospace);\n }\n .v {\n width: 100%;\n color: color-mix(in srgb, var(--kd-success, currentColor) 70%, var(--kd-text, currentColor));\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n overflow-wrap: anywhere;\n word-break: break-word;\n }\n .none {\n padding: 8px 0;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: GroupsData | undefined;\n declare mode: 'pills' | 'tree' | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const groups = group(d);\n if (!groups.length) return html`<div class=\"none\">none</div>`;\n return this.mode === 'tree' ? this.#tree(groups) : this.#pills(groups);\n }\n\n #pills(groups: Group[]) {\n return groups.map(\n (g) => html`<div class=\"group\">\n ${g.prefix ? html`<div class=\"head\">${g.prefix}</div>` : nothing}\n <div>\n ${g.entries.map(\n (e) => html`<kd-pill tone=\"info\" title=${e.key}>${e.value === '' ? e.name : `${e.name}=${e.value}`}</kd-pill>`,\n )}\n </div>\n </div>`,\n );\n }\n\n #tree(groups: Group[]) {\n return html`<table>\n <tbody>\n ${groups.map(\n (g) => html`${g.prefix ? html`<tr class=\"head\"><td colspan=\"2\">${g.prefix}</td></tr>` : nothing}\n ${g.entries.map((e, i) => {\n const parsed = jsonValue(e.value);\n return html`<tr>\n <td class=\"k\">\n ${g.prefix ? html`<span class=\"twig\">${i === g.entries.length - 1 ? '└' : '├'}</span>` : nothing}<code\n >${e.name}</code\n >\n </td>\n <td class=\"v\">\n ${parsed\n ? html`<kd-data .data=${parsed}></kd-data>`\n : e.value.length > CLIP\n ? `${e.value.slice(0, CLIP)} …`\n : e.value}\n </td>\n </tr>`;\n })}`,\n )}\n </tbody>\n </table>`;\n }\n}\n\ndefine('kd-groups', KdGroups);\n","import { css, html, type PropertyValues } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\n\n/**\n * A secret value, hidden until clicked. The value never reaches a tooltip, the\n * console or any other attribute, and the dots do not give away its length.\n *\n * `<kd-mask value=\"{{password}}\"></kd-mask>`\n */\nexport class KdMask extends KdElement {\n static override properties = { value: {}, shown: { state: true } };\n static override styles = [\n base,\n css`\n :host {\n display: inline-block;\n }\n button {\n padding: 0;\n border: none;\n background: none;\n color: inherit;\n font: inherit;\n cursor: pointer;\n }\n .dots {\n color: var(--kd-text-2, inherit);\n letter-spacing: 0.1em;\n }\n code {\n font-family: var(--kd-font-mono, monospace);\n font-size: 12px;\n overflow-wrap: anywhere;\n white-space: pre-wrap;\n user-select: all;\n }\n .hide {\n margin-left: 6px;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare value: string | undefined;\n declare shown: boolean;\n\n constructor() {\n super();\n this.shown = false;\n }\n\n // A new value starts hidden again.\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (changed.has('value') && changed.get('value') !== undefined) this.shown = false;\n }\n\n override render() {\n if (!this.shown) {\n return html`<button type=\"button\" aria-label=\"show\" @click=${() => (this.shown = true)}>\n <span class=\"dots\">••••••••</span>\n </button>`;\n }\n return html`<code>${this.value ?? ''}</code\n ><button type=\"button\" class=\"hide\" aria-label=\"hide\" @click=${() => (this.shown = false)}>×</button>`;\n }\n}\n\ndefine('kd-mask', KdMask);\n","/**\n * @license\n * Copyright 2017 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */\nconst t={ATTRIBUTE:1,CHILD:2,PROPERTY:3,BOOLEAN_ATTRIBUTE:4,EVENT:5,ELEMENT:6},e=t=>(...e)=>({_$litDirective$:t,values:e});class i{constructor(t){}get _$AU(){return this._$AM._$AU}_$AT(t,e,i){this._$Ct=t,this._$AM=e,this._$Ci=i}_$AS(t,e){return this.update(t,e)}update(t,e){return this.render(...e)}}export{i as Directive,t as PartType,e as directive};\n//# sourceMappingURL=directive.js.map\n","import{noChange as t}from\"../lit-html.js\";import{directive as e,Directive as r,PartType as s}from\"../directive.js\";\n/**\n * @license\n * Copyright 2018 Google LLC\n * SPDX-License-Identifier: BSD-3-Clause\n */const n=\"important\",i=\" !\"+n,o=e(class extends r{constructor(t){if(super(t),t.type!==s.ATTRIBUTE||\"style\"!==t.name||t.strings?.length>2)throw Error(\"The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.\")}render(t){return Object.keys(t).reduce((e,r)=>{const s=t[r];return null==s?e:e+`${r=r.includes(\"-\")?r:r.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,\"-$&\").toLowerCase()}:${s};`},\"\")}update(e,[r]){const{style:s}=e.element;if(void 0===this.ft)return this.ft=new Set(Object.keys(r)),this.render(r);for(const t of this.ft)null==r[t]&&(this.ft.delete(t),t.includes(\"-\")?s.removeProperty(t):s[t]=null);for(const t in r){const e=r[t];if(null!=e){this.ft.add(t);const r=\"string\"==typeof e&&e.endsWith(i);t.includes(\"-\")||r?s.setProperty(t,r?e.slice(0,-11):e,r?n:\"\"):s[t]=e}}return t}});export{o as styleMap};\n//# sourceMappingURL=style-map.js.map\n","import { css, html, nothing } from 'lit';\nimport { styleMap } from 'lit/directives/style-map.js';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { tone, tones, type Tone } from '../parts';\n\nexport interface MeterMark {\n label: string;\n value: number;\n tone?: Tone;\n}\n\nexport interface MeterData {\n /** The measured value; null or missing shows only the marks. */\n value?: number | null;\n /** The full scale; defaults to the largest of the value and the marks. */\n max?: number;\n /** Appended to every number as is, e.g. `Mi`, `m` or ` cores`. */\n unit?: string;\n marks?: MeterMark[];\n}\n\nconst number = (n: number) => new Intl.NumberFormat(undefined, { maximumFractionDigits: 2 }).format(n);\n\n/**\n * A value against request/limit-style marks. The fill takes the tone of the\n * highest toned mark it has reached, else primary.\n *\n * `el.data = { value: 412, unit: 'Mi', marks: [{ label: 'request', value: 256 }, { label: 'limit', value: 512, tone: 'error' }] }`\n */\nexport class KdMeter extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n tones,\n css`\n .track {\n position: relative;\n height: 8px;\n margin: 6px 0;\n border-radius: 4px;\n background: color-mix(in srgb, var(--kd-border-strong, currentColor) 35%, transparent);\n }\n .fill {\n height: 100%;\n border-radius: 4px;\n background: var(--tone);\n }\n .mark {\n position: absolute;\n top: -3px;\n bottom: -3px;\n width: 2px;\n background: var(--tone);\n box-shadow: 0 0 0 1px var(--kd-bg, transparent);\n }\n .legend {\n display: flex;\n flex-wrap: wrap;\n gap: 2px 20px;\n font-size: 12px;\n }\n .value {\n font-family: var(--kd-font-mono, monospace);\n font-size: 14px;\n }\n .legend .mark-label {\n color: var(--kd-text-2, inherit);\n }\n .legend .num {\n color: var(--tone-ink);\n font-family: var(--kd-font-mono, monospace);\n }\n .none {\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: MeterData | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const value = typeof d.value === 'number' && Number.isFinite(d.value) ? d.value : undefined;\n const marks = (d.marks ?? []).filter((m) => m && Number.isFinite(m.value));\n const unit = d.unit ?? '';\n const largest = Math.max(value ?? 0, ...marks.map((m) => m.value));\n const scale = typeof d.max === 'number' && d.max > 0 ? d.max : largest > 0 ? largest : 1;\n // A mark's left edge moves from 0 to 100% - its width, so one at the maximum stays inside.\n const clamp = (f: number) => Math.min(1, Math.max(0, f));\n const at = (n: number) => `${Math.min(100, Math.max(0, (n / scale) * 100))}%`;\n const reached = value === undefined ? [] : marks.filter((m) => m.tone && value >= m.value);\n const fill = tone(reached.sort((a, b) => b.value - a.value)[0]?.tone, 'primary');\n return html`<div\n role=\"meter\"\n aria-valuemin=\"0\"\n aria-valuemax=${scale}\n aria-valuenow=${value ?? nothing}\n >\n <div class=\"track\">\n ${value === undefined ? nothing : html`<div class=\"fill ${fill}\" style=${styleMap({ width: at(value) })}></div>`}\n ${marks.map(\n (m) =>\n html`<div\n class=\"mark ${tone(m.tone)}\"\n style=${styleMap({ left: `calc(${at(m.value)} - ${clamp(m.value / scale) * 2}px)` })}\n title=\"${m.label} ${number(m.value)}${unit}\"\n ></div>`,\n )}\n </div>\n <div class=\"legend\">\n <span class=\"value ${value === undefined ? 'none' : ''}\">${value === undefined ? '–' : `${number(value)}${unit}`}</span>\n ${marks.map(\n (m) =>\n html`<span class=${tone(m.tone)}\n ><span class=\"mark-label\">${m.label}</span> <span class=\"num\">${number(m.value)}${unit}</span></span\n >`,\n )}\n </div>\n </div>`;\n }\n}\n\ndefine('kd-meter', KdMeter);\n","import { css, html, nothing } from 'lit';\n\nimport { cellStyles, isEmpty, renderCell, type Cell } from '../cell';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\n\nexport interface SheetRow {\n key: string;\n value: Cell;\n}\n\n/** Rows in order, or a plain object (its keys in order). */\nexport type SheetData = SheetRow[] | Record<string, Cell>;\n\n/**\n * A two-column property sheet. A row whose value is empty is left out.\n *\n * `el.data = [{ key: 'Node', value: 'node-1' }, { key: 'Phase', value: { text: 'Running', tone: 'success' } }]`\n */\nexport class KdSheet extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n cellStyles,\n css`\n dl {\n display: grid;\n grid-template-columns: max-content minmax(0, 1fr);\n margin: 0;\n font-size: 13px;\n }\n dt,\n dd {\n margin: 0;\n padding: 5px 12px 5px 0;\n border-bottom: 1px solid var(--kd-border, transparent);\n }\n dt {\n color: var(--kd-text-2, inherit);\n }\n dd {\n overflow-wrap: anywhere;\n }\n `,\n ];\n\n declare data: SheetData | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const rows = Array.isArray(d) ? d : Object.entries(d).map(([key, value]) => ({ key, value }));\n return html`<dl>\n ${rows\n .filter((row) => row && !isEmpty(row.value))\n .map((row) => html`<dt>${row.key}</dt><dd>${renderCell(row.value)}</dd>`)}\n </dl>`;\n }\n}\n\ndefine('kd-sheet', KdSheet);\n","import { css, html, nothing } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\nimport { tone, tones, type Tone } from '../parts';\n\nexport type StepStatus = 'done' | 'active' | 'failed' | 'pending' | Tone;\n\nexport interface Step {\n label: string;\n status: StepStatus;\n time?: string;\n detail?: string;\n}\n\nconst STATUS: Record<string, Tone> = { done: 'success', active: 'primary', failed: 'error', pending: 'neutral' };\n\nfunction glyph(t: Tone, n: number): string {\n if (t === 'success') return '✓';\n if (t === 'error') return '✗';\n if (t === 'warning') return '!';\n return String(n);\n}\n\n/**\n * A stepper or state stripe: ordered steps, each with a status (a lifecycle\n * word or a tone), an optional time and a detail line.\n *\n * `el.data = [{ label: 'Scheduled', status: 'done', time: '2m' }, { label: 'Ready', status: 'failed', detail: 'probe failed' }]`\n */\nexport class KdSteps extends KdElement {\n static override properties = { data: { attribute: 'data', converter: json } };\n static override styles = [\n base,\n tones,\n css`\n ol {\n display: flex;\n margin: 0;\n padding: 0;\n list-style: none;\n }\n li {\n position: relative;\n flex: 1;\n min-width: 0;\n text-align: center;\n }\n li + li::before {\n content: '';\n position: absolute;\n top: 12px;\n right: 50%;\n width: 100%;\n height: 2px;\n background: var(--kd-border-strong, currentColor);\n opacity: 0.6;\n }\n li.reached::before {\n background: var(--tone);\n opacity: 1;\n }\n .dot {\n position: relative;\n z-index: 1;\n width: 26px;\n height: 26px;\n margin: 0 auto;\n border-radius: 50%;\n background: var(--tone);\n color: var(--kd-bg, inherit);\n font-size: 13px;\n font-weight: 700;\n line-height: 26px;\n }\n .neutral .dot {\n border: 2px solid var(--tone-line);\n background: var(--kd-bg, transparent);\n color: var(--kd-text-2, inherit);\n line-height: 22px;\n }\n .active .dot {\n box-shadow: 0 0 0 3px color-mix(in srgb, var(--tone) 30%, transparent);\n }\n .label {\n margin-top: 4px;\n font-size: 12px;\n }\n .time,\n .detail {\n color: var(--kd-text-2, inherit);\n font-size: 11px;\n }\n .detail {\n display: -webkit-box;\n overflow: hidden;\n -webkit-box-orient: vertical;\n -webkit-line-clamp: 2;\n overflow-wrap: anywhere;\n }\n `,\n ];\n\n declare data: Step[] | undefined;\n\n override render() {\n const steps = Array.isArray(this.data) ? this.data : [];\n if (!steps.length) return nothing;\n return html`<ol>\n ${steps.map((step, i) => {\n const t = tone(STATUS[step.status] ?? step.status);\n const reached = step.status === 'done' || step.status === 'success';\n const cls = `${t}${reached ? ' reached' : ''}${step.status === 'active' ? ' active' : ''}`;\n return html`<li class=${cls} title=${ifDefined(step.detail)}>\n <div class=\"dot\">${glyph(t, i + 1)}</div>\n <div class=\"label\">${step.label}</div>\n ${step.time ? html`<div class=\"time\">${step.time}</div>` : nothing}\n ${step.detail ? html`<div class=\"detail\">${step.detail}</div>` : nothing}\n </li>`;\n })}\n </ol>`;\n }\n}\n\ndefine('kd-steps', KdSteps);\n","import { css, html, nothing } from 'lit';\n\nimport { cellStyles, renderCell, type Cell } from '../cell';\nimport { define } from '../define';\nimport { KdElement, base, json } from '../element';\n\nexport interface TableColumn {\n key: string;\n /** Defaults to the key. */\n label?: string;\n align?: 'left' | 'center' | 'right';\n /** Keep the cell on one line (counts, times, short pills). */\n nowrap?: boolean;\n}\n\nexport interface TableData {\n /** Defaults to every key of the rows, in order of first appearance. */\n columns?: TableColumn[];\n rows: Record<string, Cell>[];\n}\n\n/**\n * A small table of cells. `data` may also be just the rows. With no rows it\n * shows `empty` (default \"none\").\n *\n * `el.data = { columns: [{ key: 'reason', label: 'Reason' }, { key: 'n', align: 'right' }], rows }`\n */\nexport class KdTable extends KdElement {\n static override properties = {\n data: { attribute: 'data', converter: json },\n empty: {},\n };\n static override styles = [\n base,\n cellStyles,\n css`\n table {\n width: 100%;\n border-collapse: collapse;\n font-size: 13px;\n }\n th,\n td {\n padding: 6px 12px 6px 0;\n border-bottom: 1px solid var(--kd-border, transparent);\n text-align: left;\n vertical-align: top;\n }\n th {\n color: var(--kd-text-2, inherit);\n font-size: 10px;\n font-weight: 500;\n letter-spacing: 0.08em;\n text-transform: uppercase;\n }\n .center {\n text-align: center;\n }\n .right {\n text-align: right;\n }\n /* Prose breaks anywhere so one hash in a message cannot widen the table;\n links keep whole words and stop at 40ch with an ellipsis instead. */\n td {\n --kd-link-max: 40ch;\n overflow-wrap: anywhere;\n }\n .nowrap {\n white-space: nowrap;\n }\n .nowrap .cells {\n flex-wrap: nowrap;\n }\n .none {\n padding: 8px 0;\n color: var(--kd-text-dim, inherit);\n }\n `,\n ];\n\n declare data: TableData | TableData['rows'] | undefined;\n declare empty: string | undefined;\n\n override render() {\n const d = this.data;\n if (!d || typeof d !== 'object') return nothing;\n const { columns, rows = [] } = Array.isArray(d) ? { columns: undefined, rows: d } : d;\n if (!rows.length) return html`<div class=\"none\">${this.empty ?? 'none'}</div>`;\n const cols = columns ?? [...new Set(rows.flatMap((row) => Object.keys(row ?? {})))].map((key) => ({ key }) as TableColumn);\n const align = (col: TableColumn) => (col.align === 'right' || col.align === 'center' ? col.align : '');\n const cls = (col: TableColumn) => [align(col), col.nowrap ? 'nowrap' : ''].filter(Boolean).join(' ');\n return html`<table>\n <thead>\n <tr>\n ${cols.map((col) => html`<th class=${align(col)}>${col.label ?? col.key}</th>`)}\n </tr>\n </thead>\n <tbody>\n ${rows.map(\n (row) => html`<tr>\n ${cols.map((col) => html`<td class=${cls(col)}>${renderCell(row?.[col.key])}</td>`)}\n </tr>`,\n )}\n </tbody>\n </table>`;\n }\n}\n\ndefine('kd-table', KdTable);\n","import { LitElement, css, html, nothing, type PropertyValues } from 'lit';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\n\nconst label = (pane: Element, i: number) => pane.getAttribute('label') || `Tab ${i + 1}`;\n\n/**\n * Tabs over its child elements, any number of them: each child is a pane,\n * labelled by its `label` attribute, with an optional `count` beside it.\n * `selected` names the open pane by label (or by index). With a `key`, the\n * choice is kept in sessionStorage, so it survives the panel recreating the\n * element. A change dispatches `change` with `{ label, index }`.\n *\n * `<kd-tabs key=\"pod-tabs\"><section label=\"Events\" count=\"3\">…</section>…</kd-tabs>`\n */\nexport class KdTabs extends KdElement {\n static override properties = { selected: {}, key: {} };\n // Panes are assigned to slots by hand, so the light DOM is never touched.\n static override shadowRootOptions: ShadowRootInit = { ...LitElement.shadowRootOptions, slotAssignment: 'manual' };\n static override styles = [\n base,\n css`\n [role='tablist'] {\n display: flex;\n flex-wrap: wrap;\n gap: 0 22px;\n margin-bottom: 10px;\n border-bottom: 1px solid var(--kd-border, transparent);\n }\n button {\n margin: 0 0 -1px;\n padding: 6px 1px;\n border: none;\n border-bottom: 2px solid transparent;\n background: none;\n color: var(--kd-text-2, inherit);\n font: inherit;\n font-size: 13px;\n cursor: pointer;\n }\n button:hover {\n color: var(--kd-text, inherit);\n }\n /* Grafana's own active tab is underlined in this orange. */\n button[aria-selected='true'] {\n border-bottom-color: var(--kd-warning, currentColor);\n color: var(--kd-text, inherit);\n }\n .count {\n margin-left: 2px;\n color: var(--kd-text-dim, inherit);\n font-size: 11px;\n }\n `,\n ];\n\n declare selected: string | undefined;\n declare key: string | undefined;\n\n #observer: MutationObserver | undefined;\n\n override connectedCallback(): void {\n super.connectedCallback();\n // Panes may arrive or be relabelled after the element is created.\n this.#observer ??= new MutationObserver(() => this.requestUpdate());\n this.#observer.observe(this, { childList: true, subtree: true, attributes: true, attributeFilter: ['label', 'count'] });\n }\n\n override disconnectedCallback(): void {\n super.disconnectedCallback();\n this.#observer?.disconnect();\n }\n\n get #storage(): Storage | undefined {\n try {\n return this.ownerDocument?.defaultView?.sessionStorage ?? undefined;\n } catch {\n return undefined;\n }\n }\n\n protected override willUpdate(changed: PropertyValues<this>): void {\n if (!changed.has('key') || !this.key) return;\n try {\n const stored = this.#storage?.getItem(`kd-tabs:${this.key}`);\n if (stored !== null && stored !== undefined) this.selected = stored;\n } catch {\n // Storage can be blocked; the tab simply is not remembered.\n }\n }\n\n #panes(): Element[] {\n return [...this.children];\n }\n\n #index(panes: Element[]): number {\n const selected = this.selected;\n if (selected === undefined || selected === null || selected === '') return 0;\n const byLabel = panes.findIndex((pane, i) => label(pane, i) === selected);\n if (byLabel >= 0) return byLabel;\n const n = Number(selected);\n return Number.isInteger(n) && n >= 0 && n < panes.length ? n : 0;\n }\n\n #select(panes: Element[], index: number): void {\n const name = label(panes[index], index);\n if (this.key) {\n try {\n this.#storage?.setItem(`kd-tabs:${this.key}`, name);\n } catch {\n // as above\n }\n }\n if (name === this.selected) return;\n this.selected = name;\n this.dispatchEvent(new CustomEvent('change', { detail: { label: name, index }, bubbles: true, composed: true }));\n }\n\n override render() {\n const panes = this.#panes();\n if (!panes.length) return nothing;\n const open = this.#index(panes);\n return html`<div role=\"tablist\">\n ${panes.map((pane, i) => {\n const count = pane.getAttribute('count');\n return html`<button\n type=\"button\"\n role=\"tab\"\n aria-selected=${i === open ? 'true' : 'false'}\n @click=${() => this.#select(panes, i)}\n >\n ${label(pane, i)}${count ? html`<span class=\"count\">${count}</span>` : nothing}\n </button>`;\n })}\n </div>\n ${panes.map((_, i) => html`<div role=\"tabpanel\" ?hidden=${i !== open}><slot></slot></div>`)}`;\n }\n\n // One slot per pane, assigned by hand; switching tabs only hides the others.\n protected override updated(): void {\n const slots = this.renderRoot.querySelectorAll('slot');\n this.#panes().forEach((pane, i) => slots[i]?.assign(pane));\n }\n}\n\ndefine('kd-tabs', KdTabs);\n","import { css, html } from 'lit';\nimport { ifDefined } from 'lit/directives/if-defined.js';\n\nimport { define } from '../define';\nimport { KdElement, base } from '../element';\nimport { renderIcon, safeHref } from '../parts';\n\n/**\n * The chat tile's header link: a large icon (an image URL or an emoji) over a\n * small label. An `http(s)` link opens in a new tab.\n *\n * `<kd-tile icon=\"🤖\" label=\"Ask\" href=\"https://…\"></kd-tile>`\n */\nexport class KdTile extends KdElement {\n static override properties = { icon: {}, label: {}, href: {} };\n static override styles = [\n base,\n css`\n a,\n div {\n display: block;\n padding-top: 6px;\n color: inherit;\n text-align: center;\n text-decoration: none;\n }\n .icon {\n display: block;\n height: 30px;\n margin: 0 auto;\n font-size: 30px;\n line-height: 1;\n }\n .label {\n display: block;\n margin-top: 6px;\n color: var(--kd-text-2, inherit);\n font-size: 12px;\n }\n `,\n ];\n\n declare icon: string | undefined;\n declare label: string | undefined;\n declare href: string | undefined;\n\n override render() {\n const body = html`${renderIcon(this.icon)}<span class=\"label\">${this.label ?? ''}</span>`;\n const href = safeHref(this.href);\n if (!href) return html`<div>${body}</div>`;\n const external = /^https?:/i.test(href);\n return html`<a\n href=${href}\n target=${ifDefined(external ? '_blank' : undefined)}\n rel=${ifDefined(external ? 'noopener' : undefined)}\n >${body}</a\n >`;\n }\n}\n\ndefine('kd-tile', KdTile);\n"],"ignoreList":[1,11,12],"mappings":"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"}
package/dist/k8s.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { c as e, l as t, n, o as r, r as i, t as a, u as o } from "./chunks/element-ChNBLJ5X.js";
2
- import { n as s, t as c } from "./chunks/define-XzEniRJH.js";
3
- import "./chunks/kd-Bbw0GeQ5.js";
2
+ import { n as s, t as c } from "./chunks/define-BSZoKakE.js";
3
+ import "./chunks/kd-BeZbw7cp.js";
4
4
  import { h as l } from "./chunks/scene-CUr0fSXC.js";
5
5
  //#region src/k8s/icons.ts
6
6
  var u = "https://cdn.jsdelivr.net/gh/kubernetes/community@149066325ed521eab576a262ddff8f4da074d5de/icons/svg/", d = "https://cdn.jsdelivr.net/gh/cncf/artwork@002662490acb2303c7301acc0256c00790e03e9f/projects/", ee = "https://cdn.jsdelivr.net/gh/external-secrets/external-secrets@088f9e5ff057d35bd9f68779893b691abb948b33/assets/", f = "https://cdn.jsdelivr.net/gh/devicons/devicon@7330accdbc47e2dc0c19789a48533c4a3c50fe58/icons/", p = (e) => `${u}resources/unlabeled/${e}.svg`, m = `${d}kubernetes/icon/color/kubernetes-icon-color.svg`, te = p("crd"), h = {
package/dist/kd.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { d as e, i as t, n, r, t as i, u as a } from "./chunks/element-ChNBLJ5X.js";
2
- import { n as o, t as s } from "./chunks/define-XzEniRJH.js";
3
- import { C as c, E as l, S as u, T as d, _ as f, a as p, b as m, c as h, d as g, f as _, g as v, h as y, i as b, l as x, m as S, n as C, o as w, p as T, r as E, s as D, t as O, u as k, v as A, w as j, x as M, y as N } from "./chunks/kd-Bbw0GeQ5.js";
2
+ import { n as o, t as s } from "./chunks/define-BSZoKakE.js";
3
+ import { C as c, E as l, S as u, T as d, _ as f, a as p, b as m, c as h, d as g, f as _, g as v, h as y, i as b, l as x, m as S, n as C, o as w, p as T, r as E, s as D, t as O, u as k, v as A, w as j, x as M, y as N } from "./chunks/kd-BeZbw7cp.js";
4
4
  import { _ as P, a as F, c as I, d as L, f as R, g as z, h as B, i as V, l as H, m as U, n as W, o as G, p as K, r as q, s as J, t as Y, u as X } from "./chunks/scene-CUr0fSXC.js";
5
5
  export { k as KdBar, M as KdData, i as KdElement, h as KdGroups, y as KdLink, D as KdMask, w as KdMeter, S as KdPill, p as KdSheet, b as KdSteps, E as KdTable, C as KdTabs, O as KdTile, s as VERSION, a as applyTheme, n as base, g as cellStyles, o as define, Y as fitPanel, W as focusPanel, e as followTheme, q as gridHeight, V as groups, F as intervalSeconds, _ as isEmpty, r as json, x as jsonValue, d as kdjson, v as linkUrl, G as pageWindow, u as quote, J as refresh, I as refreshIntervals, l as registerHelpers, T as renderCell, f as renderIcon, A as safeHref, H as scene, X as setRefresh, L as setTimeRange, R as setVariable, K as setVariables, U as snapInterval, t as themedAncestor, B as timeRange, c as toYaml, N as tone, m as tones, z as variable, P as variableValue, j as yamlLines };
@@ -27,14 +27,15 @@ export interface ChatConfig {
27
27
  user?: string;
28
28
  /** The Authorization header value. Kept in Grafana and passed in, never in this package. */
29
29
  auth?: string;
30
- /** The `@n8n/chat` version loaded from jsDelivr. */
30
+ /** The `@n8n/chat` version loaded from jsDelivr; by default the one package.json pins. */
31
31
  chatVersion?: string;
32
32
  /** The tile: an element, a selector, or by default `#n8n-chat-tile`. An `<a>` or a `<kd-tile>`. */
33
33
  tile?: Element | string | null;
34
34
  /** The page; by default the tile's, else the global window. */
35
35
  window?: Window;
36
36
  }
37
- export declare const CHAT_VERSION = "1.39.2";
37
+ /** The `@n8n/chat` build loaded by default: package.json's peer dependency, injected at build time. */
38
+ export declare const CHAT_VERSION: string;
38
39
  export interface Settings {
39
40
  icon: string;
40
41
  label: string;
package/dist/n8n.js CHANGED
@@ -1,7 +1,7 @@
1
- import { t as e } from "./chunks/define-XzEniRJH.js";
1
+ import { t as e } from "./chunks/define-BSZoKakE.js";
2
2
  import { _ as t, a as n, c as r, d as i, f as a, h as o, i as s, n as c, o as l, s as u, u as d } from "./chunks/scene-CUr0fSXC.js";
3
3
  //#region src/n8n/config.ts
4
- var f = "1.39.2";
4
+ var f = "1.41.3";
5
5
  function p(e) {
6
6
  return typeof e == "string" ? e.startsWith("${") ? "" : e : "";
7
7
  }
@@ -35,7 +35,7 @@ function g(e) {
35
35
  stream: e.stream === !0 || p(e.stream) === "true",
36
36
  user: p(e.user),
37
37
  auth: p(e.auth),
38
- chatVersion: p(e.chatVersion).trim() || "1.39.2"
38
+ chatVersion: p(e.chatVersion).trim() || "1.41.3"
39
39
  };
40
40
  }
41
41
  //#endregion
@@ -279,7 +279,7 @@ var P = [
279
279
  ].join("\n"), F = (e) => `https://cdn.jsdelivr.net/npm/@n8n/chat@${e}/dist/chat.bundle.es.js`, I = (e) => `https://cdn.jsdelivr.net/npm/@n8n/chat@${e}/dist/style.css`, L = "[data-testid=\"data-testid dashboard controls\"]", R = 900;
280
280
  function z(t) {
281
281
  let n = t.head.querySelector("style[data-n8n-chat-tile]");
282
- n?.dataset.n8nChatTile !== "0.0.4" && (n || (n = t.createElement("style"), t.head.append(n)), n.dataset.n8nChatTile = e, n.textContent = P);
282
+ n?.dataset.n8nChatTile !== "0.0.5" && (n || (n = t.createElement("style"), t.head.append(n)), n.dataset.n8nChatTile = e, n.textContent = P);
283
283
  }
284
284
  function B(e, t) {
285
285
  let n = I(t), r = e.head.querySelector("link[data-n8n-chat-style]");
package/dist/n8n.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"n8n.js","names":["VERSION","variableValue","intervalSeconds","refreshIntervals","setTimeRange","setVariable","timeRange","groups","focusPanel","pageWindow","refresh","setRefresh","CHAT_VERSION","text","value","list","x","groupNotes","notes","part","eq","settings","config","pair","key","name","wrapFetch","win","base","response","input","init","chat","url","body","vars","reply","cleaned","HIDDEN","textOf","content","p","kindOf","m","cleanHistory","data","kept","describeGroups","count","g","head","note","chatMetadata","meta","home","s","live","r","RESERVED","ALIAS","NOT_A_VALUE","readToolCalls","asked","read","call","payload","settable","applyState","applied","values","from","to","set","page","raw","stateCard","chips","k","v","focused","card","doc","chip","el","tag","b","label","i","where","go","onGo","placeCard","bots","host","applyToolCalls","state","target","CONTROL_NODE","controlFilter","decoder","encoder","carry","pass","line","chunk","node","bytes","lines","out","STYLES","chatBundle","version","chatStyle","CONTROLS","NARROW","injectStyles","style","chatStylesheet","href","link","fillTile","external","tile","icon","img","fitChat","root","wrapper","box","cs","toggle","reserve","removeChat","pageOf","given","load","mount","_auth","visible","current","names","loader","createChat"],"sources":["../src/n8n/config.ts","../src/n8n/fetch.ts","../src/n8n/history.ts","../src/n8n/metadata.ts","../src/n8n/state.ts","../src/n8n/stream.ts","../src/n8n/styles.ts","../src/n8n/mount.ts"],"sourcesContent":["/**\n * What the library panel passes to `mount`: its `chat_*` constants (decoded),\n * the viewer, and the Authorization header. A field that arrives as a literal\n * `${...}` (a dashboard without that variable) reads as empty.\n */\nexport interface ChatConfig {\n /** An emoji, or an image URL. */\n icon?: string;\n label?: string;\n /** Where the tile goes; an http(s) link opens a new tab. */\n link?: string;\n /** The n8n Chat Trigger URL. Empty means tile only, and any leftover bubble is removed. */\n webhook?: string;\n title?: string;\n subtitle?: string;\n /** Greeting lines, split on `|`. */\n greeting?: string;\n /** Extra metadata as `key=variable` pairs, read live on every send: `pod=pod,database=datname`. */\n context?: string;\n /** The names the agent may set, in applied order. `time_from`, `time_to`, `refresh` and `focus` are reserved. */\n settable?: string;\n /** Each group's purpose, `Name=purpose` pairs joined by `|` (Grafana has no description on a tab or a row). */\n groups?: string;\n /** Stream the reply. Must match the Chat Trigger's responseMode, or nothing renders. */\n stream?: boolean | string;\n /** The viewer's login, sent as metadata. */\n user?: string;\n /** The Authorization header value. Kept in Grafana and passed in, never in this package. */\n auth?: string;\n /** The `@n8n/chat` version loaded from jsDelivr. */\n chatVersion?: string;\n /** The tile: an element, a selector, or by default `#n8n-chat-tile`. An `<a>` or a `<kd-tile>`. */\n tile?: Element | string | null;\n /** The page; by default the tile's, else the global window. */\n window?: Window;\n}\n\nexport const CHAT_VERSION = '1.39.2';\n\nexport interface Settings {\n icon: string;\n label: string;\n link: string;\n webhook: string;\n title: string;\n subtitle: string;\n greeting: string[];\n context: [key: string, variable: string][];\n settable: string[];\n groups: Record<string, string>;\n stream: boolean;\n user: string;\n auth: string;\n chatVersion: string;\n}\n\nfunction text(value: unknown): string {\n if (typeof value !== 'string') return '';\n return value.startsWith('${') ? '' : value;\n}\n\nexport function list(value: string): string[] {\n return value\n .split(',')\n .map((x) => x.trim())\n .filter(Boolean);\n}\n\n/** `Name=purpose|Other=purpose` -> lower-cased name to purpose. */\nexport function groupNotes(value: string): Record<string, string> {\n const notes: Record<string, string> = {};\n for (const part of value.split('|')) {\n const eq = part.indexOf('=');\n if (eq > 0) notes[part.slice(0, eq).trim().toLowerCase()] = part.slice(eq + 1).trim();\n }\n return notes;\n}\n\nexport function settings(config: ChatConfig): Settings {\n return {\n icon: text(config.icon),\n label: text(config.label),\n link: text(config.link),\n webhook: text(config.webhook).trim(),\n title: text(config.title),\n subtitle: text(config.subtitle),\n greeting: text(config.greeting)\n .split('|')\n .map((x) => x.trim())\n .filter(Boolean),\n context: list(text(config.context)).map((pair): [string, string] => {\n if (!pair.includes('=')) return [pair, pair];\n const [key, name] = pair.split('=').map((x) => x.trim());\n return [key, name];\n }),\n settable: list(text(config.settable)),\n groups: groupNotes(text(config.groups)),\n stream: config.stream === true || text(config.stream) === 'true',\n user: text(config.user),\n auth: text(config.auth),\n chatVersion: text(config.chatVersion).trim() || CHAT_VERSION,\n };\n}\n","import type { Focused } from '../kd/scene';\n\n/**\n * What the fetch wrapper acts for: the chat on screen. Kept on the page window\n * as `n8nChat` in the shape the pre-package library panel used, so a wrapper\n * installed by either one serves the other.\n */\nexport interface ChatHandle {\n webhook: string;\n settable: string[];\n stream: boolean;\n setVariables(vars: Record<string, unknown> | null | undefined, names: string[]): Record<string, string>;\n cleanHistory<T>(reply: T): T;\n filterStream(body: ReadableStream<Uint8Array>): ReadableStream<Uint8Array>;\n}\n\n/** The page globals the chat keeps. They outlive this module across SPA navigation and package versions. */\nexport interface ChatWindow extends Window {\n n8nChat?: ChatHandle | null;\n n8nChatWatch?: number;\n n8nChatFetchWrapped?: boolean;\n n8nChatFit?: () => void;\n n8nChatResize?: boolean;\n n8nChatMount?: { key: string; done: boolean; ready: Promise<void> };\n /** The resolver the agent navigates with, for the dashboard's own buttons (Torrent's use it). */\n dashboardFocus?: (target: string | number) => Focused | null;\n}\n\n/**\n * Wraps the page's fetch, once per page. The wrapper reads `n8nChat` on every\n * call, which each mount replaces, so it acts for the dashboard on screen and\n * only for its webhook.\n */\nexport function wrapFetch(win: ChatWindow): void {\n if (win.n8nChatFetchWrapped) return;\n win.n8nChatFetchWrapped = true;\n const base = win.fetch.bind(win);\n win.fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const response = await base(input, init);\n const chat = win.n8nChat;\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : String(input?.url ?? '');\n const body = typeof init?.body === 'string' ? init.body : '';\n if (!chat || !chat.webhook || !url.includes(chat.webhook)) return response;\n if (body.includes('\"sendMessage\"')) {\n // n8n sends the NDJSON stream as application/json too, so the setting\n // decides, not the content type. Filtered even with nothing settable: the\n // control chunk must never render as a message.\n if (chat.stream && response.body) {\n return new Response(chat.filterStream(response.body), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n // responseMode lastNode: the variables ride on the JSON reply.\n if (chat.settable.length) {\n response\n .clone()\n .json()\n .then((reply: { dashboard_variables?: unknown }) => {\n let vars = reply?.dashboard_variables;\n if (typeof vars === 'string') vars = JSON.parse(vars);\n chat.setVariables(vars as Record<string, unknown>, chat.settable);\n })\n .catch(() => {});\n }\n return response;\n }\n if (body.includes('\"loadPreviousSession\"')) {\n try {\n const cleaned = chat.cleanHistory(await response.clone().json());\n return new Response(JSON.stringify(cleaned), { status: response.status, headers: response.headers });\n } catch {\n return response;\n }\n }\n return response;\n };\n}\n","interface StoredMessage {\n id?: unknown;\n kwargs?: { content?: unknown; [key: string]: unknown };\n [key: string]: unknown;\n}\n\n// LangChain tags each stored message's class in `id`, e.g.\n// ['langchain_core', 'messages', 'ToolMessage']; that is the only reliable\n// discriminator, as kwargs.type is absent on these.\nconst HIDDEN = ['ToolMessage', 'SystemMessage', 'FunctionMessage'];\n\nfunction textOf(content: unknown): string {\n if (typeof content === 'string') return content;\n if (!Array.isArray(content)) return '';\n return content.map((p) => (typeof p === 'string' ? p : (p as { text?: string } | null)?.text || '')).join('');\n}\n\nfunction kindOf(m: StoredMessage | null | undefined): string {\n return Array.isArray(m?.id) ? String(m.id[m.id.length - 1]) : '';\n}\n\n/**\n * Cleans a `loadPreviousSession` reply for the widget, whose markdown renderer\n * throws on anything but a string. Tool, system and function messages are\n * dropped (a tool message's content is the tool's raw JSON, a non-empty string\n * that would otherwise fill the reloaded chat); array content is flattened to\n * its text, and a message left with no text is dropped.\n */\nexport function cleanHistory<T>(reply: T): T {\n const data = (reply as { data?: unknown } | null)?.data;\n if (!Array.isArray(data)) return reply;\n const kept = (data as StoredMessage[]).flatMap((m) => {\n if (HIDDEN.includes(kindOf(m))) return [];\n const text = textOf(m?.kwargs?.content);\n return text.trim() ? [{ ...m, kwargs: { ...m.kwargs, content: text } }] : [];\n });\n return { ...reply, data: kept };\n}\n","import { groups, intervalSeconds, refresh, refreshIntervals, timeRange, variableValue, type Group } from '../kd/scene';\nimport type { Settings } from './config';\n\n/** The navigation map for the agent: one line per group, with its purpose from `chat_groups`. */\nexport function describeGroups(list: Group[], notes: Record<string, string>): string {\n return list\n .map((g) => {\n const count = `${g.panels.length} ${g.panels.length === 1 ? 'panel' : 'panels'}`;\n const head = `- ${g.name} (${g.kind}, ${count}${g.open ? ', OPEN' : ''}${g.focusable ? '' : ', pinned'})`;\n const note = notes[g.name.toLowerCase()];\n return note ? `${head}: ${note}` : head;\n })\n .join('\\n');\n}\n\n/**\n * The metadata sent with every message. @n8n/chat serialises this same object\n * on each send, so every live field is a getter: the agent hears about the\n * window, refresh and layout on screen at send time, not at page load.\n */\nexport function chatMetadata(win: Window, s: Settings, home: string): Record<string, unknown> {\n const meta: Record<string, unknown> = {\n dashboard: home.split('/')[2] || 'unknown',\n user: s.user,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n };\n const live = (key: string, get: () => unknown): void => {\n Object.defineProperty(meta, key, { enumerable: true, configurable: true, get });\n };\n live('dashboardUrl', () => win.location.href);\n live('timestamp', () => new Date().toISOString());\n // Raw is what to say to a person (\"now-24h\"); ISO is what a query needs.\n live('timeFrom', () => timeRange(win)?.from ?? '');\n live('timeTo', () => timeRange(win)?.to ?? '');\n live('timeFromIso', () => timeRange(win)?.fromIso ?? '');\n live('timeToIso', () => timeRange(win)?.toIso ?? '');\n live('refresh', () => {\n const r = refresh(win);\n return r === null ? '' : r || 'off';\n });\n live('refreshSeconds', () => intervalSeconds(refresh(win)));\n // The only intervals the picker accepts; anything else blanks it.\n live('refreshIntervals', () => refreshIntervals(win).join(','));\n live('groups', () => describeGroups(groups(win), s.groups));\n live('openGroups', () =>\n groups(win)\n .filter((g) => g.open && g.focusable)\n .map((g) => g.name)\n .join(', '),\n );\n for (const [key, name] of s.context) live(key, () => variableValue(win, name));\n return meta;\n}\n","import { focusPanel, pageWindow, setRefresh, setTimeRange, setVariable, type Focused, type Page } from '../kd/scene';\n\n/** Names in `chat_settable` that are not template variables. */\nexport const RESERVED = ['time_from', 'time_to', 'refresh', 'focus'];\n\n// The read tool spells the window timeFrom/timeTo; the picker's names are time_from/time_to.\nconst ALIAS: Record<string, string> = { timeFrom: 'time_from', timeTo: 'time_to' };\n\n// `.*` is the panel-data tool's \"all databases\" default; a dropdown's own\n// all-value is $__all, so `.*` would match no option. It means nothing to set.\nconst NOT_A_VALUE = ['', '.*'];\n\nexport interface ToolCalls {\n tools?: { args?: Record<string, unknown> | null }[];\n}\n\nexport interface DashboardState {\n /** Settable names to values; a later call in the turn wins. */\n vars: Record<string, string>;\n /** What to bring on screen: an explicit `focus`, else the last panel read. Null unless `focus` is settable. */\n focus: string | null;\n}\n\n/**\n * Maps a turn's tool calls onto the dashboard. An argument named like a\n * settable name IS that name, so no dashboard-specific mapping lives in n8n.\n * `panelId` is how the agent says which panel it read, so reading a panel is a\n * focus; an explicit `focus` argument beats it.\n */\nexport function readToolCalls(payload: ToolCalls | null | undefined, settable: string[]): DashboardState {\n const vars: Record<string, string> = {};\n let asked: string | null = null;\n let read: string | null = null;\n for (const call of payload?.tools ?? []) {\n for (const [key, value] of Object.entries(call?.args ?? {})) {\n if (value === null || value === undefined || NOT_A_VALUE.includes(String(value))) continue;\n if (key === 'panelId') read = String(value);\n else if (key === 'focus') asked = String(value);\n else {\n const name = ALIAS[key] ?? key;\n if (settable.includes(name)) vars[name] = String(value);\n }\n }\n }\n // Half a window would leave the picker inverted.\n if (vars.time_from && !vars.time_to) vars.time_to = 'now';\n return { vars, focus: settable.includes('focus') ? (asked ?? read) : null };\n}\n\n/**\n * Applies `values` to the page: only the `settable` names, in that order.\n * `refresh` snaps to an offered interval; `time_from`/`time_to` are applied\n * together at the end in one call, both ends reported even when one was asked\n * for. `focus` is not applied here.\n *\n * @returns what really changed, for the state card\n */\nexport function applyState(page: Page, values: Record<string, unknown> | null | undefined, settable: string[]): Record<string, string> {\n const applied: Record<string, string> = {};\n if (!values || typeof values !== 'object') return applied;\n let from: string | null = null;\n let to: string | null = null;\n for (const name of settable) {\n const value = values[name];\n if (value === undefined || value === null || value === '') continue;\n if (name === 'time_from') from = String(value);\n else if (name === 'time_to') to = String(value);\n else if (name === 'refresh') {\n const set = setRefresh(page, String(value));\n if (set !== null) applied.refresh = set;\n } else if (name !== 'focus') {\n const set = setVariable(page, name, value);\n if (set !== null) applied[name] = set;\n }\n }\n if (from || to) {\n const raw = setTimeRange(page, from, to);\n if (raw) {\n applied.time_from = raw.from;\n applied.time_to = raw.to;\n }\n }\n return applied;\n}\n\n/**\n * The card saying what the agent just did to the dashboard, or null when it\n * did nothing. Every value came from the model, so all of it is text, never\n * markup. The focused group is a button that goes back there.\n */\nexport function stateCard(\n doc: Document,\n applied: Record<string, string>,\n focused: Focused | null,\n onGo: (target: string) => void,\n): HTMLElement | null {\n const chips: [string, string][] = [];\n if (applied.time_from || applied.time_to) {\n chips.push(['time', `${applied.time_from || 'now'} → ${applied.time_to || 'now'}`]);\n }\n for (const [k, v] of Object.entries(applied)) {\n if (k !== 'time_from' && k !== 'time_to') chips.push([k, v]);\n }\n if (!chips.length && !focused) return null;\n\n const card = doc.createElement('div');\n card.className = 'n8n-chat-state';\n const head = doc.createElement('span');\n head.className = 'ncs-head';\n head.textContent = focused && !chips.length ? 'Moved your dashboard' : 'Changed your dashboard';\n card.append(head);\n\n const chip = (tag: 'span' | 'button', label: string, value: string): HTMLElement => {\n const el = doc.createElement(tag);\n el.className = tag === 'button' ? 'ncs-chip ncs-go' : 'ncs-chip';\n if (tag === 'button') (el as HTMLButtonElement).type = 'button';\n const b = doc.createElement('b');\n b.textContent = label;\n const i = doc.createElement('i');\n i.textContent = value;\n el.append(b, i);\n card.append(el);\n return el;\n };\n for (const [label, value] of chips) chip('span', label, value);\n if (focused) {\n const where = focused.panel != null ? `${focused.group} · panel ${focused.panel}` : focused.group;\n const go = chip('button', focused.kind === 'tab' ? 'tab' : 'section', where);\n go.title = 'Show me that again';\n go.addEventListener('click', () => onGo(focused.panel != null ? String(focused.panel) : focused.group));\n }\n return card;\n}\n\n/**\n * Puts the card inside the last bot message. The widget's Vue list reorders\n * foreign children of the list itself to below every later message; inside a\n * message they are that message's own subtree and scroll away with its turn.\n */\nexport function placeCard(doc: Document, card: HTMLElement): boolean {\n const bots = doc.querySelectorAll('.chat-message-from-bot');\n const host = bots.length\n ? bots[bots.length - 1]\n : doc.querySelector('.chat-messages-list') || doc.querySelector('.chat-body');\n if (!host) return false;\n card.classList.toggle('ncs-loose', !bots.length);\n host.append(card);\n card.scrollIntoView?.({ block: 'nearest' });\n return true;\n}\n\n/** Applies one turn's control chunk: the settable values, then the focus, then the card. */\nexport function applyToolCalls(page: Page, payload: ToolCalls | null | undefined, settable: string[]): void {\n if (!settable.length) return;\n const state = readToolCalls(payload, settable);\n const applied = Object.keys(state.vars).length ? applyState(page, state.vars, settable) : {};\n const focused = state.focus ? focusPanel(page, state.focus) : null;\n const win = pageWindow(page);\n if (!win) return;\n const card = stateCard(win.document, applied, focused, (target) => focusPanel(win, target));\n // The control chunk ends the stream, but the widget may still be committing\n // the reply it belongs to.\n if (card) win.setTimeout(() => placeCard(win.document, card), 150);\n}\n","/**\n * The node whose chunks drive the dashboard. Each agent workflow ends with a\n * `Dashboard State` node that writes one chunk carrying the turn's tool calls\n * as JSON, and n8n stamps every chunk with the node that wrote it.\n */\nexport const CONTROL_NODE = 'Dashboard State';\n\ninterface Chunk {\n type?: string;\n content?: string;\n metadata?: { nodeName?: string };\n}\n\n/**\n * Rewrites n8n's NDJSON stream on its way to the widget. The control node's\n * chunks are recognised by their author and swallowed whole - begin, item and\n * end alike, since a begin/end that got through would render an empty bubble -\n * and each item's content is handed to `onControl`. Every other line passes\n * untouched.\n *\n * Chunks split anywhere, so a partial line is held back until its newline\n * arrives (or the stream ends): a half-received control chunk never leaks.\n */\nexport function controlFilter(\n onControl: (payload: unknown) => void,\n node: string = CONTROL_NODE,\n): TransformStream<Uint8Array, Uint8Array> {\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n let carry = '';\n const pass = (line: string, out: TransformStreamDefaultController<Uint8Array>): void => {\n if (!line.trim()) return;\n let chunk: Chunk;\n try {\n chunk = JSON.parse(line) as Chunk;\n } catch {\n out.enqueue(encoder.encode(line + '\\n'));\n return;\n }\n if (chunk?.metadata?.nodeName === node) {\n if (chunk.type === 'item' && chunk.content) {\n try {\n onControl(JSON.parse(chunk.content));\n } catch (e) {\n console.warn('[n8n-chat] unreadable control chunk', chunk.content, e);\n }\n }\n return;\n }\n out.enqueue(encoder.encode(line + '\\n'));\n };\n return new TransformStream<Uint8Array, Uint8Array>({\n transform(bytes, out) {\n carry += decoder.decode(bytes, { stream: true });\n const lines = carry.split('\\n');\n carry = lines.pop() ?? '';\n for (const line of lines) pass(line, out);\n },\n flush(out) {\n carry += decoder.decode();\n if (carry.trim()) pass(carry, out);\n },\n });\n}\n","// The chat tile's page-global stylesheet, injected once into <head>: the bubble\n// lives on <body>, outside any panel, so these rules cannot be scoped to one.\n// Every rule is under #n8n-chat, .n8n-chat-widget or .n8n-chat-*, except the\n// kiosk footer fix.\n//\n// The colour literals are deliberate. @n8n/chat renders light even on a dark\n// Grafana, so its insides are pinned to light values, and the state card binds to\n// the widget's own --chat--* properties rather than to the page's theme.\n\nconst parts = [\n // Kiosk embeds: the \"Powered by\" footer is sticky inside a container fixed to\n // the first viewport height, so it floats up once the page scrolls.\n `[data-testid=\"public-dashboard-footer\"]{position:fixed!important;left:0;right:0;bottom:0}`,\n `#n8n-chat .chat-window-wrapper,.n8n-chat-widget{z-index:2147483647!important}`,\n\n // Size. The widget defaults to 400x600 with no media queries. On a desktop the\n // window's top sits under Grafana's controls row, measured into --n8n-chat-top by\n // the mount (these are fallbacks); --n8n-chat-reserve is what sits below the\n // window inside the widget's fixed wrapper (toggle, gap, inset).\n `#n8n-chat{--n8n-chat-top:14px;--n8n-chat-reserve:92px;` +\n `--chat--window--width:min(760px,calc(100vw - 2rem));` +\n `--chat--window--height:max(320px,calc(100vh - var(--n8n-chat-top) - var(--n8n-chat-reserve)))}`,\n // flex-end: the wrapper is a column of window then toggle, and a closed chat\n // hides the window with display:none, so without it the toggle rides up to the\n // controls row. It also makes an overlong window grow upwards.\n `#n8n-chat .chat-window-wrapper{top:var(--n8n-chat-top);justify-content:flex-end}`,\n // Narrow: full bleed. The mount stops setting the inline properties below 900px.\n `@media (max-width:900px){#n8n-chat{--chat--window--width:calc(100vw - 1.5rem);--chat--window--height:calc(100vh - 5rem)}}`,\n\n // Overflow: pod names, image refs and URLs have no break opportunity, and\n // break-word will not break a token on a line that already has content.\n `#n8n-chat .chat-message-markdown{overflow-wrap:anywhere}`,\n `#n8n-chat .chat-message-from-bot{max-width:94%}`,\n // Code and tables scroll rather than wrap: a wrapped command copies wrong.\n `#n8n-chat .chat-message-markdown pre,#n8n-chat .chat-message-markdown table{display:block;max-width:100%;overflow-x:auto}`,\n `#n8n-chat .chat-message-markdown pre code{overflow-wrap:normal;white-space:pre}`,\n `#n8n-chat .chat-message-markdown table{border-collapse:collapse;font-size:12px;white-space:nowrap}`,\n `#n8n-chat .chat-message-markdown th,#n8n-chat .chat-message-markdown td{border:1px solid var(--chat--color-light-shade-100,#d4d8dd);padding:3px 8px;text-align:left}`,\n `#n8n-chat .chat-message-markdown img{max-width:100%;height:auto}`,\n\n // Code contrast: Grafana's dark theme styles <code>/<pre> near-white globally,\n // which wins inside the light bubble. Elements only, so highlight.js spans keep\n // their colours.\n `#n8n-chat{--chat--message--pre--background:#f6f8fa}`,\n `#n8n-chat .chat-message-markdown pre,#n8n-chat .chat-message-markdown code{color:#1f2328!important;background:#f6f8fa}`,\n `#n8n-chat .chat-message-markdown pre{border:1px solid #d0d7de}`,\n `#n8n-chat .chat-message-markdown :not(pre)>code{background:#eaeef2;border:1px solid #d0d7de;border-radius:4px;padding:1px 5px;font-size:.92em}`,\n\n // Grafana styles every <textarea> globally: dark background, dark chat text.\n // -webkit-text-fill-color overrides color on WebKit.\n `#n8n-chat textarea{background:#fff!important;color:#14161a!important;-webkit-text-fill-color:#14161a!important;caret-color:#14161a!important;border:1px solid #c7ccd1!important;opacity:1!important}`,\n `#n8n-chat textarea::placeholder{color:#6b7280!important;-webkit-text-fill-color:#6b7280!important;opacity:1!important}`,\n `#n8n-chat .chat-input-send-button{color:#14161a!important}`,\n\n `.n8n-chat-tile{display:block;text-align:center;text-decoration:none;padding-top:6px;color:inherit}`,\n `.n8n-chat-tile .icon{font-size:30px;line-height:1;height:30px}`,\n `.n8n-chat-tile img{height:30px}`,\n // Grafana's legacy `.badge, .label` rule would paint this a grey box; this selector outranks it.\n `.n8n-chat-tile .label{display:block;font-size:12px;font-weight:inherit;line-height:inherit;opacity:.75;margin-top:6px;padding:0;background:none;color:inherit;border-radius:0;text-shadow:none;white-space:normal}`,\n\n // The state card. Colours come from the widget's own properties: .chat-body\n // inherits Grafana's dark-theme text colour, which measured 1.5:1 on the bubble.\n `.n8n-chat-state{display:flex;flex-wrap:wrap;align-items:center;gap:5px 6px;margin:10px 0 0;padding:8px 0 0;` +\n `border-top:1px solid var(--chat--color-medium,#d2d4d9);color:var(--chat--color-dark,#101330);font-size:12px;line-height:1.4}`,\n // With no reply to hang under, the card carries its own edges.\n `.n8n-chat-state.ncs-loose{margin:2px 0 10px;padding:8px 10px;border:1px solid var(--chat--color-medium,#d2d4d9);` +\n `border-left:3px solid #5794f2;border-radius:4px;background:var(--chat--message--bot--background,#fff)}`,\n `.n8n-chat-state .ncs-head{width:100%;margin-bottom:2px;font-size:11px;font-weight:600;letter-spacing:.02em;opacity:.62}`,\n `.n8n-chat-state .ncs-chip{display:inline-flex;align-items:baseline;gap:6px;margin:0;padding:3px 9px;border-radius:11px;` +\n `border:1px solid var(--chat--color-medium,#d2d4d9);background:var(--chat--color-light,#f2f4f8);font:inherit;color:inherit}`,\n `.n8n-chat-state .ncs-chip b{font-weight:600;font-size:10px;text-transform:uppercase;letter-spacing:.05em;opacity:.62}`,\n `.n8n-chat-state .ncs-chip i{font-style:normal}`,\n `.n8n-chat-state button.ncs-go{cursor:pointer}`,\n `.n8n-chat-state button.ncs-go:hover{border-color:#5794f2;background:rgba(87,148,242,.12)}`,\n];\n\nexport const STYLES = parts.join('\\n');\n","import { VERSION } from '../kd/define';\nimport { focusPanel } from '../kd/scene';\nimport { settings, type ChatConfig, type Settings } from './config';\nimport { wrapFetch, type ChatHandle, type ChatWindow } from './fetch';\nimport { cleanHistory } from './history';\nimport { chatMetadata } from './metadata';\nimport { applyState, applyToolCalls, type ToolCalls } from './state';\nimport { controlFilter } from './stream';\nimport { STYLES } from './styles';\n\nexport type CreateChat = (options: Record<string, unknown>) => unknown;\nexport type ChatLoader = (url: string) => Promise<{ createChat: CreateChat }>;\n\n// dist/ on purpose, for both files: the package root's chat.bundle.es.js has no\n// stream reader, and its style.css has no .chat-inputs rules.\nexport const chatBundle = (version: string): string => `https://cdn.jsdelivr.net/npm/@n8n/chat@${version}/dist/chat.bundle.es.js`;\nexport const chatStyle = (version: string): string => `https://cdn.jsdelivr.net/npm/@n8n/chat@${version}/dist/style.css`;\n\nconst CONTROLS = '[data-testid=\"data-testid dashboard controls\"]';\nconst NARROW = 900;\n\n/** Injects the tile's page-global stylesheet once; a newer build's replaces an older one's. */\nexport function injectStyles(doc: Document): void {\n let style = doc.head.querySelector<HTMLStyleElement>('style[data-n8n-chat-tile]');\n if (style?.dataset.n8nChatTile === VERSION) return;\n if (!style) {\n style = doc.createElement('style');\n doc.head.append(style);\n }\n style.dataset.n8nChatTile = VERSION;\n style.textContent = STYLES;\n}\n\nfunction chatStylesheet(doc: Document, version: string): void {\n const href = chatStyle(version);\n let link = doc.head.querySelector<HTMLLinkElement>('link[data-n8n-chat-style]');\n if (link?.getAttribute('href') === href) return;\n if (!link) {\n link = doc.createElement('link');\n link.rel = 'stylesheet';\n link.setAttribute('data-n8n-chat-style', '');\n doc.head.append(link);\n }\n link.href = href;\n}\n\n/** Fills the tile: an `<a>` with `.icon` and `.label` children, or a `<kd-tile>` by its attributes. */\nexport function fillTile(tile: Element, s: Pick<Settings, 'icon' | 'label' | 'link'>): void {\n const external = /^https?:/.test(s.link);\n if (tile.localName === 'kd-tile') {\n for (const [name, value] of [['icon', s.icon], ['label', s.label], ['href', s.link]]) {\n if (value) tile.setAttribute(name, value);\n else tile.removeAttribute(name);\n }\n return;\n }\n const icon = tile.querySelector('.icon');\n if (icon) {\n if (/^(https?:)?\\//.test(s.icon)) {\n const img = tile.ownerDocument.createElement('img');\n img.src = s.icon;\n img.alt = '';\n icon.replaceChildren(img);\n } else {\n icon.textContent = s.icon;\n }\n }\n const label = tile.querySelector('.label');\n if (label) label.textContent = s.label;\n if (s.link) tile.setAttribute('href', s.link);\n else tile.removeAttribute('href');\n if (external) {\n tile.setAttribute('target', '_blank');\n tile.setAttribute('rel', 'noopener');\n } else {\n tile.removeAttribute('target');\n tile.removeAttribute('rel');\n }\n}\n\n/**\n * Pins the chat window's top under Grafana's controls row, which is measured\n * because it grows when the variables wrap and is absent in a kiosk embed. With\n * no row, or below 900px, the inline values go so the stylesheet's apply.\n */\nexport function fitChat(win: Window): void {\n const doc = win.document;\n const root = doc.getElementById('n8n-chat');\n if (!root) return;\n const wrapper = root.querySelector('.chat-window-wrapper');\n const box = doc.querySelector(CONTROLS)?.getBoundingClientRect();\n if (!wrapper || !box || !box.height || win.innerWidth <= NARROW) {\n root.style.removeProperty('--n8n-chat-top');\n root.style.removeProperty('--n8n-chat-reserve');\n return;\n }\n const cs = win.getComputedStyle(wrapper);\n const toggle = root.querySelector('.chat-window-toggle');\n const reserve =\n (parseFloat(cs.bottom) || 14) +\n (toggle ? toggle.getBoundingClientRect().height : 64) +\n (parseFloat(cs.rowGap || cs.gap) || 14);\n root.style.setProperty('--n8n-chat-top', `${Math.round(box.bottom + 10)}px`);\n root.style.setProperty('--n8n-chat-reserve', `${Math.round(reserve)}px`);\n}\n\nfunction removeChat(doc: Document): void {\n doc.querySelectorAll('#n8n-chat, .n8n-chat-widget').forEach((el) => el.remove());\n}\n\nfunction pageOf(config: ChatConfig): { win: ChatWindow; tile: Element | null } {\n const given = config.tile;\n if (given && typeof given === 'object') {\n return { win: (config.window ?? given.ownerDocument.defaultView ?? window) as ChatWindow, tile: given };\n }\n const win = (config.window ?? window) as ChatWindow;\n const tile =\n typeof given === 'string' ? win.document.querySelector(given) : given === null ? null : win.document.getElementById('n8n-chat-tile');\n return { win, tile };\n}\n\nconst load: ChatLoader = (url) => import(/* @vite-ignore */ url);\n\n/**\n * Mounts the chat tile and its n8n chat on the page.\n *\n * Idempotent: the core text panel re-runs its script on every mount, so a\n * repeat call for the same dashboard and settings keeps the chat that is there.\n * Grafana is a single-page app, so the chat lives on `<body>` only while the URL\n * stays on this dashboard. With no webhook it fills the tile and removes any\n * leftover chat.\n *\n * @returns once the chat is created (or at once, tile only)\n */\nexport function mount(config: ChatConfig = {}, loader: ChatLoader = load): Promise<void> {\n const { win, tile } = pageOf(config);\n const doc = win.document;\n const s = settings(config);\n\n injectStyles(doc);\n if (tile) fillTile(tile, s);\n win.dashboardFocus = (target) => focusPanel(win, target);\n\n if (!s.webhook) {\n removeChat(doc);\n win.clearInterval(win.n8nChatWatch);\n win.n8nChat = null;\n win.n8nChatMount = undefined;\n return Promise.resolve();\n }\n\n const home = win.location.pathname;\n const { auth: _auth, ...visible } = s;\n const key = JSON.stringify([home, visible]);\n const current = win.n8nChatMount;\n if (current?.key === key && (!current.done || doc.getElementById('n8n-chat'))) return current.ready;\n\n removeChat(doc);\n win.clearInterval(win.n8nChatWatch);\n win.n8nChatWatch = win.setInterval(() => {\n if (win.location.pathname !== home) {\n removeChat(doc);\n win.clearInterval(win.n8nChatWatch);\n win.n8nChat = null;\n win.n8nChatMount = undefined;\n return;\n }\n // Also re-measures the controls row, whose height changes fire no event.\n win.n8nChatFit?.();\n }, 1000);\n chatStylesheet(doc, s.chatVersion);\n if (!win.n8nChatResize) {\n win.n8nChatResize = true;\n win.addEventListener('resize', () => win.n8nChatFit?.());\n }\n\n const handle: ChatHandle = {\n webhook: s.webhook,\n settable: s.settable,\n stream: s.stream,\n setVariables: (vars, names) => applyState(win, vars, names),\n cleanHistory,\n filterStream: (body) => body.pipeThrough(controlFilter((payload) => applyToolCalls(win, payload as ToolCalls, s.settable))),\n };\n win.n8nChat = handle;\n wrapFetch(win);\n\n const state: NonNullable<ChatWindow['n8nChatMount']> = { key, done: false, ready: Promise.resolve() };\n win.n8nChatMount = state;\n state.ready = (async () => {\n try {\n // Imported after the setup above, so the page is ready before the bundle arrives.\n const { createChat } = await loader(chatBundle(s.chatVersion));\n // A later mount, or leaving the dashboard, while the bundle loaded.\n if (win.n8nChatMount !== state || win.location.pathname !== home) return;\n win.n8nChatFit = () => fitChat(win);\n createChat({\n webhookUrl: s.webhook,\n webhookConfig: { headers: s.auth ? { Authorization: s.auth } : {} },\n chatSessionKey: 'sessionId',\n loadPreviousSession: true,\n enableStreaming: s.stream,\n metadata: chatMetadata(win, s, home),\n showWelcomeScreen: true,\n initialMessages: s.greeting,\n i18n: { en: { title: s.title, subtitle: s.subtitle } },\n });\n // createChat mounts asynchronously.\n win.setTimeout(() => win.n8nChatFit?.(), 200);\n } finally {\n state.done = true;\n }\n })();\n return state.ready;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"n8n.js","names":["VERSION","variableValue","intervalSeconds","refreshIntervals","setTimeRange","setVariable","timeRange","groups","focusPanel","pageWindow","refresh","setRefresh","CHAT_VERSION","text","value","list","x","groupNotes","notes","part","eq","settings","config","pair","key","name","wrapFetch","win","base","response","input","init","chat","url","body","vars","reply","cleaned","HIDDEN","textOf","content","p","kindOf","m","cleanHistory","data","kept","describeGroups","count","g","head","note","chatMetadata","meta","home","s","live","r","RESERVED","ALIAS","NOT_A_VALUE","readToolCalls","asked","read","call","payload","settable","applyState","applied","values","from","to","set","page","raw","stateCard","chips","k","v","focused","card","doc","chip","el","tag","b","label","i","where","go","onGo","placeCard","bots","host","applyToolCalls","state","target","CONTROL_NODE","controlFilter","decoder","encoder","carry","pass","line","chunk","node","bytes","lines","out","STYLES","chatBundle","version","chatStyle","CONTROLS","NARROW","injectStyles","style","chatStylesheet","href","link","fillTile","external","tile","icon","img","fitChat","root","wrapper","box","cs","toggle","reserve","removeChat","pageOf","given","load","mount","_auth","visible","current","names","loader","createChat"],"sources":["../src/n8n/config.ts","../src/n8n/fetch.ts","../src/n8n/history.ts","../src/n8n/metadata.ts","../src/n8n/state.ts","../src/n8n/stream.ts","../src/n8n/styles.ts","../src/n8n/mount.ts"],"sourcesContent":["/**\n * What the library panel passes to `mount`: its `chat_*` constants (decoded),\n * the viewer, and the Authorization header. A field that arrives as a literal\n * `${...}` (a dashboard without that variable) reads as empty.\n */\nexport interface ChatConfig {\n /** An emoji, or an image URL. */\n icon?: string;\n label?: string;\n /** Where the tile goes; an http(s) link opens a new tab. */\n link?: string;\n /** The n8n Chat Trigger URL. Empty means tile only, and any leftover bubble is removed. */\n webhook?: string;\n title?: string;\n subtitle?: string;\n /** Greeting lines, split on `|`. */\n greeting?: string;\n /** Extra metadata as `key=variable` pairs, read live on every send: `pod=pod,database=datname`. */\n context?: string;\n /** The names the agent may set, in applied order. `time_from`, `time_to`, `refresh` and `focus` are reserved. */\n settable?: string;\n /** Each group's purpose, `Name=purpose` pairs joined by `|` (Grafana has no description on a tab or a row). */\n groups?: string;\n /** Stream the reply. Must match the Chat Trigger's responseMode, or nothing renders. */\n stream?: boolean | string;\n /** The viewer's login, sent as metadata. */\n user?: string;\n /** The Authorization header value. Kept in Grafana and passed in, never in this package. */\n auth?: string;\n /** The `@n8n/chat` version loaded from jsDelivr; by default the one package.json pins. */\n chatVersion?: string;\n /** The tile: an element, a selector, or by default `#n8n-chat-tile`. An `<a>` or a `<kd-tile>`. */\n tile?: Element | string | null;\n /** The page; by default the tile's, else the global window. */\n window?: Window;\n}\n\n/** The `@n8n/chat` build loaded by default: package.json's peer dependency, injected at build time. */\nexport const CHAT_VERSION: string = __N8N_CHAT_VERSION__;\n\nexport interface Settings {\n icon: string;\n label: string;\n link: string;\n webhook: string;\n title: string;\n subtitle: string;\n greeting: string[];\n context: [key: string, variable: string][];\n settable: string[];\n groups: Record<string, string>;\n stream: boolean;\n user: string;\n auth: string;\n chatVersion: string;\n}\n\nfunction text(value: unknown): string {\n if (typeof value !== 'string') return '';\n return value.startsWith('${') ? '' : value;\n}\n\nexport function list(value: string): string[] {\n return value\n .split(',')\n .map((x) => x.trim())\n .filter(Boolean);\n}\n\n/** `Name=purpose|Other=purpose` -> lower-cased name to purpose. */\nexport function groupNotes(value: string): Record<string, string> {\n const notes: Record<string, string> = {};\n for (const part of value.split('|')) {\n const eq = part.indexOf('=');\n if (eq > 0) notes[part.slice(0, eq).trim().toLowerCase()] = part.slice(eq + 1).trim();\n }\n return notes;\n}\n\nexport function settings(config: ChatConfig): Settings {\n return {\n icon: text(config.icon),\n label: text(config.label),\n link: text(config.link),\n webhook: text(config.webhook).trim(),\n title: text(config.title),\n subtitle: text(config.subtitle),\n greeting: text(config.greeting)\n .split('|')\n .map((x) => x.trim())\n .filter(Boolean),\n context: list(text(config.context)).map((pair): [string, string] => {\n if (!pair.includes('=')) return [pair, pair];\n const [key, name] = pair.split('=').map((x) => x.trim());\n return [key, name];\n }),\n settable: list(text(config.settable)),\n groups: groupNotes(text(config.groups)),\n stream: config.stream === true || text(config.stream) === 'true',\n user: text(config.user),\n auth: text(config.auth),\n chatVersion: text(config.chatVersion).trim() || CHAT_VERSION,\n };\n}\n","import type { Focused } from '../kd/scene';\n\n/**\n * What the fetch wrapper acts for: the chat on screen. Kept on the page window\n * as `n8nChat` in the shape the pre-package library panel used, so a wrapper\n * installed by either one serves the other.\n */\nexport interface ChatHandle {\n webhook: string;\n settable: string[];\n stream: boolean;\n setVariables(vars: Record<string, unknown> | null | undefined, names: string[]): Record<string, string>;\n cleanHistory<T>(reply: T): T;\n filterStream(body: ReadableStream<Uint8Array>): ReadableStream<Uint8Array>;\n}\n\n/** The page globals the chat keeps. They outlive this module across SPA navigation and package versions. */\nexport interface ChatWindow extends Window {\n n8nChat?: ChatHandle | null;\n n8nChatWatch?: number;\n n8nChatFetchWrapped?: boolean;\n n8nChatFit?: () => void;\n n8nChatResize?: boolean;\n n8nChatMount?: { key: string; done: boolean; ready: Promise<void> };\n /** The resolver the agent navigates with, for the dashboard's own buttons (Torrent's use it). */\n dashboardFocus?: (target: string | number) => Focused | null;\n}\n\n/**\n * Wraps the page's fetch, once per page. The wrapper reads `n8nChat` on every\n * call, which each mount replaces, so it acts for the dashboard on screen and\n * only for its webhook.\n */\nexport function wrapFetch(win: ChatWindow): void {\n if (win.n8nChatFetchWrapped) return;\n win.n8nChatFetchWrapped = true;\n const base = win.fetch.bind(win);\n win.fetch = async (input: RequestInfo | URL, init?: RequestInit): Promise<Response> => {\n const response = await base(input, init);\n const chat = win.n8nChat;\n const url = typeof input === 'string' ? input : input instanceof URL ? input.href : String(input?.url ?? '');\n const body = typeof init?.body === 'string' ? init.body : '';\n if (!chat || !chat.webhook || !url.includes(chat.webhook)) return response;\n if (body.includes('\"sendMessage\"')) {\n // n8n sends the NDJSON stream as application/json too, so the setting\n // decides, not the content type. Filtered even with nothing settable: the\n // control chunk must never render as a message.\n if (chat.stream && response.body) {\n return new Response(chat.filterStream(response.body), {\n status: response.status,\n statusText: response.statusText,\n headers: response.headers,\n });\n }\n // responseMode lastNode: the variables ride on the JSON reply.\n if (chat.settable.length) {\n response\n .clone()\n .json()\n .then((reply: { dashboard_variables?: unknown }) => {\n let vars = reply?.dashboard_variables;\n if (typeof vars === 'string') vars = JSON.parse(vars);\n chat.setVariables(vars as Record<string, unknown>, chat.settable);\n })\n .catch(() => {});\n }\n return response;\n }\n if (body.includes('\"loadPreviousSession\"')) {\n try {\n const cleaned = chat.cleanHistory(await response.clone().json());\n return new Response(JSON.stringify(cleaned), { status: response.status, headers: response.headers });\n } catch {\n return response;\n }\n }\n return response;\n };\n}\n","interface StoredMessage {\n id?: unknown;\n kwargs?: { content?: unknown; [key: string]: unknown };\n [key: string]: unknown;\n}\n\n// LangChain tags each stored message's class in `id`, e.g.\n// ['langchain_core', 'messages', 'ToolMessage']; that is the only reliable\n// discriminator, as kwargs.type is absent on these.\nconst HIDDEN = ['ToolMessage', 'SystemMessage', 'FunctionMessage'];\n\nfunction textOf(content: unknown): string {\n if (typeof content === 'string') return content;\n if (!Array.isArray(content)) return '';\n return content.map((p) => (typeof p === 'string' ? p : (p as { text?: string } | null)?.text || '')).join('');\n}\n\nfunction kindOf(m: StoredMessage | null | undefined): string {\n return Array.isArray(m?.id) ? String(m.id[m.id.length - 1]) : '';\n}\n\n/**\n * Cleans a `loadPreviousSession` reply for the widget, whose markdown renderer\n * throws on anything but a string. Tool, system and function messages are\n * dropped (a tool message's content is the tool's raw JSON, a non-empty string\n * that would otherwise fill the reloaded chat); array content is flattened to\n * its text, and a message left with no text is dropped.\n */\nexport function cleanHistory<T>(reply: T): T {\n const data = (reply as { data?: unknown } | null)?.data;\n if (!Array.isArray(data)) return reply;\n const kept = (data as StoredMessage[]).flatMap((m) => {\n if (HIDDEN.includes(kindOf(m))) return [];\n const text = textOf(m?.kwargs?.content);\n return text.trim() ? [{ ...m, kwargs: { ...m.kwargs, content: text } }] : [];\n });\n return { ...reply, data: kept };\n}\n","import { groups, intervalSeconds, refresh, refreshIntervals, timeRange, variableValue, type Group } from '../kd/scene';\nimport type { Settings } from './config';\n\n/** The navigation map for the agent: one line per group, with its purpose from `chat_groups`. */\nexport function describeGroups(list: Group[], notes: Record<string, string>): string {\n return list\n .map((g) => {\n const count = `${g.panels.length} ${g.panels.length === 1 ? 'panel' : 'panels'}`;\n const head = `- ${g.name} (${g.kind}, ${count}${g.open ? ', OPEN' : ''}${g.focusable ? '' : ', pinned'})`;\n const note = notes[g.name.toLowerCase()];\n return note ? `${head}: ${note}` : head;\n })\n .join('\\n');\n}\n\n/**\n * The metadata sent with every message. @n8n/chat serialises this same object\n * on each send, so every live field is a getter: the agent hears about the\n * window, refresh and layout on screen at send time, not at page load.\n */\nexport function chatMetadata(win: Window, s: Settings, home: string): Record<string, unknown> {\n const meta: Record<string, unknown> = {\n dashboard: home.split('/')[2] || 'unknown',\n user: s.user,\n timezone: Intl.DateTimeFormat().resolvedOptions().timeZone,\n };\n const live = (key: string, get: () => unknown): void => {\n Object.defineProperty(meta, key, { enumerable: true, configurable: true, get });\n };\n live('dashboardUrl', () => win.location.href);\n live('timestamp', () => new Date().toISOString());\n // Raw is what to say to a person (\"now-24h\"); ISO is what a query needs.\n live('timeFrom', () => timeRange(win)?.from ?? '');\n live('timeTo', () => timeRange(win)?.to ?? '');\n live('timeFromIso', () => timeRange(win)?.fromIso ?? '');\n live('timeToIso', () => timeRange(win)?.toIso ?? '');\n live('refresh', () => {\n const r = refresh(win);\n return r === null ? '' : r || 'off';\n });\n live('refreshSeconds', () => intervalSeconds(refresh(win)));\n // The only intervals the picker accepts; anything else blanks it.\n live('refreshIntervals', () => refreshIntervals(win).join(','));\n live('groups', () => describeGroups(groups(win), s.groups));\n live('openGroups', () =>\n groups(win)\n .filter((g) => g.open && g.focusable)\n .map((g) => g.name)\n .join(', '),\n );\n for (const [key, name] of s.context) live(key, () => variableValue(win, name));\n return meta;\n}\n","import { focusPanel, pageWindow, setRefresh, setTimeRange, setVariable, type Focused, type Page } from '../kd/scene';\n\n/** Names in `chat_settable` that are not template variables. */\nexport const RESERVED = ['time_from', 'time_to', 'refresh', 'focus'];\n\n// The read tool spells the window timeFrom/timeTo; the picker's names are time_from/time_to.\nconst ALIAS: Record<string, string> = { timeFrom: 'time_from', timeTo: 'time_to' };\n\n// `.*` is the panel-data tool's \"all databases\" default; a dropdown's own\n// all-value is $__all, so `.*` would match no option. It means nothing to set.\nconst NOT_A_VALUE = ['', '.*'];\n\nexport interface ToolCalls {\n tools?: { args?: Record<string, unknown> | null }[];\n}\n\nexport interface DashboardState {\n /** Settable names to values; a later call in the turn wins. */\n vars: Record<string, string>;\n /** What to bring on screen: an explicit `focus`, else the last panel read. Null unless `focus` is settable. */\n focus: string | null;\n}\n\n/**\n * Maps a turn's tool calls onto the dashboard. An argument named like a\n * settable name IS that name, so no dashboard-specific mapping lives in n8n.\n * `panelId` is how the agent says which panel it read, so reading a panel is a\n * focus; an explicit `focus` argument beats it.\n */\nexport function readToolCalls(payload: ToolCalls | null | undefined, settable: string[]): DashboardState {\n const vars: Record<string, string> = {};\n let asked: string | null = null;\n let read: string | null = null;\n for (const call of payload?.tools ?? []) {\n for (const [key, value] of Object.entries(call?.args ?? {})) {\n if (value === null || value === undefined || NOT_A_VALUE.includes(String(value))) continue;\n if (key === 'panelId') read = String(value);\n else if (key === 'focus') asked = String(value);\n else {\n const name = ALIAS[key] ?? key;\n if (settable.includes(name)) vars[name] = String(value);\n }\n }\n }\n // Half a window would leave the picker inverted.\n if (vars.time_from && !vars.time_to) vars.time_to = 'now';\n return { vars, focus: settable.includes('focus') ? (asked ?? read) : null };\n}\n\n/**\n * Applies `values` to the page: only the `settable` names, in that order.\n * `refresh` snaps to an offered interval; `time_from`/`time_to` are applied\n * together at the end in one call, both ends reported even when one was asked\n * for. `focus` is not applied here.\n *\n * @returns what really changed, for the state card\n */\nexport function applyState(page: Page, values: Record<string, unknown> | null | undefined, settable: string[]): Record<string, string> {\n const applied: Record<string, string> = {};\n if (!values || typeof values !== 'object') return applied;\n let from: string | null = null;\n let to: string | null = null;\n for (const name of settable) {\n const value = values[name];\n if (value === undefined || value === null || value === '') continue;\n if (name === 'time_from') from = String(value);\n else if (name === 'time_to') to = String(value);\n else if (name === 'refresh') {\n const set = setRefresh(page, String(value));\n if (set !== null) applied.refresh = set;\n } else if (name !== 'focus') {\n const set = setVariable(page, name, value);\n if (set !== null) applied[name] = set;\n }\n }\n if (from || to) {\n const raw = setTimeRange(page, from, to);\n if (raw) {\n applied.time_from = raw.from;\n applied.time_to = raw.to;\n }\n }\n return applied;\n}\n\n/**\n * The card saying what the agent just did to the dashboard, or null when it\n * did nothing. Every value came from the model, so all of it is text, never\n * markup. The focused group is a button that goes back there.\n */\nexport function stateCard(\n doc: Document,\n applied: Record<string, string>,\n focused: Focused | null,\n onGo: (target: string) => void,\n): HTMLElement | null {\n const chips: [string, string][] = [];\n if (applied.time_from || applied.time_to) {\n chips.push(['time', `${applied.time_from || 'now'} → ${applied.time_to || 'now'}`]);\n }\n for (const [k, v] of Object.entries(applied)) {\n if (k !== 'time_from' && k !== 'time_to') chips.push([k, v]);\n }\n if (!chips.length && !focused) return null;\n\n const card = doc.createElement('div');\n card.className = 'n8n-chat-state';\n const head = doc.createElement('span');\n head.className = 'ncs-head';\n head.textContent = focused && !chips.length ? 'Moved your dashboard' : 'Changed your dashboard';\n card.append(head);\n\n const chip = (tag: 'span' | 'button', label: string, value: string): HTMLElement => {\n const el = doc.createElement(tag);\n el.className = tag === 'button' ? 'ncs-chip ncs-go' : 'ncs-chip';\n if (tag === 'button') (el as HTMLButtonElement).type = 'button';\n const b = doc.createElement('b');\n b.textContent = label;\n const i = doc.createElement('i');\n i.textContent = value;\n el.append(b, i);\n card.append(el);\n return el;\n };\n for (const [label, value] of chips) chip('span', label, value);\n if (focused) {\n const where = focused.panel != null ? `${focused.group} · panel ${focused.panel}` : focused.group;\n const go = chip('button', focused.kind === 'tab' ? 'tab' : 'section', where);\n go.title = 'Show me that again';\n go.addEventListener('click', () => onGo(focused.panel != null ? String(focused.panel) : focused.group));\n }\n return card;\n}\n\n/**\n * Puts the card inside the last bot message. The widget's Vue list reorders\n * foreign children of the list itself to below every later message; inside a\n * message they are that message's own subtree and scroll away with its turn.\n */\nexport function placeCard(doc: Document, card: HTMLElement): boolean {\n const bots = doc.querySelectorAll('.chat-message-from-bot');\n const host = bots.length\n ? bots[bots.length - 1]\n : doc.querySelector('.chat-messages-list') || doc.querySelector('.chat-body');\n if (!host) return false;\n card.classList.toggle('ncs-loose', !bots.length);\n host.append(card);\n card.scrollIntoView?.({ block: 'nearest' });\n return true;\n}\n\n/** Applies one turn's control chunk: the settable values, then the focus, then the card. */\nexport function applyToolCalls(page: Page, payload: ToolCalls | null | undefined, settable: string[]): void {\n if (!settable.length) return;\n const state = readToolCalls(payload, settable);\n const applied = Object.keys(state.vars).length ? applyState(page, state.vars, settable) : {};\n const focused = state.focus ? focusPanel(page, state.focus) : null;\n const win = pageWindow(page);\n if (!win) return;\n const card = stateCard(win.document, applied, focused, (target) => focusPanel(win, target));\n // The control chunk ends the stream, but the widget may still be committing\n // the reply it belongs to.\n if (card) win.setTimeout(() => placeCard(win.document, card), 150);\n}\n","/**\n * The node whose chunks drive the dashboard. Each agent workflow ends with a\n * `Dashboard State` node that writes one chunk carrying the turn's tool calls\n * as JSON, and n8n stamps every chunk with the node that wrote it.\n */\nexport const CONTROL_NODE = 'Dashboard State';\n\ninterface Chunk {\n type?: string;\n content?: string;\n metadata?: { nodeName?: string };\n}\n\n/**\n * Rewrites n8n's NDJSON stream on its way to the widget. The control node's\n * chunks are recognised by their author and swallowed whole - begin, item and\n * end alike, since a begin/end that got through would render an empty bubble -\n * and each item's content is handed to `onControl`. Every other line passes\n * untouched.\n *\n * Chunks split anywhere, so a partial line is held back until its newline\n * arrives (or the stream ends): a half-received control chunk never leaks.\n */\nexport function controlFilter(\n onControl: (payload: unknown) => void,\n node: string = CONTROL_NODE,\n): TransformStream<Uint8Array, Uint8Array> {\n const decoder = new TextDecoder();\n const encoder = new TextEncoder();\n let carry = '';\n const pass = (line: string, out: TransformStreamDefaultController<Uint8Array>): void => {\n if (!line.trim()) return;\n let chunk: Chunk;\n try {\n chunk = JSON.parse(line) as Chunk;\n } catch {\n out.enqueue(encoder.encode(line + '\\n'));\n return;\n }\n if (chunk?.metadata?.nodeName === node) {\n if (chunk.type === 'item' && chunk.content) {\n try {\n onControl(JSON.parse(chunk.content));\n } catch (e) {\n console.warn('[n8n-chat] unreadable control chunk', chunk.content, e);\n }\n }\n return;\n }\n out.enqueue(encoder.encode(line + '\\n'));\n };\n return new TransformStream<Uint8Array, Uint8Array>({\n transform(bytes, out) {\n carry += decoder.decode(bytes, { stream: true });\n const lines = carry.split('\\n');\n carry = lines.pop() ?? '';\n for (const line of lines) pass(line, out);\n },\n flush(out) {\n carry += decoder.decode();\n if (carry.trim()) pass(carry, out);\n },\n });\n}\n","// The chat tile's page-global stylesheet, injected once into <head>: the bubble\n// lives on <body>, outside any panel, so these rules cannot be scoped to one.\n// Every rule is under #n8n-chat, .n8n-chat-widget or .n8n-chat-*, except the\n// kiosk footer fix.\n//\n// The colour literals are deliberate. @n8n/chat renders light even on a dark\n// Grafana, so its insides are pinned to light values, and the state card binds to\n// the widget's own --chat--* properties rather than to the page's theme.\n\nconst parts = [\n // Kiosk embeds: the \"Powered by\" footer is sticky inside a container fixed to\n // the first viewport height, so it floats up once the page scrolls.\n `[data-testid=\"public-dashboard-footer\"]{position:fixed!important;left:0;right:0;bottom:0}`,\n `#n8n-chat .chat-window-wrapper,.n8n-chat-widget{z-index:2147483647!important}`,\n\n // Size. The widget defaults to 400x600 with no media queries. On a desktop the\n // window's top sits under Grafana's controls row, measured into --n8n-chat-top by\n // the mount (these are fallbacks); --n8n-chat-reserve is what sits below the\n // window inside the widget's fixed wrapper (toggle, gap, inset).\n `#n8n-chat{--n8n-chat-top:14px;--n8n-chat-reserve:92px;` +\n `--chat--window--width:min(760px,calc(100vw - 2rem));` +\n `--chat--window--height:max(320px,calc(100vh - var(--n8n-chat-top) - var(--n8n-chat-reserve)))}`,\n // flex-end: the wrapper is a column of window then toggle, and a closed chat\n // hides the window with display:none, so without it the toggle rides up to the\n // controls row. It also makes an overlong window grow upwards.\n `#n8n-chat .chat-window-wrapper{top:var(--n8n-chat-top);justify-content:flex-end}`,\n // Narrow: full bleed. The mount stops setting the inline properties below 900px.\n `@media (max-width:900px){#n8n-chat{--chat--window--width:calc(100vw - 1.5rem);--chat--window--height:calc(100vh - 5rem)}}`,\n\n // Overflow: pod names, image refs and URLs have no break opportunity, and\n // break-word will not break a token on a line that already has content.\n `#n8n-chat .chat-message-markdown{overflow-wrap:anywhere}`,\n `#n8n-chat .chat-message-from-bot{max-width:94%}`,\n // Code and tables scroll rather than wrap: a wrapped command copies wrong.\n `#n8n-chat .chat-message-markdown pre,#n8n-chat .chat-message-markdown table{display:block;max-width:100%;overflow-x:auto}`,\n `#n8n-chat .chat-message-markdown pre code{overflow-wrap:normal;white-space:pre}`,\n `#n8n-chat .chat-message-markdown table{border-collapse:collapse;font-size:12px;white-space:nowrap}`,\n `#n8n-chat .chat-message-markdown th,#n8n-chat .chat-message-markdown td{border:1px solid var(--chat--color-light-shade-100,#d4d8dd);padding:3px 8px;text-align:left}`,\n `#n8n-chat .chat-message-markdown img{max-width:100%;height:auto}`,\n\n // Code contrast: Grafana's dark theme styles <code>/<pre> near-white globally,\n // which wins inside the light bubble. Elements only, so highlight.js spans keep\n // their colours.\n `#n8n-chat{--chat--message--pre--background:#f6f8fa}`,\n `#n8n-chat .chat-message-markdown pre,#n8n-chat .chat-message-markdown code{color:#1f2328!important;background:#f6f8fa}`,\n `#n8n-chat .chat-message-markdown pre{border:1px solid #d0d7de}`,\n `#n8n-chat .chat-message-markdown :not(pre)>code{background:#eaeef2;border:1px solid #d0d7de;border-radius:4px;padding:1px 5px;font-size:.92em}`,\n\n // Grafana styles every <textarea> globally: dark background, dark chat text.\n // -webkit-text-fill-color overrides color on WebKit.\n `#n8n-chat textarea{background:#fff!important;color:#14161a!important;-webkit-text-fill-color:#14161a!important;caret-color:#14161a!important;border:1px solid #c7ccd1!important;opacity:1!important}`,\n `#n8n-chat textarea::placeholder{color:#6b7280!important;-webkit-text-fill-color:#6b7280!important;opacity:1!important}`,\n `#n8n-chat .chat-input-send-button{color:#14161a!important}`,\n\n `.n8n-chat-tile{display:block;text-align:center;text-decoration:none;padding-top:6px;color:inherit}`,\n `.n8n-chat-tile .icon{font-size:30px;line-height:1;height:30px}`,\n `.n8n-chat-tile img{height:30px}`,\n // Grafana's legacy `.badge, .label` rule would paint this a grey box; this selector outranks it.\n `.n8n-chat-tile .label{display:block;font-size:12px;font-weight:inherit;line-height:inherit;opacity:.75;margin-top:6px;padding:0;background:none;color:inherit;border-radius:0;text-shadow:none;white-space:normal}`,\n\n // The state card. Colours come from the widget's own properties: .chat-body\n // inherits Grafana's dark-theme text colour, which measured 1.5:1 on the bubble.\n `.n8n-chat-state{display:flex;flex-wrap:wrap;align-items:center;gap:5px 6px;margin:10px 0 0;padding:8px 0 0;` +\n `border-top:1px solid var(--chat--color-medium,#d2d4d9);color:var(--chat--color-dark,#101330);font-size:12px;line-height:1.4}`,\n // With no reply to hang under, the card carries its own edges.\n `.n8n-chat-state.ncs-loose{margin:2px 0 10px;padding:8px 10px;border:1px solid var(--chat--color-medium,#d2d4d9);` +\n `border-left:3px solid #5794f2;border-radius:4px;background:var(--chat--message--bot--background,#fff)}`,\n `.n8n-chat-state .ncs-head{width:100%;margin-bottom:2px;font-size:11px;font-weight:600;letter-spacing:.02em;opacity:.62}`,\n `.n8n-chat-state .ncs-chip{display:inline-flex;align-items:baseline;gap:6px;margin:0;padding:3px 9px;border-radius:11px;` +\n `border:1px solid var(--chat--color-medium,#d2d4d9);background:var(--chat--color-light,#f2f4f8);font:inherit;color:inherit}`,\n `.n8n-chat-state .ncs-chip b{font-weight:600;font-size:10px;text-transform:uppercase;letter-spacing:.05em;opacity:.62}`,\n `.n8n-chat-state .ncs-chip i{font-style:normal}`,\n `.n8n-chat-state button.ncs-go{cursor:pointer}`,\n `.n8n-chat-state button.ncs-go:hover{border-color:#5794f2;background:rgba(87,148,242,.12)}`,\n];\n\nexport const STYLES = parts.join('\\n');\n","import { VERSION } from '../kd/define';\nimport { focusPanel } from '../kd/scene';\nimport { settings, type ChatConfig, type Settings } from './config';\nimport { wrapFetch, type ChatHandle, type ChatWindow } from './fetch';\nimport { cleanHistory } from './history';\nimport { chatMetadata } from './metadata';\nimport { applyState, applyToolCalls, type ToolCalls } from './state';\nimport { controlFilter } from './stream';\nimport { STYLES } from './styles';\n\nexport type CreateChat = (options: Record<string, unknown>) => unknown;\nexport type ChatLoader = (url: string) => Promise<{ createChat: CreateChat }>;\n\n// dist/ on purpose, for both files: the package root's chat.bundle.es.js has no\n// stream reader, and its style.css has no .chat-inputs rules.\nexport const chatBundle = (version: string): string => `https://cdn.jsdelivr.net/npm/@n8n/chat@${version}/dist/chat.bundle.es.js`;\nexport const chatStyle = (version: string): string => `https://cdn.jsdelivr.net/npm/@n8n/chat@${version}/dist/style.css`;\n\nconst CONTROLS = '[data-testid=\"data-testid dashboard controls\"]';\nconst NARROW = 900;\n\n/** Injects the tile's page-global stylesheet once; a newer build's replaces an older one's. */\nexport function injectStyles(doc: Document): void {\n let style = doc.head.querySelector<HTMLStyleElement>('style[data-n8n-chat-tile]');\n if (style?.dataset.n8nChatTile === VERSION) return;\n if (!style) {\n style = doc.createElement('style');\n doc.head.append(style);\n }\n style.dataset.n8nChatTile = VERSION;\n style.textContent = STYLES;\n}\n\nfunction chatStylesheet(doc: Document, version: string): void {\n const href = chatStyle(version);\n let link = doc.head.querySelector<HTMLLinkElement>('link[data-n8n-chat-style]');\n if (link?.getAttribute('href') === href) return;\n if (!link) {\n link = doc.createElement('link');\n link.rel = 'stylesheet';\n link.setAttribute('data-n8n-chat-style', '');\n doc.head.append(link);\n }\n link.href = href;\n}\n\n/** Fills the tile: an `<a>` with `.icon` and `.label` children, or a `<kd-tile>` by its attributes. */\nexport function fillTile(tile: Element, s: Pick<Settings, 'icon' | 'label' | 'link'>): void {\n const external = /^https?:/.test(s.link);\n if (tile.localName === 'kd-tile') {\n for (const [name, value] of [['icon', s.icon], ['label', s.label], ['href', s.link]]) {\n if (value) tile.setAttribute(name, value);\n else tile.removeAttribute(name);\n }\n return;\n }\n const icon = tile.querySelector('.icon');\n if (icon) {\n if (/^(https?:)?\\//.test(s.icon)) {\n const img = tile.ownerDocument.createElement('img');\n img.src = s.icon;\n img.alt = '';\n icon.replaceChildren(img);\n } else {\n icon.textContent = s.icon;\n }\n }\n const label = tile.querySelector('.label');\n if (label) label.textContent = s.label;\n if (s.link) tile.setAttribute('href', s.link);\n else tile.removeAttribute('href');\n if (external) {\n tile.setAttribute('target', '_blank');\n tile.setAttribute('rel', 'noopener');\n } else {\n tile.removeAttribute('target');\n tile.removeAttribute('rel');\n }\n}\n\n/**\n * Pins the chat window's top under Grafana's controls row, which is measured\n * because it grows when the variables wrap and is absent in a kiosk embed. With\n * no row, or below 900px, the inline values go so the stylesheet's apply.\n */\nexport function fitChat(win: Window): void {\n const doc = win.document;\n const root = doc.getElementById('n8n-chat');\n if (!root) return;\n const wrapper = root.querySelector('.chat-window-wrapper');\n const box = doc.querySelector(CONTROLS)?.getBoundingClientRect();\n if (!wrapper || !box || !box.height || win.innerWidth <= NARROW) {\n root.style.removeProperty('--n8n-chat-top');\n root.style.removeProperty('--n8n-chat-reserve');\n return;\n }\n const cs = win.getComputedStyle(wrapper);\n const toggle = root.querySelector('.chat-window-toggle');\n const reserve =\n (parseFloat(cs.bottom) || 14) +\n (toggle ? toggle.getBoundingClientRect().height : 64) +\n (parseFloat(cs.rowGap || cs.gap) || 14);\n root.style.setProperty('--n8n-chat-top', `${Math.round(box.bottom + 10)}px`);\n root.style.setProperty('--n8n-chat-reserve', `${Math.round(reserve)}px`);\n}\n\nfunction removeChat(doc: Document): void {\n doc.querySelectorAll('#n8n-chat, .n8n-chat-widget').forEach((el) => el.remove());\n}\n\nfunction pageOf(config: ChatConfig): { win: ChatWindow; tile: Element | null } {\n const given = config.tile;\n if (given && typeof given === 'object') {\n return { win: (config.window ?? given.ownerDocument.defaultView ?? window) as ChatWindow, tile: given };\n }\n const win = (config.window ?? window) as ChatWindow;\n const tile =\n typeof given === 'string' ? win.document.querySelector(given) : given === null ? null : win.document.getElementById('n8n-chat-tile');\n return { win, tile };\n}\n\nconst load: ChatLoader = (url) => import(/* @vite-ignore */ url);\n\n/**\n * Mounts the chat tile and its n8n chat on the page.\n *\n * Idempotent: the core text panel re-runs its script on every mount, so a\n * repeat call for the same dashboard and settings keeps the chat that is there.\n * Grafana is a single-page app, so the chat lives on `<body>` only while the URL\n * stays on this dashboard. With no webhook it fills the tile and removes any\n * leftover chat.\n *\n * @returns once the chat is created (or at once, tile only)\n */\nexport function mount(config: ChatConfig = {}, loader: ChatLoader = load): Promise<void> {\n const { win, tile } = pageOf(config);\n const doc = win.document;\n const s = settings(config);\n\n injectStyles(doc);\n if (tile) fillTile(tile, s);\n win.dashboardFocus = (target) => focusPanel(win, target);\n\n if (!s.webhook) {\n removeChat(doc);\n win.clearInterval(win.n8nChatWatch);\n win.n8nChat = null;\n win.n8nChatMount = undefined;\n return Promise.resolve();\n }\n\n const home = win.location.pathname;\n const { auth: _auth, ...visible } = s;\n const key = JSON.stringify([home, visible]);\n const current = win.n8nChatMount;\n if (current?.key === key && (!current.done || doc.getElementById('n8n-chat'))) return current.ready;\n\n removeChat(doc);\n win.clearInterval(win.n8nChatWatch);\n win.n8nChatWatch = win.setInterval(() => {\n if (win.location.pathname !== home) {\n removeChat(doc);\n win.clearInterval(win.n8nChatWatch);\n win.n8nChat = null;\n win.n8nChatMount = undefined;\n return;\n }\n // Also re-measures the controls row, whose height changes fire no event.\n win.n8nChatFit?.();\n }, 1000);\n chatStylesheet(doc, s.chatVersion);\n if (!win.n8nChatResize) {\n win.n8nChatResize = true;\n win.addEventListener('resize', () => win.n8nChatFit?.());\n }\n\n const handle: ChatHandle = {\n webhook: s.webhook,\n settable: s.settable,\n stream: s.stream,\n setVariables: (vars, names) => applyState(win, vars, names),\n cleanHistory,\n filterStream: (body) => body.pipeThrough(controlFilter((payload) => applyToolCalls(win, payload as ToolCalls, s.settable))),\n };\n win.n8nChat = handle;\n wrapFetch(win);\n\n const state: NonNullable<ChatWindow['n8nChatMount']> = { key, done: false, ready: Promise.resolve() };\n win.n8nChatMount = state;\n state.ready = (async () => {\n try {\n // Imported after the setup above, so the page is ready before the bundle arrives.\n const { createChat } = await loader(chatBundle(s.chatVersion));\n // A later mount, or leaving the dashboard, while the bundle loaded.\n if (win.n8nChatMount !== state || win.location.pathname !== home) return;\n win.n8nChatFit = () => fitChat(win);\n createChat({\n webhookUrl: s.webhook,\n webhookConfig: { headers: s.auth ? { Authorization: s.auth } : {} },\n chatSessionKey: 'sessionId',\n loadPreviousSession: true,\n enableStreaming: s.stream,\n metadata: chatMetadata(win, s, home),\n showWelcomeScreen: true,\n initialMessages: s.greeting,\n i18n: { en: { title: s.title, subtitle: s.subtitle } },\n });\n // createChat mounts asynchronously.\n win.setTimeout(() => win.n8nChatFit?.(), 200);\n } finally {\n state.done = true;\n }\n })();\n return state.ready;\n}\n"],"mappings":"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"}
package/dist/openapi.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { c as e, l as t, n, o as r, t as i, u as a } from "./chunks/element-ChNBLJ5X.js";
2
- import { n as o, t as s } from "./chunks/define-XzEniRJH.js";
2
+ import { n as o, t as s } from "./chunks/define-BSZoKakE.js";
3
3
  //#region src/openapi/model.ts
4
4
  var c = /* @__PURE__ */ "$ref.type.title.description.format.pattern.default.enum.const.example.examples.minimum.maximum.exclusiveMinimum.exclusiveMaximum.multipleOf.minLength.maxLength.minItems.maxItems.uniqueItems.minProperties.maxProperties.nullable.readOnly.writeOnly.deprecated.externalDocs.required.properties.items.additionalProperties.allOf.anyOf.oneOf.not.x-kubernetes-int-or-string.x-kubernetes-preserve-unknown-fields.x-kubernetes-embedded-resource.x-kubernetes-list-type.x-kubernetes-list-map-keys.x-kubernetes-map-type.x-kubernetes-validations.x-kubernetes-patch-strategy.x-kubernetes-patch-merge-key.x-kubernetes-unions.x-kubernetes-group-version-kind".split("."), l = new Set(c), u = (e) => typeof e == "object" && !!e && !Array.isArray(e), d = "#/components/schemas/";
5
5
  function f(e) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kubed.io/cdn",
3
- "version": "0.0.4",
3
+ "version": "0.0.5",
4
4
  "description": "A theme layer and web components for Grafana panels, loaded by URL from jsDelivr.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -50,5 +50,13 @@
50
50
  },
51
51
  "dependencies": {
52
52
  "lit": "3.3.3"
53
+ },
54
+ "peerDependencies": {
55
+ "@n8n/chat": "1.41.3"
56
+ },
57
+ "peerDependenciesMeta": {
58
+ "@n8n/chat": {
59
+ "optional": true
60
+ }
53
61
  }
54
62
  }