@formulaxjs/renderer-kity 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,46 +1,48 @@
1
1
  # @formulaxjs/renderer-kity
2
2
 
3
- Kity-based read-only renderer for FormulaX.
4
-
5
- `@formulaxjs/renderer-kity` turns LaTeX into inline SVG markup by using the legacy Kity runtime behind the shared `@formulaxjs/renderer` contract. It is the current concrete renderer package for adapters that want runtime SVG output without depending on editor UI helpers.
6
-
7
- > Status: experimental. Public APIs may change before the first stable release.
8
-
9
- ## Install
10
-
11
- ```bash
12
- pnpm add @formulaxjs/renderer-kity
13
- ```
14
-
15
- ## Highlights
3
+ English | [简体中文](https://github.com/vndmea/formulaX/blob/main/packages/renderer-kity/README.zh-CN.md)
16
4
 
5
+ Kity-based read-only renderer for FormulaX.
6
+
7
+ `@formulaxjs/renderer-kity` turns LaTeX into inline SVG markup by using the legacy Kity runtime behind the shared `@formulaxjs/renderer` contract. It is the current concrete renderer package for adapters that want runtime SVG output without depending on editor UI helpers.
8
+
9
+ > Status: experimental. Public APIs may change before the first stable release.
10
+
11
+ ## Install
12
+
13
+ ```bash
14
+ npm install @formulaxjs/renderer-kity
15
+ ```
16
+
17
+ ## Highlights
18
+
17
19
  - `createKityFormulaRenderer`
18
20
  - `renderLatexToSvgMarkup`
19
21
  - `serializeKityFormulaFromRoot`
20
22
  - `waitForKityFormulaSvgLayout`
21
- - cache-safe asset overrides through `assetsVersion`
22
-
23
- ## Example
24
-
25
- ```ts
26
- import { createKityFormulaRenderer } from '@formulaxjs/renderer-kity';
27
-
28
- const renderer = createKityFormulaRenderer({
29
- fontSize: 40,
30
- });
31
-
32
- const result = await renderer.renderLatex('\\frac{a}{b}');
33
-
34
- console.log(result.engine); // kity
35
- console.log(result.html); // inline SVG markup
36
- ```
37
-
38
- If you pass custom runtime asset overrides and want caching to stay enabled, also pass an `assetsVersion` string so different asset sets do not share the same cache entry.
39
-
40
- ## Package role
41
-
42
- Use this package when you want a concrete FormulaX renderer implementation today.
43
-
44
- - It depends on `@formulaxjs/renderer` for shared renderer contracts and SVG helpers.
45
- - It depends on `@formulaxjs/kity-runtime` for the legacy Kity backend.
46
- - It does not depend on `@formulaxjs/editor`.
23
+ - cache-safe asset overrides through `assetCacheKey`
24
+
25
+ ## Example
26
+
27
+ ```ts
28
+ import { createKityFormulaRenderer } from '@formulaxjs/renderer-kity';
29
+
30
+ const renderer = createKityFormulaRenderer({
31
+ fontSize: 40,
32
+ });
33
+
34
+ const result = await renderer.renderLatex('\\frac{a}{b}');
35
+
36
+ console.log(result.engine); // kity
37
+ console.log(result.html); // inline SVG markup
38
+ ```
39
+
40
+ If you pass custom runtime asset overrides and want caching to stay enabled, also pass an `assetCacheKey` string so different asset sets do not share the same cache entry.
41
+
42
+ ## Package role
43
+
44
+ Use this package when you want a concrete FormulaX renderer implementation today.
45
+
46
+ - It depends on `@formulaxjs/renderer` for shared renderer contracts and SVG helpers.
47
+ - It depends on `@formulaxjs/kity-runtime` for the legacy Kity backend.
48
+ - It does not depend on `@formulaxjs/editor`.
@@ -0,0 +1,48 @@
1
+ # @formulaxjs/renderer-kity
2
+
3
+ [English](https://github.com/vndmea/formulaX/blob/main/packages/renderer-kity/README.md) | 简体中文
4
+
5
+ FormulaX 的基于 Kity 的只读 renderer。
6
+
7
+ `@formulaxjs/renderer-kity` 通过共享的 `@formulaxjs/renderer` 协议,利用旧版 Kity runtime 将 LaTeX 转成可内联的 SVG markup。对于需要运行时 SVG 输出、但不想依赖编辑器 UI helper 的 adapter 来说,它是当前的具体 renderer 包。
8
+
9
+ > 状态:实验阶段。在首个稳定版本发布前,公共 API 仍可能调整。
10
+
11
+ ## 安装
12
+
13
+ ```bash
14
+ npm install @formulaxjs/renderer-kity
15
+ ```
16
+
17
+ ## 功能概览
18
+
19
+ - `createKityFormulaRenderer`
20
+ - `renderLatexToSvgMarkup`
21
+ - `serializeKityFormulaFromRoot`
22
+ - `waitForKityFormulaSvgLayout`
23
+ - 通过 `assetCacheKey` 支持安全缓存的资源覆盖
24
+
25
+ ## 示例
26
+
27
+ ```ts
28
+ import { createKityFormulaRenderer } from '@formulaxjs/renderer-kity';
29
+
30
+ const renderer = createKityFormulaRenderer({
31
+ fontSize: 40,
32
+ });
33
+
34
+ const result = await renderer.renderLatex('\\frac{a}{b}');
35
+
36
+ console.log(result.engine); // kity
37
+ console.log(result.html); // inline SVG markup
38
+ ```
39
+
40
+ 如果你传入了自定义 runtime 资源覆盖,并且希望继续启用缓存,请同时传入一个 `assetCacheKey` 字符串,避免不同资源集共用同一条 cache 记录。
41
+
42
+ ## 包职责
43
+
44
+ 当你需要今天就能直接使用的 FormulaX 具体 renderer 实现时,请使用这个包。
45
+
46
+ - 它依赖 `@formulaxjs/renderer` 提供共享 renderer 协议与 SVG helper
47
+ - 它依赖 `@formulaxjs/kity-runtime` 提供旧版 Kity 后端
48
+ - 它不依赖 `@formulaxjs/editor`
package/dist/index.cjs CHANGED
@@ -115,7 +115,7 @@ function createKityFormulaRenderer(defaults = {}) {
115
115
  }
116
116
  function renderLatexToSvgMarkup(latex, options = {}) {
117
117
  const normalizedLatex = latex.trim();
118
- const shouldUseCache = options.cache !== false && !(hasCustomAssetOverrides(options.assets) && !options.assetsVersion);
118
+ const shouldUseCache = options.cache !== false && !(hasCustomAssetOverrides(options.assets) && !options.assetCacheKey);
119
119
  if (!normalizedLatex) {
120
120
  return Promise.resolve({
121
121
  engine: "kity",
@@ -131,7 +131,7 @@ function renderLatexToSvgMarkup(latex, options = {}) {
131
131
  fontSize: options.fontSize,
132
132
  displayMode: options.displayMode,
133
133
  className: options.className,
134
- assetsVersion: options.assetsVersion
134
+ assetCacheKey: options.assetCacheKey
135
135
  });
136
136
  if (shouldUseCache) {
137
137
  const cached = renderCache.get(cacheKey);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/renderer.ts","../src/dom.ts","../src/serialize.ts"],"sourcesContent":["export type { KityFormulaRenderOptions } from './types';\n\nexport {\n createKityFormulaRenderer,\n renderLatexToSvgMarkup,\n} from './renderer';\n\nexport {\n findKityFormulaSvg,\n serializeKityFormulaFromRoot,\n waitForKityFormulaSvgLayout,\n} from './serialize';\n","import {\n createFormulaRenderCacheKey,\n type FormulaRenderer,\n type FormulaRenderResult,\n} from '@formulaxjs/renderer';\nimport { mountKityEditor, type KityEditorAssets } from '@formulaxjs/kity-runtime';\nimport { createHiddenRenderHost } from './dom';\nimport {\n serializeKityFormulaFromRoot,\n waitForKityFormulaSvgLayout,\n} from './serialize';\nimport type { KityFormulaRenderOptions } from './types';\n\nconst renderCache = new Map<string, Promise<FormulaRenderResult>>();\n\nfunction hasCustomAssetOverrides(assets?: Partial<KityEditorAssets>): boolean {\n return Boolean(assets && Object.keys(assets).length > 0);\n}\n\nexport function createKityFormulaRenderer(\n defaults: KityFormulaRenderOptions = {},\n): FormulaRenderer {\n return {\n renderLatex(latex, options = {}) {\n return renderLatexToSvgMarkup(latex, {\n ...defaults,\n ...options,\n });\n },\n };\n}\n\nexport function renderLatexToSvgMarkup(\n latex: string,\n options: KityFormulaRenderOptions = {},\n): Promise<FormulaRenderResult> {\n const normalizedLatex = latex.trim();\n const shouldUseCache = options.cache !== false\n && !(hasCustomAssetOverrides(options.assets) && !options.assetsVersion);\n\n if (!normalizedLatex) {\n return Promise.resolve({\n engine: 'kity',\n output: 'svg',\n latex: normalizedLatex,\n html: '',\n });\n }\n\n const cacheKey = createFormulaRenderCacheKey({\n engine: 'kity',\n latex: normalizedLatex,\n output: 'svg',\n fontSize: options.fontSize,\n displayMode: options.displayMode,\n className: options.className,\n assetsVersion: options.assetsVersion,\n });\n\n if (shouldUseCache) {\n const cached = renderCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n }\n\n const pending = renderLatexToSvgMarkupUncached(normalizedLatex, options);\n\n if (shouldUseCache) {\n renderCache.set(cacheKey, pending);\n pending.catch(() => {\n if (renderCache.get(cacheKey) === pending) {\n renderCache.delete(cacheKey);\n }\n });\n }\n\n return pending;\n}\n\nasync function renderLatexToSvgMarkupUncached(\n latex: string,\n options: KityFormulaRenderOptions,\n): Promise<FormulaRenderResult> {\n if (typeof document === 'undefined') {\n throw new Error('Kity renderer requires a browser document.');\n }\n\n const host = createHiddenRenderHost(document);\n const handle = await mountKityEditor(host, {\n initialLatex: latex,\n height: options.height ?? '100%',\n autofocus: false,\n assets: options.assets,\n render: {\n fontsize: options.fontSize ?? 40,\n },\n });\n\n try {\n await waitForKityFormulaSvgLayout(host);\n\n return {\n engine: 'kity',\n output: 'svg',\n latex,\n html: serializeKityFormulaFromRoot(host),\n };\n } finally {\n handle.destroy();\n host.remove();\n }\n}\n","export function createHiddenRenderHost(doc: Document = document): HTMLElement {\n const host = doc.createElement('div');\n\n host.style.position = 'fixed';\n host.style.left = '-100000px';\n host.style.top = '0';\n host.style.width = '1px';\n host.style.height = '1px';\n host.style.opacity = '0';\n host.style.pointerEvents = 'none';\n host.setAttribute('aria-hidden', 'true');\n\n doc.body.appendChild(host);\n\n return host;\n}\n\nexport async function waitForDocumentFonts(doc: Document): Promise<void> {\n if (!doc.fonts?.ready) return;\n\n try {\n await doc.fonts.ready;\n } catch {\n // Ignore font readiness failures and fall back to frame-based settling.\n }\n}\n\nexport function waitForAnimationFrame(view: Window): Promise<void> {\n return new Promise((resolve) => {\n view.requestAnimationFrame(() => resolve());\n });\n}\n","import {\n readRenderedFormulaSvgBox,\n serializeSvgForInsertion,\n type SvgBox,\n} from '@formulaxjs/renderer';\nimport { waitForAnimationFrame, waitForDocumentFonts } from './dom';\n\nexport function findKityFormulaSvg(root: HTMLElement): SVGSVGElement | null {\n return root.querySelector<SVGSVGElement>(\n '.kf-editor-edit-area svg, .kf-editor-canvas-container svg, svg',\n );\n}\n\nexport function serializeKityFormulaFromRoot(root: HTMLElement): string {\n const svg = findKityFormulaSvg(root);\n\n if (!svg) {\n return '';\n }\n\n return serializeSvgForInsertion(svg);\n}\n\nexport async function waitForKityFormulaSvgLayout(root: HTMLElement): Promise<void> {\n const doc = root.ownerDocument ?? document;\n const view = doc.defaultView ?? window;\n\n await waitForDocumentFonts(doc);\n\n let previous = readRenderedFormulaBox(root);\n\n for (let attempt = 0; attempt < 4; attempt += 1) {\n await waitForAnimationFrame(view);\n const current = readRenderedFormulaBox(root);\n\n if (previous && current && areSvgBoxesClose(previous, current)) {\n return;\n }\n\n previous = current;\n }\n}\n\nfunction readRenderedFormulaBox(root: HTMLElement): SvgBox | null {\n const svg = findKityFormulaSvg(root);\n\n if (!svg) {\n return null;\n }\n\n return readRenderedFormulaSvgBox(svg);\n}\n\nfunction areSvgBoxesClose(left: SvgBox, right: SvgBox): boolean {\n return Math.abs(left.x - right.x) < 0.01\n && Math.abs(left.y - right.y) < 0.01\n && Math.abs(left.width - right.width) < 0.01\n && Math.abs(left.height - right.height) < 0.01;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,IAAAA,mBAIO;AACP,0BAAuD;;;ACLhD,SAAS,uBAAuB,MAAgB,UAAuB;AAC5E,QAAM,OAAO,IAAI,cAAc,KAAK;AAEpC,OAAK,MAAM,WAAW;AACtB,OAAK,MAAM,OAAO;AAClB,OAAK,MAAM,MAAM;AACjB,OAAK,MAAM,QAAQ;AACnB,OAAK,MAAM,SAAS;AACpB,OAAK,MAAM,UAAU;AACrB,OAAK,MAAM,gBAAgB;AAC3B,OAAK,aAAa,eAAe,MAAM;AAEvC,MAAI,KAAK,YAAY,IAAI;AAEzB,SAAO;AACT;AAEA,eAAsB,qBAAqB,KAA8B;AACvE,MAAI,CAAC,IAAI,OAAO,MAAO;AAEvB,MAAI;AACF,UAAM,IAAI,MAAM;AAAA,EAClB,QAAQ;AAAA,EAER;AACF;AAEO,SAAS,sBAAsB,MAA6B;AACjE,SAAO,IAAI,QAAQ,CAAC,YAAY;AAC9B,SAAK,sBAAsB,MAAM,QAAQ,CAAC;AAAA,EAC5C,CAAC;AACH;;;AC/BA,sBAIO;AAGA,SAAS,mBAAmB,MAAyC;AAC1E,SAAO,KAAK;AAAA,IACV;AAAA,EACF;AACF;AAEO,SAAS,6BAA6B,MAA2B;AACtE,QAAM,MAAM,mBAAmB,IAAI;AAEnC,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AAEA,aAAO,0CAAyB,GAAG;AACrC;AAEA,eAAsB,4BAA4B,MAAkC;AAClF,QAAM,MAAM,KAAK,iBAAiB;AAClC,QAAM,OAAO,IAAI,eAAe;AAEhC,QAAM,qBAAqB,GAAG;AAE9B,MAAI,WAAW,uBAAuB,IAAI;AAE1C,WAAS,UAAU,GAAG,UAAU,GAAG,WAAW,GAAG;AAC/C,UAAM,sBAAsB,IAAI;AAChC,UAAM,UAAU,uBAAuB,IAAI;AAE3C,QAAI,YAAY,WAAW,iBAAiB,UAAU,OAAO,GAAG;AAC9D;AAAA,IACF;AAEA,eAAW;AAAA,EACb;AACF;AAEA,SAAS,uBAAuB,MAAkC;AAChE,QAAM,MAAM,mBAAmB,IAAI;AAEnC,MAAI,CAAC,KAAK;AACR,WAAO;AAAA,EACT;AAEA,aAAO,2CAA0B,GAAG;AACtC;AAEA,SAAS,iBAAiB,MAAc,OAAwB;AAC9D,SAAO,KAAK,IAAI,KAAK,IAAI,MAAM,CAAC,IAAI,QAC/B,KAAK,IAAI,KAAK,IAAI,MAAM,CAAC,IAAI,QAC7B,KAAK,IAAI,KAAK,QAAQ,MAAM,KAAK,IAAI,QACrC,KAAK,IAAI,KAAK,SAAS,MAAM,MAAM,IAAI;AAC9C;;;AF7CA,IAAM,cAAc,oBAAI,IAA0C;AAElE,SAAS,wBAAwB,QAA6C;AAC5E,SAAO,QAAQ,UAAU,OAAO,KAAK,MAAM,EAAE,SAAS,CAAC;AACzD;AAEO,SAAS,0BACd,WAAqC,CAAC,GACrB;AACjB,SAAO;AAAA,IACL,YAAY,OAAO,UAAU,CAAC,GAAG;AAC/B,aAAO,uBAAuB,OAAO;AAAA,QACnC,GAAG;AAAA,QACH,GAAG;AAAA,MACL,CAAC;AAAA,IACH;AAAA,EACF;AACF;AAEO,SAAS,uBACd,OACA,UAAoC,CAAC,GACP;AAC9B,QAAM,kBAAkB,MAAM,KAAK;AACnC,QAAM,iBAAiB,QAAQ,UAAU,SACpC,EAAE,wBAAwB,QAAQ,MAAM,KAAK,CAAC,QAAQ;AAE3D,MAAI,CAAC,iBAAiB;AACpB,WAAO,QAAQ,QAAQ;AAAA,MACrB,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,MAAM;AAAA,IACR,CAAC;AAAA,EACH;AAEA,QAAM,eAAW,8CAA4B;AAAA,IAC3C,QAAQ;AAAA,IACR,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,UAAU,QAAQ;AAAA,IAClB,aAAa,QAAQ;AAAA,IACrB,WAAW,QAAQ;AAAA,IACnB,eAAe,QAAQ;AAAA,EACzB,CAAC;AAED,MAAI,gBAAgB;AAClB,UAAM,SAAS,YAAY,IAAI,QAAQ;AACvC,QAAI,QAAQ;AACV,aAAO;AAAA,IACT;AAAA,EACF;AAEA,QAAM,UAAU,+BAA+B,iBAAiB,OAAO;AAEvE,MAAI,gBAAgB;AAClB,gBAAY,IAAI,UAAU,OAAO;AACjC,YAAQ,MAAM,MAAM;AAClB,UAAI,YAAY,IAAI,QAAQ,MAAM,SAAS;AACzC,oBAAY,OAAO,QAAQ;AAAA,MAC7B;AAAA,IACF,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAEA,eAAe,+BACb,OACA,SAC8B;AAC9B,MAAI,OAAO,aAAa,aAAa;AACnC,UAAM,IAAI,MAAM,4CAA4C;AAAA,EAC9D;AAEA,QAAM,OAAO,uBAAuB,QAAQ;AAC5C,QAAM,SAAS,UAAM,qCAAgB,MAAM;AAAA,IACzC,cAAc;AAAA,IACd,QAAQ,QAAQ,UAAU;AAAA,IAC1B,WAAW;AAAA,IACX,QAAQ,QAAQ;AAAA,IAChB,QAAQ;AAAA,MACN,UAAU,QAAQ,YAAY;AAAA,IAChC;AAAA,EACF,CAAC;AAED,MAAI;AACF,UAAM,4BAA4B,IAAI;AAEtC,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,MAAM,6BAA6B,IAAI;AAAA,IACzC;AAAA,EACF,UAAE;AACA,WAAO,QAAQ;AACf,SAAK,OAAO;AAAA,EACd;AACF;","names":["import_renderer"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/renderer.ts","../src/dom.ts","../src/serialize.ts"],"sourcesContent":["export type { KityFormulaRenderOptions } from './types';\n\nexport {\n createKityFormulaRenderer,\n renderLatexToSvgMarkup,\n} from './renderer';\n\nexport {\n findKityFormulaSvg,\n serializeKityFormulaFromRoot,\n waitForKityFormulaSvgLayout,\n} from './serialize';\n","import {\n createFormulaRenderCacheKey,\n type FormulaRenderer,\n type FormulaRenderResult,\n} from '@formulaxjs/renderer';\nimport { mountKityEditor, type KityEditorAssets } from '@formulaxjs/kity-runtime';\nimport { createHiddenRenderHost } from './dom';\nimport {\n serializeKityFormulaFromRoot,\n waitForKityFormulaSvgLayout,\n} from './serialize';\nimport type { KityFormulaRenderOptions } from './types';\n\nconst renderCache = new Map<string, Promise<FormulaRenderResult>>();\n\nfunction hasCustomAssetOverrides(assets?: Partial<KityEditorAssets>): boolean {\n return Boolean(assets && Object.keys(assets).length > 0);\n}\n\nexport function createKityFormulaRenderer(\n defaults: KityFormulaRenderOptions = {},\n): FormulaRenderer {\n return {\n renderLatex(latex, options = {}) {\n return renderLatexToSvgMarkup(latex, {\n ...defaults,\n ...options,\n });\n },\n };\n}\n\nexport function renderLatexToSvgMarkup(\n latex: string,\n options: KityFormulaRenderOptions = {},\n): Promise<FormulaRenderResult> {\n const normalizedLatex = latex.trim();\n const shouldUseCache = options.cache !== false\n && !(hasCustomAssetOverrides(options.assets) && !options.assetCacheKey);\n\n if (!normalizedLatex) {\n return Promise.resolve({\n engine: 'kity',\n output: 'svg',\n latex: normalizedLatex,\n html: '',\n });\n }\n\n const cacheKey = createFormulaRenderCacheKey({\n engine: 'kity',\n latex: normalizedLatex,\n output: 'svg',\n fontSize: options.fontSize,\n displayMode: options.displayMode,\n className: options.className,\n assetCacheKey: options.assetCacheKey,\n });\n\n if (shouldUseCache) {\n const cached = renderCache.get(cacheKey);\n if (cached) {\n return cached;\n }\n }\n\n const pending = renderLatexToSvgMarkupUncached(normalizedLatex, options);\n\n if (shouldUseCache) {\n renderCache.set(cacheKey, pending);\n pending.catch(() => {\n if (renderCache.get(cacheKey) === pending) {\n renderCache.delete(cacheKey);\n }\n });\n }\n\n return pending;\n}\n\nasync function renderLatexToSvgMarkupUncached(\n latex: string,\n options: KityFormulaRenderOptions,\n): Promise<FormulaRenderResult> {\n if (typeof document === 'undefined') {\n throw new Error('Kity renderer requires a browser document.');\n }\n\n const host = createHiddenRenderHost(document);\n const handle = await mountKityEditor(host, {\n initialLatex: latex,\n height: options.height ?? '100%',\n autofocus: false,\n assets: options.assets,\n render: {\n fontsize: options.fontSize ?? 40,\n },\n });\n\n try {\n await waitForKityFormulaSvgLayout(host);\n\n return {\n engine: 'kity',\n output: 'svg',\n latex,\n html: serializeKityFormulaFromRoot(host),\n };\n } finally {\n handle.destroy();\n host.remove();\n }\n}\n","export function createHiddenRenderHost(doc: Document = document): HTMLElement {\n const host = doc.createElement('div');\n\n host.style.position = 'fixed';\n host.style.left = '-100000px';\n host.style.top = '0';\n host.style.width = '1px';\n host.style.height = '1px';\n host.style.opacity = '0';\n host.style.pointerEvents = 'none';\n host.setAttribute('aria-hidden', 'true');\n\n doc.body.appendChild(host);\n\n return host;\n}\n\nexport async function waitForDocumentFonts(doc: Document): Promise<void> {\n if (!doc.fonts?.ready) return;\n\n try {\n await doc.fonts.ready;\n } catch {\n // Ignore font readiness failures and fall back to frame-based settling.\n }\n}\n\nexport function waitForAnimationFrame(view: Window): Promise<void> {\n return new Promise((resolve) => {\n view.requestAnimationFrame(() => resolve());\n });\n}\n","import {\n readRenderedFormulaSvgBox,\n serializeSvgForInsertion,\n type SvgBox,\n} from '@formulaxjs/renderer';\nimport { waitForAnimationFrame, waitForDocumentFonts } from './dom';\n\nexport function findKityFormulaSvg(root: HTMLElement): SVGSVGElement | null {\n return root.querySelector<SVGSVGElement>(\n '.kf-editor-edit-area svg, .kf-editor-canvas-container svg, svg',\n );\n}\n\nexport function serializeKityFormulaFromRoot(root: HTMLElement): string {\n const svg = findKityFormulaSvg(root);\n\n if (!svg) {\n return '';\n }\n\n return serializeSvgForInsertion(svg);\n}\n\nexport async function waitForKityFormulaSvgLayout(root: HTMLElement): Promise<void> {\n const doc = root.ownerDocument ?? document;\n const view = doc.defaultView ?? window;\n\n await waitForDocumentFonts(doc);\n\n let previous = readRenderedFormulaBox(root);\n\n for (let attempt = 0; attempt < 4; attempt += 1) {\n await waitForAnimationFrame(view);\n const current = readRenderedFormulaBox(root);\n\n if (previous && current && areSvgBoxesClose(previous, current)) {\n return;\n }\n\n previous = current;\n }\n}\n\nfunction readRenderedFormulaBox(root: HTMLElement): SvgBox | null {\n const svg = findKityFormulaSvg(root);\n\n if (!svg) {\n return null;\n }\n\n return readRenderedFormulaSvgBox(svg);\n}\n\nfunction areSvgBoxesClose(left: SvgBox, right: SvgBox): boolean {\n return Math.abs(left.x - right.x) < 0.01\n && Math.abs(left.y - right.y) < 0.01\n && Math.abs(left.width - right.width) < 0.01\n && Math.abs(left.height - right.height) < 0.01;\n}\n"],"mappings":"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","names":["import_renderer"]}