@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 CHANGED
@@ -1,8 +1,21 @@
1
1
  # VyBit
2
2
 
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.
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 desig of it, or insert a panel to draw out changes. You can also add contextual messages. These are all draft changes until you commit.
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
- ### Commiting changes
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
 
@@ -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
- if (typeof current.type === "function") {
162
+ const t = current.type;
163
+ if (typeof t === "function") {
164
164
  return {
165
- componentType: current.type,
166
- componentName: current.type.displayName || current.type.name || "Unknown",
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) return 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: config
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,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitovi/vybit",
3
- "version": "0.11.2",
3
+ "version": "0.11.4",
4
4
  "description": "Browser overlay + inspector panel + MCP server for visually editing Tailwind CSS classes on a running React app",
5
5
  "keywords": [
6
6
  "tailwind",
@@ -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-CGc6ZuTL.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;
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>