made-refine 0.2.6 → 0.2.7
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/dist/index.d.mts +17 -7
- package/dist/index.d.ts +17 -7
- package/dist/index.js +1332 -224
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1330 -224
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/{utils-C7RBdUAE.d.mts → utils-dcZIwXa7.d.mts} +114 -2
- package/dist/{utils-C7RBdUAE.d.ts → utils-dcZIwXa7.d.ts} +114 -2
- package/dist/utils.d.mts +1 -1
- package/dist/utils.d.ts +1 -1
- package/dist/utils.js +661 -62
- package/dist/utils.js.map +1 -1
- package/dist/utils.mjs +650 -62
- package/dist/utils.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -53,6 +53,7 @@ __export(index_exports, {
|
|
|
53
53
|
colorToTailwind: () => colorToTailwind,
|
|
54
54
|
elementFromPointWithoutOverlays: () => elementFromPointWithoutOverlays,
|
|
55
55
|
findContainerAtPoint: () => findContainerAtPoint,
|
|
56
|
+
findLayoutContainerAtPoint: () => findLayoutContainerAtPoint,
|
|
56
57
|
formatColorValue: () => formatColorValue,
|
|
57
58
|
formatPropertyValue: () => formatPropertyValue,
|
|
58
59
|
getComputedBorderStyles: () => getComputedBorderStyles,
|
|
@@ -65,6 +66,7 @@ __export(index_exports, {
|
|
|
65
66
|
getFlexDirection: () => getFlexDirection,
|
|
66
67
|
getStoredGuidelines: () => getStoredGuidelines,
|
|
67
68
|
isFlexContainer: () => isFlexContainer,
|
|
69
|
+
isLayoutContainer: () => isLayoutContainer,
|
|
68
70
|
parseColorValue: () => parseColorValue,
|
|
69
71
|
parsePropertyValue: () => parsePropertyValue,
|
|
70
72
|
stylesToTailwind: () => stylesToTailwind,
|
|
@@ -85,7 +87,7 @@ var React8 = __toESM(require("react"));
|
|
|
85
87
|
var React = __toESM(require("react"));
|
|
86
88
|
|
|
87
89
|
// dist/styles.css
|
|
88
|
-
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-lg:.5rem;--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}.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-\\[30px\\]{width:30px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[260px\\]{width:260px}.w-\\[280px\\]{width:280px}.w-\\[300px\\]{width:300px}.w-\\[340px\\]{width:340px}.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}.\\[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-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-1\\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}: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)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.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-lg{border-radius:var(--radius-lg)}.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-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\\.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-3{padding-left:calc(var(--spacing)*3)}.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}.text-\\[11px\\]{font-size:11px}.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)}.whitespace-nowrap{white-space:nowrap}.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-dashed{--tw-outline-style:dashed;outline-style:dashed}.outline-dotted{--tw-outline-style:dotted;outline-style:dotted}.outline-double{--tw-outline-style:double;outline-style:double}.outline-none{--tw-outline-style:none;outline-style:none}.outline-solid{--tw-outline-style:solid;outline-style:solid}.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}.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}.disabled\\:opacity-60:disabled{opacity:.6}.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-4 svg{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\\[\\&_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}}';
|
|
90
|
+
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-lg:.5rem;--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-\\[30px\\]{width:30px}.w-\\[60px\\]{width:60px}.w-\\[68px\\]{width:68px}.w-\\[180px\\]{width:180px}.w-\\[200px\\]{width:200px}.w-\\[260px\\]{width:260px}.w-\\[280px\\]{width:280px}.w-\\[300px\\]{width:300px}.w-\\[340px\\]{width:340px}.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}.\\[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-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}.gap-\\[2px\\]{gap:2px}.gap-\\[4px\\]{gap:4px}:where(.space-y-1\\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1.5)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1.5)*calc(1 - var(--tw-space-y-reverse)))}: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)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*4)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*4)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.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-lg{border-radius:var(--radius-lg)}.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-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\\.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-3{padding-left:calc(var(--spacing)*3)}.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}.text-\\[11px\\]{font-size:11px}.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)}.whitespace-nowrap{white-space:nowrap}.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-dashed{--tw-outline-style:dashed;outline-style:dashed}.outline-dotted{--tw-outline-style:dotted;outline-style:dotted}.outline-double{--tw-outline-style:double;outline-style:double}.outline-none{--tw-outline-style:none;outline-style:none}.outline-solid{--tw-outline-style:solid;outline-style:solid}.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}.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}.disabled\\:opacity-60:disabled{opacity:.6}.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-4 svg{width:calc(var(--spacing)*4);height:calc(var(--spacing)*4)}.\\[\\&_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}}';
|
|
89
91
|
|
|
90
92
|
// src/portal-container.tsx
|
|
91
93
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -1221,6 +1223,10 @@ function getFlexDirection(element) {
|
|
|
1221
1223
|
const computed = window.getComputedStyle(element);
|
|
1222
1224
|
return computed.flexDirection;
|
|
1223
1225
|
}
|
|
1226
|
+
function isInFlowChild(el) {
|
|
1227
|
+
const cs = window.getComputedStyle(el);
|
|
1228
|
+
return cs.display !== "none" && cs.position !== "absolute" && cs.position !== "fixed";
|
|
1229
|
+
}
|
|
1224
1230
|
function detectChildrenDirection(container, exclude) {
|
|
1225
1231
|
const computed = window.getComputedStyle(container);
|
|
1226
1232
|
if (computed.display === "flex" || computed.display === "inline-flex") {
|
|
@@ -1233,8 +1239,7 @@ function detectChildrenDirection(container, exclude) {
|
|
|
1233
1239
|
const visible = [];
|
|
1234
1240
|
for (const c of container.children) {
|
|
1235
1241
|
if (!(c instanceof HTMLElement) || c === exclude) continue;
|
|
1236
|
-
|
|
1237
|
-
if (cs.display === "none" || cs.position === "absolute" || cs.position === "fixed") continue;
|
|
1242
|
+
if (!isInFlowChild(c)) continue;
|
|
1238
1243
|
visible.push(c);
|
|
1239
1244
|
if (visible.length === 2) break;
|
|
1240
1245
|
}
|
|
@@ -1247,6 +1252,29 @@ function detectChildrenDirection(container, exclude) {
|
|
|
1247
1252
|
}
|
|
1248
1253
|
return { axis: "vertical", reversed: second.bottom < first.top };
|
|
1249
1254
|
}
|
|
1255
|
+
function computeIntendedIndex(parent, draggedElement) {
|
|
1256
|
+
const { axis } = detectChildrenDirection(parent, draggedElement);
|
|
1257
|
+
const isHorizontal = axis === "horizontal";
|
|
1258
|
+
const draggedRect = draggedElement.getBoundingClientRect();
|
|
1259
|
+
const intendedCenter = isHorizontal ? draggedRect.left + draggedRect.width / 2 : draggedRect.top + draggedRect.height / 2;
|
|
1260
|
+
const siblings = [];
|
|
1261
|
+
for (const c of parent.children) {
|
|
1262
|
+
if (!(c instanceof HTMLElement) || c === draggedElement) continue;
|
|
1263
|
+
if (!isInFlowChild(c)) continue;
|
|
1264
|
+
siblings.push(c);
|
|
1265
|
+
}
|
|
1266
|
+
if (siblings.length === 0) {
|
|
1267
|
+
return { index: 0, siblingBefore: null, siblingAfter: null };
|
|
1268
|
+
}
|
|
1269
|
+
for (let i = 0; i < siblings.length; i++) {
|
|
1270
|
+
const rect = siblings[i].getBoundingClientRect();
|
|
1271
|
+
const midpoint = isHorizontal ? rect.left + rect.width / 2 : rect.top + rect.height / 2;
|
|
1272
|
+
if (intendedCenter < midpoint) {
|
|
1273
|
+
return { index: i, siblingBefore: i > 0 ? siblings[i - 1] : null, siblingAfter: siblings[i] };
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
return { index: siblings.length, siblingBefore: siblings[siblings.length - 1], siblingAfter: null };
|
|
1277
|
+
}
|
|
1250
1278
|
function htmlChildren(el) {
|
|
1251
1279
|
return Array.from(el.children).filter(
|
|
1252
1280
|
(child) => child instanceof HTMLElement
|
|
@@ -1347,6 +1375,22 @@ function findContainerAtPoint(x, y, exclude, preferredParent) {
|
|
|
1347
1375
|
}
|
|
1348
1376
|
return findContainerViaTraversal(x, y, exclude);
|
|
1349
1377
|
}
|
|
1378
|
+
function findLayoutContainerAtPoint(x, y, exclude, preferredParent) {
|
|
1379
|
+
const host = document.querySelector("[data-direct-edit-host]");
|
|
1380
|
+
if (host) host.style.display = "none";
|
|
1381
|
+
const elements = document.elementsFromPoint(x, y);
|
|
1382
|
+
if (host) host.style.display = "";
|
|
1383
|
+
for (const el of elements) {
|
|
1384
|
+
if (skipElement(el, exclude)) continue;
|
|
1385
|
+
if (isLayoutContainer(el)) return el;
|
|
1386
|
+
}
|
|
1387
|
+
if (preferredParent && isLayoutContainer(preferredParent)) {
|
|
1388
|
+
for (const el of elements) {
|
|
1389
|
+
if (el === preferredParent) return preferredParent;
|
|
1390
|
+
}
|
|
1391
|
+
}
|
|
1392
|
+
return null;
|
|
1393
|
+
}
|
|
1350
1394
|
function calculateDropPosition(container, pointerX, pointerY, draggedElement) {
|
|
1351
1395
|
const { axis, reversed: isReversed } = detectChildrenDirection(container, draggedElement);
|
|
1352
1396
|
const isHorizontal = axis === "horizontal";
|
|
@@ -1741,7 +1785,11 @@ function getReactComponentStack(element) {
|
|
|
1741
1785
|
return getRenderStack(fiber);
|
|
1742
1786
|
}
|
|
1743
1787
|
function getElementDisplayName(element) {
|
|
1744
|
-
|
|
1788
|
+
const tag = element.tagName.toLowerCase();
|
|
1789
|
+
if (element.id) return `${tag}#${element.id}`;
|
|
1790
|
+
const firstClass = Array.from(element.classList).find((c) => c && !c.startsWith("direct-edit"));
|
|
1791
|
+
if (firstClass) return `${tag}.${firstClass}`;
|
|
1792
|
+
return tag;
|
|
1745
1793
|
}
|
|
1746
1794
|
var STABLE_ATTRIBUTES = ["data-testid", "data-qa", "data-cy", "aria-label", "role"];
|
|
1747
1795
|
var MAX_SELECTOR_DEPTH = 24;
|
|
@@ -2029,26 +2077,28 @@ function parseDomSource(element) {
|
|
|
2029
2077
|
}
|
|
2030
2078
|
return { file, line, column };
|
|
2031
2079
|
}
|
|
2032
|
-
function
|
|
2033
|
-
const
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
|
|
2037
|
-
|
|
2038
|
-
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
|
|
2042
|
-
|
|
2043
|
-
|
|
2044
|
-
|
|
2045
|
-
|
|
2046
|
-
};
|
|
2047
|
-
break;
|
|
2048
|
-
}
|
|
2049
|
-
fiber = fiber._debugOwner ?? fiber.return ?? null;
|
|
2080
|
+
function getElementSource(element) {
|
|
2081
|
+
const domSource = parseDomSource(element);
|
|
2082
|
+
if (domSource) return domSource;
|
|
2083
|
+
const seenFibers = /* @__PURE__ */ new Set();
|
|
2084
|
+
let fiber = getFiberForElement(element);
|
|
2085
|
+
while (fiber && !seenFibers.has(fiber)) {
|
|
2086
|
+
seenFibers.add(fiber);
|
|
2087
|
+
const fiberSource = getSourceFromFiber(fiber);
|
|
2088
|
+
if (fiberSource?.fileName) {
|
|
2089
|
+
return {
|
|
2090
|
+
file: fiberSource.fileName,
|
|
2091
|
+
line: fiberSource.lineNumber,
|
|
2092
|
+
column: fiberSource.columnNumber
|
|
2093
|
+
};
|
|
2050
2094
|
}
|
|
2095
|
+
fiber = fiber._debugOwner ?? fiber.return ?? null;
|
|
2051
2096
|
}
|
|
2097
|
+
return null;
|
|
2098
|
+
}
|
|
2099
|
+
function getElementLocator(element) {
|
|
2100
|
+
const elementInfo = getElementInfo(element);
|
|
2101
|
+
const domSource = getElementSource(element);
|
|
2052
2102
|
return {
|
|
2053
2103
|
reactStack: getReactComponentStack(element),
|
|
2054
2104
|
domSelector: buildDomSelector(element),
|
|
@@ -2067,7 +2117,7 @@ function getLocatorHeader(locator) {
|
|
|
2067
2117
|
const formattedSource = locator.domSource?.file ? formatSourceLocation(locator.domSource.file, locator.domSource.line, locator.domSource.column) : primaryFrame?.file ? formatSourceLocation(primaryFrame.file, primaryFrame.line, primaryFrame.column) : null;
|
|
2068
2118
|
return { componentLabel, formattedSource };
|
|
2069
2119
|
}
|
|
2070
|
-
function buildLocatorContextLines(locator) {
|
|
2120
|
+
function buildLocatorContextLines(locator, options) {
|
|
2071
2121
|
const lines = [];
|
|
2072
2122
|
const { componentLabel, formattedSource } = getLocatorHeader(locator);
|
|
2073
2123
|
const target = (locator.targetHtml || locator.domContextHtml || "").trim();
|
|
@@ -2080,7 +2130,7 @@ function buildLocatorContextLines(locator) {
|
|
|
2080
2130
|
lines.push("target:");
|
|
2081
2131
|
lines.push(target);
|
|
2082
2132
|
}
|
|
2083
|
-
if (context && context !== target) {
|
|
2133
|
+
if (!options?.skipContext && context && context !== target) {
|
|
2084
2134
|
lines.push("context:");
|
|
2085
2135
|
lines.push(context);
|
|
2086
2136
|
}
|
|
@@ -2234,6 +2284,29 @@ function buildEditExport(arg1, arg2, arg3, arg4, arg5, arg6, arg7) {
|
|
|
2234
2284
|
}
|
|
2235
2285
|
return lines.join("\n");
|
|
2236
2286
|
}
|
|
2287
|
+
function buildEditExportWithOptions(locator, pendingStyles, textEdit, options) {
|
|
2288
|
+
const changes = [];
|
|
2289
|
+
const collapsedStyles = collapseExportShorthands(pendingStyles);
|
|
2290
|
+
for (const [property, value] of Object.entries(collapsedStyles)) {
|
|
2291
|
+
const tailwindClass = stylesToTailwind({ [property]: value });
|
|
2292
|
+
changes.push({ property, value, tailwind: tailwindClass });
|
|
2293
|
+
}
|
|
2294
|
+
const lines = buildLocatorContextLines(locator, options);
|
|
2295
|
+
lines.push("");
|
|
2296
|
+
if (changes.length > 0) {
|
|
2297
|
+
lines.push("edits:");
|
|
2298
|
+
for (const change of changes) {
|
|
2299
|
+
const tailwind = change.tailwind ? ` (${change.tailwind})` : "";
|
|
2300
|
+
lines.push(`${change.property}: ${change.value}${tailwind}`);
|
|
2301
|
+
}
|
|
2302
|
+
}
|
|
2303
|
+
if (textEdit) {
|
|
2304
|
+
lines.push("text content changed:");
|
|
2305
|
+
lines.push(`from: "${textEdit.originalText}"`);
|
|
2306
|
+
lines.push(`to: "${textEdit.newText}"`);
|
|
2307
|
+
}
|
|
2308
|
+
return lines.join("\n");
|
|
2309
|
+
}
|
|
2237
2310
|
function buildCommentExport(locator, commentText, replies) {
|
|
2238
2311
|
const lines = buildLocatorContextLines(locator);
|
|
2239
2312
|
lines.push("");
|
|
@@ -2245,55 +2318,545 @@ function buildCommentExport(locator, commentText, replies) {
|
|
|
2245
2318
|
}
|
|
2246
2319
|
return lines.join("\n");
|
|
2247
2320
|
}
|
|
2248
|
-
function
|
|
2249
|
-
|
|
2250
|
-
|
|
2251
|
-
if (!siblingBefore && siblingAfter) return `before <${siblingAfter}> (first)`;
|
|
2252
|
-
return "(only child)";
|
|
2321
|
+
function normalizeSelector(selector) {
|
|
2322
|
+
const value = selector?.trim();
|
|
2323
|
+
return value && value.length > 0 ? value : null;
|
|
2253
2324
|
}
|
|
2254
|
-
function
|
|
2255
|
-
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2325
|
+
function normalizeName(name) {
|
|
2326
|
+
return name?.trim().toLowerCase() || "element";
|
|
2327
|
+
}
|
|
2328
|
+
function buildAnchorRef(name, selector, source) {
|
|
2329
|
+
return {
|
|
2330
|
+
name: name?.trim() || "element",
|
|
2331
|
+
selector: normalizeSelector(selector),
|
|
2332
|
+
source: source?.file ? source : null
|
|
2333
|
+
};
|
|
2334
|
+
}
|
|
2335
|
+
function anchorKey(anchor) {
|
|
2336
|
+
if (!anchor) return "none";
|
|
2337
|
+
const selector = normalizeSelector(anchor.selector);
|
|
2338
|
+
if (selector) return `selector:${selector}`;
|
|
2339
|
+
if (anchor.source?.file) {
|
|
2340
|
+
return `source:${anchor.source.file}:${anchor.source.line ?? 0}:${anchor.source.column ?? 0}`;
|
|
2341
|
+
}
|
|
2342
|
+
return `name:${normalizeName(anchor.name)}`;
|
|
2343
|
+
}
|
|
2344
|
+
function anchorsEqual(a, b) {
|
|
2345
|
+
if (!a && !b) return true;
|
|
2346
|
+
if (!a || !b) return false;
|
|
2347
|
+
const aSelector = normalizeSelector(a.selector);
|
|
2348
|
+
const bSelector = normalizeSelector(b.selector);
|
|
2349
|
+
if (aSelector && bSelector) return aSelector === bSelector;
|
|
2350
|
+
if (a.source?.file && b.source?.file) {
|
|
2351
|
+
return a.source.file === b.source.file && (a.source.line ?? null) === (b.source.line ?? null) && (a.source.column ?? null) === (b.source.column ?? null);
|
|
2352
|
+
}
|
|
2353
|
+
return normalizeName(a.name) === normalizeName(b.name);
|
|
2354
|
+
}
|
|
2355
|
+
function formatAnchorRef(anchor, fallback = "(none)") {
|
|
2356
|
+
if (!anchor) return fallback;
|
|
2357
|
+
const selector = normalizeSelector(anchor.selector);
|
|
2358
|
+
if (selector) return selector;
|
|
2359
|
+
if (anchor.source?.file) return `<${anchor.name}> @ ${formatSourceLocation(anchor.source.file, anchor.source.line, anchor.source.column)}`;
|
|
2360
|
+
return `<${anchor.name}>`;
|
|
2361
|
+
}
|
|
2362
|
+
function buildPlacementRef(before, after) {
|
|
2363
|
+
if (before && after) {
|
|
2364
|
+
return {
|
|
2365
|
+
before,
|
|
2366
|
+
after,
|
|
2367
|
+
description: `between after ${formatAnchorRef(before)} and before ${formatAnchorRef(after)}`
|
|
2368
|
+
};
|
|
2369
|
+
}
|
|
2370
|
+
if (before) {
|
|
2371
|
+
return {
|
|
2372
|
+
before,
|
|
2373
|
+
after: null,
|
|
2374
|
+
description: `after ${formatAnchorRef(before)}`
|
|
2375
|
+
};
|
|
2376
|
+
}
|
|
2377
|
+
if (after) {
|
|
2378
|
+
return {
|
|
2379
|
+
before: null,
|
|
2380
|
+
after,
|
|
2381
|
+
description: `before ${formatAnchorRef(after)}`
|
|
2382
|
+
};
|
|
2259
2383
|
}
|
|
2260
|
-
return
|
|
2384
|
+
return {
|
|
2385
|
+
before: null,
|
|
2386
|
+
after: null,
|
|
2387
|
+
description: "as the only child"
|
|
2388
|
+
};
|
|
2261
2389
|
}
|
|
2262
|
-
function
|
|
2263
|
-
const
|
|
2264
|
-
|
|
2390
|
+
function buildPlacementFromMove(beforeName, beforeSelector, beforeSource, afterName, afterSelector, afterSource) {
|
|
2391
|
+
const before = beforeName || beforeSelector || beforeSource?.file ? buildAnchorRef(beforeName, beforeSelector, beforeSource) : null;
|
|
2392
|
+
const after = afterName || afterSelector || afterSource?.file ? buildAnchorRef(afterName, afterSelector, afterSource) : null;
|
|
2393
|
+
return buildPlacementRef(before, after);
|
|
2394
|
+
}
|
|
2395
|
+
function toRoundedVisualDelta(move) {
|
|
2396
|
+
const delta = move.visualDelta ?? move.positionDelta;
|
|
2397
|
+
if (!delta) return void 0;
|
|
2398
|
+
const rounded = { x: Math.round(delta.x), y: Math.round(delta.y) };
|
|
2399
|
+
return rounded.x === 0 && rounded.y === 0 ? void 0 : rounded;
|
|
2400
|
+
}
|
|
2401
|
+
function hasVisualIntent(move) {
|
|
2402
|
+
return Boolean(toRoundedVisualDelta(move));
|
|
2403
|
+
}
|
|
2404
|
+
function hasStructuralChange(move) {
|
|
2405
|
+
const fromParent = buildAnchorRef(move.fromParentName, move.fromParentSelector, move.fromParentSource);
|
|
2406
|
+
const toParent = buildAnchorRef(move.toParentName, move.toParentSelector, move.toParentSource);
|
|
2407
|
+
const fromPlacement = buildPlacementFromMove(
|
|
2408
|
+
move.fromSiblingBefore,
|
|
2409
|
+
move.fromSiblingBeforeSelector,
|
|
2410
|
+
move.fromSiblingBeforeSource,
|
|
2411
|
+
move.fromSiblingAfter,
|
|
2412
|
+
move.fromSiblingAfterSelector,
|
|
2413
|
+
move.fromSiblingAfterSource
|
|
2414
|
+
);
|
|
2415
|
+
const toPlacement = buildPlacementFromMove(
|
|
2416
|
+
move.toSiblingBefore,
|
|
2417
|
+
move.toSiblingBeforeSelector,
|
|
2418
|
+
move.toSiblingBeforeSource,
|
|
2419
|
+
move.toSiblingAfter,
|
|
2420
|
+
move.toSiblingAfterSelector,
|
|
2421
|
+
move.toSiblingAfterSource
|
|
2422
|
+
);
|
|
2423
|
+
if (!anchorsEqual(fromParent, toParent)) return true;
|
|
2424
|
+
if (!anchorsEqual(fromPlacement.before, toPlacement.before)) return true;
|
|
2425
|
+
if (!anchorsEqual(fromPlacement.after, toPlacement.after)) return true;
|
|
2426
|
+
if (typeof move.fromIndex === "number" && typeof move.toIndex === "number" && move.fromIndex !== move.toIndex) return true;
|
|
2427
|
+
return false;
|
|
2265
2428
|
}
|
|
2266
|
-
function
|
|
2267
|
-
|
|
2268
|
-
|
|
2429
|
+
function isStructuredLayoutContainer(layout) {
|
|
2430
|
+
return layout === "flex" || layout === "grid";
|
|
2431
|
+
}
|
|
2432
|
+
function isExistingFlexWorkflow(move) {
|
|
2433
|
+
const structuralChange = hasStructuralChange(move);
|
|
2434
|
+
if (!structuralChange) return false;
|
|
2435
|
+
const fromParent = buildAnchorRef(move.fromParentName, move.fromParentSelector, move.fromParentSource);
|
|
2436
|
+
const toParent = buildAnchorRef(move.toParentName, move.toParentSelector, move.toParentSource);
|
|
2437
|
+
const sameParent = anchorsEqual(fromParent, toParent);
|
|
2438
|
+
const fromLayout = move.fromParentLayout;
|
|
2439
|
+
const toLayout = move.toParentLayout;
|
|
2440
|
+
if (sameParent) {
|
|
2441
|
+
return Boolean(move.mode === "reorder" && (isStructuredLayoutContainer(toLayout) || isStructuredLayoutContainer(fromLayout)));
|
|
2442
|
+
}
|
|
2443
|
+
return Boolean(isStructuredLayoutContainer(fromLayout) && isStructuredLayoutContainer(toLayout));
|
|
2444
|
+
}
|
|
2445
|
+
function classifyMove(move) {
|
|
2446
|
+
const structuralChange = hasStructuralChange(move);
|
|
2447
|
+
const visualIntent = hasVisualIntent(move);
|
|
2448
|
+
if (!structuralChange && !visualIntent) return "noop";
|
|
2449
|
+
if (isExistingFlexWorkflow(move)) return "existing_layout_move";
|
|
2450
|
+
if (move.mode === "free" || move.mode === "position") return "layout_refactor";
|
|
2451
|
+
if (!structuralChange && visualIntent) return "layout_refactor";
|
|
2452
|
+
return "layout_refactor";
|
|
2453
|
+
}
|
|
2454
|
+
function buildNumericClusters(values, tolerance) {
|
|
2455
|
+
if (values.length === 0) return [];
|
|
2456
|
+
const sorted = [...values].sort((a, b) => a - b);
|
|
2457
|
+
const clusters = [{ center: sorted[0], values: [sorted[0]] }];
|
|
2458
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
2459
|
+
const value = sorted[i];
|
|
2460
|
+
const current = clusters[clusters.length - 1];
|
|
2461
|
+
if (Math.abs(value - current.center) <= tolerance) {
|
|
2462
|
+
current.values.push(value);
|
|
2463
|
+
current.center = current.values.reduce((sum, n) => sum + n, 0) / current.values.length;
|
|
2464
|
+
} else {
|
|
2465
|
+
clusters.push({ center: value, values: [value] });
|
|
2466
|
+
}
|
|
2467
|
+
}
|
|
2468
|
+
return clusters;
|
|
2269
2469
|
}
|
|
2270
|
-
function
|
|
2271
|
-
|
|
2470
|
+
function inferFlexDirection(sameRowCount, sameColumnCount, visualDelta) {
|
|
2471
|
+
if (sameRowCount > sameColumnCount) {
|
|
2472
|
+
return { direction: "row", reason: "Subject aligns with neighboring anchors on the same row." };
|
|
2473
|
+
}
|
|
2474
|
+
if (sameColumnCount > sameRowCount) {
|
|
2475
|
+
return { direction: "column", reason: "Subject aligns with neighboring anchors on the same column." };
|
|
2476
|
+
}
|
|
2477
|
+
if (sameRowCount > 0) {
|
|
2478
|
+
return { direction: "row", reason: "Detected row alignment in final geometry." };
|
|
2479
|
+
}
|
|
2480
|
+
if (sameColumnCount > 0) {
|
|
2481
|
+
return { direction: "column", reason: "Detected column alignment in final geometry." };
|
|
2482
|
+
}
|
|
2483
|
+
const horizontalDominant = Math.abs(visualDelta?.x ?? 0) >= Math.abs(visualDelta?.y ?? 0);
|
|
2484
|
+
return {
|
|
2485
|
+
direction: horizontalDominant ? "row" : "column",
|
|
2486
|
+
reason: "Fell back to movement axis because anchor alignment was ambiguous."
|
|
2487
|
+
};
|
|
2488
|
+
}
|
|
2489
|
+
function inferLayoutPrescription(edit, operation, reasons) {
|
|
2490
|
+
const parent = edit.element.parentElement;
|
|
2491
|
+
if (!parent || !edit.element.isConnected) {
|
|
2492
|
+
return {
|
|
2493
|
+
recommendedSystem: "flex",
|
|
2494
|
+
intentPatterns: ["no_geometry_context"],
|
|
2495
|
+
refactorSteps: [
|
|
2496
|
+
`Reparent ${formatAnchorRef(operation.subject)} under ${formatAnchorRef(operation.to.parent)} at ${operation.to.placement.description}.`
|
|
2497
|
+
],
|
|
2498
|
+
styleSteps: [
|
|
2499
|
+
`Convert ${formatAnchorRef(operation.to.parent)} to flex and set a clear primary axis for this relationship.`,
|
|
2500
|
+
"Use `gap` for spacing and keep positioning static."
|
|
2501
|
+
],
|
|
2502
|
+
itemSteps: [
|
|
2503
|
+
"Remove any inline `left/top/transform` move artifacts from moved elements."
|
|
2504
|
+
]
|
|
2505
|
+
};
|
|
2506
|
+
}
|
|
2507
|
+
const children = Array.from(parent.children).filter(
|
|
2508
|
+
(node) => node instanceof HTMLElement && isInFlowChild(node) && !node.hasAttribute("data-direct-edit")
|
|
2509
|
+
);
|
|
2510
|
+
const childSnapshots = children.map((child) => {
|
|
2511
|
+
const rect = child.getBoundingClientRect();
|
|
2512
|
+
const locator = getElementLocator(child);
|
|
2513
|
+
const anchor = buildAnchorRef(getElementDisplayName(child), locator.domSelector, locator.domSource);
|
|
2514
|
+
return {
|
|
2515
|
+
child,
|
|
2516
|
+
rect,
|
|
2517
|
+
centerX: rect.left + rect.width / 2,
|
|
2518
|
+
centerY: rect.top + rect.height / 2,
|
|
2519
|
+
anchor,
|
|
2520
|
+
anchorLabel: formatAnchorRef(anchor)
|
|
2521
|
+
};
|
|
2522
|
+
});
|
|
2523
|
+
const subjectSnapshot = childSnapshots.find((snapshot2) => snapshot2.child === edit.element);
|
|
2524
|
+
const subjectRect = edit.element.getBoundingClientRect();
|
|
2525
|
+
const subjectCenterX = subjectRect.left + subjectRect.width / 2;
|
|
2526
|
+
const subjectCenterY = subjectRect.top + subjectRect.height / 2;
|
|
2527
|
+
const rowTolerance = Math.max(8, subjectRect.height * 0.35);
|
|
2528
|
+
const colTolerance = Math.max(8, subjectRect.width * 0.35);
|
|
2529
|
+
const sameRowWith = [];
|
|
2530
|
+
const sameColumnWith = [];
|
|
2531
|
+
const sameRowNodes = [];
|
|
2532
|
+
let aboveAnchor = null;
|
|
2533
|
+
let belowAnchor = null;
|
|
2534
|
+
let bestAboveDistance = Number.POSITIVE_INFINITY;
|
|
2535
|
+
let bestBelowDistance = Number.POSITIVE_INFINITY;
|
|
2536
|
+
for (const node of childSnapshots) {
|
|
2537
|
+
if (node.child === edit.element) continue;
|
|
2538
|
+
if (Math.abs(node.centerY - subjectCenterY) <= rowTolerance) {
|
|
2539
|
+
sameRowWith.push(node.anchorLabel);
|
|
2540
|
+
sameRowNodes.push(node);
|
|
2541
|
+
}
|
|
2542
|
+
if (Math.abs(node.centerX - subjectCenterX) <= colTolerance) {
|
|
2543
|
+
sameColumnWith.push(node.anchorLabel);
|
|
2544
|
+
}
|
|
2545
|
+
const yDelta = node.centerY - subjectCenterY;
|
|
2546
|
+
if (yDelta < 0 && Math.abs(yDelta) < bestAboveDistance) {
|
|
2547
|
+
bestAboveDistance = Math.abs(yDelta);
|
|
2548
|
+
aboveAnchor = node.anchorLabel;
|
|
2549
|
+
}
|
|
2550
|
+
if (yDelta > 0 && yDelta < bestBelowDistance) {
|
|
2551
|
+
bestBelowDistance = yDelta;
|
|
2552
|
+
belowAnchor = node.anchorLabel;
|
|
2553
|
+
}
|
|
2554
|
+
}
|
|
2555
|
+
const rowCenters = childSnapshots.map(({ centerY }) => centerY);
|
|
2556
|
+
const colCenters = childSnapshots.map(({ centerX }) => centerX);
|
|
2557
|
+
const rowClusters = buildNumericClusters(rowCenters, rowTolerance);
|
|
2558
|
+
const colClusters = buildNumericClusters(colCenters, colTolerance);
|
|
2559
|
+
const denseRowClusters = rowClusters.filter((cluster) => cluster.values.length >= 2).length;
|
|
2560
|
+
const denseColClusters = colClusters.filter((cluster) => cluster.values.length >= 2).length;
|
|
2561
|
+
const isTwoDimensional = childSnapshots.length >= 4 && denseRowClusters >= 2 && denseColClusters >= 2;
|
|
2562
|
+
const recommendedSystem = isTwoDimensional ? "grid" : "flex";
|
|
2563
|
+
const intentPatterns = [];
|
|
2564
|
+
if (sameRowWith.length > 0) intentPatterns.push(`same_row_with:${sameRowWith.slice(0, 3).join(", ")}`);
|
|
2565
|
+
if (sameColumnWith.length > 0) intentPatterns.push(`same_column_with:${sameColumnWith.slice(0, 3).join(", ")}`);
|
|
2566
|
+
if (aboveAnchor) intentPatterns.push(`below:${aboveAnchor}`);
|
|
2567
|
+
if (belowAnchor) intentPatterns.push(`above:${belowAnchor}`);
|
|
2568
|
+
if (sameRowWith.length === 0 && sameColumnWith.length === 0) intentPatterns.push("separate_cluster");
|
|
2569
|
+
const visualDelta = operation.visualDelta;
|
|
2570
|
+
const flexDirectionInfo = inferFlexDirection(sameRowWith.length, sameColumnWith.length, visualDelta);
|
|
2571
|
+
const flexDirection = flexDirectionInfo.direction;
|
|
2572
|
+
if (recommendedSystem === "grid") {
|
|
2573
|
+
reasons.push("Detected multiple dense row and column clusters; a 2D layout system is likely intentional.");
|
|
2574
|
+
return {
|
|
2575
|
+
recommendedSystem: "grid",
|
|
2576
|
+
intentPatterns,
|
|
2577
|
+
refactorSteps: [
|
|
2578
|
+
`Create/ensure a shared container around ${formatAnchorRef(operation.subject)} and related anchors under ${formatAnchorRef(operation.to.parent)}.`,
|
|
2579
|
+
`Reorder/reparent elements to satisfy placement ${operation.to.placement.description}.`
|
|
2580
|
+
],
|
|
2581
|
+
styleSteps: [
|
|
2582
|
+
`Set ${formatAnchorRef(operation.to.parent)} to grid with explicit template rows/columns for the final layout.`,
|
|
2583
|
+
"Use `gap` for consistent spacing and keep placement structural."
|
|
2584
|
+
],
|
|
2585
|
+
itemSteps: [
|
|
2586
|
+
`Set item alignment on ${formatAnchorRef(operation.subject)} with grid self-alignment (\`justify-self\`/\`align-self\`).`
|
|
2587
|
+
]
|
|
2588
|
+
};
|
|
2589
|
+
}
|
|
2590
|
+
reasons.push(`${flexDirectionInfo.reason} Use a 1D flex layout instead of literal drag replay.`);
|
|
2591
|
+
let hasStackedCluster = false;
|
|
2592
|
+
const stackedAnchorLabels = /* @__PURE__ */ new Set();
|
|
2593
|
+
if (flexDirection === "row" && subjectSnapshot) {
|
|
2594
|
+
for (const rowPeer of sameRowNodes) {
|
|
2595
|
+
for (const node of childSnapshots) {
|
|
2596
|
+
if (node.child === edit.element || node.child === rowPeer.child) continue;
|
|
2597
|
+
const sameColumnAsPeer = Math.abs(node.centerX - rowPeer.centerX) <= colTolerance;
|
|
2598
|
+
const verticallySeparated = Math.abs(node.centerY - rowPeer.centerY) > rowTolerance;
|
|
2599
|
+
if (sameColumnAsPeer && verticallySeparated) {
|
|
2600
|
+
hasStackedCluster = true;
|
|
2601
|
+
stackedAnchorLabels.add(rowPeer.anchorLabel);
|
|
2602
|
+
stackedAnchorLabels.add(node.anchorLabel);
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
}
|
|
2607
|
+
const hasBelowCluster = childSnapshots.some((node) => node.child !== edit.element && node.centerY - subjectCenterY > rowTolerance * 1.5 && Math.abs(node.centerY - subjectCenterY) > Math.abs(node.centerX - subjectCenterX));
|
|
2608
|
+
const refactorSteps = [
|
|
2609
|
+
`Ensure ${formatAnchorRef(operation.subject)} and referenced neighbors share a common container under ${formatAnchorRef(operation.to.parent)}.`,
|
|
2610
|
+
`Reparent/reorder nodes so ${formatAnchorRef(operation.subject)} lands ${operation.to.placement.description}.`
|
|
2611
|
+
];
|
|
2612
|
+
if (flexDirection === "row" && hasStackedCluster) {
|
|
2613
|
+
const clusterSample = Array.from(stackedAnchorLabels).slice(0, 3).join(", ");
|
|
2614
|
+
refactorSteps.push(`Create a left-side content wrapper for vertically stacked items (${clusterSample}), and keep ${formatAnchorRef(operation.subject)} as the opposite-side sibling.`);
|
|
2615
|
+
}
|
|
2616
|
+
if (hasBelowCluster) {
|
|
2617
|
+
refactorSteps.push("Keep lower content sections in a separate block below the horizontal header row; do not force them into the same row.");
|
|
2618
|
+
}
|
|
2619
|
+
const styleSteps = [
|
|
2620
|
+
`Set ${formatAnchorRef(operation.to.parent)} to flex with direction ${flexDirection}.`,
|
|
2621
|
+
flexDirection === "row" ? "Use `justify-content: space-between` and `align-items: flex-start` when the moved element should sit on the opposite edge." : "Use `justify-content` / `align-items` to establish top-bottom alignment.",
|
|
2622
|
+
"Use `gap` for spacing between siblings."
|
|
2623
|
+
];
|
|
2624
|
+
if (flexDirection === "row" && hasStackedCluster) {
|
|
2625
|
+
styleSteps.push("Set the content wrapper to `display: flex` with `flex-direction: column` and an appropriate vertical gap.");
|
|
2626
|
+
}
|
|
2627
|
+
return {
|
|
2628
|
+
recommendedSystem: "flex",
|
|
2629
|
+
intentPatterns,
|
|
2630
|
+
refactorSteps,
|
|
2631
|
+
styleSteps,
|
|
2632
|
+
itemSteps: [
|
|
2633
|
+
`Apply item-level alignment (\`align-self\` / flex-basis) only when needed for ${formatAnchorRef(operation.subject)}.`,
|
|
2634
|
+
"Do not use absolute positioning, top/left offsets, transforms, or margin hacks to simulate movement."
|
|
2635
|
+
]
|
|
2636
|
+
};
|
|
2637
|
+
}
|
|
2638
|
+
function buildMoveEntries(edits) {
|
|
2639
|
+
const entries = [];
|
|
2640
|
+
let noopMoveCount = 0;
|
|
2641
|
+
for (const edit of edits) {
|
|
2642
|
+
const move = edit.move;
|
|
2643
|
+
if (!move) continue;
|
|
2644
|
+
const subject = buildAnchorRef(
|
|
2645
|
+
getElementDisplayName(edit.element) || edit.locator.tagName,
|
|
2646
|
+
edit.locator.domSelector,
|
|
2647
|
+
edit.locator.domSource
|
|
2648
|
+
);
|
|
2649
|
+
const fromParent = buildAnchorRef(move.fromParentName, move.fromParentSelector, move.fromParentSource);
|
|
2650
|
+
const toParent = buildAnchorRef(move.toParentName, move.toParentSelector, move.toParentSource);
|
|
2651
|
+
const fromPlacement = buildPlacementFromMove(
|
|
2652
|
+
move.fromSiblingBefore,
|
|
2653
|
+
move.fromSiblingBeforeSelector,
|
|
2654
|
+
move.fromSiblingBeforeSource,
|
|
2655
|
+
move.fromSiblingAfter,
|
|
2656
|
+
move.fromSiblingAfterSelector,
|
|
2657
|
+
move.fromSiblingAfterSource
|
|
2658
|
+
);
|
|
2659
|
+
const toPlacement = buildPlacementFromMove(
|
|
2660
|
+
move.toSiblingBefore,
|
|
2661
|
+
move.toSiblingBeforeSelector,
|
|
2662
|
+
move.toSiblingBeforeSource,
|
|
2663
|
+
move.toSiblingAfter,
|
|
2664
|
+
move.toSiblingAfterSelector,
|
|
2665
|
+
move.toSiblingAfterSource
|
|
2666
|
+
);
|
|
2667
|
+
const reasons = [];
|
|
2668
|
+
const classification = classifyMove(move);
|
|
2669
|
+
if (classification === "noop") {
|
|
2670
|
+
noopMoveCount++;
|
|
2671
|
+
continue;
|
|
2672
|
+
}
|
|
2673
|
+
const interactionMode = move.mode ?? "free";
|
|
2674
|
+
const visualDelta = toRoundedVisualDelta(move);
|
|
2675
|
+
if (visualDelta) {
|
|
2676
|
+
reasons.push(`Non-zero visual delta detected (${visualDelta.x}px, ${visualDelta.y}px).`);
|
|
2677
|
+
}
|
|
2678
|
+
const structuralChange = hasStructuralChange(move);
|
|
2679
|
+
if (structuralChange) reasons.push("Anchor placement changed between source and target.");
|
|
2680
|
+
else reasons.push("No anchor placement change; treating movement as layout intent translation.");
|
|
2681
|
+
const operationBase = {
|
|
2682
|
+
classification,
|
|
2683
|
+
interactionMode,
|
|
2684
|
+
subject,
|
|
2685
|
+
from: { parent: fromParent, placement: fromPlacement },
|
|
2686
|
+
to: { parent: toParent, placement: toPlacement },
|
|
2687
|
+
...visualDelta ? { visualDelta } : {},
|
|
2688
|
+
confidence: classification === "existing_layout_move" ? "high" : structuralChange ? "medium" : "high",
|
|
2689
|
+
reasons
|
|
2690
|
+
};
|
|
2691
|
+
if (classification === "layout_refactor") {
|
|
2692
|
+
operationBase.layoutPrescription = inferLayoutPrescription(edit, operationBase, reasons);
|
|
2693
|
+
}
|
|
2694
|
+
const sortSource = subject.source?.file ? `${subject.source.file}:${subject.source.line ?? 0}:${subject.source.column ?? 0}` : "";
|
|
2695
|
+
const sortKey = [
|
|
2696
|
+
sortSource,
|
|
2697
|
+
anchorKey(subject),
|
|
2698
|
+
anchorKey(toParent),
|
|
2699
|
+
toPlacement.description
|
|
2700
|
+
].join("|");
|
|
2701
|
+
entries.push({ edit, operation: operationBase, sortKey });
|
|
2702
|
+
}
|
|
2703
|
+
entries.sort((a, b) => a.sortKey.localeCompare(b.sortKey));
|
|
2704
|
+
return { entries, noopMoveCount };
|
|
2705
|
+
}
|
|
2706
|
+
function buildMovePlanContext(edits, _domContext) {
|
|
2707
|
+
const { entries, noopMoveCount } = buildMoveEntries(edits);
|
|
2708
|
+
if (entries.length === 0) {
|
|
2709
|
+
return {
|
|
2710
|
+
movePlan: null,
|
|
2711
|
+
intentsByEdit: /* @__PURE__ */ new Map(),
|
|
2712
|
+
noopMoveCount
|
|
2713
|
+
};
|
|
2714
|
+
}
|
|
2715
|
+
const operations = [];
|
|
2716
|
+
const intentsByEdit = /* @__PURE__ */ new Map();
|
|
2717
|
+
for (let i = 0; i < entries.length; i++) {
|
|
2718
|
+
const operationId = `op-${i + 1}`;
|
|
2719
|
+
const operation = { operationId, ...entries[i].operation };
|
|
2720
|
+
operations.push(operation);
|
|
2721
|
+
intentsByEdit.set(entries[i].edit, operation);
|
|
2722
|
+
}
|
|
2723
|
+
const affectedContainerMap = /* @__PURE__ */ new Map();
|
|
2724
|
+
for (const operation of operations) {
|
|
2725
|
+
affectedContainerMap.set(anchorKey(operation.from.parent), operation.from.parent);
|
|
2726
|
+
affectedContainerMap.set(anchorKey(operation.to.parent), operation.to.parent);
|
|
2727
|
+
}
|
|
2728
|
+
const orderingConstraints = operations.filter((op) => op.classification === "existing_layout_move").map((op) => `${op.operationId}: place ${formatAnchorRef(op.subject)} ${op.to.placement.description} in ${formatAnchorRef(op.to.parent)}.`);
|
|
2729
|
+
const notes = [];
|
|
2730
|
+
if (noopMoveCount > 0) notes.push(`Excluded ${noopMoveCount} no-op move(s).`);
|
|
2731
|
+
if (operations.some((op) => op.classification === "layout_refactor")) {
|
|
2732
|
+
notes.push("Layout refactor operations include best-practice flex/grid prescriptions.");
|
|
2733
|
+
}
|
|
2734
|
+
return {
|
|
2735
|
+
movePlan: {
|
|
2736
|
+
operations,
|
|
2737
|
+
affectedContainers: Array.from(affectedContainerMap.values()),
|
|
2738
|
+
orderingConstraints,
|
|
2739
|
+
notes
|
|
2740
|
+
},
|
|
2741
|
+
intentsByEdit,
|
|
2742
|
+
noopMoveCount
|
|
2743
|
+
};
|
|
2744
|
+
}
|
|
2745
|
+
function getMoveIntentForEdit(edit, context) {
|
|
2746
|
+
if (!edit.move) return null;
|
|
2747
|
+
if (context?.intentsByEdit.has(edit)) return context.intentsByEdit.get(edit) ?? null;
|
|
2748
|
+
const singleContext = buildMovePlanContext([edit]);
|
|
2749
|
+
return singleContext.intentsByEdit.get(edit) ?? null;
|
|
2750
|
+
}
|
|
2751
|
+
function buildMoveInstructionFromIntent(intent) {
|
|
2752
|
+
if (intent.classification === "existing_layout_move") {
|
|
2753
|
+
return `Apply as a structural move in code: place ${formatAnchorRef(intent.subject)} ${intent.to.placement.description} in ${formatAnchorRef(intent.to.parent)}.`;
|
|
2754
|
+
}
|
|
2755
|
+
const system = intent.layoutPrescription?.recommendedSystem ?? "flex";
|
|
2756
|
+
return `Treat this as a ${system} layout refactor. Implement the listed structure/style steps in source code instead of drag replay.`;
|
|
2757
|
+
}
|
|
2758
|
+
function formatMoveType(classification) {
|
|
2759
|
+
return classification === "existing_layout_move" ? "structural_move" : "layout_refactor";
|
|
2760
|
+
}
|
|
2761
|
+
function buildMoveExportLines(intent) {
|
|
2762
|
+
const moveType = formatMoveType(intent.classification);
|
|
2763
|
+
const implementationSteps = [];
|
|
2764
|
+
if (intent.classification === "existing_layout_move") {
|
|
2765
|
+
implementationSteps.push(`Reorder/reparent ${formatAnchorRef(intent.subject)} to ${intent.to.placement.description} in ${formatAnchorRef(intent.to.parent)}.`);
|
|
2766
|
+
} else {
|
|
2767
|
+
const prescription = intent.layoutPrescription;
|
|
2768
|
+
if (prescription) {
|
|
2769
|
+
implementationSteps.push(...prescription.refactorSteps);
|
|
2770
|
+
implementationSteps.push(...prescription.styleSteps);
|
|
2771
|
+
implementationSteps.push(...prescription.itemSteps);
|
|
2772
|
+
}
|
|
2773
|
+
}
|
|
2774
|
+
const lines = [
|
|
2272
2775
|
"moved:",
|
|
2273
|
-
`
|
|
2274
|
-
`
|
|
2275
|
-
`
|
|
2276
|
-
`
|
|
2277
|
-
`
|
|
2278
|
-
`
|
|
2279
|
-
`
|
|
2280
|
-
`to_parent_selector: ${formatMoveSelector(move.toParentSelector, "(unknown)")}`,
|
|
2281
|
-
`to_before_selector: ${formatMoveSelector(move.toSiblingBeforeSelector, "(none)")}`,
|
|
2282
|
-
`to_after_selector: ${formatMoveSelector(move.toSiblingAfterSelector, "(none)")}`,
|
|
2283
|
-
`to_parent_source: ${formatMoveSource(move.toParentSource, "(unknown)")}`,
|
|
2284
|
-
`to_before_source: ${formatMoveSource(move.toSiblingBeforeSource, "(none)")}`,
|
|
2285
|
-
`to_after_source: ${formatMoveSource(move.toSiblingAfterSource, "(none)")}`
|
|
2776
|
+
`id: ${intent.operationId}`,
|
|
2777
|
+
`type: ${moveType}`,
|
|
2778
|
+
`subject: ${formatAnchorRef(intent.subject, "(unknown)")}`,
|
|
2779
|
+
`parent: ${formatAnchorRef(intent.to.parent, "(unknown)")}`,
|
|
2780
|
+
`current_anchor: ${intent.from.placement.description}`,
|
|
2781
|
+
`target_anchor: ${intent.to.placement.description}`,
|
|
2782
|
+
...intent.visualDelta ? [`visual_hint: ${intent.visualDelta.x}px horizontal, ${intent.visualDelta.y}px vertical`] : []
|
|
2286
2783
|
];
|
|
2784
|
+
if (intent.layoutPrescription) {
|
|
2785
|
+
lines.push(`recommended_layout: ${intent.layoutPrescription.recommendedSystem}`);
|
|
2786
|
+
}
|
|
2787
|
+
lines.push("implementation_steps:");
|
|
2788
|
+
for (const step of implementationSteps) {
|
|
2789
|
+
lines.push(` - ${step}`);
|
|
2790
|
+
}
|
|
2791
|
+
lines.push("guardrails:");
|
|
2792
|
+
lines.push(" - Do not simulate movement with absolute positioning, left/top offsets, transform, or margin hacks.");
|
|
2793
|
+
lines.push(`instruction: ${buildMoveInstructionFromIntent(intent)}`);
|
|
2794
|
+
return lines;
|
|
2795
|
+
}
|
|
2796
|
+
function getExportContentProfile(edits, comments, movePlanOrContext) {
|
|
2797
|
+
const moveOpCount = movePlanOrContext ? "operations" in movePlanOrContext ? movePlanOrContext.operations.length : movePlanOrContext.movePlan?.operations.length ?? 0 : buildMovePlanContext(edits).movePlan?.operations.length ?? 0;
|
|
2798
|
+
return {
|
|
2799
|
+
hasCssEdits: edits.some((e) => Object.keys(e.pendingStyles).length > 0),
|
|
2800
|
+
hasTextEdits: edits.some((e) => e.textEdit != null),
|
|
2801
|
+
hasMoves: moveOpCount > 0,
|
|
2802
|
+
hasComments: comments.length > 0
|
|
2803
|
+
};
|
|
2804
|
+
}
|
|
2805
|
+
function buildExportInstruction(profile) {
|
|
2806
|
+
const { hasCssEdits, hasTextEdits, hasMoves, hasComments } = profile;
|
|
2807
|
+
if (!hasCssEdits && !hasTextEdits && !hasMoves && !hasComments) return "";
|
|
2808
|
+
if (!hasCssEdits && !hasTextEdits && !hasMoves) {
|
|
2809
|
+
return hasComments ? "Address this feedback on the UI. Use the provided source location and selector to find each element in the codebase." : "";
|
|
2810
|
+
}
|
|
2811
|
+
const parts = [];
|
|
2812
|
+
if (hasCssEdits) parts.push("Apply the CSS changes to the targeted elements using the project's existing styling approach (Tailwind, CSS modules, etc.).");
|
|
2813
|
+
if (hasTextEdits) parts.push("Update the text content as specified.");
|
|
2814
|
+
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.");
|
|
2815
|
+
if (hasComments) parts.push("Address the comments on the relevant elements.");
|
|
2816
|
+
return `${parts.join(" ")} Use the provided source locations, selectors, and context HTML to locate each element in the codebase.`;
|
|
2287
2817
|
}
|
|
2288
|
-
function buildSessionExport(edits, comments = []) {
|
|
2818
|
+
function buildSessionExport(edits, comments = [], options) {
|
|
2289
2819
|
const blocks = [];
|
|
2290
|
-
|
|
2291
|
-
|
|
2292
|
-
|
|
2293
|
-
|
|
2294
|
-
|
|
2820
|
+
const planContext = options?.movePlanContext ?? buildMovePlanContext(edits);
|
|
2821
|
+
const movePlan = planContext.movePlan;
|
|
2822
|
+
const includeMovePlanHeader = options?.includeMovePlanHeader !== false;
|
|
2823
|
+
if (includeMovePlanHeader && movePlan && movePlan.operations.length > 0) {
|
|
2824
|
+
const planLines = [
|
|
2825
|
+
"=== LAYOUT MOVE PLAN ===",
|
|
2826
|
+
`operations: ${movePlan.operations.length}`
|
|
2827
|
+
];
|
|
2828
|
+
if (movePlan.affectedContainers.length > 0) {
|
|
2829
|
+
planLines.push("containers:");
|
|
2830
|
+
for (const container of movePlan.affectedContainers) {
|
|
2831
|
+
planLines.push(` - ${formatAnchorRef(container, "(unknown)")}`);
|
|
2832
|
+
}
|
|
2833
|
+
}
|
|
2834
|
+
if (movePlan.orderingConstraints.length > 0) {
|
|
2835
|
+
planLines.push("structural_constraints:");
|
|
2836
|
+
for (const constraint of movePlan.orderingConstraints) {
|
|
2837
|
+
planLines.push(` - ${constraint}`);
|
|
2838
|
+
}
|
|
2295
2839
|
}
|
|
2296
|
-
|
|
2840
|
+
if (movePlan.notes.length > 0) {
|
|
2841
|
+
planLines.push("plan_notes:");
|
|
2842
|
+
for (const note of movePlan.notes) {
|
|
2843
|
+
planLines.push(` - ${note}`);
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
blocks.push(planLines.join("\n"));
|
|
2847
|
+
}
|
|
2848
|
+
for (const edit of edits) {
|
|
2849
|
+
const moveIntent = getMoveIntentForEdit(edit, planContext);
|
|
2850
|
+
const hasMove = Boolean(moveIntent);
|
|
2851
|
+
const hasStyleOrText = Object.keys(edit.pendingStyles).length > 0 || edit.textEdit != null;
|
|
2852
|
+
if (!hasMove && !hasStyleOrText) continue;
|
|
2853
|
+
const block = hasMove ? buildEditExportWithOptions(edit.locator, edit.pendingStyles, edit.textEdit, { skipContext: true }) : buildEditExport(edit.locator, edit.pendingStyles, edit.textEdit);
|
|
2854
|
+
let moveBlock = "";
|
|
2855
|
+
if (moveIntent) {
|
|
2856
|
+
moveBlock = `
|
|
2857
|
+
${buildMoveExportLines(moveIntent).join("\n")}`;
|
|
2858
|
+
}
|
|
2859
|
+
blocks.push(block + moveBlock);
|
|
2297
2860
|
}
|
|
2298
2861
|
for (const comment of comments) {
|
|
2299
2862
|
blocks.push(buildCommentExport(comment.locator, comment.text, comment.replies));
|
|
@@ -2741,6 +3304,224 @@ function useStyleUpdaters({ stateRef, pushUndo, setState }) {
|
|
|
2741
3304
|
|
|
2742
3305
|
// src/use-session-manager.ts
|
|
2743
3306
|
var React3 = __toESM(require("react"));
|
|
3307
|
+
|
|
3308
|
+
// src/clipboard.ts
|
|
3309
|
+
function buildAgentClipboardText(markdown) {
|
|
3310
|
+
return `implement the visual edits
|
|
3311
|
+
|
|
3312
|
+
${markdown}`;
|
|
3313
|
+
}
|
|
3314
|
+
function tryRestoreFocus(element) {
|
|
3315
|
+
if (!(element instanceof HTMLElement)) return;
|
|
3316
|
+
try {
|
|
3317
|
+
element.focus({ preventScroll: true });
|
|
3318
|
+
} catch {
|
|
3319
|
+
try {
|
|
3320
|
+
element.focus();
|
|
3321
|
+
} catch {
|
|
3322
|
+
}
|
|
3323
|
+
}
|
|
3324
|
+
}
|
|
3325
|
+
async function copyText(text) {
|
|
3326
|
+
const nav = globalThis.navigator;
|
|
3327
|
+
const clipboard = nav?.clipboard;
|
|
3328
|
+
const clipboardWrite = clipboard?.writeText;
|
|
3329
|
+
if (typeof clipboardWrite === "function") {
|
|
3330
|
+
try {
|
|
3331
|
+
await clipboardWrite.call(clipboard, text);
|
|
3332
|
+
return true;
|
|
3333
|
+
} catch {
|
|
3334
|
+
}
|
|
3335
|
+
}
|
|
3336
|
+
if (typeof document === "undefined") return false;
|
|
3337
|
+
if (typeof document.execCommand !== "function") return false;
|
|
3338
|
+
const body = document.body;
|
|
3339
|
+
if (!body) return false;
|
|
3340
|
+
const activeElement = document.activeElement;
|
|
3341
|
+
const selection = typeof window !== "undefined" ? window.getSelection() : null;
|
|
3342
|
+
const previousRange = selection && selection.rangeCount > 0 ? selection.getRangeAt(0).cloneRange() : null;
|
|
3343
|
+
const textarea = document.createElement("textarea");
|
|
3344
|
+
textarea.value = text;
|
|
3345
|
+
textarea.setAttribute("readonly", "");
|
|
3346
|
+
textarea.style.position = "fixed";
|
|
3347
|
+
textarea.style.top = "0";
|
|
3348
|
+
textarea.style.left = "0";
|
|
3349
|
+
textarea.style.width = "1px";
|
|
3350
|
+
textarea.style.height = "1px";
|
|
3351
|
+
textarea.style.opacity = "0";
|
|
3352
|
+
textarea.style.pointerEvents = "none";
|
|
3353
|
+
body.appendChild(textarea);
|
|
3354
|
+
let copied = false;
|
|
3355
|
+
try {
|
|
3356
|
+
try {
|
|
3357
|
+
textarea.focus({ preventScroll: true });
|
|
3358
|
+
} catch {
|
|
3359
|
+
textarea.focus();
|
|
3360
|
+
}
|
|
3361
|
+
textarea.select();
|
|
3362
|
+
textarea.setSelectionRange(0, textarea.value.length);
|
|
3363
|
+
copied = document.execCommand("copy");
|
|
3364
|
+
} catch {
|
|
3365
|
+
copied = false;
|
|
3366
|
+
} finally {
|
|
3367
|
+
textarea.remove();
|
|
3368
|
+
if (selection) {
|
|
3369
|
+
selection.removeAllRanges();
|
|
3370
|
+
if (previousRange) {
|
|
3371
|
+
selection.addRange(previousRange);
|
|
3372
|
+
}
|
|
3373
|
+
}
|
|
3374
|
+
tryRestoreFocus(activeElement);
|
|
3375
|
+
}
|
|
3376
|
+
return copied;
|
|
3377
|
+
}
|
|
3378
|
+
|
|
3379
|
+
// src/use-session-manager.ts
|
|
3380
|
+
function getLayoutFromDisplay(display) {
|
|
3381
|
+
if (display === "flex" || display === "inline-flex") return "flex";
|
|
3382
|
+
if (display === "grid" || display === "inline-grid") return "grid";
|
|
3383
|
+
if (display === "block" || display === "inline-block" || display === "flow-root" || display === "list-item") {
|
|
3384
|
+
return "block";
|
|
3385
|
+
}
|
|
3386
|
+
return "other";
|
|
3387
|
+
}
|
|
3388
|
+
function getParentLayoutMeta(parent) {
|
|
3389
|
+
if (!parent) return {};
|
|
3390
|
+
const computed = window.getComputedStyle(parent);
|
|
3391
|
+
const display = computed.display;
|
|
3392
|
+
const layout = getLayoutFromDisplay(display);
|
|
3393
|
+
const childCount = countInFlowChildren(parent);
|
|
3394
|
+
if (layout === "flex") {
|
|
3395
|
+
return {
|
|
3396
|
+
display,
|
|
3397
|
+
layout,
|
|
3398
|
+
childCount,
|
|
3399
|
+
flexDirection: computed.flexDirection,
|
|
3400
|
+
gap: computed.gap !== "normal" && computed.gap !== "0px" ? computed.gap : void 0
|
|
3401
|
+
};
|
|
3402
|
+
}
|
|
3403
|
+
if (layout === "grid") {
|
|
3404
|
+
return {
|
|
3405
|
+
display,
|
|
3406
|
+
layout,
|
|
3407
|
+
childCount,
|
|
3408
|
+
gap: computed.gap !== "normal" && computed.gap !== "0px" ? computed.gap : void 0
|
|
3409
|
+
};
|
|
3410
|
+
}
|
|
3411
|
+
return { display, layout, childCount };
|
|
3412
|
+
}
|
|
3413
|
+
function countInFlowChildren(parent) {
|
|
3414
|
+
let count = 0;
|
|
3415
|
+
for (const c of parent.children) {
|
|
3416
|
+
if (c instanceof HTMLElement && isInFlowChild(c)) count++;
|
|
3417
|
+
}
|
|
3418
|
+
return count;
|
|
3419
|
+
}
|
|
3420
|
+
function findChildIndex(parent, child) {
|
|
3421
|
+
if (!parent || !child) return void 0;
|
|
3422
|
+
const index = Array.from(parent.children).indexOf(child);
|
|
3423
|
+
return index >= 0 ? index : void 0;
|
|
3424
|
+
}
|
|
3425
|
+
function getOriginalMoveIndex(parent, previousSibling, nextSibling) {
|
|
3426
|
+
const previousIndex = findChildIndex(parent, previousSibling);
|
|
3427
|
+
if (previousIndex !== void 0) return previousIndex + 1;
|
|
3428
|
+
const nextIndex = findChildIndex(parent, nextSibling);
|
|
3429
|
+
if (nextIndex !== void 0) return nextIndex;
|
|
3430
|
+
return 0;
|
|
3431
|
+
}
|
|
3432
|
+
function applyPositionMoveCSS(element, delta) {
|
|
3433
|
+
const computed = window.getComputedStyle(element);
|
|
3434
|
+
const previousStyles = [];
|
|
3435
|
+
if (computed.position === "static") {
|
|
3436
|
+
previousStyles.push({ cssProperty: "position", previousValue: element.style.getPropertyValue("position") || null });
|
|
3437
|
+
element.style.setProperty("position", "relative");
|
|
3438
|
+
}
|
|
3439
|
+
const appliedLeft = `${(parseFloat(computed.left) || 0) + delta.x}px`;
|
|
3440
|
+
const appliedTop = `${(parseFloat(computed.top) || 0) + delta.y}px`;
|
|
3441
|
+
previousStyles.push({ cssProperty: "left", previousValue: element.style.getPropertyValue("left") || null });
|
|
3442
|
+
previousStyles.push({ cssProperty: "top", previousValue: element.style.getPropertyValue("top") || null });
|
|
3443
|
+
element.style.setProperty("left", appliedLeft);
|
|
3444
|
+
element.style.setProperty("top", appliedTop);
|
|
3445
|
+
return { previousStyles, appliedLeft, appliedTop };
|
|
3446
|
+
}
|
|
3447
|
+
function getAnchor(node) {
|
|
3448
|
+
if (!node) return { selector: null, source: null };
|
|
3449
|
+
const locator = getElementLocator(node);
|
|
3450
|
+
const selector = locator.domSelector.trim();
|
|
3451
|
+
return {
|
|
3452
|
+
selector: selector.length > 0 ? selector : null,
|
|
3453
|
+
source: locator.domSource ?? null
|
|
3454
|
+
};
|
|
3455
|
+
}
|
|
3456
|
+
function buildPositionMoveFields(element, moveInfo, appliedLeft, appliedTop, existingMove) {
|
|
3457
|
+
const parent = element.parentElement;
|
|
3458
|
+
const intended = computeIntendedIndex(parent, element);
|
|
3459
|
+
const parentMeta = getParentLayoutMeta(parent);
|
|
3460
|
+
const parentName = getElementDisplayName(parent);
|
|
3461
|
+
const parentAnchor = getAnchor(parent);
|
|
3462
|
+
const fromIndex = getOriginalMoveIndex(
|
|
3463
|
+
moveInfo.originalParent,
|
|
3464
|
+
moveInfo.originalPreviousSibling,
|
|
3465
|
+
moveInfo.originalNextSibling
|
|
3466
|
+
);
|
|
3467
|
+
const fromParentMeta = existingMove ? getParentLayoutMeta(moveInfo.originalParent) : parentMeta;
|
|
3468
|
+
const fromFields = existingMove ? {
|
|
3469
|
+
fromParentName: existingMove.fromParentName,
|
|
3470
|
+
fromSiblingBefore: existingMove.fromSiblingBefore,
|
|
3471
|
+
fromSiblingAfter: existingMove.fromSiblingAfter,
|
|
3472
|
+
fromParentSelector: existingMove.fromParentSelector ?? null,
|
|
3473
|
+
fromSiblingBeforeSelector: existingMove.fromSiblingBeforeSelector ?? null,
|
|
3474
|
+
fromSiblingAfterSelector: existingMove.fromSiblingAfterSelector ?? null,
|
|
3475
|
+
fromParentSource: existingMove.fromParentSource ?? null,
|
|
3476
|
+
fromSiblingBeforeSource: existingMove.fromSiblingBeforeSource ?? null,
|
|
3477
|
+
fromSiblingAfterSource: existingMove.fromSiblingAfterSource ?? null,
|
|
3478
|
+
fromParentDisplay: existingMove.fromParentDisplay ?? parentMeta.display,
|
|
3479
|
+
fromParentLayout: existingMove.fromParentLayout ?? parentMeta.layout,
|
|
3480
|
+
fromIndex: existingMove.fromIndex ?? fromIndex,
|
|
3481
|
+
fromFlexDirection: existingMove.fromFlexDirection ?? fromParentMeta.flexDirection,
|
|
3482
|
+
fromGap: existingMove.fromGap ?? fromParentMeta.gap,
|
|
3483
|
+
fromChildCount: existingMove.fromChildCount ?? fromParentMeta.childCount
|
|
3484
|
+
} : {
|
|
3485
|
+
fromParentName: parentName,
|
|
3486
|
+
fromSiblingBefore: moveInfo.originalPreviousSibling ? getElementDisplayName(moveInfo.originalPreviousSibling) : null,
|
|
3487
|
+
fromSiblingAfter: moveInfo.originalNextSibling ? getElementDisplayName(moveInfo.originalNextSibling) : null,
|
|
3488
|
+
fromParentSelector: parentAnchor.selector,
|
|
3489
|
+
fromSiblingBeforeSelector: getAnchor(moveInfo.originalPreviousSibling).selector,
|
|
3490
|
+
fromSiblingAfterSelector: getAnchor(moveInfo.originalNextSibling).selector,
|
|
3491
|
+
fromParentSource: parentAnchor.source,
|
|
3492
|
+
fromSiblingBeforeSource: getAnchor(moveInfo.originalPreviousSibling).source,
|
|
3493
|
+
fromSiblingAfterSource: getAnchor(moveInfo.originalNextSibling).source,
|
|
3494
|
+
fromParentDisplay: parentMeta.display,
|
|
3495
|
+
fromParentLayout: parentMeta.layout,
|
|
3496
|
+
fromIndex,
|
|
3497
|
+
fromFlexDirection: parentMeta.flexDirection,
|
|
3498
|
+
fromGap: parentMeta.gap,
|
|
3499
|
+
fromChildCount: parentMeta.childCount
|
|
3500
|
+
};
|
|
3501
|
+
return {
|
|
3502
|
+
...fromFields,
|
|
3503
|
+
mode: "position",
|
|
3504
|
+
positionDelta: moveInfo.positionDelta,
|
|
3505
|
+
appliedLeft,
|
|
3506
|
+
appliedTop,
|
|
3507
|
+
visualDelta: moveInfo.positionDelta ? { x: Math.round(moveInfo.positionDelta.x), y: Math.round(moveInfo.positionDelta.y) } : void 0,
|
|
3508
|
+
toParentName: parentName,
|
|
3509
|
+
toSiblingBefore: intended.siblingBefore ? getElementDisplayName(intended.siblingBefore) : null,
|
|
3510
|
+
toSiblingAfter: intended.siblingAfter ? getElementDisplayName(intended.siblingAfter) : null,
|
|
3511
|
+
toParentSelector: parentAnchor.selector,
|
|
3512
|
+
toSiblingBeforeSelector: getAnchor(intended.siblingBefore).selector,
|
|
3513
|
+
toSiblingAfterSelector: getAnchor(intended.siblingAfter).selector,
|
|
3514
|
+
toParentSource: parentAnchor.source,
|
|
3515
|
+
toSiblingBeforeSource: getAnchor(intended.siblingBefore).source,
|
|
3516
|
+
toSiblingAfterSource: getAnchor(intended.siblingAfter).source,
|
|
3517
|
+
toParentDisplay: parentMeta.display,
|
|
3518
|
+
toParentLayout: parentMeta.layout,
|
|
3519
|
+
toIndex: intended.index,
|
|
3520
|
+
toFlexDirection: parentMeta.flexDirection,
|
|
3521
|
+
toGap: parentMeta.gap,
|
|
3522
|
+
toChildCount: parentMeta.childCount
|
|
3523
|
+
};
|
|
3524
|
+
}
|
|
2744
3525
|
function useSessionManager({
|
|
2745
3526
|
stateRef,
|
|
2746
3527
|
sessionEditsRef,
|
|
@@ -2987,6 +3768,15 @@ function useSessionManager({
|
|
|
2987
3768
|
}
|
|
2988
3769
|
} catch {
|
|
2989
3770
|
}
|
|
3771
|
+
if (entry.previousPositionStyles) {
|
|
3772
|
+
for (const { cssProperty, previousValue } of entry.previousPositionStyles) {
|
|
3773
|
+
if (previousValue) {
|
|
3774
|
+
entry.element.style.setProperty(cssProperty, previousValue);
|
|
3775
|
+
} else {
|
|
3776
|
+
entry.element.style.removeProperty(cssProperty);
|
|
3777
|
+
}
|
|
3778
|
+
}
|
|
3779
|
+
}
|
|
2990
3780
|
const sessionEntry = sessionEditsRef.current.get(entry.element);
|
|
2991
3781
|
if (sessionEntry) {
|
|
2992
3782
|
const restoredMove = entry.previousSessionMove;
|
|
@@ -3058,77 +3848,137 @@ function useSessionManager({
|
|
|
3058
3848
|
};
|
|
3059
3849
|
};
|
|
3060
3850
|
if (moveInfo) {
|
|
3061
|
-
|
|
3062
|
-
|
|
3063
|
-
|
|
3851
|
+
if (moveInfo.mode === "position" && moveInfo.positionDelta) {
|
|
3852
|
+
const existing = sessionEditsRef.current.get(element);
|
|
3853
|
+
const styleState2 = getStyleStateForElement(existing);
|
|
3854
|
+
const { previousStyles, appliedLeft, appliedTop } = applyPositionMoveCSS(element, moveInfo.positionDelta);
|
|
3855
|
+
pushUndo({
|
|
3856
|
+
type: "move",
|
|
3857
|
+
element,
|
|
3858
|
+
originalParent: moveInfo.originalParent,
|
|
3859
|
+
originalNextSibling: moveInfo.originalNextSibling,
|
|
3860
|
+
previousSessionMove: existing?.move ?? null,
|
|
3861
|
+
previousPositionStyles: previousStyles
|
|
3862
|
+
});
|
|
3863
|
+
const locator = existing?.locator ?? getElementLocator(element);
|
|
3864
|
+
const pendingStyles = { ...styleState2.pendingStyles };
|
|
3865
|
+
delete pendingStyles["position"];
|
|
3866
|
+
delete pendingStyles["left"];
|
|
3867
|
+
delete pendingStyles["top"];
|
|
3868
|
+
const move = buildPositionMoveFields(element, moveInfo, appliedLeft, appliedTop, existing?.move ?? null);
|
|
3869
|
+
sessionEditsRef.current.set(element, {
|
|
3870
|
+
element,
|
|
3871
|
+
locator,
|
|
3872
|
+
originalStyles: styleState2.originalStyles,
|
|
3873
|
+
pendingStyles,
|
|
3874
|
+
textEdit: existing?.textEdit ?? null,
|
|
3875
|
+
move
|
|
3876
|
+
});
|
|
3877
|
+
syncSessionItemCount();
|
|
3878
|
+
} else {
|
|
3879
|
+
const existing = sessionEditsRef.current.get(element);
|
|
3880
|
+
const styleState2 = getStyleStateForElement(existing);
|
|
3881
|
+
const moveMode = moveInfo.mode ?? "free";
|
|
3882
|
+
let clearedPositionStyles;
|
|
3883
|
+
if (moveInfo.resetPositionOffsets) {
|
|
3884
|
+
clearedPositionStyles = [];
|
|
3885
|
+
for (const prop of ["position", "left", "top"]) {
|
|
3886
|
+
const prev = element.style.getPropertyValue(prop) || null;
|
|
3887
|
+
clearedPositionStyles.push({ cssProperty: prop, previousValue: prev });
|
|
3888
|
+
element.style.removeProperty(prop);
|
|
3889
|
+
}
|
|
3064
3890
|
}
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3891
|
+
pushUndo({
|
|
3892
|
+
type: "move",
|
|
3893
|
+
element,
|
|
3894
|
+
originalParent: moveInfo.originalParent,
|
|
3895
|
+
originalNextSibling: moveInfo.originalNextSibling,
|
|
3896
|
+
previousSessionMove: existing?.move ?? null,
|
|
3897
|
+
previousPositionStyles: clearedPositionStyles
|
|
3898
|
+
});
|
|
3899
|
+
const locator = existing?.locator ?? getElementLocator(element);
|
|
3900
|
+
const newParent = element.parentElement;
|
|
3901
|
+
const nextPrevSibling = element.previousElementSibling;
|
|
3902
|
+
const nextSibling = element.nextElementSibling;
|
|
3903
|
+
const fromParentAnchor = getAnchor(moveInfo.originalParent);
|
|
3904
|
+
const fromBeforeAnchor = getAnchor(moveInfo.originalPreviousSibling);
|
|
3905
|
+
const fromAfterAnchor = getAnchor(moveInfo.originalNextSibling);
|
|
3906
|
+
const toParentAnchor = getAnchor(newParent);
|
|
3907
|
+
const toBeforeAnchor = getAnchor(nextPrevSibling);
|
|
3908
|
+
const toAfterAnchor = getAnchor(nextSibling);
|
|
3909
|
+
const fromParentMeta = getParentLayoutMeta(moveInfo.originalParent);
|
|
3910
|
+
const toParentMeta = getParentLayoutMeta(newParent);
|
|
3911
|
+
const fromIndex = getOriginalMoveIndex(
|
|
3912
|
+
moveInfo.originalParent,
|
|
3913
|
+
moveInfo.originalPreviousSibling,
|
|
3914
|
+
moveInfo.originalNextSibling
|
|
3915
|
+
);
|
|
3916
|
+
const toIndex = findChildIndex(newParent, element);
|
|
3917
|
+
const fromFields = existing?.move ? {
|
|
3918
|
+
fromParentName: existing.move.fromParentName,
|
|
3919
|
+
fromSiblingBefore: existing.move.fromSiblingBefore,
|
|
3920
|
+
fromSiblingAfter: existing.move.fromSiblingAfter,
|
|
3921
|
+
fromParentSelector: existing.move.fromParentSelector ?? null,
|
|
3922
|
+
fromSiblingBeforeSelector: existing.move.fromSiblingBeforeSelector ?? null,
|
|
3923
|
+
fromSiblingAfterSelector: existing.move.fromSiblingAfterSelector ?? null,
|
|
3924
|
+
fromParentSource: existing.move.fromParentSource ?? null,
|
|
3925
|
+
fromSiblingBeforeSource: existing.move.fromSiblingBeforeSource ?? null,
|
|
3926
|
+
fromSiblingAfterSource: existing.move.fromSiblingAfterSource ?? null,
|
|
3927
|
+
fromParentDisplay: existing.move.fromParentDisplay ?? fromParentMeta.display,
|
|
3928
|
+
fromParentLayout: existing.move.fromParentLayout ?? fromParentMeta.layout,
|
|
3929
|
+
fromIndex: existing.move.fromIndex ?? fromIndex,
|
|
3930
|
+
fromFlexDirection: existing.move.fromFlexDirection ?? fromParentMeta.flexDirection,
|
|
3931
|
+
fromGap: existing.move.fromGap ?? fromParentMeta.gap,
|
|
3932
|
+
fromChildCount: existing.move.fromChildCount ?? fromParentMeta.childCount
|
|
3933
|
+
} : {
|
|
3934
|
+
fromParentName: getElementDisplayName(moveInfo.originalParent),
|
|
3935
|
+
fromSiblingBefore: moveInfo.originalPreviousSibling ? getElementDisplayName(moveInfo.originalPreviousSibling) : null,
|
|
3936
|
+
fromSiblingAfter: moveInfo.originalNextSibling ? getElementDisplayName(moveInfo.originalNextSibling) : null,
|
|
3937
|
+
fromParentSelector: fromParentAnchor.selector,
|
|
3938
|
+
fromSiblingBeforeSelector: fromBeforeAnchor.selector,
|
|
3939
|
+
fromSiblingAfterSelector: fromAfterAnchor.selector,
|
|
3940
|
+
fromParentSource: fromParentAnchor.source,
|
|
3941
|
+
fromSiblingBeforeSource: fromBeforeAnchor.source,
|
|
3942
|
+
fromSiblingAfterSource: fromAfterAnchor.source,
|
|
3943
|
+
fromParentDisplay: fromParentMeta.display,
|
|
3944
|
+
fromParentLayout: fromParentMeta.layout,
|
|
3945
|
+
fromIndex,
|
|
3946
|
+
fromFlexDirection: fromParentMeta.flexDirection,
|
|
3947
|
+
fromGap: fromParentMeta.gap,
|
|
3948
|
+
fromChildCount: fromParentMeta.childCount
|
|
3070
3949
|
};
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3075
|
-
|
|
3076
|
-
|
|
3077
|
-
|
|
3078
|
-
|
|
3079
|
-
|
|
3080
|
-
|
|
3081
|
-
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3086
|
-
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
3100
|
-
|
|
3101
|
-
|
|
3102
|
-
|
|
3103
|
-
fromSiblingBefore: moveInfo.originalPreviousSibling ? getElementDisplayName(moveInfo.originalPreviousSibling) : null,
|
|
3104
|
-
fromSiblingAfter: moveInfo.originalNextSibling ? getElementDisplayName(moveInfo.originalNextSibling) : null,
|
|
3105
|
-
fromParentSelector: fromParentAnchor.selector,
|
|
3106
|
-
fromSiblingBeforeSelector: fromBeforeAnchor.selector,
|
|
3107
|
-
fromSiblingAfterSelector: fromAfterAnchor.selector,
|
|
3108
|
-
fromParentSource: fromParentAnchor.source,
|
|
3109
|
-
fromSiblingBeforeSource: fromBeforeAnchor.source,
|
|
3110
|
-
fromSiblingAfterSource: fromAfterAnchor.source
|
|
3111
|
-
};
|
|
3112
|
-
sessionEditsRef.current.set(element, {
|
|
3113
|
-
element,
|
|
3114
|
-
locator,
|
|
3115
|
-
originalStyles: styleState2.originalStyles,
|
|
3116
|
-
pendingStyles: styleState2.pendingStyles,
|
|
3117
|
-
textEdit: existing?.textEdit ?? null,
|
|
3118
|
-
move: newParent ? {
|
|
3119
|
-
...fromFields,
|
|
3120
|
-
toParentName: getElementDisplayName(newParent),
|
|
3121
|
-
toSiblingBefore: nextPrevSibling ? getElementDisplayName(nextPrevSibling) : null,
|
|
3122
|
-
toSiblingAfter: nextSibling ? getElementDisplayName(nextSibling) : null,
|
|
3123
|
-
toParentSelector: toParentAnchor.selector,
|
|
3124
|
-
toSiblingBeforeSelector: toBeforeAnchor.selector,
|
|
3125
|
-
toSiblingAfterSelector: toAfterAnchor.selector,
|
|
3126
|
-
toParentSource: toParentAnchor.source,
|
|
3127
|
-
toSiblingBeforeSource: toBeforeAnchor.source,
|
|
3128
|
-
toSiblingAfterSource: toAfterAnchor.source
|
|
3129
|
-
} : null
|
|
3130
|
-
});
|
|
3131
|
-
syncSessionItemCount();
|
|
3950
|
+
sessionEditsRef.current.set(element, {
|
|
3951
|
+
element,
|
|
3952
|
+
locator,
|
|
3953
|
+
originalStyles: styleState2.originalStyles,
|
|
3954
|
+
pendingStyles: styleState2.pendingStyles,
|
|
3955
|
+
textEdit: existing?.textEdit ?? null,
|
|
3956
|
+
move: newParent ? {
|
|
3957
|
+
...fromFields,
|
|
3958
|
+
toParentName: getElementDisplayName(newParent),
|
|
3959
|
+
toSiblingBefore: nextPrevSibling ? getElementDisplayName(nextPrevSibling) : null,
|
|
3960
|
+
toSiblingAfter: nextSibling ? getElementDisplayName(nextSibling) : null,
|
|
3961
|
+
toParentSelector: toParentAnchor.selector,
|
|
3962
|
+
toSiblingBeforeSelector: toBeforeAnchor.selector,
|
|
3963
|
+
toSiblingAfterSelector: toAfterAnchor.selector,
|
|
3964
|
+
toParentSource: toParentAnchor.source,
|
|
3965
|
+
toSiblingBeforeSource: toBeforeAnchor.source,
|
|
3966
|
+
toSiblingAfterSource: toAfterAnchor.source,
|
|
3967
|
+
mode: moveMode,
|
|
3968
|
+
fromParentDisplay: fromFields.fromParentDisplay,
|
|
3969
|
+
fromParentLayout: fromFields.fromParentLayout,
|
|
3970
|
+
fromIndex: fromFields.fromIndex,
|
|
3971
|
+
toParentDisplay: toParentMeta.display,
|
|
3972
|
+
toParentLayout: toParentMeta.layout,
|
|
3973
|
+
toIndex,
|
|
3974
|
+
visualDelta: moveInfo.visualDelta,
|
|
3975
|
+
toFlexDirection: toParentMeta.flexDirection,
|
|
3976
|
+
toGap: toParentMeta.gap,
|
|
3977
|
+
toChildCount: toParentMeta.childCount
|
|
3978
|
+
} : null
|
|
3979
|
+
});
|
|
3980
|
+
syncSessionItemCount();
|
|
3981
|
+
}
|
|
3132
3982
|
}
|
|
3133
3983
|
const computed = getAllComputedStyles(element);
|
|
3134
3984
|
const elementInfo = getElementInfo(element);
|
|
@@ -3182,15 +4032,12 @@ function useSessionManager({
|
|
|
3182
4032
|
if (items.length === 0) return false;
|
|
3183
4033
|
const edits = items.filter((item) => item.type === "edit").map((item) => item.edit);
|
|
3184
4034
|
const comments = items.filter((item) => item.type === "comment").map((item) => item.comment);
|
|
3185
|
-
const
|
|
3186
|
-
|
|
3187
|
-
|
|
4035
|
+
const movePlanContext = buildMovePlanContext(edits);
|
|
4036
|
+
const text = buildSessionExport(edits, comments, { movePlanContext });
|
|
4037
|
+
const instruction = buildExportInstruction(getExportContentProfile(edits, comments, movePlanContext));
|
|
4038
|
+
return copyText(`${instruction}
|
|
3188
4039
|
|
|
3189
4040
|
${text}`);
|
|
3190
|
-
return true;
|
|
3191
|
-
} catch {
|
|
3192
|
-
return false;
|
|
3193
|
-
}
|
|
3194
4041
|
}, [getSessionItems]);
|
|
3195
4042
|
const revertElementStyles = React3.useCallback((element, sessionEdit) => {
|
|
3196
4043
|
for (const prop of Object.keys(sessionEdit.pendingStyles)) {
|
|
@@ -3265,22 +4112,27 @@ ${text}`);
|
|
|
3265
4112
|
const sessionEdit = sessionEditsRef.current.get(current.selectedElement);
|
|
3266
4113
|
const hasPendingStyles = Object.keys(current.pendingStyles).length > 0;
|
|
3267
4114
|
const hasTextEdit = Boolean(sessionEdit?.textEdit);
|
|
3268
|
-
const hasMove = Boolean(sessionEdit?.move);
|
|
3269
4115
|
const locator = getElementLocator(current.selectedElement);
|
|
3270
|
-
const
|
|
4116
|
+
const editForExport = sessionEdit ? {
|
|
3271
4117
|
...sessionEdit,
|
|
3272
4118
|
locator,
|
|
3273
4119
|
pendingStyles: { ...current.pendingStyles },
|
|
3274
4120
|
textEdit: sessionEdit.textEdit
|
|
3275
|
-
}
|
|
3276
|
-
|
|
3277
|
-
|
|
4121
|
+
} : null;
|
|
4122
|
+
const movePlanContext = editForExport?.move ? buildMovePlanContext([editForExport]) : null;
|
|
4123
|
+
const moveIntent = editForExport?.move ? getMoveIntentForEdit(editForExport, movePlanContext) : null;
|
|
4124
|
+
const hasMove = Boolean(moveIntent);
|
|
4125
|
+
const hasExportableEdit = hasPendingStyles || hasTextEdit || hasMove;
|
|
4126
|
+
const exportMarkdown = hasExportableEdit ? hasMove && editForExport ? buildSessionExport([editForExport], [], { movePlanContext }) : buildEditExport(locator, current.pendingStyles, sessionEdit?.textEdit) : buildElementContext(locator);
|
|
4127
|
+
const instruction = hasExportableEdit ? buildExportInstruction({
|
|
4128
|
+
hasCssEdits: hasPendingStyles,
|
|
4129
|
+
hasTextEdits: hasTextEdit,
|
|
4130
|
+
hasMoves: hasMove,
|
|
4131
|
+
hasComments: false
|
|
4132
|
+
}) : "Here is the element context for reference";
|
|
4133
|
+
return copyText(`${instruction}
|
|
3278
4134
|
|
|
3279
4135
|
${exportMarkdown}`);
|
|
3280
|
-
return true;
|
|
3281
|
-
} catch {
|
|
3282
|
-
return false;
|
|
3283
|
-
}
|
|
3284
4136
|
}, []);
|
|
3285
4137
|
return {
|
|
3286
4138
|
syncSessionItemCount,
|
|
@@ -3304,6 +4156,10 @@ ${exportMarkdown}`);
|
|
|
3304
4156
|
|
|
3305
4157
|
// src/use-text-and-comments.ts
|
|
3306
4158
|
var React4 = __toESM(require("react"));
|
|
4159
|
+
function clampUnit(value) {
|
|
4160
|
+
if (!Number.isFinite(value)) return 0;
|
|
4161
|
+
return Math.max(0, Math.min(1, value));
|
|
4162
|
+
}
|
|
3307
4163
|
function useTextAndComments({
|
|
3308
4164
|
stateRef,
|
|
3309
4165
|
sessionEditsRef,
|
|
@@ -3367,8 +4223,8 @@ function useTextAndComments({
|
|
|
3367
4223
|
const locator = getElementLocator(element);
|
|
3368
4224
|
const rect = element.getBoundingClientRect();
|
|
3369
4225
|
const relativePosition = {
|
|
3370
|
-
x: rect.width > 0 ? (clickPosition.x - rect.left) / rect.width : 0,
|
|
3371
|
-
y: rect.height > 0 ? (clickPosition.y - rect.top) / rect.height : 0
|
|
4226
|
+
x: rect.width > 0 ? clampUnit((clickPosition.x - rect.left) / rect.width) : 0,
|
|
4227
|
+
y: rect.height > 0 ? clampUnit((clickPosition.y - rect.top) / rect.height) : 0
|
|
3372
4228
|
};
|
|
3373
4229
|
const id = `comment-${Date.now()}-${Math.random().toString(36).slice(2, 7)}`;
|
|
3374
4230
|
const comment = {
|
|
@@ -3415,14 +4271,15 @@ function useTextAndComments({
|
|
|
3415
4271
|
const comment = stateRef.current.comments.find((c) => c.id === id);
|
|
3416
4272
|
if (!comment) return false;
|
|
3417
4273
|
const exportMarkdown = buildCommentExport(comment.locator, comment.text, comment.replies);
|
|
3418
|
-
|
|
3419
|
-
|
|
4274
|
+
const instruction = buildExportInstruction({
|
|
4275
|
+
hasCssEdits: false,
|
|
4276
|
+
hasTextEdits: false,
|
|
4277
|
+
hasMoves: false,
|
|
4278
|
+
hasComments: true
|
|
4279
|
+
});
|
|
4280
|
+
return copyText(`${instruction}
|
|
3420
4281
|
|
|
3421
4282
|
${exportMarkdown}`);
|
|
3422
|
-
return true;
|
|
3423
|
-
} catch {
|
|
3424
|
-
return false;
|
|
3425
|
-
}
|
|
3426
4283
|
}, []);
|
|
3427
4284
|
const setActiveCommentId = React4.useCallback((id) => {
|
|
3428
4285
|
setState((prev) => {
|
|
@@ -3820,24 +4677,36 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems }) {
|
|
|
3820
4677
|
const sessionEdit = sessionEditsRef.current.get(selectedElement);
|
|
3821
4678
|
const hasPendingStyles = Object.keys(pendingStyles).length > 0;
|
|
3822
4679
|
const hasTextEdit = Boolean(sessionEdit?.textEdit);
|
|
3823
|
-
const hasMove = Boolean(
|
|
4680
|
+
const hasMove = Boolean(
|
|
4681
|
+
sessionEdit?.move && getMoveIntentForEdit(sessionEdit, buildMovePlanContext([sessionEdit]))
|
|
4682
|
+
);
|
|
3824
4683
|
return hasPendingStyles || hasTextEdit || hasMove;
|
|
3825
4684
|
}, []);
|
|
3826
|
-
const sendSessionEditToAgent = React5.useCallback(async (sessionEdit) => {
|
|
4685
|
+
const sendSessionEditToAgent = React5.useCallback(async (sessionEdit, allEdits, movePlanContext, options) => {
|
|
3827
4686
|
const locator = sessionEdit.locator;
|
|
3828
4687
|
const pendingStyles = { ...sessionEdit.pendingStyles };
|
|
3829
|
-
const
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
4688
|
+
const editsForPlan = allEdits ?? [sessionEdit];
|
|
4689
|
+
const resolvedPlanContext = movePlanContext ?? buildMovePlanContext(editsForPlan);
|
|
4690
|
+
const includeBatchMoveEnvelope = Boolean(options?.includeBatchMoveEnvelope && sessionEdit.move);
|
|
4691
|
+
const isBatchSend = Boolean(allEdits && allEdits.length > 1);
|
|
4692
|
+
const exportMarkdown = sessionEdit.move ? buildSessionExport(
|
|
4693
|
+
includeBatchMoveEnvelope ? editsForPlan : [sessionEdit],
|
|
4694
|
+
[],
|
|
4695
|
+
{
|
|
4696
|
+
movePlanContext: resolvedPlanContext,
|
|
4697
|
+
includeMovePlanHeader: includeBatchMoveEnvelope || !isBatchSend
|
|
4698
|
+
}
|
|
4699
|
+
) : buildEditExport(locator, pendingStyles, sessionEdit.textEdit);
|
|
3835
4700
|
const collapsedStyles = collapseExportShorthands(pendingStyles);
|
|
3836
4701
|
const changes = Object.entries(collapsedStyles).map(([cssProperty, cssValue]) => ({
|
|
3837
4702
|
cssProperty,
|
|
3838
4703
|
cssValue,
|
|
3839
4704
|
tailwindClass: stylesToTailwind({ [cssProperty]: cssValue })
|
|
3840
4705
|
}));
|
|
4706
|
+
const moveIntent = sessionEdit.move ? getMoveIntentForEdit(sessionEdit, resolvedPlanContext) : null;
|
|
4707
|
+
const movePlan = includeBatchMoveEnvelope ? resolvedPlanContext.movePlan : null;
|
|
4708
|
+
const hasMeaningfulPayload = changes.length > 0 || sessionEdit.textEdit != null || moveIntent != null;
|
|
4709
|
+
if (!hasMeaningfulPayload) return true;
|
|
3841
4710
|
try {
|
|
3842
4711
|
const result = await sendEditToAgent({
|
|
3843
4712
|
element: {
|
|
@@ -3852,7 +4721,8 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems }) {
|
|
|
3852
4721
|
reactStack: locator.reactStack,
|
|
3853
4722
|
changes,
|
|
3854
4723
|
textChange: sessionEdit.textEdit ?? null,
|
|
3855
|
-
|
|
4724
|
+
moveIntent,
|
|
4725
|
+
...movePlan ? { movePlan } : {},
|
|
3856
4726
|
exportMarkdown
|
|
3857
4727
|
});
|
|
3858
4728
|
return result.ok;
|
|
@@ -3911,9 +4781,25 @@ function useAgentComms({ stateRef, sessionEditsRef, getSessionItems }) {
|
|
|
3911
4781
|
const sendAllSessionItemsToAgent = React5.useCallback(async () => {
|
|
3912
4782
|
const items = getSessionItems();
|
|
3913
4783
|
if (items.length === 0) return false;
|
|
4784
|
+
const allEdits = items.filter((i) => i.type === "edit").map((i) => i.edit);
|
|
4785
|
+
const movePlanContext = buildMovePlanContext(allEdits);
|
|
4786
|
+
let moveEnvelopeSent = false;
|
|
3914
4787
|
let allSucceeded = true;
|
|
3915
4788
|
for (const item of items) {
|
|
3916
|
-
|
|
4789
|
+
let succeeded;
|
|
4790
|
+
if (item.type === "edit") {
|
|
4791
|
+
const hasMoveIntent = Boolean(item.edit.move && getMoveIntentForEdit(item.edit, movePlanContext));
|
|
4792
|
+
const includeBatchMoveEnvelope = hasMoveIntent && !moveEnvelopeSent;
|
|
4793
|
+
succeeded = await sendSessionEditToAgent(
|
|
4794
|
+
item.edit,
|
|
4795
|
+
allEdits,
|
|
4796
|
+
movePlanContext,
|
|
4797
|
+
{ includeBatchMoveEnvelope }
|
|
4798
|
+
);
|
|
4799
|
+
if (includeBatchMoveEnvelope) moveEnvelopeSent = true;
|
|
4800
|
+
} else {
|
|
4801
|
+
succeeded = await sendSessionCommentToAgent(item.comment);
|
|
4802
|
+
}
|
|
3917
4803
|
if (!succeeded) {
|
|
3918
4804
|
allSucceeded = false;
|
|
3919
4805
|
}
|
|
@@ -4105,6 +4991,8 @@ var LINE_HEIGHT_PX = 40;
|
|
|
4105
4991
|
var PAGE_HEIGHT_PX = 800;
|
|
4106
4992
|
var CANVAS_MEASURE_NODE_BUDGET = 12e3;
|
|
4107
4993
|
var CANVAS_PRIORITY_ROOT_SELECTORS = ["#root", "#app", "#__next", "main"];
|
|
4994
|
+
var FIXED_FRAME_CANVAS_MIN_VIEWPORT_COVERAGE = 0.6;
|
|
4995
|
+
var FIXED_FRAME_CANVAS_EDGE_TOLERANCE_PX = 1;
|
|
4108
4996
|
function normalizeWheelDelta(e) {
|
|
4109
4997
|
let { deltaX, deltaY } = e;
|
|
4110
4998
|
if (e.deltaMode === 1) {
|
|
@@ -4116,6 +5004,46 @@ function normalizeWheelDelta(e) {
|
|
|
4116
5004
|
}
|
|
4117
5005
|
return { deltaX, deltaY };
|
|
4118
5006
|
}
|
|
5007
|
+
function getVisibleAreaInViewport(rect) {
|
|
5008
|
+
const left = Math.max(0, rect.left);
|
|
5009
|
+
const top = Math.max(0, rect.top);
|
|
5010
|
+
const right = Math.min(window.innerWidth, rect.right);
|
|
5011
|
+
const bottom = Math.min(window.innerHeight, rect.bottom);
|
|
5012
|
+
const width = Math.max(0, right - left);
|
|
5013
|
+
const height = Math.max(0, bottom - top);
|
|
5014
|
+
return width * height;
|
|
5015
|
+
}
|
|
5016
|
+
function getFixedFrameCanvasDimensions() {
|
|
5017
|
+
const viewportWidth = window.innerWidth;
|
|
5018
|
+
const viewportHeight = window.innerHeight;
|
|
5019
|
+
const viewportArea = viewportWidth * viewportHeight;
|
|
5020
|
+
if (viewportArea <= 0) return null;
|
|
5021
|
+
let bestArea = 0;
|
|
5022
|
+
let bestRect = null;
|
|
5023
|
+
const canvases = document.querySelectorAll("canvas");
|
|
5024
|
+
for (const canvas of canvases) {
|
|
5025
|
+
if (canvas.closest("[data-direct-edit]") || canvas.closest("[data-direct-edit-host]")) continue;
|
|
5026
|
+
const style = getComputedStyle(canvas);
|
|
5027
|
+
if (style.display === "none" || style.visibility === "hidden") continue;
|
|
5028
|
+
const opacity = parseFloat(style.opacity);
|
|
5029
|
+
if ((Number.isFinite(opacity) ? opacity : 1) <= 0) continue;
|
|
5030
|
+
const rect = canvas.getBoundingClientRect();
|
|
5031
|
+
if (style.position !== "fixed") continue;
|
|
5032
|
+
if (Math.abs(rect.left) > FIXED_FRAME_CANVAS_EDGE_TOLERANCE_PX || Math.abs(rect.top) > FIXED_FRAME_CANVAS_EDGE_TOLERANCE_PX) {
|
|
5033
|
+
continue;
|
|
5034
|
+
}
|
|
5035
|
+
const visibleArea = getVisibleAreaInViewport(rect);
|
|
5036
|
+
if (visibleArea <= bestArea) continue;
|
|
5037
|
+
bestArea = visibleArea;
|
|
5038
|
+
bestRect = rect;
|
|
5039
|
+
}
|
|
5040
|
+
if (!bestRect) return null;
|
|
5041
|
+
if (bestArea / viewportArea < FIXED_FRAME_CANVAS_MIN_VIEWPORT_COVERAGE) return null;
|
|
5042
|
+
return {
|
|
5043
|
+
width: Math.max(viewportWidth, bestRect.width),
|
|
5044
|
+
height: Math.max(viewportHeight, bestRect.height)
|
|
5045
|
+
};
|
|
5046
|
+
}
|
|
4119
5047
|
function getResolvedOverflowY(style) {
|
|
4120
5048
|
return style.overflowY || style.overflow;
|
|
4121
5049
|
}
|
|
@@ -4178,6 +5106,7 @@ function clampPan(zoom, panX, panY, bodyW, bodyH) {
|
|
|
4178
5106
|
function useCanvas({ stateRef, setState }) {
|
|
4179
5107
|
React7.useEffect(() => registerCanvasStoreOwner(), []);
|
|
4180
5108
|
const canvasRef = React7.useRef({ active: false, zoom: 1, panX: 0, panY: 0 });
|
|
5109
|
+
const canvasStrategyRef = React7.useRef("body-transform");
|
|
4181
5110
|
const savedScrollRef = React7.useRef({ x: 0, y: 0 });
|
|
4182
5111
|
const savedBodyOverflowRef = React7.useRef("");
|
|
4183
5112
|
const savedHtmlOverflowRef = React7.useRef("");
|
|
@@ -4198,6 +5127,9 @@ function useCanvas({ stateRef, setState }) {
|
|
|
4198
5127
|
window.dispatchEvent(new Event("direct-edit-canvas-change"));
|
|
4199
5128
|
}, []);
|
|
4200
5129
|
const readBodyOffset = React7.useCallback(() => {
|
|
5130
|
+
if (canvasStrategyRef.current !== "body-transform") {
|
|
5131
|
+
return { x: 0, y: 0 };
|
|
5132
|
+
}
|
|
4201
5133
|
const bodyStyle = getComputedStyle(document.body);
|
|
4202
5134
|
return {
|
|
4203
5135
|
x: parseFloat(bodyStyle.marginLeft) || 0,
|
|
@@ -4334,20 +5266,32 @@ function useCanvas({ stateRef, setState }) {
|
|
|
4334
5266
|
savedHtmlOverflowRef.current = document.documentElement.style.overflow;
|
|
4335
5267
|
savedHtmlBgColorRef.current = document.documentElement.style.backgroundColor;
|
|
4336
5268
|
domStateSavedRef.current = true;
|
|
4337
|
-
const
|
|
4338
|
-
|
|
4339
|
-
|
|
5269
|
+
const fixedFrameDims = getFixedFrameCanvasDimensions();
|
|
5270
|
+
canvasStrategyRef.current = fixedFrameDims ? "fixed-frame" : "body-transform";
|
|
5271
|
+
if (canvasStrategyRef.current === "body-transform") {
|
|
5272
|
+
const existingTransform = document.body.style.transform;
|
|
5273
|
+
if (existingTransform && existingTransform !== "none" && existingTransform !== "") {
|
|
5274
|
+
console.warn("[made-refine] canvas mode: overriding existing body transform:", existingTransform);
|
|
5275
|
+
}
|
|
4340
5276
|
}
|
|
4341
5277
|
let entered = false;
|
|
4342
5278
|
try {
|
|
4343
5279
|
window.scrollTo(0, 0);
|
|
4344
|
-
|
|
4345
|
-
|
|
5280
|
+
if (canvasStrategyRef.current === "body-transform") {
|
|
5281
|
+
savedBodyDimensionsRef.current = expandScrollableRegionsAndMeasureBody();
|
|
5282
|
+
updateBodyOffset();
|
|
5283
|
+
} else {
|
|
5284
|
+
savedBodyDimensionsRef.current = fixedFrameDims ?? {
|
|
5285
|
+
width: window.innerWidth,
|
|
5286
|
+
height: window.innerHeight
|
|
5287
|
+
};
|
|
5288
|
+
setBodyOffset({ x: 0, y: 0 });
|
|
5289
|
+
}
|
|
4346
5290
|
document.body.style.overflow = "hidden";
|
|
4347
5291
|
document.documentElement.style.overflow = "hidden";
|
|
4348
5292
|
document.documentElement.style.backgroundColor = "#F5F5F5";
|
|
4349
|
-
const initialPanX = -scrollX;
|
|
4350
|
-
const initialPanY = -scrollY;
|
|
5293
|
+
const initialPanX = canvasStrategyRef.current === "body-transform" ? -scrollX : 0;
|
|
5294
|
+
const initialPanY = canvasStrategyRef.current === "body-transform" ? -scrollY : 0;
|
|
4351
5295
|
applyTransform(1, initialPanX, initialPanY);
|
|
4352
5296
|
canvasRef.current = { active: true, zoom: 1, panX: initialPanX, panY: initialPanY };
|
|
4353
5297
|
setCanvasSnapshot(canvasRef.current);
|
|
@@ -4367,6 +5311,7 @@ function useCanvas({ stateRef, setState }) {
|
|
|
4367
5311
|
document.documentElement.style.backgroundColor = savedHtmlBgColorRef.current;
|
|
4368
5312
|
window.scrollTo(scrollX, scrollY);
|
|
4369
5313
|
domStateSavedRef.current = false;
|
|
5314
|
+
canvasStrategyRef.current = "body-transform";
|
|
4370
5315
|
}
|
|
4371
5316
|
}
|
|
4372
5317
|
}, [applyTransform, dispatchCanvasChange, setState, updateBodyOffset]);
|
|
@@ -4386,6 +5331,7 @@ function useCanvas({ stateRef, setState }) {
|
|
|
4386
5331
|
}
|
|
4387
5332
|
document.body.style.cursor = "";
|
|
4388
5333
|
domStateSavedRef.current = false;
|
|
5334
|
+
canvasStrategyRef.current = "body-transform";
|
|
4389
5335
|
setBodyOffset({ x: 0, y: 0 });
|
|
4390
5336
|
canvasRef.current = { active: false, zoom: 1, panX: 0, panY: 0 };
|
|
4391
5337
|
setCanvasSnapshot(canvasRef.current);
|
|
@@ -4455,6 +5401,14 @@ function useCanvas({ stateRef, setState }) {
|
|
|
4455
5401
|
React7.useEffect(() => {
|
|
4456
5402
|
function handleResize() {
|
|
4457
5403
|
if (!canvasRef.current.active) return;
|
|
5404
|
+
if (canvasStrategyRef.current === "fixed-frame") {
|
|
5405
|
+
savedBodyDimensionsRef.current = getFixedFrameCanvasDimensions() ?? {
|
|
5406
|
+
width: window.innerWidth,
|
|
5407
|
+
height: window.innerHeight
|
|
5408
|
+
};
|
|
5409
|
+
dispatchCanvasChange();
|
|
5410
|
+
return;
|
|
5411
|
+
}
|
|
4458
5412
|
if (updateBodyOffset()) {
|
|
4459
5413
|
dispatchCanvasChange();
|
|
4460
5414
|
}
|
|
@@ -4721,6 +5675,17 @@ function DirectEditProvider({ children }) {
|
|
|
4721
5675
|
document.removeEventListener("mousedown", handleMouseDown, true);
|
|
4722
5676
|
};
|
|
4723
5677
|
}, [state.textEditingElement, commitTextEditing]);
|
|
5678
|
+
React8.useEffect(() => {
|
|
5679
|
+
if (!state.editModeActive || state.textEditingElement) return;
|
|
5680
|
+
function blockClick(e) {
|
|
5681
|
+
const host = document.querySelector("[data-direct-edit-host]");
|
|
5682
|
+
if (host && e.target === host) return;
|
|
5683
|
+
e.preventDefault();
|
|
5684
|
+
e.stopPropagation();
|
|
5685
|
+
}
|
|
5686
|
+
document.addEventListener("click", blockClick, true);
|
|
5687
|
+
return () => document.removeEventListener("click", blockClick, true);
|
|
5688
|
+
}, [state.editModeActive, state.textEditingElement]);
|
|
4724
5689
|
const {
|
|
4725
5690
|
canSendEditToAgent,
|
|
4726
5691
|
sendEditToAgent: sendEditToAgent2,
|
|
@@ -5148,6 +6113,37 @@ var INITIAL_DRAG_STATE = {
|
|
|
5148
6113
|
ghostPosition: { x: 0, y: 0 },
|
|
5149
6114
|
dragOffset: { x: 0, y: 0 }
|
|
5150
6115
|
};
|
|
6116
|
+
var DEFAULT_DRAG_OPTIONS = {
|
|
6117
|
+
constrainToOriginalParent: false,
|
|
6118
|
+
mode: "free"
|
|
6119
|
+
};
|
|
6120
|
+
function normalizeStartDragOptions(options) {
|
|
6121
|
+
const mode = options?.mode ?? (options?.constrainToOriginalParent ? "reorder" : "free");
|
|
6122
|
+
return {
|
|
6123
|
+
mode,
|
|
6124
|
+
constrainToOriginalParent: mode === "reorder" || Boolean(options?.constrainToOriginalParent)
|
|
6125
|
+
};
|
|
6126
|
+
}
|
|
6127
|
+
function resolveFlexDirection(container, draggedElement) {
|
|
6128
|
+
const { axis, reversed } = detectChildrenDirection(container, draggedElement);
|
|
6129
|
+
if (axis === "horizontal") return reversed ? "row-reverse" : "row";
|
|
6130
|
+
return reversed ? "column-reverse" : "column";
|
|
6131
|
+
}
|
|
6132
|
+
function tryReparent(draggedElement, target, originalParent, originalNextSibling) {
|
|
6133
|
+
const isSamePosition = target.container === originalParent && target.insertBefore === originalNextSibling;
|
|
6134
|
+
const isInvalidTarget = target.container === draggedElement || draggedElement.contains(target.container) || (target.insertBefore ? draggedElement.contains(target.insertBefore) : false);
|
|
6135
|
+
if (isSamePosition || isInvalidTarget) return false;
|
|
6136
|
+
try {
|
|
6137
|
+
if (target.insertBefore) {
|
|
6138
|
+
target.container.insertBefore(draggedElement, target.insertBefore);
|
|
6139
|
+
} else {
|
|
6140
|
+
target.container.appendChild(draggedElement);
|
|
6141
|
+
}
|
|
6142
|
+
return true;
|
|
6143
|
+
} catch {
|
|
6144
|
+
return false;
|
|
6145
|
+
}
|
|
6146
|
+
}
|
|
5151
6147
|
function useMove({ onMoveComplete }) {
|
|
5152
6148
|
const [dragState, setDragState] = React12.useState(INITIAL_DRAG_STATE);
|
|
5153
6149
|
const [dropTarget, setDropTarget] = React12.useState(null);
|
|
@@ -5155,7 +6151,11 @@ function useMove({ onMoveComplete }) {
|
|
|
5155
6151
|
const dragStateRef = React12.useRef(dragState);
|
|
5156
6152
|
const dropTargetRef = React12.useRef(dropTarget);
|
|
5157
6153
|
const onMoveCompleteRef = React12.useRef(onMoveComplete);
|
|
5158
|
-
const dragOptionsRef = React12.useRef(
|
|
6154
|
+
const dragOptionsRef = React12.useRef(DEFAULT_DRAG_OPTIONS);
|
|
6155
|
+
const initialRectRef = React12.useRef(
|
|
6156
|
+
{ x: 0, y: 0, scaleX: 1, scaleY: 1 }
|
|
6157
|
+
);
|
|
6158
|
+
const originalTransformRef = React12.useRef("");
|
|
5159
6159
|
React12.useEffect(() => {
|
|
5160
6160
|
dragStateRef.current = dragState;
|
|
5161
6161
|
dropTargetRef.current = dropTarget;
|
|
@@ -5165,8 +6165,11 @@ function useMove({ onMoveComplete }) {
|
|
|
5165
6165
|
const current = dragStateRef.current;
|
|
5166
6166
|
if (current.draggedElement) {
|
|
5167
6167
|
current.draggedElement.style.opacity = "";
|
|
6168
|
+
current.draggedElement.style.transform = originalTransformRef.current;
|
|
5168
6169
|
}
|
|
5169
|
-
|
|
6170
|
+
originalTransformRef.current = "";
|
|
6171
|
+
initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
|
|
6172
|
+
dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
|
|
5170
6173
|
setDragState(INITIAL_DRAG_STATE);
|
|
5171
6174
|
setDropTarget(null);
|
|
5172
6175
|
setDropIndicator(null);
|
|
@@ -5179,31 +6182,43 @@ function useMove({ onMoveComplete }) {
|
|
|
5179
6182
|
cancelDrag();
|
|
5180
6183
|
return;
|
|
5181
6184
|
}
|
|
6185
|
+
const initialPos = { x: initialRectRef.current.x, y: initialRectRef.current.y };
|
|
6186
|
+
const { scaleX, scaleY } = initialRectRef.current;
|
|
6187
|
+
draggedElement.style.transform = originalTransformRef.current;
|
|
5182
6188
|
draggedElement.style.opacity = "";
|
|
5183
|
-
|
|
5184
|
-
|
|
5185
|
-
|
|
5186
|
-
|
|
5187
|
-
|
|
5188
|
-
|
|
5189
|
-
|
|
5190
|
-
|
|
5191
|
-
|
|
5192
|
-
|
|
5193
|
-
|
|
5194
|
-
|
|
5195
|
-
|
|
5196
|
-
|
|
6189
|
+
originalTransformRef.current = "";
|
|
6190
|
+
initialRectRef.current = { x: 0, y: 0, scaleX: 1, scaleY: 1 };
|
|
6191
|
+
const dragMode = dragOptionsRef.current.mode;
|
|
6192
|
+
dragOptionsRef.current = DEFAULT_DRAG_OPTIONS;
|
|
6193
|
+
const vd = {
|
|
6194
|
+
x: Math.round(current.ghostPosition.x - initialPos.x),
|
|
6195
|
+
y: Math.round(current.ghostPosition.y - initialPos.y)
|
|
6196
|
+
};
|
|
6197
|
+
const hasVisualDelta = vd.x !== 0 || vd.y !== 0;
|
|
6198
|
+
let moveInfo = null;
|
|
6199
|
+
if (dragMode === "position") {
|
|
6200
|
+
if (target && tryReparent(draggedElement, target, originalParent, originalNextSibling)) {
|
|
6201
|
+
if (originalParent) {
|
|
6202
|
+
moveInfo = { originalParent, originalPreviousSibling, originalNextSibling, mode: "free", resetPositionOffsets: true, visualDelta: hasVisualDelta ? vd : void 0 };
|
|
5197
6203
|
}
|
|
5198
6204
|
}
|
|
6205
|
+
if (!moveInfo) {
|
|
6206
|
+
const rect = draggedElement.getBoundingClientRect();
|
|
6207
|
+
const deltaX = (current.ghostPosition.x - rect.left) / scaleX;
|
|
6208
|
+
const deltaY = (current.ghostPosition.y - rect.top) / scaleY;
|
|
6209
|
+
if ((Math.abs(deltaX) > 0.5 || Math.abs(deltaY) > 0.5) && originalParent) {
|
|
6210
|
+
moveInfo = { originalParent, originalPreviousSibling, originalNextSibling, mode: "position", positionDelta: { x: deltaX, y: deltaY } };
|
|
6211
|
+
}
|
|
6212
|
+
}
|
|
6213
|
+
} else if (target && tryReparent(draggedElement, target, originalParent, originalNextSibling)) {
|
|
6214
|
+
if (originalParent) {
|
|
6215
|
+
moveInfo = { originalParent, originalPreviousSibling, originalNextSibling, mode: dragMode, visualDelta: hasVisualDelta ? vd : void 0 };
|
|
6216
|
+
}
|
|
5199
6217
|
}
|
|
5200
6218
|
setDragState(INITIAL_DRAG_STATE);
|
|
5201
6219
|
setDropTarget(null);
|
|
5202
6220
|
setDropIndicator(null);
|
|
5203
|
-
|
|
5204
|
-
const moveInfo = didMove && originalParent ? { originalParent, originalPreviousSibling, originalNextSibling } : null;
|
|
5205
|
-
onMoveCompleteRef.current(draggedElement, moveInfo);
|
|
5206
|
-
}
|
|
6221
|
+
onMoveCompleteRef.current?.(draggedElement, moveInfo);
|
|
5207
6222
|
}, [cancelDrag]);
|
|
5208
6223
|
const startDrag = React12.useCallback(
|
|
5209
6224
|
(e, element, options) => {
|
|
@@ -5211,7 +6226,14 @@ function useMove({ onMoveComplete }) {
|
|
|
5211
6226
|
const parent = element.parentElement;
|
|
5212
6227
|
const previousSibling = element.previousElementSibling;
|
|
5213
6228
|
const nextSibling = element.nextElementSibling;
|
|
5214
|
-
dragOptionsRef.current = options
|
|
6229
|
+
dragOptionsRef.current = normalizeStartDragOptions(options);
|
|
6230
|
+
initialRectRef.current = {
|
|
6231
|
+
x: rect.left,
|
|
6232
|
+
y: rect.top,
|
|
6233
|
+
scaleX: element.offsetWidth > 0 ? rect.width / element.offsetWidth : 1,
|
|
6234
|
+
scaleY: element.offsetHeight > 0 ? rect.height / element.offsetHeight : 1
|
|
6235
|
+
};
|
|
6236
|
+
originalTransformRef.current = element.style.transform;
|
|
5215
6237
|
setDragState({
|
|
5216
6238
|
isDragging: true,
|
|
5217
6239
|
draggedElement: element,
|
|
@@ -5237,6 +6259,44 @@ function useMove({ onMoveComplete }) {
|
|
|
5237
6259
|
y: e.clientY - dragOffset.y
|
|
5238
6260
|
}
|
|
5239
6261
|
}));
|
|
6262
|
+
if (draggedElement) {
|
|
6263
|
+
const { x, y, scaleX, scaleY } = initialRectRef.current;
|
|
6264
|
+
const dx = (e.clientX - dragOffset.x - x) / scaleX;
|
|
6265
|
+
const dy = (e.clientY - dragOffset.y - y) / scaleY;
|
|
6266
|
+
draggedElement.style.transform = `translate(${dx}px, ${dy}px)`;
|
|
6267
|
+
}
|
|
6268
|
+
if (dragOptionsRef.current.mode === "position") {
|
|
6269
|
+
let container2 = findLayoutContainerAtPoint(
|
|
6270
|
+
e.clientX,
|
|
6271
|
+
e.clientY,
|
|
6272
|
+
draggedElement,
|
|
6273
|
+
originalParent
|
|
6274
|
+
);
|
|
6275
|
+
if (!container2 && draggedElement && originalParent) {
|
|
6276
|
+
const parentRect = originalParent.getBoundingClientRect();
|
|
6277
|
+
const hasSize = parentRect.width > 0 || parentRect.height > 0;
|
|
6278
|
+
const isOutside = hasSize && (e.clientX < parentRect.left || e.clientX > parentRect.right || e.clientY < parentRect.top || e.clientY > parentRect.bottom);
|
|
6279
|
+
if (isOutside) {
|
|
6280
|
+
const found = findContainerAtPoint(e.clientX, e.clientY, draggedElement, null);
|
|
6281
|
+
if (found && found !== originalParent) container2 = found;
|
|
6282
|
+
}
|
|
6283
|
+
}
|
|
6284
|
+
if (container2 && draggedElement) {
|
|
6285
|
+
const dropPos = calculateDropPosition(container2, e.clientX, e.clientY, draggedElement);
|
|
6286
|
+
if (dropPos) {
|
|
6287
|
+
setDropTarget({
|
|
6288
|
+
container: container2,
|
|
6289
|
+
insertBefore: dropPos.insertBefore,
|
|
6290
|
+
flexDirection: resolveFlexDirection(container2, draggedElement)
|
|
6291
|
+
});
|
|
6292
|
+
setDropIndicator(dropPos.indicator);
|
|
6293
|
+
}
|
|
6294
|
+
} else {
|
|
6295
|
+
setDropTarget(null);
|
|
6296
|
+
setDropIndicator(null);
|
|
6297
|
+
}
|
|
6298
|
+
return;
|
|
6299
|
+
}
|
|
5240
6300
|
const container = dragOptionsRef.current.constrainToOriginalParent ? originalParent : findContainerAtPoint(
|
|
5241
6301
|
e.clientX,
|
|
5242
6302
|
e.clientY,
|
|
@@ -5254,11 +6314,7 @@ function useMove({ onMoveComplete }) {
|
|
|
5254
6314
|
setDropTarget({
|
|
5255
6315
|
container,
|
|
5256
6316
|
insertBefore: dropPos.insertBefore,
|
|
5257
|
-
flexDirection: (
|
|
5258
|
-
const { axis, reversed } = detectChildrenDirection(container, draggedElement);
|
|
5259
|
-
if (axis === "horizontal") return reversed ? "row-reverse" : "row";
|
|
5260
|
-
return reversed ? "column-reverse" : "column";
|
|
5261
|
-
})()
|
|
6317
|
+
flexDirection: resolveFlexDirection(container, draggedElement)
|
|
5262
6318
|
});
|
|
5263
6319
|
setDropIndicator(dropPos.indicator);
|
|
5264
6320
|
}
|
|
@@ -5719,6 +6775,12 @@ var MAGENTA = "#E11BB6";
|
|
|
5719
6775
|
var DRAG_THRESHOLD = 4;
|
|
5720
6776
|
var DBLCLICK_DELAY = 300;
|
|
5721
6777
|
var HANDLE_SIZE = 12;
|
|
6778
|
+
function isInLayoutContainer(element) {
|
|
6779
|
+
const parent = element.parentElement;
|
|
6780
|
+
if (!parent) return false;
|
|
6781
|
+
const display = window.getComputedStyle(parent).display;
|
|
6782
|
+
return display === "flex" || display === "inline-flex" || display === "grid" || display === "inline-grid";
|
|
6783
|
+
}
|
|
5722
6784
|
function SelectionOverlay({
|
|
5723
6785
|
selectedElement,
|
|
5724
6786
|
draggedElement,
|
|
@@ -5737,8 +6799,16 @@ function SelectionOverlay({
|
|
|
5737
6799
|
const [moveHandleRects, setMoveHandleRects] = React14.useState([]);
|
|
5738
6800
|
const cleanupRef = React14.useRef(null);
|
|
5739
6801
|
const clickThroughTimerRef = React14.useRef(null);
|
|
6802
|
+
const isDraggingRef = React14.useRef(isDragging);
|
|
6803
|
+
isDraggingRef.current = isDragging;
|
|
6804
|
+
React14.useLayoutEffect(() => {
|
|
6805
|
+
if (!isDragging) {
|
|
6806
|
+
setRect(rectElement.getBoundingClientRect());
|
|
6807
|
+
}
|
|
6808
|
+
}, [isDragging, rectElement]);
|
|
5740
6809
|
React14.useEffect(() => {
|
|
5741
6810
|
function updateRect() {
|
|
6811
|
+
if (isDraggingRef.current) return;
|
|
5742
6812
|
setRect(rectElement.getBoundingClientRect());
|
|
5743
6813
|
}
|
|
5744
6814
|
updateRect();
|
|
@@ -5779,7 +6849,9 @@ function SelectionOverlay({
|
|
|
5779
6849
|
const dy = moveEvent.clientY - origin.y;
|
|
5780
6850
|
if (dx * dx + dy * dy >= DRAG_THRESHOLD * DRAG_THRESHOLD) {
|
|
5781
6851
|
cleanup();
|
|
5782
|
-
onMoveStart(savedEvent
|
|
6852
|
+
onMoveStart(savedEvent, void 0, {
|
|
6853
|
+
mode: isInLayoutContainer(selectedElement) ? "free" : "position"
|
|
6854
|
+
});
|
|
5783
6855
|
}
|
|
5784
6856
|
};
|
|
5785
6857
|
const onUp = (upEvent) => {
|
|
@@ -5836,7 +6908,7 @@ function SelectionOverlay({
|
|
|
5836
6908
|
flexParent = flexParent.parentElement;
|
|
5837
6909
|
}
|
|
5838
6910
|
if (!flexParent) {
|
|
5839
|
-
return [
|
|
6911
|
+
return [];
|
|
5840
6912
|
}
|
|
5841
6913
|
let target = selectedElement;
|
|
5842
6914
|
while (target.parentElement && target.parentElement !== flexParent) {
|
|
@@ -5879,7 +6951,7 @@ function SelectionOverlay({
|
|
|
5879
6951
|
clearTimeout(clickThroughTimerRef.current);
|
|
5880
6952
|
clickThroughTimerRef.current = null;
|
|
5881
6953
|
}
|
|
5882
|
-
onMoveStart(e, target, { constrainToOriginalParent: true });
|
|
6954
|
+
onMoveStart(e, target, { constrainToOriginalParent: true, mode: "reorder" });
|
|
5883
6955
|
};
|
|
5884
6956
|
const displayX = isDragging && ghostPosition ? ghostPosition.x : rect.left;
|
|
5885
6957
|
const displayY = isDragging && ghostPosition ? ghostPosition.y : rect.top;
|
|
@@ -5959,6 +7031,10 @@ function SelectionOverlay({
|
|
|
5959
7031
|
var React15 = __toESM(require("react"));
|
|
5960
7032
|
var import_lucide_react = require("lucide-react");
|
|
5961
7033
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
7034
|
+
function clampUnit2(value) {
|
|
7035
|
+
if (!Number.isFinite(value)) return 0;
|
|
7036
|
+
return Math.max(0, Math.min(1, value));
|
|
7037
|
+
}
|
|
5962
7038
|
function formatRelativeTime(timestamp) {
|
|
5963
7039
|
const seconds = Math.floor((Date.now() - timestamp) / 1e3);
|
|
5964
7040
|
if (seconds < 60) return "just now";
|
|
@@ -6041,9 +7117,11 @@ function CommentPin({
|
|
|
6041
7117
|
function updatePosition() {
|
|
6042
7118
|
if (!comment.element.isConnected) return;
|
|
6043
7119
|
const rect = comment.element.getBoundingClientRect();
|
|
7120
|
+
const relativeX = clampUnit2(comment.relativePosition.x);
|
|
7121
|
+
const relativeY = clampUnit2(comment.relativePosition.y);
|
|
6044
7122
|
setPosition({
|
|
6045
|
-
x: rect.left +
|
|
6046
|
-
y: rect.top +
|
|
7123
|
+
x: rect.left + relativeX * rect.width,
|
|
7124
|
+
y: rect.top + relativeY * rect.height
|
|
6047
7125
|
});
|
|
6048
7126
|
setElementRect(rect);
|
|
6049
7127
|
}
|
|
@@ -10261,6 +11339,11 @@ function truncateText(value, max = 64) {
|
|
|
10261
11339
|
if (value.length <= max) return value;
|
|
10262
11340
|
return `${value.slice(0, max)}...`;
|
|
10263
11341
|
}
|
|
11342
|
+
function summarizeMoveForPreview(intent) {
|
|
11343
|
+
const system = intent.layoutPrescription?.recommendedSystem;
|
|
11344
|
+
const systemPart = system ? `, ${system}` : "";
|
|
11345
|
+
return `${intent.operationId}: ${intent.classification}${systemPart}`;
|
|
11346
|
+
}
|
|
10264
11347
|
function EditsPopover({
|
|
10265
11348
|
tooltipSide,
|
|
10266
11349
|
sessionEditCount,
|
|
@@ -10278,6 +11361,19 @@ function EditsPopover({
|
|
|
10278
11361
|
const editsPopupRef = React33.useRef(null);
|
|
10279
11362
|
const editsTriggerRef = React33.useRef(null);
|
|
10280
11363
|
const [editsSnapshot, setEditsSnapshot] = React33.useState([]);
|
|
11364
|
+
const movePlanContext = React33.useMemo(() => {
|
|
11365
|
+
const edits = editsSnapshot.filter((item) => item.type === "edit").map((item) => item.edit);
|
|
11366
|
+
return buildMovePlanContext(edits);
|
|
11367
|
+
}, [editsSnapshot]);
|
|
11368
|
+
const visibleItems = React33.useMemo(() => {
|
|
11369
|
+
return editsSnapshot.filter((item) => {
|
|
11370
|
+
if (item.type === "comment") return true;
|
|
11371
|
+
if (!item.edit.move) return true;
|
|
11372
|
+
const moveIntent = getMoveIntentForEdit(item.edit, movePlanContext);
|
|
11373
|
+
const hasStyleOrText = Object.keys(item.edit.pendingStyles).length > 0 || item.edit.textEdit != null;
|
|
11374
|
+
return Boolean(moveIntent || hasStyleOrText);
|
|
11375
|
+
});
|
|
11376
|
+
}, [editsSnapshot, movePlanContext]);
|
|
10281
11377
|
React33.useEffect(() => {
|
|
10282
11378
|
if (!isOpen) return;
|
|
10283
11379
|
function handlePointerDown(e) {
|
|
@@ -10323,16 +11419,22 @@ function EditsPopover({
|
|
|
10323
11419
|
window.setTimeout(() => setSendStatus("idle"), 2e3);
|
|
10324
11420
|
}, [onSendAllToAgents, sendStatus]);
|
|
10325
11421
|
const handleCopyItem = React33.useCallback(async (item) => {
|
|
10326
|
-
const text = item.type === "edit" ? buildSessionExport([item.edit], []
|
|
10327
|
-
|
|
10328
|
-
|
|
11422
|
+
const text = item.type === "edit" ? buildSessionExport([item.edit], [], {
|
|
11423
|
+
movePlanContext,
|
|
11424
|
+
includeMovePlanHeader: false
|
|
11425
|
+
}) : buildSessionExport([], [item.comment]);
|
|
11426
|
+
const instruction = item.type === "edit" ? buildExportInstruction(getExportContentProfile(
|
|
11427
|
+
[item.edit],
|
|
11428
|
+
[],
|
|
11429
|
+
item.edit.move ? buildMovePlanContext([item.edit]) : null
|
|
11430
|
+
)) : buildExportInstruction({ hasCssEdits: false, hasTextEdits: false, hasMoves: false, hasComments: true });
|
|
11431
|
+
const success = await copyText(`${instruction}
|
|
10329
11432
|
|
|
10330
11433
|
${text}`);
|
|
10331
|
-
|
|
10332
|
-
|
|
10333
|
-
|
|
10334
|
-
|
|
10335
|
-
}, []);
|
|
11434
|
+
if (!success) return;
|
|
11435
|
+
setCopied(true);
|
|
11436
|
+
window.setTimeout(() => setCopied(false), 2e3);
|
|
11437
|
+
}, [movePlanContext]);
|
|
10336
11438
|
return /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(import_popover2.Popover.Root, { open: isOpen, onOpenChange, children: [
|
|
10337
11439
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(Tooltip, { disabled: isOpen, children: [
|
|
10338
11440
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)(TooltipTrigger, { render: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_popover2.Popover.Trigger, { render: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(
|
|
@@ -10363,7 +11465,7 @@ ${text}`);
|
|
|
10363
11465
|
children: [
|
|
10364
11466
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center justify-between px-3 pb-1 pt-2.5", children: [
|
|
10365
11467
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsx)("span", { className: "text-xs font-medium text-foreground", children: "Copy to AI agents" }),
|
|
10366
|
-
|
|
11468
|
+
visibleItems.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex items-center gap-1", children: [
|
|
10367
11469
|
/* @__PURE__ */ (0, import_jsx_runtime30.jsxs)(
|
|
10368
11470
|
import_button7.Button,
|
|
10369
11471
|
{
|
|
@@ -10406,9 +11508,10 @@ ${text}`);
|
|
|
10406
11508
|
] })
|
|
10407
11509
|
] })
|
|
10408
11510
|
] }),
|
|
10409
|
-
|
|
11511
|
+
visibleItems.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "px-3 pb-3 pt-1 text-xs text-muted-foreground", children: "No edits or comments yet." }) : /* @__PURE__ */ (0, import_jsx_runtime30.jsx)("div", { className: "max-h-[240px] overflow-y-auto px-1 py-1", children: visibleItems.map((item, i) => {
|
|
10410
11512
|
const isEdit = item.type === "edit";
|
|
10411
|
-
const
|
|
11513
|
+
const moveIntent = isEdit && item.edit.move ? getMoveIntentForEdit(item.edit, movePlanContext) : null;
|
|
11514
|
+
const isMoved = Boolean(moveIntent);
|
|
10412
11515
|
const locator = isEdit ? item.edit.locator : item.comment.locator;
|
|
10413
11516
|
const componentName = locator.reactStack[0]?.name ?? locator.tagName;
|
|
10414
11517
|
let valueSummary = "";
|
|
@@ -10421,8 +11524,8 @@ ${text}`);
|
|
|
10421
11524
|
if (item.edit.textEdit) {
|
|
10422
11525
|
editValues.push(`text: "${item.edit.textEdit.newText}"`);
|
|
10423
11526
|
}
|
|
10424
|
-
if (
|
|
10425
|
-
editValues.push(
|
|
11527
|
+
if (moveIntent) {
|
|
11528
|
+
editValues.push(summarizeMoveForPreview(moveIntent));
|
|
10426
11529
|
}
|
|
10427
11530
|
valueSummary = editValues.length > 0 ? editValues.join(", ") : "(no edits)";
|
|
10428
11531
|
} else {
|
|
@@ -10473,7 +11576,15 @@ ${text}`);
|
|
|
10473
11576
|
} else {
|
|
10474
11577
|
onDeleteComment?.(item.comment.id);
|
|
10475
11578
|
}
|
|
10476
|
-
setEditsSnapshot((prev) => prev.filter((
|
|
11579
|
+
setEditsSnapshot((prev) => prev.filter((candidate) => {
|
|
11580
|
+
if (item.type === "edit" && candidate.type === "edit") {
|
|
11581
|
+
return candidate.edit.element !== item.edit.element;
|
|
11582
|
+
}
|
|
11583
|
+
if (item.type === "comment" && candidate.type === "comment") {
|
|
11584
|
+
return candidate.comment.id !== item.comment.id;
|
|
11585
|
+
}
|
|
11586
|
+
return true;
|
|
11587
|
+
}));
|
|
10477
11588
|
},
|
|
10478
11589
|
children: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_lucide_react13.X, { className: "size-3" })
|
|
10479
11590
|
}
|
|
@@ -11286,12 +12397,7 @@ function DirectEditDemo() {
|
|
|
11286
12397
|
const handleExportEdits = async () => {
|
|
11287
12398
|
if (Object.keys(pendingStyles).length === 0) return false;
|
|
11288
12399
|
const exportMarkdown = buildEditExport(DEMO_LOCATOR, pendingStyles);
|
|
11289
|
-
|
|
11290
|
-
await navigator.clipboard.writeText(exportMarkdown);
|
|
11291
|
-
return true;
|
|
11292
|
-
} catch {
|
|
11293
|
-
return false;
|
|
11294
|
-
}
|
|
12400
|
+
return copyText(buildAgentClipboardText(exportMarkdown));
|
|
11295
12401
|
};
|
|
11296
12402
|
return /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("div", { className: "min-h-screen p-8", children: /* @__PURE__ */ (0, import_jsx_runtime35.jsxs)("div", { className: "mx-auto max-w-4xl", children: [
|
|
11297
12403
|
/* @__PURE__ */ (0, import_jsx_runtime35.jsx)("h1", { className: "mb-2 text-2xl font-bold", children: "Direct Edit Panel" }),
|
|
@@ -11408,6 +12514,7 @@ function DirectEditDemo() {
|
|
|
11408
12514
|
colorToTailwind,
|
|
11409
12515
|
elementFromPointWithoutOverlays,
|
|
11410
12516
|
findContainerAtPoint,
|
|
12517
|
+
findLayoutContainerAtPoint,
|
|
11411
12518
|
formatColorValue,
|
|
11412
12519
|
formatPropertyValue,
|
|
11413
12520
|
getComputedBorderStyles,
|
|
@@ -11420,6 +12527,7 @@ function DirectEditDemo() {
|
|
|
11420
12527
|
getFlexDirection,
|
|
11421
12528
|
getStoredGuidelines,
|
|
11422
12529
|
isFlexContainer,
|
|
12530
|
+
isLayoutContainer,
|
|
11423
12531
|
parseColorValue,
|
|
11424
12532
|
parsePropertyValue,
|
|
11425
12533
|
stylesToTailwind,
|