@bitovi/vybit 0.11.2 → 0.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -4
- package/overlay/dist/overlay.js +78 -52
- package/package.json +1 -1
- package/panel/dist/assets/{DesignMode-Ch-krWhx.js → DesignMode-Dz9Ji12J.js} +1 -1
- package/panel/dist/assets/{index-CGc6ZuTL.js → index-B1KqavJw.js} +13 -13
- package/panel/dist/index.html +1 -1
- package/server/app.ts +0 -5
- package/server/ghost-cache.ts +1 -1
- package/server/mcp-tools.ts +0 -8
- package/server/queue.ts +0 -1
- package/server/storybook.ts +1 -5
- package/server/tailwind-v3.ts +18 -2
- package/server/tailwind-v4.ts +95 -14
- package/server/tailwind.ts +0 -1
- package/storybook-addon/preview-v10.ts +0 -2
- package/storybook-addon/preview.ts +0 -2
package/README.md
CHANGED
|
@@ -1,8 +1,21 @@
|
|
|
1
1
|
# VyBit
|
|
2
2
|
|
|
3
|
-
Change designs, draw mockups, and provide suggestions
|
|
3
|
+
Change designs, draw mockups, and provide suggestions __in your browser__ and send them to your favorite coding agent (Claude, Cursor, Copilot, etc) to be implemented. VyBit works with React apps built with Tailwind v3 or v4.
|
|
4
|
+
|
|
5
|
+
<img width="1453" height="903" alt="Cursor_and_Carton_Case_Management" src="https://github.com/user-attachments/assets/59b8e280-a827-4fa0-95e3-6c350afacbc9" />
|
|
6
|
+
|
|
7
|
+
`VyBit` changes how you can design and build an app or website. Instead of building your design system and page designs in Sketch or Figma and then implementing it in code, you:
|
|
8
|
+
|
|
9
|
+
| Step No | Task | How |
|
|
10
|
+
|----------|----------|----------|
|
|
11
|
+
| 1 | Vibe code your design system | `Claude, build a button, card and badge. Add storybook.` |
|
|
12
|
+
| 2 | __Use VyBit to fine-tune your design system in Storybook__ - Adjust colors, spacing, shadows, layout and more | <img alt="image" src="https://github.com/user-attachments/assets/79ca04be-db8f-458f-8632-87cc040875db" /> |
|
|
13
|
+
| 3a | __Use VyBit to design features__ - drop customized design system components into your pages | <img width="1481" height="922" alt="image" src="https://github.com/user-attachments/assets/415acdb7-102a-4c31-910b-10536c59ee4a" /> |
|
|
14
|
+
| 3b | __Use VyBit to design features__ - sketch a feature with the design canvas | <img width="1482" height="924" alt="image" src="https://github.com/user-attachments/assets/924e9733-baf6-4492-b9da-05fd27c2df93" /> |
|
|
15
|
+
| 4 | Add text or voice messages for extra context | <img width="376" height="261" alt="image" src="https://github.com/user-attachments/assets/546ea987-a0ad-4809-85c6-52fb91fb987e" /> |
|
|
16
|
+
|
|
17
|
+
Plus, VyBit always knows what page, components, and elements you're editing, making it easier for agents to know exactly what you want!
|
|
4
18
|
|
|
5
|
-
<img width="1546" height="860" alt="image" src="https://github.com/user-attachments/assets/de3450be-abcf-4612-93a5-ae2dd324d583" />
|
|
6
19
|
|
|
7
20
|
## Installation
|
|
8
21
|
|
|
@@ -142,9 +155,9 @@ Click it. It will open the Editor Panel.
|
|
|
142
155
|
|
|
143
156
|
### Using the Editor to make changes
|
|
144
157
|
|
|
145
|
-
More on this later. But in short, click an element, then you can adjust the
|
|
158
|
+
More on this later. But in short, click an element, then you can adjust the design of it, or insert a panel to draw out changes. You can also add contextual messages. These are all draft changes until you commit.
|
|
146
159
|
|
|
147
|
-
###
|
|
160
|
+
### Committing changes
|
|
148
161
|
|
|
149
162
|
Once you have the changes you want to make, you can click the drafts button. This will show you a list of changes. Click `Commit All` to send them to the agent to be implemented:
|
|
150
163
|
|
package/overlay/dist/overlay.js
CHANGED
|
@@ -5,18 +5,15 @@
|
|
|
5
5
|
var connected = false;
|
|
6
6
|
var handlers = [];
|
|
7
7
|
function connect(url = "ws://localhost:3333") {
|
|
8
|
-
console.log("[vybit-overlay] WS connecting to", url);
|
|
9
8
|
socket = new WebSocket(url);
|
|
10
9
|
socket.addEventListener("open", () => {
|
|
11
10
|
connected = true;
|
|
12
|
-
console.log("[vybit-overlay] WS connected, registering as overlay");
|
|
13
11
|
send({ type: "REGISTER", role: "overlay" });
|
|
14
12
|
window.dispatchEvent(new CustomEvent("overlay-ws-connected"));
|
|
15
13
|
});
|
|
16
14
|
socket.addEventListener("close", () => {
|
|
17
15
|
connected = false;
|
|
18
16
|
socket = null;
|
|
19
|
-
console.log("[vybit-overlay] WS disconnected, will reconnect in 3s");
|
|
20
17
|
window.dispatchEvent(new CustomEvent("overlay-ws-disconnected"));
|
|
21
18
|
setTimeout(() => connect(url), 3e3);
|
|
22
19
|
});
|
|
@@ -157,22 +154,43 @@ ${pad}</${tag}>`;
|
|
|
157
154
|
const key = Object.keys(domNode).find((k) => k.startsWith("__reactFiber$"));
|
|
158
155
|
return key ? domNode[key] : null;
|
|
159
156
|
}
|
|
157
|
+
var REACT_FORWARD_REF = /* @__PURE__ */ Symbol.for("react.forward_ref");
|
|
158
|
+
var REACT_MEMO = /* @__PURE__ */ Symbol.for("react.memo");
|
|
160
159
|
function findComponentBoundary(fiber) {
|
|
161
160
|
let current = fiber.return;
|
|
162
161
|
while (current) {
|
|
163
|
-
|
|
162
|
+
const t = current.type;
|
|
163
|
+
if (typeof t === "function") {
|
|
164
164
|
return {
|
|
165
|
-
componentType:
|
|
166
|
-
componentName:
|
|
165
|
+
componentType: t,
|
|
166
|
+
componentName: t.displayName || t.name || "Unknown",
|
|
167
167
|
componentFiber: current
|
|
168
168
|
};
|
|
169
169
|
}
|
|
170
|
+
if (t && t.$$typeof === REACT_FORWARD_REF) {
|
|
171
|
+
const name = t.displayName || t.render?.displayName || t.render?.name || "Unknown";
|
|
172
|
+
return { componentType: t, componentName: name, componentFiber: current };
|
|
173
|
+
}
|
|
174
|
+
if (t && t.$$typeof === REACT_MEMO) {
|
|
175
|
+
const inner = t.type;
|
|
176
|
+
const name = t.displayName || (typeof inner === "function" ? inner.displayName || inner.name : null) || (inner?.$$typeof === REACT_FORWARD_REF ? inner.displayName || inner.render?.name : null) || "Unknown";
|
|
177
|
+
return { componentType: t, componentName: name, componentFiber: current };
|
|
178
|
+
}
|
|
179
|
+
current = current.return;
|
|
180
|
+
}
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
function getRootFiberFrom(fiber) {
|
|
184
|
+
let current = fiber;
|
|
185
|
+
while (current) {
|
|
186
|
+
if (current.tag === 3) return current;
|
|
187
|
+
if (!current.return) return current;
|
|
170
188
|
current = current.return;
|
|
171
189
|
}
|
|
172
190
|
return null;
|
|
173
191
|
}
|
|
174
192
|
function getRootFiber() {
|
|
175
|
-
const candidateIds = ["root", "app", "__next"];
|
|
193
|
+
const candidateIds = ["root", "app", "__next", "storybook-root", "sb-root"];
|
|
176
194
|
for (const id of candidateIds) {
|
|
177
195
|
const el = document.getElementById(id);
|
|
178
196
|
if (!el) continue;
|
|
@@ -2002,9 +2020,10 @@ ${pad}</${tag}>`;
|
|
|
2002
2020
|
const fiber = getFiber(clickedEl);
|
|
2003
2021
|
const boundary = fiber ? findComponentBoundary(fiber) : null;
|
|
2004
2022
|
const componentName2 = boundary?.componentName ?? null;
|
|
2023
|
+
console.log("[grouping] findExactMatches \u2014 fiber:", !!fiber, "boundary:", boundary?.componentName ?? "(none)", "tag:", tag);
|
|
2005
2024
|
let exactMatches;
|
|
2006
2025
|
if (boundary) {
|
|
2007
|
-
const rootFiber = getRootFiber();
|
|
2026
|
+
const rootFiber = getRootFiberFrom(boundary.componentFiber) ?? getRootFiber();
|
|
2008
2027
|
const allNodes = rootFiber ? collectComponentDOMNodes(rootFiber, boundary.componentType, tag) : [];
|
|
2009
2028
|
exactMatches = allNodes.filter(
|
|
2010
2029
|
(n) => n.tagName === tag && n.className === clickedEl.className
|
|
@@ -2045,9 +2064,10 @@ ${pad}</${tag}>`;
|
|
|
2045
2064
|
const boundary = fiber ? findComponentBoundary(fiber) : null;
|
|
2046
2065
|
let candidates;
|
|
2047
2066
|
if (boundary) {
|
|
2048
|
-
const rootFiber = getRootFiber();
|
|
2067
|
+
const rootFiber = getRootFiberFrom(boundary.componentFiber) ?? getRootFiber();
|
|
2049
2068
|
candidates = rootFiber ? collectComponentDOMNodes(rootFiber, boundary.componentType, tag) : [];
|
|
2050
2069
|
candidates = candidates.filter((n) => !exactMatchSet.has(n));
|
|
2070
|
+
console.log("[grouping] React path \u2014 component:", boundary.componentName, "tag:", tag, "candidates:", candidates.length, candidates.map((n) => n.className.split(" ")[0]));
|
|
2051
2071
|
} else {
|
|
2052
2072
|
const seen = new Set(exactMatchSet);
|
|
2053
2073
|
candidates = [];
|
|
@@ -2062,12 +2082,14 @@ ${pad}</${tag}>`;
|
|
|
2062
2082
|
}
|
|
2063
2083
|
if (candidates.length >= MAX_CANDIDATES) break;
|
|
2064
2084
|
}
|
|
2085
|
+
console.log("[grouping] Non-React path \u2014 tag:", tag, "candidates:", candidates.length);
|
|
2065
2086
|
}
|
|
2066
2087
|
const groupMap = /* @__PURE__ */ new Map();
|
|
2067
2088
|
for (const el of candidates) {
|
|
2068
2089
|
const candidateClasses = new Set(parseClassList(typeof el.className === "string" ? el.className : ""));
|
|
2069
2090
|
const { added, removed } = classDiff(refSet, candidateClasses);
|
|
2070
2091
|
const totalDiff = added.length + removed.length;
|
|
2092
|
+
console.log("[grouping] candidate diff:", totalDiff, "added:", added.length, "removed:", removed.length, "class0:", el.className.split(" ")[0]);
|
|
2071
2093
|
if (totalDiff === 0 || totalDiff > MAX_DIFF) continue;
|
|
2072
2094
|
const key = `+${added.join(",")}|-${removed.join(",")}`;
|
|
2073
2095
|
const existing = groupMap.get(key);
|
|
@@ -2132,7 +2154,6 @@ ${pad}</${tag}>`;
|
|
|
2132
2154
|
}
|
|
2133
2155
|
if (newClass) {
|
|
2134
2156
|
try {
|
|
2135
|
-
console.log("[vybit-patcher] Fetching CSS for class:", newClass, "from", `${serverOrigin}/css`);
|
|
2136
2157
|
const res = await fetch(`${serverOrigin}/css`, {
|
|
2137
2158
|
method: "POST",
|
|
2138
2159
|
headers: { "Content-Type": "application/json" },
|
|
@@ -2144,22 +2165,13 @@ ${pad}</${tag}>`;
|
|
|
2144
2165
|
console.error("[vybit-patcher] CSS fetch FAILED:", res.status, errBody);
|
|
2145
2166
|
} else {
|
|
2146
2167
|
const { css } = await res.json();
|
|
2147
|
-
console.log("[vybit-patcher] CSS received for", newClass, ":", css ? `${css.length} chars` : "(empty)");
|
|
2148
|
-
console.log("[vybit-patcher] CSS content:", css || "(none)");
|
|
2149
2168
|
if (gen !== previewGeneration) return;
|
|
2150
2169
|
if (!previewStyleEl) {
|
|
2151
2170
|
previewStyleEl = document.createElement("style");
|
|
2152
2171
|
previewStyleEl.setAttribute("data-tw-preview", "");
|
|
2153
2172
|
document.head.appendChild(previewStyleEl);
|
|
2154
|
-
console.log("[vybit-patcher] Created <style data-tw-preview> in document.head");
|
|
2155
2173
|
}
|
|
2156
2174
|
previewStyleEl.textContent = css;
|
|
2157
|
-
console.log(
|
|
2158
|
-
"[vybit-patcher] Style element in DOM:",
|
|
2159
|
-
document.head.contains(previewStyleEl),
|
|
2160
|
-
"textContent length:",
|
|
2161
|
-
previewStyleEl.textContent?.length
|
|
2162
|
-
);
|
|
2163
2175
|
}
|
|
2164
2176
|
} catch (err) {
|
|
2165
2177
|
console.error("[vybit-patcher] CSS fetch error:", err);
|
|
@@ -2175,13 +2187,6 @@ ${pad}</${tag}>`;
|
|
|
2175
2187
|
if (oldClass) node.classList.remove(oldClass);
|
|
2176
2188
|
if (newClass) node.classList.add(newClass);
|
|
2177
2189
|
}
|
|
2178
|
-
console.log("[vybit-patcher] Applied class swap:", oldClass, "\u2192", newClass, "on", elements.length, "elements");
|
|
2179
|
-
if (elements[0]) {
|
|
2180
|
-
console.log("[vybit-patcher] Element className after swap:", elements[0].className);
|
|
2181
|
-
const computed = window.getComputedStyle(elements[0]);
|
|
2182
|
-
if (newClass.startsWith("bg-")) console.log("[vybit-patcher] Computed background:", computed.backgroundColor);
|
|
2183
|
-
if (newClass.startsWith("p-") || newClass.startsWith("px-") || newClass.startsWith("py-")) console.log("[vybit-patcher] Computed padding:", computed.padding);
|
|
2184
|
-
}
|
|
2185
2190
|
}
|
|
2186
2191
|
async function applyPreviewBatch(elements, pairs, serverOrigin) {
|
|
2187
2192
|
const gen = ++previewGeneration;
|
|
@@ -2194,7 +2199,6 @@ ${pad}</${tag}>`;
|
|
|
2194
2199
|
const newClasses = pairs.map((p) => p.newClass).filter(Boolean);
|
|
2195
2200
|
if (newClasses.length > 0) {
|
|
2196
2201
|
try {
|
|
2197
|
-
console.log("[vybit-patcher] Fetching CSS for batch:", newClasses, "from", `${serverOrigin}/css`);
|
|
2198
2202
|
const res = await fetch(`${serverOrigin}/css`, {
|
|
2199
2203
|
method: "POST",
|
|
2200
2204
|
headers: { "Content-Type": "application/json" },
|
|
@@ -2206,22 +2210,13 @@ ${pad}</${tag}>`;
|
|
|
2206
2210
|
console.error("[vybit-patcher] CSS batch fetch FAILED:", res.status, errBody);
|
|
2207
2211
|
} else {
|
|
2208
2212
|
const { css } = await res.json();
|
|
2209
|
-
console.log("[vybit-patcher] CSS batch received:", css ? `${css.length} chars` : "(empty)");
|
|
2210
|
-
console.log("[vybit-patcher] CSS batch content:", css || "(none)");
|
|
2211
2213
|
if (gen !== previewGeneration) return;
|
|
2212
2214
|
if (!previewStyleEl) {
|
|
2213
2215
|
previewStyleEl = document.createElement("style");
|
|
2214
2216
|
previewStyleEl.setAttribute("data-tw-preview", "");
|
|
2215
2217
|
document.head.appendChild(previewStyleEl);
|
|
2216
|
-
console.log("[vybit-patcher] Created <style data-tw-preview> in document.head");
|
|
2217
2218
|
}
|
|
2218
2219
|
previewStyleEl.textContent = css;
|
|
2219
|
-
console.log(
|
|
2220
|
-
"[vybit-patcher] Style element in DOM:",
|
|
2221
|
-
document.head.contains(previewStyleEl),
|
|
2222
|
-
"textContent length:",
|
|
2223
|
-
previewStyleEl.textContent?.length
|
|
2224
|
-
);
|
|
2225
2220
|
}
|
|
2226
2221
|
} catch (err) {
|
|
2227
2222
|
console.error("[vybit-patcher] CSS batch fetch error:", err);
|
|
@@ -3923,11 +3918,11 @@ ${pad}</${tag}>`;
|
|
|
3923
3918
|
return "http://localhost:3333";
|
|
3924
3919
|
}
|
|
3925
3920
|
var SERVER_ORIGIN = getServerOrigin();
|
|
3926
|
-
console.log("[vybit-overlay] SERVER_ORIGIN =", SERVER_ORIGIN);
|
|
3927
3921
|
var insideStorybook = !!window.__STORYBOOK_PREVIEW__;
|
|
3928
|
-
console.log("[vybit-overlay] insideStorybook =", insideStorybook);
|
|
3929
3922
|
async function fetchTailwindConfig() {
|
|
3930
|
-
if (tailwindConfigCache)
|
|
3923
|
+
if (tailwindConfigCache) {
|
|
3924
|
+
return tailwindConfigCache;
|
|
3925
|
+
}
|
|
3931
3926
|
try {
|
|
3932
3927
|
const res = await fetch(`${SERVER_ORIGIN}/tailwind-config`);
|
|
3933
3928
|
tailwindConfigCache = await res.json();
|
|
@@ -3937,11 +3932,51 @@ ${pad}</${tag}>`;
|
|
|
3937
3932
|
return {};
|
|
3938
3933
|
}
|
|
3939
3934
|
}
|
|
3935
|
+
function resolveConfigCssVars(config) {
|
|
3936
|
+
if (!config || !config.colors) return config;
|
|
3937
|
+
const resolved = { ...config, colors: resolveColorObject(config.colors) };
|
|
3938
|
+
return resolved;
|
|
3939
|
+
}
|
|
3940
|
+
function resolveColorObject(obj) {
|
|
3941
|
+
if (typeof obj === "string") {
|
|
3942
|
+
return resolveCssVar(obj);
|
|
3943
|
+
}
|
|
3944
|
+
if (obj && typeof obj === "object") {
|
|
3945
|
+
const result = {};
|
|
3946
|
+
for (const key of Object.keys(obj)) {
|
|
3947
|
+
result[key] = resolveColorObject(obj[key]);
|
|
3948
|
+
}
|
|
3949
|
+
return result;
|
|
3950
|
+
}
|
|
3951
|
+
return obj;
|
|
3952
|
+
}
|
|
3953
|
+
function resolveCssVar(value) {
|
|
3954
|
+
if (!value.startsWith("var(")) return value;
|
|
3955
|
+
const match = value.match(/^var\(\s*(--[^,)]+)/);
|
|
3956
|
+
if (!match) return value;
|
|
3957
|
+
const computed = getComputedStyle(document.documentElement).getPropertyValue(match[1]).trim();
|
|
3958
|
+
if (!computed) return value;
|
|
3959
|
+
const directColor = normalizeToHex(computed);
|
|
3960
|
+
if (directColor) return directColor;
|
|
3961
|
+
const hslColor = normalizeToHex(`hsl(${computed})`);
|
|
3962
|
+
if (hslColor) return hslColor;
|
|
3963
|
+
return computed;
|
|
3964
|
+
}
|
|
3965
|
+
function normalizeToHex(cssColor) {
|
|
3966
|
+
const el = document.createElement("div");
|
|
3967
|
+
el.style.color = cssColor;
|
|
3968
|
+
if (!el.style.color) return null;
|
|
3969
|
+
document.body.appendChild(el);
|
|
3970
|
+
const rgb = getComputedStyle(el).color;
|
|
3971
|
+
document.body.removeChild(el);
|
|
3972
|
+
const m = rgb.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
|
|
3973
|
+
if (!m) return null;
|
|
3974
|
+
const hex = "#" + [m[1], m[2], m[3]].map((n) => Number(n).toString(16).padStart(2, "0")).join("");
|
|
3975
|
+
return hex;
|
|
3976
|
+
}
|
|
3940
3977
|
async function clickHandler(e) {
|
|
3941
|
-
console.log("[vybit-overlay] clickHandler fired on", e.target?.tagName, e.target?.className);
|
|
3942
3978
|
const composed = e.composedPath();
|
|
3943
3979
|
if (composed.some((el) => el === shadowHost)) {
|
|
3944
|
-
console.log("[vybit-overlay] click ignored \u2014 shadow host");
|
|
3945
3980
|
return;
|
|
3946
3981
|
}
|
|
3947
3982
|
if (composed.some(
|
|
@@ -3978,16 +4013,16 @@ ${pad}</${tag}>`;
|
|
|
3978
4013
|
activeContainer.open(panelUrl);
|
|
3979
4014
|
}
|
|
3980
4015
|
}
|
|
4016
|
+
const resolvedConfig = config ? resolveConfigCssVars(config) : config;
|
|
3981
4017
|
sendTo("panel", {
|
|
3982
4018
|
type: "ELEMENT_SELECTED",
|
|
3983
4019
|
componentName: componentName2,
|
|
3984
4020
|
instanceCount: result.exactMatch.length,
|
|
3985
4021
|
classes: classString,
|
|
3986
|
-
tailwindConfig:
|
|
4022
|
+
tailwindConfig: resolvedConfig
|
|
3987
4023
|
});
|
|
3988
4024
|
}
|
|
3989
4025
|
function setSelectMode(on) {
|
|
3990
|
-
console.log("[vybit-overlay] setSelectMode", on);
|
|
3991
4026
|
if (on) {
|
|
3992
4027
|
document.documentElement.style.cursor = "crosshair";
|
|
3993
4028
|
document.addEventListener("click", clickHandler, { capture: true });
|
|
@@ -4002,7 +4037,6 @@ ${pad}</${tag}>`;
|
|
|
4002
4037
|
}
|
|
4003
4038
|
var PANEL_OPEN_KEY = "tw-inspector-panel-open";
|
|
4004
4039
|
function toggleInspect(btn) {
|
|
4005
|
-
console.log("[vybit-overlay] toggleInspect, active will be", !active2);
|
|
4006
4040
|
active2 = !active2;
|
|
4007
4041
|
if (active2) {
|
|
4008
4042
|
btn.classList.add("active");
|
|
@@ -4321,7 +4355,6 @@ ${pad}</${tag}>`;
|
|
|
4321
4355
|
return "popover";
|
|
4322
4356
|
}
|
|
4323
4357
|
function init() {
|
|
4324
|
-
console.log("[vybit-overlay] init() called");
|
|
4325
4358
|
shadowHost = document.createElement("div");
|
|
4326
4359
|
shadowHost.id = "tw-visual-editor-host";
|
|
4327
4360
|
shadowHost.style.cssText = "position:fixed;z-index:2147483647;top:0;left:0;width:0;height:0;pointer-events:none;";
|
|
@@ -4365,7 +4398,6 @@ ${pad}</${tag}>`;
|
|
|
4365
4398
|
const wsUrl = SERVER_ORIGIN.replace(/^http/, "ws");
|
|
4366
4399
|
connect(wsUrl);
|
|
4367
4400
|
onMessage((msg) => {
|
|
4368
|
-
console.log("[vybit-overlay] WS message received:", msg.type);
|
|
4369
4401
|
if (msg.type === "TOGGLE_SELECT_MODE") {
|
|
4370
4402
|
if (msg.active) {
|
|
4371
4403
|
setSelectMode(true);
|
|
@@ -4377,20 +4409,14 @@ ${pad}</${tag}>`;
|
|
|
4377
4409
|
setSelectMode(false);
|
|
4378
4410
|
}
|
|
4379
4411
|
} else if (msg.type === "PATCH_PREVIEW" && currentEquivalentNodes.length > 0) {
|
|
4380
|
-
console.log("[vybit-overlay] PATCH_PREVIEW:", msg.oldClass, "\u2192", msg.newClass, "nodes:", currentEquivalentNodes.length);
|
|
4381
4412
|
applyPreview(
|
|
4382
4413
|
currentEquivalentNodes,
|
|
4383
4414
|
msg.oldClass,
|
|
4384
4415
|
msg.newClass,
|
|
4385
4416
|
SERVER_ORIGIN
|
|
4386
4417
|
);
|
|
4387
|
-
} else if (msg.type === "PATCH_PREVIEW" && currentEquivalentNodes.length === 0) {
|
|
4388
|
-
console.warn("[vybit-overlay] PATCH_PREVIEW DROPPED \u2014 no selected elements! oldClass:", msg.oldClass, "newClass:", msg.newClass);
|
|
4389
4418
|
} else if (msg.type === "PATCH_PREVIEW_BATCH" && currentEquivalentNodes.length > 0) {
|
|
4390
|
-
console.log("[vybit-overlay] PATCH_PREVIEW_BATCH:", msg.pairs, "nodes:", currentEquivalentNodes.length);
|
|
4391
4419
|
applyPreviewBatch(currentEquivalentNodes, msg.pairs, SERVER_ORIGIN);
|
|
4392
|
-
} else if (msg.type === "PATCH_PREVIEW_BATCH" && currentEquivalentNodes.length === 0) {
|
|
4393
|
-
console.warn("[vybit-overlay] PATCH_PREVIEW_BATCH DROPPED \u2014 no selected elements!", msg.pairs);
|
|
4394
4420
|
} else if (msg.type === "PATCH_REVERT") {
|
|
4395
4421
|
revertPreview();
|
|
4396
4422
|
} else if (msg.type === "PATCH_REVERT_STAGED" && currentEquivalentNodes.length > 0) {
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as F,j as A,c as co,s as Be,o as lo,a as uo}from"./index-
|
|
1
|
+
import{r as F,j as A,c as co,s as Be,o as lo,a as uo}from"./index-B1KqavJw.js";function p(o,t,e){return(t=function(s){var r=function(i,n){if(typeof i!="object"||!i)return i;var a=i[Symbol.toPrimitive];if(a!==void 0){var h=a.call(i,n);if(typeof h!="object")return h;throw new TypeError("@@toPrimitive must return a primitive value.")}return(n==="string"?String:Number)(i)}(s,"string");return typeof r=="symbol"?r:r+""}(t))in o?Object.defineProperty(o,t,{value:e,enumerable:!0,configurable:!0,writable:!0}):o[t]=e,o}function Zr(o,t){var e=Object.keys(o);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(o);t&&(s=s.filter(function(r){return Object.getOwnPropertyDescriptor(o,r).enumerable})),e.push.apply(e,s)}return e}function m(o){for(var t=1;t<arguments.length;t++){var e=arguments[t]!=null?arguments[t]:{};t%2?Zr(Object(e),!0).forEach(function(s){p(o,s,e[s])}):Object.getOwnPropertyDescriptors?Object.defineProperties(o,Object.getOwnPropertyDescriptors(e)):Zr(Object(e)).forEach(function(s){Object.defineProperty(o,s,Object.getOwnPropertyDescriptor(e,s))})}return o}function K(o,t){if(o==null)return{};var e,s,r=function(n,a){if(n==null)return{};var h={};for(var c in n)if({}.hasOwnProperty.call(n,c)){if(a.indexOf(c)>=0)continue;h[c]=n[c]}return h}(o,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(o);for(s=0;s<i.length;s++)e=i[s],t.indexOf(e)>=0||{}.propertyIsEnumerable.call(o,e)&&(r[e]=o[e])}return r}function Yt(o,t){return t||(t=o.slice(0)),Object.freeze(Object.defineProperties(o,{raw:{value:Object.freeze(t)}}))}class Qr{constructor(){p(this,"browserShadowBlurConstant",1),p(this,"DPI",96),p(this,"devicePixelRatio",typeof window<"u"?window.devicePixelRatio:1),p(this,"perfLimitSizeTotal",2097152),p(this,"maxCacheSideLimit",4096),p(this,"minCacheSideLimit",256),p(this,"disableStyleCopyPaste",!1),p(this,"enableGLFiltering",!0),p(this,"textureSize",4096),p(this,"forceGLPutImageData",!1),p(this,"cachesBoundsOfCurve",!1),p(this,"fontPaths",{}),p(this,"NUM_FRACTION_DIGITS",4)}}const V=new class extends Qr{constructor(o){super(),this.configure(o)}configure(){let o=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};Object.assign(this,o)}addFonts(){let o=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};this.fontPaths=m(m({},this.fontPaths),o)}removeFonts(){(arguments.length>0&&arguments[0]!==void 0?arguments[0]:[]).forEach(o=>{delete this.fontPaths[o]})}clearFonts(){this.fontPaths={}}restoreDefaults(o){const t=new Qr,e=(o==null?void 0:o.reduce((s,r)=>(s[r]=t[r],s),{}))||t;this.configure(e)}},he=function(o){for(var t=arguments.length,e=new Array(t>1?t-1:0),s=1;s<t;s++)e[s-1]=arguments[s];return console[o]("fabric",...e)};class Wt extends Error{constructor(t,e){super("fabric: ".concat(t),e)}}class go extends Wt{constructor(t){super("".concat(t," 'options.signal' is in 'aborted' state"))}}class fo{}class po extends fo{testPrecision(t,e){const s="precision ".concat(e,` float;
|
|
2
2
|
void main(){}`),r=t.createShader(t.FRAGMENT_SHADER);return!!r&&(t.shaderSource(r,s),t.compileShader(r),!!t.getShaderParameter(r,t.COMPILE_STATUS))}queryWebGL(t){const e=t.getContext("webgl");e&&(this.maxTextureSize=e.getParameter(e.MAX_TEXTURE_SIZE),this.GLPrecision=["highp","mediump","lowp"].find(s=>this.testPrecision(e,s)),e.getExtension("WEBGL_lose_context").loseContext(),he("log","WebGL: max texture size ".concat(this.maxTextureSize)))}isSupported(t){return!!this.maxTextureSize&&this.maxTextureSize>=t}}const mo={};let ti;const Vt=()=>ti||(ti={document,window,isTouchSupported:"ontouchstart"in window||"ontouchstart"in document||window&&window.navigator&&window.navigator.maxTouchPoints>0,WebGLProbe:new po,dispose(){},copyPasteData:mo}),Ee=()=>Vt().document,Gs=()=>Vt().window,qi=()=>{var o;return Math.max((o=V.devicePixelRatio)!==null&&o!==void 0?o:Gs().devicePixelRatio,1)},Ve=new class{constructor(){p(this,"boundsOfCurveCache",{}),this.charWidthsCache=new Map}getFontCache(o){let{fontFamily:t,fontStyle:e,fontWeight:s}=o;t=t.toLowerCase();const r=this.charWidthsCache;r.has(t)||r.set(t,new Map);const i=r.get(t),n="".concat(e.toLowerCase(),"_").concat((s+"").toLowerCase());return i.has(n)||i.set(n,new Map),i.get(n)}clearFontCache(o){o?this.charWidthsCache.delete((o||"").toLowerCase()):this.charWidthsCache=new Map}limitDimsByArea(o){const{perfLimitSizeTotal:t}=V,e=Math.sqrt(t*o);return[Math.floor(e),Math.floor(t/e)]}},vr="6.9.1";function Ts(){}const Je=Math.PI/2,Es=2*Math.PI,Pr=Math.PI/180,gt=Object.freeze([1,0,0,1,0,0]),Ar=16,ie=.4477152502,R="center",z="left",pt="top",yr="bottom",Z="right",mt="none",jr=/\r?\n/,Ki="moving",Ns="scaling",$i="rotating",Fr="rotate",Ji="skewing",Ge="resizing",vo="modifyPoly",yo="modifyPath",Ps="changed",Us="scale",xt="scaleX",Ot="scaleY",Pe="skewX",Ae="skewY",nt="fill",vt="stroke",As="modified",ye="json",rr="svg",D=new class{constructor(){this[ye]=new Map,this[rr]=new Map}has(o){return this[ye].has(o)}getClass(o){const t=this[ye].get(o);if(!t)throw new Wt("No class registered for ".concat(o));return t}setClass(o,t){t?this[ye].set(t,o):(this[ye].set(o.type,o),this[ye].set(o.type.toLowerCase(),o))}getSVGClass(o){return this[rr].get(o)}setSVGClass(o,t){this[rr].set(t??o.type.toLowerCase(),o)}},js=new class extends Array{remove(o){const t=this.indexOf(o);t>-1&&this.splice(t,1)}cancelAll(){const o=this.splice(0);return o.forEach(t=>t.abort()),o}cancelByCanvas(o){if(!o)return[];const t=this.filter(e=>{var s;return e.target===o||typeof e.target=="object"&&((s=e.target)===null||s===void 0?void 0:s.canvas)===o});return t.forEach(e=>e.abort()),t}cancelByTarget(o){if(!o)return[];const t=this.filter(e=>e.target===o);return t.forEach(e=>e.abort()),t}};class xo{constructor(){p(this,"__eventListeners",{})}on(t,e){if(this.__eventListeners||(this.__eventListeners={}),typeof t=="object")return Object.entries(t).forEach(s=>{let[r,i]=s;this.on(r,i)}),()=>this.off(t);if(e){const s=t;return this.__eventListeners[s]||(this.__eventListeners[s]=[]),this.__eventListeners[s].push(e),()=>this.off(s,e)}return()=>!1}once(t,e){if(typeof t=="object"){const s=[];return Object.entries(t).forEach(r=>{let[i,n]=r;s.push(this.once(i,n))}),()=>s.forEach(r=>r())}if(e){const s=this.on(t,function(){for(var r=arguments.length,i=new Array(r),n=0;n<r;n++)i[n]=arguments[n];e.call(this,...i),s()});return s}return()=>!1}_removeEventListener(t,e){if(this.__eventListeners[t])if(e){const s=this.__eventListeners[t],r=s.indexOf(e);r>-1&&s.splice(r,1)}else this.__eventListeners[t]=[]}off(t,e){if(this.__eventListeners)if(t===void 0)for(const s in this.__eventListeners)this._removeEventListener(s);else typeof t=="object"?Object.entries(t).forEach(s=>{let[r,i]=s;this._removeEventListener(r,i)}):this._removeEventListener(t,e)}fire(t,e){var s;if(!this.__eventListeners)return;const r=(s=this.__eventListeners[t])===null||s===void 0?void 0:s.concat();if(r)for(let i=0;i<r.length;i++)r[i].call(this,e||{})}}const we=(o,t)=>{const e=o.indexOf(t);return e!==-1&&o.splice(e,1),o},$t=o=>{if(o===0)return 1;switch(Math.abs(o)/Je){case 1:case 3:return 0;case 2:return-1}return Math.cos(o)},Jt=o=>{if(o===0)return 0;const t=o/Je,e=Math.sign(o);switch(t){case 1:return e;case 2:return 0;case 3:return-e}return Math.sin(o)};class y{constructor(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:0,e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:0;typeof t=="object"?(this.x=t.x,this.y=t.y):(this.x=t,this.y=e)}add(t){return new y(this.x+t.x,this.y+t.y)}addEquals(t){return this.x+=t.x,this.y+=t.y,this}scalarAdd(t){return new y(this.x+t,this.y+t)}scalarAddEquals(t){return this.x+=t,this.y+=t,this}subtract(t){return new y(this.x-t.x,this.y-t.y)}subtractEquals(t){return this.x-=t.x,this.y-=t.y,this}scalarSubtract(t){return new y(this.x-t,this.y-t)}scalarSubtractEquals(t){return this.x-=t,this.y-=t,this}multiply(t){return new y(this.x*t.x,this.y*t.y)}scalarMultiply(t){return new y(this.x*t,this.y*t)}scalarMultiplyEquals(t){return this.x*=t,this.y*=t,this}divide(t){return new y(this.x/t.x,this.y/t.y)}scalarDivide(t){return new y(this.x/t,this.y/t)}scalarDivideEquals(t){return this.x/=t,this.y/=t,this}eq(t){return this.x===t.x&&this.y===t.y}lt(t){return this.x<t.x&&this.y<t.y}lte(t){return this.x<=t.x&&this.y<=t.y}gt(t){return this.x>t.x&&this.y>t.y}gte(t){return this.x>=t.x&&this.y>=t.y}lerp(t){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:.5;return e=Math.max(Math.min(1,e),0),new y(this.x+(t.x-this.x)*e,this.y+(t.y-this.y)*e)}distanceFrom(t){const e=this.x-t.x,s=this.y-t.y;return Math.sqrt(e*e+s*s)}midPointFrom(t){return this.lerp(t)}min(t){return new y(Math.min(this.x,t.x),Math.min(this.y,t.y))}max(t){return new y(Math.max(this.x,t.x),Math.max(this.y,t.y))}toString(){return"".concat(this.x,",").concat(this.y)}setXY(t,e){return this.x=t,this.y=e,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setFromPoint(t){return this.x=t.x,this.y=t.y,this}swap(t){const e=this.x,s=this.y;this.x=t.x,this.y=t.y,t.x=e,t.y=s}clone(){return new y(this.x,this.y)}rotate(t){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Lr;const s=Jt(t),r=$t(t),i=this.subtract(e);return new y(i.x*r-i.y*s,i.x*s+i.y*r).add(e)}transform(t){let e=arguments.length>1&&arguments[1]!==void 0&&arguments[1];return new y(t[0]*this.x+t[2]*this.y+(e?0:t[4]),t[1]*this.x+t[3]*this.y+(e?0:t[5]))}}const Lr=new y(0,0),Os=o=>!!o&&Array.isArray(o._objects);function Zi(o){class t extends o{constructor(){super(...arguments),p(this,"_objects",[])}_onObjectAdded(s){}_onObjectRemoved(s){}_onStackOrderChanged(s){}add(){for(var s=arguments.length,r=new Array(s),i=0;i<s;i++)r[i]=arguments[i];const n=this._objects.push(...r);return r.forEach(a=>this._onObjectAdded(a)),n}insertAt(s){for(var r=arguments.length,i=new Array(r>1?r-1:0),n=1;n<r;n++)i[n-1]=arguments[n];return this._objects.splice(s,0,...i),i.forEach(a=>this._onObjectAdded(a)),this._objects.length}remove(){const s=this._objects,r=[];for(var i=arguments.length,n=new Array(i),a=0;a<i;a++)n[a]=arguments[a];return n.forEach(h=>{const c=s.indexOf(h);c!==-1&&(s.splice(c,1),r.push(h),this._onObjectRemoved(h))}),r}forEachObject(s){this.getObjects().forEach((r,i,n)=>s(r,i,n))}getObjects(){for(var s=arguments.length,r=new Array(s),i=0;i<s;i++)r[i]=arguments[i];return r.length===0?[...this._objects]:this._objects.filter(n=>n.isType(...r))}item(s){return this._objects[s]}isEmpty(){return this._objects.length===0}size(){return this._objects.length}contains(s,r){return!!this._objects.includes(s)||!!r&&this._objects.some(i=>i instanceof t&&i.contains(s,!0))}complexity(){return this._objects.reduce((s,r)=>s+=r.complexity?r.complexity():0,0)}sendObjectToBack(s){return!(!s||s===this._objects[0])&&(we(this._objects,s),this._objects.unshift(s),this._onStackOrderChanged(s),!0)}bringObjectToFront(s){return!(!s||s===this._objects[this._objects.length-1])&&(we(this._objects,s),this._objects.push(s),this._onStackOrderChanged(s),!0)}sendObjectBackwards(s,r){if(!s)return!1;const i=this._objects.indexOf(s);if(i!==0){const n=this.findNewLowerIndex(s,i,r);return we(this._objects,s),this._objects.splice(n,0,s),this._onStackOrderChanged(s),!0}return!1}bringObjectForward(s,r){if(!s)return!1;const i=this._objects.indexOf(s);if(i!==this._objects.length-1){const n=this.findNewUpperIndex(s,i,r);return we(this._objects,s),this._objects.splice(n,0,s),this._onStackOrderChanged(s),!0}return!1}moveObjectTo(s,r){return s!==this._objects[r]&&(we(this._objects,s),this._objects.splice(r,0,s),this._onStackOrderChanged(s),!0)}findNewLowerIndex(s,r,i){let n;if(i){n=r;for(let a=r-1;a>=0;--a)if(s.isOverlapping(this._objects[a])){n=a;break}}else n=r-1;return n}findNewUpperIndex(s,r,i){let n;if(i){n=r;for(let a=r+1;a<this._objects.length;++a)if(s.isOverlapping(this._objects[a])){n=a;break}}else n=r+1;return n}collectObjects(s){let{left:r,top:i,width:n,height:a}=s,{includeIntersecting:h=!0}=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const c=[],l=new y(r,i),u=l.add(new y(n,a));for(let d=this._objects.length-1;d>=0;d--){const g=this._objects[d];g.selectable&&g.visible&&(h&&g.intersectsWithRect(l,u)||g.isContainedWithinRect(l,u)||h&&g.containsPoint(l)||h&&g.containsPoint(u))&&c.push(g)}return c}}return t}class Qi extends xo{_setOptions(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{};for(const e in t)this.set(e,t[e])}_setObject(t){for(const e in t)this._set(e,t[e])}set(t,e){return typeof t=="object"?this._setObject(t):this._set(t,e),this}_set(t,e){this[t]=e}toggle(t){const e=this.get(t);return typeof e=="boolean"&&this.set(t,!e),this}get(t){return this[t]}}function ks(o){return Gs().requestAnimationFrame(o)}function _o(o){return Gs().cancelAnimationFrame(o)}let bo=0;const ce=()=>bo++,Zt=()=>{const o=Ee().createElement("canvas");if(!o||o.getContext===void 0)throw new Wt("Failed to create `canvas` element");return o},wo=()=>Ee().createElement("img"),kt=o=>{const t=Zt();return t.width=o.width,t.height=o.height,t},tn=(o,t,e)=>o.toDataURL("image/".concat(t),e),en=(o,t,e)=>new Promise((s,r)=>{o.toBlob(s,"image/".concat(t),e)}),Q=o=>o*Pr,Qt=o=>o/Pr,So=o=>o.every((t,e)=>t===gt[e]),ft=(o,t,e)=>new y(o).transform(t,e),jt=o=>{const t=1/(o[0]*o[3]-o[1]*o[2]),e=[t*o[3],-t*o[1],-t*o[2],t*o[0],0,0],{x:s,y:r}=new y(o[4],o[5]).transform(e,!0);return e[4]=-s,e[5]=-r,e},at=(o,t,e)=>[o[0]*t[0]+o[2]*t[1],o[1]*t[0]+o[3]*t[1],o[0]*t[2]+o[2]*t[3],o[1]*t[2]+o[3]*t[3],e?0:o[0]*t[4]+o[2]*t[5]+o[4],e?0:o[1]*t[4]+o[3]*t[5]+o[5]],Rr=(o,t)=>o.reduceRight((e,s)=>s&&e?at(s,e,t):s||e,void 0)||gt.concat(),sn=o=>{let[t,e]=o;return Math.atan2(e,t)},Fs=o=>{const t=sn(o),e=Math.pow(o[0],2)+Math.pow(o[1],2),s=Math.sqrt(e),r=(o[0]*o[3]-o[2]*o[1])/s,i=Math.atan2(o[0]*o[2]+o[1]*o[3],e);return{angle:Qt(t),scaleX:s,scaleY:r,skewX:Qt(i),skewY:0,translateX:o[4]||0,translateY:o[5]||0}},Ze=function(o){return[1,0,0,1,o,arguments.length>1&&arguments[1]!==void 0?arguments[1]:0]};function je(){let{angle:o=0}=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},{x:t=0,y:e=0}=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};const s=Q(o),r=$t(s),i=Jt(s);return[r,i,-i,r,t?t-(r*t-i*e):0,e?e-(i*t+r*e):0]}const Br=function(o){return[o,0,0,arguments.length>1&&arguments[1]!==void 0?arguments[1]:o,0,0]},rn=o=>Math.tan(Q(o)),nn=o=>[1,0,rn(o),1,0,0],on=o=>[1,rn(o),0,1,0,0],qs=o=>{let{scaleX:t=1,scaleY:e=1,flipX:s=!1,flipY:r=!1,skewX:i=0,skewY:n=0}=o,a=Br(s?-t:t,r?-e:e);return i&&(a=at(a,nn(i),!0)),n&&(a=at(a,on(n),!0)),a},Co=o=>{const{translateX:t=0,translateY:e=0,angle:s=0}=o;let r=Ze(t,e);s&&(r=at(r,je({angle:s})));const i=qs(o);return So(i)||(r=at(r,i)),r},Ds=function(o){let{signal:t,crossOrigin:e=null}=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return new Promise(function(s,r){if(t&&t.aborted)return r(new go("loadImage"));const i=wo();let n;t&&(n=function(h){i.src="",r(h)},t.addEventListener("abort",n,{once:!0}));const a=function(){i.onload=i.onerror=null,n&&(t==null||t.removeEventListener("abort",n)),s(i)};o?(i.onload=a,i.onerror=function(){n&&(t==null||t.removeEventListener("abort",n)),r(new Wt("Error loading ".concat(i.src)))},e&&(i.crossOrigin=e),i.src=o):a()})},Ne=function(o){let{signal:t,reviver:e=Ts}=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return new Promise((s,r)=>{const i=[];t&&t.addEventListener("abort",r,{once:!0}),Promise.all(o.map(n=>D.getClass(n.type).fromObject(n,{signal:t}).then(a=>(e(n,a),i.push(a),a)))).then(s).catch(n=>{i.forEach(a=>{a.dispose&&a.dispose()}),r(n)}).finally(()=>{t&&t.removeEventListener("abort",r)})})},Ks=function(o){let{signal:t}=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};return new Promise((e,s)=>{const r=[];t&&t.addEventListener("abort",s,{once:!0});const i=Object.values(o).map(a=>a&&a.type&&D.has(a.type)?Ne([a],{signal:t}).then(h=>{let[c]=h;return r.push(c),c}):a),n=Object.keys(o);Promise.all(i).then(a=>a.reduce((h,c,l)=>(h[n[l]]=c,h),{})).then(e).catch(a=>{r.forEach(h=>{h.dispose&&h.dispose()}),s(a)}).finally(()=>{t&&t.removeEventListener("abort",s)})})},Fe=function(o){return(arguments.length>1&&arguments[1]!==void 0?arguments[1]:[]).reduce((t,e)=>(e in o&&(t[e]=o[e]),t),{})},Ir=(o,t)=>Object.keys(o).reduce((e,s)=>(t(o[s],s,o)&&(e[s]=o[s]),e),{}),q=(o,t)=>parseFloat(Number(o).toFixed(t)),Ue=o=>"matrix("+o.map(t=>q(t,V.NUM_FRACTION_DIGITS)).join(" ")+")",Tt=o=>!!o&&o.toLive!==void 0,ei=o=>!!o&&typeof o.toObject=="function",si=o=>!!o&&o.offsetX!==void 0&&"source"in o,ue=o=>!!o&&"multiSelectionStacking"in o;function an(o){const t=o&&At(o);let e=0,s=0;if(!o||!t)return{left:e,top:s};let r=o;const i=t.documentElement,n=t.body||{scrollLeft:0,scrollTop:0};for(;r&&(r.parentNode||r.host)&&(r=r.parentNode||r.host,r===t?(e=n.scrollLeft||i.scrollLeft||0,s=n.scrollTop||i.scrollTop||0):(e+=r.scrollLeft||0,s+=r.scrollTop||0),r.nodeType!==1||r.style.position!=="fixed"););return{left:e,top:s}}const At=o=>o.ownerDocument||null,hn=o=>{var t;return((t=o.ownerDocument)===null||t===void 0?void 0:t.defaultView)||null},cn=function(o,t,e){let{width:s,height:r}=e,i=arguments.length>3&&arguments[3]!==void 0?arguments[3]:1;o.width=s,o.height=r,i>1&&(o.setAttribute("width",(s*i).toString()),o.setAttribute("height",(r*i).toString()),t.scale(i,i))},xr=(o,t)=>{let{width:e,height:s}=t;e&&(o.style.width=typeof e=="number"?"".concat(e,"px"):e),s&&(o.style.height=typeof s=="number"?"".concat(s,"px"):s)};function ri(o){return o.onselectstart!==void 0&&(o.onselectstart=()=>!1),o.style.userSelect=mt,o}class ln{constructor(t){p(this,"_originalCanvasStyle",void 0),p(this,"lower",void 0);const e=this.createLowerCanvas(t);this.lower={el:e,ctx:e.getContext("2d")}}createLowerCanvas(t){const e=(s=t)&&s.getContext!==void 0?t:t&&Ee().getElementById(t)||Zt();var s;if(e.hasAttribute("data-fabric"))throw new Wt("Trying to initialize a canvas that has already been initialized. Did you forget to dispose the canvas?");return this._originalCanvasStyle=e.style.cssText,e.setAttribute("data-fabric","main"),e.classList.add("lower-canvas"),e}cleanupDOM(t){let{width:e,height:s}=t;const{el:r}=this.lower;r.classList.remove("lower-canvas"),r.removeAttribute("data-fabric"),r.setAttribute("width","".concat(e)),r.setAttribute("height","".concat(s)),r.style.cssText=this._originalCanvasStyle||"",this._originalCanvasStyle=void 0}setDimensions(t,e){const{el:s,ctx:r}=this.lower;cn(s,r,t,e)}setCSSDimensions(t){xr(this.lower.el,t)}calcOffset(){return function(t){var e;const s=t&&At(t),r={left:0,top:0};if(!s)return r;const i=((e=hn(t))===null||e===void 0?void 0:e.getComputedStyle(t,null))||{};r.left+=parseInt(i.borderLeftWidth,10)||0,r.top+=parseInt(i.borderTopWidth,10)||0,r.left+=parseInt(i.paddingLeft,10)||0,r.top+=parseInt(i.paddingTop,10)||0;let n={left:0,top:0};const a=s.documentElement;t.getBoundingClientRect!==void 0&&(n=t.getBoundingClientRect());const h=an(t);return{left:n.left+h.left-(a.clientLeft||0)+r.left,top:n.top+h.top-(a.clientTop||0)+r.top}}(this.lower.el)}dispose(){Vt().dispose(this.lower.el),delete this.lower}}const To={backgroundVpt:!0,backgroundColor:"",overlayVpt:!0,overlayColor:"",includeDefaultValues:!0,svgViewportTransformation:!0,renderOnAddRemove:!0,skipOffscreen:!0,enableRetinaScaling:!0,imageSmoothingEnabled:!0,controlsAboveOverlay:!1,allowTouchScrolling:!1,viewportTransform:[...gt]},Oo=["objects"];class Qe extends Zi(Qi){get lowerCanvasEl(){var t;return(t=this.elements.lower)===null||t===void 0?void 0:t.el}get contextContainer(){var t;return(t=this.elements.lower)===null||t===void 0?void 0:t.ctx}static getDefaults(){return Qe.ownDefaults}constructor(t){let e=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};super(),Object.assign(this,this.constructor.getDefaults()),this.set(e),this.initElements(t),this._setDimensionsImpl({width:this.width||this.elements.lower.el.width||0,height:this.height||this.elements.lower.el.height||0}),this.skipControlsDrawing=!1,this.viewportTransform=[...this.viewportTransform],this.calcViewportBoundaries()}initElements(t){this.elements=new ln(t)}add(){const t=super.add(...arguments);return arguments.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),t}insertAt(t){for(var e=arguments.length,s=new Array(e>1?e-1:0),r=1;r<e;r++)s[r-1]=arguments[r];const i=super.insertAt(t,...s);return s.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),i}remove(){const t=super.remove(...arguments);return t.length>0&&this.renderOnAddRemove&&this.requestRenderAll(),t}_onObjectAdded(t){t.canvas&&t.canvas!==this&&(he("warn",`Canvas is trying to add an object that belongs to a different canvas.
|
|
3
3
|
Resulting to default behavior: removing object from previous canvas and adding to new canvas`),t.canvas.remove(t)),t._set("canvas",this),t.setCoords(),this.fire("object:added",{target:t}),t.fire("added",{target:this})}_onObjectRemoved(t){t._set("canvas",void 0),this.fire("object:removed",{target:t}),t.fire("removed",{target:this})}_onStackOrderChanged(){this.renderOnAddRemove&&this.requestRenderAll()}getRetinaScaling(){return this.enableRetinaScaling?qi():1}calcOffset(){return this._offset=this.elements.calcOffset()}getWidth(){return this.width}getHeight(){return this.height}setWidth(t,e){return this.setDimensions({width:t},e)}setHeight(t,e){return this.setDimensions({height:t},e)}_setDimensionsImpl(t){let{cssOnly:e=!1,backstoreOnly:s=!1}=arguments.length>1&&arguments[1]!==void 0?arguments[1]:{};if(!e){const r=m({width:this.width,height:this.height},t);this.elements.setDimensions(r,this.getRetinaScaling()),this.hasLostContext=!0,this.width=r.width,this.height=r.height}s||this.elements.setCSSDimensions(t),this.calcOffset()}setDimensions(t,e){this._setDimensionsImpl(t,e),e&&e.cssOnly||this.requestRenderAll()}getZoom(){return this.viewportTransform[0]}setViewportTransform(t){this.viewportTransform=t,this.calcViewportBoundaries(),this.renderOnAddRemove&&this.requestRenderAll()}zoomToPoint(t,e){const s=t,r=[...this.viewportTransform],i=ft(t,jt(r));r[0]=e,r[3]=e;const n=ft(i,r);r[4]+=s.x-n.x,r[5]+=s.y-n.y,this.setViewportTransform(r)}setZoom(t){this.zoomToPoint(new y(0,0),t)}absolutePan(t){const e=[...this.viewportTransform];return e[4]=-t.x,e[5]=-t.y,this.setViewportTransform(e)}relativePan(t){return this.absolutePan(new y(-t.x-this.viewportTransform[4],-t.y-this.viewportTransform[5]))}getElement(){return this.elements.lower.el}clearContext(t){t.clearRect(0,0,this.width,this.height)}getContext(){return this.elements.lower.ctx}clear(){this.remove(...this.getObjects()),this.backgroundImage=void 0,this.overlayImage=void 0,this.backgroundColor="",this.overlayColor="",this.clearContext(this.getContext()),this.fire("canvas:cleared"),this.renderOnAddRemove&&this.requestRenderAll()}renderAll(){this.cancelRequestedRender(),this.destroyed||this.renderCanvas(this.getContext(),this._objects)}renderAndReset(){this.nextRenderHandle=0,this.renderAll()}requestRenderAll(){this.nextRenderHandle||this.disposed||this.destroyed||(this.nextRenderHandle=ks(()=>this.renderAndReset()))}calcViewportBoundaries(){const t=this.width,e=this.height,s=jt(this.viewportTransform),r=ft({x:0,y:0},s),i=ft({x:t,y:e},s),n=r.min(i),a=r.max(i);return this.vptCoords={tl:n,tr:new y(a.x,n.y),bl:new y(n.x,a.y),br:a}}cancelRequestedRender(){this.nextRenderHandle&&(_o(this.nextRenderHandle),this.nextRenderHandle=0)}drawControls(t){}renderCanvas(t,e){if(this.destroyed)return;const s=this.viewportTransform,r=this.clipPath;this.calcViewportBoundaries(),this.clearContext(t),t.imageSmoothingEnabled=this.imageSmoothingEnabled,t.patternQuality="best",this.fire("before:render",{ctx:t}),this._renderBackground(t),t.save(),t.transform(s[0],s[1],s[2],s[3],s[4],s[5]),this._renderObjects(t,e),t.restore(),this.controlsAboveOverlay||this.skipControlsDrawing||this.drawControls(t),r&&(r._set("canvas",this),r.shouldCache(),r._transformDone=!0,r.renderCache({forClipping:!0}),this.drawClipPathOnCanvas(t,r)),this._renderOverlay(t),this.controlsAboveOverlay&&!this.skipControlsDrawing&&this.drawControls(t),this.fire("after:render",{ctx:t}),this.__cleanupTask&&(this.__cleanupTask(),this.__cleanupTask=void 0)}drawClipPathOnCanvas(t,e){const s=this.viewportTransform;t.save(),t.transform(...s),t.globalCompositeOperation="destination-in",e.transform(t),t.scale(1/e.zoomX,1/e.zoomY),t.drawImage(e._cacheCanvas,-e.cacheTranslationX,-e.cacheTranslationY),t.restore()}_renderObjects(t,e){for(let s=0,r=e.length;s<r;++s)e[s]&&e[s].render(t)}_renderBackgroundOrOverlay(t,e){const s=this["".concat(e,"Color")],r=this["".concat(e,"Image")],i=this.viewportTransform,n=this["".concat(e,"Vpt")];if(!s&&!r)return;const a=Tt(s);if(s){if(t.save(),t.beginPath(),t.moveTo(0,0),t.lineTo(this.width,0),t.lineTo(this.width,this.height),t.lineTo(0,this.height),t.closePath(),t.fillStyle=a?s.toLive(t):s,n&&t.transform(...i),a){t.transform(1,0,0,1,s.offsetX||0,s.offsetY||0);const h=s.gradientTransform||s.patternTransform;h&&t.transform(...h)}t.fill(),t.restore()}if(r){t.save();const{skipOffscreen:h}=this;this.skipOffscreen=n,n&&t.transform(...i),r.render(t),this.skipOffscreen=h,t.restore()}}_renderBackground(t){this._renderBackgroundOrOverlay(t,"background")}_renderOverlay(t){this._renderBackgroundOrOverlay(t,"overlay")}getCenter(){return{top:this.height/2,left:this.width/2}}getCenterPoint(){return new y(this.width/2,this.height/2)}centerObjectH(t){return this._centerObject(t,new y(this.getCenterPoint().x,t.getCenterPoint().y))}centerObjectV(t){return this._centerObject(t,new y(t.getCenterPoint().x,this.getCenterPoint().y))}centerObject(t){return this._centerObject(t,this.getCenterPoint())}viewportCenterObject(t){return this._centerObject(t,this.getVpCenter())}viewportCenterObjectH(t){return this._centerObject(t,new y(this.getVpCenter().x,t.getCenterPoint().y))}viewportCenterObjectV(t){return this._centerObject(t,new y(t.getCenterPoint().x,this.getVpCenter().y))}getVpCenter(){return ft(this.getCenterPoint(),jt(this.viewportTransform))}_centerObject(t,e){t.setXY(e,R,R),t.setCoords(),this.renderOnAddRemove&&this.requestRenderAll()}toDatalessJSON(t){return this.toDatalessObject(t)}toObject(t){return this._toObjectMethod("toObject",t)}toJSON(){return this.toObject()}toDatalessObject(t){return this._toObjectMethod("toDatalessObject",t)}_toObjectMethod(t,e){const s=this.clipPath,r=s&&!s.excludeFromExport?this._toObject(s,t,e):null;return m(m(m({version:vr},Fe(this,e)),{},{objects:this._objects.filter(i=>!i.excludeFromExport).map(i=>this._toObject(i,t,e))},this.__serializeBgOverlay(t,e)),r?{clipPath:r}:null)}_toObject(t,e,s){let r;this.includeDefaultValues||(r=t.includeDefaultValues,t.includeDefaultValues=!1);const i=t[e](s);return this.includeDefaultValues||(t.includeDefaultValues=!!r),i}__serializeBgOverlay(t,e){const s={},r=this.backgroundImage,i=this.overlayImage,n=this.backgroundColor,a=this.overlayColor;return Tt(n)?n.excludeFromExport||(s.background=n.toObject(e)):n&&(s.background=n),Tt(a)?a.excludeFromExport||(s.overlay=a.toObject(e)):a&&(s.overlay=a),r&&!r.excludeFromExport&&(s.backgroundImage=this._toObject(r,t,e)),i&&!i.excludeFromExport&&(s.overlayImage=this._toObject(i,t,e)),s}toSVG(){let t=arguments.length>0&&arguments[0]!==void 0?arguments[0]:{},e=arguments.length>1?arguments[1]:void 0;t.reviver=e;const s=[];return this._setSVGPreamble(s,t),this._setSVGHeader(s,t),this.clipPath&&s.push('<g clip-path="url(#'.concat(this.clipPath.clipPathId,`)" >
|
|
4
4
|
`)),this._setSVGBgOverlayColor(s,"background"),this._setSVGBgOverlayImage(s,"backgroundImage",e),this._setSVGObjects(s,e),this.clipPath&&s.push(`</g>
|