@rogieking/figui3 4.15.10 → 5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,167 @@
1
+ import{gradientToValueShape as F,gradientInterpolationClause as V,normalizeGradientConfig as k}from"./fig.js";class N extends HTMLElement{#y=null;#$=null;#Q=null;#b="solid";anchorElement=null;#U="solid";#L="srgb";#Y={h:0,s:0,v:85,a:1};#H="hex";#X={type:"linear",angle:0,centerX:50,centerY:50,interpolationSpace:"oklab",hueInterpolation:"shorter",stops:[{position:0,color:"#D9D9D9",opacity:100},{position:100,color:"#737373",opacity:100}]};#j={url:null,scaleMode:"fill",scale:50};#J={url:null,scaleMode:"fill",scale:50};#K={stream:null,snapshot:null};#R={};#A={};#z=null;#O=null;#N=null;#B=null;#M=!1;#F=null;#T=null;#P=null;constructor(){super()}static get observedAttributes(){return["value","disabled","alpha","mode","experimental"]}connectedCallback(){this.style.display="contents",requestAnimationFrame(()=>{this.#o(),this.#h(),this.#W()})}disconnectedCallback(){if(this.#F)this.#F(),this.#F=null;if(this.#T)this.#T.disconnect(),this.#T=null;if(this.#P)this.#P.disconnect(),this.#P=null;if(this.#K.stream)this.#K.stream.getTracks().forEach((Q)=>Q.stop()),this.#K.stream=null;if(this.#K.snapshot?.startsWith("blob:"))URL.revokeObjectURL(this.#K.snapshot),this.#K.snapshot=null;if(this.#J.url&&this.#J.url.startsWith("blob:"))URL.revokeObjectURL(this.#J.url);if(this.#$)this.#$.removeAttribute("selected");if(this.#Q)this.#Q.close(),this.#Q.remove(),this.#Q=null}#o(){let Q=Array.from(this.children).find((X)=>!X.getAttribute("slot")?.startsWith("mode-"));if(!Q)this.#$=document.createElement("fig-chit"),this.#$.setAttribute("background","#D9D9D9"),this.appendChild(this.#$),this.#y=this.#$;else if(Q.tagName==="FIG-CHIT")this.#$=Q,this.#y=Q;else this.#y=Q,this.#$=null;if(this.#y.addEventListener("click",(X)=>{if(this.hasAttribute("disabled"))return;X.stopPropagation(),X.preventDefault(),this.#m()}),this.#$)requestAnimationFrame(()=>{let X=this.#$.querySelector('input[type="color"]');if(X)X.style.pointerEvents="none"})}#h(){let Q=this.getAttribute("value");if(!Q)return;let X=["solid","gradient","image","video","webcam"];try{let Y=JSON.parse(Q);if(Y.type)this.#U=Y.type;if(Y.color){if(typeof Y.color==="string")this.#Y=this.#C(Y.color);else if(typeof Y.color==="object"&&Y.color.h!==void 0)this.#Y=Y.color}if(Y.opacity!==void 0)this.#Y.a=Y.opacity/100;if(Y.colorSpace==="display-p3"||Y.colorSpace==="srgb")this.#L=Y.colorSpace;if(Y.gradient)this.#X=k({...this.#X,...Y.gradient});if(Y.image)this.#j={...this.#j,...Y.image};if(Y.video)this.#J={...this.#J,...Y.video};if(Y.type&&!X.includes(Y.type)){let{type:Z,...$}=Y;this.#A[Y.type]=$}}catch(Y){if(Q.startsWith("#"))this.#U="solid",this.#Y=this.#C(Q)}}#W(){if(!this.#$)return;let Q,X="cover",Y="center";switch(this.#U){case"solid":Q=this.#k(this.#Y);break;case"gradient":Q=this.#i();break;case"image":if(this.#j.url){Q=`url(${this.#j.url})`;let $=this.#u(this.#j.scaleMode,this.#j.scale);X=$.size,Y=$.position}else Q="";break;case"video":if(this.#J.url){Q=`url(${this.#J.url})`;let $=this.#u(this.#J.scaleMode,this.#J.scale);X=$.size,Y=$.position}else Q="";break;default:Q=this.#R[this.#U]?.element?.getAttribute("chit-background")||"#D9D9D9"}if(this.#$.setAttribute("background",Q),this.#$.style.setProperty("--chit-bg-size",X),this.#$.style.setProperty("--chit-bg-position",Y),this.#U==="solid")this.#$.setAttribute("alpha",this.#Y.a);else this.#$.removeAttribute("alpha")}#u(Q,X){switch(Q){case"fill":return{size:"cover",position:"center"};case"fit":return{size:"contain",position:"center"};case"crop":return{size:"cover",position:"center"};case"tile":return{size:`${X}%`,position:"top left"};default:return{size:"cover",position:"center"}}}#m(){if(!this.#Q)this.#t();this.#x(this.#U);let Q=this.#Q.querySelector(".fig-fill-picker-gamut");if(Q)Q.value=this.#L;if(this.#$)this.#$.setAttribute("selected","true");this.#Q.open=!0,requestAnimationFrame(()=>{requestAnimationFrame(()=>{this.#G(),this.#q()})})}open(){this.#m()}close(){if(this.#Q)this.#Q.open=!1}#t(){this.#R={},this.querySelectorAll('[slot^="mode-"]').forEach((q)=>{let R=q.getAttribute("slot").slice(5);this.#R[R]={element:q,label:q.getAttribute("label")||R.charAt(0).toUpperCase()+R.slice(1)}}),this.#Q=document.createElement("dialog",{is:"fig-popup"}),this.#Q.setAttribute("is","fig-popup"),this.#Q.setAttribute("drag","true"),this.#Q.setAttribute("handle","fig-header"),this.#Q.setAttribute("autoresize","false"),this.#Q.classList.add("fig-fill-picker-dialog"),this.#Q.anchor=this.anchorElement||this.#y;let Q=this.getAttribute("dialog-position")||"left";this.#Q.setAttribute("position",Q),this.#Q.setAttribute("offset",this.getAttribute("dialog-offset")||"8 8");let X=["solid","gradient","image","video","webcam"],Y={solid:"Solid",gradient:"Gradient",image:"Image",video:"Video",webcam:"Webcam"},Z=this.getAttribute("mode"),$;if(Z){if($=Z.split(",").map((R)=>R.trim().toLowerCase()).filter((R)=>X.includes(R)||this.#R[R]),$.length===0)$=[...X]}else $=[...X];let j={...Y};for(let[q,{label:R}]of Object.entries(this.#R))j[q]=R;if(!$.includes(this.#U))this.#U=$[0],this.#b=$[0];let J=this.getAttribute("experimental"),U=J?`experimental="${J}"`:"",L;if($.length===1)L=`<h3 class="fig-fill-picker-type-label">${j[$[0]]}</h3>`;else{let q=$.map((R)=>`<option value="${R}">${j[R]}</option>`).join(`
2
+ `);L=`<fig-dropdown class="fig-fill-picker-type" ${U} value="${this.#U}">
3
+ ${q}
4
+ </fig-dropdown>`}let K=$.map((q)=>`<div class="fig-fill-picker-tab" data-tab="${q}"></div>`).join(`
5
+ `),z=`<fig-dropdown class="fig-fill-picker-gamut" ${U} value="${this.#L}">
6
+ <option value="srgb">sRGB</option>
7
+ <option value="display-p3">Display P3</option>
8
+ </fig-dropdown>`;this.#Q.innerHTML=`
9
+ <fig-header>
10
+ ${L}
11
+ ${z}
12
+ <fig-button icon variant="ghost" class="fig-fill-picker-close">
13
+ <fig-icon name="close"></fig-icon>
14
+ </fig-button>
15
+ </fig-header>
16
+ <fig-content>
17
+ ${K}
18
+ </fig-content>
19
+ `,document.body.appendChild(this.#Q);for(let[q,{element:R}]of Object.entries(this.#R)){let O=this.#Q.querySelector(`[data-tab="${q}"]`);if(!O)continue;while(R.firstChild)O.appendChild(R.firstChild);this.dispatchEvent(new CustomEvent("modeready",{bubbles:!0,detail:{mode:q,container:O}}))}let W=this.#Q.querySelector(".fig-fill-picker-type");if(W)W.addEventListener("change",(q)=>{this.#x(q.target.value)});let _=this.#Q.querySelector(".fig-fill-picker-gamut");if(_){let q=(R)=>{let O=R.currentTarget?.value??R.target?.value??R.detail;if(O&&O!==this.#L)this.#L=O,this.#e()};_.addEventListener("input",q),_.addEventListener("change",q)}this.#Q.querySelector(".fig-fill-picker-close").addEventListener("click",()=>{this.#Q.open=!1});let B=()=>{if(this.#$)this.#$.removeAttribute("selected");this.#_(),this.dispatchEvent(new CustomEvent("close"))};this.#Q.addEventListener("close",B),this.#T=new MutationObserver(()=>{if(!(this.#Q.hasAttribute("open")&&this.#Q.getAttribute("open")!=="false"))B()}),this.#T.observe(this.#Q,{attributes:!0,attributeFilter:["open"]});let M={solid:()=>this.#a(),gradient:()=>this.#YQ(),image:()=>this.#jQ(),video:()=>this.#KQ(),webcam:()=>this.#UQ()};for(let[q,R]of Object.entries(M))if(!this.#R[q]&&$.includes(q))R();for(let q of Object.keys(this.#R)){if(X.includes(q))continue;let R=this.#Q.querySelector(`[data-tab="${q}"]`);if(!R)continue;R.addEventListener("input",(O)=>{if(O.target===this)return;if(O.stopPropagation(),O.detail)this.#A[q]=O.detail;this.#Z()}),R.addEventListener("change",(O)=>{if(O.target===this)return;if(O.stopPropagation(),O.detail)this.#A[q]=O.detail;this.#_()})}}#x(Q){let X=this.#Q?.querySelector(`.fig-fill-picker-tab[data-tab="${Q}"]`);if(!X)return;this.#b=Q,this.#U=Q;let Y=this.#Q.querySelector(".fig-fill-picker-type");if(Y&&Y.value!==Q)Y.value=Q;this.#Q.querySelectorAll(".fig-fill-picker-tab").forEach((j)=>{if(j.dataset.tab===Q)j.style.display="block";else j.style.display="none"});let $=this.#Q.querySelector("fig-content");if($)$.style.padding=this.#R[Q]?"0":"";if(Q==="gradient")requestAnimationFrame(()=>{this.#V();let j=X.querySelector(".fig-fill-picker-gradient-bar-input");j?.refreshLayout?.(),requestAnimationFrame(()=>{j?.refreshLayout?.()})});this.#W(),this.#Z()}#a(){let Q=this.#Q.querySelector('[data-tab="solid"]'),X=this.getAttribute("alpha")!=="false",Y=this.getAttribute("experimental"),Z=Y?`experimental="${Y}"`:"";if(Q.innerHTML=`
20
+ <fig-preview class="fig-fill-picker-color-area">
21
+ <canvas width="200" height="200"></canvas>
22
+ <fig-handle
23
+ type="color"
24
+ color="${this.#k({...this.#Y,a:1})}"
25
+ data-no-color-picker
26
+ drag
27
+ drag-surface=".fig-fill-picker-color-area"
28
+ drag-axes="x,y"
29
+ drag-snapping="modifier"
30
+ ></fig-handle>
31
+ </fig-preview>
32
+ <div class="fig-fill-picker-sliders">
33
+ <fig-tooltip text="Sample color"><fig-button icon variant="ghost" class="fig-fill-picker-eyedropper"><fig-icon name="eyedropper"></fig-icon></fig-button></fig-tooltip>
34
+ <fig-slider type="hue" text="false" min="0" max="360" value="${this.#Y.h}"></fig-slider>
35
+ ${X?`<fig-slider type="opacity" text="true" units="%" min="0" max="100" value="${this.#Y.a*100}" color="${this.#k(this.#Y)}"></fig-slider>`:""}
36
+ </div>
37
+ <fig-field class="fig-fill-picker-inputs">
38
+ <fig-dropdown class="fig-fill-picker-input-mode" ${Z} value="${this.#H}">
39
+ <option value="hex">Hex</option>
40
+ <option value="rgb">RGB</option>
41
+ <option value="hsl">HSL</option>
42
+ <option value="hsb">HSB</option>
43
+ <option value="lab">LAB</option>
44
+ <option value="lch">LCH</option>
45
+ </fig-dropdown>
46
+ <span class="fig-fill-picker-input-fields"></span>
47
+ </fig-field>
48
+ `,this.#z=Q.querySelector("canvas"),this.#O=Q.querySelector("fig-handle"),this.#G(),this.#q(),this.#g(),this.#N=Q.querySelector('fig-slider[type="hue"]'),this.#N.addEventListener("input",(J)=>{this.#Y.h=parseFloat(J.target.value),this.#G(),this.#q(),this.#D(),this.#Z()}),this.#N.addEventListener("change",()=>{this.#_()}),X)this.#B=Q.querySelector('fig-slider[type="opacity"]'),this.#B.addEventListener("input",(J)=>{this.#Y.a=parseFloat(J.target.value)/100,this.#D(),this.#Z()}),this.#B.addEventListener("change",()=>{this.#_()});Q.querySelector(".fig-fill-picker-input-mode").addEventListener("input",(J)=>{this.#H=J.target.value,this.#s()}),this.#s();let j=Q.querySelector(".fig-fill-picker-eyedropper");if("EyeDropper"in window)j.addEventListener("click",async()=>{try{let U=await new EyeDropper().open();this.#Y={...this.#C(U.sRGBHex),a:this.#Y.a},this.#G(),this.#q(),this.#D(),this.#Z()}catch(J){}});else j.setAttribute("disabled",""),j.title="EyeDropper not supported in this browser"}#e(){let Q=this.#Q?.querySelector('[data-tab="solid"]');if(Q){let X=Q.querySelector("canvas");if(X){let Y=document.createElement("canvas");Y.width=X.width,Y.height=X.height,X.replaceWith(Y),this.#z=Y,this.#g()}this.#G(),this.#q()}this.#f(),this.#Z()}#G(){if(!this.#z&&this.#Q)this.#z=this.#Q.querySelector('[data-tab="solid"] canvas');if(!this.#z)return;let Q=this.#L==="display-p3"?"display-p3":"srgb",X=this.#z.getContext("2d",{colorSpace:Q});if(!X)return;let Y=this.#z.width,Z=this.#z.height;X.clearRect(0,0,Y,Z);let $=this.#Y.h,j=this.#L==="display-p3",J=X.createLinearGradient(0,0,Y,0);if(j){J.addColorStop(0,"color(display-p3 1 1 1)");let[L,K,z]=hslToP3($,100,50);J.addColorStop(1,`color(display-p3 ${L} ${K} ${z})`)}else J.addColorStop(0,"#FFFFFF"),J.addColorStop(1,`hsl(${$}, 100%, 50%)`);X.fillStyle=J,X.fillRect(0,0,Y,Z);let U=X.createLinearGradient(0,0,0,Z);U.addColorStop(0,"rgba(0,0,0,0)"),U.addColorStop(1,"rgba(0,0,0,1)"),X.fillStyle=U,X.fillRect(0,0,Y,Z)}#q(Q=0){if(!this.#O||!this.#z)return;let X=this.#z.getBoundingClientRect();if((X.width===0||X.height===0)&&Q<5){requestAnimationFrame(()=>this.#q(Q+1));return}let Y=Math.max(0,Math.min(100,this.#Y.s)),Z=Math.max(0,Math.min(100,100-this.#Y.v));this.#O.setAttribute("value",`${Y}% ${Z}%`),this.#O.setAttribute("color",this.#k({...this.#Y,a:1}))}#w(Q,X,Y={}){let{updateHandle:Z=!0,emitInput:$=!0,emitChange:j=!1}=Y;if(this.#Y.s=Math.max(0,Math.min(100,Q*100)),this.#Y.v=Math.max(0,Math.min(100,(1-X)*100)),this.#O)this.#O.setAttribute("color",this.#k({...this.#Y,a:1}));if(Z)this.#q();if(this.#D(),$)this.#Z();if(j)this.#_()}#g(){if(this.#F)this.#F(),this.#F=null;if(!this.#z||!this.#O)return;let Q=this.#z.parentElement||this.#z,X=this.#O,Y=!1,Z=(K,z={})=>{let W=Q.getBoundingClientRect();if(W.width===0||W.height===0)return;let _=Math.max(0,Math.min(K.clientX-W.left,W.width)),B=Math.max(0,Math.min(K.clientY-W.top,W.height));this.#w(_/W.width,B/W.height,z)},$=(K)=>{if(K.button!==0)return;if(K.target===X||X.contains(K.target))return;Y=!0,this.#M=!0,Q.setPointerCapture(K.pointerId),Z(K,{updateHandle:!0,emitInput:!0})},j=(K)=>{if(!Y)return;if(K.buttons===0){J();return}Z(K,{updateHandle:!0,emitInput:!0})},J=()=>{if(!Y)return;Y=!1,this.#M=!1,this.#_()},U=(K)=>{this.#M=!0;let z=K.detail?.px,W=K.detail?.py;if(!Number.isFinite(z)||!Number.isFinite(W))return;X.setAttribute("value",`${z*100}% ${W*100}%`),this.#w(z,W,{updateHandle:!1,emitInput:!0})},L=(K)=>{let z=K.detail?.px,W=K.detail?.py;if(Number.isFinite(z)&&Number.isFinite(W))X.setAttribute("value",`${z*100}% ${W*100}%`),this.#w(z,W,{updateHandle:!1,emitInput:!1});this.#M=!1,this.#_()};Q.addEventListener("pointerdown",$),Q.addEventListener("pointermove",j),Q.addEventListener("pointerup",J),Q.addEventListener("pointercancel",J),Q.addEventListener("lostpointercapture",J),X.addEventListener("input",U),X.addEventListener("change",L),this.#F=()=>{Q.removeEventListener("pointerdown",$),Q.removeEventListener("pointermove",j),Q.removeEventListener("pointerup",J),Q.removeEventListener("pointercancel",J),Q.removeEventListener("lostpointercapture",J),X.removeEventListener("input",U),X.removeEventListener("change",L),this.#M=!1}}#s(){let Q=this.#Q?.querySelector(".fig-fill-picker-input-fields");if(!Q)return;let X=($,j)=>`<fig-tooltip text="${$}">${j}</fig-tooltip>`,Y=($,j,J,U)=>`<fig-input-number class="${$}" min="${j}" max="${J}"${U!=null?` step="${U}"`:""}></fig-input-number>`,Z;switch(this.#H){case"rgb":Z=`<div class="input-combo">
49
+ ${X("Red",Y("fig-fill-picker-ci-r",0,255))}
50
+ ${X("Green",Y("fig-fill-picker-ci-g",0,255))}
51
+ ${X("Blue",Y("fig-fill-picker-ci-b",0,255))}
52
+ </div>`;break;case"hsl":Z=`<div class="input-combo">
53
+ ${X("Hue",Y("fig-fill-picker-ci-h",0,360))}
54
+ ${X("Saturation",Y("fig-fill-picker-ci-s",0,100))}
55
+ ${X("Lightness",Y("fig-fill-picker-ci-l",0,100))}
56
+ </div>`;break;case"hsb":Z=`<div class="input-combo">
57
+ ${X("Hue",Y("fig-fill-picker-ci-h",0,360))}
58
+ ${X("Saturation",Y("fig-fill-picker-ci-s",0,100))}
59
+ ${X("Brightness",Y("fig-fill-picker-ci-v",0,100))}
60
+ </div>`;break;case"lab":Z=`<div class="input-combo">
61
+ ${X("Lightness",Y("fig-fill-picker-ci-okl",0,100))}
62
+ ${X("Green-Red axis",Y("fig-fill-picker-ci-oka",-0.4,0.4,0.001))}
63
+ ${X("Blue-Yellow axis",Y("fig-fill-picker-ci-okb",-0.4,0.4,0.001))}
64
+ </div>`;break;case"lch":Z=`<div class="input-combo">
65
+ ${X("Lightness",Y("fig-fill-picker-ci-okl",0,100))}
66
+ ${X("Chroma",Y("fig-fill-picker-ci-okc",0,0.4,0.001))}
67
+ ${X("Hue",Y("fig-fill-picker-ci-okh",0,360))}
68
+ </div>`;break;default:Z='<fig-input-text class="fig-fill-picker-ci-hex" placeholder="FFFFFF"></fig-input-text>';break}Q.innerHTML=Z,this.#QQ(),requestAnimationFrame(()=>this.#D())}#QQ(){let Q=this.#Q?.querySelector(".fig-fill-picker-input-fields");if(!Q)return;let X=()=>{if(this.#M)return;let $=this.#XQ();if(!$)return;if(this.#Y={...$,a:this.#Y.a},this.#G(),this.#q(),this.#N)this.#N.setAttribute("value",this.#Y.h);this.#Z()},Y=()=>this.#_();Q.querySelectorAll("fig-input-number, fig-input-text").forEach(($)=>{$.addEventListener("input",X),$.addEventListener("change",Y)})}#XQ(){let Q=(Y)=>this.#Q?.querySelector(`.${Y}`),X=(Y)=>parseFloat(Q(Y)?.value??0);switch(this.#H){case"rgb":return this.#S({r:X("fig-fill-picker-ci-r"),g:X("fig-fill-picker-ci-g"),b:X("fig-fill-picker-ci-b")});case"hsl":{let Y=this.#_Q({h:X("fig-fill-picker-ci-h"),s:X("fig-fill-picker-ci-s"),l:X("fig-fill-picker-ci-l")});return this.#S(Y)}case"hsb":return{h:X("fig-fill-picker-ci-h"),s:X("fig-fill-picker-ci-s"),v:X("fig-fill-picker-ci-v"),a:1};case"lab":{let Y=this.#r({l:X("fig-fill-picker-ci-okl")/100,a:X("fig-fill-picker-ci-oka"),b:X("fig-fill-picker-ci-okb")});return this.#S(Y)}case"lch":{let Y=this.#BQ({l:X("fig-fill-picker-ci-okl")/100,c:X("fig-fill-picker-ci-okc"),h:X("fig-fill-picker-ci-okh")});return this.#S(Y)}default:{let Y=Q("fig-fill-picker-ci-hex");if(!Y)return null;let Z=Y.value.replace(/^#/,"");if(Z.length===3)Z=Z[0]+Z[0]+Z[1]+Z[1]+Z[2]+Z[2];if(Z.length!==6||!/^[0-9a-fA-F]{6}$/.test(Z))return null;return this.#C(`#${Z}`)}}}#D(){if(!this.#Q)return;let Q=this.#k(this.#Y),X=this.#l(this.#Y),Y=($)=>this.#Q.querySelector(`.${$}`),Z=($,j)=>{let J=Y($);if(J)J.setAttribute("value",j)};switch(this.#H){case"rgb":Z("fig-fill-picker-ci-r",X.r),Z("fig-fill-picker-ci-g",X.g),Z("fig-fill-picker-ci-b",X.b);break;case"hsl":{let $=this.#qQ(X);Z("fig-fill-picker-ci-h",Math.round($.h)),Z("fig-fill-picker-ci-s",Math.round($.s)),Z("fig-fill-picker-ci-l",Math.round($.l));break}case"hsb":Z("fig-fill-picker-ci-h",Math.round(this.#Y.h)),Z("fig-fill-picker-ci-s",Math.round(this.#Y.s)),Z("fig-fill-picker-ci-v",Math.round(this.#Y.v));break;case"lab":{let $=this.#n(X);Z("fig-fill-picker-ci-okl",Math.round($.l*100)),Z("fig-fill-picker-ci-oka",+$.a.toFixed(3)),Z("fig-fill-picker-ci-okb",+$.b.toFixed(3));break}case"lch":{let $=this.#OQ(X);Z("fig-fill-picker-ci-okl",Math.round($.l*100)),Z("fig-fill-picker-ci-okc",+$.c.toFixed(3)),Z("fig-fill-picker-ci-okh",Math.round($.h));break}default:Z("fig-fill-picker-ci-hex",Q.replace(/^#/,"").toUpperCase());break}if(this.#B)this.#B.setAttribute("color",Q);this.#W()}#YQ(){let Q=this.#Q.querySelector('[data-tab="gradient"]'),X=this.getAttribute("experimental"),Y=X?`experimental="${X}"`:"";Q.innerHTML=`
69
+ <fig-field class="fig-fill-picker-gradient-header">
70
+ <fig-dropdown class="fig-fill-picker-gradient-type" ${Y} value="${this.#X.type}">
71
+ <option value="linear" selected>Linear</option>
72
+ <option value="radial">Radial</option>
73
+ <option value="angular">Angular</option>
74
+ </fig-dropdown>
75
+ <fig-tooltip text="Rotate gradient">
76
+ <fig-input-number class="fig-fill-picker-gradient-angle" value="${(this.#X.angle-90+360)%360}" min="0" max="360" units="°" wrap></fig-input-number>
77
+ </fig-tooltip>
78
+ <div class="fig-fill-picker-gradient-center input-combo" style="display: none;">
79
+ <fig-input-number min="0" max="100" value="${this.#X.centerX}" units="%" class="fig-fill-picker-gradient-cx"></fig-input-number>
80
+ <fig-input-number min="0" max="100" value="${this.#X.centerY}" units="%" class="fig-fill-picker-gradient-cy"></fig-input-number>
81
+ </div>
82
+ <fig-tooltip text="Flip gradient">
83
+ <fig-button icon variant="ghost" class="fig-fill-picker-gradient-flip">
84
+ <fig-icon name="swap"></fig-icon>
85
+ </fig-button>
86
+ </fig-tooltip>
87
+ </fig-field>
88
+ <fig-preview class="fig-fill-picker-gradient-preview">
89
+ <fig-input-gradient class="fig-fill-picker-gradient-bar-input" edit="true" size="large" value='${JSON.stringify({type:"gradient",gradient:F(this.#X)})}'></fig-input-gradient>
90
+ </fig-preview>
91
+ <fig-field class="fig-fill-picker-gradient-interpolation">
92
+ <label>Mixing</label>
93
+ <fig-dropdown class="fig-fill-picker-gradient-space" full ${Y} value="${this.#X.interpolationSpace==="oklch"?`oklch-${this.#X.hueInterpolation||"shorter"}`:this.#X.interpolationSpace}">
94
+ <optgroup label="sRGB">
95
+ <option value="srgb-linear">Linear</option>
96
+ </optgroup>
97
+ <optgroup label="OKLab">
98
+ <option value="oklab">Perceptual</option>
99
+ </optgroup>
100
+ <optgroup label="OKLCH">
101
+ <option value="oklch-shorter">Shorter hue</option>
102
+ <option value="oklch-longer">Longer hue</option>
103
+ <option value="oklch-increasing">Increasing hue</option>
104
+ <option value="oklch-decreasing">Decreasing hue</option>
105
+ </optgroup>
106
+ </fig-dropdown>
107
+ </fig-field>
108
+ <div class="fig-fill-picker-gradient-stops">
109
+ <fig-header class="fig-fill-picker-gradient-stops-header" borderless>
110
+ <span>Stops</span>
111
+ <fig-button icon variant="ghost" class="fig-fill-picker-gradient-add" title="Add stop">
112
+ <fig-icon name="add"></fig-icon>
113
+ </fig-button>
114
+ </fig-header>
115
+ <div class="fig-fill-picker-gradient-stops-list"></div>
116
+ </div>
117
+ `,this.#V(),this.#ZQ(Q)}#ZQ(Q){let X=Q.querySelector(".fig-fill-picker-gradient-type"),Y=(z)=>z.currentTarget?.value??z.target?.value??z.detail,Z=(z)=>{this.#X.type=Y(z),this.#V(),this.#Z()};X.addEventListener("input",Z),X.addEventListener("change",Z);let $=Q.querySelector(".fig-fill-picker-gradient-space"),j=(z)=>{let W=Y(z),_=W,B="shorter";if(W.startsWith("oklch-"))_="oklch",B=W.slice(6);this.#X=k({...this.#X,interpolationSpace:_,hueInterpolation:B}),this.#V(),this.#Z()};$?.addEventListener("input",j),$?.addEventListener("change",j),Q.querySelector(".fig-fill-picker-gradient-angle").addEventListener("input",(z)=>{let W=parseFloat(z.target.value)||0;this.#X.angle=(W+90)%360,this.#f(),this.#Z()});let U=Q.querySelector(".fig-fill-picker-gradient-cx"),L=Q.querySelector(".fig-fill-picker-gradient-cy");U?.addEventListener("input",(z)=>{this.#X.centerX=parseFloat(z.target.value)||50,this.#f(),this.#Z()}),L?.addEventListener("input",(z)=>{this.#X.centerY=parseFloat(z.target.value)||50,this.#f(),this.#Z()}),Q.querySelector(".fig-fill-picker-gradient-flip").addEventListener("click",()=>{this.#X.stops.forEach((z)=>{z.position=100-z.position}),this.#X.stops.sort((z,W)=>z.position-W.position),this.#V(),this.#Z()}),Q.querySelector(".fig-fill-picker-gradient-add").addEventListener("click",()=>{this.#X.stops.push({position:50,color:"#888888",opacity:100}),this.#X.stops.sort((W,_)=>W.position-_.position),this.#V(),this.#Z()});let K=Q.querySelector(".fig-fill-picker-gradient-bar-input");if(K){let z=(W)=>{W.stopPropagation();let _=W.detail;if(!_?.gradient)return;this.#X=k({...this.#X,..._.gradient}),this.#W(),this.#c()};K.addEventListener("input",(W)=>{z(W),this.#Z()}),K.addEventListener("change",(W)=>{z(W),this.#_()})}}#V(){if(!this.#Q)return;let Q=this.#Q.querySelector('[data-tab="gradient"]');if(!Q)return;this.#X=k(this.#X);let X=Q.querySelector(".fig-fill-picker-gradient-angle"),Y=Q.querySelector(".fig-fill-picker-gradient-center");if(this.#X.type==="radial")X.style.display="none",Y.style.display="flex";else{X.style.display="block",Y.style.display="none";let $=(this.#X.angle-90+360)%360;X.setAttribute("value",$)}let Z=Q.querySelector(".fig-fill-picker-gradient-space");if(Z)Z.value=this.#X.interpolationSpace==="oklch"?`oklch-${this.#X.hueInterpolation||"shorter"}`:this.#X.interpolationSpace;this.#f(),this.#c()}#f(){if(!this.#Q)return;let Q=this.#Q.querySelector(".fig-fill-picker-gradient-bar-input");if(Q)Q.setAttribute("value",JSON.stringify({type:"gradient",gradient:F(this.#X)}));this.#W()}#c(){if(!this.#Q)return;let Q=this.#Q.querySelector(".fig-fill-picker-gradient-stops-list");if(!Q)return;let X=Q.querySelectorAll(".fig-fill-picker-gradient-stop-row");if(X.length===this.#X.stops.length){this.#X.stops.forEach((Y,Z)=>{let $=X[Z];$.dataset.index=Z;let j=$.querySelector(".fig-fill-picker-stop-position");if(j)j.setAttribute("value",Y.position);let J=$.querySelector(".fig-fill-picker-stop-color");if(J)J.setAttribute("value",Y.color);let U=$.querySelector(".fig-fill-picker-stop-remove");if(U)if(this.#X.stops.length<=2)U.setAttribute("disabled","");else U.removeAttribute("disabled")});return}this.#$Q(Q)}#$Q(Q){Q.innerHTML=this.#X.stops.map((X,Y)=>`
118
+ <fig-field class="fig-fill-picker-gradient-stop-row" data-index="${Y}">
119
+ <fig-input-number class="fig-fill-picker-stop-position" min="0" max="100" value="${X.position}" units="%"></fig-input-number>
120
+ <fig-input-color class="fig-fill-picker-stop-color" text="true" alpha="true" picker="figma" picker-dialog-position="right" value="${X.color}"></fig-input-color>
121
+ <fig-button icon variant="ghost" class="fig-fill-picker-stop-remove" ${this.#X.stops.length<=2?"disabled":""}>
122
+ <fig-icon name="minus"></fig-icon>
123
+ </fig-button>
124
+ </fig-field>
125
+ `).join(""),Q.querySelectorAll(".fig-fill-picker-gradient-stop-row").forEach((X)=>{let Y=parseInt(X.dataset.index);X.querySelector(".fig-fill-picker-stop-position").addEventListener("input",(j)=>{this.#X.stops[Y].position=parseFloat(j.target.value)||0,this.#f(),this.#Z()});let Z=X.querySelector(".fig-fill-picker-stop-color"),$=Z.querySelector("fig-fill-picker");if($)$.anchorElement=this.#Q;else requestAnimationFrame(()=>{let j=Z.querySelector("fig-fill-picker");if(j)j.anchorElement=this.#Q});Z.addEventListener("input",(j)=>{this.#X.stops[Y].color=j.target.hexOpaque||j.target.value;let J=j.detail?.rgba?.a;if(J!==void 0)this.#X.stops[Y].opacity=Math.round(J*100);this.#f(),this.#Z()}),X.querySelector(".fig-fill-picker-stop-remove").addEventListener("click",()=>{if(this.#X.stops.length>2)this.#X.stops.splice(Y,1),this.#V(),this.#Z()})})}#v(Q,X=!0){let Y=k({...this.#X,interpolationSpace:Q??this.#X.interpolationSpace}),Z=this.#L==="display-p3",$=Y.stops.map((J)=>{let U=(J.opacity??100)/100;return`${Z?this.#RQ(J.color,U):this.#LQ(J.color,U)} ${J.position}%`}).join(", "),j=X?` ${V(Y)}`:"";switch(Y.type){case"linear":return`linear-gradient(${Y.angle}deg${j}, ${$})`;case"radial":return`radial-gradient(circle at ${Y.centerX}% ${Y.centerY}%${j}, ${$})`;case"angular":return`conic-gradient(from ${Y.angle}deg${j}, ${$})`;default:return`linear-gradient(${Y.angle}deg${j}, ${$})`}}static#p=new Map;#d(Q){let X=N.#p.get(Q);if(X!==void 0)return X;let Y=document.createElement("div");Y.style.background=Q;let Z=!!Y.style.background;return N.#p.set(Q,Z),Z}#i(){let Q=this.#v(void 0,!0);if(this.#d(Q))return Q;let X=this.#v("oklab",!0);if(this.#d(X))return X;return this.#v("oklab",!1)}#jQ(){let Q=this.#Q.querySelector('[data-tab="image"]'),X=this.getAttribute("experimental"),Y=X?`experimental="${X}"`:"";Q.innerHTML=`
126
+ <fig-field class="fig-fill-picker-media-header">
127
+ <fig-dropdown class="fig-fill-picker-scale-mode" ${Y} value="${this.#j.scaleMode}">
128
+ <option value="fill" selected>Fill</option>
129
+ <option value="fit">Fit</option>
130
+ <option value="crop">Crop</option>
131
+ <option value="tile">Tile</option>
132
+ </fig-dropdown>
133
+ <fig-input-number class="fig-fill-picker-scale" min="1" max="200" value="${this.#j.scale}" units="%" ${this.#j.scaleMode==="tile"?"":'style="display: none;"'}></fig-input-number>
134
+ <fig-button class="fig-fill-picker-media-rotate" icon variant="ghost" aria-label="Rotate">
135
+ <fig-icon name="rotate"></fig-icon>
136
+ </fig-button>
137
+ </fig-field>
138
+ <fig-image class="fig-fill-picker-media-preview fig-fill-picker-image-preview" upload="true" label="Upload from computer" size="auto" aspect-ratio="1/1" fit="cover" checkerboard="true"></fig-image>
139
+ `,this.#JQ(Q)}#JQ(Q){let X=Q.querySelector(".fig-fill-picker-scale-mode"),Y=Q.querySelector(".fig-fill-picker-scale"),Z=Q.querySelector(".fig-fill-picker-image-preview");X.addEventListener("change",($)=>{this.#j.scaleMode=$.target.value,Y.style.display=$.target.value==="tile"?"block":"none",this.#E(Z),this.#W(),this.#Z()}),Y.addEventListener("input",($)=>{this.#j.scale=parseFloat($.target.value)||100,this.#E(Z),this.#W(),this.#Z()}),Z.addEventListener("loaded",($)=>{let j=$.detail?.src||Z.src;if(!j)return;this.#j.url=j,this.#E(Z),this.#W(),this.#Z()}),Z.addEventListener("change",()=>{if(Z.src)return;this.#j.url=null,this.#E(Z),this.#W(),this.#Z()}),this.#E(Z)}#E(Q){if(!this.#j.url){Q.removeAttribute("src"),Q.classList.remove("has-media","is-tiled"),Q.style.backgroundImage="",Q.style.backgroundPosition="",Q.style.backgroundRepeat="",Q.style.backgroundSize="";return}Q.setAttribute("src",this.#j.url),Q.classList.add("has-media"),Q.style.backgroundImage="",Q.style.backgroundPosition="",Q.style.backgroundRepeat="",Q.style.backgroundSize="",Q.mediaEl?.style.removeProperty("opacity");let X=Q.querySelector("fig-input-file[data-generated]");if(X)X.setAttribute("label","Replace"),X.removeAttribute("url");switch(this.#j.scaleMode){case"fill":Q.classList.remove("is-tiled"),Q.setAttribute("fit","cover");break;case"crop":Q.classList.remove("is-tiled"),Q.setAttribute("fit","cover");break;case"fit":Q.classList.remove("is-tiled"),Q.setAttribute("fit","contain");break;case"tile":if(Q.classList.add("is-tiled"),Q.setAttribute("fit","none"),Q.style.backgroundImage=`url(${this.#j.url})`,Q.style.backgroundPosition="top left",Q.style.backgroundSize=`${this.#j.scale}%`,Q.style.backgroundRepeat="repeat",Q.mediaEl)Q.mediaEl.style.opacity="0";break}}#I(Q){if(Q.tagName==="FIG-MEDIA"){if(!this.#J.url){Q.removeAttribute("src"),Q.classList.remove("has-media");return}Q.setAttribute("src",this.#J.url),Q.classList.add("has-media");let X=Q.querySelector("fig-input-file[data-generated]");if(X)X.setAttribute("label","Replace"),X.removeAttribute("url");switch(this.#J.scaleMode){case"fill":case"crop":Q.setAttribute("fit","cover");break;case"fit":Q.setAttribute("fit","contain");break}return}switch(Q.style.objectPosition="center",Q.style.width="100%",Q.style.height="100%",this.#J.scaleMode){case"fill":case"crop":Q.style.objectFit="cover";break;case"fit":Q.style.objectFit="contain";break}}#KQ(){let Q=this.#Q.querySelector('[data-tab="video"]'),X=this.getAttribute("experimental"),Y=X?`experimental="${X}"`:"";Q.innerHTML=`
140
+ <fig-field class="fig-fill-picker-media-header">
141
+ <fig-dropdown class="fig-fill-picker-scale-mode" ${Y} value="${this.#J.scaleMode}">
142
+ <option value="fill" selected>Fill</option>
143
+ <option value="fit">Fit</option>
144
+ <option value="crop">Crop</option>
145
+ </fig-dropdown>
146
+ <fig-button class="fig-fill-picker-media-rotate" icon variant="ghost" aria-label="Rotate">
147
+ <fig-icon name="rotate"></fig-icon>
148
+ </fig-button>
149
+ </fig-field>
150
+ <fig-media class="fig-fill-picker-media-preview fig-fill-picker-video-preview" type="video" upload="true" label="Upload from computer" size="auto" aspect-ratio="1/1" fit="cover" checkerboard="true" autoplay="true" muted="true" loop="true"></fig-media>
151
+ `,this.#WQ(Q)}#WQ(Q){let X=Q.querySelector(".fig-fill-picker-scale-mode"),Y=Q.querySelector(".fig-fill-picker-video-preview");X.addEventListener("change",(Z)=>{this.#J.scaleMode=Z.target.value,this.#I(Y),this.#W(),this.#Z()}),Y.addEventListener("loaded",(Z)=>{let $=Z.detail?.src||Y.src;if(!$)return;this.#J.url=$,this.#I(Y),Y.play?.(),this.#W(),this.#Z()}),Y.addEventListener("change",()=>{if(Y.src)return;this.#J.url=null,this.#I(Y),this.#W(),this.#Z()}),this.#I(Y)}#UQ(){let Q=this.#Q.querySelector('[data-tab="webcam"]'),X=this.getAttribute("experimental"),Y=X?`experimental="${X}"`:"";Q.innerHTML=`
152
+ <fig-field class="fig-fill-picker-webcam-camera" style="display: none;">
153
+ <fig-dropdown class="fig-fill-picker-camera-select" full ${Y}>
154
+ </fig-dropdown>
155
+ </fig-field>
156
+ <fig-video class="fig-fill-picker-webcam-preview" aspect-ratio="1/1" fit="cover" checkerboard="true" autoplay="true" muted="true">
157
+ <video class="fig-fill-picker-webcam-video" autoplay muted playsinline></video>
158
+ <div class="fig-fill-picker-webcam-status">
159
+ <span>Camera access required</span>
160
+ </div>
161
+ </fig-video>
162
+ <div class="fig-fill-picker-webcam-controls">
163
+ <fig-button class="fig-fill-picker-webcam-capture" variant="secondary" full>
164
+ Capture
165
+ </fig-button>
166
+ </div>
167
+ `,this.#zQ(Q)}#zQ(Q){let X=Q.querySelector(".fig-fill-picker-webcam-video"),Y=Q.querySelector(".fig-fill-picker-webcam-status"),Z=Q.querySelector(".fig-fill-picker-webcam-capture"),$=Q.querySelector(".fig-fill-picker-webcam-camera"),j=Q.querySelector(".fig-fill-picker-camera-select"),J=async(U=null)=>{try{let L={video:U?{deviceId:{exact:U}}:!0};if(this.#K.stream)this.#K.stream.getTracks().forEach((W)=>W.stop());this.#K.stream=await navigator.mediaDevices.getUserMedia(L),X.srcObject=this.#K.stream,X.style.display="block",Y.style.display="none";let z=(await navigator.mediaDevices.enumerateDevices()).filter((W)=>W.kind==="videoinput");if(z.length>1){if($.style.display="",j.querySelectorAll(":scope > option, :scope > optgroup").forEach((W)=>W.remove()),z.forEach((W,_)=>{let B=document.createElement("option");B.value=W.deviceId;let M=W.label||(z.length>1?`Camera ${_+1}`:"Camera");B.textContent=M.replace(/\s*\((?:[0-9a-f]{4}:)*([0-9a-f]{4})\)$/i,(q,R)=>{return` ${/^\d+$/.test(R)?Number.parseInt(R,10).toString():R.replace(/^0+/,"")||"0"}`}),j.append(B)}),U)j.value=U}else $.style.display="none",j.querySelectorAll(":scope > option, :scope > optgroup").forEach((W)=>W.remove())}catch(L){console.error("Webcam error:",L.name,L.message);let K="Camera access denied";if(L.name==="NotAllowedError")K="Camera permission denied";else if(L.name==="NotFoundError")K="No camera found";else if(L.name==="NotReadableError")K="Camera in use by another app";else if(L.name==="OverconstrainedError")K="Camera constraints not supported";else if(!window.isSecureContext)K="Camera requires secure context";Y.innerHTML=`<span>${K}</span>`,Y.style.display="flex",X.style.display="none"}};this.#P=new MutationObserver(()=>{if(Q.style.display!=="none"&&!this.#K.stream)J()}),this.#P.observe(Q,{attributes:!0,attributeFilter:["style"]}),j.addEventListener("change",(U)=>{J(U.target.value)}),Z.addEventListener("click",async()=>{if(!this.#K.stream)return;if(!X.videoWidth||!X.videoHeight)return;let U=document.createElement("canvas");U.width=X.videoWidth,U.height=X.videoHeight,U.getContext("2d").drawImage(X,0,0,U.width,U.height);let L=await new Promise((z)=>U.toBlob(z,"image/png"));if(!L)return;if(this.#K.snapshot?.startsWith("blob:"))URL.revokeObjectURL(this.#K.snapshot);this.#K.snapshot=URL.createObjectURL(L),this.#j.url=this.#K.snapshot;let K=this.#Q.querySelector(".fig-fill-picker-image-preview");if(K)this.#E(K);this.#x("image")})}#l(Q){let X=Q.h/360,Y=Q.s/100,Z=Q.v/100,$,j,J,U=Math.floor(X*6),L=X*6-U,K=Z*(1-Y),z=Z*(1-L*Y),W=Z*(1-(1-L)*Y);switch(U%6){case 0:$=Z,j=W,J=K;break;case 1:$=z,j=Z,J=K;break;case 2:$=K,j=Z,J=W;break;case 3:$=K,j=z,J=Z;break;case 4:$=W,j=K,J=Z;break;case 5:$=Z,j=K,J=z;break}return{r:Math.round($*255),g:Math.round(j*255),b:Math.round(J*255)}}#S(Q){let X=Q.r/255,Y=Q.g/255,Z=Q.b/255,$=Math.max(X,Y,Z),j=Math.min(X,Y,Z),J=$-j,U=0,L=$===0?0:J/$,K=$;if($!==j){switch($){case X:U=(Y-Z)/J+(Y<Z?6:0);break;case Y:U=(Z-X)/J+2;break;case Z:U=(X-Y)/J+4;break}U/=6}return{h:U*360,s:L*100,v:K*100,a:1}}#k(Q){if(!Q||typeof Q.h!=="number"||typeof Q.s!=="number"||typeof Q.v!=="number")return"#D9D9D9";let X=this.#l(Q),Y=(Z)=>{return(isNaN(Z)?217:Math.max(0,Math.min(255,Math.round(Z)))).toString(16).padStart(2,"0")};return`#${Y(X.r)}${Y(X.g)}${Y(X.b)}`}#C(Q){let X=parseInt(Q.slice(1,3),16),Y=parseInt(Q.slice(3,5),16),Z=parseInt(Q.slice(5,7),16);return this.#S({r:X,g:Y,b:Z})}#LQ(Q,X=1){let Y=parseInt(Q.slice(1,3),16),Z=parseInt(Q.slice(3,5),16),$=parseInt(Q.slice(5,7),16);return`rgba(${Y}, ${Z}, ${$}, ${X})`}#RQ(Q,X=1){let Y=+(parseInt(Q.slice(1,3),16)/255).toFixed(4),Z=+(parseInt(Q.slice(3,5),16)/255).toFixed(4),$=+(parseInt(Q.slice(5,7),16)/255).toFixed(4);return`color(display-p3 ${Y} ${Z} ${$} / ${X})`}#qQ(Q){let X=Q.r/255,Y=Q.g/255,Z=Q.b/255,$=Math.max(X,Y,Z),j=Math.min(X,Y,Z),J,U,L=($+j)/2;if($===j)J=U=0;else{let K=$-j;switch(U=L>0.5?K/(2-$-j):K/($+j),$){case X:J=((Y-Z)/K+(Y<Z?6:0))/6;break;case Y:J=((Z-X)/K+2)/6;break;case Z:J=((X-Y)/K+4)/6;break}}return{h:J*360,s:U*100,l:L*100}}#_Q(Q){let X=Q.h/360,Y=Q.s/100,Z=Q.l/100,$,j,J;if(Y===0)$=j=J=Z;else{let U=(z,W,_)=>{if(_<0)_+=1;if(_>1)_-=1;if(_<0.16666666666666666)return z+(W-z)*6*_;if(_<0.5)return W;if(_<0.6666666666666666)return z+(W-z)*(0.6666666666666666-_)*6;return z},L=Z<0.5?Z*(1+Y):Z+Y-Z*Y,K=2*Z-L;$=U(K,L,X+0.3333333333333333),j=U(K,L,X),J=U(K,L,X-0.3333333333333333)}return{r:Math.round($*255),g:Math.round(j*255),b:Math.round(J*255)}}#n(Q){let X=(W)=>{return W=W/255,W<=0.04045?W/12.92:Math.pow((W+0.055)/1.055,2.4)},Y=X(Q.r),Z=X(Q.g),$=X(Q.b),j=0.4122214708*Y+0.5363325363*Z+0.0514459929*$,J=0.2119034982*Y+0.6806995451*Z+0.1073969566*$,U=0.0883024619*Y+0.2817188376*Z+0.6299787005*$,L=Math.cbrt(j),K=Math.cbrt(J),z=Math.cbrt(U);return{l:0.2104542553*L+0.793617785*K-0.0040720468*z,a:1.9779984951*L-2.428592205*K+0.4505937099*z,b:0.0259040371*L+0.7827717662*K-0.808675766*z}}#OQ(Q){let X=this.#n(Q);return{l:X.l,c:Math.sqrt(X.a*X.a+X.b*X.b),h:(Math.atan2(X.b,X.a)*180/Math.PI+360)%360}}#r(Q){let X=Q.l+0.3963377774*Q.a+0.2158037573*Q.b,Y=Q.l-0.1055613458*Q.a-0.0638541728*Q.b,Z=Q.l-0.0894841775*Q.a-1.291485548*Q.b,$=X*X*X,j=Y*Y*Y,J=Z*Z*Z,U=(L)=>{let K=L<=0.0031308?12.92*L:1.055*Math.pow(L,0.4166666666666667)-0.055;return Math.round(Math.max(0,Math.min(1,K))*255)};return{r:U(4.0767416621*$-3.3077115913*j+0.2309699292*J),g:U(-1.2684380046*$+2.6097574011*j-0.3413193965*J),b:U(-0.0041960863*$-0.7034186147*j+1.707614701*J)}}#BQ(Q){let X=Q.h*Math.PI/180;return this.#r({l:Q.l,a:Q.c*Math.cos(X),b:Q.c*Math.sin(X)})}#Z(){this.#W(),this.dispatchEvent(new CustomEvent("input",{bubbles:!0,detail:this.value}))}#_(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:this.value}))}get value(){let Q={type:this.#U,colorSpace:this.#L};switch(this.#U){case"solid":return{...Q,color:this.#k(this.#Y),alpha:this.#Y.a,hsv:{...this.#Y}};case"gradient":return{...Q,gradient:F(this.#X),css:this.#i()};case"image":return{...Q,image:{...this.#j}};case"video":return{...Q,video:{...this.#J}};case"webcam":return{...Q,image:{url:this.#K.snapshot,scaleMode:"fill",scale:50}};default:return{...Q,...this.#A[this.#U]}}}set value(Q){if(typeof Q==="string")this.setAttribute("value",Q);else this.setAttribute("value",JSON.stringify(Q))}attributeChangedCallback(Q,X,Y){if(X===Y)return;switch(Q){case"value":if(this.#h(),this.#W(),this.#Q){if(!this.#M){if(this.#q(),this.#D(),this.#N)this.#N.setAttribute("value",this.#Y.h);if(this.#B)this.#B.setAttribute("value",this.#Y.a*100),this.#B.setAttribute("color",this.#k(this.#Y))}}break;case"disabled":break}}}customElements.define("fig-fill-picker",N);
@@ -0,0 +1 @@
1
+ fig-fill-picker{display:contents;&>[slot^=mode-]{display:none}}.fig-fill-picker-dialog{contain:layout;width:240px;padding:0;&>fig-header{padding:var(--spacer-2);justify-content:space-between;align-items:center;display:flex}& fig-tab{padding:var(--spacer-1) var(--spacer-1);font-size:.6875rem}&>fig-content{padding-bottom:var(--spacer-2-5)}& .fig-fill-picker-type-label{font-size:var(--font-size-small);font-weight:var(--font-weight-medium);color:var(--figma-color-text);padding:var(--spacer-1) var(--spacer-2)}& .fig-fill-picker-gamut{margin-left:auto}& .fig-fill-picker-tab{display:none;&:first-child{display:block}}& .fig-fill-picker-color-area{aspect-ratio:1;width:calc(100% - var(--spacer-3) * 2);margin:var(--spacer-2) var(--spacer-3);&>:not(fig-handle){border-radius:inherit;place-self:center;width:100%;height:100%}& canvas{border-radius:var(--radius-medium);width:100%;height:100%}}& .fig-fill-picker-color-area fig-handle{z-index:1}& .fig-fill-picker-sliders{grid-template-columns:calc(3.5rem + var(--spacer-3)) 1fr;padding-right:var(--spacer-3);align-items:center;gap:var(--spacer-2);padding-bottom:var(--spacer-1);grid-template-rows:1fr 1fr;display:grid;& .fig-fill-picker-eyedropper{margin-right:calc(var(--spacer-3) * -1);aspect-ratio:1;grid-area:1/1/3;place-self:center;width:3.5rem;height:3.5rem}& fig-slider{grid-column:2;min-width:0}}& .fig-fill-picker-inputs{& .fig-fill-picker-input-fields{flex:1;min-width:0;display:flex;& .input-combo,& fig-input-text{flex:1;min-width:0}}}& .fig-fill-picker-gradient-preview{aspect-ratio:auto;width:calc(100% - var(--spacer-3) * 2);margin:var(--spacer-2) var(--spacer-3);margin-top:var(--spacer-4);background:0 0}& .fig-fill-picker-gradient-header{padding-right:var(--spacer-2);padding-left:var(--spacer-3);gap:var(--spacer-2);display:flex;& .fig-fill-picker-gradient-type{flex:1;min-width:0}&>:last-child fig-button{margin-left:auto}& .fig-fill-picker-gradient-center{& fig-input-number{width:48px}}}& .fig-fill-picker-gradient-stops{& .fig-fill-picker-gradient-stops-header{&>span{flex:1}}}& .fig-fill-picker-gradient-stops-list{gap:var(--spacer-1);flex-direction:column;display:flex}& .fig-fill-picker-gradient-stop-row{padding-right:var(--spacer-2);padding-left:var(--spacer-3);gap:var(--spacer-2);display:flex;&>.fig-fill-picker-stop-position{flex:0 3rem;width:3rem;min-width:0}& .fig-fill-picker-stop-color{flex:1;min-width:0;& fig-input-text{min-width:0}}& .fig-fill-picker-stop-remove{flex-shrink:0}}& .fig-fill-picker-media-header{& .fig-fill-picker-scale-mode{flex:1}& .fig-fill-picker-scale{width:56px}}& .fig-fill-picker-media-preview{aspect-ratio:1;margin:var(--spacer-1) var(--spacer-3);border-radius:var(--radius-medium);justify-content:center;align-items:center;display:flex;position:relative;overflow:hidden;&.dragover{outline:2px dashed var(--figma-color-border-brand);outline-offset:-2px}&.has-media{& fig-button{visibility:hidden}&:hover{& fig-button{visibility:visible}}}}& .fig-fill-picker-checkerboard{background-image:linear-gradient(45deg, var(--figma-color-bg-tertiary) 25%, transparent 25%), linear-gradient(-45deg, var(--figma-color-bg-tertiary) 25%, transparent 25%), linear-gradient(45deg, transparent 75%, var(--figma-color-bg-tertiary) 75%), linear-gradient(-45deg, transparent 75%, var(--figma-color-bg-tertiary) 75%);background-position:0 0,0 8px,8px -8px,-8px 0;background-size:16px 16px;position:absolute;inset:0}& div.fig-fill-picker-image-preview{width:100%;height:100%;display:none;position:absolute;inset:0}& fig-image.fig-fill-picker-image-preview{width:auto;max-width:none;max-height:none}& video.fig-fill-picker-video-preview{object-fit:cover;width:100%;height:100%;display:none;position:absolute;inset:0}& fig-media.fig-fill-picker-video-preview{width:auto;max-width:none;max-height:none}& .fig-fill-picker-upload{z-index:1;position:relative}& .fig-fill-picker-webcam-preview{aspect-ratio:1;margin:0 var(--spacer-3);border-radius:var(--radius-medium);margin-bottom:var(--spacer-2);position:relative;overflow:hidden}& .fig-fill-picker-webcam-video{object-fit:cover;width:100%;height:100%;position:absolute;inset:0}& .fig-fill-picker-webcam-status{background:var(--figma-color-bg-secondary);color:var(--figma-color-text-secondary);justify-content:center;align-items:center;font-size:.75rem;display:flex;position:absolute;inset:0}& .fig-fill-picker-webcam-controls{gap:var(--spacer-1);display:flex;& .fig-fill-picker-camera-select{flex:1}& .fig-fill-picker-webcam-capture{flex-shrink:0}}}
@@ -0,0 +1,160 @@
1
+ import{gradientToValueShape as F,gradientInterpolationClause as V,normalizeGradientConfig as k}from"./fig.js";class N extends HTMLElement{#E=null;#$=null;#Q=null;#b="solid";anchorElement=null;#W="solid";#L="srgb";#Y={h:0,s:0,v:85,a:1};#y="hex";#X={type:"linear",angle:0,centerX:50,centerY:50,interpolationSpace:"oklab",hueInterpolation:"shorter",stops:[{position:0,color:"#D9D9D9",opacity:100},{position:100,color:"#737373",opacity:100}]};#j={url:null,scaleMode:"fill",scale:50};#J={url:null,scaleMode:"fill",scale:50};#z={stream:null,snapshot:null};#R={};#A={};#U=null;#O=null;#N=null;#B=null;#F=!1;#M=null;#H=null;#T=null;constructor(){super()}static get observedAttributes(){return["value","disabled","alpha","mode","experimental"]}connectedCallback(){this.style.display="contents",requestAnimationFrame(()=>{this.#o(),this.#h(),this.#K()})}disconnectedCallback(){if(this.#M)this.#M(),this.#M=null;if(this.#H)this.#H.disconnect(),this.#H=null;if(this.#T)this.#T.disconnect(),this.#T=null;if(this.#z.stream)this.#z.stream.getTracks().forEach((Q)=>Q.stop()),this.#z.stream=null;if(this.#J.url&&this.#J.url.startsWith("blob:"))URL.revokeObjectURL(this.#J.url);if(this.#$)this.#$.removeAttribute("selected");if(this.#Q)this.#Q.close(),this.#Q.remove(),this.#Q=null}#o(){let Q=Array.from(this.children).find((X)=>!X.getAttribute("slot")?.startsWith("mode-"));if(!Q)this.#$=document.createElement("fig-chit"),this.#$.setAttribute("background","#D9D9D9"),this.appendChild(this.#$),this.#E=this.#$;else if(Q.tagName==="FIG-CHIT")this.#$=Q,this.#E=Q;else this.#E=Q,this.#$=null;if(this.#E.addEventListener("click",(X)=>{if(this.hasAttribute("disabled"))return;X.stopPropagation(),X.preventDefault(),this.#m()}),this.#$)requestAnimationFrame(()=>{let X=this.#$.querySelector('input[type="color"]');if(X)X.style.pointerEvents="none"})}#h(){let Q=this.getAttribute("value");if(!Q)return;let X=["solid","gradient","image","video","webcam"];try{let Y=JSON.parse(Q);if(Y.type)this.#W=Y.type;if(Y.color){if(typeof Y.color==="string")this.#Y=this.#C(Y.color);else if(typeof Y.color==="object"&&Y.color.h!==void 0)this.#Y=Y.color}if(Y.opacity!==void 0)this.#Y.a=Y.opacity/100;if(Y.colorSpace==="display-p3"||Y.colorSpace==="srgb")this.#L=Y.colorSpace;if(Y.gradient)this.#X=k({...this.#X,...Y.gradient});if(Y.image)this.#j={...this.#j,...Y.image};if(Y.video)this.#J={...this.#J,...Y.video};if(Y.type&&!X.includes(Y.type)){let{type:Z,...$}=Y;this.#A[Y.type]=$}}catch(Y){if(Q.startsWith("#"))this.#W="solid",this.#Y=this.#C(Q)}}#K(){if(!this.#$)return;let Q,X="cover",Y="center";switch(this.#W){case"solid":Q=this.#k(this.#Y);break;case"gradient":Q=this.#i();break;case"image":if(this.#j.url){Q=`url(${this.#j.url})`;let $=this.#u(this.#j.scaleMode,this.#j.scale);X=$.size,Y=$.position}else Q="";break;case"video":if(this.#J.url){Q=`url(${this.#J.url})`;let $=this.#u(this.#J.scaleMode,this.#J.scale);X=$.size,Y=$.position}else Q="";break;default:Q=this.#R[this.#W]?.element?.getAttribute("chit-background")||"#D9D9D9"}if(this.#$.setAttribute("background",Q),this.#$.style.setProperty("--chit-bg-size",X),this.#$.style.setProperty("--chit-bg-position",Y),this.#W==="solid")this.#$.setAttribute("alpha",this.#Y.a);else this.#$.removeAttribute("alpha")}#u(Q,X){switch(Q){case"fill":return{size:"cover",position:"center"};case"fit":return{size:"contain",position:"center"};case"crop":return{size:"cover",position:"center"};case"tile":return{size:`${X}%`,position:"top left"};default:return{size:"cover",position:"center"}}}#m(){if(!this.#Q)this.#t();this.#x(this.#W);let Q=this.#Q.querySelector(".fig-fill-picker-gamut");if(Q)Q.value=this.#L;if(this.#$)this.#$.setAttribute("selected","true");this.#Q.open=!0,requestAnimationFrame(()=>{requestAnimationFrame(()=>{this.#G(),this.#q()})})}open(){this.#m()}close(){if(this.#Q)this.#Q.open=!1}#t(){this.#R={},this.querySelectorAll('[slot^="mode-"]').forEach((R)=>{let q=R.getAttribute("slot").slice(5);this.#R[q]={element:R,label:R.getAttribute("label")||q.charAt(0).toUpperCase()+q.slice(1)}}),this.#Q=document.createElement("dialog",{is:"fig-popup"}),this.#Q.setAttribute("is","fig-popup"),this.#Q.setAttribute("drag","true"),this.#Q.setAttribute("handle","fig-header"),this.#Q.setAttribute("autoresize","false"),this.#Q.classList.add("fig-fill-picker-dialog"),this.#Q.anchor=this.anchorElement||this.#E;let Q=this.getAttribute("dialog-position")||"left";this.#Q.setAttribute("position",Q),this.#Q.setAttribute("offset",this.getAttribute("dialog-offset")||"8 8");let X=["solid","gradient","image","video","webcam"],Y={solid:"Solid",gradient:"Gradient",image:"Image",video:"Video",webcam:"Webcam"},Z=this.getAttribute("mode"),$;if(Z){if($=Z.split(",").map((q)=>q.trim().toLowerCase()).filter((q)=>X.includes(q)||this.#R[q]),$.length===0)$=[...X]}else $=[...X];let j={...Y};for(let[R,{label:q}]of Object.entries(this.#R))j[R]=q;if(!$.includes(this.#W))this.#W=$[0],this.#b=$[0];let J=this.getAttribute("experimental"),K=J?`experimental="${J}"`:"",L;if($.length===1)L=`<h3 class="fig-fill-picker-type-label">${j[$[0]]}</h3>`;else{let R=$.map((q)=>`<option value="${q}">${j[q]}</option>`).join(`
2
+ `);L=`<fig-dropdown class="fig-fill-picker-type" ${K} value="${this.#W}">
3
+ ${R}
4
+ </fig-dropdown>`}let U=$.map((R)=>`<div class="fig-fill-picker-tab" data-tab="${R}"></div>`).join(`
5
+ `),W=`<fig-dropdown class="fig-fill-picker-gamut" ${K} value="${this.#L}">
6
+ <option value="srgb">sRGB</option>
7
+ <option value="display-p3">Display P3</option>
8
+ </fig-dropdown>`;this.#Q.innerHTML=`
9
+ <fig-header>
10
+ ${L}
11
+ ${W}
12
+ <fig-button icon variant="ghost" class="fig-fill-picker-close">
13
+ <fig-icon name="close"></fig-icon>
14
+ </fig-button>
15
+ </fig-header>
16
+ <fig-content>
17
+ ${U}
18
+ </fig-content>
19
+ `,document.body.appendChild(this.#Q);for(let[R,{element:q}]of Object.entries(this.#R)){let O=this.#Q.querySelector(`[data-tab="${R}"]`);if(!O)continue;while(q.firstChild)O.appendChild(q.firstChild);this.dispatchEvent(new CustomEvent("modeready",{bubbles:!0,detail:{mode:R,container:O}}))}let z=this.#Q.querySelector(".fig-fill-picker-type");if(z)z.addEventListener("change",(R)=>{this.#x(R.target.value)});let _=this.#Q.querySelector(".fig-fill-picker-gamut");if(_){let R=(q)=>{let O=q.currentTarget?.value??q.target?.value??q.detail;if(O&&O!==this.#L)this.#L=O,this.#e()};_.addEventListener("input",R),_.addEventListener("change",R)}this.#Q.querySelector(".fig-fill-picker-close").addEventListener("click",()=>{this.#Q.open=!1});let B=()=>{if(this.#$)this.#$.removeAttribute("selected");this.#_(),this.dispatchEvent(new CustomEvent("close"))};this.#Q.addEventListener("close",B),this.#H=new MutationObserver(()=>{if(!(this.#Q.hasAttribute("open")&&this.#Q.getAttribute("open")!=="false"))B()}),this.#H.observe(this.#Q,{attributes:!0,attributeFilter:["open"]});let M={solid:()=>this.#a(),gradient:()=>this.#YQ(),image:()=>this.#jQ(),video:()=>this.#KQ(),webcam:()=>this.#UQ()};for(let[R,q]of Object.entries(M))if(!this.#R[R]&&$.includes(R))q();for(let R of Object.keys(this.#R)){if(X.includes(R))continue;let q=this.#Q.querySelector(`[data-tab="${R}"]`);if(!q)continue;q.addEventListener("input",(O)=>{if(O.target===this)return;if(O.stopPropagation(),O.detail)this.#A[R]=O.detail;this.#Z()}),q.addEventListener("change",(O)=>{if(O.target===this)return;if(O.stopPropagation(),O.detail)this.#A[R]=O.detail;this.#_()})}}#x(Q){let X=this.#Q?.querySelector(`.fig-fill-picker-tab[data-tab="${Q}"]`);if(!X)return;this.#b=Q,this.#W=Q;let Y=this.#Q.querySelector(".fig-fill-picker-type");if(Y&&Y.value!==Q)Y.value=Q;this.#Q.querySelectorAll(".fig-fill-picker-tab").forEach((j)=>{if(j.dataset.tab===Q)j.style.display="block";else j.style.display="none"});let $=this.#Q.querySelector("fig-content");if($)$.style.padding=this.#R[Q]?"0":"";if(Q==="gradient")requestAnimationFrame(()=>{this.#V();let j=X.querySelector(".fig-fill-picker-gradient-bar-input");j?.refreshLayout?.(),requestAnimationFrame(()=>{j?.refreshLayout?.()})});this.#K(),this.#Z()}#a(){let Q=this.#Q.querySelector('[data-tab="solid"]'),X=this.getAttribute("alpha")!=="false",Y=this.getAttribute("experimental"),Z=Y?`experimental="${Y}"`:"";if(Q.innerHTML=`
20
+ <fig-preview class="fig-fill-picker-color-area">
21
+ <canvas width="200" height="200"></canvas>
22
+ <fig-handle
23
+ type="color"
24
+ color="${this.#k({...this.#Y,a:1})}"
25
+ data-no-color-picker
26
+ drag
27
+ drag-surface=".fig-fill-picker-color-area"
28
+ drag-axes="x,y"
29
+ drag-snapping="modifier"
30
+ ></fig-handle>
31
+ </fig-preview>
32
+ <div class="fig-fill-picker-sliders">
33
+ <fig-tooltip text="Sample color"><fig-button icon variant="ghost" class="fig-fill-picker-eyedropper"><fig-icon name="eyedropper"></fig-icon></fig-button></fig-tooltip>
34
+ <fig-slider type="hue" variant="neue" min="0" max="360" value="${this.#Y.h}"></fig-slider>
35
+ ${X?`<fig-slider type="opacity" variant="neue" text="true" units="%" min="0" max="100" value="${this.#Y.a*100}" color="${this.#k(this.#Y)}"></fig-slider>`:""}
36
+ </div>
37
+ <fig-field class="fig-fill-picker-inputs" direction="horizontal">
38
+ <fig-dropdown class="fig-fill-picker-input-mode" ${Z} value="${this.#y}">
39
+ <option value="hex">Hex</option>
40
+ <option value="rgb">RGB</option>
41
+ <option value="hsl">HSL</option>
42
+ <option value="hsb">HSB</option>
43
+ <option value="lab">LAB</option>
44
+ <option value="lch">LCH</option>
45
+ </fig-dropdown>
46
+ <span class="fig-fill-picker-input-fields"></span>
47
+ </fig-field>
48
+ `,this.#U=Q.querySelector("canvas"),this.#O=Q.querySelector("fig-handle"),this.#G(),this.#q(),this.#c(),this.#N=Q.querySelector('fig-slider[type="hue"]'),this.#N.addEventListener("input",(J)=>{this.#Y.h=parseFloat(J.target.value),this.#G(),this.#q(),this.#D(),this.#Z()}),this.#N.addEventListener("change",()=>{this.#_()}),X)this.#B=Q.querySelector('fig-slider[type="opacity"]'),this.#B.addEventListener("input",(J)=>{this.#Y.a=parseFloat(J.target.value)/100,this.#D(),this.#Z()}),this.#B.addEventListener("change",()=>{this.#_()});Q.querySelector(".fig-fill-picker-input-mode").addEventListener("input",(J)=>{this.#y=J.target.value,this.#g()}),this.#g();let j=Q.querySelector(".fig-fill-picker-eyedropper");if("EyeDropper"in window)j.addEventListener("click",async()=>{try{let K=await new EyeDropper().open();this.#Y={...this.#C(K.sRGBHex),a:this.#Y.a},this.#G(),this.#q(),this.#D(),this.#Z()}catch(J){}});else j.setAttribute("disabled",""),j.title="EyeDropper not supported in this browser"}#e(){let Q=this.#Q?.querySelector('[data-tab="solid"]');if(Q){let X=Q.querySelector("canvas");if(X){let Y=document.createElement("canvas");Y.width=X.width,Y.height=X.height,X.replaceWith(Y),this.#U=Y,this.#c()}this.#G(),this.#q()}this.#f(),this.#Z()}#G(){if(!this.#U&&this.#Q)this.#U=this.#Q.querySelector('[data-tab="solid"] canvas');if(!this.#U)return;let Q=this.#L==="display-p3"?"display-p3":"srgb",X=this.#U.getContext("2d",{colorSpace:Q});if(!X)return;let Y=this.#U.width,Z=this.#U.height;X.clearRect(0,0,Y,Z);let $=this.#Y.h,j=this.#L==="display-p3",J=X.createLinearGradient(0,0,Y,0);if(j){J.addColorStop(0,"color(display-p3 1 1 1)");let[L,U,W]=hslToP3($,100,50);J.addColorStop(1,`color(display-p3 ${L} ${U} ${W})`)}else J.addColorStop(0,"#FFFFFF"),J.addColorStop(1,`hsl(${$}, 100%, 50%)`);X.fillStyle=J,X.fillRect(0,0,Y,Z);let K=X.createLinearGradient(0,0,0,Z);K.addColorStop(0,"rgba(0,0,0,0)"),K.addColorStop(1,"rgba(0,0,0,1)"),X.fillStyle=K,X.fillRect(0,0,Y,Z)}#q(Q=0){if(!this.#O||!this.#U)return;let X=this.#U.getBoundingClientRect();if((X.width===0||X.height===0)&&Q<5){requestAnimationFrame(()=>this.#q(Q+1));return}let Y=Math.max(0,Math.min(100,this.#Y.s)),Z=Math.max(0,Math.min(100,100-this.#Y.v));this.#O.setAttribute("value",`${Y}% ${Z}%`),this.#O.setAttribute("color",this.#k({...this.#Y,a:1}))}#w(Q,X,Y={}){let{updateHandle:Z=!0,emitInput:$=!0,emitChange:j=!1}=Y;if(this.#Y.s=Math.max(0,Math.min(100,Q*100)),this.#Y.v=Math.max(0,Math.min(100,(1-X)*100)),this.#O)this.#O.setAttribute("color",this.#k({...this.#Y,a:1}));if(Z)this.#q();if(this.#D(),$)this.#Z();if(j)this.#_()}#c(){if(this.#M)this.#M(),this.#M=null;if(!this.#U||!this.#O)return;let Q=this.#U.parentElement||this.#U,X=this.#O,Y=!1,Z=(U,W={})=>{let z=Q.getBoundingClientRect();if(z.width===0||z.height===0)return;let _=Math.max(0,Math.min(U.clientX-z.left,z.width)),B=Math.max(0,Math.min(U.clientY-z.top,z.height));this.#w(_/z.width,B/z.height,W)},$=(U)=>{if(U.button!==0)return;if(U.target===X||X.contains(U.target))return;Y=!0,this.#F=!0,Q.setPointerCapture(U.pointerId),Z(U,{updateHandle:!0,emitInput:!0})},j=(U)=>{if(!Y)return;if(U.buttons===0){J();return}Z(U,{updateHandle:!0,emitInput:!0})},J=()=>{if(!Y)return;Y=!1,this.#F=!1,this.#_()},K=(U)=>{this.#F=!0;let W=U.detail?.px,z=U.detail?.py;if(!Number.isFinite(W)||!Number.isFinite(z))return;X.setAttribute("value",`${W*100}% ${z*100}%`),this.#w(W,z,{updateHandle:!1,emitInput:!0})},L=(U)=>{let W=U.detail?.px,z=U.detail?.py;if(Number.isFinite(W)&&Number.isFinite(z))X.setAttribute("value",`${W*100}% ${z*100}%`),this.#w(W,z,{updateHandle:!1,emitInput:!1});this.#F=!1,this.#_()};Q.addEventListener("pointerdown",$),Q.addEventListener("pointermove",j),Q.addEventListener("pointerup",J),Q.addEventListener("pointercancel",J),Q.addEventListener("lostpointercapture",J),X.addEventListener("input",K),X.addEventListener("change",L),this.#M=()=>{Q.removeEventListener("pointerdown",$),Q.removeEventListener("pointermove",j),Q.removeEventListener("pointerup",J),Q.removeEventListener("pointercancel",J),Q.removeEventListener("lostpointercapture",J),X.removeEventListener("input",K),X.removeEventListener("change",L),this.#F=!1}}#g(){let Q=this.#Q?.querySelector(".fig-fill-picker-input-fields");if(!Q)return;let X=($,j)=>`<fig-tooltip text="${$}">${j}</fig-tooltip>`,Y=($,j,J,K)=>`<fig-input-number class="${$}" min="${j}" max="${J}"${K!=null?` step="${K}"`:""}></fig-input-number>`,Z;switch(this.#y){case"rgb":Z=`<div class="input-combo">
49
+ ${X("Red",Y("fig-fill-picker-ci-r",0,255))}
50
+ ${X("Green",Y("fig-fill-picker-ci-g",0,255))}
51
+ ${X("Blue",Y("fig-fill-picker-ci-b",0,255))}
52
+ </div>`;break;case"hsl":Z=`<div class="input-combo">
53
+ ${X("Hue",Y("fig-fill-picker-ci-h",0,360))}
54
+ ${X("Saturation",Y("fig-fill-picker-ci-s",0,100))}
55
+ ${X("Lightness",Y("fig-fill-picker-ci-l",0,100))}
56
+ </div>`;break;case"hsb":Z=`<div class="input-combo">
57
+ ${X("Hue",Y("fig-fill-picker-ci-h",0,360))}
58
+ ${X("Saturation",Y("fig-fill-picker-ci-s",0,100))}
59
+ ${X("Brightness",Y("fig-fill-picker-ci-v",0,100))}
60
+ </div>`;break;case"lab":Z=`<div class="input-combo">
61
+ ${X("Lightness",Y("fig-fill-picker-ci-okl",0,100))}
62
+ ${X("Green-Red axis",Y("fig-fill-picker-ci-oka",-0.4,0.4,0.001))}
63
+ ${X("Blue-Yellow axis",Y("fig-fill-picker-ci-okb",-0.4,0.4,0.001))}
64
+ </div>`;break;case"lch":Z=`<div class="input-combo">
65
+ ${X("Lightness",Y("fig-fill-picker-ci-okl",0,100))}
66
+ ${X("Chroma",Y("fig-fill-picker-ci-okc",0,0.4,0.001))}
67
+ ${X("Hue",Y("fig-fill-picker-ci-okh",0,360))}
68
+ </div>`;break;default:Z='<fig-input-text class="fig-fill-picker-ci-hex" placeholder="FFFFFF"></fig-input-text>';break}Q.innerHTML=Z,this.#QQ(),requestAnimationFrame(()=>this.#D())}#QQ(){let Q=this.#Q?.querySelector(".fig-fill-picker-input-fields");if(!Q)return;let X=()=>{if(this.#F)return;let $=this.#XQ();if(!$)return;if(this.#Y={...$,a:this.#Y.a},this.#G(),this.#q(),this.#N)this.#N.setAttribute("value",this.#Y.h);this.#Z()},Y=()=>this.#_();Q.querySelectorAll("fig-input-number, fig-input-text").forEach(($)=>{$.addEventListener("input",X),$.addEventListener("change",Y)})}#XQ(){let Q=(Y)=>this.#Q?.querySelector(`.${Y}`),X=(Y)=>parseFloat(Q(Y)?.value??0);switch(this.#y){case"rgb":return this.#S({r:X("fig-fill-picker-ci-r"),g:X("fig-fill-picker-ci-g"),b:X("fig-fill-picker-ci-b")});case"hsl":{let Y=this.#_Q({h:X("fig-fill-picker-ci-h"),s:X("fig-fill-picker-ci-s"),l:X("fig-fill-picker-ci-l")});return this.#S(Y)}case"hsb":return{h:X("fig-fill-picker-ci-h"),s:X("fig-fill-picker-ci-s"),v:X("fig-fill-picker-ci-v"),a:1};case"lab":{let Y=this.#r({l:X("fig-fill-picker-ci-okl")/100,a:X("fig-fill-picker-ci-oka"),b:X("fig-fill-picker-ci-okb")});return this.#S(Y)}case"lch":{let Y=this.#BQ({l:X("fig-fill-picker-ci-okl")/100,c:X("fig-fill-picker-ci-okc"),h:X("fig-fill-picker-ci-okh")});return this.#S(Y)}default:{let Y=Q("fig-fill-picker-ci-hex");if(!Y)return null;let Z=Y.value.replace(/^#/,"");if(Z.length===3)Z=Z[0]+Z[0]+Z[1]+Z[1]+Z[2]+Z[2];if(Z.length!==6||!/^[0-9a-fA-F]{6}$/.test(Z))return null;return this.#C(`#${Z}`)}}}#D(){if(!this.#Q)return;let Q=this.#k(this.#Y),X=this.#l(this.#Y),Y=($)=>this.#Q.querySelector(`.${$}`),Z=($,j)=>{let J=Y($);if(J)J.setAttribute("value",j)};switch(this.#y){case"rgb":Z("fig-fill-picker-ci-r",X.r),Z("fig-fill-picker-ci-g",X.g),Z("fig-fill-picker-ci-b",X.b);break;case"hsl":{let $=this.#qQ(X);Z("fig-fill-picker-ci-h",Math.round($.h)),Z("fig-fill-picker-ci-s",Math.round($.s)),Z("fig-fill-picker-ci-l",Math.round($.l));break}case"hsb":Z("fig-fill-picker-ci-h",Math.round(this.#Y.h)),Z("fig-fill-picker-ci-s",Math.round(this.#Y.s)),Z("fig-fill-picker-ci-v",Math.round(this.#Y.v));break;case"lab":{let $=this.#n(X);Z("fig-fill-picker-ci-okl",Math.round($.l*100)),Z("fig-fill-picker-ci-oka",+$.a.toFixed(3)),Z("fig-fill-picker-ci-okb",+$.b.toFixed(3));break}case"lch":{let $=this.#OQ(X);Z("fig-fill-picker-ci-okl",Math.round($.l*100)),Z("fig-fill-picker-ci-okc",+$.c.toFixed(3)),Z("fig-fill-picker-ci-okh",Math.round($.h));break}default:Z("fig-fill-picker-ci-hex",Q.replace(/^#/,"").toUpperCase());break}if(this.#B)this.#B.setAttribute("color",Q);this.#K()}#YQ(){let Q=this.#Q.querySelector('[data-tab="gradient"]'),X=this.getAttribute("experimental"),Y=X?`experimental="${X}"`:"";Q.innerHTML=`
69
+ <fig-field class="fig-fill-picker-gradient-header" direction="horizontal">
70
+ <fig-dropdown class="fig-fill-picker-gradient-type" ${Y} value="${this.#X.type}">
71
+ <option value="linear" selected>Linear</option>
72
+ <option value="radial">Radial</option>
73
+ <option value="angular">Angular</option>
74
+ </fig-dropdown>
75
+ <fig-tooltip text="Rotate gradient">
76
+ <fig-input-number class="fig-fill-picker-gradient-angle" value="${(this.#X.angle-90+360)%360}" min="0" max="360" units="°" wrap></fig-input-number>
77
+ </fig-tooltip>
78
+ <div class="fig-fill-picker-gradient-center input-combo" style="display: none;">
79
+ <fig-input-number min="0" max="100" value="${this.#X.centerX}" units="%" class="fig-fill-picker-gradient-cx"></fig-input-number>
80
+ <fig-input-number min="0" max="100" value="${this.#X.centerY}" units="%" class="fig-fill-picker-gradient-cy"></fig-input-number>
81
+ </div>
82
+ <fig-tooltip text="Flip gradient">
83
+ <fig-button icon variant="ghost" class="fig-fill-picker-gradient-flip">
84
+ <fig-icon name="swap"></fig-icon>
85
+ </fig-button>
86
+ </fig-tooltip>
87
+ </fig-field>
88
+ <fig-preview class="fig-fill-picker-gradient-preview">
89
+ <fig-input-gradient class="fig-fill-picker-gradient-bar-input" edit="true" size="large" value='${JSON.stringify({type:"gradient",gradient:F(this.#X)})}'></fig-input-gradient>
90
+ </fig-preview>
91
+ <fig-field class="fig-fill-picker-gradient-interpolation" direction="horizontal">
92
+ <label>Mixing</label>
93
+ <fig-dropdown class="fig-fill-picker-gradient-space" full ${Y} value="${this.#X.interpolationSpace==="oklch"?`oklch-${this.#X.hueInterpolation||"shorter"}`:this.#X.interpolationSpace}">
94
+ <optgroup label="sRGB">
95
+ <option value="srgb-linear">Linear</option>
96
+ </optgroup>
97
+ <optgroup label="OKLab">
98
+ <option value="oklab">Perceptual</option>
99
+ </optgroup>
100
+ <optgroup label="OKLCH">
101
+ <option value="oklch-shorter">Shorter hue</option>
102
+ <option value="oklch-longer">Longer hue</option>
103
+ <option value="oklch-increasing">Increasing hue</option>
104
+ <option value="oklch-decreasing">Decreasing hue</option>
105
+ </optgroup>
106
+ </fig-dropdown>
107
+ </fig-field>
108
+ <div class="fig-fill-picker-gradient-stops">
109
+ <fig-header class="fig-fill-picker-gradient-stops-header" borderless>
110
+ <span>Stops</span>
111
+ <fig-button icon variant="ghost" class="fig-fill-picker-gradient-add" title="Add stop">
112
+ <fig-icon name="add"></fig-icon>
113
+ </fig-button>
114
+ </fig-header>
115
+ <div class="fig-fill-picker-gradient-stops-list"></div>
116
+ </div>
117
+ `,this.#V(),this.#ZQ(Q)}#ZQ(Q){let X=Q.querySelector(".fig-fill-picker-gradient-type"),Y=(W)=>W.currentTarget?.value??W.target?.value??W.detail,Z=(W)=>{this.#X.type=Y(W),this.#V(),this.#Z()};X.addEventListener("input",Z),X.addEventListener("change",Z);let $=Q.querySelector(".fig-fill-picker-gradient-space"),j=(W)=>{let z=Y(W),_=z,B="shorter";if(z.startsWith("oklch-"))_="oklch",B=z.slice(6);this.#X=k({...this.#X,interpolationSpace:_,hueInterpolation:B}),this.#V(),this.#Z()};$?.addEventListener("input",j),$?.addEventListener("change",j),Q.querySelector(".fig-fill-picker-gradient-angle").addEventListener("input",(W)=>{let z=parseFloat(W.target.value)||0;this.#X.angle=(z+90)%360,this.#f(),this.#Z()});let K=Q.querySelector(".fig-fill-picker-gradient-cx"),L=Q.querySelector(".fig-fill-picker-gradient-cy");K?.addEventListener("input",(W)=>{this.#X.centerX=parseFloat(W.target.value)||50,this.#f(),this.#Z()}),L?.addEventListener("input",(W)=>{this.#X.centerY=parseFloat(W.target.value)||50,this.#f(),this.#Z()}),Q.querySelector(".fig-fill-picker-gradient-flip").addEventListener("click",()=>{this.#X.stops.forEach((W)=>{W.position=100-W.position}),this.#X.stops.sort((W,z)=>W.position-z.position),this.#V(),this.#Z()}),Q.querySelector(".fig-fill-picker-gradient-add").addEventListener("click",()=>{this.#X.stops.push({position:50,color:"#888888",opacity:100}),this.#X.stops.sort((z,_)=>z.position-_.position),this.#V(),this.#Z()});let U=Q.querySelector(".fig-fill-picker-gradient-bar-input");if(U){let W=(z)=>{z.stopPropagation();let _=z.detail;if(!_?.gradient)return;this.#X=k({...this.#X,..._.gradient}),this.#K(),this.#s()};U.addEventListener("input",(z)=>{W(z),this.#Z()}),U.addEventListener("change",(z)=>{W(z),this.#_()})}}#V(){if(!this.#Q)return;let Q=this.#Q.querySelector('[data-tab="gradient"]');if(!Q)return;this.#X=k(this.#X);let X=Q.querySelector(".fig-fill-picker-gradient-angle"),Y=Q.querySelector(".fig-fill-picker-gradient-center");if(this.#X.type==="radial")X.style.display="none",Y.style.display="flex";else{X.style.display="block",Y.style.display="none";let $=(this.#X.angle-90+360)%360;X.setAttribute("value",$)}let Z=Q.querySelector(".fig-fill-picker-gradient-space");if(Z)Z.value=this.#X.interpolationSpace==="oklch"?`oklch-${this.#X.hueInterpolation||"shorter"}`:this.#X.interpolationSpace;this.#f(),this.#s()}#f(){if(!this.#Q)return;let Q=this.#Q.querySelector(".fig-fill-picker-gradient-bar-input");if(Q)Q.setAttribute("value",JSON.stringify({type:"gradient",gradient:F(this.#X)}));this.#K()}#s(){if(!this.#Q)return;let Q=this.#Q.querySelector(".fig-fill-picker-gradient-stops-list");if(!Q)return;let X=Q.querySelectorAll(".fig-fill-picker-gradient-stop-row");if(X.length===this.#X.stops.length){this.#X.stops.forEach((Y,Z)=>{let $=X[Z];$.dataset.index=Z;let j=$.querySelector(".fig-fill-picker-stop-position");if(j)j.setAttribute("value",Y.position);let J=$.querySelector(".fig-fill-picker-stop-color");if(J)J.setAttribute("value",Y.color);let K=$.querySelector(".fig-fill-picker-stop-remove");if(K)if(this.#X.stops.length<=2)K.setAttribute("disabled","");else K.removeAttribute("disabled")});return}this.#$Q(Q)}#$Q(Q){Q.innerHTML=this.#X.stops.map((X,Y)=>`
118
+ <fig-field class="fig-fill-picker-gradient-stop-row" direction="horizontal" data-index="${Y}">
119
+ <fig-input-number class="fig-fill-picker-stop-position" min="0" max="100" value="${X.position}" units="%"></fig-input-number>
120
+ <fig-input-color class="fig-fill-picker-stop-color" text="true" alpha="true" picker="figma" picker-dialog-position="right" value="${X.color}"></fig-input-color>
121
+ <fig-button icon variant="ghost" class="fig-fill-picker-stop-remove" ${this.#X.stops.length<=2?"disabled":""}>
122
+ <fig-icon name="minus"></fig-icon>
123
+ </fig-button>
124
+ </fig-field>
125
+ `).join(""),Q.querySelectorAll(".fig-fill-picker-gradient-stop-row").forEach((X)=>{let Y=parseInt(X.dataset.index);X.querySelector(".fig-fill-picker-stop-position").addEventListener("input",(j)=>{this.#X.stops[Y].position=parseFloat(j.target.value)||0,this.#f(),this.#Z()});let Z=X.querySelector(".fig-fill-picker-stop-color"),$=Z.querySelector("fig-fill-picker");if($)$.anchorElement=this.#Q;else requestAnimationFrame(()=>{let j=Z.querySelector("fig-fill-picker");if(j)j.anchorElement=this.#Q});Z.addEventListener("input",(j)=>{this.#X.stops[Y].color=j.target.hexOpaque||j.target.value;let J=j.detail?.rgba?.a;if(J!==void 0)this.#X.stops[Y].opacity=Math.round(J*100);this.#f(),this.#Z()}),X.querySelector(".fig-fill-picker-stop-remove").addEventListener("click",()=>{if(this.#X.stops.length>2)this.#X.stops.splice(Y,1),this.#V(),this.#Z()})})}#v(Q,X=!0){let Y=k({...this.#X,interpolationSpace:Q??this.#X.interpolationSpace}),Z=this.#L==="display-p3",$=Y.stops.map((J)=>{let K=(J.opacity??100)/100;return`${Z?this.#RQ(J.color,K):this.#LQ(J.color,K)} ${J.position}%`}).join(", "),j=X?` ${V(Y)}`:"";switch(Y.type){case"linear":return`linear-gradient(${Y.angle}deg${j}, ${$})`;case"radial":return`radial-gradient(circle at ${Y.centerX}% ${Y.centerY}%${j}, ${$})`;case"angular":return`conic-gradient(from ${Y.angle}deg${j}, ${$})`;default:return`linear-gradient(${Y.angle}deg${j}, ${$})`}}static#p=new Map;#d(Q){let X=N.#p.get(Q);if(X!==void 0)return X;let Y=document.createElement("div");Y.style.background=Q;let Z=!!Y.style.background;return N.#p.set(Q,Z),Z}#i(){let Q=this.#v(void 0,!0);if(this.#d(Q))return Q;let X=this.#v("oklab",!0);if(this.#d(X))return X;return this.#v("oklab",!1)}#jQ(){let Q=this.#Q.querySelector('[data-tab="image"]'),X=this.getAttribute("experimental"),Y=X?`experimental="${X}"`:"";Q.innerHTML=`
126
+ <fig-field class="fig-fill-picker-media-header" direction="horizontal">
127
+ <fig-dropdown class="fig-fill-picker-scale-mode" ${Y} value="${this.#j.scaleMode}">
128
+ <option value="fill" selected>Fill</option>
129
+ <option value="fit">Fit</option>
130
+ <option value="crop">Crop</option>
131
+ <option value="tile">Tile</option>
132
+ </fig-dropdown>
133
+ <fig-input-number class="fig-fill-picker-scale" min="1" max="200" value="${this.#j.scale}" units="%" ${this.#j.scaleMode==="tile"?"":'style="display: none;"'}></fig-input-number>
134
+ </fig-field>
135
+ <fig-image class="fig-fill-picker-media-preview fig-fill-picker-image-preview" upload="true" label="Upload from computer" size="auto" aspect-ratio="1/1" fit="cover" checkerboard="true"></fig-image>
136
+ `,this.#JQ(Q)}#JQ(Q){let X=Q.querySelector(".fig-fill-picker-scale-mode"),Y=Q.querySelector(".fig-fill-picker-scale"),Z=Q.querySelector(".fig-fill-picker-image-preview");X.addEventListener("change",($)=>{this.#j.scaleMode=$.target.value,Y.style.display=$.target.value==="tile"?"block":"none",this.#P(Z),this.#K(),this.#Z()}),Y.addEventListener("input",($)=>{this.#j.scale=parseFloat($.target.value)||100,this.#P(Z),this.#K(),this.#Z()}),Z.addEventListener("loaded",($)=>{let j=$.detail?.src||Z.src;if(!j)return;this.#j.url=j,this.#P(Z),this.#K(),this.#Z()}),Z.addEventListener("change",()=>{if(Z.src)return;this.#j.url=null,this.#P(Z),this.#K(),this.#Z()}),this.#P(Z)}#P(Q){if(!this.#j.url){Q.removeAttribute("src"),Q.classList.remove("has-media","is-tiled"),Q.style.backgroundImage="",Q.style.backgroundPosition="",Q.style.backgroundRepeat="",Q.style.backgroundSize="";return}Q.setAttribute("src",this.#j.url),Q.classList.add("has-media"),Q.style.backgroundImage="",Q.style.backgroundPosition="",Q.style.backgroundRepeat="",Q.style.backgroundSize="",Q.mediaEl?.style.removeProperty("opacity");let X=Q.querySelector("fig-input-file[data-generated]");if(X)X.setAttribute("label","Replace"),X.removeAttribute("url");switch(this.#j.scaleMode){case"fill":Q.classList.remove("is-tiled"),Q.setAttribute("fit","cover");break;case"crop":Q.classList.remove("is-tiled"),Q.setAttribute("fit","cover");break;case"fit":Q.classList.remove("is-tiled"),Q.setAttribute("fit","contain");break;case"tile":if(Q.classList.add("is-tiled"),Q.setAttribute("fit","none"),Q.style.backgroundImage=`url(${this.#j.url})`,Q.style.backgroundPosition="top left",Q.style.backgroundSize=`${this.#j.scale}%`,Q.style.backgroundRepeat="repeat",Q.mediaEl)Q.mediaEl.style.opacity="0";break}}#I(Q){if(Q.tagName==="FIG-MEDIA"){if(!this.#J.url){Q.removeAttribute("src"),Q.classList.remove("has-media");return}Q.setAttribute("src",this.#J.url),Q.classList.add("has-media");let X=Q.querySelector("fig-input-file[data-generated]");if(X)X.setAttribute("label","Replace"),X.removeAttribute("url");switch(this.#J.scaleMode){case"fill":case"crop":Q.setAttribute("fit","cover");break;case"fit":Q.setAttribute("fit","contain");break}return}switch(Q.style.objectPosition="center",Q.style.width="100%",Q.style.height="100%",this.#J.scaleMode){case"fill":case"crop":Q.style.objectFit="cover";break;case"fit":Q.style.objectFit="contain";break}}#KQ(){let Q=this.#Q.querySelector('[data-tab="video"]'),X=this.getAttribute("experimental"),Y=X?`experimental="${X}"`:"";Q.innerHTML=`
137
+ <fig-field class="fig-fill-picker-media-header" direction="horizontal">
138
+ <fig-dropdown class="fig-fill-picker-scale-mode" ${Y} value="${this.#J.scaleMode}">
139
+ <option value="fill" selected>Fill</option>
140
+ <option value="fit">Fit</option>
141
+ <option value="crop">Crop</option>
142
+ </fig-dropdown>
143
+ </fig-field>
144
+ <fig-media class="fig-fill-picker-media-preview fig-fill-picker-video-preview" type="video" upload="true" label="Upload from computer" size="auto" aspect-ratio="1/1" fit="cover" checkerboard="true" autoplay="true" muted="true" loop="true"></fig-media>
145
+ `,this.#WQ(Q)}#WQ(Q){let X=Q.querySelector(".fig-fill-picker-scale-mode"),Y=Q.querySelector(".fig-fill-picker-video-preview");X.addEventListener("change",(Z)=>{this.#J.scaleMode=Z.target.value,this.#I(Y),this.#K(),this.#Z()}),Y.addEventListener("loaded",(Z)=>{let $=Z.detail?.src||Y.src;if(!$)return;this.#J.url=$,this.#I(Y),Y.play?.(),this.#K(),this.#Z()}),Y.addEventListener("change",()=>{if(Y.src)return;this.#J.url=null,this.#I(Y),this.#K(),this.#Z()}),this.#I(Y)}#UQ(){let Q=this.#Q.querySelector('[data-tab="webcam"]'),X=this.getAttribute("experimental"),Y=X?`experimental="${X}"`:"";Q.innerHTML=`
146
+ <div class="fig-fill-picker-webcam-preview">
147
+ <div class="fig-fill-picker-checkerboard"></div>
148
+ <video class="fig-fill-picker-webcam-video" autoplay muted playsinline></video>
149
+ <div class="fig-fill-picker-webcam-status">
150
+ <span>Camera access required</span>
151
+ </div>
152
+ </div>
153
+ <fig-field class="fig-fill-picker-webcam-controls" direction="horizontal">
154
+ <fig-dropdown class="fig-fill-picker-camera-select" ${Y} style="display: none;">
155
+ </fig-dropdown>
156
+ <fig-button class="fig-fill-picker-webcam-capture" variant="primary">
157
+ Capture
158
+ </fig-button>
159
+ </fig-field>
160
+ `,this.#zQ(Q)}#zQ(Q){let X=Q.querySelector(".fig-fill-picker-webcam-video"),Y=Q.querySelector(".fig-fill-picker-webcam-status"),Z=Q.querySelector(".fig-fill-picker-webcam-capture"),$=Q.querySelector(".fig-fill-picker-camera-select"),j=async(J=null)=>{try{let K={video:J?{deviceId:{exact:J}}:!0};if(this.#z.stream)this.#z.stream.getTracks().forEach((W)=>W.stop());this.#z.stream=await navigator.mediaDevices.getUserMedia(K),X.srcObject=this.#z.stream,X.style.display="block",Y.style.display="none";let U=(await navigator.mediaDevices.enumerateDevices()).filter((W)=>W.kind==="videoinput");if(U.length>1)$.style.display="block",$.innerHTML=U.map((W,z)=>`<option value="${W.deviceId}">${W.label||`Camera ${z+1}`}</option>`).join("")}catch(K){console.error("Webcam error:",K.name,K.message);let L="Camera access denied";if(K.name==="NotAllowedError")L="Camera permission denied";else if(K.name==="NotFoundError")L="No camera found";else if(K.name==="NotReadableError")L="Camera in use by another app";else if(K.name==="OverconstrainedError")L="Camera constraints not supported";else if(!window.isSecureContext)L="Camera requires secure context";Y.innerHTML=`<span>${L}</span>`,Y.style.display="flex",X.style.display="none"}};this.#T=new MutationObserver(()=>{if(Q.style.display!=="none"&&!this.#z.stream)j()}),this.#T.observe(Q,{attributes:!0,attributeFilter:["style"]}),$.addEventListener("change",(J)=>{j(J.target.value)}),Z.addEventListener("click",()=>{if(!this.#z.stream)return;let J=document.createElement("canvas");J.width=X.videoWidth,J.height=X.videoHeight,J.getContext("2d").drawImage(X,0,0),this.#z.snapshot=J.toDataURL("image/png"),this.#j.url=this.#z.snapshot,this.#W="image",this.#K(),this.#Z(),this.#x("image");let K=this.#Q.querySelector("fig-tabs");K.value="image"})}#l(Q){let X=Q.h/360,Y=Q.s/100,Z=Q.v/100,$,j,J,K=Math.floor(X*6),L=X*6-K,U=Z*(1-Y),W=Z*(1-L*Y),z=Z*(1-(1-L)*Y);switch(K%6){case 0:$=Z,j=z,J=U;break;case 1:$=W,j=Z,J=U;break;case 2:$=U,j=Z,J=z;break;case 3:$=U,j=W,J=Z;break;case 4:$=z,j=U,J=Z;break;case 5:$=Z,j=U,J=W;break}return{r:Math.round($*255),g:Math.round(j*255),b:Math.round(J*255)}}#S(Q){let X=Q.r/255,Y=Q.g/255,Z=Q.b/255,$=Math.max(X,Y,Z),j=Math.min(X,Y,Z),J=$-j,K=0,L=$===0?0:J/$,U=$;if($!==j){switch($){case X:K=(Y-Z)/J+(Y<Z?6:0);break;case Y:K=(Z-X)/J+2;break;case Z:K=(X-Y)/J+4;break}K/=6}return{h:K*360,s:L*100,v:U*100,a:1}}#k(Q){if(!Q||typeof Q.h!=="number"||typeof Q.s!=="number"||typeof Q.v!=="number")return"#D9D9D9";let X=this.#l(Q),Y=(Z)=>{return(isNaN(Z)?217:Math.max(0,Math.min(255,Math.round(Z)))).toString(16).padStart(2,"0")};return`#${Y(X.r)}${Y(X.g)}${Y(X.b)}`}#C(Q){let X=parseInt(Q.slice(1,3),16),Y=parseInt(Q.slice(3,5),16),Z=parseInt(Q.slice(5,7),16);return this.#S({r:X,g:Y,b:Z})}#LQ(Q,X=1){let Y=parseInt(Q.slice(1,3),16),Z=parseInt(Q.slice(3,5),16),$=parseInt(Q.slice(5,7),16);return`rgba(${Y}, ${Z}, ${$}, ${X})`}#RQ(Q,X=1){let Y=+(parseInt(Q.slice(1,3),16)/255).toFixed(4),Z=+(parseInt(Q.slice(3,5),16)/255).toFixed(4),$=+(parseInt(Q.slice(5,7),16)/255).toFixed(4);return`color(display-p3 ${Y} ${Z} ${$} / ${X})`}#qQ(Q){let X=Q.r/255,Y=Q.g/255,Z=Q.b/255,$=Math.max(X,Y,Z),j=Math.min(X,Y,Z),J,K,L=($+j)/2;if($===j)J=K=0;else{let U=$-j;switch(K=L>0.5?U/(2-$-j):U/($+j),$){case X:J=((Y-Z)/U+(Y<Z?6:0))/6;break;case Y:J=((Z-X)/U+2)/6;break;case Z:J=((X-Y)/U+4)/6;break}}return{h:J*360,s:K*100,l:L*100}}#_Q(Q){let X=Q.h/360,Y=Q.s/100,Z=Q.l/100,$,j,J;if(Y===0)$=j=J=Z;else{let K=(W,z,_)=>{if(_<0)_+=1;if(_>1)_-=1;if(_<0.16666666666666666)return W+(z-W)*6*_;if(_<0.5)return z;if(_<0.6666666666666666)return W+(z-W)*(0.6666666666666666-_)*6;return W},L=Z<0.5?Z*(1+Y):Z+Y-Z*Y,U=2*Z-L;$=K(U,L,X+0.3333333333333333),j=K(U,L,X),J=K(U,L,X-0.3333333333333333)}return{r:Math.round($*255),g:Math.round(j*255),b:Math.round(J*255)}}#n(Q){let X=(z)=>{return z=z/255,z<=0.04045?z/12.92:Math.pow((z+0.055)/1.055,2.4)},Y=X(Q.r),Z=X(Q.g),$=X(Q.b),j=0.4122214708*Y+0.5363325363*Z+0.0514459929*$,J=0.2119034982*Y+0.6806995451*Z+0.1073969566*$,K=0.0883024619*Y+0.2817188376*Z+0.6299787005*$,L=Math.cbrt(j),U=Math.cbrt(J),W=Math.cbrt(K);return{l:0.2104542553*L+0.793617785*U-0.0040720468*W,a:1.9779984951*L-2.428592205*U+0.4505937099*W,b:0.0259040371*L+0.7827717662*U-0.808675766*W}}#OQ(Q){let X=this.#n(Q);return{l:X.l,c:Math.sqrt(X.a*X.a+X.b*X.b),h:(Math.atan2(X.b,X.a)*180/Math.PI+360)%360}}#r(Q){let X=Q.l+0.3963377774*Q.a+0.2158037573*Q.b,Y=Q.l-0.1055613458*Q.a-0.0638541728*Q.b,Z=Q.l-0.0894841775*Q.a-1.291485548*Q.b,$=X*X*X,j=Y*Y*Y,J=Z*Z*Z,K=(L)=>{let U=L<=0.0031308?12.92*L:1.055*Math.pow(L,0.4166666666666667)-0.055;return Math.round(Math.max(0,Math.min(1,U))*255)};return{r:K(4.0767416621*$-3.3077115913*j+0.2309699292*J),g:K(-1.2684380046*$+2.6097574011*j-0.3413193965*J),b:K(-0.0041960863*$-0.7034186147*j+1.707614701*J)}}#BQ(Q){let X=Q.h*Math.PI/180;return this.#r({l:Q.l,a:Q.c*Math.cos(X),b:Q.c*Math.sin(X)})}#Z(){this.#K(),this.dispatchEvent(new CustomEvent("input",{bubbles:!0,detail:this.value}))}#_(){this.dispatchEvent(new CustomEvent("change",{bubbles:!0,detail:this.value}))}get value(){let Q={type:this.#W,colorSpace:this.#L};switch(this.#W){case"solid":return{...Q,color:this.#k(this.#Y),alpha:this.#Y.a,hsv:{...this.#Y}};case"gradient":return{...Q,gradient:F(this.#X),css:this.#i()};case"image":return{...Q,image:{...this.#j}};case"video":return{...Q,video:{...this.#J}};case"webcam":return{...Q,image:{url:this.#z.snapshot,scaleMode:"fill",scale:50}};default:return{...Q,...this.#A[this.#W]}}}set value(Q){if(typeof Q==="string")this.setAttribute("value",Q);else this.setAttribute("value",JSON.stringify(Q))}attributeChangedCallback(Q,X,Y){if(X===Y)return;switch(Q){case"value":if(this.#h(),this.#K(),this.#Q){if(!this.#F){if(this.#q(),this.#D(),this.#N)this.#N.setAttribute("value",this.#Y.h);if(this.#B)this.#B.setAttribute("value",this.#Y.a*100),this.#B.setAttribute("color",this.#k(this.#Y))}}break;case"disabled":break}}}customElements.define("fig-fill-picker",N);