pptx-react-viewer 4.0.0 → 4.1.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/CHANGELOG.md +6 -0
- package/dist/{AiChatPanel-MHURGN6G.mjs → AiChatPanel-C3ACRWOY.mjs} +4 -4
- package/dist/AiChatPanel-C3ACRWOY.mjs.br +0 -0
- package/dist/AiChatPanel-C3ACRWOY.mjs.gz +0 -0
- package/dist/{AiChatPanel-WMVQFNDC.js → AiChatPanel-GQNSKMP6.js} +25 -25
- package/dist/AiChatPanel-GQNSKMP6.js.br +0 -0
- package/dist/AiChatPanel-GQNSKMP6.js.gz +0 -0
- package/dist/{Area3DChartScene-IMGZEZNU.js → Area3DChartScene-3I6KB2DN.js} +2 -2
- package/dist/Area3DChartScene-3I6KB2DN.js.br +0 -0
- package/dist/Area3DChartScene-3I6KB2DN.js.gz +0 -0
- package/dist/{Area3DChartScene-LKOWSMAU.mjs → Area3DChartScene-4TPNRYXS.mjs} +1 -1
- package/dist/{Area3DChartScene-LKOWSMAU.mjs.br → Area3DChartScene-4TPNRYXS.mjs.br} +0 -0
- package/dist/Area3DChartScene-4TPNRYXS.mjs.gz +0 -0
- package/dist/{Bar3DChartScene-NQNSIMUL.mjs → Bar3DChartScene-V45IUIT7.mjs} +1 -1
- package/dist/{Bar3DChartScene-NQNSIMUL.mjs.br → Bar3DChartScene-V45IUIT7.mjs.br} +0 -0
- package/dist/Bar3DChartScene-V45IUIT7.mjs.gz +0 -0
- package/dist/{Bar3DChartScene-VLSYVFRT.js → Bar3DChartScene-ZSCATOYF.js} +2 -2
- package/dist/Bar3DChartScene-ZSCATOYF.js.br +0 -0
- package/dist/Bar3DChartScene-ZSCATOYF.js.gz +0 -0
- package/dist/{Line3DChartScene-ANZBJYQI.mjs → Line3DChartScene-DCQJEZK6.mjs} +1 -1
- package/dist/{Line3DChartScene-ANZBJYQI.mjs.br → Line3DChartScene-DCQJEZK6.mjs.br} +0 -0
- package/dist/Line3DChartScene-DCQJEZK6.mjs.gz +0 -0
- package/dist/{Line3DChartScene-IWZHA563.js → Line3DChartScene-DK55LQ2D.js} +2 -2
- package/dist/Line3DChartScene-DK55LQ2D.js.br +0 -0
- package/dist/Line3DChartScene-DK55LQ2D.js.gz +0 -0
- package/dist/{Model3DScene-2L3YRAMR.js → Model3DScene-2WNP4XBP.js} +2 -2
- package/dist/Model3DScene-2WNP4XBP.js.br +0 -0
- package/dist/Model3DScene-2WNP4XBP.js.gz +0 -0
- package/dist/{Model3DScene-Y34HTZXK.mjs → Model3DScene-SA5XMR2D.mjs} +1 -1
- package/dist/Model3DScene-SA5XMR2D.mjs.br +0 -0
- package/dist/Model3DScene-SA5XMR2D.mjs.gz +0 -0
- package/dist/{PieChart3DScene-FBRPLHLG.mjs → PieChart3DScene-HC2ZWL42.mjs} +1 -1
- package/dist/{PieChart3DScene-FBRPLHLG.mjs.br → PieChart3DScene-HC2ZWL42.mjs.br} +0 -0
- package/dist/PieChart3DScene-HC2ZWL42.mjs.gz +0 -0
- package/dist/{PieChart3DScene-NE3GN5VG.js → PieChart3DScene-Q75D66HS.js} +2 -2
- package/dist/PieChart3DScene-Q75D66HS.js.br +0 -0
- package/dist/PieChart3DScene-Q75D66HS.js.gz +0 -0
- package/dist/{SmartArt3DScene-QZGIABOK.mjs → SmartArt3DScene-D4VNNPHS.mjs} +124 -19
- package/dist/SmartArt3DScene-D4VNNPHS.mjs.br +0 -0
- package/dist/SmartArt3DScene-D4VNNPHS.mjs.gz +0 -0
- package/dist/{SmartArt3DScene-T236GYUT.js → SmartArt3DScene-NHD7CZJ5.js} +123 -18
- package/dist/SmartArt3DScene-NHD7CZJ5.js.br +0 -0
- package/dist/SmartArt3DScene-NHD7CZJ5.js.gz +0 -0
- package/dist/{SurfaceChart3DScene-7HE5DA3X.mjs → SurfaceChart3DScene-JRMX4PN5.mjs} +1 -1
- package/dist/SurfaceChart3DScene-JRMX4PN5.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-JRMX4PN5.mjs.gz +0 -0
- package/dist/{SurfaceChart3DScene-OSMAVZJC.js → SurfaceChart3DScene-ODS5E6ZG.js} +2 -2
- package/dist/SurfaceChart3DScene-ODS5E6ZG.js.br +0 -0
- package/dist/SurfaceChart3DScene-ODS5E6ZG.js.gz +0 -0
- package/dist/{chunk-H7J4EYXS.mjs → chunk-25CABWCR.mjs} +131 -329
- package/dist/chunk-25CABWCR.mjs.br +0 -0
- package/dist/chunk-25CABWCR.mjs.gz +0 -0
- package/dist/{chunk-IWHZ2DUD.mjs → chunk-3B6YIH4K.mjs} +626 -133
- package/dist/chunk-3B6YIH4K.mjs.br +0 -0
- package/dist/chunk-3B6YIH4K.mjs.gz +0 -0
- package/dist/{chunk-L6I73WMO.js → chunk-A6JKOHSV.js} +2143 -1644
- package/dist/chunk-A6JKOHSV.js.br +0 -0
- package/dist/chunk-A6JKOHSV.js.gz +0 -0
- package/dist/{chunk-5F426BCZ.mjs → chunk-GRAARMUW.mjs} +1 -1
- package/dist/chunk-GRAARMUW.mjs.br +0 -0
- package/dist/chunk-GRAARMUW.mjs.gz +0 -0
- package/dist/{chunk-ZOB6ITIM.js → chunk-MQHMMB6V.js} +5 -5
- package/dist/chunk-MQHMMB6V.js.br +0 -0
- package/dist/chunk-MQHMMB6V.js.gz +0 -0
- package/dist/{chunk-I5F3XLVR.js → chunk-NR4MQJM5.js} +1961 -2161
- package/dist/chunk-NR4MQJM5.js.br +0 -0
- package/dist/chunk-NR4MQJM5.js.gz +0 -0
- package/dist/{chunk-M24DEOP6.js → chunk-NXGUR2DO.js} +2 -0
- package/dist/chunk-NXGUR2DO.js.br +0 -0
- package/dist/chunk-NXGUR2DO.js.gz +0 -0
- package/dist/{chunk-R664EPDC.mjs → chunk-PC7H3C5W.mjs} +2 -0
- package/dist/chunk-PC7H3C5W.mjs.br +0 -0
- package/dist/chunk-PC7H3C5W.mjs.gz +0 -0
- package/dist/{chunk-NKACTGK5.js → chunk-PUALTXTU.js} +182 -182
- package/dist/chunk-PUALTXTU.js.br +0 -0
- package/dist/chunk-PUALTXTU.js.gz +0 -0
- package/dist/{chunk-33YE6E2O.mjs → chunk-Q6QJOD56.mjs} +2145 -470
- package/dist/chunk-Q6QJOD56.mjs.br +0 -0
- package/dist/chunk-Q6QJOD56.mjs.gz +0 -0
- package/dist/{chunk-LAAXFMRE.js → chunk-SK2CZQ6P.js} +2151 -469
- package/dist/chunk-SK2CZQ6P.js.br +0 -0
- package/dist/chunk-SK2CZQ6P.js.gz +0 -0
- package/dist/{chunk-GITM3RKP.mjs → chunk-WLWAYLL6.mjs} +2 -2
- package/dist/chunk-WLWAYLL6.mjs.br +0 -0
- package/dist/chunk-WLWAYLL6.mjs.gz +0 -0
- package/dist/i18n/de.cjs +2 -0
- package/dist/i18n/de.cjs.br +0 -0
- package/dist/i18n/de.cjs.gz +0 -0
- package/dist/i18n/de.mjs +2 -0
- package/dist/i18n/de.mjs.br +0 -0
- package/dist/i18n/de.mjs.gz +0 -0
- package/dist/i18n/es.cjs +2 -0
- package/dist/i18n/es.cjs.br +0 -0
- package/dist/i18n/es.cjs.gz +0 -0
- package/dist/i18n/es.mjs +2 -0
- package/dist/i18n/es.mjs.br +0 -0
- package/dist/i18n/es.mjs.gz +0 -0
- package/dist/i18n/fr.cjs +2 -0
- package/dist/i18n/fr.cjs.br +0 -0
- package/dist/i18n/fr.cjs.gz +0 -0
- package/dist/i18n/fr.mjs +2 -0
- package/dist/i18n/fr.mjs.br +0 -0
- package/dist/i18n/fr.mjs.gz +0 -0
- package/dist/i18n/zh-CN.cjs +2 -0
- package/dist/i18n/zh-CN.cjs.br +0 -0
- package/dist/i18n/zh-CN.cjs.gz +0 -0
- package/dist/i18n/zh-CN.mjs +2 -0
- package/dist/i18n/zh-CN.mjs.br +0 -0
- package/dist/i18n/zh-CN.mjs.gz +0 -0
- package/dist/i18n.js +4 -4
- package/dist/i18n.js.br +0 -0
- package/dist/i18n.js.gz +0 -0
- package/dist/i18n.mjs +1 -1
- package/dist/i18n.mjs.br +0 -0
- package/dist/i18n.mjs.gz +0 -0
- package/dist/index.d.ts +586 -7
- package/dist/index.js +52 -48
- package/dist/index.js.br +0 -0
- package/dist/index.js.gz +0 -0
- package/dist/index.mjs +6 -6
- package/dist/index.mjs.br +0 -0
- package/dist/index.mjs.gz +0 -0
- package/dist/internals.d.ts +447 -13
- package/dist/internals.js +105 -105
- package/dist/internals.js.br +0 -0
- package/dist/internals.js.gz +0 -0
- package/dist/internals.mjs +4 -4
- package/dist/internals.mjs.br +0 -0
- package/dist/internals.mjs.gz +0 -0
- package/dist/viewer/index.js +32 -32
- package/dist/viewer/index.js.br +0 -0
- package/dist/viewer/index.js.gz +0 -0
- package/dist/viewer/index.mjs +6 -6
- package/dist/viewer/index.mjs.br +0 -0
- package/dist/viewer/index.mjs.gz +0 -0
- package/package.json +2 -2
- package/dist/AiChatPanel-MHURGN6G.mjs.br +0 -0
- package/dist/AiChatPanel-MHURGN6G.mjs.gz +0 -0
- package/dist/AiChatPanel-WMVQFNDC.js.br +0 -0
- package/dist/AiChatPanel-WMVQFNDC.js.gz +0 -0
- package/dist/Area3DChartScene-IMGZEZNU.js.br +0 -0
- package/dist/Area3DChartScene-IMGZEZNU.js.gz +0 -0
- package/dist/Area3DChartScene-LKOWSMAU.mjs.gz +0 -0
- package/dist/Bar3DChartScene-NQNSIMUL.mjs.gz +0 -0
- package/dist/Bar3DChartScene-VLSYVFRT.js.br +0 -0
- package/dist/Bar3DChartScene-VLSYVFRT.js.gz +0 -0
- package/dist/Line3DChartScene-ANZBJYQI.mjs.gz +0 -0
- package/dist/Line3DChartScene-IWZHA563.js.br +0 -0
- package/dist/Line3DChartScene-IWZHA563.js.gz +0 -0
- package/dist/Model3DScene-2L3YRAMR.js.br +0 -0
- package/dist/Model3DScene-2L3YRAMR.js.gz +0 -0
- package/dist/Model3DScene-Y34HTZXK.mjs.br +0 -0
- package/dist/Model3DScene-Y34HTZXK.mjs.gz +0 -0
- package/dist/PieChart3DScene-FBRPLHLG.mjs.gz +0 -0
- package/dist/PieChart3DScene-NE3GN5VG.js.br +0 -0
- package/dist/PieChart3DScene-NE3GN5VG.js.gz +0 -0
- package/dist/SmartArt3DScene-QZGIABOK.mjs.br +0 -0
- package/dist/SmartArt3DScene-QZGIABOK.mjs.gz +0 -0
- package/dist/SmartArt3DScene-T236GYUT.js.br +0 -0
- package/dist/SmartArt3DScene-T236GYUT.js.gz +0 -0
- package/dist/SurfaceChart3DScene-7HE5DA3X.mjs.br +0 -0
- package/dist/SurfaceChart3DScene-7HE5DA3X.mjs.gz +0 -0
- package/dist/SurfaceChart3DScene-OSMAVZJC.js.br +0 -0
- package/dist/SurfaceChart3DScene-OSMAVZJC.js.gz +0 -0
- package/dist/chunk-33YE6E2O.mjs.br +0 -0
- package/dist/chunk-33YE6E2O.mjs.gz +0 -0
- package/dist/chunk-5F426BCZ.mjs.br +0 -0
- package/dist/chunk-5F426BCZ.mjs.gz +0 -0
- package/dist/chunk-GITM3RKP.mjs.br +0 -0
- package/dist/chunk-GITM3RKP.mjs.gz +0 -0
- package/dist/chunk-H7J4EYXS.mjs.br +0 -0
- package/dist/chunk-H7J4EYXS.mjs.gz +0 -0
- package/dist/chunk-I5F3XLVR.js.br +0 -0
- package/dist/chunk-I5F3XLVR.js.gz +0 -0
- package/dist/chunk-IWHZ2DUD.mjs.br +0 -0
- package/dist/chunk-IWHZ2DUD.mjs.gz +0 -0
- package/dist/chunk-L6I73WMO.js.br +0 -0
- package/dist/chunk-L6I73WMO.js.gz +0 -0
- package/dist/chunk-LAAXFMRE.js.br +0 -0
- package/dist/chunk-LAAXFMRE.js.gz +0 -0
- package/dist/chunk-M24DEOP6.js.br +0 -0
- package/dist/chunk-M24DEOP6.js.gz +0 -0
- package/dist/chunk-NKACTGK5.js.br +0 -0
- package/dist/chunk-NKACTGK5.js.gz +0 -0
- package/dist/chunk-R664EPDC.mjs.br +0 -0
- package/dist/chunk-R664EPDC.mjs.gz +0 -0
- package/dist/chunk-ZOB6ITIM.js.br +0 -0
- package/dist/chunk-ZOB6ITIM.js.gz +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,12 @@ A release listed with no entries carried no Conventional Commit in this package'
|
|
|
7
7
|
scope: scripts/release-plan.mjs re-releases a package whenever any of its files
|
|
8
8
|
change, not only on conventional ones.
|
|
9
9
|
|
|
10
|
+
## [4.0.0](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-react-viewer@4.0.0) - 2026-09-18
|
|
11
|
+
|
|
12
|
+
### Bug Fixes
|
|
13
|
+
|
|
14
|
+
- **core:** Switch to emf-converter's unified convertMetafileToDataUrl (by @ChristopherVR) ([70a2ea5](https://github.com/ChristopherVR/pptx-viewer/commit/70a2ea5059af31627dfa1f0a7ebe5e12219804bb))
|
|
15
|
+
|
|
10
16
|
## [3.21.0](https://github.com/ChristopherVR/pptx-viewer/releases/tag/pptx-react-viewer@3.21.0) - 2026-09-17
|
|
11
17
|
|
|
12
18
|
### Features
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { deckIdFromBridge, isAiAvailable, createAiChatSession, toolCanvasTarget, createChatHistoryStore, focusTargetChips, isTwoTableFocus, mergeTablesDirective, humanizeDiffLine, buildDeckContext, describeToolActivity, summarizeToolArgs, toolLabel } from './chunk-
|
|
2
|
-
import { cn } from './chunk-
|
|
3
|
-
import './chunk-
|
|
4
|
-
import './chunk-
|
|
1
|
+
import { deckIdFromBridge, isAiAvailable, createAiChatSession, toolCanvasTarget, createChatHistoryStore, focusTargetChips, isTwoTableFocus, mergeTablesDirective, humanizeDiffLine, buildDeckContext, describeToolActivity, summarizeToolArgs, toolLabel } from './chunk-GRAARMUW.mjs';
|
|
2
|
+
import { cn } from './chunk-WLWAYLL6.mjs';
|
|
3
|
+
import './chunk-Q6QJOD56.mjs';
|
|
4
|
+
import './chunk-PC7H3C5W.mjs';
|
|
5
5
|
import './chunk-XGB3TDIC.mjs';
|
|
6
6
|
import { useMemo, useRef, useState, useEffect, useReducer, useCallback } from 'react';
|
|
7
7
|
import { useTranslation } from 'react-i18next';
|
|
Binary file
|
|
Binary file
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
4
|
-
var
|
|
5
|
-
require('./chunk-
|
|
6
|
-
require('./chunk-
|
|
3
|
+
var chunkMQHMMB6V_js = require('./chunk-MQHMMB6V.js');
|
|
4
|
+
var chunkPUALTXTU_js = require('./chunk-PUALTXTU.js');
|
|
5
|
+
require('./chunk-SK2CZQ6P.js');
|
|
6
|
+
require('./chunk-NXGUR2DO.js');
|
|
7
7
|
require('./chunk-4VNS5WPM.js');
|
|
8
8
|
var react = require('react');
|
|
9
9
|
var reactI18next = require('react-i18next');
|
|
@@ -23,7 +23,7 @@ function useAiChat(bridge, config) {
|
|
|
23
23
|
setInitError(void 0);
|
|
24
24
|
void (async () => {
|
|
25
25
|
try {
|
|
26
|
-
const available = await
|
|
26
|
+
const available = await chunkMQHMMB6V_js.isAiAvailable();
|
|
27
27
|
if (cancelled) {
|
|
28
28
|
return;
|
|
29
29
|
}
|
|
@@ -31,7 +31,7 @@ function useAiChat(bridge, config) {
|
|
|
31
31
|
setState("unavailable");
|
|
32
32
|
return;
|
|
33
33
|
}
|
|
34
|
-
const built = await
|
|
34
|
+
const built = await chunkMQHMMB6V_js.createAiChatSession(bridge, configRef.current);
|
|
35
35
|
if (cancelled) {
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
@@ -137,7 +137,7 @@ function withDeckContext(inner, bridge, strategy) {
|
|
|
137
137
|
}
|
|
138
138
|
let context = "";
|
|
139
139
|
try {
|
|
140
|
-
context = await
|
|
140
|
+
context = await chunkMQHMMB6V_js.buildDeckContext(bridge, { strategy, focus: {} });
|
|
141
141
|
} catch {
|
|
142
142
|
context = "";
|
|
143
143
|
}
|
|
@@ -200,7 +200,7 @@ function useAiConversation(useChat, session, config, bridge, options = {}) {
|
|
|
200
200
|
continue;
|
|
201
201
|
}
|
|
202
202
|
seen.add(call.toolCallId);
|
|
203
|
-
onToolTargetRef.current?.(
|
|
203
|
+
onToolTargetRef.current?.(chunkMQHMMB6V_js.toolCanvasTarget(call.toolName, call.input));
|
|
204
204
|
}
|
|
205
205
|
}, [chat.messages]);
|
|
206
206
|
const send = react.useCallback(
|
|
@@ -276,7 +276,7 @@ function deriveTitle(messages) {
|
|
|
276
276
|
}
|
|
277
277
|
function useAiHistory(input) {
|
|
278
278
|
const { deckId, messages, setMessages } = input;
|
|
279
|
-
const store = react.useMemo(() => input.store ??
|
|
279
|
+
const store = react.useMemo(() => input.store ?? chunkMQHMMB6V_js.createChatHistoryStore(), [input.store]);
|
|
280
280
|
const [activeChatId, setActiveChatId] = react.useState(newChatId);
|
|
281
281
|
const [chats, setChats] = react.useState([]);
|
|
282
282
|
const createdAtRef = react.useRef(Date.now());
|
|
@@ -419,7 +419,7 @@ function AiComposer({
|
|
|
419
419
|
disabled: value.trim().length === 0,
|
|
420
420
|
title: t("pptx.ai.send"),
|
|
421
421
|
"aria-label": t("pptx.ai.send"),
|
|
422
|
-
className:
|
|
422
|
+
className: chunkPUALTXTU_js.cn(
|
|
423
423
|
"shrink-0 rounded-sm p-1.5 transition-colors",
|
|
424
424
|
value.trim().length === 0 ? "text-muted-foreground/50" : "bg-primary text-primary-foreground hover:bg-primary/90"
|
|
425
425
|
),
|
|
@@ -442,15 +442,15 @@ function AiFocusBar({
|
|
|
442
442
|
onClearPicks
|
|
443
443
|
}) {
|
|
444
444
|
const { t } = reactI18next.useTranslation();
|
|
445
|
-
const chips =
|
|
446
|
-
const twoTables =
|
|
445
|
+
const chips = chunkMQHMMB6V_js.focusTargetChips(targets, slides);
|
|
446
|
+
const twoTables = chunkMQHMMB6V_js.isTwoTableFocus(targets, slides);
|
|
447
447
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "border-b border-border bg-secondary/30", children: [
|
|
448
448
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex flex-wrap items-center gap-1 px-2.5 py-1.5", children: [
|
|
449
449
|
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[10px] font-semibold uppercase tracking-wide text-muted-foreground", children: t("pptx.ai.focusScope") }),
|
|
450
450
|
chips.map((chip) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
451
451
|
"span",
|
|
452
452
|
{
|
|
453
|
-
className:
|
|
453
|
+
className: chunkPUALTXTU_js.cn(
|
|
454
454
|
"inline-flex max-w-[10rem] items-center rounded-full px-2 py-0.5 text-[11px]",
|
|
455
455
|
hasPicks || isPinned ? "bg-primary/15 text-primary" : "bg-muted text-muted-foreground"
|
|
456
456
|
),
|
|
@@ -466,7 +466,7 @@ function AiFocusBar({
|
|
|
466
466
|
{
|
|
467
467
|
type: "button",
|
|
468
468
|
onClick: () => onSendDirective(
|
|
469
|
-
|
|
469
|
+
chunkMQHMMB6V_js.mergeTablesDirective(
|
|
470
470
|
twoTables.slideIndex,
|
|
471
471
|
twoTables.elementIdA,
|
|
472
472
|
twoTables.elementIdB
|
|
@@ -487,7 +487,7 @@ function AiFocusBar({
|
|
|
487
487
|
title: t("pptx.ai.pickElement"),
|
|
488
488
|
"aria-label": t("pptx.ai.pickAria"),
|
|
489
489
|
"aria-pressed": pickMode,
|
|
490
|
-
className:
|
|
490
|
+
className: chunkPUALTXTU_js.cn(
|
|
491
491
|
"rounded-sm p-1 max-md:min-w-[44px]! max-md:min-h-[44px]! flex items-center justify-center",
|
|
492
492
|
pickMode ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:bg-accent"
|
|
493
493
|
),
|
|
@@ -566,7 +566,7 @@ function AiHistoryList({ chats, activeChatId, onResume, onDelete }) {
|
|
|
566
566
|
{
|
|
567
567
|
type: "button",
|
|
568
568
|
onClick: () => onResume(chat.id),
|
|
569
|
-
className:
|
|
569
|
+
className: chunkPUALTXTU_js.cn(
|
|
570
570
|
"flex min-w-0 flex-1 items-start gap-2 rounded-sm px-2 py-1.5 text-left hover:bg-accent",
|
|
571
571
|
chat.id === activeChatId && "bg-accent/60"
|
|
572
572
|
),
|
|
@@ -721,26 +721,26 @@ function AiToolCallCard({ part }) {
|
|
|
721
721
|
const failed = part.state === "output-error";
|
|
722
722
|
const done = part.state === "output-available";
|
|
723
723
|
const running = !failed && !done;
|
|
724
|
-
const activity =
|
|
724
|
+
const activity = chunkMQHMMB6V_js.describeToolActivity(part.toolName, part.input, running ? "present" : "past");
|
|
725
725
|
const Icon = ICONS[activity.icon] ?? lu.LuWrench;
|
|
726
|
-
const rawSummary =
|
|
726
|
+
const rawSummary = chunkMQHMMB6V_js.summarizeToolArgs(part.input);
|
|
727
727
|
const statusLabel = failed ? t("pptx.ai.toolFailed") : done ? t("pptx.ai.toolDone") : t("pptx.ai.toolRunning");
|
|
728
728
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[12px]", children: [
|
|
729
729
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-1.5", children: [
|
|
730
730
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
731
731
|
Icon,
|
|
732
732
|
{
|
|
733
|
-
className:
|
|
733
|
+
className: chunkPUALTXTU_js.cn(
|
|
734
734
|
"w-3.5 h-3.5 shrink-0",
|
|
735
735
|
failed ? "text-destructive" : "text-muted-foreground"
|
|
736
736
|
)
|
|
737
737
|
}
|
|
738
738
|
),
|
|
739
|
-
/* @__PURE__ */ jsxRuntime.jsx("span", { className:
|
|
739
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: chunkPUALTXTU_js.cn("truncate", failed ? "text-destructive" : "text-foreground"), children: activity.label }),
|
|
740
740
|
/* @__PURE__ */ jsxRuntime.jsxs(
|
|
741
741
|
"span",
|
|
742
742
|
{
|
|
743
|
-
className:
|
|
743
|
+
className: chunkPUALTXTU_js.cn(
|
|
744
744
|
"ml-auto inline-flex items-center gap-1 rounded-sm px-1.5 py-0.5 text-[10px]",
|
|
745
745
|
failed ? "bg-destructive/15 text-destructive" : done ? "bg-primary/10 text-primary" : "bg-muted text-muted-foreground"
|
|
746
746
|
),
|
|
@@ -757,7 +757,7 @@ function AiToolCallCard({ part }) {
|
|
|
757
757
|
rawSummary && /* @__PURE__ */ jsxRuntime.jsxs("details", { className: "group mt-0.5 pl-5", children: [
|
|
758
758
|
/* @__PURE__ */ jsxRuntime.jsx("summary", { className: "cursor-pointer list-none text-[10px] text-muted-foreground/70 hover:text-muted-foreground", children: t("pptx.ai.toolDetails") }),
|
|
759
759
|
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: "mt-0.5 break-words font-mono text-[10px] text-muted-foreground/80", children: [
|
|
760
|
-
|
|
760
|
+
chunkMQHMMB6V_js.toolLabel(part.toolName),
|
|
761
761
|
": ",
|
|
762
762
|
rawSummary
|
|
763
763
|
] })
|
|
@@ -788,7 +788,7 @@ function AiMessageList({ messages, isStreaming, bridge }) {
|
|
|
788
788
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
789
789
|
"div",
|
|
790
790
|
{
|
|
791
|
-
className:
|
|
791
|
+
className: chunkPUALTXTU_js.cn(
|
|
792
792
|
"mt-0.5 flex h-6 w-6 shrink-0 items-center justify-center rounded-full",
|
|
793
793
|
isUser ? "bg-secondary text-muted-foreground" : "bg-primary/15 text-primary"
|
|
794
794
|
),
|
|
@@ -835,7 +835,7 @@ function AiMessageList({ messages, isStreaming, bridge }) {
|
|
|
835
835
|
}
|
|
836
836
|
function AiProposalCard({ proposal, onAccept, onReject }) {
|
|
837
837
|
const { t } = reactI18next.useTranslation();
|
|
838
|
-
const lines = proposal.summary.map(
|
|
838
|
+
const lines = proposal.summary.map(chunkMQHMMB6V_js.humanizeDiffLine);
|
|
839
839
|
return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "rounded-md border border-primary/40 bg-primary/5 p-2.5", children: [
|
|
840
840
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "mb-1.5 text-[11px] font-semibold uppercase tracking-wide text-primary", children: t("pptx.ai.proposedChange") }),
|
|
841
841
|
/* @__PURE__ */ jsxRuntime.jsx("div", { className: "text-[12px] font-medium text-foreground", children: proposal.label }),
|
|
@@ -1043,7 +1043,7 @@ function AiChatPanel({
|
|
|
1043
1043
|
}) {
|
|
1044
1044
|
const { t } = reactI18next.useTranslation();
|
|
1045
1045
|
const { state, session, initError } = useAiChat(bridge, config);
|
|
1046
|
-
const deckId = react.useMemo(() =>
|
|
1046
|
+
const deckId = react.useMemo(() => chunkMQHMMB6V_js.deckIdFromBridge(bridge), [bridge]);
|
|
1047
1047
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
1048
1048
|
"div",
|
|
1049
1049
|
{
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkDNR6CH6I_js = require('./chunk-DNR6CH6I.js');
|
|
4
|
-
var
|
|
4
|
+
var chunkSK2CZQ6P_js = require('./chunk-SK2CZQ6P.js');
|
|
5
5
|
require('./chunk-4VNS5WPM.js');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -23,7 +23,7 @@ function Area3DChartScene({
|
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
let disposed = false;
|
|
26
|
-
void
|
|
26
|
+
void chunkSK2CZQ6P_js.mountAreaChart3D(container, options, stableInteraction).then((handle) => {
|
|
27
27
|
if (disposed) {
|
|
28
28
|
handle.dispose();
|
|
29
29
|
} else {
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useStableChart3DInteraction, useLatestRef } from './chunk-T6GFCLSM.mjs';
|
|
2
|
-
import { mountAreaChart3D } from './chunk-
|
|
2
|
+
import { mountAreaChart3D } from './chunk-Q6QJOD56.mjs';
|
|
3
3
|
import './chunk-XGB3TDIC.mjs';
|
|
4
4
|
import { useRef, useEffect } from 'react';
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useStableChart3DInteraction, useLatestRef } from './chunk-T6GFCLSM.mjs';
|
|
2
|
-
import { mountBarChart3D } from './chunk-
|
|
2
|
+
import { mountBarChart3D } from './chunk-Q6QJOD56.mjs';
|
|
3
3
|
import './chunk-XGB3TDIC.mjs';
|
|
4
4
|
import { useRef, useEffect } from 'react';
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkDNR6CH6I_js = require('./chunk-DNR6CH6I.js');
|
|
4
|
-
var
|
|
4
|
+
var chunkSK2CZQ6P_js = require('./chunk-SK2CZQ6P.js');
|
|
5
5
|
require('./chunk-4VNS5WPM.js');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -23,7 +23,7 @@ function Bar3DChartScene({
|
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
let disposed = false;
|
|
26
|
-
void
|
|
26
|
+
void chunkSK2CZQ6P_js.mountBarChart3D(container, options, stableInteraction).then((handle) => {
|
|
27
27
|
if (disposed) {
|
|
28
28
|
handle.dispose();
|
|
29
29
|
} else {
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useStableChart3DInteraction, useLatestRef } from './chunk-T6GFCLSM.mjs';
|
|
2
|
-
import { mountLineChart3D } from './chunk-
|
|
2
|
+
import { mountLineChart3D } from './chunk-Q6QJOD56.mjs';
|
|
3
3
|
import './chunk-XGB3TDIC.mjs';
|
|
4
4
|
import { useRef, useEffect } from 'react';
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkDNR6CH6I_js = require('./chunk-DNR6CH6I.js');
|
|
4
|
-
var
|
|
4
|
+
var chunkSK2CZQ6P_js = require('./chunk-SK2CZQ6P.js');
|
|
5
5
|
require('./chunk-4VNS5WPM.js');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -23,7 +23,7 @@ function Line3DChartScene({
|
|
|
23
23
|
return;
|
|
24
24
|
}
|
|
25
25
|
let disposed = false;
|
|
26
|
-
void
|
|
26
|
+
void chunkSK2CZQ6P_js.mountLineChart3D(container, options, stableInteraction).then((handle) => {
|
|
27
27
|
if (disposed) {
|
|
28
28
|
handle.dispose();
|
|
29
29
|
} else {
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var chunkSK2CZQ6P_js = require('./chunk-SK2CZQ6P.js');
|
|
4
4
|
require('./chunk-4VNS5WPM.js');
|
|
5
5
|
var react = require('react');
|
|
6
6
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -14,7 +14,7 @@ function Model3DScene({ modelUrl, interactive, width, height }) {
|
|
|
14
14
|
return;
|
|
15
15
|
}
|
|
16
16
|
let disposed = false;
|
|
17
|
-
void
|
|
17
|
+
void chunkSK2CZQ6P_js.mountModel3D(container, modelUrl, { width, height, interactive }).then((handle) => {
|
|
18
18
|
if (disposed) {
|
|
19
19
|
handle.dispose();
|
|
20
20
|
} else {
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useStableChart3DInteraction, useLatestRef } from './chunk-T6GFCLSM.mjs';
|
|
2
|
-
import { mountPieChart3D } from './chunk-
|
|
2
|
+
import { mountPieChart3D } from './chunk-Q6QJOD56.mjs';
|
|
3
3
|
import './chunk-XGB3TDIC.mjs';
|
|
4
4
|
import { useRef, useEffect } from 'react';
|
|
5
5
|
import { jsx } from 'react/jsx-runtime';
|
|
Binary file
|
|
Binary file
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
3
|
var chunkDNR6CH6I_js = require('./chunk-DNR6CH6I.js');
|
|
4
|
-
var
|
|
4
|
+
var chunkSK2CZQ6P_js = require('./chunk-SK2CZQ6P.js');
|
|
5
5
|
require('./chunk-4VNS5WPM.js');
|
|
6
6
|
var react = require('react');
|
|
7
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
@@ -21,7 +21,7 @@ function PieChart3DScene({
|
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
23
|
let disposed = false;
|
|
24
|
-
void
|
|
24
|
+
void chunkSK2CZQ6P_js.mountPieChart3D(container, options, stableInteraction).then((handle) => {
|
|
25
25
|
if (disposed) {
|
|
26
26
|
handle.dispose();
|
|
27
27
|
} else {
|
|
Binary file
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useLatestRef } from './chunk-T6GFCLSM.mjs';
|
|
2
2
|
import { OrbitControls } from './chunk-MV2GCDBR.mjs';
|
|
3
|
-
import { WebGLRenderer, Scene, Color, PerspectiveCamera, AmbientLight, DirectionalLight, Group, MeshStandardMaterial, Mesh, EdgesGeometry, LineBasicMaterial, LineSegments, PlaneGeometry, MeshBasicMaterial, Euler, Vector3, BufferGeometry, Line, Shape, ExtrudeGeometry, CanvasTexture, SRGBColorSpace, LinearFilter, RepeatWrapping } from './chunk-7TAWW5QQ.mjs';
|
|
3
|
+
import { WebGLRenderer, Scene, Color, PerspectiveCamera, AmbientLight, DirectionalLight, Group, MeshStandardMaterial, Mesh, EdgesGeometry, LineBasicMaterial, LineSegments, PlaneGeometry, MeshBasicMaterial, DoubleSide, Euler, Vector3, BufferGeometry, Line, Shape, ExtrudeGeometry, CanvasTexture, SRGBColorSpace, LinearFilter, RepeatWrapping } from './chunk-7TAWW5QQ.mjs';
|
|
4
4
|
import './chunk-XGB3TDIC.mjs';
|
|
5
5
|
import { useRef, useEffect } from 'react';
|
|
6
6
|
import { jsx } from 'react/jsx-runtime';
|
|
@@ -159,9 +159,12 @@ function buildLabelPlane(m, textStyle) {
|
|
|
159
159
|
const planeMaterial = new MeshBasicMaterial({
|
|
160
160
|
map: tex.texture,
|
|
161
161
|
transparent: true,
|
|
162
|
-
depthWrite: false
|
|
162
|
+
depthWrite: false,
|
|
163
|
+
depthTest: false,
|
|
164
|
+
side: DoubleSide
|
|
163
165
|
});
|
|
164
166
|
const plane = new Mesh(planeGeo, planeMaterial);
|
|
167
|
+
plane.renderOrder = 1;
|
|
165
168
|
const euler = new Euler(m.rotation.x, m.rotation.y, m.rotation.z);
|
|
166
169
|
const offset = new Vector3(0, 0, m.depth + m.bevel + 0.4).applyEuler(euler);
|
|
167
170
|
plane.position.set(m.position.x + offset.x, m.position.y + offset.y, m.position.z + offset.z);
|
|
@@ -218,6 +221,13 @@ function buildMeshGroup(model, textStyle) {
|
|
|
218
221
|
}
|
|
219
222
|
}
|
|
220
223
|
},
|
|
224
|
+
forEachLabelPlane(fn) {
|
|
225
|
+
for (const entry of labelEntries) {
|
|
226
|
+
if (entry.plane) {
|
|
227
|
+
fn(entry.plane);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
},
|
|
221
231
|
dispose() {
|
|
222
232
|
for (const d of blockDisposables) {
|
|
223
233
|
d.dispose();
|
|
@@ -229,6 +239,17 @@ function buildMeshGroup(model, textStyle) {
|
|
|
229
239
|
};
|
|
230
240
|
}
|
|
231
241
|
var FOV = 42;
|
|
242
|
+
function expandForMesh(expand, m) {
|
|
243
|
+
const hx = m.halfWidth + m.bevel;
|
|
244
|
+
const hy = m.halfHeight + m.bevel;
|
|
245
|
+
const hz = m.depth / 2 + m.bevel;
|
|
246
|
+
const midZ = m.position.z + m.depth / 2;
|
|
247
|
+
const cosY = Math.cos(m.rotation.y);
|
|
248
|
+
const sinY = Math.sin(m.rotation.y);
|
|
249
|
+
const worldHalfX = Math.abs(hx * cosY) + Math.abs(hz * sinY);
|
|
250
|
+
const worldHalfZ = Math.abs(hx * sinY) + Math.abs(hz * cosY);
|
|
251
|
+
expand(m.position.x, m.position.y, midZ, worldHalfX, hy, worldHalfZ);
|
|
252
|
+
}
|
|
232
253
|
function contentSphere(model) {
|
|
233
254
|
let minX = Infinity;
|
|
234
255
|
let minY = Infinity;
|
|
@@ -236,32 +257,36 @@ function contentSphere(model) {
|
|
|
236
257
|
let maxX = -Infinity;
|
|
237
258
|
let maxY = -Infinity;
|
|
238
259
|
let maxZ = -Infinity;
|
|
239
|
-
const expand = (x, y, z,
|
|
240
|
-
minX = Math.min(minX, x -
|
|
241
|
-
minY = Math.min(minY, y -
|
|
242
|
-
minZ = Math.min(minZ, z -
|
|
243
|
-
maxX = Math.max(maxX, x +
|
|
244
|
-
maxY = Math.max(maxY, y +
|
|
245
|
-
maxZ = Math.max(maxZ, z +
|
|
260
|
+
const expand = (x, y, z, rx, ry, rz) => {
|
|
261
|
+
minX = Math.min(minX, x - rx);
|
|
262
|
+
minY = Math.min(minY, y - ry);
|
|
263
|
+
minZ = Math.min(minZ, z - rz);
|
|
264
|
+
maxX = Math.max(maxX, x + rx);
|
|
265
|
+
maxY = Math.max(maxY, y + ry);
|
|
266
|
+
maxZ = Math.max(maxZ, z + rz);
|
|
246
267
|
};
|
|
247
268
|
for (const m of model.meshes) {
|
|
248
|
-
|
|
249
|
-
expand(m.position.x, m.position.y, m.position.z, r);
|
|
269
|
+
expandForMesh(expand, m);
|
|
250
270
|
}
|
|
251
271
|
for (const c of model.connectors) {
|
|
252
272
|
for (const p of c.points) {
|
|
253
|
-
expand(p.x, p.y, p.z, 1);
|
|
273
|
+
expand(p.x, p.y, p.z, 1, 1, 1);
|
|
254
274
|
}
|
|
255
275
|
}
|
|
256
276
|
if (!Number.isFinite(minX)) {
|
|
257
|
-
const
|
|
258
|
-
|
|
277
|
+
const halfW = model.bounds.width / 2 || 1;
|
|
278
|
+
const halfH = model.bounds.height / 2 || 1;
|
|
279
|
+
const fallback = Math.max(halfW, halfH);
|
|
280
|
+
return { cx: 0, cy: 0, cz: 0, radius: fallback, halfW, halfH, halfD: 1 };
|
|
259
281
|
}
|
|
260
282
|
return {
|
|
261
283
|
cx: (minX + maxX) / 2,
|
|
262
284
|
cy: (minY + maxY) / 2,
|
|
263
285
|
cz: (minZ + maxZ) / 2,
|
|
264
|
-
radius: 0.5 * Math.hypot(maxX - minX, maxY - minY, maxZ - minZ) || 1
|
|
286
|
+
radius: 0.5 * Math.hypot(maxX - minX, maxY - minY, maxZ - minZ) || 1,
|
|
287
|
+
halfW: (maxX - minX) / 2,
|
|
288
|
+
halfH: (maxY - minY) / 2,
|
|
289
|
+
halfD: (maxZ - minZ) / 2
|
|
265
290
|
};
|
|
266
291
|
}
|
|
267
292
|
function frameDistance(radius, aspect) {
|
|
@@ -270,6 +295,83 @@ function frameDistance(radius, aspect) {
|
|
|
270
295
|
const minFov = Math.min(vFov, hFov);
|
|
271
296
|
return radius / Math.sin(minFov / 2) * 1.1;
|
|
272
297
|
}
|
|
298
|
+
var FRAME_FILL = 0.92;
|
|
299
|
+
function placeCamera(bounds, family, dist) {
|
|
300
|
+
const { cx, cy, cz, radius } = bounds;
|
|
301
|
+
const elevation = cameraElevation(family, radius, dist);
|
|
302
|
+
return {
|
|
303
|
+
position: [cx + radius * 0.25, cy + elevation, cz + dist],
|
|
304
|
+
target: [cx, cy, cz],
|
|
305
|
+
dist
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function projectedFill(bounds, placement, aspect) {
|
|
309
|
+
const vFov = FOV * Math.PI / 180;
|
|
310
|
+
const tanV = Math.tan(vFov / 2);
|
|
311
|
+
const tanH = tanV * aspect;
|
|
312
|
+
const [px, py, pz] = placement.position;
|
|
313
|
+
const [tx, ty, tz] = placement.target;
|
|
314
|
+
let fx = tx - px, fy = ty - py, fz = tz - pz;
|
|
315
|
+
const fl = Math.hypot(fx, fy, fz) || 1;
|
|
316
|
+
fx /= fl;
|
|
317
|
+
fy /= fl;
|
|
318
|
+
fz /= fl;
|
|
319
|
+
let rx = -fz, rz = fx;
|
|
320
|
+
const rl = Math.hypot(rx, rz) || 1;
|
|
321
|
+
rx /= rl;
|
|
322
|
+
rz /= rl;
|
|
323
|
+
const ux = -rz * fy, uy = rz * fx - rx * fz, uz = rx * fy;
|
|
324
|
+
let worst = 0;
|
|
325
|
+
for (const sx of [-1, 1]) {
|
|
326
|
+
for (const sy of [-1, 1]) {
|
|
327
|
+
for (const sz of [-1, 1]) {
|
|
328
|
+
const dx = bounds.cx + sx * bounds.halfW - px;
|
|
329
|
+
const dy = bounds.cy + sy * bounds.halfH - py;
|
|
330
|
+
const dz = bounds.cz + sz * bounds.halfD - pz;
|
|
331
|
+
const depth = dx * fx + dy * fy + dz * fz;
|
|
332
|
+
if (depth <= 1e-6) {
|
|
333
|
+
return Infinity;
|
|
334
|
+
}
|
|
335
|
+
const x = Math.abs(dx * rx + dz * rz) / (depth * tanH);
|
|
336
|
+
const y = Math.abs(dx * ux + dy * uy + dz * uz) / (depth * tanV);
|
|
337
|
+
worst = Math.max(worst, x, y);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
return worst;
|
|
342
|
+
}
|
|
343
|
+
function fitCamera(bounds, family, aspect) {
|
|
344
|
+
let dist = frameDistance(bounds.radius, aspect);
|
|
345
|
+
let placement = placeCamera(bounds, family, dist);
|
|
346
|
+
for (let step = 0; step < 8; step++) {
|
|
347
|
+
const fill = projectedFill(bounds, placement, aspect);
|
|
348
|
+
if (!Number.isFinite(fill)) {
|
|
349
|
+
dist *= 2;
|
|
350
|
+
} else {
|
|
351
|
+
const ratio = fill / FRAME_FILL;
|
|
352
|
+
if (Math.abs(ratio - 1) < 0.01) {
|
|
353
|
+
break;
|
|
354
|
+
}
|
|
355
|
+
dist *= ratio;
|
|
356
|
+
}
|
|
357
|
+
placement = placeCamera(bounds, family, dist);
|
|
358
|
+
}
|
|
359
|
+
return placement;
|
|
360
|
+
}
|
|
361
|
+
var CAROUSEL_ELEVATION_DEG = 34;
|
|
362
|
+
function cameraElevation(family, radius, dist) {
|
|
363
|
+
if (family === "cycle" || family === "radial") {
|
|
364
|
+
return dist * Math.tan(CAROUSEL_ELEVATION_DEG * Math.PI / 180);
|
|
365
|
+
}
|
|
366
|
+
return radius * 0.3;
|
|
367
|
+
}
|
|
368
|
+
function billboardLabels(built, camera) {
|
|
369
|
+
built.forEachLabelPlane((plane) => {
|
|
370
|
+
const dx = camera.position.x - plane.position.x;
|
|
371
|
+
const dz = camera.position.z - plane.position.z;
|
|
372
|
+
plane.rotation.set(0, Math.atan2(dx, dz), 0);
|
|
373
|
+
});
|
|
374
|
+
}
|
|
273
375
|
function mountSmartArt3D(canvas, model, width, height, options = {}) {
|
|
274
376
|
const renderer = new WebGLRenderer({ canvas, antialias: true, alpha: !options.background });
|
|
275
377
|
renderer.setPixelRatio(
|
|
@@ -283,12 +385,14 @@ function mountSmartArt3D(canvas, model, width, height, options = {}) {
|
|
|
283
385
|
if (options.background) {
|
|
284
386
|
scene.background = new Color(options.background);
|
|
285
387
|
}
|
|
286
|
-
const
|
|
388
|
+
const bounds = contentSphere(model);
|
|
389
|
+
const { cx, cy, cz, radius } = bounds;
|
|
287
390
|
const aspect = width / Math.max(1, height);
|
|
288
|
-
const
|
|
391
|
+
const placement = fitCamera(bounds, model.family, aspect);
|
|
392
|
+
const { dist } = placement;
|
|
289
393
|
const camera = new PerspectiveCamera(FOV, aspect, 0.1, dist * 8 + radius * 4);
|
|
290
|
-
camera.position.set(
|
|
291
|
-
camera.lookAt(
|
|
394
|
+
camera.position.set(...placement.position);
|
|
395
|
+
camera.lookAt(...placement.target);
|
|
292
396
|
scene.add(new AmbientLight(16777215, 0.62));
|
|
293
397
|
const key = new DirectionalLight(16777215, 0.95);
|
|
294
398
|
key.position.set(cx + radius, cy + radius * 1.4, cz + dist);
|
|
@@ -324,6 +428,7 @@ function mountSmartArt3D(canvas, model, width, height, options = {}) {
|
|
|
324
428
|
return;
|
|
325
429
|
}
|
|
326
430
|
frame = requestAnimationFrame(renderLoop);
|
|
431
|
+
billboardLabels(built, camera);
|
|
327
432
|
controls?.update();
|
|
328
433
|
renderer.render(scene, camera);
|
|
329
434
|
};
|
|
Binary file
|
|
Binary file
|