@react-native/debugger-frontend
Version:
Debugger frontend for React Native based on Chrome DevTools
1 lines • 59.6 kB
JavaScript
import*as e from"../../core/sdk/sdk.js";import*as t from"../../ui/components/icon_button/icon_button.js";import*as i from"../../ui/legacy/legacy.js";import*as n from"../../ui/visual_logging/visual_logging.js";import*as s from"../../core/common/common.js";import*as r from"../../core/host/host.js";import*as o from"../../core/i18n/i18n.js";import*as a from"../../core/platform/platform.js";import*as l from"../../ui/legacy/components/inline_editor/inline_editor.js";const d="devtools_animations",c="__devtools_report_scroll_position__",h=e=>`__devtools_scroll_listener_${e}__`;async function m(t,i){const n=t.domModel().target().model(e.ResourceTreeModel.ResourceTreeModel),s=t.domModel().target().pageAgent();for(const e of n.frames()){const{executionContextId:n}=await s.invoke_createIsolatedWorld({frameId:e.id,worldName:i}),r=await t.resolveToObject(void 0,n);if(r)return r}return null}class u{#e;#t;#i;static lastAddedListenerId=0;constructor(e){this.#e=e,this.#t=new Map}async#n(){if(this.#i)return;this.#i=e=>{const{name:t,payload:i}=e.data;if(t!==c)return;const{scrollTop:n,scrollLeft:s,id:r}=JSON.parse(i),o=this.#t.get(r);o&&o({scrollTop:n,scrollLeft:s})};const t=this.#e.domModel().target().model(e.RuntimeModel.RuntimeModel);await t.addBinding({name:c,executionContextName:d}),t.addEventListener(e.RuntimeModel.Events.BindingCalled,this.#i)}async#s(){if(!this.#i)return;const t=this.#e.domModel().target().model(e.RuntimeModel.RuntimeModel);await t.removeBinding({name:c}),t.removeEventListener(e.RuntimeModel.Events.BindingCalled,this.#i),this.#i=void 0}async addScrollEventListener(t){u.lastAddedListenerId++;const i=u.lastAddedListenerId;this.#t.set(i,t),this.#i||await this.#n();const n=await m(this.#e,d);return n?(await n.callFunction((function(e,t,i){if("scrollingElement"in this&&!this.scrollingElement)return;const n="scrollingElement"in this?this.scrollingElement:this;this[i]=()=>{globalThis[t](JSON.stringify({scrollTop:n.scrollTop,scrollLeft:n.scrollLeft,id:e}))},this.addEventListener("scroll",this[i],!0)}),[i,c,h(i)].map((t=>e.RemoteObject.RemoteObject.toCallArgument(t)))),n.release(),i):null}async removeScrollEventListener(t){const i=await m(this.#e,d);i&&(await i.callFunction((function(e){this.removeEventListener("scroll",this[e]),delete this[e]}),[h(t)].map((t=>e.RemoteObject.RemoteObject.toCallArgument(t)))),i.release(),this.#t.delete(t),0===this.#t.size&&await this.#s())}async scrollTop(){return this.#e.callFunction((function(){if("scrollingElement"in this)return this.scrollingElement?this.scrollingElement.scrollTop:0;return this.scrollTop})).then((e=>e?.value??null))}async scrollLeft(){return this.#e.callFunction((function(){if("scrollingElement"in this)return this.scrollingElement?this.scrollingElement.scrollLeft:0;return this.scrollLeft})).then((e=>e?.value??null))}async setScrollTop(e){await this.#e.callFunction((function(e){if("scrollingElement"in this){if(!this.scrollingElement)return;this.scrollingElement.scrollTop=e}else this.scrollTop=e}),[e])}async setScrollLeft(e){await this.#e.callFunction((function(e){if("scrollingElement"in this){if(!this.scrollingElement)return;this.scrollingElement.scrollLeft=e}else this.scrollLeft=e}),[e])}async verticalScrollRange(){return this.#e.callFunction((function(){if("scrollingElement"in this)return this.scrollingElement?this.scrollingElement.scrollHeight-this.scrollingElement.clientHeight:0;return this.scrollHeight-this.clientHeight})).then((e=>e?.value??null))}async horizontalScrollRange(){return this.#e.callFunction((function(){if("scrollingElement"in this)return this.scrollingElement?this.scrollingElement.scrollWidth-this.scrollingElement.clientWidth:0;return this.scrollWidth-this.clientWidth})).then((e=>e?.value??null))}}var p,f=Object.freeze({__proto__:null,AnimationDOMNode:u});function b(e,t){const i=e.viewOrScrollTimeline(),n=t.viewOrScrollTimeline();return i?Boolean(n&&i.sourceNodeId===n.sourceNodeId&&i.axis===n.axis):!n&&e.startTime()===t.startTime()}class g extends e.SDKModel.SDKModel{runtimeModel;agent;#r;animationGroups;#o;playbackRate;#a;#l;#d;constructor(t){super(t),this.runtimeModel=t.model(e.RuntimeModel.RuntimeModel),this.agent=t.animationAgent(),t.registerAnimationDispatcher(new A(this)),this.#r=new Map,this.animationGroups=new Map,this.#o=new Set,this.playbackRate=1;t.model(e.ResourceTreeModel.ResourceTreeModel).addEventListener(e.ResourceTreeModel.Events.PrimaryPageChanged,this.reset,this);const i=t.model(e.ScreenCaptureModel.ScreenCaptureModel);i&&(this.#a=new k(this,i)),this.#d=s.Debouncer.debounce((()=>{for(;this.#o.size;)this.matchExistingGroups(this.createGroupFromPendingAnimations())}),100)}reset(){this.#r.clear(),this.animationGroups.clear(),this.#o.clear(),this.dispatchEventToListeners(p.ModelReset)}async devicePixelRatio(){const e=await this.target().runtimeAgent().invoke_evaluate({expression:"window.devicePixelRatio"});return"number"===e?.result.type?e?.result.value??1:1}animationCanceled(e){this.#o.delete(e)}async animationUpdated(e){let t,i;for(const n of this.animationGroups.values())if(i=n.animations().find((t=>t.id()===e.id)),i){t=n;break}i&&t&&(await i.setPayload(e),this.dispatchEventToListeners(p.AnimationGroupUpdated,t))}async animationStarted(e){if(!e.source||!e.source.backendNodeId)return;const t=await y.parsePayload(this,e),i=t.source().keyframesRule();"WebAnimation"===t.type()&&i&&0===i.keyframes().length?this.#o.delete(t.id()):(this.#r.set(t.id(),t),this.#o.add(t.id())),this.#d()}matchExistingGroups(e){let t=null;for(const i of this.animationGroups.values()){if(i.matches(e)){t=i,i.rebaseTo(e);break}if(i.shouldInclude(e)){t=i,i.appendAnimations(e.animations());break}}return t?this.dispatchEventToListeners(p.AnimationGroupUpdated,t):(this.animationGroups.set(e.id(),e),this.#a&&this.#a.captureScreenshots(e.finiteDuration(),e.screenshotsInternal),this.dispatchEventToListeners(p.AnimationGroupStarted,e)),Boolean(t)}createGroupFromPendingAnimations(){console.assert(this.#o.size>0);const e=this.#o.values().next().value;this.#o.delete(e);const t=this.#r.get(e);if(!t)throw new Error("Unable to locate first animation");const i=[t],n=new Set;for(const e of this.#o){const s=this.#r.get(e);b(t,s)?i.push(s):n.add(e)}return this.#o=n,i.sort(((e,t)=>e.startTime()-t.startTime())),new T(this,e,i)}setPlaybackRate(e){this.playbackRate=e,this.agent.invoke_setPlaybackRate({playbackRate:e})}releaseAnimations(e){this.agent.invoke_releaseAnimations({animations:e})}async suspendModel(){this.reset(),await this.agent.invoke_disable()}async resumeModel(){this.#l&&await this.agent.invoke_enable()}async ensureEnabled(){this.#l||(await this.agent.invoke_enable(),this.#l=!0)}}!function(e){e.AnimationGroupStarted="AnimationGroupStarted",e.AnimationGroupUpdated="AnimationGroupUpdated",e.ModelReset="ModelReset"}(p||(p={}));class y{#c;#h;#m;#u;constructor(e){this.#c=e}static async parsePayload(e,t){const i=new y(e);return await i.setPayload(t),i}async setPayload(e){if(e.viewOrScrollTimeline){const t=await this.#c.devicePixelRatio();e.viewOrScrollTimeline.startOffset&&(e.viewOrScrollTimeline.startOffset/=t),e.viewOrScrollTimeline.endOffset&&(e.viewOrScrollTimeline.endOffset/=t)}this.#h=e,this.#m&&e.source?this.#m.setPayload(e.source):!this.#m&&e.source&&(this.#m=new v(this.#c,e.source))}percentageToPixels(e,t){const{startOffset:i,endOffset:n}=t;if(void 0===i||void 0===n)throw new Error("startOffset or endOffset does not exist in viewOrScrollTimeline");return e/100*(n-i)}viewOrScrollTimeline(){return this.#h.viewOrScrollTimeline}id(){return this.#h.id}name(){return this.#h.name}paused(){return this.#h.pausedState}playState(){return this.#u||this.#h.playState}setPlayState(e){this.#u=e}playbackRate(){return this.#h.playbackRate}startTime(){const e=this.viewOrScrollTimeline();return e?this.percentageToPixels(this.playbackRate()>0?this.#h.startTime:100-this.#h.startTime,e)+(this.viewOrScrollTimeline()?.startOffset??0):this.#h.startTime}iterationDuration(){const e=this.viewOrScrollTimeline();return e?this.percentageToPixels(this.source().duration(),e):this.source().duration()}endTime(){return this.source().iterations?this.viewOrScrollTimeline()?this.startTime()+this.iterationDuration()*this.source().iterations():this.startTime()+this.source().delay()+this.source().duration()*this.source().iterations()+this.source().endDelay():1/0}finiteDuration(){const e=Math.min(this.source().iterations(),3);return this.viewOrScrollTimeline()?this.iterationDuration()*e:this.source().delay()+this.source().duration()*e}currentTime(){const e=this.viewOrScrollTimeline();return e?this.percentageToPixels(this.#h.currentTime,e):this.#h.currentTime}source(){return this.#m}type(){return this.#h.type}overlaps(e){if(!this.source().iterations()||!e.source().iterations())return!0;const t=this.startTime()<e.startTime()?this:e,i=t===this?e:this;return t.endTime()>=i.startTime()}delayOrStartTime(){return this.viewOrScrollTimeline()?this.startTime():this.source().delay()}setTiming(e,t){this.#m.node().then((i=>{if(!i)throw new Error("Unable to find node");this.updateNodeStyle(e,t,i)})),this.#m.durationInternal=e,this.#m.delayInternal=t,this.#c.agent.invoke_setTiming({animationId:this.id(),duration:e,delay:t})}updateNodeStyle(e,t,i){let n;if("CSSTransition"===this.type())n="transition-";else{if("CSSAnimation"!==this.type())return;n="animation-"}if(!i.id)throw new Error("Node has no id");const s=i.domModel().cssModel();s.setEffectivePropertyValueForNode(i.id,n+"duration",e+"ms"),s.setEffectivePropertyValueForNode(i.id,n+"delay",t+"ms")}async remoteObjectPromise(){const e=await this.#c.agent.invoke_resolveAnimation({animationId:this.id()});return e?this.#c.runtimeModel.createRemoteObject(e.remoteObject):null}cssId(){return this.#h.cssId||""}}class v{#c;#p;delayInternal;durationInternal;#f;#b;constructor(e,t){this.#c=e,this.setPayload(t)}setPayload(e){this.#p=e,!this.#f&&e.keyframesRule?this.#f=new w(e.keyframesRule):this.#f&&e.keyframesRule&&this.#f.setPayload(e.keyframesRule),this.delayInternal=e.delay,this.durationInternal=e.duration}delay(){return this.delayInternal}endDelay(){return this.#p.endDelay}iterations(){return this.delay()||this.endDelay()||this.duration()?this.#p.iterations||1/0:0}duration(){return this.durationInternal}direction(){return this.#p.direction}fill(){return this.#p.fill}node(){return this.#b||(this.#b=new e.DOMModel.DeferredDOMNode(this.#c.target(),this.backendNodeId())),this.#b.resolvePromise()}deferredNode(){return new e.DOMModel.DeferredDOMNode(this.#c.target(),this.backendNodeId())}backendNodeId(){return this.#p.backendNodeId}keyframesRule(){return this.#f||null}easing(){return this.#p.easing}}class w{#p;#g;constructor(e){this.setPayload(e)}setPayload(e){this.#p=e,this.#g?this.#p.keyframes.forEach(((e,t)=>{this.#g[t]?.setPayload(e)})):this.#g=this.#p.keyframes.map((e=>new x(e)))}name(){return this.#p.name}keyframes(){return this.#g}}class x{#p;#y;constructor(e){this.setPayload(e)}setPayload(e){this.#p=e,this.#y=e.offset}offset(){return this.#y}setOffset(e){this.#y=100*e+"%"}offsetAsNumber(){return parseFloat(this.#y)/100}easing(){return this.#p.easing}}class T{#c;#v;#w;#x;#T;screenshotsInternal;#A;constructor(e,t,i){this.#c=e,this.#v=t,this.#x=i,this.#T=!1,this.screenshotsInternal=[],this.#A=[]}isScrollDriven(){return Boolean(this.#x[0]?.viewOrScrollTimeline())}id(){return this.#v}animations(){return this.#x}release(){this.#c.animationGroups.delete(this.id()),this.#c.releaseAnimations(this.animationIds())}animationIds(){return this.#x.map((function(e){return e.id()}))}startTime(){return this.#x[0].startTime()}groupDuration(){let e=0;for(const t of this.#x)e=Math.max(e,t.delayOrStartTime()+t.iterationDuration());return e}finiteDuration(){let e=0;for(let t=0;t<this.#x.length;++t)e=Math.max(e,this.#x[t].finiteDuration());return e}scrollOrientation(){const e=this.#x[0]?.viewOrScrollTimeline();return e?e.axis:null}async scrollNode(){if(this.#w)return this.#w;if(!this.isScrollDriven())return null;const t=this.#x[0]?.viewOrScrollTimeline()?.sourceNodeId;if(!t)return null;const i=new e.DOMModel.DeferredDOMNode(this.#c.target(),t),n=await i.resolvePromise();return n?(this.#w=new u(n),this.#w):null}seekTo(e){this.#c.agent.invoke_seekAnimations({animations:this.animationIds(),currentTime:e})}paused(){return this.#T}togglePause(e){e!==this.#T&&(this.#T=e,this.#c.agent.invoke_setPaused({animations:this.animationIds(),paused:e}))}currentTimePromise(){let e=null;for(const t of this.#x)(!e||t.endTime()>e.endTime())&&(e=t);if(!e)throw new Error("No longest animation found");return this.#c.agent.invoke_getCurrentTime({id:e.id()}).then((({currentTime:e})=>e||0))}matches(e){function t(e){const t=(e.viewOrScrollTimeline()?.sourceNodeId??"")+(e.viewOrScrollTimeline()?.axis??"");return("WebAnimation"===e.type()?e.type()+e.id():e.cssId())+t}if(this.#x.length!==e.#x.length)return!1;const i=this.#x.map(t).sort(),n=e.#x.map(t).sort();for(let e=0;e<i.length;e++)if(i[e]!==n[e])return!1;return!0}shouldInclude(e){const[t]=e.#x,[i]=this.#x;return b(i,t)}appendAnimations(e){this.#x.push(...e)}rebaseTo(e){this.#c.releaseAnimations(this.animationIds()),this.#x=e.#x,this.#w=void 0}screenshots(){for(let e=0;e<this.screenshotsInternal.length;++e){const t=new Image;t.src="data:image/jpeg;base64,"+this.screenshotsInternal[e],this.#A.push(t)}return this.screenshotsInternal=[],this.#A}}class A{#c;constructor(e){this.#c=e}animationCreated(e){}animationCanceled({id:e}){this.#c.animationCanceled(e)}animationStarted({animation:e}){this.#c.animationStarted(e)}animationUpdated({animation:e}){this.#c.animationUpdated(e)}}class k{#k;#I;#c;#M;#S;#C;constructor(e,t){this.#k=[],this.#I=t,this.#c=e,this.#c.addEventListener(p.ModelReset,this.stopScreencast,this)}captureScreenshots(e,t){const i=Math.min(e/this.#c.playbackRate,3e3),n=i+window.performance.now();this.#k.push({endTime:n,screenshots:t}),(!this.#S||n>this.#S)&&(clearTimeout(this.#M),this.#M=window.setTimeout(this.stopScreencast.bind(this),i),this.#S=n),this.#C||(this.#C=!0,this.#I.startScreencast("jpeg",80,void 0,300,2,this.screencastFrame.bind(this),(e=>{})))}screencastFrame(e,t){if(!this.#C)return;const i=window.performance.now();this.#k=this.#k.filter((function(e){return e.endTime>=i}));for(const t of this.#k)t.screenshots.push(e)}stopScreencast(){this.#C&&(this.#M=void 0,this.#S=void 0,this.#k=[],this.#C=!1,this.#I.stopScreencast())}}e.SDKModel.SDKModel.register(g,{capabilities:2,autostart:!1});var I=Object.freeze({__proto__:null,AnimationModel:g,get Events(){return p},AnimationImpl:y,AnimationEffect:v,KeyframesRule:w,KeyframeStyle:x,AnimationGroup:T,AnimationDispatcher:A,ScreenshotCapture:k});const M=new CSSStyleSheet;M.replaceSync("img{max-height:300px;border-radius:2px}.animation-progress{position:absolute;height:2px;bottom:0;left:0;background:var(--legacy-selection-bg-color)}\n/*# sourceURL=animationScreenshotPopover.css */\n");class S extends i.Widget.VBox{#P;#R;#E;#L;#G;#B;constructor(e){super(!0),console.assert(e.length>0),this.contentElement.classList.add("animation-screenshot-popover"),this.#P=e;for(const t of e)this.contentElement.appendChild(t),t.style.display="none";this.#R=0,this.#E=0,this.#P[0].style.display="block",this.#L=this.contentElement.createChild("div","animation-progress")}wasShown(){this.#R=this.contentElement.window().requestAnimationFrame(this.changeFrame.bind(this)),this.registerCSSFiles([M])}willHide(){this.contentElement.window().cancelAnimationFrame(this.#R),this.#B=void 0}changeFrame(){if(this.#R=this.contentElement.window().requestAnimationFrame(this.changeFrame.bind(this)),this.#B)return void this.#B--;if(this.#G=!this.#G,!this.#G)return;const e=this.#P.length;this.#P[this.#E%e].style.display="none",this.#E++,this.#P[this.#E%e].style.display="block",this.#E%e==e-1&&(this.#B=50),this.#L.style.width=(this.#E%e+1)/e*100+"%"}}var C=Object.freeze({__proto__:null,AnimationScreenshotPopover:S});const P=new CSSStyleSheet;P.replaceSync(':host{overflow:hidden;--timeline-controls-width:150px}.animation-node-row{width:100%;display:flex;border-bottom:1px dashed var(--sys-color-divider)}.animation-node-description{padding-left:8px;overflow:hidden;position:relative;background-color:var(--sys-color-cdt-base-container);display:flex;flex-direction:column;justify-content:space-around;align-items:flex-start;white-space:nowrap;flex:0 0 var(--timeline-controls-width);z-index:1}.animation-node-description > *{flex:0 0 auto}.animation-timeline-row{height:32px;position:relative}path.animation-keyframe{fill-opacity:0.2}.animation-node-selected path.animation-keyframe,\nsvg.animation-ui g:first-child:hover path.animation-keyframe{fill-opacity:0.4}line.animation-line{stroke-width:2px;stroke-linecap:round;fill:none}line.animation-delay-line{stroke-width:2px;stroke-dasharray:6,4}line.animation-delay-line.animation-fill{stroke-dasharray:none}circle.animation-keyframe-point{fill:var(--sys-color-cdt-base-container)}circle.animation-endpoint,\ncircle.animation-keyframe-point{stroke-width:2px;transition:transform 100ms cubic-bezier(0,0,0.2,1);transform:scale(1);transform-box:fill-box;transform-origin:50% 50%}circle.animation-endpoint:active,\ncircle.animation-keyframe-point:active{transform:scale(1)}.animation-ui circle.animation-endpoint:hover,\n.animation-ui circle.animation-keyframe-point:hover{transform:scale(1.2)}.animation-name{position:absolute;top:8px;color:var(--sys-color-on-surface);text-align:center;margin-left:-8px;white-space:nowrap}.animation-timeline-toolbar-container{display:flex;background-color:var(--sys-color-cdt-base-container);border-bottom:1px solid var(--sys-color-divider);flex:0 0 auto}.animation-timeline-toolbar{display:inline-block}.animation-timeline-header{height:28px;border-bottom:1px solid var(--sys-color-divider);flex-shrink:0;display:flex}.animation-timeline-header::after{content:"";height:calc(100% - 48px - 28px);position:absolute;width:var(--timeline-controls-width);left:0;margin-top:28px;background-color:var(--sys-color-cdt-base-container);z-index:0;border-right:1px solid var(--sys-color-divider)}.animation-controls{flex:0 0 var(--timeline-controls-width);position:relative;display:flex;justify-content:flex-end;padding-right:8px}.animation-timeline-current-time{flex:0 0 auto;line-height:28px;margin-right:5px}.animation-grid-header{flex:1 0 auto;z-index:2}.animation-grid-header.scrubber-enabled{cursor:pointer}.animation-timeline-buffer,\n.animation-timeline-buffer-hint{height:48px;flex:0 0 auto;border-bottom:1px solid var(--sys-color-divider);display:flex;padding:0 2px}.animation-timeline-buffer:empty,\n.animation-timeline-buffer-hint{display:none}.animation-timeline-buffer:empty ~ .animation-timeline-buffer-hint{align-items:center;justify-content:center;font-size:14px;z-index:101;display:flex}.animation-time-overlay{background-color:var(--sys-color-on-surface);opacity:5%;position:absolute;height:100%;width:100%;z-index:-1}.animation-timeline-end > .animation-time-overlay{visibility:hidden}.animation-scrubber{opacity:100%;position:absolute;left:10px;height:100%;width:100%;top:28px;border-left:1px solid var(--sys-color-error);z-index:2}.animation-scrubber-line{width:11px;background:linear-gradient(to right,transparent 5px,var(--sys-color-error) 5px,var(--sys-color-error) 6px,transparent 6px);position:absolute;top:-28px;height:28px;left:-6px;padding:0 5px;z-index:3}.animation-scrubber-head{width:7px;height:7px;transform:rotate(45deg);background:var(--sys-color-error);position:absolute;left:2px;top:1px;z-index:4}.grid-overflow-wrapper{position:absolute;left:calc(var(--timeline-controls-width) - 10px);top:76px;z-index:1;overflow:hidden;width:100%;height:100%}svg.animation-timeline-grid{position:absolute;left:0;top:0;right:0;bottom:0;width:100%;height:100%}rect.animation-timeline-grid-line{fill:var(--sys-color-divider)}.animation-timeline-row > svg.animation-ui{position:absolute}.animation-node-timeline{flex-grow:1}.animation-node-description > div{position:absolute;top:50%;transform:translateY(-50%);max-height:100%}.animation-node-removed{filter:saturate(0);cursor:not-allowed}.animation-node-removed-overlay{width:100%;height:100%;z-index:100;cursor:not-allowed}svg.animation-ui g:first-child{opacity:100%}svg.animation-ui circle:focus-visible,\nsvg.animation-ui path:focus-visible{outline:2px solid -webkit-focus-ring-color}.animation-tail-iterations{opacity:50%}.animation-keyframe-step line{stroke-width:2;stroke-opacity:0.3}text.animation-timeline-grid-label{font-size:10px;fill:var(--sys-color-token-subtle);text-anchor:middle}@keyframes --full-opacity-for-screenshots-container{from{opacity:100%}to{opacity:100%}}.preview-ui-container{position:relative;& .screenshot-arrow{background-image:var(--image-file-popoverArrows);background-position:0 76px;width:19px;height:19px;position:absolute;left:6px;top:-19px;z-index:100;pointer-events:none}& .screenshots-container{position:absolute;display:none;opacity:0%;left:6px;top:100%;z-index:100;border:1px solid transparent;box-shadow:var(--drop-shadow);border-radius:2px;max-width:220px;max-height:220px}& .screenshots-container.to-the-left{left:unset;right:6px}& .screenshots-container.to-the-left .screenshot-arrow{left:unset;right:6px}&:hover .screenshots-container:not(.no-screenshots){display:block;animation-name:--full-opacity-for-screenshots-container;animation-duration:0s;animation-delay:0.2s;animation-fill-mode:forwards}&:hover .screenshots-container:not(.no-screenshots):hover{display:none}&:has(.selected):hover .screenshots-container:not(.no-screenshots){display:none}}.animation-timeline-rows,\n.animation-timeline-rows-hint{flex-grow:1;overflow-y:auto;z-index:1;overflow-x:hidden}.animation-timeline-rows-hint{display:none}.animation-timeline-buffer:not(:empty) ~ .animation-timeline-rows:empty{flex-grow:0}.animation-timeline-buffer:not(:empty) ~ .animation-timeline-rows:empty ~ .animation-timeline-rows-hint{font-size:14px;display:flex;align-items:center;justify-content:center;margin-left:var(--timeline-controls-width);padding:10px}.toolbar.animation-controls-toolbar{flex:0 0 auto}.animation-node-row.animation-node-selected{background-color:var(--sys-color-state-ripple-primary)}.animation-node-selected > .animation-node-description{background-color:var(--sys-color-tonal-container)}.animation-buffer-preview{height:40px;margin:4px 2px;background-color:var(--sys-color-neutral-container);border:1px solid transparent;border-radius:2px;flex:1 1;padding:4px;max-width:100px;animation:newGroupAnim 200ms;position:relative}.animation-buffer-preview.no-animation{animation:none}.animation-buffer-preview .preview-icon{position:absolute;width:14px;height:14px;right:1px;bottom:2px;opacity:60%}.animation-buffer-preview-animation{width:100%;height:100%;border-radius:2px 0 0 2px;position:absolute;top:0;left:0;background:var(--sys-color-tonal-container);opacity:0%;border-right:1px solid var(--sys-color-divider)}.animation-buffer-preview:focus-visible{outline:-webkit-focus-ring-color auto 5px}.animation-buffer-preview.selected .preview-icon{opacity:100%}.animation-buffer-preview:not(.selected):focus-visible,\n.animation-buffer-preview:not(.selected):hover{background-color:var(--sys-color-surface-variant);& .preview-icon{opacity:80%}}.animation-buffer-preview.selected{background-color:var(--sys-color-tonal-container)}.animation-paused{align-items:center;justify-content:center;display:none}.animation-paused::before,\n.animation-paused::after{content:"";background:var(--sys-color-cdt-base-container);width:7px;height:20px;border-radius:2px;margin:2px;border:1px solid var(--sys-color-divider)}.animation-buffer-preview.paused .animation-paused{display:flex}.animation-buffer-preview > svg > line{stroke-width:1px}.animation-buffer-preview.selected > svg > line{stroke:var(--sys-color-on-tonal-container)!important}@keyframes newGroupAnim{from{clip-path:polygon(0% 0%,0% 100%,50% 100%,50% 0%)}to{clip-path:polygon(0% 0%,0% 100%,100% 100%,100% 0%)}}.animation-playback-rate-control{margin:4px 0 4px 2px;display:flex;width:120px}.animation-playback-rate-button{border-width:1px;border-style:solid;border-color:var(--sys-color-tonal-outline);border-right-width:0;color:var(--sys-color-on-surface);display:inline-block;margin-right:-1px;padding:1px 4px;background-color:transparent;flex:1 0 auto;text-align:center}.animation-playback-rate-button:first-child{border-radius:4px 0 0 4px}.animation-playback-rate-button:last-child{border-radius:0 4px 4px 0;border-right-width:1px}.animation-playback-rate-button.selected{color:var(--sys-color-on-tonal-container);background-color:var(--sys-color-tonal-container);border-color:var(--sys-color-tonal-container);z-index:1}.animation-playback-rate-button.selected:focus-visible{color:var(--sys-color-on-surface)}.animation-playback-rate-button:focus-visible{outline:2px solid var(--sys-color-primary);outline-offset:2px}.animation-playback-rate-button:not(.selected):not([disabled]):hover{background:var(--sys-color-state-hover-on-subtle)}.animation-playback-rate-button[disabled]{background:unset;border-color:var(--sys-color-state-disabled);color:var(--sys-color-state-disabled)}.animation-remove-button{position:absolute;top:-3px;right:-3px;background:var(--sys-color-token-subtle);border-radius:12px;border:0;height:16px;width:16px;z-index:100;display:none;padding:0;& > devtools-icon{height:16px;width:16px;color:var(--sys-color-cdt-base-container)}&:hover{background-color:var(--sys-color-on-surface)}}.animation-buffer-preview:hover .animation-remove-button{display:flex}.timeline-controls-resizer{position:absolute;width:6px;height:100%;left:var(--timeline-controls-width);top:104px;z-index:3;margin-left:-4px}@media (forced-colors: active){.animation-playback-rate-button.selected,\n .animation-playback-rate-button.selected:first-child,\n .animation-playback-rate-button.selected:first-child:focus-visible,\n .animation-playback-rate-button:focus-visible{forced-color-adjust:none;color:HighlightText;background-color:Highlight}.animation-node-description:focus-visible{background-color:var(--sys-color-cdt-base-container);forced-color-adjust:none}.monospace{forced-color-adjust:auto}}\n/*# sourceURL=animationTimeline.css */\n');const R={selectAnEffectAboveToInspectAnd:"Select an effect above to inspect and modify.",clearAll:"Clear all",pauseAll:"Pause all",playbackRates:"Playback rates",playbackRatePlaceholder:"{PH1}%",pause:"Pause",setSpeedToS:"Set speed to {PH1}",animationPreviews:"Animation previews",waitingForAnimations:"Waiting for animations...",replayTimeline:"Replay timeline",resumeAll:"Resume all",playTimeline:"Play timeline",pauseTimeline:"Pause timeline",animationPreviewS:"Animation Preview {PH1}"},E=o.i18n.registerUIStrings("panels/animation/AnimationTimeline.ts",R),L=o.i18n.getLocalizedString.bind(void 0,E),G=new WeakMap,B=new WeakMap;let D;class O extends i.Widget.VBox{#D;#O;#U;#N;#F=[];#z;#_;#j;#H;#W;#V;#K;#X;#$;#q;#Q;#J;#Y;#Z;#ee;#te;#ie;#ne;#se;#re;#oe;#ae;#le;#de;#ce;#he;#me;#ue;#pe;#fe;#be;#ge=new s.Throttler.Throttler(10);#ye=new s.Throttler.Throttler(10);#ve=!1;constructor(){super(!0),this.element.classList.add("animations-timeline"),this.element.setAttribute("jslog",`${n.panel("animations").track({resize:!0})}`),this.#ue=this.contentElement.createChild("div","timeline-controls-resizer"),this.#D=this.contentElement.createChild("div","grid-overflow-wrapper"),this.#O=i.UIUtils.createSVGChild(this.#D,"svg","animation-timeline-grid"),this.#U=1,this.#N=!1,this.#he=!1,this.createHeader(),this.#z=this.contentElement.createChild("div","animation-timeline-rows"),this.#z.setAttribute("jslog",`${n.section("animations")}`);this.contentElement.createChild("div","animation-timeline-rows-hint").textContent=L(R.selectAnEffectAboveToInspectAnd),this.#$=100,this.#q=this.#$,this.#J=new Map,this.#Y=[],this.#Z=[],this.#be=[],this.#ee=new Map,this.#te=new Map,this.#Q=150,this.element.style.setProperty("--timeline-controls-width",`${this.#Q}px`),e.TargetManager.TargetManager.instance().addModelListener(e.DOMModel.DOMModel,e.DOMModel.Events.NodeRemoved,(e=>this.markNodeAsRemoved(e.data.node)),this,{scoped:!0}),e.TargetManager.TargetManager.instance().observeModels(g,this,{scoped:!0}),i.Context.Context.instance().addFlavorChangeListener(e.DOMModel.DOMNode,this.nodeChanged,this),this.#we()}static instance(e){return D&&!e?.forceNew||(D=new O),D}#we(){let e;i.UIUtils.installDragHandle(this.#ue,(t=>(e=t.clientX,!0)),(t=>{if(void 0===e)return;const i=this.#Q+t.clientX-e;this.#Q=Math.min(Math.max(i,120),720),e=t.clientX,this.element.style.setProperty("--timeline-controls-width",this.#Q+"px"),this.onResize()}),(()=>{e=void 0}),"ew-resize")}get previewMap(){return this.#ee}get uiAnimations(){return this.#Y}get groupBuffer(){return this.#Z}wasShown(){if(!this.#ve){for(const t of e.TargetManager.TargetManager.instance().models(g,{scoped:!0}))this.addEventListeners(t);this.registerCSSFiles([P]),this.#ve=!0}}modelAdded(e){this.isShowing()&&this.addEventListeners(e)}modelRemoved(e){this.removeEventListeners(e)}addEventListeners(e){e.ensureEnabled(),e.addEventListener(p.AnimationGroupStarted,this.animationGroupStarted,this),e.addEventListener(p.AnimationGroupUpdated,this.animationGroupUpdated,this),e.addEventListener(p.ModelReset,this.reset,this)}removeEventListeners(e){e.removeEventListener(p.AnimationGroupStarted,this.animationGroupStarted,this),e.removeEventListener(p.AnimationGroupUpdated,this.animationGroupUpdated,this),e.removeEventListener(p.ModelReset,this.reset,this)}nodeChanged(){for(const e of this.#J.values())e.nodeChanged()}createScrubber(){return this.#H=document.createElement("div"),this.#H.classList.add("animation-scrubber"),this.#H.classList.add("hidden"),this.#ie=this.#H.createChild("div","animation-scrubber-line"),this.#ie.createChild("div","animation-scrubber-head"),this.#H.createChild("div","animation-time-overlay"),this.#H}createHeader(){const e=this.contentElement.createChild("div","animation-timeline-toolbar-container");e.setAttribute("jslog",`${n.toolbar()}`);const t=new i.Toolbar.Toolbar("animation-timeline-toolbar",e);this.#V=new i.Toolbar.ToolbarButton(L(R.clearAll),"clear",void 0,"animations.clear"),this.#V.addEventListener("Click",(()=>{r.userMetrics.actionTaken(r.UserMetrics.Action.AnimationGroupsCleared),this.reset()})),t.appendToolbarItem(this.#V),t.appendSeparator(),this.#ne=new i.Toolbar.ToolbarToggle(L(R.pauseAll),"pause","resume","animations.pause-resume-all"),this.#ne.addEventListener("Click",(()=>{this.togglePauseAll()})),t.appendToolbarItem(this.#ne);const s=e.createChild("div","animation-playback-rate-control");s.addEventListener("keydown",this.handlePlaybackRateControlKeyDown.bind(this)),i.ARIAUtils.markAsListBox(s),i.ARIAUtils.setLabel(s,L(R.playbackRates)),this.#_=[];for(const e of U){const t=s.createChild("button","animation-playback-rate-button");t.textContent=e?L(R.playbackRatePlaceholder,{PH1:100*e}):L(R.pause),t.setAttribute("jslog",`${n.action().context("animations.playback-rate-"+100*e).track({click:!0,keydown:"ArrowUp|ArrowDown|ArrowLeft|ArrowRight"})}`),B.set(t,e),t.addEventListener("click",this.setPlaybackRate.bind(this,e)),i.ARIAUtils.markAsOption(t),i.Tooltip.Tooltip.install(t,L(R.setSpeedToS,{PH1:t.textContent})),t.tabIndex=-1,this.#_.push(t)}this.updatePlaybackControls(),this.#j=this.contentElement.createChild("div","animation-timeline-buffer"),this.#j.setAttribute("jslog",`${n.section("film-strip")}`),i.ARIAUtils.markAsListBox(this.#j),i.ARIAUtils.setLabel(this.#j,L(R.animationPreviews));this.contentElement.createChild("div","animation-timeline-buffer-hint").textContent=L(R.waitingForAnimations);const o=this.contentElement.createChild("div","animation-timeline-header"),a=o.createChild("div","animation-controls");this.#W=a.createChild("div","animation-timeline-current-time monospace");const l=new i.Toolbar.Toolbar("animation-controls-toolbar",a);return this.#se=new i.Toolbar.ToolbarButton(L(R.replayTimeline),"replay",void 0,"animations.play-replay-pause-animation-group"),this.#se.element.classList.add("toolbar-state-on"),this.#re="replay-outline",this.#se.addEventListener("Click",this.controlButtonToggle.bind(this)),l.appendToolbarItem(this.#se),this.#pe=o.createChild("div","animation-grid-header"),this.#pe.setAttribute("jslog",`${n.timeline("animations.grid-header").track({drag:!0,click:!0})}`),i.UIUtils.installDragHandle(this.#pe,this.scrubberDragStart.bind(this),this.scrubberDragMove.bind(this),this.scrubberDragEnd.bind(this),null),this.#D.appendChild(this.createScrubber()),this.clearCurrentTimeText(),o}handlePlaybackRateControlKeyDown(e){switch(e.key){case"ArrowLeft":case"ArrowUp":this.focusNextPlaybackRateButton(e.target,!0);break;case"ArrowRight":case"ArrowDown":this.focusNextPlaybackRateButton(e.target)}}focusNextPlaybackRateButton(e,t){const i=e,n=this.#_.indexOf(i),s=t?n-1:n+1;if(s<0||s>=this.#_.length)return;const r=this.#_[s];r.tabIndex=0,r.focus(),e&&(e.tabIndex=-1)}togglePauseAll(){this.#N=!this.#N,r.userMetrics.actionTaken(this.#N?r.UserMetrics.Action.AnimationsPaused:r.UserMetrics.Action.AnimationsResumed),this.#ne&&this.#ne.setToggled(this.#N),this.setPlaybackRate(this.#U),this.#ne&&this.#ne.setTitle(this.#N?L(R.resumeAll):L(R.pauseAll))}setPlaybackRate(t){t!==this.#U&&r.userMetrics.animationPlaybackRateChanged(.1===t?2:.25===t?1:1===t?0:3),this.#U=t;for(const t of e.TargetManager.TargetManager.instance().models(g,{scoped:!0}))t.setPlaybackRate(this.#N?0:this.#U);r.userMetrics.actionTaken(r.UserMetrics.Action.AnimationsPlaybackRateChanged),this.#le&&(this.#le.playbackRate=this.effectivePlaybackRate()),this.updatePlaybackControls()}updatePlaybackControls(){for(const e of this.#_){const t=this.#U===B.get(e);e.classList.toggle("selected",t),e.tabIndex=t?0:-1}}controlButtonToggle(){"play-outline"===this.#re?this.togglePause(!1):"replay-outline"===this.#re?(r.userMetrics.actionTaken(r.UserMetrics.Action.AnimationGroupReplayed),this.replay()):this.togglePause(!0)}updateControlButton(){this.#se&&(this.#se.setEnabled(Boolean(this.#K)&&this.hasAnimationGroupActiveNodes()&&!this.#K?.isScrollDriven()),this.#K&&this.#K.paused()?(this.#re="play-outline",this.#se.element.classList.toggle("toolbar-state-on",!0),this.#se.setTitle(L(R.playTimeline)),this.#se.setGlyph("play")):!this.#le||!this.#le.currentTime||"number"!=typeof this.#le.currentTime||this.#le.currentTime>=this.duration()?(this.#re="replay-outline",this.#se.element.classList.toggle("toolbar-state-on",!0),this.#se.setTitle(L(R.replayTimeline)),this.#se.setGlyph("replay")):(this.#re="pause-outline",this.#se.element.classList.toggle("toolbar-state-on",!1),this.#se.setTitle(L(R.pauseTimeline)),this.#se.setGlyph("pause")))}effectivePlaybackRate(){return this.#N||this.#K&&this.#K.paused()?0:this.#U}togglePause(e){if(this.#K){this.#K.togglePause(e);const t=this.#ee.get(this.#K);t&&t.element.classList.toggle("paused",e)}this.#le&&(this.#le.playbackRate=this.effectivePlaybackRate()),this.updateControlButton()}replay(){this.#K&&this.hasAnimationGroupActiveNodes()&&!this.#K.isScrollDriven()&&(this.#K.seekTo(0),this.animateTime(0),this.updateControlButton())}duration(){return this.#q}setDuration(e){this.#q=e,this.scheduleRedraw()}clearTimeline(){this.#K&&this.#fe&&this.#K.scrollNode().then((e=>{e?.removeScrollEventListener(this.#fe),this.#fe=void 0})),this.#Y=[],this.#J.clear(),this.#te.clear(),this.#z.removeChildren(),this.#q=this.#$,this.#H.classList.add("hidden"),this.#pe.classList.remove("scrubber-enabled"),this.#K=null,this.#le&&this.#le.cancel(),this.#le=void 0,this.clearCurrentTimeText(),this.updateControlButton()}reset(){this.clearTimeline(),this.setPlaybackRate(this.#U);for(const e of this.#Z)e.release();this.#Z=[],this.clearPreviews(),this.renderGrid()}animationGroupStarted({data:e}){this.addAnimationGroup(e)}scheduledRedrawAfterAnimationGroupUpdatedForTest(){}animationGroupUpdated({data:e}){this.#ye.schedule((async()=>{const t=this.#ee.get(e);if(t&&t.replay(),this.#K===e){if(e.isScrollDriven()){const t=await e.scrollNode();if(t){const i="vertical"===e.scrollOrientation()?await t.verticalScrollRange():await t.horizontalScrollRange(),n="vertical"===e.scrollOrientation()?await t.scrollTop():await t.scrollLeft();null!==i&&this.setDuration(i),null!==n&&(this.setCurrentTimeText(n),this.setTimelineScrubberPosition(n))}}else this.setDuration(e.finiteDuration());this.updateControlButton(),this.scheduleRedraw(),this.scheduledRedrawAfterAnimationGroupUpdatedForTest()}}))}clearPreviews(){this.#ee.clear(),this.#F.forEach((e=>{e.detach()})),this.#j.removeChildren(),this.#F=[]}createPreview(e){const t=new $(e),n=document.createElement("div");n.classList.add("preview-ui-container"),n.appendChild(t.element);const s=document.createElement("div");if(s.classList.add("screenshots-container","no-screenshots"),s.createChild("span","screenshot-arrow"),s.addEventListener("animationend",(()=>{const{right:e,left:t,width:i}=s.getBoundingClientRect();e>window.innerWidth&&t-i>=0&&s.classList.add("to-the-left")})),n.appendChild(s),this.#Z.push(e),this.#ee.set(e,t),this.#j.appendChild(n),t.removeButton().addEventListener("click",this.removeAnimationGroup.bind(this,e)),t.element.addEventListener("click",this.selectAnimationGroup.bind(this,e)),t.element.addEventListener("keydown",this.handleAnimationGroupKeyDown.bind(this,e)),t.element.addEventListener("mouseover",(()=>{const t=e.screenshots();if(!t.length)return;s.classList.remove("no-screenshots");const i=()=>{const e=new S(t);this.#F.push(e),e.show(s)};t[0].complete?i():t[0].onload=i}),{once:!0}),i.ARIAUtils.setLabel(t.element,L(R.animationPreviewS,{PH1:this.#Z.indexOf(e)+1})),i.ARIAUtils.markAsOption(t.element),1===this.#ee.size){const e=this.#ee.get(this.#Z[0]);e&&(e.element.tabIndex=0)}}previewsCreatedForTest(){}createPreviewForCollectedGroups(){this.#be.sort(((e,t)=>e.isScrollDriven()&&!t.isScrollDriven()?-1:!e.isScrollDriven()&&t.isScrollDriven()?1:e.startTime()!==t.startTime()?e.startTime()-t.startTime():e.animations.length-t.animations.length));for(const e of this.#be)this.createPreview(e);this.#be=[],this.previewsCreatedForTest()}addAnimationGroup(e){const t=this.#ee.get(e);if(t)return void(this.#K===e?this.syncScrubber():t.replay());this.#Z.sort(((e,t)=>e.startTime()-t.startTime()));const i=[],n=this.width()/50;for(;this.#Z.length>n;){const e=this.#Z.splice(this.#Z[0]===this.#K?1:0,1);i.push(e[0])}for(const e of i){const t=this.#ee.get(e);t&&(t.element.remove(),this.#ee.delete(e),e.release())}this.#be.push(e),this.#ge.schedule((()=>Promise.resolve(this.createPreviewForCollectedGroups())))}handleAnimationGroupKeyDown(e,t){switch(t.key){case"Backspace":case"Delete":this.removeAnimationGroup(e,t);break;case"ArrowLeft":case"ArrowUp":this.focusNextGroup(e,t.target,!0);break;case"ArrowRight":case"ArrowDown":this.focusNextGroup(e,t.target)}}focusNextGroup(e,t,i){const n=this.#Z.indexOf(e),s=i?n-1:n+1;if(s<0||s>=this.#Z.length)return;const r=this.#ee.get(this.#Z[s]);r&&(r.element.tabIndex=0,r.element.focus()),t&&(t.tabIndex=-1)}removeAnimationGroup(e,t){const i=this.#Z.indexOf(e);a.ArrayUtilities.removeElement(this.#Z,e);const n=this.#ee.get(e);n&&n.element.remove(),this.#ee.delete(e),e.release(),t.consume(!0),this.#K===e&&(this.clearTimeline(),this.renderGrid());if(0===this.#Z.length)return void this.#V.element.focus();const s=i>=this.#Z.length?this.#ee.get(this.#Z[this.#Z.length-1]):this.#ee.get(this.#Z[i]);s&&(s.element.tabIndex=0,s.element.focus())}clearCurrentTimeText(){this.#W.textContent=""}setCurrentTimeText(e){this.#K&&(this.#W.textContent=this.#K?.isScrollDriven()?`${e.toFixed(0)}px`:o.TimeUtilities.millisToString(e))}async selectAnimationGroup(e){if(this.#K===e)return this.togglePause(!1),void this.replay();if(this.clearTimeline(),this.#K=e,this.#ee.forEach(((e,t)=>{e.element.classList.toggle("selected",this.#K===t)})),e.isScrollDriven()){const t=await e.scrollNode();if(!t)throw new Error("Scroll container is not found for the scroll driven animation");const i="vertical"===e.scrollOrientation()?await t.verticalScrollRange():await t.horizontalScrollRange(),n="vertical"===e.scrollOrientation()?await t.scrollTop():await t.scrollLeft();if("number"!=typeof i||"number"!=typeof n)throw new Error("Scroll range or scroll offset is not resolved for the scroll driven animation");this.#fe=await t.addScrollEventListener((({scrollTop:t,scrollLeft:i})=>{const n="vertical"===e.scrollOrientation()?t:i;this.setCurrentTimeText(n),this.setTimelineScrubberPosition(n)})),this.setDuration(i),this.setCurrentTimeText(n),this.setTimelineScrubberPosition(n),this.#_.forEach((e=>{e.setAttribute("disabled","true")})),this.#ne&&this.#ne.setEnabled(!1)}else this.setDuration(Math.max(500,e.finiteDuration()+100)),this.#_.forEach((e=>{e.removeAttribute("disabled")})),this.#ne&&this.#ne.setEnabled(!0);await Promise.all(e.animations().map((e=>this.addAnimation(e)))),this.scheduleRedraw(),this.togglePause(!1),this.replay(),this.hasAnimationGroupActiveNodes()&&(this.#H.classList.remove("hidden"),this.#pe.classList.add("scrubber-enabled")),r.userMetrics.actionTaken(r.UserMetrics.Action.AnimationGroupSelected),this.#K.isScrollDriven()&&r.userMetrics.actionTaken(r.UserMetrics.Action.ScrollDrivenAnimationGroupSelected),this.animationGroupSelectedForTest()}animationGroupSelectedForTest(){}async addAnimation(e){let t=this.#J.get(e.source().backendNodeId());t||(t=new N(e.source()),this.#z.appendChild(t.element),this.#J.set(e.source().backendNodeId(),t));const i=t.createNewRow(),n=new W(e,this,i),s=await e.source().deferredNode().resolvePromise();n.setNode(s),s&&t&&(t.nodeResolved(s),G.set(s,t)),this.#Y.push(n),this.#te.set(e.id(),e)}markNodeAsRemoved(e){G.get(e)?.nodeRemoved();for(const t of e.pseudoElements().values())t.forEach((e=>this.markNodeAsRemoved(e)));e.children()?.forEach((e=>{this.markNodeAsRemoved(e)})),this.hasAnimationGroupActiveNodes()||(this.#pe.classList.remove("scrubber-enabled"),this.#H.classList.add("hidden"),this.#le?.cancel(),this.#le=void 0,this.clearCurrentTimeText(),this.updateControlButton())}hasAnimationGroupActiveNodes(){for(const e of this.#J.values())if(e.hasActiveNode())return!0;return!1}renderGrid(){const e=this.#K?.isScrollDriven(),t=e?this.duration()/10:250;let n;this.#O.removeChildren();for(let e=0;e<this.duration();e+=t){const t=i.UIUtils.createSVGChild(this.#O,"rect","animation-timeline-grid-line");t.setAttribute("x",(e*this.pixelTimeRatio()+10).toString()),t.setAttribute("y","23"),t.setAttribute("height","100%"),t.setAttribute("width","1")}for(let s=0;s<this.duration();s+=t){const t=s*this.pixelTimeRatio();if(void 0===n||t-n>50){n=t;const r=i.UIUtils.createSVGChild(this.#O,"text","animation-timeline-grid-label");r.textContent=e?`${s.toFixed(0)}px`:o.TimeUtilities.millisToString(s),r.setAttribute("x",(t+10).toString()),r.setAttribute("y","16")}}}scheduleRedraw(){this.renderGrid(),this.#X=[];for(const e of this.#Y)this.#X.push(e);this.#oe||(this.#oe=!0,this.#z.window().requestAnimationFrame(this.render.bind(this)))}render(e){for(;this.#X.length&&(!e||window.performance.now()-e<50);){const e=this.#X.shift();e&&e.redraw()}this.#X.length?this.#z.window().requestAnimationFrame(this.render.bind(this)):this.#oe=void 0}onResize(){this.#ae=Math.max(0,this.#z.offsetWidth-this.#Q)||0,this.scheduleRedraw(),this.#le&&this.syncScrubber(),this.#de=void 0}width(){return this.#ae||0}syncScrubber(){this.#K&&this.hasAnimationGroupActiveNodes()&&this.#K.currentTimePromise().then(this.animateTime.bind(this)).then(this.updateControlButton.bind(this))}animateTime(e){this.#K?.isScrollDriven()||(this.#le&&this.#le.cancel(),this.#le=this.#H.animate([{transform:"translateX(0px)"},{transform:"translateX("+this.width()+"px)"}],{duration:this.duration(),fill:"forwards"}),this.#le.playbackRate=this.effectivePlaybackRate(),this.#le.onfinish=this.updateControlButton.bind(this),this.#le.currentTime=e,this.element.window().requestAnimationFrame(this.updateScrubber.bind(this)))}pixelTimeRatio(){return this.width()/this.duration()||0}updateScrubber(e){this.#le&&(this.setCurrentTimeText(this.#xe()),"pending"===this.#le.playState.toString()||"running"===this.#le.playState?this.element.window().requestAnimationFrame(this.updateScrubber.bind(this)):"finished"===this.#le.playState&&this.clearCurrentTimeText())}scrubberDragStart(e){if(!this.#K||!this.hasAnimationGroupActiveNodes())return!1;this.#de||(this.#de=this.#O.getBoundingClientRect().left+10);const{x:t}=e,i=Math.max(0,t-this.#de)/this.pixelTimeRatio();if(this.#ce=i,this.#me=t,this.setCurrentTimeText(i),this.#K.isScrollDriven())this.setTimelineScrubberPosition(i),this.updateScrollOffsetOnPage(i);else{const e=this.#le?.currentTime;this.#he=this.#K.paused()||"number"==typeof e&&e>=this.duration(),this.#K.seekTo(i),this.togglePause(!0),this.animateTime(i)}return!0}async updateScrollOffsetOnPage(e){const t=await(this.#K?.scrollNode());if(t)return"vertical"===this.#K?.scrollOrientation()?t.setScrollTop(e):t.setScrollLeft(e)}setTimelineScrubberPosition(e){this.#H.style.transform=`translateX(${e*this.pixelTimeRatio()}px)`}scrubberDragMove(e){const{x:t}=e,i=t-(this.#me||0),n=Math.max(0,Math.min((this.#ce||0)+i/this.pixelTimeRatio(),this.duration()));this.#le?this.#le.currentTime=n:(this.setTimelineScrubberPosition(n),this.updateScrollOffsetOnPage(n)),this.setCurrentTimeText(n),this.#K&&!this.#K.isScrollDriven()&&this.#K.seekTo(n)}#xe(){return"number"==typeof this.#le?.currentTime?this.#le.currentTime:0}scrubberDragEnd(e){if(this.#le){const e=Math.max(0,this.#xe());this.#le.play(),this.#le.currentTime=e}r.userMetrics.actionTaken(r.UserMetrics.Action.AnimationGroupScrubbed),this.#K?.isScrollDriven()&&r.userMetrics.actionTaken(r.UserMetrics.Action.ScrollDrivenAnimationGroupScrubbed),this.#W.window().requestAnimationFrame(this.updateScrubber.bind(this)),this.#he||this.togglePause(!1)}}const U=[1,.25,.1];class N{element;#Te;#Ae;#ke;#Ie;constructor(e){this.element=document.createElement("div"),this.element.classList.add("animation-node-row"),this.#Te=this.element.createChild("div","animation-node-description"),this.#Te.setAttribute("jslog",`${n.tableCell("description").track({resize:!0})}`),this.#Ae=this.element.createChild("div","animation-node-timeline"),this.#Ae.setAttribute("jslog",`${n.tableCell("timeline").track({resize:!0})}`),i.ARIAUtils.markAsApplication(this.#Ae)}nodeResolved(e){e?(this.#Ie=e,this.nodeChanged(),s.Linkifier.Linkifier.linkify(e).then((e=>{e.addEventListener("click",(()=>{r.userMetrics.actionTaken(r.UserMetrics.Action.AnimatedNodeDescriptionClicked)})),this.#Te.appendChild(e)})),e.ownerDocument||this.nodeRemoved()):i.UIUtils.createTextChild(this.#Te,"<node>")}createNewRow(){return this.#Ae.createChild("div","animation-timeline-row")}nodeRemoved(){this.element.classList.add("animation-node-removed"),this.#ke||(this.#ke=document.createElement("div"),this.#ke.classList.add("animation-node-removed-overlay"),this.#Te.appendChild(this.#ke)),this.#Ie=null}hasActiveNode(){return Boolean(this.#Ie)}nodeChanged(){let t=!1;this.#Ie&&(t=this.#Ie===i.Context.Context.instance().flavor(e.DOMModel.DOMNode)),this.element.classList.toggle("animation-node-selected",t)}}class F{steps;stepAtPosition;constructor(e,t){this.steps=e,this.stepAtPosition=t}static parse(e){let t=e.match(/^steps\((\d+), (start|middle)\)$/);return t?new F(parseInt(t[1],10),t[2]):(t=e.match(/^steps\((\d+)\)$/),t?new F(parseInt(t[1],10),"end"):null)}}var z=Object.freeze({__proto__:null,AnimationTimeline:O,GlobalPlaybackRates:U,NodeUI:N,StepTimingFunction:F});const _={animationEndpointSlider:"Animation Endpoint slider",animationKeyframeSlider:"Animation Keyframe slider",sSlider:"{PH1} slider"},j=o.i18n.registerUIStrings("panels/animation/AnimationUI.ts",_),H=o.i18n.getLocalizedString.bind(void 0,j);class W{#Me;#Se;#Ce;#Pe;#Re;#Ee;#Le;#Ge;#Be;#De;#Ie;#Oe;#Ue;#Ne;#Fe;#ze;#_e;constructor(e,t,s){this.#Me=e,this.#Se=t;const r=this.#Me.source().keyframesRule();r&&(this.#Ce=r.keyframes(),e.viewOrScrollTimeline()&&e.playbackRate()<0&&this.#Ce.reverse()),this.#Pe=s.createChild("div","animation-name"),this.#Pe.textContent=this.#Me.name(),this.#Re=i.UIUtils.createSVGChild(s,"svg","animation-ui"),this.#Re.setAttribute("height",V.AnimationSVGHeight.toString()),this.#Re.style.marginLeft="-"+V.AnimationMargin+"px",this.#Re.addEventListener("contextmenu",this.onContextMenu.bind(this)),this.#Ee=i.UIUtils.createSVGChild(this.#Re,"g"),this.#Ee.setAttribute("jslog",`${n.animationClip().track({drag:!0})}`),this.#Me.viewOrScrollTimeline()||(i.UIUtils.installDragHandle(this.#Ee,this.mouseDown.bind(this,"AnimationDrag",null),this.mouseMove.bind(this),this.mouseUp.bind(this),"-webkit-grabbing","-webkit-grab"),W.installDragHandleKeyboard(this.#Ee,this.keydownMove.bind(this,"AnimationDrag",null))),this.#Le=[],this.#Ge=0,this.#Be=50,this.#De=W.colorForAnimation(this.#Me)}static colorForAnimation(e){const t=Array.from(K.keys()),i=t[a.StringUtilities.hashCode(e.name()||e.id())%t.length],n=K.get(i);if(!n)throw new Error("Unable to locate color");return n.asString("rgb")||""}static installDragHandleKeyboard(e,t){e.addEventListener("keydown",t,!1)}animation(){return this.#Me}get nameElement(){return this.#Pe}get svg(){return this.#Re}setNode(e){this.#Ie=e}createLine(e,t){const n=i.UIUtils.createSVGChild(e,"line",t);return n.setAttribute("x1",V.AnimationMargin.toString()),n.setAttribute("y1",V.AnimationHeight.toString()),n.setAttribute("y2",V.AnimationHeight.toString()),n.style.stroke=this.#De,n}drawAnimationLine(e,t){const i=this.#Le[e];i.animationLine||(i.animationLine=this.createLine(t,"animation-line")),i.animationLine&&i.animationLine.setAttribute("x2",(this.duration()*this.#Se.pixelTimeRatio()+V.AnimationMargin).toFixed(2))}drawDelayLine(e){this.#Oe&&this.#Ue||(this.#Oe=this.createLine(e,"animation-delay-line"),this.#Ue=this.createLine(e,"animation-delay-line"));const t=this.#Me.source().fill();this.#Oe.classList.toggle("animation-fill","backwards"===t||"both"===t);const i=V.AnimationMargin;this.#Oe.setAttribute("x1",i.toString()),this.#Oe.setAttribute("x2",(this.delayOrStartTime()*this.#Se.pixelTimeRatio()+i).toFixed(2));const n="forwards"===t||"both"===t;this.#Ue.classList.to