made-refine 0.2.20 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/babel.cjs +5 -1
- package/dist/index.d.mts +22 -4
- package/dist/index.d.ts +22 -4
- package/dist/index.js +1525 -793
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1526 -794
- package/dist/index.mjs.map +1 -1
- package/dist/preload/preload.js +26 -3
- package/dist/preload.js +25 -3
- package/dist/preload.js.map +1 -1
- package/dist/preload.mjs +10 -3
- package/dist/preload.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/{utils-CpmjloNg.d.mts → utils-ovHeRo0g.d.mts} +20 -16
- package/dist/{utils-CpmjloNg.d.ts → utils-ovHeRo0g.d.ts} +20 -16
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +292 -198
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +292 -198
- package/dist/utils.mjs.map +1 -1
- package/package.json +14 -3
package/dist/index.mjs
CHANGED
|
@@ -7,7 +7,7 @@ import * as React8 from "react";
|
|
|
7
7
|
import * as React from "react";
|
|
8
8
|
|
|
9
9
|
// dist/styles.css
|
|
10
|
-
var styles_default = '/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--font-weight-thin:100;--font-weight-extralight:200;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--leading-relaxed:1.625;--radius-sm:calc(.5rem - 4px);--radius-md:calc(.5rem - 2px);--radius-xl:.75rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-border:#e6e6e6;--color-ring:#262626;--color-background:#fff;--color-foreground:#171717;--color-primary:#171717;--color-primary-foreground:#fafafa;--color-secondary-foreground:#171717;--color-destructive:#ef4444;--color-destructive-foreground:#fafafa;--color-muted:#f2f2f2;--color-muted-foreground:#737373;--color-popover-foreground:#171717}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,:host{color-scheme:light;color:var(--color-foreground)}@media (prefers-color-scheme:dark){:root,:host(:not([data-theme])),:host([data-theme=system]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}}:host([data-theme=dark]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}*,:before,:after{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:var(--color-background);--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;border-color:var(--color-border)}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.top-1\\/2{top:50%}.left-1\\.5{left:calc(var(--spacing)*1.5)}.left-1\\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-3{left:calc(var(--spacing)*3)}.z-\\[99990\\]{z-index:99990}.z-\\[99991\\]{z-index:99991}.z-\\[99998\\]{z-index:99998}.z-\\[99999\\]{z-index:99999}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-4{margin:calc(var(--spacing)*4)}.mx-0\\.5{margin-inline:calc(var(--spacing)*.5)}.mx-2{margin-inline:calc(var(--spacing)*2)}.my-0\\.5{margin-block:calc(var(--spacing)*.5)}.my-1{margin-block:calc(var(--spacing)*1)}.mt-0{margin-top:calc(var(--spacing)*0)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2\\.5{margin-top:calc(var(--spacing)*2.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.ml-0{margin-left:calc(var(--spacing)*0)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.block{display:block}.contents{display:contents}.flex{display:flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.inline-grid{display:inline-grid}.list-item{display:list-item}.size-1{width:calc(var(--spacing)*1);height:calc(var(--spacing)*1)}.size-2\\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-full{width:100%;height:100%}.h-0\\.5{height:calc(var(--spacing)*.5)}.h-2{height:calc(var(--spacing)*2)}.h-3\\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-\\[150px\\]{height:150px}.h-auto{height:auto}.h-fit{height:fit-content}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-\\[240px\\]{max-height:240px}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\\[18px\\]{min-height:18px}.w-0\\.5{width:calc(var(--spacing)*.5)}.w-2{width:calc(var(--spacing)*2)}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-14{width:calc(var(--spacing)*14)}.w-\\[1\\.5px\\]{width:1.5px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[240px\\]{width:240px}.w-\\[260px\\]{width:260px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\\[18px\\]{min-width:18px}.min-w-\\[20px\\]{min-width:20px}.min-w-\\[100px\\]{min-width:100px}.min-w-\\[120px\\]{min-width:120px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-\\(--transform-origin\\){transform-origin:var(--transform-origin)}.-translate-x-1\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.\\[appearance\\:textfield\\]{appearance:textfield}.appearance-none{appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\\[0fr\\]{grid-template-columns:0fr}.grid-cols-\\[1fr\\]{grid-template-columns:1fr}.grid-rows-\\[0fr\\]{grid-template-rows:0fr}.grid-rows-\\[1fr\\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-evenly{justify-content:space-evenly}.justify-start{justify-content:flex-start}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.rounded{border-radius:.25rem}.rounded-\\[6px\\]{border-radius:6px}.rounded-\\[8px\\]{border-radius:8px}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-tl{border-top-left-radius:.25rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-bl{border-bottom-left-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dotted{--tw-border-style:dotted;border-style:dotted}.border-double{--tw-border-style:double;border-style:double}.border-none{--tw-border-style:none;border-style:none}.border-solid{--tw-border-style:solid;border-style:solid}.\\[border-top-style\\:solid\\]{border-top-style:solid}.\\[border-right-style\\:dashed\\]{border-right-style:dashed}.\\[border-bottom-style\\:dashed\\]{border-bottom-style:dashed}.\\[border-bottom-style\\:dotted\\]{border-bottom-style:dotted}.\\[border-bottom-style\\:solid\\]{border-bottom-style:solid}.\\[border-left-style\\:double\\]{border-left-style:double}.\\[border-left-style\\:solid\\]{border-left-style:solid}.border-border{border-color:var(--color-border)}.border-border\\/30{border-color:#e6e6e64d}@supports (color:color-mix(in lab, red, red)){.border-border\\/30{border-color:color-mix(in oklab,var(--color-border)30%,transparent)}}.border-border\\/50{border-color:#e6e6e680}@supports (color:color-mix(in lab, red, red)){.border-border\\/50{border-color:color-mix(in oklab,var(--color-border)50%,transparent)}}.border-foreground\\/10{border-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.border-foreground\\/10{border-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.bg-\\[canvas\\]{background-color:canvas}.bg-background{background-color:var(--color-background)}.bg-background\\/85{background-color:#ffffffd9}@supports (color:color-mix(in lab, red, red)){.bg-background\\/85{background-color:color-mix(in oklab,var(--color-background)85%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-border{background-color:var(--color-border)}.bg-destructive{background-color:var(--color-destructive)}.bg-foreground{background-color:var(--color-foreground)}.bg-foreground\\/25{background-color:#17171740}@supports (color:color-mix(in lab, red, red)){.bg-foreground\\/25{background-color:color-mix(in oklab,var(--color-foreground)25%,transparent)}}.bg-muted{background-color:var(--color-muted)}.bg-muted-foreground\\/30{background-color:#7373734d}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\/30{background-color:color-mix(in oklab,var(--color-muted-foreground)30%,transparent)}}.bg-primary{background-color:var(--color-primary)}.bg-transparent{background-color:#0000}.fill-border{fill:var(--color-border)}.p-0{padding:calc(var(--spacing)*0)}.p-0\\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-3\\.5{padding-block:calc(var(--spacing)*3.5)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2\\.5{padding-top:calc(var(--spacing)*2.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pt-\\[13px\\]{padding-top:13px}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-1\\.5{padding-right:calc(var(--spacing)*1.5)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\\.5{padding-bottom:calc(var(--spacing)*1.5)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pl-0{padding-left:calc(var(--spacing)*0)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-7{padding-left:calc(var(--spacing)*7)}.text-center{text-align:center}.text-justify{text-align:justify}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[7px\\]{font-size:7px}.text-\\[9px\\]{font-size:9px}.text-\\[10px\\]{font-size:10px}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-extralight{--tw-font-weight:var(--font-weight-extralight);font-weight:var(--font-weight-extralight)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.font-thin{--tw-font-weight:var(--font-weight-thin);font-weight:var(--font-weight-thin)}.\\[overflow-wrap\\:anywhere\\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-background{color:var(--color-background)}.text-blue-500{color:var(--color-blue-500)}.text-destructive-foreground{color:var(--color-destructive-foreground)}.text-foreground{color:var(--color-foreground)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-muted-foreground{color:var(--color-muted-foreground)}.text-popover-foreground{color:var(--color-popover-foreground)}.text-primary{color:var(--color-primary)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-red-500{color:var(--color-red-500)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xs{--tw-shadow:0 1px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.3\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_4px_6px_-1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[inset_0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-white{--tw-ring-color:var(--color-white)}.outline,.outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.outline-border{outline-color:var(--color-border)}.outline-foreground\\/10{outline-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.outline-foreground\\/10{outline-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.outline-red-500\\/70{outline-color:#fb2c36b3}@supports (color:color-mix(in lab, red, red)){.outline-red-500\\/70{outline-color:color-mix(in oklab,var(--color-red-500)70%,transparent)}}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[color\\,background-color\\]{transition-property:color,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[opacity\\,background-color\\,color\\]{transition-property:opacity,background-color,color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[transform\\,scale\\,opacity\\]{transition-property:transform,scale,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.animate-in{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\\[-ms-overflow-style\\:none\\]{-ms-overflow-style:none}.\\[scrollbar-width\\:none\\]{scrollbar-width:none}.duration-150{animation-duration:.15s}.duration-200{animation-duration:.2s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.fade-in-0{--tw-enter-opacity:0}.running{animation-play-state:running}.zoom-in-95{--tw-enter-scale:.95}@media (hover:hover){.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\\/pin\\:inline:is(:where(.group\\/pin):hover *){display:inline}}.file\\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\\:bg-transparent::file-selector-button{background-color:#0000}.file\\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\\:text-foreground::file-selector-button{color:var(--color-foreground)}.placeholder\\:text-muted-foreground::placeholder{color:var(--color-muted-foreground)}.placeholder\\:text-red-400::placeholder{color:var(--color-red-400)}.focus-within\\:ring-1:focus-within{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-within\\:ring-ring:focus-within{--tw-ring-color:var(--color-ring)}.focus-within\\:outline-none:focus-within{--tw-outline-style:none;outline-style:none}.focus-within\\:ring-inset:focus-within{--tw-ring-inset:inset}@media (hover:hover){.hover\\:scale-\\[1\\.67\\]:hover{scale:1.67}.hover\\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\\:bg-destructive\\/90:hover{background-color:#ef4444e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-destructive\\/90:hover{background-color:color-mix(in oklab,var(--color-destructive)90%,transparent)}}.hover\\:bg-foreground\\/80:hover{background-color:#171717cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-foreground\\/80:hover{background-color:color-mix(in oklab,var(--color-foreground)80%,transparent)}}.hover\\:bg-muted:hover{background-color:var(--color-muted)}.hover\\:bg-muted-foreground\\/10:hover{background-color:#7373731a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted-foreground\\/10:hover{background-color:color-mix(in oklab,var(--color-muted-foreground)10%,transparent)}}.hover\\:bg-muted\\/50:hover{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/50:hover{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.hover\\:bg-muted\\/80:hover{background-color:#f2f2f2cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/80:hover{background-color:color-mix(in oklab,var(--color-muted)80%,transparent)}}.hover\\:bg-primary\\/90:hover{background-color:#171717e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-primary\\/90:hover{background-color:color-mix(in oklab,var(--color-primary)90%,transparent)}}.hover\\:text-foreground:hover{color:var(--color-foreground)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring)}.focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-inset:focus-visible{--tw-ring-inset:inset}.active\\:cursor-grabbing:active{cursor:grabbing}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.data-ending-style\\:scale-90[data-ending-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-ending-style\\:opacity-0[data-ending-style]{opacity:0}.data-instant\\:transition-none[data-instant]{transition-property:none}.data-starting-style\\:scale-90[data-starting-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-starting-style\\:opacity-0[data-starting-style]{opacity:0}.data-\\[highlighted\\]\\:bg-muted[data-highlighted]{background-color:var(--color-muted)}.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.data-\\[highlighted\\]\\:text-foreground[data-highlighted]{color:var(--color-foreground)}@media (prefers-color-scheme:dark){.dark\\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dark\\:-outline-offset-1{outline-offset:calc(1px*-1)}}.\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.\\[\\&_svg\\]\\:size-3\\.5 svg{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.\\[\\&\\:\\:-webkit-inner-spin-button\\]\\:appearance-none::-webkit-inner-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-outer-spin-button\\]\\:appearance-none::-webkit-outer-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-scrollbar\\]\\:hidden::-webkit-scrollbar{display:none}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none;animation:none}}.lucide{stroke-width:1px}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes pulse{50%{opacity:.5}}';
|
|
10
|
+
var styles_default = '/*! tailwindcss v4.1.18 | MIT License | https://tailwindcss.com */\n@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1}}}@layer theme{:root,:host{--font-sans:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";--font-mono:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace;--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-600:oklch(54.6% .245 262.881);--color-white:#fff;--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--font-weight-thin:100;--font-weight-extralight:200;--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-extrabold:800;--font-weight-black:900;--leading-relaxed:1.625;--radius-sm:calc(.5rem - 4px);--radius-md:calc(.5rem - 2px);--radius-xl:.75rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-border:#e6e6e6;--color-ring:#262626;--color-background:#fff;--color-foreground:#171717;--color-primary:#171717;--color-primary-foreground:#fafafa;--color-secondary-foreground:#171717;--color-destructive:#ef4444;--color-destructive-foreground:#fafafa;--color-muted:#f2f2f2;--color-muted-foreground:#737373;--color-popover-foreground:#171717}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root,:host{color-scheme:light;color:var(--color-foreground)}@media (prefers-color-scheme:dark){:root,:host(:not([data-theme])),:host([data-theme=system]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}}:host([data-theme=dark]){color-scheme:dark;color:var(--color-foreground);--color-border:#2e2e2e;--color-input:#2e2e2e;--color-ring:#d4d4d4;--color-background:#121212;--color-foreground:#fafafa;--color-primary:#fafafa;--color-primary-foreground:#171717;--color-secondary:#262626;--color-secondary-foreground:#fafafa;--color-destructive:#7f1d1d;--color-destructive-foreground:#fafafa;--color-muted:#262626;--color-muted-foreground:#a3a3a3;--color-accent:#262626;--color-accent-foreground:#fafafa;--color-popover:#171717;--color-popover-foreground:#fafafa}*,:before,:after{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:var(--color-background);--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;border-color:var(--color-border)}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.invisible{visibility:hidden}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing)*0)}.top-1\\/2{top:50%}.left-1\\.5{left:calc(var(--spacing)*1.5)}.left-1\\/2{left:50%}.left-2{left:calc(var(--spacing)*2)}.left-3{left:calc(var(--spacing)*3)}.isolate{isolation:isolate}.z-\\[99990\\]{z-index:99990}.z-\\[99991\\]{z-index:99991}.z-\\[99998\\]{z-index:99998}.z-\\[99999\\]{z-index:99999}.\\!container{width:100%!important}@media (min-width:40rem){.\\!container{max-width:40rem!important}}@media (min-width:48rem){.\\!container{max-width:48rem!important}}@media (min-width:64rem){.\\!container{max-width:64rem!important}}@media (min-width:80rem){.\\!container{max-width:80rem!important}}@media (min-width:96rem){.\\!container{max-width:96rem!important}}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.m-4{margin:calc(var(--spacing)*4)}.mx-0\\.5{margin-inline:calc(var(--spacing)*.5)}.mx-2{margin-inline:calc(var(--spacing)*2)}.my-0\\.5{margin-block:calc(var(--spacing)*.5)}.my-1{margin-block:calc(var(--spacing)*1)}.mt-0{margin-top:calc(var(--spacing)*0)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2\\.5{margin-top:calc(var(--spacing)*2.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-1\\.5{margin-bottom:calc(var(--spacing)*1.5)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.ml-0{margin-left:calc(var(--spacing)*0)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-1\\.5{margin-left:calc(var(--spacing)*1.5)}.ml-2{margin-left:calc(var(--spacing)*2)}.block{display:block}.contents{display:contents}.flex{display:flex}.flow-root{display:flow-root}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.inline-grid{display:inline-grid}.list-item{display:list-item}.table{display:table}.size-1{width:calc(var(--spacing)*1);height:calc(var(--spacing)*1)}.size-2\\.5{width:calc(var(--spacing)*2.5);height:calc(var(--spacing)*2.5)}.size-3{width:calc(var(--spacing)*3);height:calc(var(--spacing)*3)}.size-3\\.5{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.size-4{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.size-5{width:calc(var(--spacing)*5);height:calc(var(--spacing)*5)}.size-6{width:calc(var(--spacing)*6);height:calc(var(--spacing)*6)}.size-7{width:calc(var(--spacing)*7);height:calc(var(--spacing)*7)}.size-full{width:100%;height:100%}.h-0\\.5{height:calc(var(--spacing)*.5)}.h-2{height:calc(var(--spacing)*2)}.h-3\\.5{height:calc(var(--spacing)*3.5)}.h-4{height:calc(var(--spacing)*4)}.h-5{height:calc(var(--spacing)*5)}.h-6{height:calc(var(--spacing)*6)}.h-7{height:calc(var(--spacing)*7)}.h-8{height:calc(var(--spacing)*8)}.h-9{height:calc(var(--spacing)*9)}.h-10{height:calc(var(--spacing)*10)}.h-11{height:calc(var(--spacing)*11)}.h-\\[150px\\]{height:150px}.h-auto{height:auto}.h-fit{height:fit-content}.h-full{height:100%}.max-h-48{max-height:calc(var(--spacing)*48)}.max-h-\\[240px\\]{max-height:240px}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-\\[18px\\]{min-height:18px}.w-0\\.5{width:calc(var(--spacing)*.5)}.w-2{width:calc(var(--spacing)*2)}.w-3{width:calc(var(--spacing)*3)}.w-4{width:calc(var(--spacing)*4)}.w-5{width:calc(var(--spacing)*5)}.w-8{width:calc(var(--spacing)*8)}.w-9{width:calc(var(--spacing)*9)}.w-10{width:calc(var(--spacing)*10)}.w-11{width:calc(var(--spacing)*11)}.w-14{width:calc(var(--spacing)*14)}.w-\\[1\\.5px\\]{width:1.5px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[240px\\]{width:240px}.w-\\[260px\\]{width:260px}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-full{max-width:100%}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\\[18px\\]{min-width:18px}.min-w-\\[20px\\]{min-width:20px}.min-w-\\[100px\\]{min-width:100px}.min-w-\\[120px\\]{min-width:120px}.flex-1{flex:1}.flex-shrink-0,.shrink-0{flex-shrink:0}.origin-\\(--transform-origin\\){transform-origin:var(--transform-origin)}.-translate-x-1\\/2{--tw-translate-x:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-1\\/2{--tw-translate-y:calc(calc(1/2*100%)*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.rotate-45{rotate:45deg}.transform{transform:var(--tw-rotate-x,)var(--tw-rotate-y,)var(--tw-rotate-z,)var(--tw-skew-x,)var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-crosshair{cursor:crosshair}.cursor-default{cursor:default}.cursor-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.\\[appearance\\:textfield\\]{appearance:textfield}.appearance-none{appearance:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.grid-cols-\\[0fr\\]{grid-template-columns:0fr}.grid-cols-\\[1fr\\]{grid-template-columns:1fr}.grid-rows-\\[0fr\\]{grid-template-rows:0fr}.grid-rows-\\[1fr\\]{grid-template-rows:1fr}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-around{justify-content:space-around}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.justify-evenly{justify-content:space-evenly}.justify-start{justify-content:flex-start}.gap-0\\.5{gap:calc(var(--spacing)*.5)}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.overflow-y-hidden{overflow-y:hidden}.rounded{border-radius:.25rem}.rounded-\\[6px\\]{border-radius:6px}.rounded-\\[8px\\]{border-radius:8px}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.rounded-tl{border-top-left-radius:.25rem}.rounded-tr{border-top-right-radius:.25rem}.rounded-br{border-bottom-right-radius:.25rem}.rounded-bl{border-bottom-left-radius:.25rem}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-2{border-style:var(--tw-border-style);border-width:2px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-dotted{--tw-border-style:dotted;border-style:dotted}.border-double{--tw-border-style:double;border-style:double}.border-none{--tw-border-style:none;border-style:none}.border-solid{--tw-border-style:solid;border-style:solid}.\\[border-top-style\\:solid\\]{border-top-style:solid}.\\[border-right-style\\:dashed\\]{border-right-style:dashed}.\\[border-bottom-style\\:dashed\\]{border-bottom-style:dashed}.\\[border-bottom-style\\:dotted\\]{border-bottom-style:dotted}.\\[border-bottom-style\\:solid\\]{border-bottom-style:solid}.\\[border-left-style\\:double\\]{border-left-style:double}.\\[border-left-style\\:solid\\]{border-left-style:solid}.border-border{border-color:var(--color-border)}.border-border\\/30{border-color:#e6e6e64d}@supports (color:color-mix(in lab, red, red)){.border-border\\/30{border-color:color-mix(in oklab,var(--color-border)30%,transparent)}}.border-border\\/50{border-color:#e6e6e680}@supports (color:color-mix(in lab, red, red)){.border-border\\/50{border-color:color-mix(in oklab,var(--color-border)50%,transparent)}}.border-foreground\\/10{border-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.border-foreground\\/10{border-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.border-transparent{border-color:#0000}.border-white{border-color:var(--color-white)}.bg-\\[canvas\\]{background-color:canvas}.bg-background{background-color:var(--color-background)}.bg-background\\/85{background-color:#ffffffd9}@supports (color:color-mix(in lab, red, red)){.bg-background\\/85{background-color:color-mix(in oklab,var(--color-background)85%,transparent)}}.bg-blue-500{background-color:var(--color-blue-500)}.bg-border{background-color:var(--color-border)}.bg-destructive{background-color:var(--color-destructive)}.bg-foreground{background-color:var(--color-foreground)}.bg-foreground\\/25{background-color:#17171740}@supports (color:color-mix(in lab, red, red)){.bg-foreground\\/25{background-color:color-mix(in oklab,var(--color-foreground)25%,transparent)}}.bg-muted{background-color:var(--color-muted)}.bg-muted-foreground\\/30{background-color:#7373734d}@supports (color:color-mix(in lab, red, red)){.bg-muted-foreground\\/30{background-color:color-mix(in oklab,var(--color-muted-foreground)30%,transparent)}}.bg-primary{background-color:var(--color-primary)}.bg-red-500{background-color:var(--color-red-500)}.bg-transparent{background-color:#0000}.fill-border{fill:var(--color-border)}.p-0{padding:calc(var(--spacing)*0)}.p-0\\.5{padding:calc(var(--spacing)*.5)}.p-1{padding:calc(var(--spacing)*1)}.p-1\\.5{padding:calc(var(--spacing)*1.5)}.p-2{padding:calc(var(--spacing)*2)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.px-8{padding-inline:calc(var(--spacing)*8)}.py-0{padding-block:calc(var(--spacing)*0)}.py-0\\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-3\\.5{padding-block:calc(var(--spacing)*3.5)}.pt-0{padding-top:calc(var(--spacing)*0)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-2\\.5{padding-top:calc(var(--spacing)*2.5)}.pt-4{padding-top:calc(var(--spacing)*4)}.pt-6{padding-top:calc(var(--spacing)*6)}.pt-\\[13px\\]{padding-top:13px}.pr-1{padding-right:calc(var(--spacing)*1)}.pr-1\\.5{padding-right:calc(var(--spacing)*1.5)}.pr-2{padding-right:calc(var(--spacing)*2)}.pb-1{padding-bottom:calc(var(--spacing)*1)}.pb-1\\.5{padding-bottom:calc(var(--spacing)*1.5)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pl-0{padding-left:calc(var(--spacing)*0)}.pl-6{padding-left:calc(var(--spacing)*6)}.pl-7{padding-left:calc(var(--spacing)*7)}.text-center{text-align:center}.text-justify{text-align:justify}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\\[7px\\]{font-size:7px}.text-\\[9px\\]{font-size:9px}.text-\\[10px\\]{font-size:10px}.leading-\\[18px\\]{--tw-leading:18px;line-height:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-extrabold{--tw-font-weight:var(--font-weight-extrabold);font-weight:var(--font-weight-extrabold)}.font-extralight{--tw-font-weight:var(--font-weight-extralight);font-weight:var(--font-weight-extralight)}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.font-thin{--tw-font-weight:var(--font-weight-thin);font-weight:var(--font-weight-thin)}.\\[overflow-wrap\\:anywhere\\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-background{color:var(--color-background)}.text-blue-500{color:var(--color-blue-500)}.text-destructive-foreground{color:var(--color-destructive-foreground)}.text-foreground{color:var(--color-foreground)}.text-green-400{color:var(--color-green-400)}.text-green-500{color:var(--color-green-500)}.text-muted-foreground{color:var(--color-muted-foreground)}.text-popover-foreground{color:var(--color-popover-foreground)}.text-primary{color:var(--color-primary)}.text-primary-foreground{color:var(--color-primary-foreground)}.text-red-500{color:var(--color-red-500)}.text-secondary-foreground{color:var(--color-secondary-foreground)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,)var(--tw-slashed-zero,)var(--tw-numeric-figure,)var(--tw-numeric-spacing,)var(--tw-numeric-fraction,)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-100{opacity:1}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-2xs{--tw-shadow:0 1px var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.3\\)\\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,#0000004d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[0_4px_6px_-1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\\[inset_0_0_0_1px_rgba\\(0\\,0\\,0\\,0\\.1\\)\\]{--tw-shadow:inset 0 0 0 1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-inner{--tw-shadow:inset 0 2px 4px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a),0 8px 10px -6px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-2{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring-white{--tw-ring-color:var(--color-white)}.outline,.outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.outline-border{outline-color:var(--color-border)}.outline-foreground\\/10{outline-color:#1717171a}@supports (color:color-mix(in lab, red, red)){.outline-foreground\\/10{outline-color:color-mix(in oklab,var(--color-foreground)10%,transparent)}}.outline-red-500\\/70{outline-color:#fb2c36b3}@supports (color:color-mix(in lab, red, red)){.outline-red-500\\/70{outline-color:color-mix(in oklab,var(--color-red-500)70%,transparent)}}.blur{--tw-blur:blur(8px);filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,)var(--tw-brightness,)var(--tw-contrast,)var(--tw-grayscale,)var(--tw-hue-rotate,)var(--tw-invert,)var(--tw-saturate,)var(--tw-sepia,)var(--tw-drop-shadow,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,)var(--tw-backdrop-brightness,)var(--tw-backdrop-contrast,)var(--tw-backdrop-grayscale,)var(--tw-backdrop-hue-rotate,)var(--tw-backdrop-invert,)var(--tw-backdrop-opacity,)var(--tw-backdrop-saturate,)var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[color\\,background-color\\]{transition-property:color,background-color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[opacity\\,background-color\\,color\\]{transition-property:opacity,background-color,color;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\\[transform\\,scale\\,opacity\\]{transition-property:transform,scale,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.animate-in{--tw-enter-opacity:initial;--tw-enter-scale:initial;--tw-enter-rotate:initial;--tw-enter-translate-x:initial;--tw-enter-translate-y:initial;animation-name:enter;animation-duration:.15s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.\\[-ms-overflow-style\\:none\\]{-ms-overflow-style:none}.\\[scrollbar-width\\:none\\]{scrollbar-width:none}.duration-150{animation-duration:.15s}.duration-200{animation-duration:.2s}.ease-in-out{animation-timing-function:cubic-bezier(.4,0,.2,1)}.ease-out{animation-timing-function:cubic-bezier(0,0,.2,1)}.fade-in-0{--tw-enter-opacity:0}.running{animation-play-state:running}.zoom-in-95{--tw-enter-scale:.95}@media (hover:hover){.group-hover\\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\\/pin\\:inline:is(:where(.group\\/pin):hover *){display:inline}}.file\\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\\:bg-transparent::file-selector-button{background-color:#0000}.file\\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\\:text-foreground::file-selector-button{color:var(--color-foreground)}.placeholder\\:text-muted-foreground::placeholder{color:var(--color-muted-foreground)}.placeholder\\:text-red-400::placeholder{color:var(--color-red-400)}.focus-within\\:ring-1:focus-within{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-within\\:ring-ring:focus-within{--tw-ring-color:var(--color-ring)}.focus-within\\:outline-none:focus-within{--tw-outline-style:none;outline-style:none}.focus-within\\:ring-inset:focus-within{--tw-ring-inset:inset}@media (hover:hover){.hover\\:scale-\\[1\\.67\\]:hover{scale:1.67}.hover\\:bg-blue-600:hover{background-color:var(--color-blue-600)}.hover\\:bg-destructive\\/90:hover{background-color:#ef4444e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-destructive\\/90:hover{background-color:color-mix(in oklab,var(--color-destructive)90%,transparent)}}.hover\\:bg-foreground\\/80:hover{background-color:#171717cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-foreground\\/80:hover{background-color:color-mix(in oklab,var(--color-foreground)80%,transparent)}}.hover\\:bg-muted:hover{background-color:var(--color-muted)}.hover\\:bg-muted-foreground\\/10:hover{background-color:#7373731a}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted-foreground\\/10:hover{background-color:color-mix(in oklab,var(--color-muted-foreground)10%,transparent)}}.hover\\:bg-muted\\/50:hover{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/50:hover{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.hover\\:bg-muted\\/80:hover{background-color:#f2f2f2cc}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-muted\\/80:hover{background-color:color-mix(in oklab,var(--color-muted)80%,transparent)}}.hover\\:bg-primary\\/90:hover{background-color:#171717e6}@supports (color:color-mix(in lab, red, red)){.hover\\:bg-primary\\/90:hover{background-color:color-mix(in oklab,var(--color-primary)90%,transparent)}}.hover\\:text-foreground:hover{color:var(--color-foreground)}.hover\\:underline:hover{text-decoration-line:underline}.hover\\:shadow-lg:hover{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}}.focus\\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(1px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\\:ring-ring:focus-visible{--tw-ring-color:var(--color-ring)}.focus-visible\\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.focus-visible\\:ring-inset:focus-visible{--tw-ring-inset:inset}.active\\:cursor-grabbing:active{cursor:grabbing}.disabled\\:pointer-events-none:disabled{pointer-events:none}.disabled\\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\\:opacity-50:disabled{opacity:.5}.data-ending-style\\:scale-90[data-ending-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-ending-style\\:opacity-0[data-ending-style]{opacity:0}.data-instant\\:transition-none[data-instant]{transition-property:none}.data-starting-style\\:scale-90[data-starting-style]{--tw-scale-x:90%;--tw-scale-y:90%;--tw-scale-z:90%;scale:var(--tw-scale-x)var(--tw-scale-y)}.data-starting-style\\:opacity-0[data-starting-style]{opacity:0}.data-\\[highlighted\\]\\:bg-muted[data-highlighted]{background-color:var(--color-muted)}.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:#f2f2f280}@supports (color:color-mix(in lab, red, red)){.data-\\[highlighted\\]\\:bg-muted\\/50[data-highlighted]{background-color:color-mix(in oklab,var(--color-muted)50%,transparent)}}.data-\\[highlighted\\]\\:text-foreground[data-highlighted]{color:var(--color-foreground)}@media (prefers-color-scheme:dark){.dark\\:shadow-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dark\\:-outline-offset-1{outline-offset:calc(1px*-1)}}.\\[\\&_svg\\]\\:pointer-events-none svg{pointer-events:none}.\\[\\&_svg\\]\\:size-3\\.5 svg{width:calc(var(--spacing)*3.5);height:calc(var(--spacing)*3.5)}.\\[\\&_svg\\]\\:shrink-0 svg{flex-shrink:0}.\\[\\&\\:\\:-webkit-inner-spin-button\\]\\:appearance-none::-webkit-inner-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-outer-spin-button\\]\\:appearance-none::-webkit-outer-spin-button{appearance:none}.\\[\\&\\:\\:-webkit-scrollbar\\]\\:hidden::-webkit-scrollbar{display:none}}@media (prefers-reduced-motion:reduce){*,:before,:after{transition:none;animation:none}}.lucide{stroke-width:1px}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0))}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@keyframes pulse{50%{opacity:.5}}';
|
|
11
11
|
|
|
12
12
|
// src/portal-container.tsx
|
|
13
13
|
import { jsx } from "react/jsx-runtime";
|
|
@@ -397,10 +397,30 @@ function getSourceFromFiber(fiber) {
|
|
|
397
397
|
if (fromDebugStack?.fileName) return fromDebugStack;
|
|
398
398
|
return null;
|
|
399
399
|
}
|
|
400
|
+
var REACT_FORWARD_REF_TYPE = /* @__PURE__ */ Symbol.for("react.forward_ref");
|
|
401
|
+
var REACT_MEMO_TYPE = /* @__PURE__ */ Symbol.for("react.memo");
|
|
402
|
+
function resolveComponentName(type) {
|
|
403
|
+
let current = type;
|
|
404
|
+
for (let depth = 0; depth < 4 && current != null; depth++) {
|
|
405
|
+
const name = current.displayName || (typeof current === "function" ? current.name : void 0);
|
|
406
|
+
if (name) return name;
|
|
407
|
+
if (typeof current !== "object") return null;
|
|
408
|
+
if (current.$$typeof === REACT_MEMO_TYPE) {
|
|
409
|
+
current = current.type;
|
|
410
|
+
continue;
|
|
411
|
+
}
|
|
412
|
+
if (current.$$typeof === REACT_FORWARD_REF_TYPE) {
|
|
413
|
+
current = current.render;
|
|
414
|
+
continue;
|
|
415
|
+
}
|
|
416
|
+
return null;
|
|
417
|
+
}
|
|
418
|
+
return null;
|
|
419
|
+
}
|
|
400
420
|
function buildFrame(fiber) {
|
|
401
421
|
const type = fiber?.type;
|
|
402
422
|
if (typeof type !== "function" && typeof type !== "object") return null;
|
|
403
|
-
const name = type
|
|
423
|
+
const name = resolveComponentName(type);
|
|
404
424
|
if (!name || name === "Fragment") return null;
|
|
405
425
|
const frame = { name };
|
|
406
426
|
const source = getSourceFromFiber(fiber);
|
|
@@ -472,14 +492,7 @@ function getReactComponentInfo(element) {
|
|
|
472
492
|
}
|
|
473
493
|
return { ...getRenderStack(fiber), elementSourceFile };
|
|
474
494
|
}
|
|
475
|
-
var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set([
|
|
476
|
-
"className",
|
|
477
|
-
"style",
|
|
478
|
-
"children",
|
|
479
|
-
"ref",
|
|
480
|
-
"key",
|
|
481
|
-
"render"
|
|
482
|
-
]);
|
|
495
|
+
var EXCLUDED_PROP_KEYS = /* @__PURE__ */ new Set(["className", "style", "children", "ref", "key", "render"]);
|
|
483
496
|
function serializePropValue(value) {
|
|
484
497
|
if (typeof value === "function") return "[function]";
|
|
485
498
|
if (typeof value === "symbol") return void 0;
|
|
@@ -590,19 +603,7 @@ function classifyComponentFiber(fiber, frames, elementSourceFile) {
|
|
|
590
603
|
return { isComponentPrimitive: false };
|
|
591
604
|
}
|
|
592
605
|
|
|
593
|
-
// src/utils.ts
|
|
594
|
-
function clamp(value, min, max) {
|
|
595
|
-
if (!Number.isFinite(value)) return min;
|
|
596
|
-
if (max < min) return min;
|
|
597
|
-
return Math.max(min, Math.min(max, value));
|
|
598
|
-
}
|
|
599
|
-
function isInputFocused() {
|
|
600
|
-
let active = document.activeElement;
|
|
601
|
-
while (active?.shadowRoot?.activeElement) {
|
|
602
|
-
active = active.shadowRoot.activeElement;
|
|
603
|
-
}
|
|
604
|
-
return active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable;
|
|
605
|
-
}
|
|
606
|
+
// src/utils/computed-styles.ts
|
|
606
607
|
function getComputedStyles(element) {
|
|
607
608
|
const computed = window.getComputedStyle(element);
|
|
608
609
|
return {
|
|
@@ -711,6 +712,255 @@ function getOriginalInlineStyles(element) {
|
|
|
711
712
|
}
|
|
712
713
|
return styles;
|
|
713
714
|
}
|
|
715
|
+
function getComputedTypography(element) {
|
|
716
|
+
const computed = window.getComputedStyle(element);
|
|
717
|
+
let textVerticalAlign = "flex-start";
|
|
718
|
+
if (computed.display === "flex" || computed.display === "inline-flex") {
|
|
719
|
+
const alignItems = computed.alignItems;
|
|
720
|
+
if (alignItems === "center") textVerticalAlign = "center";
|
|
721
|
+
else if (alignItems === "flex-end" || alignItems === "end") textVerticalAlign = "flex-end";
|
|
722
|
+
}
|
|
723
|
+
const lineHeight = computed.lineHeight === "normal" ? {
|
|
724
|
+
numericValue: parseFloat(computed.fontSize) * 1.2,
|
|
725
|
+
unit: "px",
|
|
726
|
+
raw: `${Math.round(parseFloat(computed.fontSize) * 1.2)}px`
|
|
727
|
+
} : parsePropertyValue(computed.lineHeight);
|
|
728
|
+
const fontSize = parseFloat(computed.fontSize);
|
|
729
|
+
let letterSpacing;
|
|
730
|
+
if (computed.letterSpacing === "normal") {
|
|
731
|
+
letterSpacing = { numericValue: 0, unit: "em", raw: "0em" };
|
|
732
|
+
} else {
|
|
733
|
+
const parsed = parsePropertyValue(computed.letterSpacing);
|
|
734
|
+
if (parsed.unit === "px" && fontSize > 0) {
|
|
735
|
+
const emValue = Math.round(parsed.numericValue / fontSize * 100) / 100;
|
|
736
|
+
letterSpacing = { numericValue: emValue, unit: "em", raw: `${emValue}em` };
|
|
737
|
+
} else {
|
|
738
|
+
letterSpacing = parsed;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
return {
|
|
742
|
+
fontFamily: computed.fontFamily,
|
|
743
|
+
fontWeight: computed.fontWeight,
|
|
744
|
+
fontSize: parsePropertyValue(computed.fontSize),
|
|
745
|
+
lineHeight,
|
|
746
|
+
letterSpacing,
|
|
747
|
+
textAlign: computed.textAlign,
|
|
748
|
+
textVerticalAlign
|
|
749
|
+
};
|
|
750
|
+
}
|
|
751
|
+
function getComputedSizing(element) {
|
|
752
|
+
return {
|
|
753
|
+
width: getSizingValue(element, "width"),
|
|
754
|
+
height: getSizingValue(element, "height")
|
|
755
|
+
};
|
|
756
|
+
}
|
|
757
|
+
var TEXT_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
758
|
+
"p",
|
|
759
|
+
"h1",
|
|
760
|
+
"h2",
|
|
761
|
+
"h3",
|
|
762
|
+
"h4",
|
|
763
|
+
"h5",
|
|
764
|
+
"h6",
|
|
765
|
+
"span",
|
|
766
|
+
"label",
|
|
767
|
+
"a",
|
|
768
|
+
"strong",
|
|
769
|
+
"em",
|
|
770
|
+
"small",
|
|
771
|
+
"blockquote",
|
|
772
|
+
"li",
|
|
773
|
+
"td",
|
|
774
|
+
"th",
|
|
775
|
+
"caption",
|
|
776
|
+
"figcaption",
|
|
777
|
+
"legend",
|
|
778
|
+
"dt",
|
|
779
|
+
"dd",
|
|
780
|
+
"abbr",
|
|
781
|
+
"cite",
|
|
782
|
+
"code",
|
|
783
|
+
"pre"
|
|
784
|
+
]);
|
|
785
|
+
function hasDirectNonWhitespaceText(element) {
|
|
786
|
+
return Array.from(element.childNodes).some(
|
|
787
|
+
(node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
|
|
788
|
+
);
|
|
789
|
+
}
|
|
790
|
+
var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
|
|
791
|
+
function isVisibleBorderSide(side) {
|
|
792
|
+
return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
|
|
793
|
+
}
|
|
794
|
+
function hasVisibleOutline(computed) {
|
|
795
|
+
return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
|
|
796
|
+
}
|
|
797
|
+
function parseVisibleColor(value, fallbackCurrentColor) {
|
|
798
|
+
const raw = value.trim();
|
|
799
|
+
const lowered = raw.toLowerCase();
|
|
800
|
+
if (!raw || lowered === "none" || lowered === "transparent") {
|
|
801
|
+
return null;
|
|
802
|
+
}
|
|
803
|
+
const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
|
|
804
|
+
const parsed = parseColorValue(resolved);
|
|
805
|
+
if (parsed.alpha <= 0) {
|
|
806
|
+
return null;
|
|
807
|
+
}
|
|
808
|
+
return parsed;
|
|
809
|
+
}
|
|
810
|
+
function addUniqueColor(colors, color) {
|
|
811
|
+
if (!color) return;
|
|
812
|
+
colors.set(`${color.hex}:${color.alpha}`, color);
|
|
813
|
+
}
|
|
814
|
+
function isTextRenderingFormControl(element) {
|
|
815
|
+
if (element instanceof HTMLTextAreaElement) return true;
|
|
816
|
+
if (element instanceof HTMLSelectElement) return true;
|
|
817
|
+
if (element instanceof HTMLButtonElement) return true;
|
|
818
|
+
if (element instanceof HTMLInputElement) {
|
|
819
|
+
const textlessInputTypes = /* @__PURE__ */ new Set([
|
|
820
|
+
"hidden",
|
|
821
|
+
"checkbox",
|
|
822
|
+
"radio",
|
|
823
|
+
"range",
|
|
824
|
+
"color",
|
|
825
|
+
"file",
|
|
826
|
+
"image"
|
|
827
|
+
]);
|
|
828
|
+
return !textlessInputTypes.has(element.type.toLowerCase());
|
|
829
|
+
}
|
|
830
|
+
return false;
|
|
831
|
+
}
|
|
832
|
+
function hasRenderableTextNode(element) {
|
|
833
|
+
if (element.isContentEditable) return true;
|
|
834
|
+
if (isTextRenderingFormControl(element)) return true;
|
|
835
|
+
if (!element.textContent?.trim()) return false;
|
|
836
|
+
if (hasDirectNonWhitespaceText(element)) return true;
|
|
837
|
+
const tagName = element.tagName.toLowerCase();
|
|
838
|
+
return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
|
|
839
|
+
}
|
|
840
|
+
function getComputedBoxShadow(element) {
|
|
841
|
+
const computed = window.getComputedStyle(element);
|
|
842
|
+
const value = computed.boxShadow.trim();
|
|
843
|
+
return value || "none";
|
|
844
|
+
}
|
|
845
|
+
function getComputedColorStyles(element) {
|
|
846
|
+
const computed = window.getComputedStyle(element);
|
|
847
|
+
const borderSides = [
|
|
848
|
+
{
|
|
849
|
+
style: computed.borderTopStyle,
|
|
850
|
+
width: computed.borderTopWidth,
|
|
851
|
+
color: computed.borderTopColor
|
|
852
|
+
},
|
|
853
|
+
{
|
|
854
|
+
style: computed.borderRightStyle,
|
|
855
|
+
width: computed.borderRightWidth,
|
|
856
|
+
color: computed.borderRightColor
|
|
857
|
+
},
|
|
858
|
+
{
|
|
859
|
+
style: computed.borderBottomStyle,
|
|
860
|
+
width: computed.borderBottomWidth,
|
|
861
|
+
color: computed.borderBottomColor
|
|
862
|
+
},
|
|
863
|
+
{
|
|
864
|
+
style: computed.borderLeftStyle,
|
|
865
|
+
width: computed.borderLeftWidth,
|
|
866
|
+
color: computed.borderLeftColor
|
|
867
|
+
}
|
|
868
|
+
];
|
|
869
|
+
const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
|
|
870
|
+
const hasBorder = Boolean(visibleBorderSide);
|
|
871
|
+
const hasOutline = hasVisibleOutline(computed);
|
|
872
|
+
return {
|
|
873
|
+
backgroundColor: parseColorValue(computed.backgroundColor),
|
|
874
|
+
color: parseColorValue(computed.color),
|
|
875
|
+
borderColor: hasBorder && visibleBorderSide ? parseColorValue(visibleBorderSide.color) : TRANSPARENT_COLOR,
|
|
876
|
+
outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
|
|
877
|
+
};
|
|
878
|
+
}
|
|
879
|
+
function getSelectionColors(element) {
|
|
880
|
+
const uniqueColors = /* @__PURE__ */ new Map();
|
|
881
|
+
const queue = [element];
|
|
882
|
+
for (let index = 0; index < queue.length; index++) {
|
|
883
|
+
const node = queue[index];
|
|
884
|
+
const computed = window.getComputedStyle(node);
|
|
885
|
+
if (computed.display === "none") {
|
|
886
|
+
continue;
|
|
887
|
+
}
|
|
888
|
+
const isVisibilityHidden = computed.visibility === "hidden" || computed.visibility === "collapse";
|
|
889
|
+
const currentTextColor = computed.color;
|
|
890
|
+
if (!isVisibilityHidden) {
|
|
891
|
+
addUniqueColor(uniqueColors, parseVisibleColor(computed.backgroundColor));
|
|
892
|
+
if (node instanceof HTMLElement && hasRenderableTextNode(node)) {
|
|
893
|
+
addUniqueColor(uniqueColors, parseVisibleColor(currentTextColor));
|
|
894
|
+
}
|
|
895
|
+
const borderSides = [
|
|
896
|
+
{
|
|
897
|
+
style: computed.borderTopStyle,
|
|
898
|
+
width: computed.borderTopWidth,
|
|
899
|
+
color: computed.borderTopColor
|
|
900
|
+
},
|
|
901
|
+
{
|
|
902
|
+
style: computed.borderRightStyle,
|
|
903
|
+
width: computed.borderRightWidth,
|
|
904
|
+
color: computed.borderRightColor
|
|
905
|
+
},
|
|
906
|
+
{
|
|
907
|
+
style: computed.borderBottomStyle,
|
|
908
|
+
width: computed.borderBottomWidth,
|
|
909
|
+
color: computed.borderBottomColor
|
|
910
|
+
},
|
|
911
|
+
{
|
|
912
|
+
style: computed.borderLeftStyle,
|
|
913
|
+
width: computed.borderLeftWidth,
|
|
914
|
+
color: computed.borderLeftColor
|
|
915
|
+
}
|
|
916
|
+
];
|
|
917
|
+
for (const side of borderSides) {
|
|
918
|
+
if (!isVisibleBorderSide(side)) continue;
|
|
919
|
+
addUniqueColor(uniqueColors, parseVisibleColor(side.color, currentTextColor));
|
|
920
|
+
}
|
|
921
|
+
if (hasVisibleOutline(computed)) {
|
|
922
|
+
addUniqueColor(uniqueColors, parseVisibleColor(computed.outlineColor, currentTextColor));
|
|
923
|
+
}
|
|
924
|
+
if (node instanceof SVGElement) {
|
|
925
|
+
const fillColor = parseVisibleColor(computed.getPropertyValue("fill"), currentTextColor) ?? parseVisibleColor(node.getAttribute("fill") ?? "", currentTextColor);
|
|
926
|
+
const strokeColor = parseVisibleColor(computed.getPropertyValue("stroke"), currentTextColor) ?? parseVisibleColor(node.getAttribute("stroke") ?? "", currentTextColor);
|
|
927
|
+
addUniqueColor(uniqueColors, fillColor);
|
|
928
|
+
addUniqueColor(uniqueColors, strokeColor);
|
|
929
|
+
}
|
|
930
|
+
}
|
|
931
|
+
for (const child of node.children) {
|
|
932
|
+
queue.push(child);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
return Array.from(uniqueColors.values());
|
|
936
|
+
}
|
|
937
|
+
function getAllComputedStyles(element) {
|
|
938
|
+
const { spacing, borderRadius, flex } = getComputedStyles(element);
|
|
939
|
+
return {
|
|
940
|
+
spacing,
|
|
941
|
+
borderRadius,
|
|
942
|
+
border: getComputedBorderStyles(element),
|
|
943
|
+
flex,
|
|
944
|
+
sizing: getComputedSizing(element),
|
|
945
|
+
color: getComputedColorStyles(element),
|
|
946
|
+
boxShadow: getComputedBoxShadow(element),
|
|
947
|
+
typography: getComputedTypography(element)
|
|
948
|
+
};
|
|
949
|
+
}
|
|
950
|
+
|
|
951
|
+
// src/utils.ts
|
|
952
|
+
function clamp(value, min, max) {
|
|
953
|
+
if (!Number.isFinite(value)) return min;
|
|
954
|
+
if (max < min) return min;
|
|
955
|
+
return Math.max(min, Math.min(max, value));
|
|
956
|
+
}
|
|
957
|
+
function isInputFocused() {
|
|
958
|
+
let active = document.activeElement;
|
|
959
|
+
while (active?.shadowRoot?.activeElement) {
|
|
960
|
+
active = active.shadowRoot.activeElement;
|
|
961
|
+
}
|
|
962
|
+
return active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement || active instanceof HTMLElement && active.isContentEditable;
|
|
963
|
+
}
|
|
714
964
|
var spacingScale = { 0: "0", 1: "px", 2: "0.5", 4: "1", 8: "2", 12: "3", 16: "4", 20: "5", 24: "6", 32: "8" };
|
|
715
965
|
var tailwindClassMap = {
|
|
716
966
|
padding: { prefix: "p", scale: spacingScale },
|
|
@@ -1037,7 +1287,7 @@ var typographyPropertyToCSSMap = {
|
|
|
1037
1287
|
textAlign: "text-align",
|
|
1038
1288
|
textVerticalAlign: "align-items"
|
|
1039
1289
|
};
|
|
1040
|
-
var
|
|
1290
|
+
var TEXT_ELEMENT_TAGS2 = /* @__PURE__ */ new Set([
|
|
1041
1291
|
"p",
|
|
1042
1292
|
"h1",
|
|
1043
1293
|
"h2",
|
|
@@ -1065,55 +1315,23 @@ var TEXT_ELEMENT_TAGS = /* @__PURE__ */ new Set([
|
|
|
1065
1315
|
"code",
|
|
1066
1316
|
"pre"
|
|
1067
1317
|
]);
|
|
1068
|
-
function
|
|
1318
|
+
function hasDirectNonWhitespaceText2(element) {
|
|
1069
1319
|
return Array.from(element.childNodes).some(
|
|
1070
1320
|
(node) => node.nodeType === Node.TEXT_NODE && Boolean(node.textContent?.trim())
|
|
1071
1321
|
);
|
|
1072
1322
|
}
|
|
1073
1323
|
function isTextElement2(element) {
|
|
1074
1324
|
const tagName = element.tagName.toLowerCase();
|
|
1075
|
-
if (
|
|
1076
|
-
return true;
|
|
1077
|
-
}
|
|
1078
|
-
if (
|
|
1079
|
-
return true;
|
|
1080
|
-
}
|
|
1081
|
-
if (element.children.length === 0 && element.textContent?.trim()) {
|
|
1082
|
-
return true;
|
|
1083
|
-
}
|
|
1084
|
-
return false;
|
|
1085
|
-
}
|
|
1086
|
-
function getComputedTypography(element) {
|
|
1087
|
-
const computed = window.getComputedStyle(element);
|
|
1088
|
-
let textVerticalAlign = "flex-start";
|
|
1089
|
-
if (computed.display === "flex" || computed.display === "inline-flex") {
|
|
1090
|
-
const alignItems = computed.alignItems;
|
|
1091
|
-
if (alignItems === "center") textVerticalAlign = "center";
|
|
1092
|
-
else if (alignItems === "flex-end" || alignItems === "end") textVerticalAlign = "flex-end";
|
|
1093
|
-
}
|
|
1094
|
-
const lineHeight = computed.lineHeight === "normal" ? { numericValue: parseFloat(computed.fontSize) * 1.2, unit: "px", raw: `${Math.round(parseFloat(computed.fontSize) * 1.2)}px` } : parsePropertyValue(computed.lineHeight);
|
|
1095
|
-
const fontSize = parseFloat(computed.fontSize);
|
|
1096
|
-
let letterSpacing;
|
|
1097
|
-
if (computed.letterSpacing === "normal") {
|
|
1098
|
-
letterSpacing = { numericValue: 0, unit: "em", raw: "0em" };
|
|
1099
|
-
} else {
|
|
1100
|
-
const parsed = parsePropertyValue(computed.letterSpacing);
|
|
1101
|
-
if (parsed.unit === "px" && fontSize > 0) {
|
|
1102
|
-
const emValue = Math.round(parsed.numericValue / fontSize * 100) / 100;
|
|
1103
|
-
letterSpacing = { numericValue: emValue, unit: "em", raw: `${emValue}em` };
|
|
1104
|
-
} else {
|
|
1105
|
-
letterSpacing = parsed;
|
|
1106
|
-
}
|
|
1107
|
-
}
|
|
1108
|
-
return {
|
|
1109
|
-
fontFamily: computed.fontFamily,
|
|
1110
|
-
fontWeight: computed.fontWeight,
|
|
1111
|
-
fontSize: parsePropertyValue(computed.fontSize),
|
|
1112
|
-
lineHeight,
|
|
1113
|
-
letterSpacing,
|
|
1114
|
-
textAlign: computed.textAlign,
|
|
1115
|
-
textVerticalAlign
|
|
1116
|
-
};
|
|
1325
|
+
if (TEXT_ELEMENT_TAGS2.has(tagName)) {
|
|
1326
|
+
return true;
|
|
1327
|
+
}
|
|
1328
|
+
if (hasDirectNonWhitespaceText2(element)) {
|
|
1329
|
+
return true;
|
|
1330
|
+
}
|
|
1331
|
+
if (element.children.length === 0 && element.textContent?.trim()) {
|
|
1332
|
+
return true;
|
|
1333
|
+
}
|
|
1334
|
+
return false;
|
|
1117
1335
|
}
|
|
1118
1336
|
function detectSizingMode(element, dimension) {
|
|
1119
1337
|
const computed = window.getComputedStyle(element);
|
|
@@ -1162,12 +1380,6 @@ function getSizingValue(element, dimension) {
|
|
|
1162
1380
|
}
|
|
1163
1381
|
};
|
|
1164
1382
|
}
|
|
1165
|
-
function getComputedSizing(element) {
|
|
1166
|
-
return {
|
|
1167
|
-
width: getSizingValue(element, "width"),
|
|
1168
|
-
height: getSizingValue(element, "height")
|
|
1169
|
-
};
|
|
1170
|
-
}
|
|
1171
1383
|
function sizingValueToCSS(sizing) {
|
|
1172
1384
|
switch (sizing.mode) {
|
|
1173
1385
|
case "fill":
|
|
@@ -1276,134 +1488,6 @@ function parseColorValue(cssValue) {
|
|
|
1276
1488
|
}
|
|
1277
1489
|
return parseNamedColor(raw);
|
|
1278
1490
|
}
|
|
1279
|
-
var TRANSPARENT_COLOR = { hex: "000000", alpha: 0, raw: "transparent" };
|
|
1280
|
-
function isVisibleBorderSide(side) {
|
|
1281
|
-
return side.style !== "none" && side.style !== "hidden" && parseFloat(side.width) > 0;
|
|
1282
|
-
}
|
|
1283
|
-
function hasVisibleOutline(computed) {
|
|
1284
|
-
return computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0;
|
|
1285
|
-
}
|
|
1286
|
-
function parseVisibleColor(value, fallbackCurrentColor) {
|
|
1287
|
-
const raw = value.trim();
|
|
1288
|
-
const lowered = raw.toLowerCase();
|
|
1289
|
-
if (!raw || lowered === "none" || lowered === "transparent") {
|
|
1290
|
-
return null;
|
|
1291
|
-
}
|
|
1292
|
-
const resolved = /^currentcolor$/i.test(raw) ? fallbackCurrentColor ?? raw : raw;
|
|
1293
|
-
const parsed = parseColorValue(resolved);
|
|
1294
|
-
if (parsed.alpha <= 0) {
|
|
1295
|
-
return null;
|
|
1296
|
-
}
|
|
1297
|
-
return parsed;
|
|
1298
|
-
}
|
|
1299
|
-
function addUniqueColor(colors, color) {
|
|
1300
|
-
if (!color) return;
|
|
1301
|
-
colors.set(`${color.hex}:${color.alpha}`, color);
|
|
1302
|
-
}
|
|
1303
|
-
function isTextRenderingFormControl(element) {
|
|
1304
|
-
if (element instanceof HTMLTextAreaElement) return true;
|
|
1305
|
-
if (element instanceof HTMLSelectElement) return true;
|
|
1306
|
-
if (element instanceof HTMLButtonElement) return true;
|
|
1307
|
-
if (element instanceof HTMLInputElement) {
|
|
1308
|
-
const textlessInputTypes = /* @__PURE__ */ new Set([
|
|
1309
|
-
"hidden",
|
|
1310
|
-
"checkbox",
|
|
1311
|
-
"radio",
|
|
1312
|
-
"range",
|
|
1313
|
-
"color",
|
|
1314
|
-
"file",
|
|
1315
|
-
"image"
|
|
1316
|
-
]);
|
|
1317
|
-
return !textlessInputTypes.has(element.type.toLowerCase());
|
|
1318
|
-
}
|
|
1319
|
-
return false;
|
|
1320
|
-
}
|
|
1321
|
-
function hasRenderableTextNode(element) {
|
|
1322
|
-
if (element.isContentEditable) return true;
|
|
1323
|
-
if (isTextRenderingFormControl(element)) return true;
|
|
1324
|
-
if (!element.textContent?.trim()) return false;
|
|
1325
|
-
if (hasDirectNonWhitespaceText(element)) return true;
|
|
1326
|
-
const tagName = element.tagName.toLowerCase();
|
|
1327
|
-
return TEXT_ELEMENT_TAGS.has(tagName) || element.children.length === 0;
|
|
1328
|
-
}
|
|
1329
|
-
function getComputedBoxShadow(element) {
|
|
1330
|
-
const computed = window.getComputedStyle(element);
|
|
1331
|
-
const value = computed.boxShadow.trim();
|
|
1332
|
-
return value || "none";
|
|
1333
|
-
}
|
|
1334
|
-
function getComputedColorStyles(element) {
|
|
1335
|
-
const computed = window.getComputedStyle(element);
|
|
1336
|
-
const borderSides = [
|
|
1337
|
-
{ style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
|
|
1338
|
-
{ style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
|
|
1339
|
-
{ style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
|
|
1340
|
-
{ style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
|
|
1341
|
-
];
|
|
1342
|
-
const visibleBorderSide = borderSides.find((side) => isVisibleBorderSide(side));
|
|
1343
|
-
const hasBorder = Boolean(visibleBorderSide);
|
|
1344
|
-
const hasOutline = hasVisibleOutline(computed);
|
|
1345
|
-
return {
|
|
1346
|
-
backgroundColor: parseColorValue(computed.backgroundColor),
|
|
1347
|
-
color: parseColorValue(computed.color),
|
|
1348
|
-
borderColor: hasBorder && visibleBorderSide ? parseColorValue(visibleBorderSide.color) : TRANSPARENT_COLOR,
|
|
1349
|
-
outlineColor: hasOutline ? parseColorValue(computed.outlineColor) : TRANSPARENT_COLOR
|
|
1350
|
-
};
|
|
1351
|
-
}
|
|
1352
|
-
function getSelectionColors(element) {
|
|
1353
|
-
const uniqueColors = /* @__PURE__ */ new Map();
|
|
1354
|
-
const queue = [element];
|
|
1355
|
-
for (let index = 0; index < queue.length; index++) {
|
|
1356
|
-
const node = queue[index];
|
|
1357
|
-
const computed = window.getComputedStyle(node);
|
|
1358
|
-
if (computed.display === "none") {
|
|
1359
|
-
continue;
|
|
1360
|
-
}
|
|
1361
|
-
const isVisibilityHidden = computed.visibility === "hidden" || computed.visibility === "collapse";
|
|
1362
|
-
const currentTextColor = computed.color;
|
|
1363
|
-
if (!isVisibilityHidden) {
|
|
1364
|
-
addUniqueColor(uniqueColors, parseVisibleColor(computed.backgroundColor));
|
|
1365
|
-
if (node instanceof HTMLElement && hasRenderableTextNode(node)) {
|
|
1366
|
-
addUniqueColor(uniqueColors, parseVisibleColor(currentTextColor));
|
|
1367
|
-
}
|
|
1368
|
-
const borderSides = [
|
|
1369
|
-
{ style: computed.borderTopStyle, width: computed.borderTopWidth, color: computed.borderTopColor },
|
|
1370
|
-
{ style: computed.borderRightStyle, width: computed.borderRightWidth, color: computed.borderRightColor },
|
|
1371
|
-
{ style: computed.borderBottomStyle, width: computed.borderBottomWidth, color: computed.borderBottomColor },
|
|
1372
|
-
{ style: computed.borderLeftStyle, width: computed.borderLeftWidth, color: computed.borderLeftColor }
|
|
1373
|
-
];
|
|
1374
|
-
for (const side of borderSides) {
|
|
1375
|
-
if (!isVisibleBorderSide(side)) continue;
|
|
1376
|
-
addUniqueColor(uniqueColors, parseVisibleColor(side.color, currentTextColor));
|
|
1377
|
-
}
|
|
1378
|
-
if (hasVisibleOutline(computed)) {
|
|
1379
|
-
addUniqueColor(uniqueColors, parseVisibleColor(computed.outlineColor, currentTextColor));
|
|
1380
|
-
}
|
|
1381
|
-
if (node instanceof SVGElement) {
|
|
1382
|
-
const fillColor = parseVisibleColor(computed.getPropertyValue("fill"), currentTextColor) ?? parseVisibleColor(node.getAttribute("fill") ?? "", currentTextColor);
|
|
1383
|
-
const strokeColor = parseVisibleColor(computed.getPropertyValue("stroke"), currentTextColor) ?? parseVisibleColor(node.getAttribute("stroke") ?? "", currentTextColor);
|
|
1384
|
-
addUniqueColor(uniqueColors, fillColor);
|
|
1385
|
-
addUniqueColor(uniqueColors, strokeColor);
|
|
1386
|
-
}
|
|
1387
|
-
}
|
|
1388
|
-
for (const child of node.children) {
|
|
1389
|
-
queue.push(child);
|
|
1390
|
-
}
|
|
1391
|
-
}
|
|
1392
|
-
return Array.from(uniqueColors.values());
|
|
1393
|
-
}
|
|
1394
|
-
function getAllComputedStyles(element) {
|
|
1395
|
-
const { spacing, borderRadius, flex } = getComputedStyles(element);
|
|
1396
|
-
return {
|
|
1397
|
-
spacing,
|
|
1398
|
-
borderRadius,
|
|
1399
|
-
border: getComputedBorderStyles(element),
|
|
1400
|
-
flex,
|
|
1401
|
-
sizing: getComputedSizing(element),
|
|
1402
|
-
color: getComputedColorStyles(element),
|
|
1403
|
-
boxShadow: getComputedBoxShadow(element),
|
|
1404
|
-
typography: getComputedTypography(element)
|
|
1405
|
-
};
|
|
1406
|
-
}
|
|
1407
1491
|
var colorPropertyToCSSMap = {
|
|
1408
1492
|
backgroundColor: "background-color",
|
|
1409
1493
|
color: "color",
|
|
@@ -1858,7 +1942,7 @@ function findChildAtPoint(parent, clientX, clientY) {
|
|
|
1858
1942
|
return clientX >= r.left && clientX <= r.right && clientY >= r.top && clientY <= r.bottom;
|
|
1859
1943
|
});
|
|
1860
1944
|
if (hit) return hit;
|
|
1861
|
-
if (children.length === 1 && !
|
|
1945
|
+
if (children.length === 1 && !hasDirectNonWhitespaceText2(parent)) return children[0];
|
|
1862
1946
|
return null;
|
|
1863
1947
|
}
|
|
1864
1948
|
function elementFromPointWithoutOverlays(x, y) {
|
|
@@ -2412,7 +2496,7 @@ function buildElementContext(locator) {
|
|
|
2412
2496
|
return buildLocatorContextLines(locator).join("\n");
|
|
2413
2497
|
}
|
|
2414
2498
|
function hasSessionEditChanges(edit) {
|
|
2415
|
-
return Object.keys(edit.pendingStyles).length > 0 || Boolean(edit.textEdit) || Boolean(edit.move);
|
|
2499
|
+
return Object.keys(edit.pendingStyles).length > 0 || Boolean(edit.textEdit) || Boolean(edit.move) || Boolean(edit.deleted);
|
|
2416
2500
|
}
|
|
2417
2501
|
function partitionMultiSelectedEdits(elements, sessionEditsRef) {
|
|
2418
2502
|
const editsWithChanges = [];
|
|
@@ -2934,7 +3018,7 @@ function buildMoveEntries(edits) {
|
|
|
2934
3018
|
let noopMoveCount = 0;
|
|
2935
3019
|
for (const edit of edits) {
|
|
2936
3020
|
const move = edit.move;
|
|
2937
|
-
if (!move) continue;
|
|
3021
|
+
if (!move || edit.deleted) continue;
|
|
2938
3022
|
const subject = buildAnchorRef(
|
|
2939
3023
|
getElementDisplayName(edit.element) || edit.locator.tagName,
|
|
2940
3024
|
edit.locator.domSelector,
|
|
@@ -3093,19 +3177,22 @@ function getExportContentProfile(edits, comments, movePlanOrContext) {
|
|
|
3093
3177
|
hasCssEdits: edits.some((e) => Object.keys(e.pendingStyles).length > 0),
|
|
3094
3178
|
hasTextEdits: edits.some((e) => e.textEdit != null),
|
|
3095
3179
|
hasMoves: moveOpCount > 0,
|
|
3096
|
-
hasComments: comments.length > 0
|
|
3180
|
+
hasComments: comments.length > 0,
|
|
3181
|
+
hasDeletes: edits.some((e) => e.deleted)
|
|
3097
3182
|
};
|
|
3098
3183
|
}
|
|
3099
3184
|
function buildExportInstruction(profile) {
|
|
3100
3185
|
const { hasCssEdits, hasTextEdits, hasMoves, hasComments } = profile;
|
|
3101
|
-
|
|
3102
|
-
if (!hasCssEdits && !hasTextEdits && !hasMoves)
|
|
3186
|
+
const hasDeletes = Boolean(profile.hasDeletes);
|
|
3187
|
+
if (!hasCssEdits && !hasTextEdits && !hasMoves && !hasComments && !hasDeletes) return "";
|
|
3188
|
+
if (!hasCssEdits && !hasTextEdits && !hasMoves && !hasDeletes) {
|
|
3103
3189
|
return hasComments ? "Address this feedback on the UI. Use the provided source location and selector to find each element in the codebase." : "";
|
|
3104
3190
|
}
|
|
3105
3191
|
const parts = [];
|
|
3106
3192
|
if (hasCssEdits) parts.push("Apply the CSS changes to the targeted elements using the project's existing styling approach (Tailwind, CSS modules, etc.). Map values to existing CSS variables, design tokens, or utility classes already used in the project whenever possible.");
|
|
3107
3193
|
if (hasTextEdits) parts.push("Update the text content as specified.");
|
|
3108
3194
|
if (hasMoves) parts.push("Implement the move plan below directly in source code. For `structural_move`, reorder/reparent elements using the target anchors. For `layout_refactor`, apply the listed flex/grid refactor steps. Do NOT simulate movement with absolute positioning, left/top offsets, transform, or margin hacks.");
|
|
3195
|
+
if (hasDeletes) parts.push("Delete the elements marked for deletion from the source code \u2014 remove their markup/JSX (and any now-dead props, handlers, or imports they solely used).");
|
|
3109
3196
|
if (hasComments) parts.push("Address the comments on the relevant elements.");
|
|
3110
3197
|
return `${parts.join(" ")} Use the provided source locations, selectors, and context HTML to locate each element in the codebase.`;
|
|
3111
3198
|
}
|
|
@@ -3140,6 +3227,13 @@ function buildSessionExport(edits, comments = [], options) {
|
|
|
3140
3227
|
blocks.push(planLines.join("\n"));
|
|
3141
3228
|
}
|
|
3142
3229
|
for (const edit of edits) {
|
|
3230
|
+
if (edit.deleted) {
|
|
3231
|
+
const lines = buildLocatorContextLines(edit.locator);
|
|
3232
|
+
lines.push("");
|
|
3233
|
+
lines.push("action: delete this element \u2014 remove it from the source");
|
|
3234
|
+
blocks.push(lines.join("\n"));
|
|
3235
|
+
continue;
|
|
3236
|
+
}
|
|
3143
3237
|
const moveIntent = getMoveIntentForEdit(edit, planContext);
|
|
3144
3238
|
const hasMove = Boolean(moveIntent);
|
|
3145
3239
|
const hasStyleOrText = Object.keys(edit.pendingStyles).length > 0 || edit.textEdit != null;
|
|
@@ -4048,6 +4142,7 @@ function useSessionManager({
|
|
|
4048
4142
|
sessionEditsRef,
|
|
4049
4143
|
removedSessionEditsRef,
|
|
4050
4144
|
undoStackRef,
|
|
4145
|
+
onElementInsertedRef,
|
|
4051
4146
|
pushUndo,
|
|
4052
4147
|
setState,
|
|
4053
4148
|
setSessionEditCount
|
|
@@ -4244,27 +4339,48 @@ function useSessionManager({
|
|
|
4244
4339
|
selectElement(firstChild);
|
|
4245
4340
|
}
|
|
4246
4341
|
}, [getSelectableChild, selectElement]);
|
|
4342
|
+
const centerElementOnBody = React3.useCallback((element, size) => {
|
|
4343
|
+
const bodyRect = document.body.getBoundingClientRect();
|
|
4344
|
+
const scaleX = document.body.offsetWidth > 0 ? bodyRect.width / document.body.offsetWidth : 1;
|
|
4345
|
+
const scaleY = document.body.offsetHeight > 0 ? bodyRect.height / document.body.offsetHeight : 1;
|
|
4346
|
+
const fallbackWidth = size?.width ?? element.offsetWidth ?? 0;
|
|
4347
|
+
const fallbackHeight = size?.height ?? element.offsetHeight ?? 0;
|
|
4348
|
+
const measuredRect = element.getBoundingClientRect();
|
|
4349
|
+
const width = measuredRect.width || fallbackWidth;
|
|
4350
|
+
const height = measuredRect.height || fallbackHeight;
|
|
4351
|
+
const left = Math.round((window.innerWidth / 2 - bodyRect.left) / scaleX - width / 2);
|
|
4352
|
+
const top = Math.round((window.innerHeight / 2 - bodyRect.top) / scaleY - height / 2);
|
|
4353
|
+
element.style.left = `${left}px`;
|
|
4354
|
+
element.style.top = `${top}px`;
|
|
4355
|
+
}, []);
|
|
4247
4356
|
const insertElement = React3.useCallback((kind) => {
|
|
4248
4357
|
if (!stateRef.current.editModeActive) return;
|
|
4249
4358
|
saveCurrentToSession();
|
|
4250
4359
|
const restoreSelection = buildSelectionSnapshot();
|
|
4251
4360
|
const selectedEl = stateRef.current.selectedElement;
|
|
4252
|
-
const
|
|
4253
|
-
const
|
|
4254
|
-
const
|
|
4255
|
-
const element = document.createElement("div");
|
|
4361
|
+
const insertsAsSibling = kind === "frame" || kind === "text";
|
|
4362
|
+
const hasSelection = insertsAsSibling && selectedEl !== null && selectedEl !== document.body && selectedEl.parentElement !== null;
|
|
4363
|
+
const element = document.createElement(kind === "text" ? "p" : "div");
|
|
4256
4364
|
element.id = nextGeneratedCanvasId(kind);
|
|
4257
4365
|
element.setAttribute(GENERATED_CANVAS_NODE_ATTR, kind);
|
|
4258
|
-
element.style.width = `${width}px`;
|
|
4259
|
-
element.style.height = `${height}px`;
|
|
4260
4366
|
element.style.boxSizing = "border-box";
|
|
4261
4367
|
if (kind === "frame") {
|
|
4368
|
+
element.style.width = "100px";
|
|
4369
|
+
element.style.height = "100px";
|
|
4262
4370
|
element.style.background = "#F5F5F5";
|
|
4263
4371
|
element.style.border = "1px solid #E0E0E0";
|
|
4264
|
-
} else {
|
|
4372
|
+
} else if (kind === "div") {
|
|
4373
|
+
element.style.width = "160px";
|
|
4374
|
+
element.style.height = "96px";
|
|
4265
4375
|
element.style.borderRadius = "12px";
|
|
4266
4376
|
element.style.border = "1px solid rgba(13, 153, 255, 0.35)";
|
|
4267
4377
|
element.style.background = "rgba(13, 153, 255, 0.08)";
|
|
4378
|
+
} else {
|
|
4379
|
+
element.textContent = "Text";
|
|
4380
|
+
element.style.display = "inline-block";
|
|
4381
|
+
element.style.margin = "0";
|
|
4382
|
+
element.style.minHeight = "24px";
|
|
4383
|
+
element.style.textAlign = "center";
|
|
4268
4384
|
}
|
|
4269
4385
|
if (hasSelection) {
|
|
4270
4386
|
const insertionParent = selectedEl.parentElement;
|
|
@@ -4275,16 +4391,22 @@ function useSessionManager({
|
|
|
4275
4391
|
insertionParent.appendChild(element);
|
|
4276
4392
|
}
|
|
4277
4393
|
} else {
|
|
4278
|
-
const bodyRect = document.body.getBoundingClientRect();
|
|
4279
|
-
const scaleX = document.body.offsetWidth > 0 ? bodyRect.width / document.body.offsetWidth : 1;
|
|
4280
|
-
const scaleY = document.body.offsetHeight > 0 ? bodyRect.height / document.body.offsetHeight : 1;
|
|
4281
|
-
const left = Math.round((window.innerWidth / 2 - bodyRect.left) / scaleX - width / 2);
|
|
4282
|
-
const top = Math.round((window.innerHeight / 2 - bodyRect.top) / scaleY - height / 2);
|
|
4283
4394
|
element.style.position = "absolute";
|
|
4284
|
-
element.style.left = `${left}px`;
|
|
4285
|
-
element.style.top = `${top}px`;
|
|
4286
4395
|
element.style.zIndex = "1";
|
|
4287
|
-
|
|
4396
|
+
if (kind === "text") {
|
|
4397
|
+
element.style.left = "0px";
|
|
4398
|
+
element.style.top = "0px";
|
|
4399
|
+
element.style.visibility = "hidden";
|
|
4400
|
+
document.body.appendChild(element);
|
|
4401
|
+
centerElementOnBody(element);
|
|
4402
|
+
element.style.visibility = "";
|
|
4403
|
+
} else {
|
|
4404
|
+
centerElementOnBody(
|
|
4405
|
+
element,
|
|
4406
|
+
kind === "frame" ? { width: 100, height: 100 } : { width: 160, height: 96 }
|
|
4407
|
+
);
|
|
4408
|
+
document.body.appendChild(element);
|
|
4409
|
+
}
|
|
4288
4410
|
}
|
|
4289
4411
|
pushUndo({
|
|
4290
4412
|
type: "structure",
|
|
@@ -4299,7 +4421,8 @@ function useSessionManager({
|
|
|
4299
4421
|
primaryElement: element,
|
|
4300
4422
|
pushUndo: false
|
|
4301
4423
|
});
|
|
4302
|
-
|
|
4424
|
+
onElementInsertedRef.current?.(kind, element);
|
|
4425
|
+
}, [applySelection, buildSelectionSnapshot, centerElementOnBody, onElementInsertedRef, pushUndo, saveCurrentToSession, stateRef]);
|
|
4303
4426
|
const groupSelection = React3.useCallback(() => {
|
|
4304
4427
|
const selected = getSanitizedSelection(stateRef.current.selectedElements);
|
|
4305
4428
|
if (selected.length < 2) return;
|
|
@@ -4395,9 +4518,17 @@ function useSessionManager({
|
|
|
4395
4518
|
}));
|
|
4396
4519
|
const sessionSnapshots = /* @__PURE__ */ new Map();
|
|
4397
4520
|
for (const el of selected) {
|
|
4398
|
-
const
|
|
4399
|
-
|
|
4400
|
-
sessionEditsRef.current.
|
|
4521
|
+
const existing = sessionEditsRef.current.get(el);
|
|
4522
|
+
sessionSnapshots.set(el, existing ?? null);
|
|
4523
|
+
sessionEditsRef.current.set(el, existing ? { ...existing, deleted: true } : {
|
|
4524
|
+
element: el,
|
|
4525
|
+
locator: getElementLocator(el),
|
|
4526
|
+
originalStyles: {},
|
|
4527
|
+
pendingStyles: {},
|
|
4528
|
+
move: null,
|
|
4529
|
+
textEdit: null,
|
|
4530
|
+
deleted: true
|
|
4531
|
+
});
|
|
4401
4532
|
}
|
|
4402
4533
|
syncSessionItemCount();
|
|
4403
4534
|
for (const { element } of snapshots) {
|
|
@@ -4418,7 +4549,8 @@ function useSessionManager({
|
|
|
4418
4549
|
}
|
|
4419
4550
|
}
|
|
4420
4551
|
for (const [el, edit] of sessionSnapshots) {
|
|
4421
|
-
sessionEditsRef.current.set(el, edit);
|
|
4552
|
+
if (edit) sessionEditsRef.current.set(el, edit);
|
|
4553
|
+
else sessionEditsRef.current.delete(el);
|
|
4422
4554
|
}
|
|
4423
4555
|
syncSessionItemCount();
|
|
4424
4556
|
}
|
|
@@ -4809,7 +4941,7 @@ function useSessionManager({
|
|
|
4809
4941
|
saveCurrentToSession();
|
|
4810
4942
|
const edits = [];
|
|
4811
4943
|
for (const edit of sessionEditsRef.current.values()) {
|
|
4812
|
-
if (!edit.element.isConnected) {
|
|
4944
|
+
if (!edit.element.isConnected && !edit.deleted) {
|
|
4813
4945
|
sessionEditsRef.current.delete(edit.element);
|
|
4814
4946
|
continue;
|
|
4815
4947
|
}
|
|
@@ -4978,6 +5110,7 @@ ${exportMarkdown}`);
|
|
|
4978
5110
|
|
|
4979
5111
|
// src/use-text-and-comments.ts
|
|
4980
5112
|
import * as React4 from "react";
|
|
5113
|
+
var GENERATED_CANVAS_NODE_ATTR2 = "data-made-refine-canvas-node";
|
|
4981
5114
|
function clampUnit(value) {
|
|
4982
5115
|
if (!Number.isFinite(value)) return 0;
|
|
4983
5116
|
return Math.max(0, Math.min(1, value));
|
|
@@ -5013,6 +5146,94 @@ function useTextAndComments({
|
|
|
5013
5146
|
editingElement.style.outlineOffset = "";
|
|
5014
5147
|
editingElement.style.cursor = originalCursor;
|
|
5015
5148
|
editingElement.blur();
|
|
5149
|
+
const isGeneratedTextElement = editingElement.getAttribute(GENERATED_CANVAS_NODE_ATTR2) === "text";
|
|
5150
|
+
const shouldDeleteGeneratedText = isGeneratedTextElement && newText.trim().length === 0;
|
|
5151
|
+
if (shouldDeleteGeneratedText) {
|
|
5152
|
+
const parent = editingElement.parentElement;
|
|
5153
|
+
const nextSibling = editingElement.nextSibling;
|
|
5154
|
+
const current = stateRef.current;
|
|
5155
|
+
const removedComments = current.comments.filter((comment) => comment.element === editingElement);
|
|
5156
|
+
const removedCommentIds = new Set(removedComments.map((comment) => comment.id));
|
|
5157
|
+
const remainingComments = current.comments.filter((comment) => comment.element !== editingElement);
|
|
5158
|
+
const restoredActiveCommentId = current.activeCommentId && removedCommentIds.has(current.activeCommentId) ? current.activeCommentId : null;
|
|
5159
|
+
const existingSessionEdit = existing ? {
|
|
5160
|
+
...existing,
|
|
5161
|
+
originalStyles: { ...existing.originalStyles },
|
|
5162
|
+
pendingStyles: { ...existing.pendingStyles },
|
|
5163
|
+
move: existing.move ? { ...existing.move } : null,
|
|
5164
|
+
textEdit: existing.textEdit ? { ...existing.textEdit } : null
|
|
5165
|
+
} : null;
|
|
5166
|
+
const restoreSelection = {
|
|
5167
|
+
isOpen: current.isOpen,
|
|
5168
|
+
selectedElement: current.selectedElement,
|
|
5169
|
+
selectedElements: [...current.selectedElements],
|
|
5170
|
+
selectionAnchorElement: current.selectionAnchorElement,
|
|
5171
|
+
originalStyles: { ...current.originalStyles },
|
|
5172
|
+
pendingStyles: { ...current.pendingStyles }
|
|
5173
|
+
};
|
|
5174
|
+
sessionEditsRef.current.delete(editingElement);
|
|
5175
|
+
if (editingElement.isConnected) {
|
|
5176
|
+
editingElement.remove();
|
|
5177
|
+
}
|
|
5178
|
+
pushUndo({
|
|
5179
|
+
type: "structure",
|
|
5180
|
+
restoreSelection,
|
|
5181
|
+
undo: () => {
|
|
5182
|
+
editingElement.textContent = previousText;
|
|
5183
|
+
if (!editingElement.isConnected && parent?.isConnected) {
|
|
5184
|
+
if (nextSibling && nextSibling.parentNode === parent) {
|
|
5185
|
+
parent.insertBefore(editingElement, nextSibling);
|
|
5186
|
+
} else {
|
|
5187
|
+
parent.appendChild(editingElement);
|
|
5188
|
+
}
|
|
5189
|
+
}
|
|
5190
|
+
if (existingSessionEdit) {
|
|
5191
|
+
sessionEditsRef.current.set(editingElement, existingSessionEdit);
|
|
5192
|
+
}
|
|
5193
|
+
setState((prev) => ({
|
|
5194
|
+
...prev,
|
|
5195
|
+
comments: current.comments,
|
|
5196
|
+
activeCommentId: restoredActiveCommentId ?? prev.activeCommentId
|
|
5197
|
+
}));
|
|
5198
|
+
syncSessionItemCount(current.comments);
|
|
5199
|
+
}
|
|
5200
|
+
});
|
|
5201
|
+
syncSessionItemCount(remainingComments);
|
|
5202
|
+
setState((prev) => {
|
|
5203
|
+
const selectionContainsElement = prev.selectedElement === editingElement || prev.selectionAnchorElement === editingElement || prev.selectedElements.includes(editingElement);
|
|
5204
|
+
if (!selectionContainsElement) {
|
|
5205
|
+
return prev.textEditingElement === editingElement ? {
|
|
5206
|
+
...prev,
|
|
5207
|
+
comments: prev.comments.filter((comment) => comment.element !== editingElement),
|
|
5208
|
+
activeCommentId: prev.activeCommentId && removedCommentIds.has(prev.activeCommentId) ? null : prev.activeCommentId,
|
|
5209
|
+
textEditingElement: null
|
|
5210
|
+
} : prev;
|
|
5211
|
+
}
|
|
5212
|
+
return {
|
|
5213
|
+
...prev,
|
|
5214
|
+
isOpen: false,
|
|
5215
|
+
selectedElement: null,
|
|
5216
|
+
selectedElements: [],
|
|
5217
|
+
selectionAnchorElement: null,
|
|
5218
|
+
elementInfo: null,
|
|
5219
|
+
computedSpacing: null,
|
|
5220
|
+
computedBorderRadius: null,
|
|
5221
|
+
computedBorder: null,
|
|
5222
|
+
computedFlex: null,
|
|
5223
|
+
computedSizing: null,
|
|
5224
|
+
computedColor: null,
|
|
5225
|
+
computedBoxShadow: null,
|
|
5226
|
+
computedTypography: null,
|
|
5227
|
+
isComponentPrimitive: false,
|
|
5228
|
+
comments: remainingComments,
|
|
5229
|
+
activeCommentId: restoredActiveCommentId ? null : prev.activeCommentId,
|
|
5230
|
+
originalStyles: {},
|
|
5231
|
+
pendingStyles: {},
|
|
5232
|
+
textEditingElement: null
|
|
5233
|
+
};
|
|
5234
|
+
});
|
|
5235
|
+
return;
|
|
5236
|
+
}
|
|
5016
5237
|
if (newText !== previousText) {
|
|
5017
5238
|
pushUndo({ type: "textEdit", element: editingElement, originalText, previousText });
|
|
5018
5239
|
removedSessionEditsRef.current.delete(editingElement);
|
|
@@ -5531,28 +5752,30 @@ async function toClientResponse(response) {
|
|
|
5531
5752
|
const data = await readJsonRecord(response);
|
|
5532
5753
|
const bodyOk = data?.ok;
|
|
5533
5754
|
const parsedOk = typeof bodyOk === "boolean" ? bodyOk : response.ok;
|
|
5755
|
+
const ok = parsedOk && response.ok;
|
|
5534
5756
|
return {
|
|
5535
|
-
ok
|
|
5536
|
-
id: readString(data, "id") ?? ""
|
|
5757
|
+
ok,
|
|
5758
|
+
id: readString(data, "id") ?? "",
|
|
5759
|
+
...!ok ? { errorKind: "rejected" } : {}
|
|
5537
5760
|
};
|
|
5538
5761
|
}
|
|
5539
5762
|
async function postWithSessionToken(path, payload) {
|
|
5540
5763
|
const idempotencyKey = createIdempotencyKey();
|
|
5541
5764
|
let session = await bootstrapSession();
|
|
5542
|
-
if (!session) return { ok: false, id: "" };
|
|
5765
|
+
if (!session) return { ok: false, id: "", errorKind: "network" };
|
|
5543
5766
|
let response;
|
|
5544
5767
|
try {
|
|
5545
5768
|
response = await sendAnnotationRequest(session, path, payload, idempotencyKey);
|
|
5546
5769
|
} catch {
|
|
5547
|
-
return { ok: false, id: "" };
|
|
5770
|
+
return { ok: false, id: "", errorKind: "network" };
|
|
5548
5771
|
}
|
|
5549
5772
|
if (response.status === 401 || response.status === 403) {
|
|
5550
5773
|
session = await refreshSessionToken(session) ?? await bootstrapSession(true);
|
|
5551
|
-
if (!session) return { ok: false, id: "" };
|
|
5774
|
+
if (!session) return { ok: false, id: "", errorKind: "network" };
|
|
5552
5775
|
try {
|
|
5553
5776
|
response = await sendAnnotationRequest(session, path, payload, idempotencyKey);
|
|
5554
5777
|
} catch {
|
|
5555
|
-
return { ok: false, id: "" };
|
|
5778
|
+
return { ok: false, id: "", errorKind: "network" };
|
|
5556
5779
|
}
|
|
5557
5780
|
}
|
|
5558
5781
|
return toClientResponse(response);
|
|
@@ -5605,8 +5828,10 @@ function buildLocatorPayload(locator) {
|
|
|
5605
5828
|
}
|
|
5606
5829
|
function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrentToSession, removeSessionEdit, deleteComment }) {
|
|
5607
5830
|
const [agentAvailable, setAgentAvailable] = React5.useState(false);
|
|
5831
|
+
const [lastSendFailure, setLastSendFailure] = React5.useState(null);
|
|
5608
5832
|
const isMountedRef = React5.useRef(true);
|
|
5609
5833
|
React5.useEffect(() => {
|
|
5834
|
+
isMountedRef.current = true;
|
|
5610
5835
|
return () => {
|
|
5611
5836
|
isMountedRef.current = false;
|
|
5612
5837
|
};
|
|
@@ -5663,7 +5888,7 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5663
5888
|
const resolvedPlanContext = movePlanContext ?? buildMovePlanContext(editsForPlan);
|
|
5664
5889
|
const includeBatchMoveEnvelope = Boolean(options?.includeBatchMoveEnvelope && sessionEdit.move);
|
|
5665
5890
|
const isBatchSend = Boolean(allEdits && allEdits.length > 1);
|
|
5666
|
-
const exportMarkdown = sessionEdit.move ? buildSessionExport(
|
|
5891
|
+
const exportMarkdown = sessionEdit.move || sessionEdit.deleted ? buildSessionExport(
|
|
5667
5892
|
includeBatchMoveEnvelope ? editsForPlan : [sessionEdit],
|
|
5668
5893
|
[],
|
|
5669
5894
|
{
|
|
@@ -5679,7 +5904,7 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5679
5904
|
}));
|
|
5680
5905
|
const moveIntent = sessionEdit.move ? getMoveIntentForEdit(sessionEdit, resolvedPlanContext) : null;
|
|
5681
5906
|
const movePlan = includeBatchMoveEnvelope ? resolvedPlanContext.movePlan : null;
|
|
5682
|
-
const hasMeaningfulPayload = changes.length > 0 || sessionEdit.textEdit != null || moveIntent != null;
|
|
5907
|
+
const hasMeaningfulPayload = changes.length > 0 || sessionEdit.textEdit != null || moveIntent != null || Boolean(sessionEdit.deleted);
|
|
5683
5908
|
if (!hasMeaningfulPayload) return true;
|
|
5684
5909
|
const profile = getExportContentProfile(
|
|
5685
5910
|
[sessionEdit],
|
|
@@ -5693,17 +5918,44 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5693
5918
|
textChange: sessionEdit.textEdit ?? null,
|
|
5694
5919
|
moveIntent,
|
|
5695
5920
|
...movePlan ? { movePlan } : {},
|
|
5921
|
+
...sessionEdit.deleted ? { deleted: true } : {},
|
|
5696
5922
|
exportMarkdown: withInstruction(profile, exportMarkdown)
|
|
5697
5923
|
});
|
|
5698
5924
|
if (result.ok) {
|
|
5699
5925
|
removeSessionEdit(sessionEdit.element);
|
|
5926
|
+
updateAgentAvailability(true);
|
|
5927
|
+
} else {
|
|
5928
|
+
const kind = result.errorKind === "network" ? "unreachable" : "rejected";
|
|
5929
|
+
updateAgentAvailability(result.errorKind === "network" ? false : true);
|
|
5930
|
+
if (options?._isBatchCall) {
|
|
5931
|
+
options._batchFailKinds?.push(result.errorKind ?? "rejected");
|
|
5932
|
+
} else if (isMountedRef.current) {
|
|
5933
|
+
setLastSendFailure({
|
|
5934
|
+
reason: kind,
|
|
5935
|
+
failedEditElements: [sessionEdit.element],
|
|
5936
|
+
failedCommentIds: [],
|
|
5937
|
+
at: Date.now()
|
|
5938
|
+
});
|
|
5939
|
+
}
|
|
5700
5940
|
}
|
|
5701
|
-
return
|
|
5702
|
-
} catch {
|
|
5703
|
-
|
|
5941
|
+
return result.ok;
|
|
5942
|
+
} catch (err) {
|
|
5943
|
+
updateAgentAvailability(false);
|
|
5944
|
+
if (options?._isBatchCall) {
|
|
5945
|
+
throw err;
|
|
5946
|
+
}
|
|
5947
|
+
if (isMountedRef.current) {
|
|
5948
|
+
setLastSendFailure({
|
|
5949
|
+
reason: "unreachable",
|
|
5950
|
+
failedEditElements: [sessionEdit.element],
|
|
5951
|
+
failedCommentIds: [],
|
|
5952
|
+
at: Date.now()
|
|
5953
|
+
});
|
|
5954
|
+
}
|
|
5955
|
+
return false;
|
|
5704
5956
|
}
|
|
5705
5957
|
}, [updateAgentAvailability, removeSessionEdit]);
|
|
5706
|
-
const sendSessionCommentToAgent = React5.useCallback(async (comment) => {
|
|
5958
|
+
const sendSessionCommentToAgent = React5.useCallback(async (comment, _options) => {
|
|
5707
5959
|
const exportMarkdown = buildCommentExport(comment.locator, comment.text, comment.replies);
|
|
5708
5960
|
const commentProfile = { hasCssEdits: false, hasTextEdits: false, hasMoves: false, hasComments: true };
|
|
5709
5961
|
try {
|
|
@@ -5715,13 +5967,40 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5715
5967
|
});
|
|
5716
5968
|
if (result.ok) {
|
|
5717
5969
|
deleteComment(comment.id);
|
|
5970
|
+
updateAgentAvailability(true);
|
|
5971
|
+
} else {
|
|
5972
|
+
const kind = result.errorKind === "network" ? "unreachable" : "rejected";
|
|
5973
|
+
updateAgentAvailability(result.errorKind === "network" ? false : true);
|
|
5974
|
+
if (_options?._isBatchCall) {
|
|
5975
|
+
_options._batchFailKinds?.push(result.errorKind ?? "rejected");
|
|
5976
|
+
} else if (isMountedRef.current) {
|
|
5977
|
+
setLastSendFailure({
|
|
5978
|
+
reason: kind,
|
|
5979
|
+
failedEditElements: [],
|
|
5980
|
+
failedCommentIds: [comment.id],
|
|
5981
|
+
at: Date.now()
|
|
5982
|
+
});
|
|
5983
|
+
}
|
|
5718
5984
|
}
|
|
5719
|
-
return
|
|
5720
|
-
} catch {
|
|
5721
|
-
|
|
5985
|
+
return result.ok;
|
|
5986
|
+
} catch (err) {
|
|
5987
|
+
updateAgentAvailability(false);
|
|
5988
|
+
if (_options?._isBatchCall) {
|
|
5989
|
+
throw err;
|
|
5990
|
+
}
|
|
5991
|
+
if (isMountedRef.current) {
|
|
5992
|
+
setLastSendFailure({
|
|
5993
|
+
reason: "unreachable",
|
|
5994
|
+
failedEditElements: [],
|
|
5995
|
+
failedCommentIds: [comment.id],
|
|
5996
|
+
at: Date.now()
|
|
5997
|
+
});
|
|
5998
|
+
}
|
|
5999
|
+
return false;
|
|
5722
6000
|
}
|
|
5723
6001
|
}, [updateAgentAvailability, deleteComment]);
|
|
5724
6002
|
const sendEditToAgent2 = React5.useCallback(async () => {
|
|
6003
|
+
if (isMountedRef.current) setLastSendFailure(null);
|
|
5725
6004
|
const current = stateRef.current;
|
|
5726
6005
|
if (current.selectedElements.length > 1) {
|
|
5727
6006
|
saveCurrentToSession();
|
|
@@ -5756,9 +6035,28 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5756
6035
|
removeSessionEdit(el);
|
|
5757
6036
|
}
|
|
5758
6037
|
}
|
|
6038
|
+
updateAgentAvailability(true);
|
|
6039
|
+
} else {
|
|
6040
|
+
updateAgentAvailability(result.errorKind === "network" ? false : true);
|
|
6041
|
+
if (isMountedRef.current) {
|
|
6042
|
+
setLastSendFailure({
|
|
6043
|
+
reason: result.errorKind === "network" ? "unreachable" : "rejected",
|
|
6044
|
+
failedEditElements: editsWithChanges.map((e) => e.element),
|
|
6045
|
+
failedCommentIds: [],
|
|
6046
|
+
at: Date.now()
|
|
6047
|
+
});
|
|
6048
|
+
}
|
|
5759
6049
|
}
|
|
5760
|
-
return
|
|
6050
|
+
return result.ok;
|
|
5761
6051
|
} catch {
|
|
6052
|
+
if (isMountedRef.current) {
|
|
6053
|
+
setLastSendFailure({
|
|
6054
|
+
reason: "unreachable",
|
|
6055
|
+
failedEditElements: editsWithChanges.map((e) => e.element),
|
|
6056
|
+
failedCommentIds: [],
|
|
6057
|
+
at: Date.now()
|
|
6058
|
+
});
|
|
6059
|
+
}
|
|
5762
6060
|
return updateAgentAvailability(false);
|
|
5763
6061
|
}
|
|
5764
6062
|
}
|
|
@@ -5781,11 +6079,13 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5781
6079
|
return sendSessionEditToAgent(editToSend);
|
|
5782
6080
|
}, [canSendEditToAgent, sendSessionEditToAgent, saveCurrentToSession]);
|
|
5783
6081
|
const sendCommentToAgent2 = React5.useCallback(async (id) => {
|
|
6082
|
+
if (isMountedRef.current) setLastSendFailure(null);
|
|
5784
6083
|
const comment = stateRef.current.comments.find((c) => c.id === id);
|
|
5785
6084
|
if (!comment) return false;
|
|
5786
6085
|
return sendSessionCommentToAgent(comment);
|
|
5787
6086
|
}, [sendSessionCommentToAgent]);
|
|
5788
6087
|
const sendAllSessionItemsToAgent = React5.useCallback(async () => {
|
|
6088
|
+
if (isMountedRef.current) setLastSendFailure(null);
|
|
5789
6089
|
const items = getSessionItems();
|
|
5790
6090
|
const current = stateRef.current;
|
|
5791
6091
|
const contextOnlyBlocks = getContextOnlyBlocks(current.selectedElements, items);
|
|
@@ -5794,25 +6094,44 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5794
6094
|
const movePlanContext = buildMovePlanContext(allEdits);
|
|
5795
6095
|
let moveEnvelopeSent = false;
|
|
5796
6096
|
let allSucceeded = true;
|
|
6097
|
+
const failedEditElements = [];
|
|
6098
|
+
const failedCommentIds = [];
|
|
6099
|
+
let anyThrown = false;
|
|
6100
|
+
const batchFailKinds = [];
|
|
5797
6101
|
for (const item of items) {
|
|
5798
6102
|
let succeeded;
|
|
5799
6103
|
if (item.type === "edit") {
|
|
5800
6104
|
const hasMoveIntent = Boolean(item.edit.move && getMoveIntentForEdit(item.edit, movePlanContext));
|
|
5801
6105
|
const includeBatchMoveEnvelope = hasMoveIntent && !moveEnvelopeSent;
|
|
5802
|
-
|
|
5803
|
-
|
|
5804
|
-
|
|
5805
|
-
|
|
5806
|
-
|
|
5807
|
-
|
|
6106
|
+
try {
|
|
6107
|
+
succeeded = await sendSessionEditToAgent(
|
|
6108
|
+
item.edit,
|
|
6109
|
+
allEdits,
|
|
6110
|
+
movePlanContext,
|
|
6111
|
+
{ includeBatchMoveEnvelope, _isBatchCall: true, _batchFailKinds: batchFailKinds }
|
|
6112
|
+
);
|
|
6113
|
+
if (!succeeded) failedEditElements.push(item.edit.element);
|
|
6114
|
+
} catch {
|
|
6115
|
+
succeeded = false;
|
|
6116
|
+
anyThrown = true;
|
|
6117
|
+
failedEditElements.push(item.edit.element);
|
|
6118
|
+
}
|
|
5808
6119
|
if (includeBatchMoveEnvelope) moveEnvelopeSent = true;
|
|
5809
6120
|
} else {
|
|
5810
|
-
|
|
6121
|
+
try {
|
|
6122
|
+
succeeded = await sendSessionCommentToAgent(item.comment, { _isBatchCall: true, _batchFailKinds: batchFailKinds });
|
|
6123
|
+
if (!succeeded) failedCommentIds.push(item.comment.id);
|
|
6124
|
+
} catch {
|
|
6125
|
+
succeeded = false;
|
|
6126
|
+
anyThrown = true;
|
|
6127
|
+
failedCommentIds.push(item.comment.id);
|
|
6128
|
+
}
|
|
5811
6129
|
}
|
|
5812
6130
|
if (!succeeded) {
|
|
5813
6131
|
allSucceeded = false;
|
|
5814
6132
|
}
|
|
5815
6133
|
}
|
|
6134
|
+
let contextBlockFailed = false;
|
|
5816
6135
|
if (contextOnlyBlocks.length > 0) {
|
|
5817
6136
|
const primaryEl = current.selectedElements.find(
|
|
5818
6137
|
(el) => el.isConnected && !allEdits.some((e) => e.element === el)
|
|
@@ -5826,16 +6145,39 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems, saveCurrent
|
|
|
5826
6145
|
moveIntent: null,
|
|
5827
6146
|
exportMarkdown: contextOnlyBlocks.join("\n\n")
|
|
5828
6147
|
});
|
|
5829
|
-
if (
|
|
6148
|
+
if (result.ok) {
|
|
6149
|
+
updateAgentAvailability(true);
|
|
6150
|
+
} else {
|
|
6151
|
+
updateAgentAvailability(result.errorKind === "network" ? false : true);
|
|
6152
|
+
allSucceeded = false;
|
|
6153
|
+
contextBlockFailed = true;
|
|
6154
|
+
}
|
|
5830
6155
|
} catch {
|
|
6156
|
+
updateAgentAvailability(false);
|
|
5831
6157
|
allSucceeded = false;
|
|
6158
|
+
anyThrown = true;
|
|
6159
|
+
contextBlockFailed = true;
|
|
5832
6160
|
}
|
|
5833
6161
|
}
|
|
5834
6162
|
}
|
|
6163
|
+
if (!allSucceeded && isMountedRef.current) {
|
|
6164
|
+
const reason = anyThrown || batchFailKinds.includes("network") ? "unreachable" : "rejected";
|
|
6165
|
+
setLastSendFailure({
|
|
6166
|
+
reason,
|
|
6167
|
+
failedEditElements,
|
|
6168
|
+
failedCommentIds,
|
|
6169
|
+
at: Date.now()
|
|
6170
|
+
});
|
|
6171
|
+
}
|
|
5835
6172
|
return allSucceeded;
|
|
5836
|
-
}, [getSessionItems, sendSessionCommentToAgent, sendSessionEditToAgent]);
|
|
6173
|
+
}, [getSessionItems, sendSessionCommentToAgent, sendSessionEditToAgent, updateAgentAvailability]);
|
|
6174
|
+
const clearSendFailure = React5.useCallback(() => {
|
|
6175
|
+
if (isMountedRef.current) setLastSendFailure(null);
|
|
6176
|
+
}, []);
|
|
5837
6177
|
return {
|
|
5838
6178
|
agentAvailable,
|
|
6179
|
+
lastSendFailure,
|
|
6180
|
+
clearSendFailure,
|
|
5839
6181
|
canSendEditToAgent,
|
|
5840
6182
|
sendEditToAgent: sendEditToAgent2,
|
|
5841
6183
|
sendCommentToAgent: sendCommentToAgent2,
|
|
@@ -5882,7 +6224,9 @@ function useKeyboardShortcuts({
|
|
|
5882
6224
|
const s = stateRef.current;
|
|
5883
6225
|
const undoShortcutPressed = usesMetaForUndo ? e.metaKey && !e.ctrlKey && !e.altKey : e.ctrlKey && !e.metaKey && !e.altKey;
|
|
5884
6226
|
if (undoShortcutPressed && e.key === "z" && !e.shiftKey) {
|
|
6227
|
+
if (!s.editModeActive) return;
|
|
5885
6228
|
if (s.textEditingElement) return;
|
|
6229
|
+
if (isInputFocused()) return;
|
|
5886
6230
|
e.preventDefault();
|
|
5887
6231
|
undo();
|
|
5888
6232
|
return;
|
|
@@ -5937,6 +6281,11 @@ function useKeyboardShortcuts({
|
|
|
5937
6281
|
insertElement("frame");
|
|
5938
6282
|
return;
|
|
5939
6283
|
}
|
|
6284
|
+
if (lowerKey === "t") {
|
|
6285
|
+
e.preventDefault();
|
|
6286
|
+
insertElement("text");
|
|
6287
|
+
return;
|
|
6288
|
+
}
|
|
5940
6289
|
if (lowerKey === "d") {
|
|
5941
6290
|
e.preventDefault();
|
|
5942
6291
|
insertElement("div");
|
|
@@ -6599,6 +6948,10 @@ function DirectEditProvider({ children }) {
|
|
|
6599
6948
|
const undoStackRef = React8.useRef([]);
|
|
6600
6949
|
const sessionEditsRef = React8.useRef(/* @__PURE__ */ new Map());
|
|
6601
6950
|
const removedSessionEditsRef = React8.useRef(/* @__PURE__ */ new WeakSet());
|
|
6951
|
+
const commentDraftTextRef = React8.useRef("");
|
|
6952
|
+
const commentDraftBlockedHandlerRef = React8.useRef(null);
|
|
6953
|
+
const onElementInsertedRef = React8.useRef(null);
|
|
6954
|
+
const textInsertRafRef = React8.useRef(null);
|
|
6602
6955
|
const [sessionEditCount, setSessionEditCount] = React8.useState(0);
|
|
6603
6956
|
const stateRef = React8.useRef(state);
|
|
6604
6957
|
React8.useEffect(() => {
|
|
@@ -6633,12 +6986,13 @@ function DirectEditProvider({ children }) {
|
|
|
6633
6986
|
clearSessionEdits,
|
|
6634
6987
|
groupSelection,
|
|
6635
6988
|
deleteSelection,
|
|
6636
|
-
insertElement
|
|
6989
|
+
insertElement: insertElementBase
|
|
6637
6990
|
} = useSessionManager({
|
|
6638
6991
|
stateRef,
|
|
6639
6992
|
sessionEditsRef,
|
|
6640
6993
|
removedSessionEditsRef,
|
|
6641
6994
|
undoStackRef,
|
|
6995
|
+
onElementInsertedRef,
|
|
6642
6996
|
pushUndo,
|
|
6643
6997
|
setState,
|
|
6644
6998
|
setSessionEditCount
|
|
@@ -6688,6 +7042,41 @@ function DirectEditProvider({ children }) {
|
|
|
6688
7042
|
syncSessionItemCount,
|
|
6689
7043
|
setState
|
|
6690
7044
|
});
|
|
7045
|
+
React8.useEffect(() => {
|
|
7046
|
+
onElementInsertedRef.current = (kind, element) => {
|
|
7047
|
+
if (kind === "text") {
|
|
7048
|
+
if (textInsertRafRef.current) {
|
|
7049
|
+
cancelAnimationFrame(textInsertRafRef.current);
|
|
7050
|
+
}
|
|
7051
|
+
textInsertRafRef.current = requestAnimationFrame(() => {
|
|
7052
|
+
textInsertRafRef.current = null;
|
|
7053
|
+
if (element.isConnected) {
|
|
7054
|
+
startTextEditing(element);
|
|
7055
|
+
}
|
|
7056
|
+
});
|
|
7057
|
+
}
|
|
7058
|
+
};
|
|
7059
|
+
return () => {
|
|
7060
|
+
if (textInsertRafRef.current) {
|
|
7061
|
+
cancelAnimationFrame(textInsertRafRef.current);
|
|
7062
|
+
textInsertRafRef.current = null;
|
|
7063
|
+
}
|
|
7064
|
+
onElementInsertedRef.current = null;
|
|
7065
|
+
};
|
|
7066
|
+
}, [startTextEditing]);
|
|
7067
|
+
const setCommentDraftText = React8.useCallback((text) => {
|
|
7068
|
+
commentDraftTextRef.current = text;
|
|
7069
|
+
}, []);
|
|
7070
|
+
const setCommentDraftBlockedHandler = React8.useCallback((handler) => {
|
|
7071
|
+
commentDraftBlockedHandlerRef.current = handler;
|
|
7072
|
+
}, []);
|
|
7073
|
+
const hasPendingCommentDraft = React8.useCallback(() => {
|
|
7074
|
+
const activeCommentId = stateRef.current.activeCommentId;
|
|
7075
|
+
if (!activeCommentId) return false;
|
|
7076
|
+
const active = stateRef.current.comments.find((comment) => comment.id === activeCommentId);
|
|
7077
|
+
if (!active) return false;
|
|
7078
|
+
return active.text.trim().length === 0 && commentDraftTextRef.current.trim().length > 0;
|
|
7079
|
+
}, []);
|
|
6691
7080
|
const { toggleCanvas, enterCanvas, exitCanvas, setCanvasZoom, fitCanvasToViewport, zoomCanvasTo100 } = useCanvas({
|
|
6692
7081
|
stateRef,
|
|
6693
7082
|
setState
|
|
@@ -6824,6 +7213,8 @@ function DirectEditProvider({ children }) {
|
|
|
6824
7213
|
}, [state.editModeActive]);
|
|
6825
7214
|
const {
|
|
6826
7215
|
agentAvailable,
|
|
7216
|
+
lastSendFailure,
|
|
7217
|
+
clearSendFailure,
|
|
6827
7218
|
canSendEditToAgent,
|
|
6828
7219
|
sendEditToAgent: sendEditToAgent2,
|
|
6829
7220
|
sendCommentToAgent: sendCommentToAgent2,
|
|
@@ -6850,6 +7241,16 @@ function DirectEditProvider({ children }) {
|
|
|
6850
7241
|
} catch {
|
|
6851
7242
|
}
|
|
6852
7243
|
}, []);
|
|
7244
|
+
const insertElement = React8.useCallback((kind) => {
|
|
7245
|
+
if (hasPendingCommentDraft()) {
|
|
7246
|
+
commentDraftBlockedHandlerRef.current?.();
|
|
7247
|
+
return;
|
|
7248
|
+
}
|
|
7249
|
+
if (stateRef.current.textEditingElement) {
|
|
7250
|
+
commitTextEditing();
|
|
7251
|
+
}
|
|
7252
|
+
insertElementBase(kind);
|
|
7253
|
+
}, [commitTextEditing, hasPendingCommentDraft, insertElementBase, stateRef]);
|
|
6853
7254
|
useKeyboardShortcuts({
|
|
6854
7255
|
stateRef,
|
|
6855
7256
|
toggleEditMode,
|
|
@@ -6879,9 +7280,10 @@ function DirectEditProvider({ children }) {
|
|
|
6879
7280
|
const stateContextValue = React8.useMemo(() => ({
|
|
6880
7281
|
...state,
|
|
6881
7282
|
agentAvailable,
|
|
7283
|
+
lastSendFailure,
|
|
6882
7284
|
sessionEditCount,
|
|
6883
7285
|
multiSelectContextCount
|
|
6884
|
-
}), [agentAvailable, state, sessionEditCount, multiSelectContextCount]);
|
|
7286
|
+
}), [agentAvailable, lastSendFailure, state, sessionEditCount, multiSelectContextCount]);
|
|
6885
7287
|
const actionsContextValue = React8.useMemo(() => ({
|
|
6886
7288
|
selectElement,
|
|
6887
7289
|
selectElements,
|
|
@@ -6904,6 +7306,7 @@ function DirectEditProvider({ children }) {
|
|
|
6904
7306
|
updateTypographyProperty,
|
|
6905
7307
|
resetToOriginal,
|
|
6906
7308
|
exportEdits,
|
|
7309
|
+
clearSendFailure,
|
|
6907
7310
|
canSendEditToAgent,
|
|
6908
7311
|
sendEditToAgent: sendEditToAgent2,
|
|
6909
7312
|
sendAllSessionItemsToAgent,
|
|
@@ -6928,6 +7331,8 @@ function DirectEditProvider({ children }) {
|
|
|
6928
7331
|
removeSessionEdit,
|
|
6929
7332
|
startTextEditing,
|
|
6930
7333
|
commitTextEditing,
|
|
7334
|
+
setCommentDraftText,
|
|
7335
|
+
setCommentDraftBlockedHandler,
|
|
6931
7336
|
groupSelection,
|
|
6932
7337
|
deleteSelection,
|
|
6933
7338
|
insertElement,
|
|
@@ -6957,6 +7362,7 @@ function DirectEditProvider({ children }) {
|
|
|
6957
7362
|
updateTypographyProperty,
|
|
6958
7363
|
resetToOriginal,
|
|
6959
7364
|
exportEdits,
|
|
7365
|
+
clearSendFailure,
|
|
6960
7366
|
canSendEditToAgent,
|
|
6961
7367
|
sendEditToAgent2,
|
|
6962
7368
|
sendAllSessionItemsToAgent,
|
|
@@ -6981,6 +7387,8 @@ function DirectEditProvider({ children }) {
|
|
|
6981
7387
|
removeSessionEdit,
|
|
6982
7388
|
startTextEditing,
|
|
6983
7389
|
commitTextEditing,
|
|
7390
|
+
setCommentDraftText,
|
|
7391
|
+
setCommentDraftBlockedHandler,
|
|
6984
7392
|
groupSelection,
|
|
6985
7393
|
deleteSelection,
|
|
6986
7394
|
insertElement,
|
|
@@ -7332,10 +7740,223 @@ function createDragInteractionGuard() {
|
|
|
7332
7740
|
};
|
|
7333
7741
|
}
|
|
7334
7742
|
return {
|
|
7335
|
-
activate,
|
|
7336
|
-
deactivate
|
|
7743
|
+
activate,
|
|
7744
|
+
deactivate
|
|
7745
|
+
};
|
|
7746
|
+
}
|
|
7747
|
+
|
|
7748
|
+
// src/utils/resize-geometry.ts
|
|
7749
|
+
function toFinite(value, fallback) {
|
|
7750
|
+
if (!Number.isFinite(value)) return fallback;
|
|
7751
|
+
return value;
|
|
7752
|
+
}
|
|
7753
|
+
function multiplyMatrix(left, right) {
|
|
7754
|
+
return {
|
|
7755
|
+
a: left.a * right.a + left.c * right.b,
|
|
7756
|
+
b: left.b * right.a + left.d * right.b,
|
|
7757
|
+
c: left.a * right.c + left.c * right.d,
|
|
7758
|
+
d: left.b * right.c + left.d * right.d
|
|
7759
|
+
};
|
|
7760
|
+
}
|
|
7761
|
+
function splitTransformArgs(raw) {
|
|
7762
|
+
return raw.trim().replace(/,/g, " ").split(/\s+/).filter(Boolean);
|
|
7763
|
+
}
|
|
7764
|
+
function parseAngleRadians(value) {
|
|
7765
|
+
const numeric = Number.parseFloat(value);
|
|
7766
|
+
if (!Number.isFinite(numeric)) return 0;
|
|
7767
|
+
const unit = value.trim().replace(String(numeric), "").trim().toLowerCase();
|
|
7768
|
+
switch (unit) {
|
|
7769
|
+
case "rad":
|
|
7770
|
+
return numeric;
|
|
7771
|
+
case "turn":
|
|
7772
|
+
return numeric * Math.PI * 2;
|
|
7773
|
+
case "grad":
|
|
7774
|
+
return numeric * Math.PI / 200;
|
|
7775
|
+
case "deg":
|
|
7776
|
+
case "":
|
|
7777
|
+
default:
|
|
7778
|
+
return numeric * Math.PI / 180;
|
|
7779
|
+
}
|
|
7780
|
+
}
|
|
7781
|
+
function parseTransformFunction(name, rawArgs) {
|
|
7782
|
+
const args = splitTransformArgs(rawArgs);
|
|
7783
|
+
switch (name.toLowerCase()) {
|
|
7784
|
+
case "matrix": {
|
|
7785
|
+
if (args.length < 4) return null;
|
|
7786
|
+
const [a, b, c, d] = args.map(Number.parseFloat);
|
|
7787
|
+
if (![a, b, c, d].every(Number.isFinite)) return null;
|
|
7788
|
+
return { a, b, c, d };
|
|
7789
|
+
}
|
|
7790
|
+
case "matrix3d": {
|
|
7791
|
+
if (args.length < 16) return null;
|
|
7792
|
+
const values = args.map(Number.parseFloat);
|
|
7793
|
+
if (!values.every(Number.isFinite)) return null;
|
|
7794
|
+
return { a: values[0], b: values[1], c: values[4], d: values[5] };
|
|
7795
|
+
}
|
|
7796
|
+
case "scale": {
|
|
7797
|
+
const scaleX = Number.parseFloat(args[0] ?? "1");
|
|
7798
|
+
const scaleY = Number.parseFloat(args[1] ?? args[0] ?? "1");
|
|
7799
|
+
if (!Number.isFinite(scaleX) || !Number.isFinite(scaleY)) return null;
|
|
7800
|
+
return { a: scaleX, b: 0, c: 0, d: scaleY };
|
|
7801
|
+
}
|
|
7802
|
+
case "scalex": {
|
|
7803
|
+
const scaleX = Number.parseFloat(args[0] ?? "1");
|
|
7804
|
+
if (!Number.isFinite(scaleX)) return null;
|
|
7805
|
+
return { a: scaleX, b: 0, c: 0, d: 1 };
|
|
7806
|
+
}
|
|
7807
|
+
case "scaley": {
|
|
7808
|
+
const scaleY = Number.parseFloat(args[0] ?? "1");
|
|
7809
|
+
if (!Number.isFinite(scaleY)) return null;
|
|
7810
|
+
return { a: 1, b: 0, c: 0, d: scaleY };
|
|
7811
|
+
}
|
|
7812
|
+
case "rotate": {
|
|
7813
|
+
const angle = parseAngleRadians(args[0] ?? "0deg");
|
|
7814
|
+
const cos = Math.cos(angle);
|
|
7815
|
+
const sin = Math.sin(angle);
|
|
7816
|
+
return { a: cos, b: sin, c: -sin, d: cos };
|
|
7817
|
+
}
|
|
7818
|
+
case "translate":
|
|
7819
|
+
case "translatex":
|
|
7820
|
+
case "translatey":
|
|
7821
|
+
return { a: 1, b: 0, c: 0, d: 1 };
|
|
7822
|
+
default:
|
|
7823
|
+
return null;
|
|
7824
|
+
}
|
|
7825
|
+
}
|
|
7826
|
+
function parseTransformMatrix(transform) {
|
|
7827
|
+
const functionPattern = /([a-zA-Z0-9]+)\(([^)]*)\)/g;
|
|
7828
|
+
let matrix = { a: 1, b: 0, c: 0, d: 1 };
|
|
7829
|
+
let matched = false;
|
|
7830
|
+
for (const match of transform.matchAll(functionPattern)) {
|
|
7831
|
+
const next = parseTransformFunction(match[1], match[2]);
|
|
7832
|
+
if (!next) return null;
|
|
7833
|
+
matrix = multiplyMatrix(matrix, next);
|
|
7834
|
+
matched = true;
|
|
7835
|
+
}
|
|
7836
|
+
return matched ? matrix : null;
|
|
7837
|
+
}
|
|
7838
|
+
function scaleFromMatrix(matrix) {
|
|
7839
|
+
return {
|
|
7840
|
+
scaleX: Math.hypot(matrix.a, matrix.b) || 1,
|
|
7841
|
+
scaleY: Math.hypot(matrix.c, matrix.d) || 1
|
|
7842
|
+
};
|
|
7843
|
+
}
|
|
7844
|
+
function getRenderedOffsetScale(element) {
|
|
7845
|
+
const rect = element.getBoundingClientRect();
|
|
7846
|
+
const width = element.offsetWidth;
|
|
7847
|
+
const height = element.offsetHeight;
|
|
7848
|
+
if (width <= 0 || height <= 0 || rect.width <= 0 || rect.height <= 0) return null;
|
|
7849
|
+
return {
|
|
7850
|
+
scaleX: rect.width / width,
|
|
7851
|
+
scaleY: rect.height / height
|
|
7852
|
+
};
|
|
7853
|
+
}
|
|
7854
|
+
function clampSize(value, minSize = 1) {
|
|
7855
|
+
const safeMin = Math.max(1, toFinite(minSize, 1));
|
|
7856
|
+
const safeValue = toFinite(value, safeMin);
|
|
7857
|
+
return Math.max(safeMin, safeValue);
|
|
7858
|
+
}
|
|
7859
|
+
function getElementScale(element) {
|
|
7860
|
+
const transform = getComputedStyle(element).transform;
|
|
7861
|
+
if (!transform || transform === "none") {
|
|
7862
|
+
return getRenderedOffsetScale(element) ?? { scaleX: 1, scaleY: 1 };
|
|
7863
|
+
}
|
|
7864
|
+
let transformMatrix = null;
|
|
7865
|
+
if (typeof DOMMatrix !== "undefined") {
|
|
7866
|
+
try {
|
|
7867
|
+
const matrix = new DOMMatrix(transform);
|
|
7868
|
+
transformMatrix = matrix;
|
|
7869
|
+
} catch {
|
|
7870
|
+
}
|
|
7871
|
+
}
|
|
7872
|
+
transformMatrix = transformMatrix ?? parseTransformMatrix(transform);
|
|
7873
|
+
if (!transformMatrix) return getRenderedOffsetScale(element) ?? { scaleX: 1, scaleY: 1 };
|
|
7874
|
+
const localScale = scaleFromMatrix(transformMatrix);
|
|
7875
|
+
const rect = element.getBoundingClientRect();
|
|
7876
|
+
const width = element.offsetWidth;
|
|
7877
|
+
const height = element.offsetHeight;
|
|
7878
|
+
if (width <= 0 || height <= 0 || rect.width <= 0 || rect.height <= 0) return localScale;
|
|
7879
|
+
const transformedWidth = Math.abs(transformMatrix.a) * width + Math.abs(transformMatrix.c) * height;
|
|
7880
|
+
const transformedHeight = Math.abs(transformMatrix.b) * width + Math.abs(transformMatrix.d) * height;
|
|
7881
|
+
if (transformedWidth <= 0 || transformedHeight <= 0) return localScale;
|
|
7882
|
+
return {
|
|
7883
|
+
scaleX: rect.width / transformedWidth * localScale.scaleX,
|
|
7884
|
+
scaleY: rect.height / transformedHeight * localScale.scaleY
|
|
7337
7885
|
};
|
|
7338
7886
|
}
|
|
7887
|
+
function computeEdgeSize({
|
|
7888
|
+
handle,
|
|
7889
|
+
startWidth,
|
|
7890
|
+
startHeight,
|
|
7891
|
+
dx,
|
|
7892
|
+
dy,
|
|
7893
|
+
minSize = 1
|
|
7894
|
+
}) {
|
|
7895
|
+
const baseWidth = clampSize(startWidth, minSize);
|
|
7896
|
+
const baseHeight = clampSize(startHeight, minSize);
|
|
7897
|
+
switch (handle) {
|
|
7898
|
+
case "right":
|
|
7899
|
+
return { width: clampSize(baseWidth + dx, minSize), height: baseHeight };
|
|
7900
|
+
case "left":
|
|
7901
|
+
return { width: clampSize(baseWidth - dx, minSize), height: baseHeight };
|
|
7902
|
+
case "bottom":
|
|
7903
|
+
return { width: baseWidth, height: clampSize(baseHeight + dy, minSize) };
|
|
7904
|
+
case "top":
|
|
7905
|
+
return { width: baseWidth, height: clampSize(baseHeight - dy, minSize) };
|
|
7906
|
+
}
|
|
7907
|
+
}
|
|
7908
|
+
function computeCornerProportionalSize({
|
|
7909
|
+
handle,
|
|
7910
|
+
startWidth,
|
|
7911
|
+
startHeight,
|
|
7912
|
+
dx,
|
|
7913
|
+
dy,
|
|
7914
|
+
minSize = 1
|
|
7915
|
+
}) {
|
|
7916
|
+
const baseWidth = clampSize(startWidth, minSize);
|
|
7917
|
+
const baseHeight = clampSize(startHeight, minSize);
|
|
7918
|
+
const ratio = baseWidth > 0 && baseHeight > 0 ? baseWidth / baseHeight : 1;
|
|
7919
|
+
const widthSign = handle === "top-left" || handle === "bottom-left" ? -1 : 1;
|
|
7920
|
+
const heightSign = handle === "top-left" || handle === "top-right" ? -1 : 1;
|
|
7921
|
+
const rawWidth = baseWidth + widthSign * dx;
|
|
7922
|
+
const rawHeight = baseHeight + heightSign * dy;
|
|
7923
|
+
const widthIntent = clampSize(rawWidth, minSize);
|
|
7924
|
+
const heightIntent = clampSize(rawHeight, minSize);
|
|
7925
|
+
const widthChange = Math.abs(widthIntent - baseWidth) / Math.max(baseWidth, 1);
|
|
7926
|
+
const heightChange = Math.abs(heightIntent - baseHeight) / Math.max(baseHeight, 1);
|
|
7927
|
+
if (widthChange >= heightChange) {
|
|
7928
|
+
const width2 = clampSize(widthIntent, minSize);
|
|
7929
|
+
const height2 = clampSize(width2 / Math.max(ratio, 1e-4), minSize);
|
|
7930
|
+
return { width: width2, height: height2 };
|
|
7931
|
+
}
|
|
7932
|
+
const height = clampSize(heightIntent, minSize);
|
|
7933
|
+
const width = clampSize(height * ratio, minSize);
|
|
7934
|
+
return { width, height };
|
|
7935
|
+
}
|
|
7936
|
+
function computeFillRenderedWidth(element) {
|
|
7937
|
+
const parent = element.parentElement;
|
|
7938
|
+
if (!parent) return null;
|
|
7939
|
+
const parentComputed = window.getComputedStyle(parent);
|
|
7940
|
+
const elementComputed = window.getComputedStyle(element);
|
|
7941
|
+
const parentClientWidth = parent.clientWidth;
|
|
7942
|
+
const parentPaddingLeft = parseFloat(parentComputed.paddingLeft) || 0;
|
|
7943
|
+
const parentPaddingRight = parseFloat(parentComputed.paddingRight) || 0;
|
|
7944
|
+
const parentContentWidth = parentClientWidth - parentPaddingLeft - parentPaddingRight;
|
|
7945
|
+
if (!Number.isFinite(parentContentWidth) || parentContentWidth <= 0) {
|
|
7946
|
+
return null;
|
|
7947
|
+
}
|
|
7948
|
+
const elementPaddingLeft = parseFloat(elementComputed.paddingLeft) || 0;
|
|
7949
|
+
const elementPaddingRight = parseFloat(elementComputed.paddingRight) || 0;
|
|
7950
|
+
const elementBorderLeft = parseFloat(elementComputed.borderLeftWidth) || 0;
|
|
7951
|
+
const elementBorderRight = parseFloat(elementComputed.borderRightWidth) || 0;
|
|
7952
|
+
if (elementComputed.boxSizing === "border-box") {
|
|
7953
|
+
return clampSize(parentContentWidth, 1);
|
|
7954
|
+
}
|
|
7955
|
+
return clampSize(
|
|
7956
|
+
parentContentWidth + elementPaddingLeft + elementPaddingRight + elementBorderLeft + elementBorderRight,
|
|
7957
|
+
1
|
|
7958
|
+
);
|
|
7959
|
+
}
|
|
7339
7960
|
|
|
7340
7961
|
// src/use-move.ts
|
|
7341
7962
|
var INITIAL_DRAG_STATE = {
|
|
@@ -7409,10 +8030,14 @@ function useMove({ onMoveComplete }) {
|
|
|
7409
8030
|
const onMoveCompleteRef = React12.useRef(onMoveComplete);
|
|
7410
8031
|
const dragOptionsRef = React12.useRef(DEFAULT_DRAG_OPTIONS);
|
|
7411
8032
|
const dragGuardRef = React12.useRef(createDragInteractionGuard());
|
|
7412
|
-
const initialRectRef = React12.useRef(
|
|
7413
|
-
|
|
7414
|
-
|
|
8033
|
+
const initialRectRef = React12.useRef({
|
|
8034
|
+
x: 0,
|
|
8035
|
+
y: 0,
|
|
8036
|
+
scaleX: 1,
|
|
8037
|
+
scaleY: 1
|
|
8038
|
+
});
|
|
7415
8039
|
const originalTransformRef = React12.useRef("");
|
|
8040
|
+
const composeBaseRef = React12.useRef("");
|
|
7416
8041
|
const reorderPreviewRef = React12.useRef(/* @__PURE__ */ new Map());
|
|
7417
8042
|
React12.useEffect(() => {
|
|
7418
8043
|
dragStateRef.current = dragState;
|
|
@@ -7426,79 +8051,85 @@ function useMove({ onMoveComplete }) {
|
|
|
7426
8051
|
}
|
|
7427
8052
|
reorderPreviewRef.current.clear();
|
|
7428
8053
|
}, []);
|
|
7429
|
-
const setReorderPreviewTransform = React12.useCallback(
|
|
7430
|
-
|
|
7431
|
-
|
|
7432
|
-
|
|
7433
|
-
|
|
7434
|
-
|
|
7435
|
-
|
|
7436
|
-
|
|
7437
|
-
|
|
7438
|
-
|
|
7439
|
-
|
|
7440
|
-
|
|
7441
|
-
|
|
7442
|
-
|
|
7443
|
-
|
|
7444
|
-
|
|
7445
|
-
|
|
7446
|
-
|
|
7447
|
-
|
|
7448
|
-
|
|
7449
|
-
|
|
7450
|
-
|
|
7451
|
-
|
|
7452
|
-
|
|
7453
|
-
|
|
7454
|
-
|
|
7455
|
-
|
|
7456
|
-
|
|
7457
|
-
|
|
7458
|
-
|
|
7459
|
-
|
|
7460
|
-
|
|
7461
|
-
|
|
7462
|
-
|
|
7463
|
-
|
|
7464
|
-
|
|
7465
|
-
|
|
7466
|
-
|
|
7467
|
-
|
|
7468
|
-
|
|
7469
|
-
|
|
7470
|
-
|
|
7471
|
-
|
|
7472
|
-
|
|
7473
|
-
|
|
7474
|
-
|
|
7475
|
-
|
|
7476
|
-
|
|
7477
|
-
|
|
7478
|
-
|
|
8054
|
+
const setReorderPreviewTransform = React12.useCallback(
|
|
8055
|
+
(element, transform) => {
|
|
8056
|
+
const existing = reorderPreviewRef.current.get(element);
|
|
8057
|
+
if (!existing) {
|
|
8058
|
+
reorderPreviewRef.current.set(element, {
|
|
8059
|
+
transform: element.style.transform,
|
|
8060
|
+
transition: element.style.transition
|
|
8061
|
+
});
|
|
8062
|
+
}
|
|
8063
|
+
const originalTransition = reorderPreviewRef.current.get(element)?.transition ?? element.style.transition;
|
|
8064
|
+
element.style.transition = withTransformTransition(originalTransition);
|
|
8065
|
+
element.style.transform = transform;
|
|
8066
|
+
},
|
|
8067
|
+
[]
|
|
8068
|
+
);
|
|
8069
|
+
const applyReorderPreview = React12.useCallback(
|
|
8070
|
+
(target, draggedElement, originalParent) => {
|
|
8071
|
+
if (!target || !draggedElement) {
|
|
8072
|
+
clearReorderPreview();
|
|
8073
|
+
return;
|
|
8074
|
+
}
|
|
8075
|
+
const container = target.container;
|
|
8076
|
+
const containerChildren = Array.from(container.children).filter(
|
|
8077
|
+
(child) => child instanceof HTMLElement
|
|
8078
|
+
);
|
|
8079
|
+
const siblings = containerChildren.filter((child) => child !== draggedElement);
|
|
8080
|
+
const insertIndex = getInsertIndex(siblings, target.insertBefore);
|
|
8081
|
+
if (insertIndex === null) {
|
|
8082
|
+
clearReorderPreview();
|
|
8083
|
+
return;
|
|
8084
|
+
}
|
|
8085
|
+
const draggedRect = draggedElement.getBoundingClientRect();
|
|
8086
|
+
const isHorizontal = isHorizontalDirection(target.flexDirection);
|
|
8087
|
+
const dragSize = isHorizontal ? draggedRect.width : draggedRect.height;
|
|
8088
|
+
if (!Number.isFinite(dragSize) || dragSize <= 0) {
|
|
8089
|
+
clearReorderPreview();
|
|
8090
|
+
return;
|
|
8091
|
+
}
|
|
8092
|
+
const sign = forwardVisualSign(target.flexDirection);
|
|
8093
|
+
const shiftedElements = /* @__PURE__ */ new Map();
|
|
8094
|
+
if (container === originalParent) {
|
|
8095
|
+
const originalIndex = containerChildren.indexOf(draggedElement);
|
|
8096
|
+
if (originalIndex >= 0) {
|
|
8097
|
+
if (insertIndex > originalIndex) {
|
|
8098
|
+
const shift = -sign * dragSize;
|
|
8099
|
+
for (let i = originalIndex; i < insertIndex; i++) {
|
|
8100
|
+
const sibling = siblings[i];
|
|
8101
|
+
if (sibling) shiftedElements.set(sibling, shift);
|
|
8102
|
+
}
|
|
8103
|
+
} else if (insertIndex < originalIndex) {
|
|
8104
|
+
const shift = sign * dragSize;
|
|
8105
|
+
for (let i = insertIndex; i < originalIndex; i++) {
|
|
8106
|
+
const sibling = siblings[i];
|
|
8107
|
+
if (sibling) shiftedElements.set(sibling, shift);
|
|
8108
|
+
}
|
|
7479
8109
|
}
|
|
7480
8110
|
}
|
|
8111
|
+
} else {
|
|
8112
|
+
const shift = sign * dragSize;
|
|
8113
|
+
for (let i = insertIndex; i < siblings.length; i++) {
|
|
8114
|
+
shiftedElements.set(siblings[i], shift);
|
|
8115
|
+
}
|
|
7481
8116
|
}
|
|
7482
|
-
|
|
7483
|
-
const
|
|
7484
|
-
for (
|
|
7485
|
-
|
|
8117
|
+
const axis = isHorizontal ? "x" : "y";
|
|
8118
|
+
const keep = new Set(shiftedElements.keys());
|
|
8119
|
+
for (const [element, snapshot2] of reorderPreviewRef.current) {
|
|
8120
|
+
if (!keep.has(element)) {
|
|
8121
|
+
element.style.transform = snapshot2.transform;
|
|
8122
|
+
element.style.transition = snapshot2.transition;
|
|
8123
|
+
reorderPreviewRef.current.delete(element);
|
|
8124
|
+
}
|
|
7486
8125
|
}
|
|
7487
|
-
|
|
7488
|
-
|
|
7489
|
-
|
|
7490
|
-
for (const [element, snapshot2] of reorderPreviewRef.current) {
|
|
7491
|
-
if (!keep.has(element)) {
|
|
7492
|
-
element.style.transform = snapshot2.transform;
|
|
7493
|
-
element.style.transition = snapshot2.transition;
|
|
7494
|
-
reorderPreviewRef.current.delete(element);
|
|
8126
|
+
for (const [element, shift] of shiftedElements) {
|
|
8127
|
+
const baseTransform = reorderPreviewRef.current.get(element)?.transform ?? element.style.transform;
|
|
8128
|
+
setReorderPreviewTransform(element, withAxisTranslate(baseTransform, axis, shift));
|
|
7495
8129
|
}
|
|
7496
|
-
}
|
|
7497
|
-
|
|
7498
|
-
|
|
7499
|
-
setReorderPreviewTransform(element, withAxisTranslate(baseTransform, axis, shift));
|
|
7500
|
-
}
|
|
7501
|
-
}, [clearReorderPreview, setReorderPreviewTransform]);
|
|
8130
|
+
},
|
|
8131
|
+
[clearReorderPreview, setReorderPreviewTransform]
|
|
8132
|
+
);
|
|
7502
8133
|
const cancelDrag = React12.useCallback(() => {
|
|
7503
8134
|
const current = dragStateRef.current;
|
|
7504
8135
|
if (current.draggedElement) {
|
|
@@ -7507,6 +8138,7 @@ function useMove({ onMoveComplete }) {
|
|
|
7507
8138
|
}
|
|
7508
8139
|
clearReorderPreview();
|
|
7509
8140
|
originalTransformRef.current = "";
|
|
8141
|
+
composeBaseRef.current = "";
|
|
7510
8142
|
initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
|
|
7511
8143
|
dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
|
|
7512
8144
|
dragGuardRef.current.deactivate();
|
|
@@ -7528,6 +8160,7 @@ function useMove({ onMoveComplete }) {
|
|
|
7528
8160
|
draggedElement.style.opacity = "";
|
|
7529
8161
|
clearReorderPreview();
|
|
7530
8162
|
originalTransformRef.current = "";
|
|
8163
|
+
composeBaseRef.current = "";
|
|
7531
8164
|
initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
|
|
7532
8165
|
const dragMode = dragOptionsRef.current.mode;
|
|
7533
8166
|
dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
|
|
@@ -7556,7 +8189,13 @@ function useMove({ onMoveComplete }) {
|
|
|
7556
8189
|
const deltaX = (current.ghostPosition.x - rect.left) / scaleX;
|
|
7557
8190
|
const deltaY = (current.ghostPosition.y - rect.top) / scaleY;
|
|
7558
8191
|
if ((Math.abs(deltaX) > 0.5 || Math.abs(deltaY) > 0.5) && originalParent) {
|
|
7559
|
-
moveInfo = {
|
|
8192
|
+
moveInfo = {
|
|
8193
|
+
originalParent,
|
|
8194
|
+
originalPreviousSibling,
|
|
8195
|
+
originalNextSibling,
|
|
8196
|
+
mode: "position",
|
|
8197
|
+
positionDelta: { x: deltaX, y: deltaY }
|
|
8198
|
+
};
|
|
7560
8199
|
}
|
|
7561
8200
|
}
|
|
7562
8201
|
} else if (target && tryReparent(draggedElement, target, originalParent, originalNextSibling)) {
|
|
@@ -7582,13 +8221,21 @@ function useMove({ onMoveComplete }) {
|
|
|
7582
8221
|
const previousSibling = element.previousElementSibling;
|
|
7583
8222
|
const nextSibling = element.nextElementSibling;
|
|
7584
8223
|
dragOptionsRef.current = normalizeStartDragOptions(options);
|
|
8224
|
+
const { scaleX, scaleY } = getElementScale(element);
|
|
7585
8225
|
initialRectRef.current = {
|
|
7586
8226
|
x: rect.left,
|
|
7587
8227
|
y: rect.top,
|
|
7588
|
-
scaleX
|
|
7589
|
-
scaleY
|
|
8228
|
+
scaleX,
|
|
8229
|
+
scaleY
|
|
7590
8230
|
};
|
|
7591
|
-
|
|
8231
|
+
const inlineTransform = element.style.transform;
|
|
8232
|
+
originalTransformRef.current = inlineTransform;
|
|
8233
|
+
if (inlineTransform) {
|
|
8234
|
+
composeBaseRef.current = inlineTransform;
|
|
8235
|
+
} else {
|
|
8236
|
+
const computed = getComputedStyle(element).transform;
|
|
8237
|
+
composeBaseRef.current = computed && computed !== "none" ? computed : "";
|
|
8238
|
+
}
|
|
7592
8239
|
dragGuardRef.current.activate();
|
|
7593
8240
|
setDragState({
|
|
7594
8241
|
isDragging: true,
|
|
@@ -7621,7 +8268,8 @@ function useMove({ onMoveComplete }) {
|
|
|
7621
8268
|
const { x, y, scaleX, scaleY } = initialRectRef.current;
|
|
7622
8269
|
const dx = (e.clientX - dragOffset.x - x) / scaleX;
|
|
7623
8270
|
const dy = (e.clientY - dragOffset.y - y) / scaleY;
|
|
7624
|
-
|
|
8271
|
+
const base = composeBaseRef.current;
|
|
8272
|
+
draggedElement.style.transform = base ? `translate(${dx}px, ${dy}px) ${base}` : `translate(${dx}px, ${dy}px)`;
|
|
7625
8273
|
}
|
|
7626
8274
|
if (dragOptionsRef.current.mode === "position") {
|
|
7627
8275
|
let container2 = findLayoutContainerAtPoint(
|
|
@@ -7662,19 +8310,9 @@ function useMove({ onMoveComplete }) {
|
|
|
7662
8310
|
}
|
|
7663
8311
|
return;
|
|
7664
8312
|
}
|
|
7665
|
-
const container = dragOptionsRef.current.constrainToOriginalParent ? originalParent : findContainerAtPoint(
|
|
7666
|
-
e.clientX,
|
|
7667
|
-
e.clientY,
|
|
7668
|
-
draggedElement,
|
|
7669
|
-
originalParent
|
|
7670
|
-
);
|
|
8313
|
+
const container = dragOptionsRef.current.constrainToOriginalParent ? originalParent : findContainerAtPoint(e.clientX, e.clientY, draggedElement, originalParent);
|
|
7671
8314
|
if (container && draggedElement) {
|
|
7672
|
-
const dropPos = calculateDropPosition(
|
|
7673
|
-
container,
|
|
7674
|
-
e.clientX,
|
|
7675
|
-
e.clientY,
|
|
7676
|
-
draggedElement
|
|
7677
|
-
);
|
|
8315
|
+
const dropPos = calculateDropPosition(container, e.clientX, e.clientY, draggedElement);
|
|
7678
8316
|
if (dropPos) {
|
|
7679
8317
|
const nextTarget = {
|
|
7680
8318
|
container,
|
|
@@ -8047,7 +8685,10 @@ function isSelectableElement(element) {
|
|
|
8047
8685
|
if (!(element instanceof HTMLElement)) return false;
|
|
8048
8686
|
if (!element.isConnected) return false;
|
|
8049
8687
|
if (element === document.body || element === document.documentElement) return false;
|
|
8050
|
-
if (element.matches(
|
|
8688
|
+
if (element.matches(
|
|
8689
|
+
"[data-direct-edit], [data-direct-edit-host], script, style, link, meta, noscript"
|
|
8690
|
+
))
|
|
8691
|
+
return false;
|
|
8051
8692
|
const rect = element.getBoundingClientRect();
|
|
8052
8693
|
if (rect.width <= 0 || rect.height <= 0) return false;
|
|
8053
8694
|
const computed = window.getComputedStyle(element);
|
|
@@ -8065,7 +8706,9 @@ function compareDomOrder2(a, b) {
|
|
|
8065
8706
|
}
|
|
8066
8707
|
function collectMarqueeTargets(rect) {
|
|
8067
8708
|
const hits = Array.from(document.querySelectorAll("*")).filter(isSelectableElement).filter((element) => rectsIntersect(rect, element.getBoundingClientRect()));
|
|
8068
|
-
const deepestHits = hits.filter(
|
|
8709
|
+
const deepestHits = hits.filter(
|
|
8710
|
+
(element) => !hits.some((other) => other !== element && element.contains(other))
|
|
8711
|
+
);
|
|
8069
8712
|
deepestHits.sort(compareDomOrder2);
|
|
8070
8713
|
return deepestHits;
|
|
8071
8714
|
}
|
|
@@ -8488,6 +9131,7 @@ function SelectedCommentComposer({
|
|
|
8488
9131
|
comment,
|
|
8489
9132
|
attentionNonce,
|
|
8490
9133
|
draftRef,
|
|
9134
|
+
onDraftTextChange,
|
|
8491
9135
|
onSubmit,
|
|
8492
9136
|
onCancel
|
|
8493
9137
|
}) {
|
|
@@ -8533,7 +9177,8 @@ function SelectedCommentComposer({
|
|
|
8533
9177
|
}, [attentionNonce]);
|
|
8534
9178
|
React17.useEffect(() => {
|
|
8535
9179
|
if (draftRef) draftRef.current = text;
|
|
8536
|
-
|
|
9180
|
+
onDraftTextChange?.(text);
|
|
9181
|
+
}, [draftRef, onDraftTextChange, text]);
|
|
8537
9182
|
const submit = React17.useCallback(() => {
|
|
8538
9183
|
const nextText = text.trim();
|
|
8539
9184
|
if (!nextText) return;
|
|
@@ -8592,161 +9237,89 @@ function SelectedCommentComposer({
|
|
|
8592
9237
|
} else if (e.key === "Escape") {
|
|
8593
9238
|
onCancel();
|
|
8594
9239
|
}
|
|
8595
|
-
}
|
|
8596
|
-
}
|
|
8597
|
-
),
|
|
8598
|
-
/* @__PURE__ */ jsx7(
|
|
8599
|
-
Button,
|
|
8600
|
-
{
|
|
8601
|
-
type: "button",
|
|
8602
|
-
variant: "ghost",
|
|
8603
|
-
size: "icon",
|
|
8604
|
-
className: cn(
|
|
8605
|
-
"size-7 shrink-0 self-start",
|
|
8606
|
-
text.trim() ? "bg-blue-500 text-white hover:bg-blue-600" : "bg-muted text-muted-foreground"
|
|
8607
|
-
),
|
|
8608
|
-
disabled: !text.trim(),
|
|
8609
|
-
onClick: submit,
|
|
8610
|
-
children: /* @__PURE__ */ jsx7(ArrowUp, {})
|
|
8611
|
-
}
|
|
8612
|
-
)
|
|
8613
|
-
]
|
|
8614
|
-
}
|
|
8615
|
-
);
|
|
8616
|
-
}
|
|
8617
|
-
|
|
8618
|
-
// src/move-overlay.tsx
|
|
8619
|
-
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
8620
|
-
var BLUE2 = "#0D99FF";
|
|
8621
|
-
function MoveOverlay({ dropIndicator }) {
|
|
8622
|
-
if (!dropIndicator) {
|
|
8623
|
-
return null;
|
|
8624
|
-
}
|
|
8625
|
-
return /* @__PURE__ */ jsx8(
|
|
8626
|
-
"svg",
|
|
8627
|
-
{
|
|
8628
|
-
"data-direct-edit": "move-overlay",
|
|
8629
|
-
style: {
|
|
8630
|
-
position: "fixed",
|
|
8631
|
-
inset: 0,
|
|
8632
|
-
width: "100vw",
|
|
8633
|
-
height: "100vh",
|
|
8634
|
-
pointerEvents: "none",
|
|
8635
|
-
zIndex: 99997
|
|
8636
|
-
},
|
|
8637
|
-
children: /* @__PURE__ */ jsx8(
|
|
8638
|
-
"rect",
|
|
8639
|
-
{
|
|
8640
|
-
x: dropIndicator.x,
|
|
8641
|
-
y: dropIndicator.y,
|
|
8642
|
-
width: dropIndicator.width,
|
|
8643
|
-
height: dropIndicator.height,
|
|
8644
|
-
fill: BLUE2
|
|
8645
|
-
}
|
|
8646
|
-
)
|
|
8647
|
-
}
|
|
8648
|
-
);
|
|
8649
|
-
}
|
|
8650
|
-
|
|
8651
|
-
// src/selection-overlay.tsx
|
|
8652
|
-
import * as React19 from "react";
|
|
8653
|
-
import { MessageSquare } from "lucide-react";
|
|
8654
|
-
|
|
8655
|
-
// src/use-selection-resize.ts
|
|
8656
|
-
import * as React18 from "react";
|
|
8657
|
-
|
|
8658
|
-
// src/utils/resize-geometry.ts
|
|
8659
|
-
function toFinite(value, fallback) {
|
|
8660
|
-
if (!Number.isFinite(value)) return fallback;
|
|
8661
|
-
return value;
|
|
8662
|
-
}
|
|
8663
|
-
function clampSize(value, minSize = 1) {
|
|
8664
|
-
const safeMin = Math.max(1, toFinite(minSize, 1));
|
|
8665
|
-
const safeValue = toFinite(value, safeMin);
|
|
8666
|
-
return Math.max(safeMin, safeValue);
|
|
8667
|
-
}
|
|
8668
|
-
function computeEdgeSize({
|
|
8669
|
-
handle,
|
|
8670
|
-
startWidth,
|
|
8671
|
-
startHeight,
|
|
8672
|
-
dx,
|
|
8673
|
-
dy,
|
|
8674
|
-
minSize = 1
|
|
8675
|
-
}) {
|
|
8676
|
-
const baseWidth = clampSize(startWidth, minSize);
|
|
8677
|
-
const baseHeight = clampSize(startHeight, minSize);
|
|
8678
|
-
switch (handle) {
|
|
8679
|
-
case "right":
|
|
8680
|
-
return { width: clampSize(baseWidth + dx, minSize), height: baseHeight };
|
|
8681
|
-
case "left":
|
|
8682
|
-
return { width: clampSize(baseWidth - dx, minSize), height: baseHeight };
|
|
8683
|
-
case "bottom":
|
|
8684
|
-
return { width: baseWidth, height: clampSize(baseHeight + dy, minSize) };
|
|
8685
|
-
case "top":
|
|
8686
|
-
return { width: baseWidth, height: clampSize(baseHeight - dy, minSize) };
|
|
8687
|
-
}
|
|
8688
|
-
}
|
|
8689
|
-
function computeCornerProportionalSize({
|
|
8690
|
-
handle,
|
|
8691
|
-
startWidth,
|
|
8692
|
-
startHeight,
|
|
8693
|
-
dx,
|
|
8694
|
-
dy,
|
|
8695
|
-
minSize = 1
|
|
8696
|
-
}) {
|
|
8697
|
-
const baseWidth = clampSize(startWidth, minSize);
|
|
8698
|
-
const baseHeight = clampSize(startHeight, minSize);
|
|
8699
|
-
const ratio = baseWidth > 0 && baseHeight > 0 ? baseWidth / baseHeight : 1;
|
|
8700
|
-
const widthSign = handle === "top-left" || handle === "bottom-left" ? -1 : 1;
|
|
8701
|
-
const heightSign = handle === "top-left" || handle === "top-right" ? -1 : 1;
|
|
8702
|
-
const rawWidth = baseWidth + widthSign * dx;
|
|
8703
|
-
const rawHeight = baseHeight + heightSign * dy;
|
|
8704
|
-
const widthIntent = clampSize(rawWidth, minSize);
|
|
8705
|
-
const heightIntent = clampSize(rawHeight, minSize);
|
|
8706
|
-
const widthChange = Math.abs(widthIntent - baseWidth) / Math.max(baseWidth, 1);
|
|
8707
|
-
const heightChange = Math.abs(heightIntent - baseHeight) / Math.max(baseHeight, 1);
|
|
8708
|
-
if (widthChange >= heightChange) {
|
|
8709
|
-
const width2 = clampSize(widthIntent, minSize);
|
|
8710
|
-
const height2 = clampSize(width2 / Math.max(ratio, 1e-4), minSize);
|
|
8711
|
-
return { width: width2, height: height2 };
|
|
8712
|
-
}
|
|
8713
|
-
const height = clampSize(heightIntent, minSize);
|
|
8714
|
-
const width = clampSize(height * ratio, minSize);
|
|
8715
|
-
return { width, height };
|
|
9240
|
+
}
|
|
9241
|
+
}
|
|
9242
|
+
),
|
|
9243
|
+
/* @__PURE__ */ jsx7(
|
|
9244
|
+
Button,
|
|
9245
|
+
{
|
|
9246
|
+
type: "button",
|
|
9247
|
+
variant: "ghost",
|
|
9248
|
+
size: "icon",
|
|
9249
|
+
className: cn(
|
|
9250
|
+
"size-7 shrink-0 self-start",
|
|
9251
|
+
text.trim() ? "bg-blue-500 text-white hover:bg-blue-600" : "bg-muted text-muted-foreground"
|
|
9252
|
+
),
|
|
9253
|
+
disabled: !text.trim(),
|
|
9254
|
+
onClick: submit,
|
|
9255
|
+
children: /* @__PURE__ */ jsx7(ArrowUp, {})
|
|
9256
|
+
}
|
|
9257
|
+
)
|
|
9258
|
+
]
|
|
9259
|
+
}
|
|
9260
|
+
);
|
|
8716
9261
|
}
|
|
8717
|
-
|
|
8718
|
-
|
|
8719
|
-
|
|
8720
|
-
|
|
8721
|
-
|
|
8722
|
-
|
|
8723
|
-
const parentPaddingLeft = parseFloat(parentComputed.paddingLeft) || 0;
|
|
8724
|
-
const parentPaddingRight = parseFloat(parentComputed.paddingRight) || 0;
|
|
8725
|
-
const parentContentWidth = parentClientWidth - parentPaddingLeft - parentPaddingRight;
|
|
8726
|
-
if (!Number.isFinite(parentContentWidth) || parentContentWidth <= 0) {
|
|
9262
|
+
|
|
9263
|
+
// src/move-overlay.tsx
|
|
9264
|
+
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
9265
|
+
var BLUE2 = "#0D99FF";
|
|
9266
|
+
function MoveOverlay({ dropIndicator }) {
|
|
9267
|
+
if (!dropIndicator) {
|
|
8727
9268
|
return null;
|
|
8728
9269
|
}
|
|
8729
|
-
|
|
8730
|
-
|
|
8731
|
-
|
|
8732
|
-
|
|
8733
|
-
|
|
8734
|
-
|
|
8735
|
-
|
|
8736
|
-
|
|
8737
|
-
|
|
8738
|
-
|
|
9270
|
+
return /* @__PURE__ */ jsx8(
|
|
9271
|
+
"svg",
|
|
9272
|
+
{
|
|
9273
|
+
"data-direct-edit": "move-overlay",
|
|
9274
|
+
style: {
|
|
9275
|
+
position: "fixed",
|
|
9276
|
+
inset: 0,
|
|
9277
|
+
width: "100vw",
|
|
9278
|
+
height: "100vh",
|
|
9279
|
+
pointerEvents: "none",
|
|
9280
|
+
zIndex: 99997
|
|
9281
|
+
},
|
|
9282
|
+
children: /* @__PURE__ */ jsx8(
|
|
9283
|
+
"rect",
|
|
9284
|
+
{
|
|
9285
|
+
x: dropIndicator.x,
|
|
9286
|
+
y: dropIndicator.y,
|
|
9287
|
+
width: dropIndicator.width,
|
|
9288
|
+
height: dropIndicator.height,
|
|
9289
|
+
fill: BLUE2
|
|
9290
|
+
}
|
|
9291
|
+
)
|
|
9292
|
+
}
|
|
8739
9293
|
);
|
|
8740
9294
|
}
|
|
8741
9295
|
|
|
9296
|
+
// src/selection-overlay.tsx
|
|
9297
|
+
import * as React19 from "react";
|
|
9298
|
+
import { MessageSquare } from "lucide-react";
|
|
9299
|
+
|
|
8742
9300
|
// src/use-selection-resize.ts
|
|
9301
|
+
import * as React18 from "react";
|
|
8743
9302
|
var MIN_SIZE_PX = 1;
|
|
8744
9303
|
var SNAP_IN_PX = 2;
|
|
8745
9304
|
var SNAP_OUT_PX = 6;
|
|
8746
9305
|
var EPSILON = 1e-4;
|
|
8747
9306
|
var EDGE_HANDLES = /* @__PURE__ */ new Set(["top", "right", "bottom", "left"]);
|
|
8748
|
-
var WIDTH_HANDLES = /* @__PURE__ */ new Set([
|
|
8749
|
-
|
|
9307
|
+
var WIDTH_HANDLES = /* @__PURE__ */ new Set([
|
|
9308
|
+
"left",
|
|
9309
|
+
"right",
|
|
9310
|
+
"top-left",
|
|
9311
|
+
"top-right",
|
|
9312
|
+
"bottom-left",
|
|
9313
|
+
"bottom-right"
|
|
9314
|
+
]);
|
|
9315
|
+
var HEIGHT_HANDLES = /* @__PURE__ */ new Set([
|
|
9316
|
+
"top",
|
|
9317
|
+
"bottom",
|
|
9318
|
+
"top-left",
|
|
9319
|
+
"top-right",
|
|
9320
|
+
"bottom-left",
|
|
9321
|
+
"bottom-right"
|
|
9322
|
+
]);
|
|
8750
9323
|
function createSizingValue(mode, numericValue) {
|
|
8751
9324
|
const rounded = Math.max(MIN_SIZE_PX, Math.round(clampSize(numericValue, MIN_SIZE_PX)));
|
|
8752
9325
|
return {
|
|
@@ -8768,125 +9341,135 @@ function useSelectionResize({
|
|
|
8768
9341
|
}) {
|
|
8769
9342
|
const cleanupRef = React18.useRef(null);
|
|
8770
9343
|
const txCounterRef = React18.useRef(0);
|
|
8771
|
-
const emitSizingChange = React18.useCallback(
|
|
8772
|
-
|
|
8773
|
-
|
|
9344
|
+
const emitSizingChange = React18.useCallback(
|
|
9345
|
+
(changes, options) => {
|
|
9346
|
+
onResizeSizingChange?.(changes, options);
|
|
9347
|
+
},
|
|
9348
|
+
[onResizeSizingChange]
|
|
9349
|
+
);
|
|
8774
9350
|
React18.useEffect(() => {
|
|
8775
9351
|
return () => {
|
|
8776
9352
|
cleanupRef.current?.();
|
|
8777
9353
|
cleanupRef.current = null;
|
|
8778
9354
|
};
|
|
8779
9355
|
}, []);
|
|
8780
|
-
const getResizeHandlePointerDown = React18.useCallback(
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
|
|
8784
|
-
|
|
8785
|
-
|
|
8786
|
-
|
|
8787
|
-
|
|
8788
|
-
|
|
8789
|
-
|
|
8790
|
-
|
|
8791
|
-
|
|
8792
|
-
|
|
8793
|
-
|
|
8794
|
-
|
|
8795
|
-
|
|
8796
|
-
transactionId
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8801
|
-
|
|
8802
|
-
|
|
8803
|
-
|
|
8804
|
-
|
|
8805
|
-
|
|
8806
|
-
|
|
8807
|
-
|
|
8808
|
-
|
|
8809
|
-
|
|
8810
|
-
const
|
|
8811
|
-
|
|
8812
|
-
|
|
8813
|
-
|
|
8814
|
-
|
|
8815
|
-
|
|
8816
|
-
|
|
8817
|
-
|
|
8818
|
-
|
|
8819
|
-
|
|
8820
|
-
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8824
|
-
|
|
8825
|
-
|
|
8826
|
-
|
|
8827
|
-
|
|
8828
|
-
|
|
8829
|
-
|
|
8830
|
-
|
|
8831
|
-
|
|
8832
|
-
if (state.
|
|
8833
|
-
|
|
8834
|
-
|
|
9356
|
+
const getResizeHandlePointerDown = React18.useCallback(
|
|
9357
|
+
(handle) => {
|
|
9358
|
+
return (e) => {
|
|
9359
|
+
if (!enabled || !onResizeSizingChange) return;
|
|
9360
|
+
if (e.button !== 0) return;
|
|
9361
|
+
e.preventDefault();
|
|
9362
|
+
e.stopPropagation();
|
|
9363
|
+
cleanupRef.current?.();
|
|
9364
|
+
const rect = selectedElement.getBoundingClientRect();
|
|
9365
|
+
const offsetWidth = selectedElement.offsetWidth;
|
|
9366
|
+
const offsetHeight = selectedElement.offsetHeight;
|
|
9367
|
+
const startWidth = clampSize(offsetWidth > 0 ? offsetWidth : rect.width, MIN_SIZE_PX);
|
|
9368
|
+
const startHeight = clampSize(offsetHeight > 0 ? offsetHeight : rect.height, MIN_SIZE_PX);
|
|
9369
|
+
const { scaleX: rawScaleX, scaleY: rawScaleY } = getElementScale(selectedElement);
|
|
9370
|
+
const scaleX = Math.max(EPSILON, rawScaleX);
|
|
9371
|
+
const scaleY = Math.max(EPSILON, rawScaleY);
|
|
9372
|
+
const transactionId = `resize-${Date.now()}-${txCounterRef.current++}`;
|
|
9373
|
+
const state = {
|
|
9374
|
+
transactionId,
|
|
9375
|
+
handle,
|
|
9376
|
+
startClientX: e.clientX,
|
|
9377
|
+
startClientY: e.clientY,
|
|
9378
|
+
startWidth,
|
|
9379
|
+
startHeight,
|
|
9380
|
+
scaleX,
|
|
9381
|
+
scaleY,
|
|
9382
|
+
fillTargetWidth: computeFillRenderedWidth(selectedElement),
|
|
9383
|
+
fillLocked: detectSizingMode(selectedElement, "width") === "fill"
|
|
9384
|
+
};
|
|
9385
|
+
emitSizingChange({}, { transactionId: state.transactionId, phase: "start" });
|
|
9386
|
+
const onPointerMove = (moveEvent) => {
|
|
9387
|
+
const dx = (moveEvent.clientX - state.startClientX) / state.scaleX;
|
|
9388
|
+
const dy = (moveEvent.clientY - state.startClientY) / state.scaleY;
|
|
9389
|
+
const nextSize = isEdgeHandle(state.handle) ? computeEdgeSize({
|
|
9390
|
+
handle: state.handle,
|
|
9391
|
+
startWidth: state.startWidth,
|
|
9392
|
+
startHeight: state.startHeight,
|
|
9393
|
+
dx,
|
|
9394
|
+
dy,
|
|
9395
|
+
minSize: MIN_SIZE_PX
|
|
9396
|
+
}) : computeCornerProportionalSize({
|
|
9397
|
+
handle: state.handle,
|
|
9398
|
+
startWidth: state.startWidth,
|
|
9399
|
+
startHeight: state.startHeight,
|
|
9400
|
+
dx,
|
|
9401
|
+
dy,
|
|
9402
|
+
minSize: MIN_SIZE_PX
|
|
9403
|
+
});
|
|
9404
|
+
const nextWidth = Math.max(MIN_SIZE_PX, Math.round(nextSize.width));
|
|
9405
|
+
const nextHeight = Math.max(MIN_SIZE_PX, Math.round(nextSize.height));
|
|
9406
|
+
const changes = {};
|
|
9407
|
+
if (WIDTH_HANDLES.has(state.handle)) {
|
|
9408
|
+
if (state.fillTargetWidth !== null) {
|
|
9409
|
+
const distance = Math.abs(nextWidth - state.fillTargetWidth);
|
|
9410
|
+
if (state.fillLocked) {
|
|
9411
|
+
if (distance > SNAP_OUT_PX) {
|
|
9412
|
+
state.fillLocked = false;
|
|
9413
|
+
}
|
|
9414
|
+
} else if (distance <= SNAP_IN_PX) {
|
|
9415
|
+
state.fillLocked = true;
|
|
8835
9416
|
}
|
|
8836
|
-
} else
|
|
8837
|
-
state.fillLocked =
|
|
9417
|
+
} else {
|
|
9418
|
+
state.fillLocked = false;
|
|
9419
|
+
}
|
|
9420
|
+
if (state.fillLocked) {
|
|
9421
|
+
const fillWidth = state.fillTargetWidth ?? nextWidth;
|
|
9422
|
+
changes.width = createSizingValue("fill", fillWidth);
|
|
9423
|
+
} else {
|
|
9424
|
+
changes.width = createSizingValue("fixed", nextWidth);
|
|
8838
9425
|
}
|
|
8839
|
-
} else {
|
|
8840
|
-
state.fillLocked = false;
|
|
8841
9426
|
}
|
|
8842
|
-
if (state.
|
|
8843
|
-
|
|
8844
|
-
changes.width = createSizingValue("fill", fillWidth);
|
|
8845
|
-
} else {
|
|
8846
|
-
changes.width = createSizingValue("fixed", nextWidth);
|
|
9427
|
+
if (HEIGHT_HANDLES.has(state.handle)) {
|
|
9428
|
+
changes.height = createSizingValue("fixed", nextHeight);
|
|
8847
9429
|
}
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
8851
|
-
|
|
8852
|
-
|
|
8853
|
-
|
|
9430
|
+
if (Object.keys(changes).length === 0) return;
|
|
9431
|
+
emitSizingChange(changes, { transactionId: state.transactionId, phase: "update" });
|
|
9432
|
+
};
|
|
9433
|
+
const stop = () => {
|
|
9434
|
+
window.removeEventListener("pointermove", onPointerMove);
|
|
9435
|
+
window.removeEventListener("pointerup", stop);
|
|
9436
|
+
window.removeEventListener("pointercancel", stop);
|
|
9437
|
+
window.removeEventListener("blur", stop);
|
|
9438
|
+
cleanupRef.current = null;
|
|
9439
|
+
emitSizingChange({}, { transactionId: state.transactionId, phase: "end" });
|
|
9440
|
+
};
|
|
9441
|
+
cleanupRef.current = stop;
|
|
9442
|
+
window.addEventListener("pointermove", onPointerMove);
|
|
9443
|
+
window.addEventListener("pointerup", stop);
|
|
9444
|
+
window.addEventListener("pointercancel", stop);
|
|
9445
|
+
window.addEventListener("blur", stop);
|
|
8854
9446
|
};
|
|
8855
|
-
|
|
8856
|
-
|
|
8857
|
-
|
|
8858
|
-
|
|
8859
|
-
|
|
8860
|
-
|
|
8861
|
-
|
|
9447
|
+
},
|
|
9448
|
+
[emitSizingChange, enabled, onResizeSizingChange, selectedElement]
|
|
9449
|
+
);
|
|
9450
|
+
const getResizeHandleDoubleClick = React18.useCallback(
|
|
9451
|
+
(handle) => {
|
|
9452
|
+
return (e) => {
|
|
9453
|
+
if (!enabled || !onResizeSizingChange) return;
|
|
9454
|
+
if (!isEdgeHandle(handle)) return;
|
|
9455
|
+
const hasElementChildren = selectedElement.children.length > 0;
|
|
9456
|
+
const hasTextContent = Boolean(selectedElement.textContent?.trim());
|
|
9457
|
+
const isEligibleElement = hasElementChildren || hasTextContent;
|
|
9458
|
+
if (!isEligibleElement) return;
|
|
9459
|
+
e.preventDefault();
|
|
9460
|
+
e.stopPropagation();
|
|
9461
|
+
const rect = selectedElement.getBoundingClientRect();
|
|
9462
|
+
const width = Math.max(MIN_SIZE_PX, Math.round(rect.width));
|
|
9463
|
+
const height = Math.max(MIN_SIZE_PX, Math.round(rect.height));
|
|
9464
|
+
if (handle === "left" || handle === "right") {
|
|
9465
|
+
emitSizingChange({ width: createSizingValue("fit", width) });
|
|
9466
|
+
} else {
|
|
9467
|
+
emitSizingChange({ height: createSizingValue("fit", height) });
|
|
9468
|
+
}
|
|
8862
9469
|
};
|
|
8863
|
-
|
|
8864
|
-
|
|
8865
|
-
|
|
8866
|
-
window.addEventListener("pointercancel", stop);
|
|
8867
|
-
window.addEventListener("blur", stop);
|
|
8868
|
-
};
|
|
8869
|
-
}, [emitSizingChange, enabled, onResizeSizingChange, selectedElement]);
|
|
8870
|
-
const getResizeHandleDoubleClick = React18.useCallback((handle) => {
|
|
8871
|
-
return (e) => {
|
|
8872
|
-
if (!enabled || !onResizeSizingChange) return;
|
|
8873
|
-
if (!isEdgeHandle(handle)) return;
|
|
8874
|
-
const hasElementChildren = selectedElement.children.length > 0;
|
|
8875
|
-
const hasTextContent = Boolean(selectedElement.textContent?.trim());
|
|
8876
|
-
const isEligibleElement = hasElementChildren || hasTextContent;
|
|
8877
|
-
if (!isEligibleElement) return;
|
|
8878
|
-
e.preventDefault();
|
|
8879
|
-
e.stopPropagation();
|
|
8880
|
-
const rect = selectedElement.getBoundingClientRect();
|
|
8881
|
-
const width = Math.max(MIN_SIZE_PX, Math.round(rect.width));
|
|
8882
|
-
const height = Math.max(MIN_SIZE_PX, Math.round(rect.height));
|
|
8883
|
-
if (handle === "left" || handle === "right") {
|
|
8884
|
-
emitSizingChange({ width: createSizingValue("fit", width) });
|
|
8885
|
-
} else {
|
|
8886
|
-
emitSizingChange({ height: createSizingValue("fit", height) });
|
|
8887
|
-
}
|
|
8888
|
-
};
|
|
8889
|
-
}, [emitSizingChange, enabled, onResizeSizingChange, selectedElement]);
|
|
9470
|
+
},
|
|
9471
|
+
[emitSizingChange, enabled, onResizeSizingChange, selectedElement]
|
|
9472
|
+
);
|
|
8890
9473
|
return {
|
|
8891
9474
|
getResizeHandlePointerDown,
|
|
8892
9475
|
getResizeHandleDoubleClick
|
|
@@ -9511,17 +10094,20 @@ function getGroupBounds(rects) {
|
|
|
9511
10094
|
if (rects.length === 0) {
|
|
9512
10095
|
return { left: 0, top: 0, right: 0, bottom: 0 };
|
|
9513
10096
|
}
|
|
9514
|
-
return rects.reduce(
|
|
9515
|
-
|
|
9516
|
-
|
|
9517
|
-
|
|
9518
|
-
|
|
9519
|
-
|
|
9520
|
-
|
|
9521
|
-
|
|
9522
|
-
|
|
9523
|
-
|
|
9524
|
-
|
|
10097
|
+
return rects.reduce(
|
|
10098
|
+
(bounds, rect) => ({
|
|
10099
|
+
left: Math.min(bounds.left, rect.left),
|
|
10100
|
+
top: Math.min(bounds.top, rect.top),
|
|
10101
|
+
right: Math.max(bounds.right, rect.right),
|
|
10102
|
+
bottom: Math.max(bounds.bottom, rect.bottom)
|
|
10103
|
+
}),
|
|
10104
|
+
{
|
|
10105
|
+
left: rects[0].left,
|
|
10106
|
+
top: rects[0].top,
|
|
10107
|
+
right: rects[0].right,
|
|
10108
|
+
bottom: rects[0].bottom
|
|
10109
|
+
}
|
|
10110
|
+
);
|
|
9525
10111
|
}
|
|
9526
10112
|
function MultiSelectionOverlay({ selectedElements }) {
|
|
9527
10113
|
const elements = React20.useMemo(
|
|
@@ -9530,10 +10116,12 @@ function MultiSelectionOverlay({ selectedElements }) {
|
|
|
9530
10116
|
);
|
|
9531
10117
|
const [selectionRects, setSelectionRects] = React20.useState([]);
|
|
9532
10118
|
const updateRects = React20.useCallback(() => {
|
|
9533
|
-
setSelectionRects(
|
|
9534
|
-
element
|
|
9535
|
-
|
|
9536
|
-
|
|
10119
|
+
setSelectionRects(
|
|
10120
|
+
elements.map((element) => ({
|
|
10121
|
+
element,
|
|
10122
|
+
rect: element.getBoundingClientRect()
|
|
10123
|
+
}))
|
|
10124
|
+
);
|
|
9537
10125
|
}, [elements]);
|
|
9538
10126
|
React20.useLayoutEffect(() => {
|
|
9539
10127
|
updateRects();
|
|
@@ -11917,6 +12505,7 @@ function PanelFooter({
|
|
|
11917
12505
|
onExportEdits,
|
|
11918
12506
|
onSendToAgent,
|
|
11919
12507
|
showSendButton = true,
|
|
12508
|
+
sendFailureReason,
|
|
11920
12509
|
onPointerDown,
|
|
11921
12510
|
onPointerMove,
|
|
11922
12511
|
onPointerUp,
|
|
@@ -11925,6 +12514,13 @@ function PanelFooter({
|
|
|
11925
12514
|
const [copied, setCopied] = React30.useState(false);
|
|
11926
12515
|
const [copyError, setCopyError] = React30.useState(false);
|
|
11927
12516
|
const [sendStatus, setSendStatus] = React30.useState("idle");
|
|
12517
|
+
const prevCanTriggerSendRef = React30.useRef(canTriggerSend);
|
|
12518
|
+
React30.useEffect(() => {
|
|
12519
|
+
if (prevCanTriggerSendRef.current !== canTriggerSend) {
|
|
12520
|
+
prevCanTriggerSendRef.current = canTriggerSend;
|
|
12521
|
+
setSendStatus("idle");
|
|
12522
|
+
}
|
|
12523
|
+
}, [canTriggerSend]);
|
|
11928
12524
|
const handleCopy = async () => {
|
|
11929
12525
|
if (!onExportEdits) return;
|
|
11930
12526
|
const success = await onExportEdits();
|
|
@@ -11938,6 +12534,7 @@ function PanelFooter({
|
|
|
11938
12534
|
setCopyError(true);
|
|
11939
12535
|
setTimeout(() => setCopyError(false), 2e3);
|
|
11940
12536
|
};
|
|
12537
|
+
const sendTooltipLabel = sendStatus === "offline" ? sendFailureReason === "unreachable" ? "Agent unreachable \u2014 click to retry" : "Agent rejected the edit \u2014 click to retry" : "Apply changes via agent";
|
|
11941
12538
|
const handleSendToAgent = async () => {
|
|
11942
12539
|
if (!onSendToAgent || sendStatus === "sending") return;
|
|
11943
12540
|
setSendStatus("sending");
|
|
@@ -11947,7 +12544,6 @@ function PanelFooter({
|
|
|
11947
12544
|
setTimeout(() => setSendStatus("idle"), 2e3);
|
|
11948
12545
|
} else {
|
|
11949
12546
|
setSendStatus("offline");
|
|
11950
|
-
setTimeout(() => setSendStatus("idle"), 2e3);
|
|
11951
12547
|
}
|
|
11952
12548
|
};
|
|
11953
12549
|
return /* @__PURE__ */ jsxs18(
|
|
@@ -11975,7 +12571,7 @@ function PanelFooter({
|
|
|
11975
12571
|
children: copyError ? /* @__PURE__ */ jsx24(X3, { className: "text-red-500" }) : copied ? /* @__PURE__ */ jsx24(Check3, { className: "text-green-500" }) : /* @__PURE__ */ jsx24(Copy2, {})
|
|
11976
12572
|
}
|
|
11977
12573
|
) }),
|
|
11978
|
-
showSendButton && onSendToAgent && /* @__PURE__ */ jsx24("span", { className: !canTriggerSend || sendStatus === "sending" ? "cursor-not-allowed" : void 0, children: /* @__PURE__ */ jsx24(Tip, { label:
|
|
12574
|
+
showSendButton && onSendToAgent && /* @__PURE__ */ jsx24("span", { className: !canTriggerSend || sendStatus === "sending" ? "cursor-not-allowed" : void 0, children: /* @__PURE__ */ jsx24(Tip, { label: sendTooltipLabel, children: /* @__PURE__ */ jsx24(
|
|
11979
12575
|
Button,
|
|
11980
12576
|
{
|
|
11981
12577
|
variant: "outline",
|
|
@@ -12692,6 +13288,7 @@ function DirectEditPanelInner({
|
|
|
12692
13288
|
onSendToAgent,
|
|
12693
13289
|
canSendToAgent = false,
|
|
12694
13290
|
showSendButton = true,
|
|
13291
|
+
sendFailureReason,
|
|
12695
13292
|
className,
|
|
12696
13293
|
style,
|
|
12697
13294
|
panelRef,
|
|
@@ -12754,89 +13351,91 @@ function DirectEditPanelInner({
|
|
|
12754
13351
|
sectionRefs
|
|
12755
13352
|
}
|
|
12756
13353
|
),
|
|
12757
|
-
/* @__PURE__ */ jsxs23(
|
|
12758
|
-
|
|
12759
|
-
|
|
12760
|
-
|
|
12761
|
-
|
|
12762
|
-
|
|
12763
|
-
|
|
12764
|
-
|
|
12765
|
-
|
|
12766
|
-
|
|
12767
|
-
|
|
12768
|
-
|
|
12769
|
-
|
|
12770
|
-
|
|
12771
|
-
|
|
12772
|
-
|
|
12773
|
-
|
|
12774
|
-
|
|
12775
|
-
|
|
12776
|
-
|
|
12777
|
-
|
|
12778
|
-
|
|
12779
|
-
|
|
12780
|
-
|
|
12781
|
-
|
|
12782
|
-
|
|
12783
|
-
|
|
12784
|
-
|
|
12785
|
-
|
|
12786
|
-
|
|
12787
|
-
|
|
12788
|
-
|
|
12789
|
-
|
|
12790
|
-
|
|
12791
|
-
|
|
12792
|
-
|
|
12793
|
-
|
|
12794
|
-
|
|
12795
|
-
|
|
12796
|
-
|
|
12797
|
-
|
|
12798
|
-
|
|
12799
|
-
|
|
12800
|
-
|
|
12801
|
-
|
|
12802
|
-
|
|
12803
|
-
|
|
12804
|
-
|
|
12805
|
-
|
|
12806
|
-
|
|
12807
|
-
|
|
12808
|
-
|
|
12809
|
-
|
|
12810
|
-
|
|
12811
|
-
|
|
12812
|
-
|
|
12813
|
-
|
|
12814
|
-
|
|
12815
|
-
|
|
12816
|
-
|
|
12817
|
-
|
|
12818
|
-
|
|
12819
|
-
|
|
12820
|
-
|
|
12821
|
-
|
|
12822
|
-
|
|
12823
|
-
|
|
12824
|
-
|
|
12825
|
-
|
|
12826
|
-
|
|
12827
|
-
|
|
12828
|
-
|
|
12829
|
-
|
|
12830
|
-
|
|
12831
|
-
|
|
12832
|
-
|
|
12833
|
-
|
|
12834
|
-
|
|
12835
|
-
|
|
12836
|
-
|
|
12837
|
-
|
|
12838
|
-
|
|
12839
|
-
|
|
13354
|
+
/* @__PURE__ */ jsxs23(
|
|
13355
|
+
"div",
|
|
13356
|
+
{
|
|
13357
|
+
className: "flex-1 overflow-y-auto backdrop-blur-xl bg-background/85",
|
|
13358
|
+
ref: scrollRef,
|
|
13359
|
+
onWheelCapture: (e) => e.stopPropagation(),
|
|
13360
|
+
children: [
|
|
13361
|
+
/* @__PURE__ */ jsx29(
|
|
13362
|
+
LayoutSection,
|
|
13363
|
+
{
|
|
13364
|
+
elementInfo,
|
|
13365
|
+
computedFlex,
|
|
13366
|
+
computedSpacing,
|
|
13367
|
+
computedSizing,
|
|
13368
|
+
onToggleFlex,
|
|
13369
|
+
onUpdateFlex,
|
|
13370
|
+
onUpdateSpacing,
|
|
13371
|
+
onUpdateSizing,
|
|
13372
|
+
sectionRef: sectionRefs.layout
|
|
13373
|
+
}
|
|
13374
|
+
),
|
|
13375
|
+
/* @__PURE__ */ jsx29("div", { ref: sectionRefs.radius, children: /* @__PURE__ */ jsx29(CollapsibleSection, { title: "Radius", children: /* @__PURE__ */ jsx29(
|
|
13376
|
+
BorderRadiusInputs,
|
|
13377
|
+
{
|
|
13378
|
+
values: {
|
|
13379
|
+
topLeft: computedBorderRadius.borderTopLeftRadius,
|
|
13380
|
+
topRight: computedBorderRadius.borderTopRightRadius,
|
|
13381
|
+
bottomRight: computedBorderRadius.borderBottomRightRadius,
|
|
13382
|
+
bottomLeft: computedBorderRadius.borderBottomLeftRadius
|
|
13383
|
+
},
|
|
13384
|
+
onChange: onUpdateBorderRadius
|
|
13385
|
+
}
|
|
13386
|
+
) }) }),
|
|
13387
|
+
computedColor && /* @__PURE__ */ jsx29("div", { ref: sectionRefs.fill, children: /* @__PURE__ */ jsx29(
|
|
13388
|
+
BackgroundFillSection,
|
|
13389
|
+
{
|
|
13390
|
+
backgroundColor: computedColor.backgroundColor,
|
|
13391
|
+
onSetCSS,
|
|
13392
|
+
pendingStyles
|
|
13393
|
+
}
|
|
13394
|
+
) }),
|
|
13395
|
+
/* @__PURE__ */ jsx29("div", { ref: sectionRefs.border, children: /* @__PURE__ */ jsx29(
|
|
13396
|
+
BorderSection,
|
|
13397
|
+
{
|
|
13398
|
+
border: computedBorder,
|
|
13399
|
+
borderColor: computedColor?.borderColor,
|
|
13400
|
+
outlineColor: computedColor?.outlineColor,
|
|
13401
|
+
borderStyleControlPreference,
|
|
13402
|
+
onChange: onUpdateBorder,
|
|
13403
|
+
onBatchChange: onBatchUpdateBorder,
|
|
13404
|
+
onBorderColorChange: (value) => onUpdateColor("borderColor", value),
|
|
13405
|
+
onOutlineColorChange: (value) => onUpdateColor("outlineColor", value),
|
|
13406
|
+
onSetCSS,
|
|
13407
|
+
pendingStyles
|
|
13408
|
+
}
|
|
13409
|
+
) }),
|
|
13410
|
+
/* @__PURE__ */ jsx29("div", { ref: sectionRefs.shadow, children: /* @__PURE__ */ jsx29(
|
|
13411
|
+
ShadowSection,
|
|
13412
|
+
{
|
|
13413
|
+
boxShadow: computedBoxShadow,
|
|
13414
|
+
onSetCSS,
|
|
13415
|
+
pendingStyles
|
|
13416
|
+
}
|
|
13417
|
+
) }),
|
|
13418
|
+
elementInfo.isTextElement && computedTypography && /* @__PURE__ */ jsx29("div", { ref: sectionRefs.text, children: /* @__PURE__ */ jsx29(CollapsibleSection, { title: "Text", children: /* @__PURE__ */ jsx29(TypographyInputs, { typography: computedTypography, onUpdate: onUpdateTypography }) }) }),
|
|
13419
|
+
computedColor && /* @__PURE__ */ jsx29("div", { ref: sectionRefs.colors, children: /* @__PURE__ */ jsx29(CollapsibleSection, { title: "Selection colors", children: /* @__PURE__ */ jsx29(
|
|
13420
|
+
FillSection,
|
|
13421
|
+
{
|
|
13422
|
+
textColor: computedColor.color,
|
|
13423
|
+
borderColor: computedColor.borderColor,
|
|
13424
|
+
outlineColor: computedColor.outlineColor,
|
|
13425
|
+
selectionColors,
|
|
13426
|
+
onTextChange: (value) => onUpdateColor("color", value),
|
|
13427
|
+
onBorderColorChange: (value) => onUpdateColor("borderColor", value),
|
|
13428
|
+
onOutlineColorChange: (value) => onUpdateColor("outlineColor", value),
|
|
13429
|
+
onSelectionColorChange: onReplaceSelectionColor,
|
|
13430
|
+
onSelectionColorTarget: onSelectSelectionColorTarget,
|
|
13431
|
+
hasTextContent: elementInfo.isTextElement,
|
|
13432
|
+
showBorderColor: computedColor.borderColor.alpha > 0,
|
|
13433
|
+
showOutlineColor: computedColor.outlineColor.alpha > 0
|
|
13434
|
+
}
|
|
13435
|
+
) }) })
|
|
13436
|
+
]
|
|
13437
|
+
}
|
|
13438
|
+
),
|
|
12840
13439
|
(onExportEdits || showSendButton && onSendToAgent) && /* @__PURE__ */ jsx29(
|
|
12841
13440
|
PanelFooter,
|
|
12842
13441
|
{
|
|
@@ -12845,6 +13444,7 @@ function DirectEditPanelInner({
|
|
|
12845
13444
|
onExportEdits,
|
|
12846
13445
|
onSendToAgent,
|
|
12847
13446
|
showSendButton,
|
|
13447
|
+
sendFailureReason,
|
|
12848
13448
|
onPointerDown: onHeaderPointerDown,
|
|
12849
13449
|
onPointerMove: onHeaderPointerMove,
|
|
12850
13450
|
onPointerUp: onHeaderPointerUp,
|
|
@@ -12879,7 +13479,8 @@ function DirectEditPanelContent() {
|
|
|
12879
13479
|
comments,
|
|
12880
13480
|
activeCommentId,
|
|
12881
13481
|
textEditingElement,
|
|
12882
|
-
agentAvailable
|
|
13482
|
+
agentAvailable,
|
|
13483
|
+
lastSendFailure
|
|
12883
13484
|
} = useDirectEditState();
|
|
12884
13485
|
const {
|
|
12885
13486
|
selectParent,
|
|
@@ -12907,11 +13508,15 @@ function DirectEditPanelContent() {
|
|
|
12907
13508
|
addCommentReply,
|
|
12908
13509
|
deleteComment,
|
|
12909
13510
|
exportComment,
|
|
13511
|
+
exportEdits,
|
|
13512
|
+
sendEditToAgent: sendEditToAgent2,
|
|
12910
13513
|
sendCommentToAgent: sendCommentToAgent2,
|
|
12911
13514
|
setActiveCommentId,
|
|
12912
13515
|
startTextEditing,
|
|
12913
13516
|
toggleEditMode,
|
|
12914
|
-
deleteSelection
|
|
13517
|
+
deleteSelection,
|
|
13518
|
+
setCommentDraftText,
|
|
13519
|
+
setCommentDraftBlockedHandler
|
|
12915
13520
|
} = useDirectEditActions();
|
|
12916
13521
|
const {
|
|
12917
13522
|
position,
|
|
@@ -12933,46 +13538,67 @@ function DirectEditPanelContent() {
|
|
|
12933
13538
|
});
|
|
12934
13539
|
React34.useEffect(() => {
|
|
12935
13540
|
commentDraftRef.current = "";
|
|
12936
|
-
|
|
13541
|
+
setCommentDraftText("");
|
|
13542
|
+
}, [activeCommentId, setCommentDraftText]);
|
|
12937
13543
|
const activeDraftComment = React34.useMemo(() => {
|
|
12938
13544
|
if (!commentTargetElement || !activeCommentId) return null;
|
|
12939
13545
|
const active = comments.find((comment) => comment.id === activeCommentId);
|
|
12940
|
-
if (!active || active.text.trim().length > 0 || active.element !== commentTargetElement)
|
|
13546
|
+
if (!active || active.text.trim().length > 0 || active.element !== commentTargetElement)
|
|
13547
|
+
return null;
|
|
12941
13548
|
return active;
|
|
12942
13549
|
}, [activeCommentId, commentTargetElement, comments]);
|
|
12943
|
-
const { isActive: measurementActive, hoveredElement, measurements, mousePosition } = useMeasurement(
|
|
12944
|
-
isOpen ? selectedElement : null
|
|
12945
|
-
);
|
|
12946
13550
|
const {
|
|
12947
|
-
|
|
12948
|
-
|
|
12949
|
-
|
|
12950
|
-
|
|
13551
|
+
isActive: measurementActive,
|
|
13552
|
+
hoveredElement,
|
|
13553
|
+
measurements,
|
|
13554
|
+
mousePosition
|
|
13555
|
+
} = useMeasurement(isOpen ? selectedElement : null);
|
|
13556
|
+
const { dragState, dropIndicator, startDrag } = useMove({
|
|
12951
13557
|
onMoveComplete: handleMoveComplete
|
|
12952
13558
|
});
|
|
12953
13559
|
const triggerCommentInputAttention = React34.useCallback((commentId) => {
|
|
12954
|
-
setCommentInputAttention(
|
|
13560
|
+
setCommentInputAttention(
|
|
13561
|
+
(prev) => prev?.commentId === commentId ? { commentId, nonce: prev.nonce + 1 } : { commentId, nonce: 1 }
|
|
13562
|
+
);
|
|
12955
13563
|
}, []);
|
|
12956
|
-
|
|
12957
|
-
if (!activeCommentId)
|
|
12958
|
-
|
|
12959
|
-
|
|
12960
|
-
|
|
12961
|
-
|
|
12962
|
-
|
|
12963
|
-
|
|
12964
|
-
return
|
|
12965
|
-
|
|
12966
|
-
|
|
12967
|
-
|
|
12968
|
-
|
|
13564
|
+
React34.useEffect(() => {
|
|
13565
|
+
if (!activeCommentId) {
|
|
13566
|
+
setCommentDraftBlockedHandler(null);
|
|
13567
|
+
return;
|
|
13568
|
+
}
|
|
13569
|
+
setCommentDraftBlockedHandler(() => {
|
|
13570
|
+
triggerCommentInputAttention(activeCommentId);
|
|
13571
|
+
});
|
|
13572
|
+
return () => {
|
|
13573
|
+
setCommentDraftBlockedHandler(null);
|
|
13574
|
+
};
|
|
13575
|
+
}, [activeCommentId, setCommentDraftBlockedHandler, triggerCommentInputAttention]);
|
|
13576
|
+
const hasPendingCommentDraft = React34.useCallback(
|
|
13577
|
+
(nextCommentId = null) => {
|
|
13578
|
+
if (!activeCommentId) return false;
|
|
13579
|
+
if (nextCommentId && nextCommentId === activeCommentId) return false;
|
|
12969
13580
|
const active = comments.find((comment) => comment.id === activeCommentId);
|
|
12970
|
-
if (active
|
|
12971
|
-
|
|
13581
|
+
if (!active) return false;
|
|
13582
|
+
const hasUnsentDraft = active.text.trim().length === 0 && commentDraftRef.current.trim().length > 0;
|
|
13583
|
+
if (!hasUnsentDraft) return false;
|
|
13584
|
+
triggerCommentInputAttention(active.id);
|
|
13585
|
+
return true;
|
|
13586
|
+
},
|
|
13587
|
+
[activeCommentId, comments, triggerCommentInputAttention]
|
|
13588
|
+
);
|
|
13589
|
+
const handleSetActiveComment = React34.useCallback(
|
|
13590
|
+
(id) => {
|
|
13591
|
+
if (hasPendingCommentDraft(id)) return;
|
|
13592
|
+
if (activeCommentId && activeCommentId !== id) {
|
|
13593
|
+
const active = comments.find((comment) => comment.id === activeCommentId);
|
|
13594
|
+
if (active && active.text.trim().length === 0) {
|
|
13595
|
+
deleteComment(active.id);
|
|
13596
|
+
}
|
|
12972
13597
|
}
|
|
12973
|
-
|
|
12974
|
-
|
|
12975
|
-
|
|
13598
|
+
setActiveCommentId(id);
|
|
13599
|
+
},
|
|
13600
|
+
[activeCommentId, comments, hasPendingCommentDraft, deleteComment, setActiveCommentId]
|
|
13601
|
+
);
|
|
12976
13602
|
const handleCommentPillClick = React34.useCallback(() => {
|
|
12977
13603
|
if (activeDraftComment) {
|
|
12978
13604
|
handleSetActiveComment(null);
|
|
@@ -12980,13 +13606,23 @@ function DirectEditPanelContent() {
|
|
|
12980
13606
|
}
|
|
12981
13607
|
if (hasPendingCommentDraft()) return;
|
|
12982
13608
|
if (!commentTargetElement) return;
|
|
12983
|
-
const existingDraft = comments.find(
|
|
13609
|
+
const existingDraft = comments.find(
|
|
13610
|
+
(comment) => comment.element === commentTargetElement && comment.text.trim().length === 0
|
|
13611
|
+
);
|
|
12984
13612
|
if (existingDraft) {
|
|
12985
13613
|
setActiveCommentId(existingDraft.id);
|
|
12986
13614
|
return;
|
|
12987
13615
|
}
|
|
12988
13616
|
addComment(commentTargetElement, getElementCommentAnchor(commentTargetElement));
|
|
12989
|
-
}, [
|
|
13617
|
+
}, [
|
|
13618
|
+
activeDraftComment,
|
|
13619
|
+
handleSetActiveComment,
|
|
13620
|
+
hasPendingCommentDraft,
|
|
13621
|
+
commentTargetElement,
|
|
13622
|
+
comments,
|
|
13623
|
+
setActiveCommentId,
|
|
13624
|
+
addComment
|
|
13625
|
+
]);
|
|
12990
13626
|
React34.useEffect(() => {
|
|
12991
13627
|
const previous = previousCommentTriggerRef.current;
|
|
12992
13628
|
previousCommentTriggerRef.current = { editModeActive, commentTargetElement };
|
|
@@ -13062,6 +13698,7 @@ function DirectEditPanelContent() {
|
|
|
13062
13698
|
comment: activeDraftComment,
|
|
13063
13699
|
attentionNonce: commentInputAttention?.commentId === activeDraftComment.id ? commentInputAttention.nonce : 0,
|
|
13064
13700
|
draftRef: commentDraftRef,
|
|
13701
|
+
onDraftTextChange: setCommentDraftText,
|
|
13065
13702
|
onSubmit: (text) => submitCommentDraft(activeDraftComment.id, text),
|
|
13066
13703
|
onCancel: () => handleSetActiveComment(null)
|
|
13067
13704
|
}
|
|
@@ -13082,58 +13719,81 @@ function DirectEditPanelContent() {
|
|
|
13082
13719
|
if (pageTitle.length > 0) return pageTitle;
|
|
13083
13720
|
return getElementDisplayName(pageFrameElement);
|
|
13084
13721
|
}, [pageFrameElement]);
|
|
13085
|
-
const handleSelectSelectionColorTarget = React34.useCallback(
|
|
13086
|
-
|
|
13087
|
-
|
|
13088
|
-
|
|
13089
|
-
|
|
13090
|
-
|
|
13091
|
-
|
|
13092
|
-
|
|
13093
|
-
const
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
|
|
13097
|
-
|
|
13098
|
-
|
|
13099
|
-
const currentTextColor = computed.color;
|
|
13100
|
-
const matches = (raw, fallback) => {
|
|
13101
|
-
const parsed = parseVisibleColor3(raw, fallback);
|
|
13102
|
-
return Boolean(parsed && toKey(parsed) === targetKey);
|
|
13722
|
+
const handleSelectSelectionColorTarget = React34.useCallback(
|
|
13723
|
+
(targetColor) => {
|
|
13724
|
+
if (!selectedElement) return;
|
|
13725
|
+
const toKey = (color) => `${color.hex.toUpperCase()}:${Math.round(color.alpha)}`;
|
|
13726
|
+
const targetKey = toKey(targetColor);
|
|
13727
|
+
const hasOwnText2 = (node) => Array.from(node.childNodes).some(
|
|
13728
|
+
(child) => child.nodeType === Node.TEXT_NODE && (child.textContent ?? "").trim().length > 0
|
|
13729
|
+
);
|
|
13730
|
+
const parseVisibleColor3 = (raw, fallbackCurrentColor) => {
|
|
13731
|
+
const trimmed = raw.trim();
|
|
13732
|
+
if (!trimmed || trimmed === "none" || trimmed === "transparent") return null;
|
|
13733
|
+
const resolved = trimmed.toLowerCase() === "currentcolor" ? fallbackCurrentColor ?? trimmed : trimmed;
|
|
13734
|
+
const parsed = parseColorValue(resolved);
|
|
13735
|
+
return parsed.alpha > 0 ? parsed : null;
|
|
13103
13736
|
};
|
|
13104
|
-
|
|
13105
|
-
|
|
13106
|
-
|
|
13107
|
-
|
|
13108
|
-
|
|
13109
|
-
|
|
13110
|
-
|
|
13111
|
-
|
|
13112
|
-
|
|
13113
|
-
|
|
13737
|
+
const hasMatchingColor = (node) => {
|
|
13738
|
+
const computed = window.getComputedStyle(node);
|
|
13739
|
+
const currentTextColor = computed.color;
|
|
13740
|
+
const matches = (raw, fallback) => {
|
|
13741
|
+
const parsed = parseVisibleColor3(raw, fallback);
|
|
13742
|
+
return Boolean(parsed && toKey(parsed) === targetKey);
|
|
13743
|
+
};
|
|
13744
|
+
if (matches(computed.backgroundColor)) return true;
|
|
13745
|
+
if (hasOwnText2(node) && matches(currentTextColor)) return true;
|
|
13746
|
+
const borderSides = [
|
|
13747
|
+
{
|
|
13748
|
+
style: computed.borderTopStyle,
|
|
13749
|
+
width: computed.borderTopWidth,
|
|
13750
|
+
color: computed.borderTopColor
|
|
13751
|
+
},
|
|
13752
|
+
{
|
|
13753
|
+
style: computed.borderRightStyle,
|
|
13754
|
+
width: computed.borderRightWidth,
|
|
13755
|
+
color: computed.borderRightColor
|
|
13756
|
+
},
|
|
13757
|
+
{
|
|
13758
|
+
style: computed.borderBottomStyle,
|
|
13759
|
+
width: computed.borderBottomWidth,
|
|
13760
|
+
color: computed.borderBottomColor
|
|
13761
|
+
},
|
|
13762
|
+
{
|
|
13763
|
+
style: computed.borderLeftStyle,
|
|
13764
|
+
width: computed.borderLeftWidth,
|
|
13765
|
+
color: computed.borderLeftColor
|
|
13766
|
+
}
|
|
13767
|
+
];
|
|
13768
|
+
for (const side of borderSides) {
|
|
13769
|
+
if (side.style !== "none" && parseFloat(side.width) > 0 && matches(side.color, currentTextColor)) {
|
|
13770
|
+
return true;
|
|
13771
|
+
}
|
|
13772
|
+
}
|
|
13773
|
+
if (computed.outlineStyle !== "none" && parseFloat(computed.outlineWidth) > 0 && matches(computed.outlineColor, currentTextColor)) {
|
|
13114
13774
|
return true;
|
|
13115
13775
|
}
|
|
13776
|
+
if (node instanceof SVGGraphicsElement) {
|
|
13777
|
+
const fillMatch = matches(computed.getPropertyValue("fill"), currentTextColor) || matches(node.getAttribute("fill") ?? "", currentTextColor);
|
|
13778
|
+
const strokeMatch = matches(computed.getPropertyValue("stroke"), currentTextColor) || matches(node.getAttribute("stroke") ?? "", currentTextColor);
|
|
13779
|
+
if (fillMatch || strokeMatch) return true;
|
|
13780
|
+
}
|
|
13781
|
+
return false;
|
|
13782
|
+
};
|
|
13783
|
+
const descendants = Array.from(selectedElement.querySelectorAll("*"));
|
|
13784
|
+
const firstDescendantMatch = descendants.find(
|
|
13785
|
+
(node) => node instanceof HTMLElement && hasMatchingColor(node)
|
|
13786
|
+
);
|
|
13787
|
+
if (firstDescendantMatch) {
|
|
13788
|
+
selectElement(firstDescendantMatch);
|
|
13789
|
+
return;
|
|
13116
13790
|
}
|
|
13117
|
-
if (
|
|
13118
|
-
|
|
13119
|
-
}
|
|
13120
|
-
if (node instanceof SVGGraphicsElement) {
|
|
13121
|
-
const fillMatch = matches(computed.getPropertyValue("fill"), currentTextColor) || matches(node.getAttribute("fill") ?? "", currentTextColor);
|
|
13122
|
-
const strokeMatch = matches(computed.getPropertyValue("stroke"), currentTextColor) || matches(node.getAttribute("stroke") ?? "", currentTextColor);
|
|
13123
|
-
if (fillMatch || strokeMatch) return true;
|
|
13791
|
+
if (hasMatchingColor(selectedElement)) {
|
|
13792
|
+
selectElement(selectedElement);
|
|
13124
13793
|
}
|
|
13125
|
-
|
|
13126
|
-
|
|
13127
|
-
|
|
13128
|
-
const firstDescendantMatch = descendants.find((node) => node instanceof HTMLElement && hasMatchingColor(node));
|
|
13129
|
-
if (firstDescendantMatch) {
|
|
13130
|
-
selectElement(firstDescendantMatch);
|
|
13131
|
-
return;
|
|
13132
|
-
}
|
|
13133
|
-
if (hasMatchingColor(selectedElement)) {
|
|
13134
|
-
selectElement(selectedElement);
|
|
13135
|
-
}
|
|
13136
|
-
}, [selectedElement, selectElement]);
|
|
13794
|
+
},
|
|
13795
|
+
[selectedElement, selectElement]
|
|
13796
|
+
);
|
|
13137
13797
|
const handleMoveStart = (e, targetElement, options) => {
|
|
13138
13798
|
const elementToDrag = targetElement ?? selectedElement;
|
|
13139
13799
|
if (elementToDrag) {
|
|
@@ -13222,7 +13882,11 @@ function DirectEditPanelContent() {
|
|
|
13222
13882
|
hoveredElement,
|
|
13223
13883
|
measurements: [
|
|
13224
13884
|
...measurements,
|
|
13225
|
-
...calculateGuidelineMeasurements(
|
|
13885
|
+
...calculateGuidelineMeasurements(
|
|
13886
|
+
selectedElement,
|
|
13887
|
+
getStoredGuidelines(),
|
|
13888
|
+
mousePosition
|
|
13889
|
+
)
|
|
13226
13890
|
]
|
|
13227
13891
|
}
|
|
13228
13892
|
),
|
|
@@ -13277,6 +13941,9 @@ function DirectEditPanelContent() {
|
|
|
13277
13941
|
onSelectSelectionColorTarget: handleSelectSelectionColorTarget,
|
|
13278
13942
|
onUpdateTypography: updateTypographyProperty,
|
|
13279
13943
|
onReset: resetToOriginal,
|
|
13944
|
+
onExportEdits: exportEdits,
|
|
13945
|
+
onSendToAgent: agentAvailable ? sendEditToAgent2 : void 0,
|
|
13946
|
+
sendFailureReason: lastSendFailure?.reason ?? null,
|
|
13280
13947
|
className: "fixed z-[99999]",
|
|
13281
13948
|
style: {
|
|
13282
13949
|
left: position.x,
|
|
@@ -14148,7 +14815,7 @@ function useToolbarDock(toolbarRef) {
|
|
|
14148
14815
|
}
|
|
14149
14816
|
|
|
14150
14817
|
// src/toolbar.tsx
|
|
14151
|
-
import { MousePointer2, Command as Command2, Send as Send3, Check as Check8, X as X5 } from "lucide-react";
|
|
14818
|
+
import { MousePointer2, Command as Command2, Send as Send3, Check as Check8, X as X5, Square as Square2, Type as Type2 } from "lucide-react";
|
|
14152
14819
|
|
|
14153
14820
|
// src/toolbar/edits-popover.tsx
|
|
14154
14821
|
import * as React38 from "react";
|
|
@@ -14211,7 +14878,8 @@ function EditsPopover({
|
|
|
14211
14878
|
onExportAllEdits,
|
|
14212
14879
|
onClearSessionEdits,
|
|
14213
14880
|
onRemoveSessionEdit,
|
|
14214
|
-
onDeleteComment
|
|
14881
|
+
onDeleteComment,
|
|
14882
|
+
sendFailure
|
|
14215
14883
|
}) {
|
|
14216
14884
|
const [copied, setCopied] = React38.useState(false);
|
|
14217
14885
|
const editsPopupRef = React38.useRef(null);
|
|
@@ -14224,6 +14892,7 @@ function EditsPopover({
|
|
|
14224
14892
|
const visibleItems = React38.useMemo(() => {
|
|
14225
14893
|
return editsSnapshot.filter((item) => {
|
|
14226
14894
|
if (item.type === "comment") return true;
|
|
14895
|
+
if (item.edit.deleted) return true;
|
|
14227
14896
|
if (!item.edit.move) return true;
|
|
14228
14897
|
const moveIntent = getMoveIntentForEdit(item.edit, movePlanContext);
|
|
14229
14898
|
const hasStyleOrText = Object.keys(item.edit.pendingStyles).length > 0 || item.edit.textEdit != null;
|
|
@@ -14328,12 +14997,15 @@ ${text}`);
|
|
|
14328
14997
|
visibleItems.length === 0 && multiSelectContextItems.length === 0 ? /* @__PURE__ */ jsx32("div", { className: "px-3 pb-3 pt-1 text-xs text-muted-foreground", children: "No edits or comments yet." }) : /* @__PURE__ */ jsxs25("div", { className: "max-h-[240px] overflow-y-auto px-1 py-1", children: [
|
|
14329
14998
|
visibleItems.map((item, i) => {
|
|
14330
14999
|
const isEdit = item.type === "edit";
|
|
15000
|
+
const isDeleted = isEdit && Boolean(item.edit.deleted);
|
|
14331
15001
|
const moveIntent = isEdit && item.edit.move ? getMoveIntentForEdit(item.edit, movePlanContext) : null;
|
|
14332
15002
|
const isMoved = Boolean(moveIntent);
|
|
14333
15003
|
const locator = isEdit ? item.edit.locator : item.comment.locator;
|
|
14334
15004
|
const componentName = locator.reactStack[0]?.name ?? locator.tagName;
|
|
14335
15005
|
let valueSummary = "";
|
|
14336
|
-
if (isEdit) {
|
|
15006
|
+
if (isEdit && isDeleted) {
|
|
15007
|
+
valueSummary = locator.textPreview || locator.domSelector || locator.tagName;
|
|
15008
|
+
} else if (isEdit) {
|
|
14337
15009
|
const entries = Object.entries(item.edit.pendingStyles);
|
|
14338
15010
|
const editValues = [];
|
|
14339
15011
|
for (const [prop, value] of entries) {
|
|
@@ -14354,6 +15026,7 @@ ${text}`);
|
|
|
14354
15026
|
}
|
|
14355
15027
|
valueSummary = commentValues.join(", ");
|
|
14356
15028
|
}
|
|
15029
|
+
const failed = isEdit ? sendFailure?.failedEditElements.includes(item.edit.element) : sendFailure?.failedCommentIds.includes(item.comment.id);
|
|
14357
15030
|
return /* @__PURE__ */ jsxs25(
|
|
14358
15031
|
"div",
|
|
14359
15032
|
{
|
|
@@ -14372,13 +15045,16 @@ ${text}`);
|
|
|
14372
15045
|
},
|
|
14373
15046
|
children: [
|
|
14374
15047
|
/* @__PURE__ */ jsxs25("div", { className: "min-w-0 flex flex-1 flex-col items-start gap-[4px]", children: [
|
|
14375
|
-
/* @__PURE__ */ jsxs25(
|
|
14376
|
-
"
|
|
14377
|
-
|
|
14378
|
-
|
|
15048
|
+
/* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-1", children: [
|
|
15049
|
+
/* @__PURE__ */ jsxs25(Badge, { variant: "secondary", className: "h-6 shrink-0 px-1.5 text-xs", children: [
|
|
15050
|
+
"@<",
|
|
15051
|
+
componentName,
|
|
15052
|
+
">"
|
|
15053
|
+
] }),
|
|
15054
|
+
failed && /* @__PURE__ */ jsx32(Badge, { variant: "default", className: "h-6 shrink-0 px-1.5 text-xs bg-red-500 text-white border-transparent", children: "Failed" })
|
|
14379
15055
|
] }),
|
|
14380
15056
|
/* @__PURE__ */ jsxs25("span", { className: "min-w-0 max-w-full truncate text-xs text-muted-foreground", children: [
|
|
14381
|
-
isEdit ? isMoved ? "moved: " : "edit: " : "comment: ",
|
|
15057
|
+
isEdit ? isDeleted ? "deleted: " : isMoved ? "moved: " : "edit: " : "comment: ",
|
|
14382
15058
|
truncateText(valueSummary, 128)
|
|
14383
15059
|
] })
|
|
14384
15060
|
] }),
|
|
@@ -14643,6 +15319,7 @@ function SettingsPopover({
|
|
|
14643
15319
|
{ label: "Undo", keys: isMac ? [/* @__PURE__ */ jsx33(Command, { className: "size-2.5" }, "cmd"), "Z"] : ["Ctrl", "Z"] },
|
|
14644
15320
|
{ label: "Group selection", keys: isMac ? [/* @__PURE__ */ jsx33(Command, { className: "size-2.5" }, "cmd"), "G"] : ["Ctrl", "G"] },
|
|
14645
15321
|
{ label: "Add frame", keys: ["F"] },
|
|
15322
|
+
{ label: "Add text", keys: ["T"] },
|
|
14646
15323
|
{ label: "Add div", keys: ["D"] },
|
|
14647
15324
|
{ label: "Add to selection", keys: [/* @__PURE__ */ jsx33(ArrowBigUp, { className: "size-3" }, "shift"), "Click"] },
|
|
14648
15325
|
{ label: "Marquee select", keys: ["Drag"] },
|
|
@@ -14685,6 +15362,8 @@ function DirectEditToolbarInner({
|
|
|
14685
15362
|
onExportAllEdits,
|
|
14686
15363
|
onSendAllToAgents,
|
|
14687
15364
|
agentAvailable = true,
|
|
15365
|
+
sendFailureReason,
|
|
15366
|
+
sendFailure,
|
|
14688
15367
|
onClearSessionEdits,
|
|
14689
15368
|
onRemoveSessionEdit,
|
|
14690
15369
|
onDeleteComment,
|
|
@@ -14694,7 +15373,8 @@ function DirectEditToolbarInner({
|
|
|
14694
15373
|
onToggleCanvas,
|
|
14695
15374
|
onSetCanvasZoom,
|
|
14696
15375
|
onZoomTo100,
|
|
14697
|
-
onFitToViewport
|
|
15376
|
+
onFitToViewport,
|
|
15377
|
+
onInsertElement
|
|
14698
15378
|
}) {
|
|
14699
15379
|
const container = usePortalContainer();
|
|
14700
15380
|
const toolbarRef = React40.useRef(null);
|
|
@@ -14703,7 +15383,8 @@ function DirectEditToolbarInner({
|
|
|
14703
15383
|
const [activePopover, setActivePopover] = React40.useState(null);
|
|
14704
15384
|
const [applyStatus, setApplyStatus] = React40.useState("idle");
|
|
14705
15385
|
const applyTimerRef = React40.useRef(null);
|
|
14706
|
-
const showApplyButton = agentAvailable && Boolean(onSendAllToAgents);
|
|
15386
|
+
const showApplyButton = (agentAvailable || applyStatus !== "idle") && Boolean(onSendAllToAgents);
|
|
15387
|
+
const showInsertButtons = Boolean(onInsertElement);
|
|
14707
15388
|
const totalItemCount = sessionEditCount + multiSelectCount;
|
|
14708
15389
|
const sizeCacheRef = React40.useRef({});
|
|
14709
15390
|
React40.useEffect(() => {
|
|
@@ -14757,6 +15438,16 @@ function DirectEditToolbarInner({
|
|
|
14757
15438
|
setApplyStatus("idle");
|
|
14758
15439
|
}, 2e3);
|
|
14759
15440
|
}, []);
|
|
15441
|
+
const prevTotalItemCountRef = React40.useRef(totalItemCount);
|
|
15442
|
+
React40.useEffect(() => {
|
|
15443
|
+
if (prevTotalItemCountRef.current !== totalItemCount) {
|
|
15444
|
+
prevTotalItemCountRef.current = totalItemCount;
|
|
15445
|
+
if (applyStatus === "offline") {
|
|
15446
|
+
setApplyStatus("idle");
|
|
15447
|
+
}
|
|
15448
|
+
}
|
|
15449
|
+
}, [totalItemCount, applyStatus]);
|
|
15450
|
+
const applyTooltipLabel = applyStatus === "offline" ? sendFailureReason === "unreachable" ? "Agent unreachable \u2014 click to retry" : "Agent rejected the edit \u2014 click to retry" : "Apply all changes via agent";
|
|
14760
15451
|
const handleApplyAll = React40.useCallback(async () => {
|
|
14761
15452
|
if (!onSendAllToAgents || totalItemCount === 0 || applyStatus === "sending") return;
|
|
14762
15453
|
setApplyStatus("sending");
|
|
@@ -14766,8 +15457,12 @@ function DirectEditToolbarInner({
|
|
|
14766
15457
|
} catch {
|
|
14767
15458
|
success = false;
|
|
14768
15459
|
}
|
|
14769
|
-
|
|
14770
|
-
|
|
15460
|
+
if (success) {
|
|
15461
|
+
setApplyStatus("sent");
|
|
15462
|
+
scheduleApplyReset();
|
|
15463
|
+
} else {
|
|
15464
|
+
setApplyStatus("offline");
|
|
15465
|
+
}
|
|
14771
15466
|
}, [applyStatus, onSendAllToAgents, scheduleApplyReset, totalItemCount]);
|
|
14772
15467
|
const dragHandlers = React40.useMemo(() => ({
|
|
14773
15468
|
onPointerDown: handlePointerDown,
|
|
@@ -14848,6 +15543,38 @@ function DirectEditToolbarInner({
|
|
|
14848
15543
|
},
|
|
14849
15544
|
...dragHandlers,
|
|
14850
15545
|
children: [
|
|
15546
|
+
showInsertButtons && /* @__PURE__ */ jsxs27(Fragment8, { children: [
|
|
15547
|
+
/* @__PURE__ */ jsxs27(Tooltip, { children: [
|
|
15548
|
+
/* @__PURE__ */ jsx34(
|
|
15549
|
+
TooltipTrigger,
|
|
15550
|
+
{
|
|
15551
|
+
className: cn(toolbarBtnClass, "text-muted-foreground hover:bg-muted hover:text-foreground"),
|
|
15552
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
15553
|
+
onClick: () => onInsertElement?.("frame"),
|
|
15554
|
+
children: /* @__PURE__ */ jsx34(Square2, { className: "size-4" })
|
|
15555
|
+
}
|
|
15556
|
+
),
|
|
15557
|
+
/* @__PURE__ */ jsxs27(TooltipContent, { side: tooltipSide, className: "inline-flex items-center gap-1.5", children: [
|
|
15558
|
+
/* @__PURE__ */ jsx34("span", { children: "Add frame" }),
|
|
15559
|
+
/* @__PURE__ */ jsx34("kbd", { className: kbdClass, children: "F" })
|
|
15560
|
+
] })
|
|
15561
|
+
] }),
|
|
15562
|
+
/* @__PURE__ */ jsxs27(Tooltip, { children: [
|
|
15563
|
+
/* @__PURE__ */ jsx34(
|
|
15564
|
+
TooltipTrigger,
|
|
15565
|
+
{
|
|
15566
|
+
className: cn(toolbarBtnClass, "text-muted-foreground hover:bg-muted hover:text-foreground"),
|
|
15567
|
+
onPointerDown: (e) => e.stopPropagation(),
|
|
15568
|
+
onClick: () => onInsertElement?.("text"),
|
|
15569
|
+
children: /* @__PURE__ */ jsx34(Type2, { className: "size-4" })
|
|
15570
|
+
}
|
|
15571
|
+
),
|
|
15572
|
+
/* @__PURE__ */ jsxs27(TooltipContent, { side: tooltipSide, className: "inline-flex items-center gap-1.5", children: [
|
|
15573
|
+
/* @__PURE__ */ jsx34("span", { children: "Add text" }),
|
|
15574
|
+
/* @__PURE__ */ jsx34("kbd", { className: kbdClass, children: "T" })
|
|
15575
|
+
] })
|
|
15576
|
+
] })
|
|
15577
|
+
] }),
|
|
14851
15578
|
/* @__PURE__ */ jsx34(
|
|
14852
15579
|
EditsPopover,
|
|
14853
15580
|
{
|
|
@@ -14860,7 +15587,8 @@ function DirectEditToolbarInner({
|
|
|
14860
15587
|
onExportAllEdits,
|
|
14861
15588
|
onClearSessionEdits,
|
|
14862
15589
|
onRemoveSessionEdit,
|
|
14863
|
-
onDeleteComment
|
|
15590
|
+
onDeleteComment,
|
|
15591
|
+
sendFailure
|
|
14864
15592
|
}
|
|
14865
15593
|
),
|
|
14866
15594
|
showApplyButton && /* @__PURE__ */ jsxs27(Tooltip, { children: [
|
|
@@ -14884,7 +15612,7 @@ function DirectEditToolbarInner({
|
|
|
14884
15612
|
]
|
|
14885
15613
|
}
|
|
14886
15614
|
),
|
|
14887
|
-
/* @__PURE__ */ jsx34(TooltipContent, { side: tooltipSide, children: /* @__PURE__ */ jsx34("span", { children:
|
|
15615
|
+
/* @__PURE__ */ jsx34(TooltipContent, { side: tooltipSide, children: /* @__PURE__ */ jsx34("span", { children: applyTooltipLabel }) })
|
|
14888
15616
|
] }),
|
|
14889
15617
|
/* @__PURE__ */ jsx34(
|
|
14890
15618
|
"div",
|
|
@@ -14946,7 +15674,7 @@ function DirectEditToolbarInner({
|
|
|
14946
15674
|
return toolbar;
|
|
14947
15675
|
}
|
|
14948
15676
|
function DirectEditToolbarContent() {
|
|
14949
|
-
const { editModeActive, theme, sessionEditCount, multiSelectContextCount, selectedElements, canvas, agentAvailable } = useDirectEditState();
|
|
15677
|
+
const { editModeActive, theme, sessionEditCount, multiSelectContextCount, selectedElements, canvas, agentAvailable, lastSendFailure } = useDirectEditState();
|
|
14950
15678
|
const {
|
|
14951
15679
|
toggleEditMode,
|
|
14952
15680
|
setTheme,
|
|
@@ -14956,6 +15684,7 @@ function DirectEditToolbarContent() {
|
|
|
14956
15684
|
clearSessionEdits,
|
|
14957
15685
|
removeSessionEdit,
|
|
14958
15686
|
deleteComment,
|
|
15687
|
+
insertElement,
|
|
14959
15688
|
toggleCanvas,
|
|
14960
15689
|
setCanvasZoom,
|
|
14961
15690
|
zoomCanvasTo100,
|
|
@@ -14978,6 +15707,8 @@ function DirectEditToolbarContent() {
|
|
|
14978
15707
|
onExportAllEdits: exportAllEdits,
|
|
14979
15708
|
onSendAllToAgents: sendAllSessionItemsToAgent,
|
|
14980
15709
|
agentAvailable,
|
|
15710
|
+
sendFailureReason: lastSendFailure?.reason ?? null,
|
|
15711
|
+
sendFailure: lastSendFailure,
|
|
14981
15712
|
onClearSessionEdits: clearSessionEdits,
|
|
14982
15713
|
onRemoveSessionEdit: removeSessionEdit,
|
|
14983
15714
|
onDeleteComment: deleteComment,
|
|
@@ -14986,7 +15717,8 @@ function DirectEditToolbarContent() {
|
|
|
14986
15717
|
onToggleCanvas: toggleCanvas,
|
|
14987
15718
|
onSetCanvasZoom: setCanvasZoom,
|
|
14988
15719
|
onZoomTo100: zoomCanvasTo100,
|
|
14989
|
-
onFitToViewport: fitCanvasToViewport
|
|
15720
|
+
onFitToViewport: fitCanvasToViewport,
|
|
15721
|
+
onInsertElement: insertElement
|
|
14990
15722
|
}
|
|
14991
15723
|
);
|
|
14992
15724
|
}
|