@printwithsynergy/lens-pdf 0.3.0-beta.81
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/LICENSE +661 -0
- package/README.md +344 -0
- package/dist/browser/codexOverlay.d.ts +109 -0
- package/dist/browser/codexOverlay.d.ts.map +1 -0
- package/dist/browser/codexOverlay.js +256 -0
- package/dist/browser/codexOverlay.js.map +1 -0
- package/dist/browser/constants.d.ts +13 -0
- package/dist/browser/constants.d.ts.map +1 -0
- package/dist/browser/constants.js +13 -0
- package/dist/browser/constants.js.map +1 -0
- package/dist/browser/index.d.ts +211 -0
- package/dist/browser/index.d.ts.map +1 -0
- package/dist/browser/index.js +1190 -0
- package/dist/browser/index.js.map +1 -0
- package/dist/browser/pantone-gold.d.ts +59 -0
- package/dist/browser/pantone-gold.d.ts.map +1 -0
- package/dist/browser/pantone-gold.js +237 -0
- package/dist/browser/pantone-gold.js.map +1 -0
- package/dist/components/AnnotationCanvas.d.ts +27 -0
- package/dist/components/AnnotationCanvas.d.ts.map +1 -0
- package/dist/components/AnnotationCanvas.js +401 -0
- package/dist/components/AnnotationCanvas.js.map +1 -0
- package/dist/components/AnnotationNotesPanel.d.ts +15 -0
- package/dist/components/AnnotationNotesPanel.d.ts.map +1 -0
- package/dist/components/AnnotationNotesPanel.js +235 -0
- package/dist/components/AnnotationNotesPanel.js.map +1 -0
- package/dist/components/AnnotationThread.d.ts +18 -0
- package/dist/components/AnnotationThread.d.ts.map +1 -0
- package/dist/components/AnnotationThread.js +163 -0
- package/dist/components/AnnotationThread.js.map +1 -0
- package/dist/components/AnnotationToolbar.d.ts +39 -0
- package/dist/components/AnnotationToolbar.d.ts.map +1 -0
- package/dist/components/AnnotationToolbar.js +258 -0
- package/dist/components/AnnotationToolbar.js.map +1 -0
- package/dist/components/BoxOverlay.d.ts +20 -0
- package/dist/components/BoxOverlay.d.ts.map +1 -0
- package/dist/components/BoxOverlay.js +107 -0
- package/dist/components/BoxOverlay.js.map +1 -0
- package/dist/components/ColorPickerTool.d.ts +11 -0
- package/dist/components/ColorPickerTool.d.ts.map +1 -0
- package/dist/components/ColorPickerTool.js +220 -0
- package/dist/components/ColorPickerTool.js.map +1 -0
- package/dist/components/DensitometerTool.d.ts +25 -0
- package/dist/components/DensitometerTool.d.ts.map +1 -0
- package/dist/components/DensitometerTool.js +246 -0
- package/dist/components/DensitometerTool.js.map +1 -0
- package/dist/components/DielineInfoPanel.d.ts +27 -0
- package/dist/components/DielineInfoPanel.d.ts.map +1 -0
- package/dist/components/DielineInfoPanel.js +23 -0
- package/dist/components/DielineInfoPanel.js.map +1 -0
- package/dist/components/DielineOverlay.d.ts +10 -0
- package/dist/components/DielineOverlay.d.ts.map +1 -0
- package/dist/components/DielineOverlay.js +57 -0
- package/dist/components/DielineOverlay.js.map +1 -0
- package/dist/components/FindingsSidebar.d.ts +50 -0
- package/dist/components/FindingsSidebar.d.ts.map +1 -0
- package/dist/components/FindingsSidebar.js +78 -0
- package/dist/components/FindingsSidebar.js.map +1 -0
- package/dist/components/LayerCanvas.d.ts +30 -0
- package/dist/components/LayerCanvas.d.ts.map +1 -0
- package/dist/components/LayerCanvas.js +84 -0
- package/dist/components/LayerCanvas.js.map +1 -0
- package/dist/components/LayerPanel.d.ts +9 -0
- package/dist/components/LayerPanel.d.ts.map +1 -0
- package/dist/components/LayerPanel.js +144 -0
- package/dist/components/LayerPanel.js.map +1 -0
- package/dist/components/LensPDF.d.ts +61 -0
- package/dist/components/LensPDF.d.ts.map +1 -0
- package/dist/components/LensPDF.js +49 -0
- package/dist/components/LensPDF.js.map +1 -0
- package/dist/components/LensPDFDemo.d.ts +160 -0
- package/dist/components/LensPDFDemo.d.ts.map +1 -0
- package/dist/components/LensPDFDemo.js +1060 -0
- package/dist/components/LensPDFDemo.js.map +1 -0
- package/dist/components/LensPDFDemo.styles.d.ts +38 -0
- package/dist/components/LensPDFDemo.styles.d.ts.map +1 -0
- package/dist/components/LensPDFDemo.styles.js +282 -0
- package/dist/components/LensPDFDemo.styles.js.map +1 -0
- package/dist/components/LensPDFViewer.d.ts +79 -0
- package/dist/components/LensPDFViewer.d.ts.map +1 -0
- package/dist/components/LensPDFViewer.js +254 -0
- package/dist/components/LensPDFViewer.js.map +1 -0
- package/dist/components/MeasureTool.d.ts +16 -0
- package/dist/components/MeasureTool.d.ts.map +1 -0
- package/dist/components/MeasureTool.js +137 -0
- package/dist/components/MeasureTool.js.map +1 -0
- package/dist/components/MobileBottomSheet.d.ts +12 -0
- package/dist/components/MobileBottomSheet.d.ts.map +1 -0
- package/dist/components/MobileBottomSheet.js +113 -0
- package/dist/components/MobileBottomSheet.js.map +1 -0
- package/dist/components/MobileDrawer.d.ts +31 -0
- package/dist/components/MobileDrawer.d.ts.map +1 -0
- package/dist/components/MobileDrawer.js +67 -0
- package/dist/components/MobileDrawer.js.map +1 -0
- package/dist/components/PageCanvas.d.ts +33 -0
- package/dist/components/PageCanvas.d.ts.map +1 -0
- package/dist/components/PageCanvas.js +385 -0
- package/dist/components/PageCanvas.js.map +1 -0
- package/dist/components/PageNavigator.d.ts +18 -0
- package/dist/components/PageNavigator.d.ts.map +1 -0
- package/dist/components/PageNavigator.js +44 -0
- package/dist/components/PageNavigator.js.map +1 -0
- package/dist/components/SeparationCanvas.d.ts +12 -0
- package/dist/components/SeparationCanvas.d.ts.map +1 -0
- package/dist/components/SeparationCanvas.js +174 -0
- package/dist/components/SeparationCanvas.js.map +1 -0
- package/dist/components/TACHeatmapOverlay.d.ts +17 -0
- package/dist/components/TACHeatmapOverlay.d.ts.map +1 -0
- package/dist/components/TACHeatmapOverlay.js +119 -0
- package/dist/components/TACHeatmapOverlay.js.map +1 -0
- package/dist/components/ZoomControls.d.ts +11 -0
- package/dist/components/ZoomControls.d.ts.map +1 -0
- package/dist/components/ZoomControls.js +26 -0
- package/dist/components/ZoomControls.js.map +1 -0
- package/dist/components/defaultShellPlugins.d.ts +3 -0
- package/dist/components/defaultShellPlugins.d.ts.map +1 -0
- package/dist/components/defaultShellPlugins.js +273 -0
- package/dist/components/defaultShellPlugins.js.map +1 -0
- package/dist/components/index.d.ts +32 -0
- package/dist/components/index.d.ts.map +1 -0
- package/dist/components/index.js +32 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/presets.d.ts +8 -0
- package/dist/components/presets.d.ts.map +1 -0
- package/dist/components/presets.js +14 -0
- package/dist/components/presets.js.map +1 -0
- package/dist/components/shellPlugins.d.ts +105 -0
- package/dist/components/shellPlugins.d.ts.map +1 -0
- package/dist/components/shellPlugins.js +52 -0
- package/dist/components/shellPlugins.js.map +1 -0
- package/dist/components/useIsMobile.d.ts +16 -0
- package/dist/components/useIsMobile.d.ts.map +1 -0
- package/dist/components/useIsMobile.js +30 -0
- package/dist/components/useIsMobile.js.map +1 -0
- package/dist/fallback-pdfjs/index.d.ts +60 -0
- package/dist/fallback-pdfjs/index.d.ts.map +1 -0
- package/dist/fallback-pdfjs/index.js +163 -0
- package/dist/fallback-pdfjs/index.js.map +1 -0
- package/dist/host/LensPDFProvider.d.ts +36 -0
- package/dist/host/LensPDFProvider.d.ts.map +1 -0
- package/dist/host/LensPDFProvider.js +12 -0
- package/dist/host/LensPDFProvider.js.map +1 -0
- package/dist/host/index.d.ts +167 -0
- package/dist/host/index.d.ts.map +1 -0
- package/dist/host/index.js +173 -0
- package/dist/host/index.js.map +1 -0
- package/dist/host/pdfFallback.d.ts +50 -0
- package/dist/host/pdfFallback.d.ts.map +1 -0
- package/dist/host/pdfFallback.js +171 -0
- package/dist/host/pdfFallback.js.map +1 -0
- package/dist/host/pdfValidation.d.ts +45 -0
- package/dist/host/pdfValidation.d.ts.map +1 -0
- package/dist/host/pdfValidation.js +78 -0
- package/dist/host/pdfValidation.js.map +1 -0
- package/dist/host/shareLink.d.ts +80 -0
- package/dist/host/shareLink.d.ts.map +1 -0
- package/dist/host/shareLink.js +114 -0
- package/dist/host/shareLink.js.map +1 -0
- package/dist/host/useLensPDF.d.ts +73 -0
- package/dist/host/useLensPDF.d.ts.map +1 -0
- package/dist/host/useLensPDF.js +213 -0
- package/dist/host/useLensPDF.js.map +1 -0
- package/dist/index.d.ts +68 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +62 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/context.d.ts +70 -0
- package/dist/plugin/context.d.ts.map +1 -0
- package/dist/plugin/context.js +16 -0
- package/dist/plugin/context.js.map +1 -0
- package/dist/plugin/findings-location.d.ts +53 -0
- package/dist/plugin/findings-location.d.ts.map +1 -0
- package/dist/plugin/findings-location.js +72 -0
- package/dist/plugin/findings-location.js.map +1 -0
- package/dist/plugin/index.d.ts +19 -0
- package/dist/plugin/index.d.ts.map +1 -0
- package/dist/plugin/index.js +16 -0
- package/dist/plugin/index.js.map +1 -0
- package/dist/plugin/registry.d.ts +61 -0
- package/dist/plugin/registry.d.ts.map +1 -0
- package/dist/plugin/registry.js +102 -0
- package/dist/plugin/registry.js.map +1 -0
- package/dist/plugin/services.d.ts +380 -0
- package/dist/plugin/services.d.ts.map +1 -0
- package/dist/plugin/services.js +104 -0
- package/dist/plugin/services.js.map +1 -0
- package/dist/plugin/types.d.ts +198 -0
- package/dist/plugin/types.d.ts.map +1 -0
- package/dist/plugin/types.js +24 -0
- package/dist/plugin/types.js.map +1 -0
- package/dist/types/index.d.ts +191 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +95 -0
- package/dist/types/index.js.map +1 -0
- package/dist/units/index.d.ts +64 -0
- package/dist/units/index.d.ts.map +1 -0
- package/dist/units/index.js +98 -0
- package/dist/units/index.js.map +1 -0
- package/docs/architecture.md +90 -0
- package/docs/components.md +569 -0
- package/docs/contributing.md +78 -0
- package/docs/fallback.md +174 -0
- package/docs/lens-pdf-viewer.md +128 -0
- package/docs/licensing.md +78 -0
- package/docs/measurement-units.md +87 -0
- package/docs/plugins.md +256 -0
- package/docs/security.md +69 -0
- package/docs/server.md +212 -0
- package/docs/services.md +210 -0
- package/docs/share-links.md +111 -0
- package/docs/theming.md +164 -0
- package/docs/validation.md +83 -0
- package/package.json +139 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef } from "react";
|
|
4
|
+
import { THUMBNAIL_DPI } from "../types/index.js";
|
|
5
|
+
import { useViewerServices } from "../host/index.js";
|
|
6
|
+
export function PageNavigator({ pages, currentPage, items, onPageChange, horizontal, }) {
|
|
7
|
+
const { pageImages } = useViewerServices();
|
|
8
|
+
const activeRef = useRef(null);
|
|
9
|
+
useEffect(() => {
|
|
10
|
+
activeRef.current?.scrollIntoView({
|
|
11
|
+
block: horizontal ? "nearest" : "nearest",
|
|
12
|
+
inline: horizontal ? "center" : undefined,
|
|
13
|
+
behavior: "smooth",
|
|
14
|
+
});
|
|
15
|
+
}, [currentPage, horizontal]);
|
|
16
|
+
const itemsPerPage = new Map();
|
|
17
|
+
for (const item of items) {
|
|
18
|
+
if (!item.page)
|
|
19
|
+
continue;
|
|
20
|
+
const curr = itemsPerPage.get(item.page) ?? { errors: 0, warnings: 0 };
|
|
21
|
+
if (item.tier === "error")
|
|
22
|
+
curr.errors++;
|
|
23
|
+
else if (item.tier === "warning")
|
|
24
|
+
curr.warnings++;
|
|
25
|
+
itemsPerPage.set(item.page, curr);
|
|
26
|
+
}
|
|
27
|
+
if (horizontal) {
|
|
28
|
+
return (_jsx(_Fragment, { children: pages.map((page) => {
|
|
29
|
+
const isActive = page.page_num === currentPage;
|
|
30
|
+
const counts = itemsPerPage.get(page.page_num);
|
|
31
|
+
return (_jsxs("button", { ref: isActive ? activeRef : undefined, onClick: () => onPageChange(page.page_num), className: `relative shrink-0 rounded border p-0.5 transition-colors ${isActive
|
|
32
|
+
? "border-blue-500 ring-2 ring-blue-500/30"
|
|
33
|
+
: "border-white/[0.06] hover:border-slate-500"}`, style: { width: 56 }, children: [_jsx("img", { src: pageImages.getPageImageUrl({ pageNum: page.page_num, dpi: THUMBNAIL_DPI }), alt: `Page ${page.page_num}`, className: "w-full rounded", loading: "lazy" }), _jsx("span", { className: "absolute bottom-0.5 left-0.5 rounded bg-black/60 px-1 text-[9px] text-white", children: page.page_num }), counts && (_jsxs("div", { className: "absolute right-0.5 top-0.5 flex gap-0.5", children: [counts.errors > 0 && (_jsx("span", { className: "rounded-full bg-red-500 px-1 text-[8px] text-white", children: counts.errors })), counts.warnings > 0 && (_jsx("span", { className: "rounded-full bg-amber-500 px-1 text-[8px] text-white", children: counts.warnings }))] }))] }, page.page_num));
|
|
34
|
+
}) }));
|
|
35
|
+
}
|
|
36
|
+
return (_jsxs("div", { className: "flex flex-col gap-1 overflow-y-auto p-2", children: [_jsxs("div", { className: "mb-1 text-xs font-medium text-muted-foreground", children: ["Pages (", pages.length, ")"] }), pages.map((page) => {
|
|
37
|
+
const isActive = page.page_num === currentPage;
|
|
38
|
+
const counts = itemsPerPage.get(page.page_num);
|
|
39
|
+
return (_jsxs("button", { ref: isActive ? activeRef : undefined, onClick: () => onPageChange(page.page_num), className: `relative rounded border p-0.5 transition-colors ${isActive
|
|
40
|
+
? "border-primary ring-2 ring-primary/30"
|
|
41
|
+
: "border-border hover:border-primary/50"}`, children: [_jsx("img", { src: pageImages.getPageImageUrl({ pageNum: page.page_num, dpi: THUMBNAIL_DPI }), alt: `Page ${page.page_num}`, className: "w-full rounded", loading: "lazy" }), _jsx("span", { className: "absolute bottom-0.5 left-0.5 rounded bg-black/60 px-1 text-[10px] text-white", children: page.page_num }), counts && (_jsxs("div", { className: "absolute right-0.5 top-0.5 flex gap-0.5", children: [counts.errors > 0 && (_jsx("span", { className: "rounded-full bg-destructive px-1 text-[9px] text-white", children: counts.errors })), counts.warnings > 0 && (_jsx("span", { className: "rounded-full bg-warning px-1 text-[9px] text-white", children: counts.warnings }))] }))] }, page.page_num));
|
|
42
|
+
})] }));
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=PageNavigator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageNavigator.js","sourceRoot":"","sources":["../../components/PageNavigator.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface SeparationCanvasProps {
|
|
2
|
+
jobId: string;
|
|
3
|
+
pageNum: number;
|
|
4
|
+
enabledChannels: Set<string>;
|
|
5
|
+
allChannels: string[];
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
dpi?: number;
|
|
9
|
+
}
|
|
10
|
+
export declare function SeparationCanvas({ jobId: _jobId, pageNum, enabledChannels, allChannels, width, height, dpi, }: SeparationCanvasProps): import("react/jsx-runtime").JSX.Element | null;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=SeparationCanvas.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeparationCanvas.d.ts","sourceRoot":"","sources":["../../components/SeparationCanvas.tsx"],"names":[],"mappings":"AA4CA,UAAU,qBAAqB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,eAAe,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC7B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,gBAAgB,CAAC,EAC/B,KAAK,EAAE,MAAM,EACb,OAAO,EACP,eAAe,EACf,WAAW,EACX,KAAK,EACL,MAAM,EACN,GAAiB,GAClB,EAAE,qBAAqB,kDA6IvB"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
4
|
+
import { DEFAULT_DPI } from "../types/index.js";
|
|
5
|
+
import { isUnwired, logUnwiredHide, useViewerHost, useViewerServices } from "../host/index.js";
|
|
6
|
+
/**
|
|
7
|
+
* RGB tint colors for compositing each channel onto a white background
|
|
8
|
+
* using multiply blending. For CMYK channels, we use their subtractive
|
|
9
|
+
* color representation. Spot colors get a generated hue.
|
|
10
|
+
*/
|
|
11
|
+
const CHANNEL_RGB = {
|
|
12
|
+
Cyan: [0, 183, 235],
|
|
13
|
+
Magenta: [236, 0, 140],
|
|
14
|
+
Yellow: [255, 242, 0],
|
|
15
|
+
Black: [35, 31, 32],
|
|
16
|
+
};
|
|
17
|
+
function spotColorRgb(name) {
|
|
18
|
+
let hash = 0;
|
|
19
|
+
for (let i = 0; i < name.length; i++) {
|
|
20
|
+
hash = name.charCodeAt(i) + ((hash << 5) - hash);
|
|
21
|
+
}
|
|
22
|
+
const hue = Math.abs(hash) % 360;
|
|
23
|
+
// Convert HSL(hue, 70%, 45%) to RGB
|
|
24
|
+
const s = 0.7;
|
|
25
|
+
const l = 0.45;
|
|
26
|
+
const c = (1 - Math.abs(2 * l - 1)) * s;
|
|
27
|
+
const x = c * (1 - Math.abs(((hue / 60) % 2) - 1));
|
|
28
|
+
const m = l - c / 2;
|
|
29
|
+
let r = 0, g = 0, b = 0;
|
|
30
|
+
if (hue < 60) {
|
|
31
|
+
r = c;
|
|
32
|
+
g = x;
|
|
33
|
+
}
|
|
34
|
+
else if (hue < 120) {
|
|
35
|
+
r = x;
|
|
36
|
+
g = c;
|
|
37
|
+
}
|
|
38
|
+
else if (hue < 180) {
|
|
39
|
+
g = c;
|
|
40
|
+
b = x;
|
|
41
|
+
}
|
|
42
|
+
else if (hue < 240) {
|
|
43
|
+
g = x;
|
|
44
|
+
b = c;
|
|
45
|
+
}
|
|
46
|
+
else if (hue < 300) {
|
|
47
|
+
r = x;
|
|
48
|
+
b = c;
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
r = c;
|
|
52
|
+
b = x;
|
|
53
|
+
}
|
|
54
|
+
return [
|
|
55
|
+
Math.round((r + m) * 255),
|
|
56
|
+
Math.round((g + m) * 255),
|
|
57
|
+
Math.round((b + m) * 255),
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
export function SeparationCanvas({ jobId: _jobId, pageNum, enabledChannels, allChannels, width, height, dpi = DEFAULT_DPI, }) {
|
|
61
|
+
const { separations } = useViewerServices();
|
|
62
|
+
const { debug } = useViewerHost();
|
|
63
|
+
const hidden = isUnwired(separations);
|
|
64
|
+
const canvasRef = useRef(null);
|
|
65
|
+
const [channelImages, setChannelImages] = useState(new Map());
|
|
66
|
+
const [loadingChannels, setLoadingChannels] = useState(new Set());
|
|
67
|
+
// Clear cached channel images when page changes
|
|
68
|
+
useEffect(() => {
|
|
69
|
+
setChannelImages(new Map());
|
|
70
|
+
setLoadingChannels(new Set());
|
|
71
|
+
}, [pageNum]);
|
|
72
|
+
useEffect(() => {
|
|
73
|
+
if (hidden && debug)
|
|
74
|
+
logUnwiredHide("SeparationCanvas", "separations");
|
|
75
|
+
}, [hidden, debug]);
|
|
76
|
+
// Load channel images lazily
|
|
77
|
+
const loadChannel = useCallback(async (channelName) => {
|
|
78
|
+
if (channelImages.has(channelName) || loadingChannels.has(channelName)) {
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
setLoadingChannels((prev) => new Set(prev).add(channelName));
|
|
82
|
+
const img = new Image();
|
|
83
|
+
const url = separations.getChannelImageUrl({ pageNum, channelName, dpi });
|
|
84
|
+
await new Promise((resolve) => {
|
|
85
|
+
img.onload = () => {
|
|
86
|
+
setChannelImages((prev) => {
|
|
87
|
+
const next = new Map(prev);
|
|
88
|
+
next.set(channelName, img);
|
|
89
|
+
return next;
|
|
90
|
+
});
|
|
91
|
+
setLoadingChannels((prev) => {
|
|
92
|
+
const next = new Set(prev);
|
|
93
|
+
next.delete(channelName);
|
|
94
|
+
return next;
|
|
95
|
+
});
|
|
96
|
+
resolve();
|
|
97
|
+
};
|
|
98
|
+
img.onerror = () => {
|
|
99
|
+
setLoadingChannels((prev) => {
|
|
100
|
+
const next = new Set(prev);
|
|
101
|
+
next.delete(channelName);
|
|
102
|
+
return next;
|
|
103
|
+
});
|
|
104
|
+
resolve();
|
|
105
|
+
};
|
|
106
|
+
img.src = url;
|
|
107
|
+
});
|
|
108
|
+
}, [separations, pageNum, dpi, channelImages, loadingChannels]);
|
|
109
|
+
// Load enabled channels
|
|
110
|
+
useEffect(() => {
|
|
111
|
+
for (const ch of enabledChannels) {
|
|
112
|
+
if (!channelImages.has(ch)) {
|
|
113
|
+
loadChannel(ch);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}, [enabledChannels, channelImages, loadChannel]);
|
|
117
|
+
// Composite enabled channels onto canvas
|
|
118
|
+
useEffect(() => {
|
|
119
|
+
const canvas = canvasRef.current;
|
|
120
|
+
if (!canvas)
|
|
121
|
+
return;
|
|
122
|
+
const ctx = canvas.getContext("2d");
|
|
123
|
+
if (!ctx)
|
|
124
|
+
return;
|
|
125
|
+
// Start with white paper
|
|
126
|
+
ctx.fillStyle = "#ffffff";
|
|
127
|
+
ctx.fillRect(0, 0, width, height);
|
|
128
|
+
// Composite each enabled channel using multiply blend
|
|
129
|
+
for (const channelName of allChannels) {
|
|
130
|
+
if (!enabledChannels.has(channelName))
|
|
131
|
+
continue;
|
|
132
|
+
const img = channelImages.get(channelName);
|
|
133
|
+
if (!img)
|
|
134
|
+
continue;
|
|
135
|
+
// channelName comes from the allChannels list we own — typed Record lookup.
|
|
136
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
137
|
+
const rgb = CHANNEL_RGB[channelName] ?? spotColorRgb(channelName);
|
|
138
|
+
// Create offscreen canvas for tinting
|
|
139
|
+
const offscreen = document.createElement("canvas");
|
|
140
|
+
offscreen.width = width;
|
|
141
|
+
offscreen.height = height;
|
|
142
|
+
const offCtx = offscreen.getContext("2d");
|
|
143
|
+
// Draw grayscale channel image
|
|
144
|
+
offCtx.drawImage(img, 0, 0, width, height);
|
|
145
|
+
// Get pixel data and tint with channel color
|
|
146
|
+
const imageData = offCtx.getImageData(0, 0, width, height);
|
|
147
|
+
const data = imageData.data;
|
|
148
|
+
for (let i = 0; i < data.length; i += 4) {
|
|
149
|
+
// Grayscale value: 0 = full ink, 255 = no ink (inverted)
|
|
150
|
+
// Convert to ink density: 0 = no ink, 255 = full ink
|
|
151
|
+
// data is a Uint8ClampedArray and i is a bounded loop index.
|
|
152
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
153
|
+
const inkDensity = 255 - (data[i] ?? 0);
|
|
154
|
+
// Tinted color = white * (1 - density/255) + channelColor * (density/255)
|
|
155
|
+
const t = inkDensity / 255;
|
|
156
|
+
// eslint-disable-next-line security/detect-object-injection
|
|
157
|
+
data[i] = Math.round(255 * (1 - t) + (rgb[0] ?? 0) * t);
|
|
158
|
+
data[i + 1] = Math.round(255 * (1 - t) + (rgb[1] ?? 0) * t);
|
|
159
|
+
data[i + 2] = Math.round(255 * (1 - t) + (rgb[2] ?? 0) * t);
|
|
160
|
+
data[i + 3] = 255;
|
|
161
|
+
}
|
|
162
|
+
offCtx.putImageData(imageData, 0, 0);
|
|
163
|
+
// Multiply blend onto main canvas
|
|
164
|
+
ctx.globalCompositeOperation = "multiply";
|
|
165
|
+
ctx.drawImage(offscreen, 0, 0);
|
|
166
|
+
}
|
|
167
|
+
// Reset blend mode
|
|
168
|
+
ctx.globalCompositeOperation = "source-over";
|
|
169
|
+
}, [width, height, enabledChannels, channelImages, allChannels]);
|
|
170
|
+
if (hidden)
|
|
171
|
+
return null;
|
|
172
|
+
return (_jsx("canvas", { ref: canvasRef, width: width, height: height, style: { position: "absolute", left: 0, top: 0, width, height } }));
|
|
173
|
+
}
|
|
174
|
+
//# sourceMappingURL=SeparationCanvas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SeparationCanvas.js","sourceRoot":"","sources":["../../components/SeparationCanvas.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
interface TACHeatmapOverlayProps {
|
|
2
|
+
jobId: string;
|
|
3
|
+
pageNum: number;
|
|
4
|
+
width: number;
|
|
5
|
+
height: number;
|
|
6
|
+
/** Page width in PDF points — needed to place SVG hit-targets from
|
|
7
|
+
* the top-left-origin bbox coordinates. */
|
|
8
|
+
pageWidthPts?: number;
|
|
9
|
+
/** Page height in PDF points. */
|
|
10
|
+
pageHeightPts?: number;
|
|
11
|
+
opacity?: number;
|
|
12
|
+
dpi?: number;
|
|
13
|
+
tacLimit?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare function TACHeatmapOverlay({ jobId: _jobId, pageNum, width, height, pageWidthPts, pageHeightPts, opacity, dpi, tacLimit, }: TACHeatmapOverlayProps): import("react/jsx-runtime").JSX.Element | null;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=TACHeatmapOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TACHeatmapOverlay.d.ts","sourceRoot":"","sources":["../../components/TACHeatmapOverlay.tsx"],"names":[],"mappings":"AAyBA,UAAU,sBAAsB;IAC9B,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;gDAC4C;IAC5C,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,iCAAiC;IACjC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,wBAAgB,iBAAiB,CAAC,EAChC,KAAK,EAAE,MAAM,EACb,OAAO,EACP,KAAK,EACL,MAAM,EACN,YAAY,EACZ,aAAa,EACb,OAAa,EACb,GAAiB,EACjB,QAAc,GACf,EAAE,sBAAsB,kDAsMxB"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { DEFAULT_DPI } from "../types/index.js";
|
|
5
|
+
import { isUnwired, logUnwiredHide, useViewerHost, useViewerServices } from "../host/index.js";
|
|
6
|
+
export function TACHeatmapOverlay({ jobId: _jobId, pageNum, width, height, pageWidthPts, pageHeightPts, opacity = 0.5, dpi = DEFAULT_DPI, tacLimit = 300, }) {
|
|
7
|
+
const { tacHeatmap } = useViewerServices();
|
|
8
|
+
const { debug } = useViewerHost();
|
|
9
|
+
const hidden = isUnwired(tacHeatmap);
|
|
10
|
+
const canvasRef = useRef(null);
|
|
11
|
+
const [heatmapImg, setHeatmapImg] = useState(null);
|
|
12
|
+
const [loading, setLoading] = useState(true);
|
|
13
|
+
const [error, setError] = useState("");
|
|
14
|
+
const [runs, setRuns] = useState([]);
|
|
15
|
+
const [hoveredRun, setHoveredRun] = useState(null);
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
if (hidden) {
|
|
18
|
+
if (debug)
|
|
19
|
+
logUnwiredHide("TACHeatmapOverlay", "tacHeatmap");
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
setLoading(true);
|
|
23
|
+
setError("");
|
|
24
|
+
const img = new Image();
|
|
25
|
+
img.onload = () => {
|
|
26
|
+
setHeatmapImg(img);
|
|
27
|
+
setLoading(false);
|
|
28
|
+
};
|
|
29
|
+
img.onerror = () => {
|
|
30
|
+
setError("Failed to load TAC heatmap");
|
|
31
|
+
setLoading(false);
|
|
32
|
+
};
|
|
33
|
+
img.src = tacHeatmap.getHeatmapImageUrl({ pageNum, dpi, tacLimit });
|
|
34
|
+
}, [tacHeatmap, pageNum, dpi, tacLimit, hidden, debug]);
|
|
35
|
+
// Fetch run metadata in parallel with the PNG so the tooltip layer
|
|
36
|
+
// and the pixel gradient appear together. The service's listRuns()
|
|
37
|
+
// already swallows non-fatal failures and returns [] — keep the
|
|
38
|
+
// local cancellation flag so a fast page-flip doesn't write stale
|
|
39
|
+
// runs onto the new page.
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
let cancelled = false;
|
|
42
|
+
setRuns([]);
|
|
43
|
+
void tacHeatmap
|
|
44
|
+
.listRuns({ pageNum, dpi, tacLimit })
|
|
45
|
+
.then((items) => {
|
|
46
|
+
if (!cancelled)
|
|
47
|
+
setRuns([...items]);
|
|
48
|
+
});
|
|
49
|
+
return () => {
|
|
50
|
+
cancelled = true;
|
|
51
|
+
};
|
|
52
|
+
}, [tacHeatmap, pageNum, dpi, tacLimit]);
|
|
53
|
+
useEffect(() => {
|
|
54
|
+
const canvas = canvasRef.current;
|
|
55
|
+
if (!canvas || !heatmapImg)
|
|
56
|
+
return;
|
|
57
|
+
const ctx = canvas.getContext("2d");
|
|
58
|
+
if (!ctx)
|
|
59
|
+
return;
|
|
60
|
+
ctx.clearRect(0, 0, width, height);
|
|
61
|
+
ctx.globalAlpha = opacity;
|
|
62
|
+
ctx.drawImage(heatmapImg, 0, 0, width, height);
|
|
63
|
+
ctx.globalAlpha = 1.0;
|
|
64
|
+
}, [heatmapImg, width, height, opacity]);
|
|
65
|
+
if (hidden)
|
|
66
|
+
return null;
|
|
67
|
+
if (loading) {
|
|
68
|
+
return (_jsx("div", { className: "flex items-center justify-center", style: {
|
|
69
|
+
position: "absolute",
|
|
70
|
+
left: 0,
|
|
71
|
+
top: 0,
|
|
72
|
+
width,
|
|
73
|
+
height,
|
|
74
|
+
}, children: _jsxs("div", { className: "flex flex-col items-center gap-2 rounded-lg bg-black/60 px-4 py-3", children: [_jsxs("svg", { className: "h-6 w-6 animate-spin text-white", fill: "none", viewBox: "0 0 24 24", children: [_jsx("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }), _jsx("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })] }), _jsx("span", { className: "text-xs text-white/70", children: "Generating heatmap" })] }) }));
|
|
75
|
+
}
|
|
76
|
+
if (error) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
// pt → CSS-pixel scale. Falls back to identity when the caller didn't
|
|
80
|
+
// pass dimensions (in that case the SVG layer is skipped entirely so
|
|
81
|
+
// we don't render rectangles at nonsense coordinates).
|
|
82
|
+
const sx = pageWidthPts && pageWidthPts > 0 ? width / pageWidthPts : 0;
|
|
83
|
+
const sy = pageHeightPts && pageHeightPts > 0 ? height / pageHeightPts : 0;
|
|
84
|
+
const showTooltipLayer = sx > 0 && sy > 0 && runs.length > 0;
|
|
85
|
+
return (_jsxs(_Fragment, { children: [_jsx("canvas", { ref: canvasRef, width: width, height: height, style: {
|
|
86
|
+
position: "absolute",
|
|
87
|
+
left: 0,
|
|
88
|
+
top: 0,
|
|
89
|
+
width,
|
|
90
|
+
height,
|
|
91
|
+
pointerEvents: "none",
|
|
92
|
+
} }), showTooltipLayer && (_jsx("svg", { style: {
|
|
93
|
+
position: "absolute",
|
|
94
|
+
left: 0,
|
|
95
|
+
top: 0,
|
|
96
|
+
width,
|
|
97
|
+
height,
|
|
98
|
+
pointerEvents: "none",
|
|
99
|
+
}, width: width, height: height, children: runs.map((run, idx) => {
|
|
100
|
+
const x = run.x0 * sx;
|
|
101
|
+
const y = run.y0 * sy;
|
|
102
|
+
const w = Math.max(1, (run.x1 - run.x0) * sx);
|
|
103
|
+
const h = Math.max(1, (run.y1 - run.y0) * sy);
|
|
104
|
+
return (_jsx("rect", { x: x, y: y, width: w, height: h, fill: "transparent", stroke: "transparent", style: { pointerEvents: "all", cursor: "help" }, onMouseEnter: () => setHoveredRun({
|
|
105
|
+
run,
|
|
106
|
+
x: x + w / 2,
|
|
107
|
+
y,
|
|
108
|
+
}), onMouseLeave: () => setHoveredRun(null) }, idx));
|
|
109
|
+
}) })), hoveredRun && (_jsxs("div", { className: "pointer-events-none absolute z-20 -translate-x-1/2 -translate-y-full rounded-md px-2 py-1 text-xs font-medium text-white shadow-lg", style: {
|
|
110
|
+
left: hoveredRun.x,
|
|
111
|
+
top: Math.max(0, hoveredRun.y - 4),
|
|
112
|
+
backgroundColor: hoveredRun.run.exceeds
|
|
113
|
+
? "rgba(220, 38, 38, 0.95)"
|
|
114
|
+
: "rgba(37, 99, 235, 0.92)",
|
|
115
|
+
}, children: ["Mean TAC ", Math.round(hoveredRun.run.mean_tac), "%", hoveredRun.run.exceeds
|
|
116
|
+
? ` — exceeds ${Math.round(hoveredRun.run.limit)}% limit`
|
|
117
|
+
: ` (limit ${Math.round(hoveredRun.run.limit)}%)`] })), _jsxs("div", { className: "absolute bottom-20 right-2 rounded bg-black/80 p-2 text-xs text-white shadow-lg sm:bottom-2", children: [_jsx("p", { className: "mb-1 font-semibold", children: "TAC Coverage" }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "inline-block h-2 w-4 rounded", style: { backgroundColor: "rgb(0, 180, 0)" } }), _jsx("span", { children: "< 250%" })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "inline-block h-2 w-4 rounded", style: { backgroundColor: "rgb(255, 200, 0)" } }), _jsxs("span", { children: ["250\u2013", tacLimit, "%"] })] }), _jsxs("div", { className: "flex items-center gap-1", children: [_jsx("span", { className: "inline-block h-2 w-4 rounded", style: { backgroundColor: "rgb(255, 0, 0)" } }), _jsxs("span", { children: ["\u2265 ", tacLimit, "%"] })] })] })] }));
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=TACHeatmapOverlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TACHeatmapOverlay.js","sourceRoot":"","sources":["../../components/TACHeatmapOverlay.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface ZoomControlsProps {
|
|
2
|
+
zoom: number;
|
|
3
|
+
onZoomChange: (zoom: number) => void;
|
|
4
|
+
/** Compact mode: smaller buttons, no border. */
|
|
5
|
+
compact?: boolean;
|
|
6
|
+
/** Dark theme: light text on dark background. */
|
|
7
|
+
dark?: boolean;
|
|
8
|
+
}
|
|
9
|
+
export declare function ZoomControls({ zoom, onZoomChange, compact, dark }: ZoomControlsProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=ZoomControls.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZoomControls.d.ts","sourceRoot":"","sources":["../../components/ZoomControls.tsx"],"names":[],"mappings":"AAEA,UAAU,iBAAiB;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,gDAAgD;IAChD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,iDAAiD;IACjD,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAID,wBAAgB,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,iBAAiB,2CAqEpF"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
const ZOOM_STEPS = [25, 50, 75, 100, 125, 150, 200, 300, 400];
|
|
4
|
+
export function ZoomControls({ zoom, onZoomChange, compact, dark }) {
|
|
5
|
+
const zoomIn = () => {
|
|
6
|
+
const next = ZOOM_STEPS.find((z) => z > zoom);
|
|
7
|
+
if (next)
|
|
8
|
+
onZoomChange(next);
|
|
9
|
+
};
|
|
10
|
+
const zoomOut = () => {
|
|
11
|
+
const prev = [...ZOOM_STEPS].reverse().find((z) => z < zoom);
|
|
12
|
+
if (prev)
|
|
13
|
+
onZoomChange(prev);
|
|
14
|
+
};
|
|
15
|
+
if (compact) {
|
|
16
|
+
const btnClass = dark
|
|
17
|
+
? "rounded p-1 text-xs text-slate-300 hover:bg-white/10 hover:text-white disabled:opacity-40"
|
|
18
|
+
: "rounded p-1 text-xs hover:bg-muted disabled:opacity-40";
|
|
19
|
+
const selectClass = dark
|
|
20
|
+
? "rounded border border-white/10 bg-white/[0.04] px-1 py-0.5 text-xs text-white outline-none"
|
|
21
|
+
: "rounded border px-1 py-0.5 text-xs";
|
|
22
|
+
return (_jsxs("div", { className: "flex items-center gap-0.5", children: [_jsx("button", { onClick: zoomOut, disabled: zoom <= ZOOM_STEPS[0], className: btnClass, title: "Zoom out", children: "\u2212" }), _jsx("select", { value: zoom, onChange: (e) => onZoomChange(Number(e.target.value)), className: selectClass, children: ZOOM_STEPS.map((z) => (_jsxs("option", { value: z, children: [z, "%"] }, z))) }), _jsx("button", { onClick: zoomIn, disabled: zoom >= ZOOM_STEPS[ZOOM_STEPS.length - 1], className: btnClass, title: "Zoom in", children: "+" })] }));
|
|
23
|
+
}
|
|
24
|
+
return (_jsxs("div", { className: "flex items-center gap-1", children: [_jsx("button", { onClick: zoomOut, disabled: zoom <= ZOOM_STEPS[0], className: "rounded border px-2 py-1 text-sm hover:bg-muted disabled:opacity-40", title: "Zoom out", children: "\u2212" }), _jsx("select", { value: zoom, onChange: (e) => onZoomChange(Number(e.target.value)), className: "rounded border px-1 py-1 text-sm", children: ZOOM_STEPS.map((z) => (_jsxs("option", { value: z, children: [z, "%"] }, z))) }), _jsx("button", { onClick: zoomIn, disabled: zoom >= ZOOM_STEPS[ZOOM_STEPS.length - 1], className: "rounded border px-2 py-1 text-sm hover:bg-muted disabled:opacity-40", title: "Zoom in", children: "+" })] }));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=ZoomControls.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ZoomControls.js","sourceRoot":"","sources":["../../components/ZoomControls.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAC;;AAWb,MAAM,UAAU,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAE9D,MAAM,UAAU,YAAY,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,IAAI,EAAqB;IACnF,MAAM,MAAM,GAAG,GAAG,EAAE;QAClB,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC9C,IAAI,IAAI;YAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,MAAM,IAAI,GAAG,CAAC,GAAG,UAAU,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;QAC7D,IAAI,IAAI;YAAE,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC,CAAC;IAEF,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,QAAQ,GAAG,IAAI;YACnB,CAAC,CAAC,2FAA2F;YAC7F,CAAC,CAAC,wDAAwD,CAAC;QAC7D,MAAM,WAAW,GAAG,IAAI;YACtB,CAAC,CAAC,4FAA4F;YAC9F,CAAC,CAAC,oCAAoC,CAAC;QAEzC,OAAO,CACL,eAAK,SAAS,EAAC,2BAA2B,aACxC,iBAAQ,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,CAAC,CAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAC,UAAU,uBAExF,EACT,iBAAQ,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,SAAS,EAAE,WAAW,YAC/F,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACrB,kBAAgB,KAAK,EAAE,CAAC,aACrB,CAAC,UADS,CAAC,CAEL,CACV,CAAC,GACK,EACT,iBAAQ,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,EAAC,SAAS,kBAE1G,IACL,CACP,CAAC;IACJ,CAAC;IAED,OAAO,CACL,eAAK,SAAS,EAAC,yBAAyB,aACtC,iBACE,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,CAAC,CAAE,EAChC,SAAS,EAAC,qEAAqE,EAC/E,KAAK,EAAC,UAAU,uBAGT,EACT,iBACE,KAAK,EAAE,IAAI,EACX,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EACrD,SAAS,EAAC,kCAAkC,YAE3C,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CACrB,kBAAgB,KAAK,EAAE,CAAC,aACrB,CAAC,UADS,CAAC,CAEL,CACV,CAAC,GACK,EACT,iBACE,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAE,EACpD,SAAS,EAAC,qEAAqE,EAC/E,KAAK,EAAC,SAAS,kBAGR,IACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"defaultShellPlugins.d.ts","sourceRoot":"","sources":["../../components/defaultShellPlugins.tsx"],"names":[],"mappings":"AAcA,OAAO,KAAK,EAAE,kBAAkB,EAA6B,MAAM,gBAAgB,CAAC;AA6jBpF,wBAAgB,yBAAyB,IAAI,kBAAkB,EAAE,CAShE"}
|