@yumiai/chat-widget 0.2.0 → 0.2.2

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.
Files changed (100) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +1 -1
  3. package/dist/ExcelCore-EAXQMKZT.js +10 -0
  4. package/dist/{ExcelViewer-3YLLYYIQ.js → ExcelViewer-OGWM52ZT.js} +2 -3
  5. package/dist/{ExcelViewer-3YLLYYIQ.js.map → ExcelViewer-OGWM52ZT.js.map} +1 -1
  6. package/dist/{GerberViewerA2UI-X5FWAD5M.js → GerberViewerA2UI-AORHOCF6.js} +2 -3
  7. package/dist/{GerberViewerA2UI-X5FWAD5M.js.map → GerberViewerA2UI-AORHOCF6.js.map} +1 -1
  8. package/dist/{GraphStatsLegend-D5bPeXB_.d.cts → GraphStatsLegend-CV0Y3-cP.d.cts} +39 -0
  9. package/dist/{GraphStatsLegend-D5bPeXB_.d.ts → GraphStatsLegend-CV0Y3-cP.d.ts} +39 -0
  10. package/dist/JsonRenderStandalone-L5ROJ6XP.js +17 -0
  11. package/dist/{KicadViewer-GV6ZC4AQ.js → KicadViewer-H6YY6WVC.js} +3 -4
  12. package/dist/{KicadViewer-GV6ZC4AQ.js.map → KicadViewer-H6YY6WVC.js.map} +1 -1
  13. package/dist/KicadViewerCore-XVJE2FTQ.js +10 -0
  14. package/dist/{PdfViewer-CHPDRK46.js → PdfViewer-GKVDDNCZ.js} +9 -10
  15. package/dist/{PdfViewer-CHPDRK46.js.map → PdfViewer-GKVDDNCZ.js.map} +1 -1
  16. package/dist/{PdfViewerCore-HJPEHSRA.js → PdfViewerCore-SUVXHXYO.js} +24 -11
  17. package/dist/PdfViewerCore-SUVXHXYO.js.map +1 -0
  18. package/dist/PowerPointCore-IZ4G6HEQ.js +10 -0
  19. package/dist/{PowerPointViewer-LQTO6UCU.js → PowerPointViewer-5R2KSWWJ.js} +2 -3
  20. package/dist/{PowerPointViewer-LQTO6UCU.js.map → PowerPointViewer-5R2KSWWJ.js.map} +1 -1
  21. package/dist/{StepViewerCore-7W3L3R4E.js → StepViewerCore-RORWXIRU.js} +2 -3
  22. package/dist/{StepViewerCore-7W3L3R4E.js.map → StepViewerCore-RORWXIRU.js.map} +1 -1
  23. package/dist/{ThreeViewerCore-N3QJD5QI.js → ThreeViewerCore-GTUZKD5V.js} +2 -3
  24. package/dist/{ThreeViewerCore-N3QJD5QI.js.map → ThreeViewerCore-GTUZKD5V.js.map} +1 -1
  25. package/dist/WordCore-QFG5HTYD.js +10 -0
  26. package/dist/{WordViewer-ZHCQMHOH.js → WordViewer-7XUQFS4A.js} +2 -3
  27. package/dist/{WordViewer-ZHCQMHOH.js.map → WordViewer-7XUQFS4A.js.map} +1 -1
  28. package/dist/{chunk-QLVPIM6R.js → chunk-3CNQONCV.js} +79 -1
  29. package/dist/chunk-3CNQONCV.js.map +1 -0
  30. package/dist/{chunk-2UC7YLVX.js → chunk-3LOSHCSH.js} +3 -3
  31. package/dist/chunk-5VUKEGFC.js +108 -0
  32. package/dist/chunk-5VUKEGFC.js.map +1 -0
  33. package/dist/chunk-AO4YUJQT.js +479 -0
  34. package/dist/chunk-AO4YUJQT.js.map +1 -0
  35. package/dist/{chunk-KQV7IKET.js → chunk-ASV4TISB.js} +2 -2
  36. package/dist/{chunk-CFKGNAJM.js → chunk-AT6VLLOO.js} +15 -15
  37. package/dist/{chunk-56WRZM3R.js → chunk-EYWNUJVZ.js} +3 -3
  38. package/dist/{chunk-K4KGNVL5.js → chunk-EZ46FGQ6.js} +3 -3
  39. package/dist/{chunk-GYXTSY22.js → chunk-KXPR6SRW.js} +4 -4
  40. package/dist/{chunk-7S67DOHQ.js → chunk-MTN6SUUQ.js} +2 -2
  41. package/dist/chunk-Q5PLT3AI.js +29 -0
  42. package/dist/chunk-Q5PLT3AI.js.map +1 -0
  43. package/dist/{chunk-PZXSASDY.js → chunk-R5LHMOAC.js} +3 -3
  44. package/dist/chunk-X67V7257.js +238 -0
  45. package/dist/chunk-X67V7257.js.map +1 -0
  46. package/dist/citationContext-CILHTO2Z.js +25 -0
  47. package/dist/components/JsonRender/standalone.cjs +56 -9753
  48. package/dist/components/JsonRender/standalone.cjs.map +1 -1
  49. package/dist/components/JsonRender/standalone.js +10 -11
  50. package/dist/components/JsonRender/standalone.js.map +1 -1
  51. package/dist/{gerber-2d-entry-OQ4SQRBY.js → gerber-2d-entry-HEFXQGBK.js} +5 -9
  52. package/dist/{gerber-2d-entry-OQ4SQRBY.js.map → gerber-2d-entry-HEFXQGBK.js.map} +1 -1
  53. package/dist/{gerber-3d-entry-DEHDBOO2.js → gerber-3d-entry-KVTONA37.js} +5 -9
  54. package/dist/{gerber-3d-entry-DEHDBOO2.js.map → gerber-3d-entry-KVTONA37.js.map} +1 -1
  55. package/dist/{gerber-simulation-entry-EBDX72XE.js → gerber-simulation-entry-GZ62QX5H.js} +5 -9
  56. package/dist/{gerber-simulation-entry-EBDX72XE.js.map → gerber-simulation-entry-GZ62QX5H.js.map} +1 -1
  57. package/dist/index.cjs +6690 -13472
  58. package/dist/index.cjs.map +1 -1
  59. package/dist/index.css +776 -4
  60. package/dist/index.css.map +1 -1
  61. package/dist/index.d.cts +979 -26
  62. package/dist/index.d.ts +979 -26
  63. package/dist/index.js +4350 -1859
  64. package/dist/index.js.map +1 -1
  65. package/dist/provenance/index.cjs +78 -0
  66. package/dist/provenance/index.cjs.map +1 -1
  67. package/dist/provenance/index.d.cts +2 -2
  68. package/dist/provenance/index.d.ts +2 -2
  69. package/dist/provenance/index.js +2 -3
  70. package/dist/{resolveToArrayBuffer-AQIDZHSQ.js → resolveToArrayBuffer-PVSVIAII.js} +1 -3
  71. package/dist/{resolveToArrayBuffer-AQIDZHSQ.js.map → resolveToArrayBuffer-PVSVIAII.js.map} +1 -1
  72. package/dist/sseAdapter-LFXYGYC4.js +8 -0
  73. package/dist/sseAdapter-LFXYGYC4.js.map +1 -0
  74. package/package.json +4 -1
  75. package/dist/ExcelCore-DJOIVQMI.js +0 -11
  76. package/dist/JsonRenderStandalone-EIZM62JU.js +0 -18
  77. package/dist/KicadViewerCore-U7BWZHKJ.js +0 -11
  78. package/dist/PdfViewerCore-HJPEHSRA.js.map +0 -1
  79. package/dist/PowerPointCore-FPDR2BL4.js +0 -11
  80. package/dist/WordCore-JKSXK2XD.js +0 -11
  81. package/dist/chunk-7A4FY6FK.js +0 -10226
  82. package/dist/chunk-7A4FY6FK.js.map +0 -1
  83. package/dist/chunk-7D4SUZUM.js +0 -38
  84. package/dist/chunk-QLVPIM6R.js.map +0 -1
  85. package/dist/chunk-VXJWGLZ7.js +0 -21
  86. package/dist/chunk-VXJWGLZ7.js.map +0 -1
  87. /package/dist/{ExcelCore-DJOIVQMI.js.map → ExcelCore-EAXQMKZT.js.map} +0 -0
  88. /package/dist/{JsonRenderStandalone-EIZM62JU.js.map → JsonRenderStandalone-L5ROJ6XP.js.map} +0 -0
  89. /package/dist/{KicadViewerCore-U7BWZHKJ.js.map → KicadViewerCore-XVJE2FTQ.js.map} +0 -0
  90. /package/dist/{PowerPointCore-FPDR2BL4.js.map → PowerPointCore-IZ4G6HEQ.js.map} +0 -0
  91. /package/dist/{WordCore-JKSXK2XD.js.map → WordCore-QFG5HTYD.js.map} +0 -0
  92. /package/dist/{chunk-2UC7YLVX.js.map → chunk-3LOSHCSH.js.map} +0 -0
  93. /package/dist/{chunk-KQV7IKET.js.map → chunk-ASV4TISB.js.map} +0 -0
  94. /package/dist/{chunk-CFKGNAJM.js.map → chunk-AT6VLLOO.js.map} +0 -0
  95. /package/dist/{chunk-56WRZM3R.js.map → chunk-EYWNUJVZ.js.map} +0 -0
  96. /package/dist/{chunk-K4KGNVL5.js.map → chunk-EZ46FGQ6.js.map} +0 -0
  97. /package/dist/{chunk-GYXTSY22.js.map → chunk-KXPR6SRW.js.map} +0 -0
  98. /package/dist/{chunk-7S67DOHQ.js.map → chunk-MTN6SUUQ.js.map} +0 -0
  99. /package/dist/{chunk-PZXSASDY.js.map → chunk-R5LHMOAC.js.map} +0 -0
  100. /package/dist/{chunk-7D4SUZUM.js.map → citationContext-CILHTO2Z.js.map} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,21 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.2] - 2026-05-31
4
+
5
+ ### Fixed
6
+
7
+ - **进入历史对话时置顶区不再先闪 `(历史消息)` 占位**:后端会把 a2ui/GenUI 内容作为一个 `interaction_id="genui"` 的独立 round 下发(无 `user_input`),历史模式下 `convertTurnsToRounds` 会给它填占位文案 `(历史消息)`。此前置顶/钉选逻辑仅判断 `userMessage` 是否非空,导致刚进对话把这个 genui 续作 round 误钉到顶,滚动后才恢复。
8
+ - `Round` 新增 `hasUserMessage` 标记区分「用户提问 round」与「无 `user_input` 的续作 round」(历史 `!!userTurn`、用户乐观插入 `true`、通知自动建立 `false`)。
9
+ - `pinnedRound` 与 `useScrollManager` 的首屏/新 round 钉选逻辑改为只认 `userMessage` 非空且 `hasUserMessage !== false` 的 round;被钉的是续作 round 时回退到其之前最近一条用户提问 round。
10
+
11
+ ## [0.2.1] - 2026-05-19
12
+
13
+ ### Fixed
14
+
15
+ - **完善 `peerDependencies`**:将 `@ant-design/icons` 和 `tailwindcss-scoped-preflight` 加入 `peerDependencies`。0.2.0 的 dist 直接以 bare import 引用这两者,但 package.json 既未声明 dep 也未声明 peerDep,导致下游消费者(如 JetForge frontend)`npm install` 后 vite/rollup 在 `Can't resolve 'tailwindcss-scoped-preflight'` 处崩。`@ant-design/icons` 同款问题,但消费侧若自己已装则巧合可过。
16
+ - `@ant-design/icons`: `^6.0.0 || ^7.0.0`,标记 `optional`(仅在使用相关 icon 时需要)。
17
+ - `tailwindcss-scoped-preflight`: `^4.0.0`,**必需**(chat-widget 的 CSS scoping 依赖它)。
18
+
3
19
  ## [0.2.0] - 2026-05-19
4
20
 
5
21
  聚合自 0.1.2 以来 ~198 次提交,覆盖 **CWRF-001 → CWRF-013** 全部 Phase(P1 ~ P6)和若干 JETP 集成。重点是:a2ui / GenUI 渲染管线落地、shadcn × Tailwind v4 设计体系接入、DashboardLayout / RiskRegister / DataTable 三件套 Split 重构(已删除 legacy 但提供 transformer 自动迁移)、Phase 5 a11y 严格化(axe-core CI gate)、Phase 6 catalog 89 组件三件 contract 形式化。
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # @yumiai/chat-widget
1
+ # @yumiai/chat-widget
2
2
 
3
3
  Agent 对话 UI 组件 — 为 AI Agent 系统提供开箱即用的聊天界面。
4
4
 
@@ -0,0 +1,10 @@
1
+ import {
2
+ ExcelCore,
3
+ ExcelCore_default
4
+ } from "./chunk-EYWNUJVZ.js";
5
+ import "./chunk-Q5PLT3AI.js";
6
+ export {
7
+ ExcelCore,
8
+ ExcelCore_default as default
9
+ };
10
+ //# sourceMappingURL=ExcelCore-EAXQMKZT.js.map
@@ -3,7 +3,6 @@ import {
3
3
  useResource,
4
4
  useResourceContext
5
5
  } from "./chunk-GAMA3VA7.js";
6
- import "./chunk-7D4SUZUM.js";
7
6
 
8
7
  // src/components/JsonRender/domain/ExcelViewer.tsx
9
8
  import React, { useEffect } from "react";
@@ -17,7 +16,7 @@ var SHEET = `
17
16
  }
18
17
  .jr-excel-viewer--error { color: var(--jr-danger, #ef4444); }
19
18
  `;
20
- var LazyExcelCore = React.lazy(() => import("./ExcelCore-DJOIVQMI.js"));
19
+ var LazyExcelCore = React.lazy(() => import("./ExcelCore-EAXQMKZT.js"));
21
20
  var ExcelViewer = ({ props, emit }) => {
22
21
  injectStyles(STYLE_ID, SHEET);
23
22
  const res = useResource({ resource_id: props.resource_id, url: props.url, content: props.content });
@@ -62,4 +61,4 @@ export {
62
61
  ExcelViewer,
63
62
  ExcelViewer_default as default
64
63
  };
65
- //# sourceMappingURL=ExcelViewer-3YLLYYIQ.js.map
64
+ //# sourceMappingURL=ExcelViewer-OGWM52ZT.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/JsonRender/domain/ExcelViewer.tsx"],"sourcesContent":["import React, { useEffect } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport { useResourceContext } from '../../../contexts/ResourceContext.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-excel-viewer'\nconst SHEET = `\n.jr-excel-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 300px; }\n.jr-excel-viewer--loading, .jr-excel-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-excel-viewer--error { color: var(--jr-danger, #ef4444); }\n`\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n content?: string\n title?: string\n sheet?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nconst LazyExcelCore = React.lazy(() => import('../../ViewerCore/ExcelCore.js'))\n\nexport const ExcelViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n const res = useResource({ resource_id: props.resource_id, url: props.url, content: props.content })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: props.resource_id, error: res.error })\n } else {\n emit?.('viewer:loaded', { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName })\n }\n }, [res.loading, res.error])\n\n const ctx = useResourceContext()\n\n if (res.loading) return <div className=\"jr-excel-viewer jr-excel-viewer--loading\">Loading…</div>\n if (res.error) return <div className=\"jr-excel-viewer jr-excel-viewer--error\">{res.error}</div>\n\n const textContent = res.content\n const src = res.url\n const isLegacy = res.fileName?.match(/\\.xls$/i) && !res.fileName?.match(/\\.xlsx$/i)\n\n if (isLegacy && ctx?.resolvePreviewUrl && props.resource_id) {\n return <LegacyFallback resourceId={props.resource_id} ctx={ctx} />\n }\n\n if (textContent) {\n return (\n <div className=\"jr-excel-viewer ycw-excel-viewer\">\n <React.Suspense fallback={<div className=\"jr-excel-viewer--loading\">Loading Excel viewer…</div>}>\n <LazyExcelCore content={textContent} sheet={props.sheet} />\n </React.Suspense>\n </div>\n )\n }\n\n if (!src) return <div className=\"jr-excel-viewer jr-excel-viewer--error\">No spreadsheet source</div>\n\n return (\n <div className=\"jr-excel-viewer ycw-excel-viewer\">\n <React.Suspense fallback={<div className=\"jr-excel-viewer--loading\">Loading Excel viewer…</div>}>\n <LazyExcelCore src={src} sheet={props.sheet} />\n </React.Suspense>\n </div>\n )\n}\n\nconst LegacyFallback: React.FC<{ resourceId: string; ctx: { resolvePreviewUrl?(id: string, fmt: 'html' | 'pdf'): Promise<string> } }> = ({ resourceId, ctx }) => {\n const [previewUrl, setPreviewUrl] = React.useState<string>()\n const [error, setError] = React.useState<string>()\n\n React.useEffect(() => {\n ctx.resolvePreviewUrl?.(resourceId, 'html')\n .then(url => setPreviewUrl(url))\n .catch(err => setError(String(err?.message ?? err)))\n }, [resourceId, ctx])\n\n if (error) return <div className=\"jr-excel-viewer jr-excel-viewer--error\">.xls preview failed: {error}</div>\n if (!previewUrl) return <div className=\"jr-excel-viewer jr-excel-viewer--loading\">Converting .xls…</div>\n\n return (\n <div className=\"jr-excel-viewer\">\n <iframe src={previewUrl} title=\"Excel Preview\" style={{ width: '100%', height: 600, border: 'none' }} />\n </div>\n )\n}\n\nexport default ExcelViewer\n"],"mappings":";;;;;;;;AAAA,OAAO,SAAS,iBAAiB;AA2CP,cA0CN,YA1CM;AAtC1B,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBd,IAAM,gBAAgB,MAAM,KAAK,MAAM,OAAO,yBAA+B,CAAC;AAEvE,IAAM,cAA+B,CAAC,EAAE,OAAO,KAAK,MAAM;AAC/D,eAAa,UAAU,KAAK;AAC5B,QAAM,MAAM,YAAY,EAAE,aAAa,MAAM,aAAa,KAAK,MAAM,KAAK,SAAS,MAAM,QAAQ,CAAC;AAElG,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,MAAM,aAAa,OAAO,IAAI,MAAM,CAAC;AAAA,IAC7E,OAAO;AACL,aAAO,iBAAiB,EAAE,aAAa,MAAM,aAAa,UAAU,IAAI,UAAU,UAAU,IAAI,SAAS,CAAC;AAAA,IAC5G;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAE3B,QAAM,MAAM,mBAAmB;AAE/B,MAAI,IAAI,QAAS,QAAO,oBAAC,SAAI,WAAU,4CAA2C,2BAAQ;AAC1F,MAAI,IAAI,MAAO,QAAO,oBAAC,SAAI,WAAU,0CAA0C,cAAI,OAAM;AAEzF,QAAM,cAAc,IAAI;AACxB,QAAM,MAAM,IAAI;AAChB,QAAM,WAAW,IAAI,UAAU,MAAM,SAAS,KAAK,CAAC,IAAI,UAAU,MAAM,UAAU;AAElF,MAAI,YAAY,KAAK,qBAAqB,MAAM,aAAa;AAC3D,WAAO,oBAAC,kBAAe,YAAY,MAAM,aAAa,KAAU;AAAA,EAClE;AAEA,MAAI,aAAa;AACf,WACE,oBAAC,SAAI,WAAU,oCACb,8BAAC,MAAM,UAAN,EAAe,UAAU,oBAAC,SAAI,WAAU,4BAA2B,wCAAqB,GACvF,8BAAC,iBAAc,SAAS,aAAa,OAAO,MAAM,OAAO,GAC3D,GACF;AAAA,EAEJ;AAEA,MAAI,CAAC,IAAK,QAAO,oBAAC,SAAI,WAAU,0CAAyC,mCAAqB;AAE9F,SACE,oBAAC,SAAI,WAAU,oCACb,8BAAC,MAAM,UAAN,EAAe,UAAU,oBAAC,SAAI,WAAU,4BAA2B,wCAAqB,GACvF,8BAAC,iBAAc,KAAU,OAAO,MAAM,OAAO,GAC/C,GACF;AAEJ;AAEA,IAAM,iBAAkI,CAAC,EAAE,YAAY,IAAI,MAAM;AAC/J,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAiB;AAC3D,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAiB;AAEjD,QAAM,UAAU,MAAM;AACpB,QAAI,oBAAoB,YAAY,MAAM,EACvC,KAAK,SAAO,cAAc,GAAG,CAAC,EAC9B,MAAM,SAAO,SAAS,OAAO,KAAK,WAAW,GAAG,CAAC,CAAC;AAAA,EACvD,GAAG,CAAC,YAAY,GAAG,CAAC;AAEpB,MAAI,MAAO,QAAO,qBAAC,SAAI,WAAU,0CAAyC;AAAA;AAAA,IAAsB;AAAA,KAAM;AACtG,MAAI,CAAC,WAAY,QAAO,oBAAC,SAAI,WAAU,4CAA2C,mCAAgB;AAElG,SACE,oBAAC,SAAI,WAAU,mBACb,8BAAC,YAAO,KAAK,YAAY,OAAM,iBAAgB,OAAO,EAAE,OAAO,QAAQ,QAAQ,KAAK,QAAQ,OAAO,GAAG,GACxG;AAEJ;AAEA,IAAO,sBAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/components/JsonRender/domain/ExcelViewer.tsx"],"sourcesContent":["import React, { useEffect } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport { useResourceContext } from '../../../contexts/ResourceContext.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-excel-viewer'\nconst SHEET = `\n.jr-excel-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 300px; }\n.jr-excel-viewer--loading, .jr-excel-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-excel-viewer--error { color: var(--jr-danger, #ef4444); }\n`\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n content?: string\n title?: string\n sheet?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nconst LazyExcelCore = React.lazy(() => import('../../ViewerCore/ExcelCore.js'))\n\nexport const ExcelViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n const res = useResource({ resource_id: props.resource_id, url: props.url, content: props.content })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: props.resource_id, error: res.error })\n } else {\n emit?.('viewer:loaded', { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName })\n }\n }, [res.loading, res.error])\n\n const ctx = useResourceContext()\n\n if (res.loading) return <div className=\"jr-excel-viewer jr-excel-viewer--loading\">Loading…</div>\n if (res.error) return <div className=\"jr-excel-viewer jr-excel-viewer--error\">{res.error}</div>\n\n const textContent = res.content\n const src = res.url\n const isLegacy = res.fileName?.match(/\\.xls$/i) && !res.fileName?.match(/\\.xlsx$/i)\n\n if (isLegacy && ctx?.resolvePreviewUrl && props.resource_id) {\n return <LegacyFallback resourceId={props.resource_id} ctx={ctx} />\n }\n\n if (textContent) {\n return (\n <div className=\"jr-excel-viewer ycw-excel-viewer\">\n <React.Suspense fallback={<div className=\"jr-excel-viewer--loading\">Loading Excel viewer…</div>}>\n <LazyExcelCore content={textContent} sheet={props.sheet} />\n </React.Suspense>\n </div>\n )\n }\n\n if (!src) return <div className=\"jr-excel-viewer jr-excel-viewer--error\">No spreadsheet source</div>\n\n return (\n <div className=\"jr-excel-viewer ycw-excel-viewer\">\n <React.Suspense fallback={<div className=\"jr-excel-viewer--loading\">Loading Excel viewer…</div>}>\n <LazyExcelCore src={src} sheet={props.sheet} />\n </React.Suspense>\n </div>\n )\n}\n\nconst LegacyFallback: React.FC<{ resourceId: string; ctx: { resolvePreviewUrl?(id: string, fmt: 'html' | 'pdf'): Promise<string> } }> = ({ resourceId, ctx }) => {\n const [previewUrl, setPreviewUrl] = React.useState<string>()\n const [error, setError] = React.useState<string>()\n\n React.useEffect(() => {\n ctx.resolvePreviewUrl?.(resourceId, 'html')\n .then(url => setPreviewUrl(url))\n .catch(err => setError(String(err?.message ?? err)))\n }, [resourceId, ctx])\n\n if (error) return <div className=\"jr-excel-viewer jr-excel-viewer--error\">.xls preview failed: {error}</div>\n if (!previewUrl) return <div className=\"jr-excel-viewer jr-excel-viewer--loading\">Converting .xls…</div>\n\n return (\n <div className=\"jr-excel-viewer\">\n <iframe src={previewUrl} title=\"Excel Preview\" style={{ width: '100%', height: 600, border: 'none' }} />\n </div>\n )\n}\n\nexport default ExcelViewer\n"],"mappings":";;;;;;;AAAA,OAAO,SAAS,iBAAiB;AA2CP,cA0CN,YA1CM;AAtC1B,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAoBd,IAAM,gBAAgB,MAAM,KAAK,MAAM,OAAO,yBAA+B,CAAC;AAEvE,IAAM,cAA+B,CAAC,EAAE,OAAO,KAAK,MAAM;AAC/D,eAAa,UAAU,KAAK;AAC5B,QAAM,MAAM,YAAY,EAAE,aAAa,MAAM,aAAa,KAAK,MAAM,KAAK,SAAS,MAAM,QAAQ,CAAC;AAElG,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,MAAM,aAAa,OAAO,IAAI,MAAM,CAAC;AAAA,IAC7E,OAAO;AACL,aAAO,iBAAiB,EAAE,aAAa,MAAM,aAAa,UAAU,IAAI,UAAU,UAAU,IAAI,SAAS,CAAC;AAAA,IAC5G;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAE3B,QAAM,MAAM,mBAAmB;AAE/B,MAAI,IAAI,QAAS,QAAO,oBAAC,SAAI,WAAU,4CAA2C,2BAAQ;AAC1F,MAAI,IAAI,MAAO,QAAO,oBAAC,SAAI,WAAU,0CAA0C,cAAI,OAAM;AAEzF,QAAM,cAAc,IAAI;AACxB,QAAM,MAAM,IAAI;AAChB,QAAM,WAAW,IAAI,UAAU,MAAM,SAAS,KAAK,CAAC,IAAI,UAAU,MAAM,UAAU;AAElF,MAAI,YAAY,KAAK,qBAAqB,MAAM,aAAa;AAC3D,WAAO,oBAAC,kBAAe,YAAY,MAAM,aAAa,KAAU;AAAA,EAClE;AAEA,MAAI,aAAa;AACf,WACE,oBAAC,SAAI,WAAU,oCACb,8BAAC,MAAM,UAAN,EAAe,UAAU,oBAAC,SAAI,WAAU,4BAA2B,wCAAqB,GACvF,8BAAC,iBAAc,SAAS,aAAa,OAAO,MAAM,OAAO,GAC3D,GACF;AAAA,EAEJ;AAEA,MAAI,CAAC,IAAK,QAAO,oBAAC,SAAI,WAAU,0CAAyC,mCAAqB;AAE9F,SACE,oBAAC,SAAI,WAAU,oCACb,8BAAC,MAAM,UAAN,EAAe,UAAU,oBAAC,SAAI,WAAU,4BAA2B,wCAAqB,GACvF,8BAAC,iBAAc,KAAU,OAAO,MAAM,OAAO,GAC/C,GACF;AAEJ;AAEA,IAAM,iBAAkI,CAAC,EAAE,YAAY,IAAI,MAAM;AAC/J,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAiB;AAC3D,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAiB;AAEjD,QAAM,UAAU,MAAM;AACpB,QAAI,oBAAoB,YAAY,MAAM,EACvC,KAAK,SAAO,cAAc,GAAG,CAAC,EAC9B,MAAM,SAAO,SAAS,OAAO,KAAK,WAAW,GAAG,CAAC,CAAC;AAAA,EACvD,GAAG,CAAC,YAAY,GAAG,CAAC;AAEpB,MAAI,MAAO,QAAO,qBAAC,SAAI,WAAU,0CAAyC;AAAA;AAAA,IAAsB;AAAA,KAAM;AACtG,MAAI,CAAC,WAAY,QAAO,oBAAC,SAAI,WAAU,4CAA2C,mCAAgB;AAElG,SACE,oBAAC,SAAI,WAAU,mBACb,8BAAC,YAAO,KAAK,YAAY,OAAM,iBAAgB,OAAO,EAAE,OAAO,QAAQ,QAAQ,KAAK,QAAQ,OAAO,GAAG,GACxG;AAEJ;AAEA,IAAO,sBAAQ;","names":[]}
@@ -1,11 +1,10 @@
1
1
  import {
2
2
  GerberViewer_default
3
- } from "./chunk-GYXTSY22.js";
3
+ } from "./chunk-KXPR6SRW.js";
4
4
  import {
5
5
  injectStyles,
6
6
  useResource
7
7
  } from "./chunk-GAMA3VA7.js";
8
- import "./chunk-7D4SUZUM.js";
9
8
 
10
9
  // src/components/JsonRender/domain/GerberViewerA2UI.tsx
11
10
  import { useEffect, useCallback } from "react";
@@ -54,4 +53,4 @@ export {
54
53
  GerberViewer,
55
54
  GerberViewerA2UI_default as default
56
55
  };
57
- //# sourceMappingURL=GerberViewerA2UI-X5FWAD5M.js.map
56
+ //# sourceMappingURL=GerberViewerA2UI-AORHOCF6.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/JsonRender/domain/GerberViewerA2UI.tsx"],"sourcesContent":["import React, { useEffect, useCallback } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport GerberViewerCore, { type GerberViewMode } from '../../FileViewer/viewers/GerberViewer.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-gerber-viewer'\nconst SHEET = `\n.jr-gerber-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 400px; }\n.jr-gerber-viewer--loading, .jr-gerber-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-gerber-viewer--error { color: var(--jr-danger, #ef4444); }\n`\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n mode?: GerberViewMode\n title?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nexport const GerberViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n const res = useResource({ resource_id: props.resource_id, url: props.url })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: props.resource_id, error: res.error })\n } else {\n emit?.('viewer:loaded', { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName })\n }\n }, [res.loading, res.error])\n\n // CWRF-013 Phase 0 PR #3 — bridge Core mode changes back to the A2UI\n // emit channel so ActionBinding consumers can write the new mode back into\n // the spec (forming a real controlled loop when the catalog `mode` field\n // is bound to a state path).\n const handleModeChange = useCallback(\n (next: GerberViewMode) => {\n emit?.('viewer:mode-change', { resource_id: props.resource_id, mode: next })\n },\n [emit, props.resource_id],\n )\n\n if (res.loading) return <div className=\"jr-gerber-viewer jr-gerber-viewer--loading\">Loading…</div>\n if (res.error) return <div className=\"jr-gerber-viewer jr-gerber-viewer--error\">{res.error}</div>\n\n // When the catalog `mode` field is provided, drive the Core in controlled\n // mode (toggle bar becomes read-only — Agent owns the truth). Otherwise\n // run uncontrolled with default '2d' so legacy specs / external consumers\n // behave exactly as before.\n const isControlled = props.mode !== undefined\n return (\n <div className=\"jr-gerber-viewer\">\n <GerberViewerCore\n url={res.url}\n mode={isControlled ? props.mode : undefined}\n defaultMode={isControlled ? undefined : '2d'}\n onModeChange={handleModeChange}\n />\n </div>\n )\n}\n\nexport default GerberViewer\n"],"mappings":";;;;;;;;;;AAAA,SAAgB,WAAW,mBAAmB;AAiDpB;AA5C1B,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBP,IAAM,eAAgC,CAAC,EAAE,OAAO,KAAK,MAAM;AAChE,eAAa,UAAU,KAAK;AAC5B,QAAM,MAAM,YAAY,EAAE,aAAa,MAAM,aAAa,KAAK,MAAM,IAAI,CAAC;AAE1E,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,MAAM,aAAa,OAAO,IAAI,MAAM,CAAC;AAAA,IAC7E,OAAO;AACL,aAAO,iBAAiB,EAAE,aAAa,MAAM,aAAa,UAAU,IAAI,UAAU,UAAU,IAAI,SAAS,CAAC;AAAA,IAC5G;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAM3B,QAAM,mBAAmB;AAAA,IACvB,CAAC,SAAyB;AACxB,aAAO,sBAAsB,EAAE,aAAa,MAAM,aAAa,MAAM,KAAK,CAAC;AAAA,IAC7E;AAAA,IACA,CAAC,MAAM,MAAM,WAAW;AAAA,EAC1B;AAEA,MAAI,IAAI,QAAS,QAAO,oBAAC,SAAI,WAAU,8CAA6C,2BAAQ;AAC5F,MAAI,IAAI,MAAO,QAAO,oBAAC,SAAI,WAAU,4CAA4C,cAAI,OAAM;AAM3F,QAAM,eAAe,MAAM,SAAS;AACpC,SACE,oBAAC,SAAI,WAAU,oBACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,IAAI;AAAA,MACT,MAAM,eAAe,MAAM,OAAO;AAAA,MAClC,aAAa,eAAe,SAAY;AAAA,MACxC,cAAc;AAAA;AAAA,EAChB,GACF;AAEJ;AAEA,IAAO,2BAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/components/JsonRender/domain/GerberViewerA2UI.tsx"],"sourcesContent":["import React, { useEffect, useCallback } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport GerberViewerCore, { type GerberViewMode } from '../../FileViewer/viewers/GerberViewer.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-gerber-viewer'\nconst SHEET = `\n.jr-gerber-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 400px; }\n.jr-gerber-viewer--loading, .jr-gerber-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-gerber-viewer--error { color: var(--jr-danger, #ef4444); }\n`\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n mode?: GerberViewMode\n title?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nexport const GerberViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n const res = useResource({ resource_id: props.resource_id, url: props.url })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: props.resource_id, error: res.error })\n } else {\n emit?.('viewer:loaded', { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName })\n }\n }, [res.loading, res.error])\n\n // CWRF-013 Phase 0 PR #3 — bridge Core mode changes back to the A2UI\n // emit channel so ActionBinding consumers can write the new mode back into\n // the spec (forming a real controlled loop when the catalog `mode` field\n // is bound to a state path).\n const handleModeChange = useCallback(\n (next: GerberViewMode) => {\n emit?.('viewer:mode-change', { resource_id: props.resource_id, mode: next })\n },\n [emit, props.resource_id],\n )\n\n if (res.loading) return <div className=\"jr-gerber-viewer jr-gerber-viewer--loading\">Loading…</div>\n if (res.error) return <div className=\"jr-gerber-viewer jr-gerber-viewer--error\">{res.error}</div>\n\n // When the catalog `mode` field is provided, drive the Core in controlled\n // mode (toggle bar becomes read-only — Agent owns the truth). Otherwise\n // run uncontrolled with default '2d' so legacy specs / external consumers\n // behave exactly as before.\n const isControlled = props.mode !== undefined\n return (\n <div className=\"jr-gerber-viewer\">\n <GerberViewerCore\n url={res.url}\n mode={isControlled ? props.mode : undefined}\n defaultMode={isControlled ? undefined : '2d'}\n onModeChange={handleModeChange}\n />\n </div>\n )\n}\n\nexport default GerberViewer\n"],"mappings":";;;;;;;;;AAAA,SAAgB,WAAW,mBAAmB;AAiDpB;AA5C1B,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBP,IAAM,eAAgC,CAAC,EAAE,OAAO,KAAK,MAAM;AAChE,eAAa,UAAU,KAAK;AAC5B,QAAM,MAAM,YAAY,EAAE,aAAa,MAAM,aAAa,KAAK,MAAM,IAAI,CAAC;AAE1E,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,MAAM,aAAa,OAAO,IAAI,MAAM,CAAC;AAAA,IAC7E,OAAO;AACL,aAAO,iBAAiB,EAAE,aAAa,MAAM,aAAa,UAAU,IAAI,UAAU,UAAU,IAAI,SAAS,CAAC;AAAA,IAC5G;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAM3B,QAAM,mBAAmB;AAAA,IACvB,CAAC,SAAyB;AACxB,aAAO,sBAAsB,EAAE,aAAa,MAAM,aAAa,MAAM,KAAK,CAAC;AAAA,IAC7E;AAAA,IACA,CAAC,MAAM,MAAM,WAAW;AAAA,EAC1B;AAEA,MAAI,IAAI,QAAS,QAAO,oBAAC,SAAI,WAAU,8CAA6C,2BAAQ;AAC5F,MAAI,IAAI,MAAO,QAAO,oBAAC,SAAI,WAAU,4CAA4C,cAAI,OAAM;AAM3F,QAAM,eAAe,MAAM,SAAS;AACpC,SACE,oBAAC,SAAI,WAAU,oBACb;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,IAAI;AAAA,MACT,MAAM,eAAe,MAAM,OAAO;AAAA,MAClC,aAAa,eAAe,SAAY;AAAA,MACxC,cAAc;AAAA;AAAA,EAChB,GACF;AAEJ;AAEA,IAAO,2BAAQ;","names":[]}
@@ -396,6 +396,45 @@ interface ChatWidgetMessages {
396
396
  'modelPicker.chip.aria': string;
397
397
  'modelPicker.chip.title.available': string;
398
398
  'modelPicker.chip.title.unavailable': string;
399
+ 'modelPicker.search.placeholder': string;
400
+ 'modelPicker.search.aria': string;
401
+ 'modelPicker.search.clear.aria': string;
402
+ 'modelPicker.modality.aria': string;
403
+ 'modelPicker.modality.all': string;
404
+ 'modelPicker.modality.chat': string;
405
+ 'modelPicker.modality.image': string;
406
+ 'modelPicker.modality.video': string;
407
+ 'modelPicker.modality.audio': string;
408
+ 'modelPicker.modality.embedding': string;
409
+ 'modelPicker.modality.realtime': string;
410
+ 'modelPicker.section.recent': string;
411
+ 'modelPicker.section.vendor': string;
412
+ 'modelPicker.section.toggle.expand': string;
413
+ 'modelPicker.section.toggle.collapse': string;
414
+ 'modelPicker.empty.title': string;
415
+ 'modelPicker.empty.hint': string;
416
+ 'modelPicker.vendor.openai': string;
417
+ 'modelPicker.vendor.anthropic': string;
418
+ 'modelPicker.vendor.google': string;
419
+ 'modelPicker.vendor.xai': string;
420
+ 'modelPicker.vendor.alibaba': string;
421
+ 'modelPicker.vendor.zhipu': string;
422
+ 'modelPicker.vendor.moonshot': string;
423
+ 'modelPicker.vendor.bytedance': string;
424
+ 'modelPicker.vendor.deepseek': string;
425
+ 'modelPicker.vendor.minimax': string;
426
+ 'modelPicker.vendor.openrouter': string;
427
+ 'modelPicker.vendor.xiaomi': string;
428
+ 'modelPicker.vendor.other': string;
429
+ 'modelPicker.cap.aria': string;
430
+ 'modelPicker.cap.image.title': string;
431
+ 'modelPicker.cap.video.native.title': string;
432
+ 'modelPicker.cap.video.derived.title': string;
433
+ 'modelPicker.cap.audio.title': string;
434
+ 'modelPicker.cap.tools.title': string;
435
+ 'modelPicker.cap.imageGen.title': string;
436
+ 'modelPicker.cap.videoGen.title': string;
437
+ 'modelPicker.cap.audioGen.title': string;
399
438
  'jr.confirmDialog.cancel': string;
400
439
  'jr.confirmDialog.confirm': string;
401
440
  'jr.confirmDialog.loading': string;
@@ -396,6 +396,45 @@ interface ChatWidgetMessages {
396
396
  'modelPicker.chip.aria': string;
397
397
  'modelPicker.chip.title.available': string;
398
398
  'modelPicker.chip.title.unavailable': string;
399
+ 'modelPicker.search.placeholder': string;
400
+ 'modelPicker.search.aria': string;
401
+ 'modelPicker.search.clear.aria': string;
402
+ 'modelPicker.modality.aria': string;
403
+ 'modelPicker.modality.all': string;
404
+ 'modelPicker.modality.chat': string;
405
+ 'modelPicker.modality.image': string;
406
+ 'modelPicker.modality.video': string;
407
+ 'modelPicker.modality.audio': string;
408
+ 'modelPicker.modality.embedding': string;
409
+ 'modelPicker.modality.realtime': string;
410
+ 'modelPicker.section.recent': string;
411
+ 'modelPicker.section.vendor': string;
412
+ 'modelPicker.section.toggle.expand': string;
413
+ 'modelPicker.section.toggle.collapse': string;
414
+ 'modelPicker.empty.title': string;
415
+ 'modelPicker.empty.hint': string;
416
+ 'modelPicker.vendor.openai': string;
417
+ 'modelPicker.vendor.anthropic': string;
418
+ 'modelPicker.vendor.google': string;
419
+ 'modelPicker.vendor.xai': string;
420
+ 'modelPicker.vendor.alibaba': string;
421
+ 'modelPicker.vendor.zhipu': string;
422
+ 'modelPicker.vendor.moonshot': string;
423
+ 'modelPicker.vendor.bytedance': string;
424
+ 'modelPicker.vendor.deepseek': string;
425
+ 'modelPicker.vendor.minimax': string;
426
+ 'modelPicker.vendor.openrouter': string;
427
+ 'modelPicker.vendor.xiaomi': string;
428
+ 'modelPicker.vendor.other': string;
429
+ 'modelPicker.cap.aria': string;
430
+ 'modelPicker.cap.image.title': string;
431
+ 'modelPicker.cap.video.native.title': string;
432
+ 'modelPicker.cap.video.derived.title': string;
433
+ 'modelPicker.cap.audio.title': string;
434
+ 'modelPicker.cap.tools.title': string;
435
+ 'modelPicker.cap.imageGen.title': string;
436
+ 'modelPicker.cap.videoGen.title': string;
437
+ 'modelPicker.cap.audioGen.title': string;
399
438
  'jr.confirmDialog.cancel': string;
400
439
  'jr.confirmDialog.confirm': string;
401
440
  'jr.confirmDialog.loading': string;
@@ -0,0 +1,17 @@
1
+ import {
2
+ JsonRenderStandalone
3
+ } from "./chunk-AT6VLLOO.js";
4
+ import "./chunk-3LOSHCSH.js";
5
+ import "./chunk-2SKA3F5U.js";
6
+ import "./chunk-KXPR6SRW.js";
7
+ import "./chunk-GAMA3VA7.js";
8
+ import "./chunk-EZ46FGQ6.js";
9
+ import "./chunk-EYWNUJVZ.js";
10
+ import "./chunk-R5LHMOAC.js";
11
+ import "./chunk-Q5PLT3AI.js";
12
+ import "./chunk-MTN6SUUQ.js";
13
+ import "./chunk-3CNQONCV.js";
14
+ export {
15
+ JsonRenderStandalone
16
+ };
17
+ //# sourceMappingURL=JsonRenderStandalone-L5ROJ6XP.js.map
@@ -7,9 +7,8 @@ import {
7
7
  } from "./chunk-GAMA3VA7.js";
8
8
  import {
9
9
  KicadViewerCore_default
10
- } from "./chunk-7S67DOHQ.js";
11
- import "./chunk-QLVPIM6R.js";
12
- import "./chunk-7D4SUZUM.js";
10
+ } from "./chunk-MTN6SUUQ.js";
11
+ import "./chunk-3CNQONCV.js";
13
12
 
14
13
  // src/components/JsonRender/domain/KicadViewer.tsx
15
14
  import { useEffect, useMemo } from "react";
@@ -121,4 +120,4 @@ export {
121
120
  KicadViewer,
122
121
  KicadViewer_default as default
123
122
  };
124
- //# sourceMappingURL=KicadViewer-GV6ZC4AQ.js.map
123
+ //# sourceMappingURL=KicadViewer-H6YY6WVC.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/JsonRender/domain/KicadViewer.tsx","../src/hooks/useKicadProject.ts"],"sourcesContent":["import React, { useEffect, useMemo } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport { useKicadProject } from '../../../hooks/useKicadProject.js'\nimport KicadViewerCore from '../../FileViewer/viewers/KicadViewerCore.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-kicad-viewer'\nconst SHEET = `\n.jr-kicad-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 400px; }\n.jr-kicad-viewer--loading, .jr-kicad-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-kicad-viewer--error { color: var(--jr-danger, #ef4444); }\n.jr-kicad-viewer--warning {\n padding: 0.5rem 1rem; font-size: 0.85rem;\n font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-warning, #f59e0b);\n border-top: 1px solid var(--jr-border, #e2e8f0);\n}\n`\n\nconst isProjectFile = (fn: string) => fn.toLowerCase().endsWith('.kicad_pro')\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n content?: string\n title?: string\n /**\n * CWRF-013 Phase 0 PR #4 — `project_resource_id` is an alias for\n * `resource_id` retained for backward compatibility with prompts\n * generated against the older catalog. When both are provided,\n * `resource_id` wins and a console.warn is emitted. Phase 3 will\n * migrate this field away via the spec migrator.\n */\n project_resource_id?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nexport const KicadViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n\n if (props.resource_id && props.project_resource_id) {\n console.warn(\n '[KicadViewer] both `resource_id` and `project_resource_id` provided; `resource_id` wins. `project_resource_id` is an alias retained for backward compatibility (see CWRF-013 Phase 0 design doc 04_kicad_project_resource_id.md).',\n )\n }\n const effectiveResourceId = props.resource_id ?? props.project_resource_id\n\n const res = useResource({ resource_id: effectiveResourceId, url: props.url, content: props.content })\n\n const text = res.content ?? ''\n const fileName = res.fileName ?? props.title ?? 'file.kicad_sch'\n const gitPath = res.gitPath ?? ''\n\n const isProject = useMemo(\n () => isProjectFile(fileName) && !!gitPath,\n [fileName, gitPath],\n )\n\n const projectResult = useKicadProject({\n proContent: text,\n gitPath,\n enabled: isProject && !res.loading && !res.error,\n })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: effectiveResourceId, error: res.error })\n } else {\n emit?.('viewer:loaded', {\n resource_id: effectiveResourceId,\n mimeType: res.mimeType,\n fileName: res.fileName,\n isProject,\n })\n }\n }, [res.loading, res.error, isProject])\n\n if (res.loading || (isProject && projectResult.loading)) {\n return <div className=\"jr-kicad-viewer jr-kicad-viewer--loading\">Loading…</div>\n }\n if (res.error) {\n return <div className=\"jr-kicad-viewer jr-kicad-viewer--error\">{res.error}</div>\n }\n\n if (isProject && projectResult.files.length > 0) {\n return (\n <div className=\"jr-kicad-viewer\">\n <KicadViewerCore\n content={text}\n fileName={fileName}\n files={projectResult.files}\n />\n {projectResult.error && (\n <div className=\"jr-kicad-viewer--warning\">{projectResult.error}</div>\n )}\n </div>\n )\n }\n\n return (\n <div className=\"jr-kicad-viewer\">\n <KicadViewerCore\n content={text}\n fileName={fileName}\n contentUrl={res.url}\n />\n </div>\n )\n}\n\nexport default KicadViewer\n","import type { KicadFile } from '../components/FileViewer/viewers/KicadViewerCore.js'\nimport { useProjectFiles } from './useProjectFiles.js'\nimport type { UseProjectFilesResult } from './useProjectFiles.js'\n\nconst KICAD_DESIGN_EXTS = [\n '.kicad_sch', '.kicad_pcb', '.kicad_pro',\n '.kicad_sym', '.kicad_mod', '.kicad_wks',\n '.kicad_dru',\n]\n\nexport interface UseKicadProjectOptions {\n proContent: string\n gitPath: string\n enabled: boolean\n}\n\nexport interface UseKicadProjectResult {\n files: KicadFile[]\n loading: boolean\n error: string | null\n}\n\n/**\n * Discover and load all KiCad design files that belong to a project.\n * Thin wrapper over the generic `useProjectFiles` hook, providing\n * KiCad-specific extensions and the `KicadFile` return type.\n */\nexport function useKicadProject(opts: UseKicadProjectOptions): UseKicadProjectResult {\n const result: UseProjectFilesResult = useProjectFiles({\n gitPath: opts.gitPath,\n extensions: KICAD_DESIGN_EXTS,\n enabled: opts.enabled,\n recursive: true,\n generateUrls: false,\n deps: [opts.proContent],\n })\n\n return result as UseKicadProjectResult\n}\n"],"mappings":";;;;;;;;;;;;;;AAAA,SAAgB,WAAW,eAAe;;;ACI1C,IAAM,oBAAoB;AAAA,EACxB;AAAA,EAAc;AAAA,EAAc;AAAA,EAC5B;AAAA,EAAc;AAAA,EAAc;AAAA,EAC5B;AACF;AAmBO,SAAS,gBAAgB,MAAqD;AACnF,QAAM,SAAgC,gBAAgB;AAAA,IACpD,SAAS,KAAK;AAAA,IACd,YAAY;AAAA,IACZ,SAAS,KAAK;AAAA,IACd,WAAW;AAAA,IACX,cAAc;AAAA,IACd,MAAM,CAAC,KAAK,UAAU;AAAA,EACxB,CAAC;AAED,SAAO;AACT;;;AD8CW,cAQL,YARK;AA9EX,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAed,IAAM,gBAAgB,CAAC,OAAe,GAAG,YAAY,EAAE,SAAS,YAAY;AAoBrE,IAAM,cAA+B,CAAC,EAAE,OAAO,KAAK,MAAM;AAC/D,eAAa,UAAU,KAAK;AAE5B,MAAI,MAAM,eAAe,MAAM,qBAAqB;AAClD,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,QAAM,sBAAsB,MAAM,eAAe,MAAM;AAEvD,QAAM,MAAM,YAAY,EAAE,aAAa,qBAAqB,KAAK,MAAM,KAAK,SAAS,MAAM,QAAQ,CAAC;AAEpG,QAAM,OAAO,IAAI,WAAW;AAC5B,QAAM,WAAW,IAAI,YAAY,MAAM,SAAS;AAChD,QAAM,UAAU,IAAI,WAAW;AAE/B,QAAM,YAAY;AAAA,IAChB,MAAM,cAAc,QAAQ,KAAK,CAAC,CAAC;AAAA,IACnC,CAAC,UAAU,OAAO;AAAA,EACpB;AAEA,QAAM,gBAAgB,gBAAgB;AAAA,IACpC,YAAY;AAAA,IACZ;AAAA,IACA,SAAS,aAAa,CAAC,IAAI,WAAW,CAAC,IAAI;AAAA,EAC7C,CAAC;AAED,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,qBAAqB,OAAO,IAAI,MAAM,CAAC;AAAA,IAC/E,OAAO;AACL,aAAO,iBAAiB;AAAA,QACtB,aAAa;AAAA,QACb,UAAU,IAAI;AAAA,QACd,UAAU,IAAI;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,OAAO,SAAS,CAAC;AAEtC,MAAI,IAAI,WAAY,aAAa,cAAc,SAAU;AACvD,WAAO,oBAAC,SAAI,WAAU,4CAA2C,2BAAQ;AAAA,EAC3E;AACA,MAAI,IAAI,OAAO;AACb,WAAO,oBAAC,SAAI,WAAU,0CAA0C,cAAI,OAAM;AAAA,EAC5E;AAEA,MAAI,aAAa,cAAc,MAAM,SAAS,GAAG;AAC/C,WACE,qBAAC,SAAI,WAAU,mBACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS;AAAA,UACT;AAAA,UACA,OAAO,cAAc;AAAA;AAAA,MACvB;AAAA,MACC,cAAc,SACb,oBAAC,SAAI,WAAU,4BAA4B,wBAAc,OAAM;AAAA,OAEnE;AAAA,EAEJ;AAEA,SACE,oBAAC,SAAI,WAAU,mBACb;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT;AAAA,MACA,YAAY,IAAI;AAAA;AAAA,EAClB,GACF;AAEJ;AAEA,IAAO,sBAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/components/JsonRender/domain/KicadViewer.tsx","../src/hooks/useKicadProject.ts"],"sourcesContent":["import React, { useEffect, useMemo } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport { useKicadProject } from '../../../hooks/useKicadProject.js'\nimport KicadViewerCore from '../../FileViewer/viewers/KicadViewerCore.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-kicad-viewer'\nconst SHEET = `\n.jr-kicad-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 400px; }\n.jr-kicad-viewer--loading, .jr-kicad-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-kicad-viewer--error { color: var(--jr-danger, #ef4444); }\n.jr-kicad-viewer--warning {\n padding: 0.5rem 1rem; font-size: 0.85rem;\n font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-warning, #f59e0b);\n border-top: 1px solid var(--jr-border, #e2e8f0);\n}\n`\n\nconst isProjectFile = (fn: string) => fn.toLowerCase().endsWith('.kicad_pro')\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n content?: string\n title?: string\n /**\n * CWRF-013 Phase 0 PR #4 — `project_resource_id` is an alias for\n * `resource_id` retained for backward compatibility with prompts\n * generated against the older catalog. When both are provided,\n * `resource_id` wins and a console.warn is emitted. Phase 3 will\n * migrate this field away via the spec migrator.\n */\n project_resource_id?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nexport const KicadViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n\n if (props.resource_id && props.project_resource_id) {\n console.warn(\n '[KicadViewer] both `resource_id` and `project_resource_id` provided; `resource_id` wins. `project_resource_id` is an alias retained for backward compatibility (see CWRF-013 Phase 0 design doc 04_kicad_project_resource_id.md).',\n )\n }\n const effectiveResourceId = props.resource_id ?? props.project_resource_id\n\n const res = useResource({ resource_id: effectiveResourceId, url: props.url, content: props.content })\n\n const text = res.content ?? ''\n const fileName = res.fileName ?? props.title ?? 'file.kicad_sch'\n const gitPath = res.gitPath ?? ''\n\n const isProject = useMemo(\n () => isProjectFile(fileName) && !!gitPath,\n [fileName, gitPath],\n )\n\n const projectResult = useKicadProject({\n proContent: text,\n gitPath,\n enabled: isProject && !res.loading && !res.error,\n })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: effectiveResourceId, error: res.error })\n } else {\n emit?.('viewer:loaded', {\n resource_id: effectiveResourceId,\n mimeType: res.mimeType,\n fileName: res.fileName,\n isProject,\n })\n }\n }, [res.loading, res.error, isProject])\n\n if (res.loading || (isProject && projectResult.loading)) {\n return <div className=\"jr-kicad-viewer jr-kicad-viewer--loading\">Loading…</div>\n }\n if (res.error) {\n return <div className=\"jr-kicad-viewer jr-kicad-viewer--error\">{res.error}</div>\n }\n\n if (isProject && projectResult.files.length > 0) {\n return (\n <div className=\"jr-kicad-viewer\">\n <KicadViewerCore\n content={text}\n fileName={fileName}\n files={projectResult.files}\n />\n {projectResult.error && (\n <div className=\"jr-kicad-viewer--warning\">{projectResult.error}</div>\n )}\n </div>\n )\n }\n\n return (\n <div className=\"jr-kicad-viewer\">\n <KicadViewerCore\n content={text}\n fileName={fileName}\n contentUrl={res.url}\n />\n </div>\n )\n}\n\nexport default KicadViewer\n","import type { KicadFile } from '../components/FileViewer/viewers/KicadViewerCore.js'\nimport { useProjectFiles } from './useProjectFiles.js'\nimport type { UseProjectFilesResult } from './useProjectFiles.js'\n\nconst KICAD_DESIGN_EXTS = [\n '.kicad_sch', '.kicad_pcb', '.kicad_pro',\n '.kicad_sym', '.kicad_mod', '.kicad_wks',\n '.kicad_dru',\n]\n\nexport interface UseKicadProjectOptions {\n proContent: string\n gitPath: string\n enabled: boolean\n}\n\nexport interface UseKicadProjectResult {\n files: KicadFile[]\n loading: boolean\n error: string | null\n}\n\n/**\n * Discover and load all KiCad design files that belong to a project.\n * Thin wrapper over the generic `useProjectFiles` hook, providing\n * KiCad-specific extensions and the `KicadFile` return type.\n */\nexport function useKicadProject(opts: UseKicadProjectOptions): UseKicadProjectResult {\n const result: UseProjectFilesResult = useProjectFiles({\n gitPath: opts.gitPath,\n extensions: KICAD_DESIGN_EXTS,\n enabled: opts.enabled,\n recursive: true,\n generateUrls: false,\n deps: [opts.proContent],\n })\n\n return result as UseKicadProjectResult\n}\n"],"mappings":";;;;;;;;;;;;;AAAA,SAAgB,WAAW,eAAe;;;ACI1C,IAAM,oBAAoB;AAAA,EACxB;AAAA,EAAc;AAAA,EAAc;AAAA,EAC5B;AAAA,EAAc;AAAA,EAAc;AAAA,EAC5B;AACF;AAmBO,SAAS,gBAAgB,MAAqD;AACnF,QAAM,SAAgC,gBAAgB;AAAA,IACpD,SAAS,KAAK;AAAA,IACd,YAAY;AAAA,IACZ,SAAS,KAAK;AAAA,IACd,WAAW;AAAA,IACX,cAAc;AAAA,IACd,MAAM,CAAC,KAAK,UAAU;AAAA,EACxB,CAAC;AAED,SAAO;AACT;;;AD8CW,cAQL,YARK;AA9EX,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAed,IAAM,gBAAgB,CAAC,OAAe,GAAG,YAAY,EAAE,SAAS,YAAY;AAoBrE,IAAM,cAA+B,CAAC,EAAE,OAAO,KAAK,MAAM;AAC/D,eAAa,UAAU,KAAK;AAE5B,MAAI,MAAM,eAAe,MAAM,qBAAqB;AAClD,YAAQ;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,QAAM,sBAAsB,MAAM,eAAe,MAAM;AAEvD,QAAM,MAAM,YAAY,EAAE,aAAa,qBAAqB,KAAK,MAAM,KAAK,SAAS,MAAM,QAAQ,CAAC;AAEpG,QAAM,OAAO,IAAI,WAAW;AAC5B,QAAM,WAAW,IAAI,YAAY,MAAM,SAAS;AAChD,QAAM,UAAU,IAAI,WAAW;AAE/B,QAAM,YAAY;AAAA,IAChB,MAAM,cAAc,QAAQ,KAAK,CAAC,CAAC;AAAA,IACnC,CAAC,UAAU,OAAO;AAAA,EACpB;AAEA,QAAM,gBAAgB,gBAAgB;AAAA,IACpC,YAAY;AAAA,IACZ;AAAA,IACA,SAAS,aAAa,CAAC,IAAI,WAAW,CAAC,IAAI;AAAA,EAC7C,CAAC;AAED,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,qBAAqB,OAAO,IAAI,MAAM,CAAC;AAAA,IAC/E,OAAO;AACL,aAAO,iBAAiB;AAAA,QACtB,aAAa;AAAA,QACb,UAAU,IAAI;AAAA,QACd,UAAU,IAAI;AAAA,QACd;AAAA,MACF,CAAC;AAAA,IACH;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,OAAO,SAAS,CAAC;AAEtC,MAAI,IAAI,WAAY,aAAa,cAAc,SAAU;AACvD,WAAO,oBAAC,SAAI,WAAU,4CAA2C,2BAAQ;AAAA,EAC3E;AACA,MAAI,IAAI,OAAO;AACb,WAAO,oBAAC,SAAI,WAAU,0CAA0C,cAAI,OAAM;AAAA,EAC5E;AAEA,MAAI,aAAa,cAAc,MAAM,SAAS,GAAG;AAC/C,WACE,qBAAC,SAAI,WAAU,mBACb;AAAA;AAAA,QAAC;AAAA;AAAA,UACC,SAAS;AAAA,UACT;AAAA,UACA,OAAO,cAAc;AAAA;AAAA,MACvB;AAAA,MACC,cAAc,SACb,oBAAC,SAAI,WAAU,4BAA4B,wBAAc,OAAM;AAAA,OAEnE;AAAA,EAEJ;AAEA,SACE,oBAAC,SAAI,WAAU,mBACb;AAAA,IAAC;AAAA;AAAA,MACC,SAAS;AAAA,MACT;AAAA,MACA,YAAY,IAAI;AAAA;AAAA,EAClB,GACF;AAEJ;AAEA,IAAO,sBAAQ;","names":[]}
@@ -0,0 +1,10 @@
1
+ import {
2
+ KICAD_EXTS,
3
+ KicadViewerCore_default
4
+ } from "./chunk-MTN6SUUQ.js";
5
+ import "./chunk-3CNQONCV.js";
6
+ export {
7
+ KICAD_EXTS,
8
+ KicadViewerCore_default as default
9
+ };
10
+ //# sourceMappingURL=KicadViewerCore-XVJE2FTQ.js.map
@@ -1,18 +1,17 @@
1
1
  import {
2
2
  PdfCore
3
- } from "./chunk-2UC7YLVX.js";
4
- import "./chunk-GYXTSY22.js";
5
- import "./chunk-K4KGNVL5.js";
6
- import "./chunk-56WRZM3R.js";
7
- import "./chunk-PZXSASDY.js";
8
- import "./chunk-VXJWGLZ7.js";
3
+ } from "./chunk-3LOSHCSH.js";
4
+ import "./chunk-KXPR6SRW.js";
9
5
  import {
10
6
  injectStyles,
11
7
  useResource
12
8
  } from "./chunk-GAMA3VA7.js";
13
- import "./chunk-7S67DOHQ.js";
14
- import "./chunk-QLVPIM6R.js";
15
- import "./chunk-7D4SUZUM.js";
9
+ import "./chunk-EZ46FGQ6.js";
10
+ import "./chunk-EYWNUJVZ.js";
11
+ import "./chunk-R5LHMOAC.js";
12
+ import "./chunk-Q5PLT3AI.js";
13
+ import "./chunk-MTN6SUUQ.js";
14
+ import "./chunk-3CNQONCV.js";
16
15
 
17
16
  // src/components/JsonRender/domain/PdfViewer.tsx
18
17
  import { useEffect } from "react";
@@ -48,4 +47,4 @@ export {
48
47
  PdfViewer,
49
48
  PdfViewer_default as default
50
49
  };
51
- //# sourceMappingURL=PdfViewer-CHPDRK46.js.map
50
+ //# sourceMappingURL=PdfViewer-GKVDDNCZ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/JsonRender/domain/PdfViewer.tsx"],"sourcesContent":["import React, { useEffect } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport { PdfCore } from '../../ViewerCore/index.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-pdf-viewer'\nconst SHEET = `\n.jr-pdf-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 600px; }\n.jr-pdf-viewer--loading, .jr-pdf-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-pdf-viewer--error { color: var(--jr-danger, #ef4444); }\n`\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n title?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nexport const PdfViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n const res = useResource({ resource_id: props.resource_id, url: props.url })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: props.resource_id, error: res.error })\n } else {\n emit?.('viewer:loaded', { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName })\n }\n }, [res.loading, res.error])\n\n if (res.loading) return <div className=\"jr-pdf-viewer jr-pdf-viewer--loading\">Loading…</div>\n if (res.error) return <div className=\"jr-pdf-viewer jr-pdf-viewer--error\">{res.error}</div>\n\n const src = res.url ?? ''\n if (!src) return <div className=\"jr-pdf-viewer jr-pdf-viewer--error\">No PDF source</div>\n\n return (\n <div className=\"jr-pdf-viewer\">\n <PdfCore src={src} title={props.title} />\n </div>\n )\n}\n\nexport default PdfViewer\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA,SAAgB,iBAAiB;AAqCP;AAhC1B,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBP,IAAM,YAA6B,CAAC,EAAE,OAAO,KAAK,MAAM;AAC7D,eAAa,UAAU,KAAK;AAC5B,QAAM,MAAM,YAAY,EAAE,aAAa,MAAM,aAAa,KAAK,MAAM,IAAI,CAAC;AAE1E,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,MAAM,aAAa,OAAO,IAAI,MAAM,CAAC;AAAA,IAC7E,OAAO;AACL,aAAO,iBAAiB,EAAE,aAAa,MAAM,aAAa,UAAU,IAAI,UAAU,UAAU,IAAI,SAAS,CAAC;AAAA,IAC5G;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAE3B,MAAI,IAAI,QAAS,QAAO,oBAAC,SAAI,WAAU,wCAAuC,2BAAQ;AACtF,MAAI,IAAI,MAAO,QAAO,oBAAC,SAAI,WAAU,sCAAsC,cAAI,OAAM;AAErF,QAAM,MAAM,IAAI,OAAO;AACvB,MAAI,CAAC,IAAK,QAAO,oBAAC,SAAI,WAAU,sCAAqC,2BAAa;AAElF,SACE,oBAAC,SAAI,WAAU,iBACb,8BAAC,WAAQ,KAAU,OAAO,MAAM,OAAO,GACzC;AAEJ;AAEA,IAAO,oBAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/components/JsonRender/domain/PdfViewer.tsx"],"sourcesContent":["import React, { useEffect } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport { PdfCore } from '../../ViewerCore/index.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-pdf-viewer'\nconst SHEET = `\n.jr-pdf-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 600px; }\n.jr-pdf-viewer--loading, .jr-pdf-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-pdf-viewer--error { color: var(--jr-danger, #ef4444); }\n`\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n title?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nexport const PdfViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n const res = useResource({ resource_id: props.resource_id, url: props.url })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: props.resource_id, error: res.error })\n } else {\n emit?.('viewer:loaded', { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName })\n }\n }, [res.loading, res.error])\n\n if (res.loading) return <div className=\"jr-pdf-viewer jr-pdf-viewer--loading\">Loading…</div>\n if (res.error) return <div className=\"jr-pdf-viewer jr-pdf-viewer--error\">{res.error}</div>\n\n const src = res.url ?? ''\n if (!src) return <div className=\"jr-pdf-viewer jr-pdf-viewer--error\">No PDF source</div>\n\n return (\n <div className=\"jr-pdf-viewer\">\n <PdfCore src={src} title={props.title} />\n </div>\n )\n}\n\nexport default PdfViewer\n"],"mappings":";;;;;;;;;;;;;;;;AAAA,SAAgB,iBAAiB;AAqCP;AAhC1B,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBP,IAAM,YAA6B,CAAC,EAAE,OAAO,KAAK,MAAM;AAC7D,eAAa,UAAU,KAAK;AAC5B,QAAM,MAAM,YAAY,EAAE,aAAa,MAAM,aAAa,KAAK,MAAM,IAAI,CAAC;AAE1E,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,MAAM,aAAa,OAAO,IAAI,MAAM,CAAC;AAAA,IAC7E,OAAO;AACL,aAAO,iBAAiB,EAAE,aAAa,MAAM,aAAa,UAAU,IAAI,UAAU,UAAU,IAAI,SAAS,CAAC;AAAA,IAC5G;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAE3B,MAAI,IAAI,QAAS,QAAO,oBAAC,SAAI,WAAU,wCAAuC,2BAAQ;AACtF,MAAI,IAAI,MAAO,QAAO,oBAAC,SAAI,WAAU,sCAAsC,cAAI,OAAM;AAErF,QAAM,MAAM,IAAI,OAAO;AACvB,MAAI,CAAC,IAAK,QAAO,oBAAC,SAAI,WAAU,sCAAqC,2BAAa;AAElF,SACE,oBAAC,SAAI,WAAU,iBACb,8BAAC,WAAQ,KAAU,OAAO,MAAM,OAAO,GACzC;AAEJ;AAEA,IAAO,oBAAQ;","names":[]}
@@ -1,10 +1,9 @@
1
1
  import {
2
2
  useRevokeBlobUrl
3
- } from "./chunk-VXJWGLZ7.js";
3
+ } from "./chunk-Q5PLT3AI.js";
4
4
  import {
5
5
  useChatWidgetI18n
6
- } from "./chunk-QLVPIM6R.js";
7
- import "./chunk-7D4SUZUM.js";
6
+ } from "./chunk-3CNQONCV.js";
8
7
 
9
8
  // src/components/FileViewer/viewers/PdfViewerCore.tsx
10
9
  import { useEffect, useRef, useState, useCallback } from "react";
@@ -23,6 +22,23 @@ if (typeof ReadableStream !== "undefined" && !(Symbol.asyncIterator in ReadableS
23
22
  }
24
23
  };
25
24
  }
25
+ function supportsModernUint8() {
26
+ const proto = Uint8Array.prototype;
27
+ return typeof proto.toHex === "function" && typeof proto.toBase64 === "function" && typeof Uint8Array.fromBase64 === "function";
28
+ }
29
+ var pdfjsLibPromise = null;
30
+ function loadPdfjs() {
31
+ if (pdfjsLibPromise) return pdfjsLibPromise;
32
+ const useLegacy = !supportsModernUint8();
33
+ pdfjsLibPromise = (useLegacy ? import("pdfjs-dist/legacy/build/pdf.mjs") : import("pdfjs-dist")).then((lib) => {
34
+ if (!lib.GlobalWorkerOptions.workerSrc) {
35
+ const buildDir = useLegacy ? "legacy/build" : "build";
36
+ lib.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${lib.version}/${buildDir}/pdf.worker.min.mjs`;
37
+ }
38
+ return lib;
39
+ });
40
+ return pdfjsLibPromise;
41
+ }
26
42
  var BASE_SCALE = 1.333;
27
43
  var ZOOM_STEP = 0.25;
28
44
  var ZOOM_MIN = 0.5;
@@ -245,11 +261,8 @@ var PdfViewerCore = ({ src, className, loadingLabel, onImageSelect }) => {
245
261
  setLoading(true);
246
262
  setError(void 0);
247
263
  setZoom(1);
248
- const pdfjsLib = await import("pdfjs-dist");
249
- if (!pdfjsLib.GlobalWorkerOptions.workerSrc) {
250
- pdfjsLib.GlobalWorkerOptions.workerSrc = `https://cdn.jsdelivr.net/npm/pdfjs-dist@${pdfjsLib.version}/build/pdf.worker.min.mjs`;
251
- }
252
- const { resolveToArrayBuffer } = await import("./resolveToArrayBuffer-AQIDZHSQ.js");
264
+ const pdfjsLib = await loadPdfjs();
265
+ const { resolveToArrayBuffer } = await import("./resolveToArrayBuffer-PVSVIAII.js");
253
266
  const buf = await resolveToArrayBuffer(src);
254
267
  if (cancelled) return;
255
268
  cleanup();
@@ -268,7 +281,7 @@ var PdfViewerCore = ({ src, className, loadingLabel, onImageSelect }) => {
268
281
  const container = containerRef.current;
269
282
  if (!container || cancelled) return;
270
283
  const rid = ++renderIdRef.current;
271
- await renderPages(await import("pdfjs-dist"), pdfDoc, container, 1, rid);
284
+ await renderPages(pdfjsLib, pdfDoc, container, 1, rid);
272
285
  } catch (err) {
273
286
  if (!cancelled) {
274
287
  setError(String(err?.message ?? err));
@@ -287,7 +300,7 @@ var PdfViewerCore = ({ src, className, loadingLabel, onImageSelect }) => {
287
300
  if (!pdfDoc || !container || loading) return;
288
301
  const rid = ++renderIdRef.current;
289
302
  (async () => {
290
- const pdfjsLib = await import("pdfjs-dist");
303
+ const pdfjsLib = await loadPdfjs();
291
304
  await renderPages(pdfjsLib, pdfDoc, container, zoom, rid);
292
305
  })().catch(() => {
293
306
  });
@@ -361,4 +374,4 @@ var PdfViewerCore_default = PdfViewerCore;
361
374
  export {
362
375
  PdfViewerCore_default as default
363
376
  };
364
- //# sourceMappingURL=PdfViewerCore-HJPEHSRA.js.map
377
+ //# sourceMappingURL=PdfViewerCore-SUVXHXYO.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/components/FileViewer/viewers/PdfViewerCore.tsx"],"sourcesContent":["import React, { useEffect, useRef, useState, useCallback } from 'react'\nimport { useRevokeBlobUrl } from '../../ViewerCore/hooks/useRevokeBlobUrl.js'\nimport { useChatWidgetI18n } from '../../../i18n'\n\n// Safari <17.5 lacks ReadableStream async iterator — pdfjs-dist v5 needs it\nif (\n typeof ReadableStream !== 'undefined' &&\n !(Symbol.asyncIterator in ReadableStream.prototype)\n) {\n (ReadableStream.prototype as any)[Symbol.asyncIterator] = async function* (this: ReadableStream) {\n const reader = this.getReader()\n try {\n for (;;) {\n const { done, value } = await reader.read()\n if (done) return\n yield value\n }\n } finally {\n reader.releaseLock()\n }\n }\n}\n\n// pdfjs-dist v5 modern build relies on TC39 arraybuffer-base64 APIs\n// (Uint8Array.prototype.toHex / toBase64 / Uint8Array.fromBase64). Those are\n// available only in Chrome 140+ / Safari 18.4+ / Firefox 137+. On older engines\n// the modern worker throws `n.toHex is not a function`, and the modern main\n// build silently fails inside font (data: URL) rendering, producing blank\n// pages. The legacy build ships core-js polyfills for all of them, so on\n// unsupported engines we MUST load main + worker from legacy in lockstep.\nfunction supportsModernUint8(): boolean {\n const proto: any = Uint8Array.prototype\n return (\n typeof proto.toHex === 'function' &&\n typeof proto.toBase64 === 'function' &&\n typeof (Uint8Array as any).fromBase64 === 'function'\n )\n}\n\nlet pdfjsLibPromise: Promise<any> | null = null\nfunction loadPdfjs(): Promise<any> {\n if (pdfjsLibPromise) return pdfjsLibPromise\n const useLegacy = !supportsModernUint8()\n pdfjsLibPromise = (useLegacy\n ? import('pdfjs-dist/legacy/build/pdf.mjs')\n : import('pdfjs-dist')\n ).then(lib => {\n if (!lib.GlobalWorkerOptions.workerSrc) {\n const buildDir = useLegacy ? 'legacy/build' : 'build'\n lib.GlobalWorkerOptions.workerSrc =\n `https://cdn.jsdelivr.net/npm/pdfjs-dist@${lib.version}/${buildDir}/pdf.worker.min.mjs`\n }\n return lib\n })\n return pdfjsLibPromise\n}\n\nexport interface PdfImageSelection {\n page: number\n imageIndex: number\n imageSrc: string\n rect: DOMRect\n}\n\ninterface PdfViewerCoreProps {\n src: string\n className?: string\n loadingLabel?: string\n onImageSelect?: (sel: PdfImageSelection | null) => void\n}\n\nconst BASE_SCALE = 1.333 // 96dpi / 72pt\nconst ZOOM_STEP = 0.25\nconst ZOOM_MIN = 0.5\nconst ZOOM_MAX = 4\nconst MAX_IMAGES_PER_PAGE = 50\nconst MIN_IMAGE_DIM = 8\n\ntype Img = { src: string; x: number; y: number; w: number; h: number }\n\nfunction mulM(a: number[], b: number[]): number[] {\n return [\n a[0] * b[0] + a[2] * b[1],\n a[1] * b[0] + a[3] * b[1],\n a[0] * b[2] + a[2] * b[3],\n a[1] * b[2] + a[3] * b[3],\n a[0] * b[4] + a[2] * b[5] + a[4],\n a[1] * b[4] + a[3] * b[5] + a[5],\n ]\n}\n\nasync function extractPageImages(page: any, viewport: any, OPS: any): Promise<Img[]> {\n const opList = await page.getOperatorList()\n const results: Img[] = []\n const ID = [1, 0, 0, 1, 0, 0]\n let ctm = ID.slice()\n const stack: number[][] = []\n const vt: number[] = viewport.transform\n\n for (let i = 0; i < opList.fnArray.length; i++) {\n if (results.length >= MAX_IMAGES_PER_PAGE) break\n const fn = opList.fnArray[i]\n const args = opList.argsArray[i]\n\n switch (fn) {\n case OPS.save:\n stack.push(ctm.slice())\n break\n case OPS.restore:\n ctm = stack.pop() || ID.slice()\n break\n case OPS.transform:\n ctm = mulM(ctm, args as number[])\n break\n case OPS.paintImageXObject:\n case OPS.paintJpegXObject: {\n const imgName = args[0]\n try {\n const imgData: any = await new Promise((res, rej) => {\n const timeout = setTimeout(() => rej('timeout'), 2000)\n page.objs.get(imgName, (d: any) => { clearTimeout(timeout); res(d) })\n })\n if (!imgData || (!imgData.data && !imgData.bitmap)) break\n if (imgData.width < MIN_IMAGE_DIM || imgData.height < MIN_IMAGE_DIM) break\n\n const tc = document.createElement('canvas')\n tc.width = imgData.width\n tc.height = imgData.height\n const tctx = tc.getContext('2d')!\n if (imgData.bitmap) {\n tctx.drawImage(imgData.bitmap, 0, 0)\n } else {\n const id = tctx.createImageData(imgData.width, imgData.height)\n id.data.set(imgData.data)\n tctx.putImageData(id, 0, 0)\n }\n const src = tc.toDataURL('image/png')\n\n const sm = mulM(vt, ctm)\n const corners = [\n [sm[4], sm[5]],\n [sm[0] + sm[4], sm[1] + sm[5]],\n [sm[2] + sm[4], sm[3] + sm[5]],\n [sm[0] + sm[2] + sm[4], sm[1] + sm[3] + sm[5]],\n ]\n const xs = corners.map(c => c[0])\n const ys = corners.map(c => c[1])\n results.push({\n src,\n x: Math.min(...xs),\n y: Math.min(...ys),\n w: Math.max(...xs) - Math.min(...xs),\n h: Math.max(...ys) - Math.min(...ys),\n })\n } catch { /* skip failed images */ }\n break\n }\n }\n }\n return results\n}\n\nconst PdfViewerCore: React.FC<PdfViewerCoreProps> = ({ src, className, loadingLabel, onImageSelect }) => {\n const { t } = useChatWidgetI18n()\n const containerRef = useRef<HTMLDivElement>(null)\n const pdfDocRef = useRef<any>(null)\n const renderIdRef = useRef(0)\n const [loading, setLoading] = useState(true)\n const [error, setError] = useState<string>()\n const [totalPages, setTotalPages] = useState(0)\n const [zoom, setZoom] = useState(1)\n\n useRevokeBlobUrl(src)\n\n const cleanup = useCallback(() => {\n if (pdfDocRef.current) {\n try { pdfDocRef.current.destroy() } catch {}\n pdfDocRef.current = null\n }\n }, [])\n\n const renderPages = useCallback(async (\n pdfjsLib: any,\n pdfDoc: any,\n container: HTMLDivElement,\n userZoom: number,\n renderId: number,\n ) => {\n container.innerHTML = ''\n\n const dpr = window.devicePixelRatio || 1\n const numPages = pdfDoc.numPages\n const containerWidth = container.clientWidth || 600\n\n for (let i = 1; i <= numPages; i++) {\n if (renderIdRef.current !== renderId) return\n const page = await pdfDoc.getPage(i)\n if (renderIdRef.current !== renderId) return\n\n const baseViewport = page.getViewport({ scale: BASE_SCALE })\n const fitScale = containerWidth / baseViewport.width\n const finalScale = BASE_SCALE * fitScale * userZoom\n const viewport = page.getViewport({ scale: finalScale })\n\n const pageDiv = document.createElement('div')\n pageDiv.className = 'ycw-pdf-page'\n pageDiv.style.width = `${viewport.width}px`\n pageDiv.style.height = `${viewport.height}px`\n\n // Canvas\n const canvas = document.createElement('canvas')\n canvas.width = Math.floor(viewport.width * dpr)\n canvas.height = Math.floor(viewport.height * dpr)\n canvas.style.width = `${viewport.width}px`\n canvas.style.height = `${viewport.height}px`\n pageDiv.appendChild(canvas)\n\n const ctx = canvas.getContext('2d')!\n ctx.scale(dpr, dpr)\n await page.render({ canvasContext: ctx, canvas, viewport }).promise\n if (renderIdRef.current !== renderId) return\n\n // Text selection layer — manual spans with inline px positioning\n const textContent = await page.getTextContent()\n if (renderIdRef.current !== renderId) return\n\n const textDiv = document.createElement('div')\n textDiv.className = 'ycw-pdf-text-layer'\n textDiv.dataset.page = String(i)\n textDiv.style.cssText =\n 'position:absolute;inset:0;z-index:2;line-height:1;pointer-events:auto;'\n\n const measureCanvas = document.createElement('canvas')\n const mCtx = measureCanvas.getContext('2d')!\n\n for (const item of textContent.items as any[]) {\n if (!item.str) continue\n const tx = pdfjsLib.Util.transform(viewport.transform, item.transform)\n const angle = Math.atan2(tx[1], tx[0])\n const fontSize = Math.hypot(tx[2], tx[3])\n if (fontSize < 1) continue\n\n const fontFamily = textContent.styles?.[item.fontName]?.fontFamily || 'sans-serif'\n\n const ascent = fontSize * 0.8\n let left: number, top: number\n if (Math.abs(angle) < 0.001) {\n left = tx[4]\n top = tx[5] - ascent\n } else {\n left = tx[4] + ascent * Math.sin(angle)\n top = tx[5] - ascent * Math.cos(angle)\n }\n\n const span = document.createElement('span')\n span.textContent = item.str\n span.dataset.page = String(i)\n span.style.position = 'absolute'\n span.style.left = `${left.toFixed(1)}px`\n span.style.top = `${top.toFixed(1)}px`\n span.style.fontSize = `${fontSize.toFixed(1)}px`\n span.style.fontFamily = fontFamily\n span.style.color = 'transparent'\n span.style.whiteSpace = 'pre'\n span.style.cursor = 'text'\n span.style.transformOrigin = '0% 0%'\n\n if (item.width) {\n const targetWidth = item.width * finalScale\n mCtx.font = `${fontSize}px ${fontFamily}`\n const measured = mCtx.measureText(item.str).width\n if (measured > 0) {\n const scaleX = targetWidth / measured\n if (Math.abs(angle) < 0.001) {\n span.style.transform = `scaleX(${scaleX.toFixed(4)})`\n } else {\n const deg = angle * (180 / Math.PI)\n span.style.transform = `rotate(${deg.toFixed(2)}deg) scaleX(${scaleX.toFixed(4)})`\n }\n }\n } else if (Math.abs(angle) >= 0.001) {\n const deg = angle * (180 / Math.PI)\n span.style.transform = `rotate(${deg.toFixed(2)}deg)`\n }\n\n textDiv.appendChild(span)\n }\n\n pageDiv.appendChild(textDiv)\n\n // Image overlay layer (above text layer — click to select image)\n try {\n const images = await extractPageImages(page, viewport, pdfjsLib.OPS)\n if (renderIdRef.current !== renderId) return\n if (images.length > 0) {\n const imgLayer = document.createElement('div')\n imgLayer.className = 'ycw-pdf-image-layer'\n images.forEach((img, imgIdx) => {\n const el = document.createElement('img')\n el.src = img.src\n el.dataset.page = String(i)\n el.dataset.imgIdx = String(imgIdx)\n el.style.position = 'absolute'\n el.style.left = `${img.x}px`\n el.style.top = `${img.y}px`\n el.style.width = `${img.w}px`\n el.style.height = `${img.h}px`\n el.draggable = true\n imgLayer.appendChild(el)\n })\n pageDiv.appendChild(imgLayer)\n }\n } catch { /* image extraction is best-effort */ }\n\n container.appendChild(pageDiv)\n }\n }, [])\n\n // Load PDF doc once\n useEffect(() => {\n if (!src) return\n let cancelled = false\n\n ;(async () => {\n try {\n setLoading(true)\n setError(undefined)\n setZoom(1)\n\n const pdfjsLib = await loadPdfjs()\n\n const { resolveToArrayBuffer } = await import('../../ViewerCore/utils/resolveToArrayBuffer.js')\n const buf = await resolveToArrayBuffer(src)\n if (cancelled) return\n\n cleanup()\n\n const pdfDoc = await pdfjsLib.getDocument({\n data: new Uint8Array(buf.slice(0)),\n disableStream: true,\n disableAutoFetch: true,\n }).promise\n if (cancelled) { pdfDoc.destroy(); return }\n pdfDocRef.current = pdfDoc\n\n setTotalPages(pdfDoc.numPages)\n setLoading(false)\n\n const container = containerRef.current\n if (!container || cancelled) return\n\n const rid = ++renderIdRef.current\n await renderPages(pdfjsLib, pdfDoc, container, 1, rid)\n } catch (err) {\n if (!cancelled) {\n setError(String((err as Error)?.message ?? err))\n setLoading(false)\n }\n }\n })()\n\n return () => {\n cancelled = true\n cleanup()\n }\n }, [src, cleanup, renderPages])\n\n // Re-render on zoom change\n useEffect(() => {\n const pdfDoc = pdfDocRef.current\n const container = containerRef.current\n if (!pdfDoc || !container || loading) return\n\n const rid = ++renderIdRef.current\n ;(async () => {\n const pdfjsLib = await loadPdfjs()\n await renderPages(pdfjsLib, pdfDoc, container, zoom, rid)\n })().catch(() => {})\n }, [zoom, renderPages, loading])\n\n const handleZoomIn = useCallback(() => {\n setZoom(z => Math.min(ZOOM_MAX, +(z + ZOOM_STEP).toFixed(2)))\n }, [])\n const handleZoomOut = useCallback(() => {\n setZoom(z => Math.max(ZOOM_MIN, +(z - ZOOM_STEP).toFixed(2)))\n }, [])\n const handleZoomReset = useCallback(() => setZoom(1), [])\n\n // Image click → select/deselect\n useEffect(() => {\n const el = containerRef.current\n if (!el || !onImageSelect) return\n const onClick = (e: MouseEvent) => {\n const target = e.target as HTMLElement\n if (target.tagName !== 'IMG' || !target.closest('.ycw-pdf-image-layer')) return\n const img = target as HTMLImageElement\n const prev = el.querySelector('.ycw-pdf-image-layer img[data-selected=\"true\"]')\n if (prev && prev !== img) prev.removeAttribute('data-selected')\n\n if (img.dataset.selected === 'true') {\n img.removeAttribute('data-selected')\n onImageSelect(null)\n } else {\n img.dataset.selected = 'true'\n onImageSelect({\n page: parseInt(img.dataset.page || '1', 10),\n imageIndex: parseInt(img.dataset.imgIdx || '0', 10),\n imageSrc: img.src,\n rect: img.getBoundingClientRect(),\n })\n }\n }\n el.addEventListener('click', onClick)\n return () => el.removeEventListener('click', onClick)\n }, [onImageSelect])\n\n // Ctrl/Cmd + scroll for zoom\n useEffect(() => {\n const el = containerRef.current?.parentElement\n if (!el) return\n const onWheel = (e: WheelEvent) => {\n if (!e.ctrlKey && !e.metaKey) return\n e.preventDefault()\n setZoom(z => {\n const delta = e.deltaY > 0 ? -ZOOM_STEP : ZOOM_STEP\n return Math.max(ZOOM_MIN, Math.min(ZOOM_MAX, +(z + delta).toFixed(2)))\n })\n }\n el.addEventListener('wheel', onWheel, { passive: false })\n return () => el.removeEventListener('wheel', onWheel)\n }, [loading])\n\n if (error) {\n return (\n <div className={`ycw-file-viewer-pdf ${className || ''}`}>\n <div className=\"ycw-viewer-error\">{error}</div>\n </div>\n )\n }\n\n return (\n <div className={`ycw-file-viewer-pdf ${className || ''}`}>\n {loading && <div className=\"ycw-viewer-loading\">{loadingLabel || t('viewer.loading')}</div>}\n {!loading && totalPages > 0 && (\n <div className=\"ycw-pdf-toolbar\">\n <span className=\"ycw-pdf-page-count\">\n {t('viewer.pdfPages', { count: String(totalPages) })}\n </span>\n <div className=\"ycw-pdf-zoom-controls\">\n <button className=\"ycw-pdf-zoom-btn\" onClick={handleZoomOut} disabled={zoom <= ZOOM_MIN} title={t('viewer.zoomOut')}>−</button>\n <button className=\"ycw-pdf-zoom-label\" onClick={handleZoomReset} title={t('viewer.zoomReset')}>{Math.round(zoom * 100)}%</button>\n <button className=\"ycw-pdf-zoom-btn\" onClick={handleZoomIn} disabled={zoom >= ZOOM_MAX} title={t('viewer.zoomIn')}>+</button>\n </div>\n </div>\n )}\n <div ref={containerRef} className=\"ycw-pdf-pages\" />\n </div>\n )\n}\n\nexport default PdfViewerCore\n"],"mappings":"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","names":[]}
@@ -0,0 +1,10 @@
1
+ import {
2
+ PowerPointCore,
3
+ PowerPointCore_default
4
+ } from "./chunk-R5LHMOAC.js";
5
+ import "./chunk-Q5PLT3AI.js";
6
+ export {
7
+ PowerPointCore,
8
+ PowerPointCore_default as default
9
+ };
10
+ //# sourceMappingURL=PowerPointCore-IZ4G6HEQ.js.map
@@ -3,7 +3,6 @@ import {
3
3
  useResource,
4
4
  useResourceContext
5
5
  } from "./chunk-GAMA3VA7.js";
6
- import "./chunk-7D4SUZUM.js";
7
6
 
8
7
  // src/components/JsonRender/domain/PowerPointViewer.tsx
9
8
  import React, { useEffect } from "react";
@@ -17,7 +16,7 @@ var SHEET = `
17
16
  }
18
17
  .jr-pptx-viewer--error { color: var(--jr-danger, #ef4444); }
19
18
  `;
20
- var LazyPowerPointCore = React.lazy(() => import("./PowerPointCore-FPDR2BL4.js"));
19
+ var LazyPowerPointCore = React.lazy(() => import("./PowerPointCore-IZ4G6HEQ.js"));
21
20
  var PowerPointViewer = ({ props, emit }) => {
22
21
  injectStyles(STYLE_ID, SHEET);
23
22
  const res = useResource({ resource_id: props.resource_id, url: props.url });
@@ -58,4 +57,4 @@ export {
58
57
  PowerPointViewer,
59
58
  PowerPointViewer_default as default
60
59
  };
61
- //# sourceMappingURL=PowerPointViewer-LQTO6UCU.js.map
60
+ //# sourceMappingURL=PowerPointViewer-5R2KSWWJ.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/JsonRender/domain/PowerPointViewer.tsx"],"sourcesContent":["import React, { useEffect } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport { useResourceContext } from '../../../contexts/ResourceContext.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-pptx-viewer'\nconst SHEET = `\n.jr-pptx-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 400px; }\n.jr-pptx-viewer--loading, .jr-pptx-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-pptx-viewer--error { color: var(--jr-danger, #ef4444); }\n`\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n title?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nconst LazyPowerPointCore = React.lazy(() => import('../../ViewerCore/PowerPointCore.js'))\n\nexport const PowerPointViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n const res = useResource({ resource_id: props.resource_id, url: props.url })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: props.resource_id, error: res.error })\n } else {\n emit?.('viewer:loaded', { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName })\n }\n }, [res.loading, res.error])\n\n const ctx = useResourceContext()\n\n if (res.loading) return <div className=\"jr-pptx-viewer jr-pptx-viewer--loading\">Loading…</div>\n if (res.error) return <div className=\"jr-pptx-viewer jr-pptx-viewer--error\">{res.error}</div>\n\n const src = res.url\n const isLegacy = res.fileName?.match(/\\.ppt$/i) && !res.fileName?.match(/\\.pptx$/i)\n\n if (isLegacy && ctx?.resolvePreviewUrl && props.resource_id) {\n return <LegacyFallback resourceId={props.resource_id} ctx={ctx} />\n }\n\n if (!src) return <div className=\"jr-pptx-viewer jr-pptx-viewer--error\">No presentation source</div>\n\n return (\n <div className=\"jr-pptx-viewer ycw-ppt-viewer\">\n <React.Suspense fallback={<div className=\"jr-pptx-viewer--loading\">Loading PowerPoint viewer…</div>}>\n <LazyPowerPointCore src={src} />\n </React.Suspense>\n </div>\n )\n}\n\nconst LegacyFallback: React.FC<{ resourceId: string; ctx: { resolvePreviewUrl?(id: string, fmt: 'html' | 'pdf'): Promise<string> } }> = ({ resourceId, ctx }) => {\n const [previewUrl, setPreviewUrl] = React.useState<string>()\n const [error, setError] = React.useState<string>()\n\n React.useEffect(() => {\n ctx.resolvePreviewUrl?.(resourceId, 'html')\n .then(url => setPreviewUrl(url))\n .catch(err => setError(String(err?.message ?? err)))\n }, [resourceId, ctx])\n\n if (error) return <div className=\"jr-pptx-viewer jr-pptx-viewer--error\">.ppt preview failed: {error}</div>\n if (!previewUrl) return <div className=\"jr-pptx-viewer jr-pptx-viewer--loading\">Converting .ppt…</div>\n\n return (\n <div className=\"jr-pptx-viewer\">\n <iframe src={previewUrl} title=\"PowerPoint Preview\" style={{ width: '100%', height: 600, border: 'none' }} />\n </div>\n )\n}\n\nexport default PowerPointViewer\n"],"mappings":";;;;;;;;AAAA,OAAO,SAAS,iBAAiB;AAyCP,cA+BN,YA/BM;AApC1B,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBd,IAAM,qBAAqB,MAAM,KAAK,MAAM,OAAO,8BAAoC,CAAC;AAEjF,IAAM,mBAAoC,CAAC,EAAE,OAAO,KAAK,MAAM;AACpE,eAAa,UAAU,KAAK;AAC5B,QAAM,MAAM,YAAY,EAAE,aAAa,MAAM,aAAa,KAAK,MAAM,IAAI,CAAC;AAE1E,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,MAAM,aAAa,OAAO,IAAI,MAAM,CAAC;AAAA,IAC7E,OAAO;AACL,aAAO,iBAAiB,EAAE,aAAa,MAAM,aAAa,UAAU,IAAI,UAAU,UAAU,IAAI,SAAS,CAAC;AAAA,IAC5G;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAE3B,QAAM,MAAM,mBAAmB;AAE/B,MAAI,IAAI,QAAS,QAAO,oBAAC,SAAI,WAAU,0CAAyC,2BAAQ;AACxF,MAAI,IAAI,MAAO,QAAO,oBAAC,SAAI,WAAU,wCAAwC,cAAI,OAAM;AAEvF,QAAM,MAAM,IAAI;AAChB,QAAM,WAAW,IAAI,UAAU,MAAM,SAAS,KAAK,CAAC,IAAI,UAAU,MAAM,UAAU;AAElF,MAAI,YAAY,KAAK,qBAAqB,MAAM,aAAa;AAC3D,WAAO,oBAAC,kBAAe,YAAY,MAAM,aAAa,KAAU;AAAA,EAClE;AAEA,MAAI,CAAC,IAAK,QAAO,oBAAC,SAAI,WAAU,wCAAuC,oCAAsB;AAE7F,SACE,oBAAC,SAAI,WAAU,iCACb,8BAAC,MAAM,UAAN,EAAe,UAAU,oBAAC,SAAI,WAAU,2BAA0B,6CAA0B,GAC3F,8BAAC,sBAAmB,KAAU,GAChC,GACF;AAEJ;AAEA,IAAM,iBAAkI,CAAC,EAAE,YAAY,IAAI,MAAM;AAC/J,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAiB;AAC3D,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAiB;AAEjD,QAAM,UAAU,MAAM;AACpB,QAAI,oBAAoB,YAAY,MAAM,EACvC,KAAK,SAAO,cAAc,GAAG,CAAC,EAC9B,MAAM,SAAO,SAAS,OAAO,KAAK,WAAW,GAAG,CAAC,CAAC;AAAA,EACvD,GAAG,CAAC,YAAY,GAAG,CAAC;AAEpB,MAAI,MAAO,QAAO,qBAAC,SAAI,WAAU,wCAAuC;AAAA;AAAA,IAAsB;AAAA,KAAM;AACpG,MAAI,CAAC,WAAY,QAAO,oBAAC,SAAI,WAAU,0CAAyC,mCAAgB;AAEhG,SACE,oBAAC,SAAI,WAAU,kBACb,8BAAC,YAAO,KAAK,YAAY,OAAM,sBAAqB,OAAO,EAAE,OAAO,QAAQ,QAAQ,KAAK,QAAQ,OAAO,GAAG,GAC7G;AAEJ;AAEA,IAAO,2BAAQ;","names":[]}
1
+ {"version":3,"sources":["../src/components/JsonRender/domain/PowerPointViewer.tsx"],"sourcesContent":["import React, { useEffect } from 'react'\nimport { useResource } from '../../../hooks/useResource.js'\nimport { useResourceContext } from '../../../contexts/ResourceContext.js'\nimport { injectStyles } from './injectStyles.js'\n\nconst STYLE_ID = 'jr-styles-pptx-viewer'\nconst SHEET = `\n.jr-pptx-viewer { width: 100%; min-width: 0; max-width: 100%; min-height: 400px; }\n.jr-pptx-viewer--loading, .jr-pptx-viewer--error {\n padding: 1rem; font-family: var(--jr-font, system-ui, sans-serif);\n color: var(--jr-text-muted, #64748b);\n}\n.jr-pptx-viewer--error { color: var(--jr-danger, #ef4444); }\n`\n\ninterface Props {\n props: {\n resource_id?: string\n url?: string\n title?: string\n }\n emit?: (event: string, data?: unknown) => void\n}\n\nconst LazyPowerPointCore = React.lazy(() => import('../../ViewerCore/PowerPointCore.js'))\n\nexport const PowerPointViewer: React.FC<Props> = ({ props, emit }) => {\n injectStyles(STYLE_ID, SHEET)\n const res = useResource({ resource_id: props.resource_id, url: props.url })\n\n useEffect(() => {\n if (res.loading) return\n if (res.error) {\n emit?.('viewer:error', { resource_id: props.resource_id, error: res.error })\n } else {\n emit?.('viewer:loaded', { resource_id: props.resource_id, mimeType: res.mimeType, fileName: res.fileName })\n }\n }, [res.loading, res.error])\n\n const ctx = useResourceContext()\n\n if (res.loading) return <div className=\"jr-pptx-viewer jr-pptx-viewer--loading\">Loading…</div>\n if (res.error) return <div className=\"jr-pptx-viewer jr-pptx-viewer--error\">{res.error}</div>\n\n const src = res.url\n const isLegacy = res.fileName?.match(/\\.ppt$/i) && !res.fileName?.match(/\\.pptx$/i)\n\n if (isLegacy && ctx?.resolvePreviewUrl && props.resource_id) {\n return <LegacyFallback resourceId={props.resource_id} ctx={ctx} />\n }\n\n if (!src) return <div className=\"jr-pptx-viewer jr-pptx-viewer--error\">No presentation source</div>\n\n return (\n <div className=\"jr-pptx-viewer ycw-ppt-viewer\">\n <React.Suspense fallback={<div className=\"jr-pptx-viewer--loading\">Loading PowerPoint viewer…</div>}>\n <LazyPowerPointCore src={src} />\n </React.Suspense>\n </div>\n )\n}\n\nconst LegacyFallback: React.FC<{ resourceId: string; ctx: { resolvePreviewUrl?(id: string, fmt: 'html' | 'pdf'): Promise<string> } }> = ({ resourceId, ctx }) => {\n const [previewUrl, setPreviewUrl] = React.useState<string>()\n const [error, setError] = React.useState<string>()\n\n React.useEffect(() => {\n ctx.resolvePreviewUrl?.(resourceId, 'html')\n .then(url => setPreviewUrl(url))\n .catch(err => setError(String(err?.message ?? err)))\n }, [resourceId, ctx])\n\n if (error) return <div className=\"jr-pptx-viewer jr-pptx-viewer--error\">.ppt preview failed: {error}</div>\n if (!previewUrl) return <div className=\"jr-pptx-viewer jr-pptx-viewer--loading\">Converting .ppt…</div>\n\n return (\n <div className=\"jr-pptx-viewer\">\n <iframe src={previewUrl} title=\"PowerPoint Preview\" style={{ width: '100%', height: 600, border: 'none' }} />\n </div>\n )\n}\n\nexport default PowerPointViewer\n"],"mappings":";;;;;;;AAAA,OAAO,SAAS,iBAAiB;AAyCP,cA+BN,YA/BM;AApC1B,IAAM,WAAW;AACjB,IAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAkBd,IAAM,qBAAqB,MAAM,KAAK,MAAM,OAAO,8BAAoC,CAAC;AAEjF,IAAM,mBAAoC,CAAC,EAAE,OAAO,KAAK,MAAM;AACpE,eAAa,UAAU,KAAK;AAC5B,QAAM,MAAM,YAAY,EAAE,aAAa,MAAM,aAAa,KAAK,MAAM,IAAI,CAAC;AAE1E,YAAU,MAAM;AACd,QAAI,IAAI,QAAS;AACjB,QAAI,IAAI,OAAO;AACb,aAAO,gBAAgB,EAAE,aAAa,MAAM,aAAa,OAAO,IAAI,MAAM,CAAC;AAAA,IAC7E,OAAO;AACL,aAAO,iBAAiB,EAAE,aAAa,MAAM,aAAa,UAAU,IAAI,UAAU,UAAU,IAAI,SAAS,CAAC;AAAA,IAC5G;AAAA,EACF,GAAG,CAAC,IAAI,SAAS,IAAI,KAAK,CAAC;AAE3B,QAAM,MAAM,mBAAmB;AAE/B,MAAI,IAAI,QAAS,QAAO,oBAAC,SAAI,WAAU,0CAAyC,2BAAQ;AACxF,MAAI,IAAI,MAAO,QAAO,oBAAC,SAAI,WAAU,wCAAwC,cAAI,OAAM;AAEvF,QAAM,MAAM,IAAI;AAChB,QAAM,WAAW,IAAI,UAAU,MAAM,SAAS,KAAK,CAAC,IAAI,UAAU,MAAM,UAAU;AAElF,MAAI,YAAY,KAAK,qBAAqB,MAAM,aAAa;AAC3D,WAAO,oBAAC,kBAAe,YAAY,MAAM,aAAa,KAAU;AAAA,EAClE;AAEA,MAAI,CAAC,IAAK,QAAO,oBAAC,SAAI,WAAU,wCAAuC,oCAAsB;AAE7F,SACE,oBAAC,SAAI,WAAU,iCACb,8BAAC,MAAM,UAAN,EAAe,UAAU,oBAAC,SAAI,WAAU,2BAA0B,6CAA0B,GAC3F,8BAAC,sBAAmB,KAAU,GAChC,GACF;AAEJ;AAEA,IAAM,iBAAkI,CAAC,EAAE,YAAY,IAAI,MAAM;AAC/J,QAAM,CAAC,YAAY,aAAa,IAAI,MAAM,SAAiB;AAC3D,QAAM,CAAC,OAAO,QAAQ,IAAI,MAAM,SAAiB;AAEjD,QAAM,UAAU,MAAM;AACpB,QAAI,oBAAoB,YAAY,MAAM,EACvC,KAAK,SAAO,cAAc,GAAG,CAAC,EAC9B,MAAM,SAAO,SAAS,OAAO,KAAK,WAAW,GAAG,CAAC,CAAC;AAAA,EACvD,GAAG,CAAC,YAAY,GAAG,CAAC;AAEpB,MAAI,MAAO,QAAO,qBAAC,SAAI,WAAU,wCAAuC;AAAA;AAAA,IAAsB;AAAA,KAAM;AACpG,MAAI,CAAC,WAAY,QAAO,oBAAC,SAAI,WAAU,0CAAyC,mCAAgB;AAEhG,SACE,oBAAC,SAAI,WAAU,kBACb,8BAAC,YAAO,KAAK,YAAY,OAAM,sBAAqB,OAAO,EAAE,OAAO,QAAQ,QAAQ,KAAK,QAAQ,OAAO,GAAG,GAC7G;AAEJ;AAEA,IAAO,2BAAQ;","names":[]}
@@ -6,8 +6,7 @@ import {
6
6
  } from "./chunk-3R6T3LBR.js";
7
7
  import {
8
8
  useChatWidgetI18n
9
- } from "./chunk-QLVPIM6R.js";
10
- import "./chunk-7D4SUZUM.js";
9
+ } from "./chunk-3CNQONCV.js";
11
10
 
12
11
  // src/components/FileViewer/viewers/StepViewerCore.tsx
13
12
  import { useEffect, useState, useCallback } from "react";
@@ -282,4 +281,4 @@ var StepViewerCore_default = StepViewerCore;
282
281
  export {
283
282
  StepViewerCore_default as default
284
283
  };
285
- //# sourceMappingURL=StepViewerCore-7W3L3R4E.js.map
284
+ //# sourceMappingURL=StepViewerCore-RORWXIRU.js.map