@react-native/debugger-frontend
Version:
Debugger frontend for React Native based on Chrome DevTools
1 lines • 53.3 kB
JavaScript
import*as e from"../../core/common/common.js";import*as t from"../../core/i18n/i18n.js";import*as i from"../../core/sdk/sdk.js";import*as s from"../../ui/legacy/legacy.js";import*as r from"../../ui/visual_logging/visual_logging.js";import*as n from"../../ui/legacy/theme_support/theme_support.js";import*as a from"../../core/platform/platform.js";import*as o from"../../ui/legacy/components/perf_ui/perf_ui.js";var l={cssText:`.layer-details-container:has(.empty-view-scroller){display:flex}table{border-spacing:0}table td{font:var(--sys-typescale-body4-regular);line-height:18px;padding:var(--sys-size-3) var(--sys-size-5);vertical-align:top}table td:first-child{color:var(--sys-color-on-surface-subtle);font:var(--sys-typescale-body5-medium);line-height:18px;white-space:nowrap}.scroll-rect.active{background-color:var(--sys-color-neutral-container)}ul{list-style:none;padding-inline-start:0;margin-block:0}.devtools-link.link-margin{margin:8px;display:inline-block}\n/*# sourceURL=${import.meta.resolve("./layerDetailsView.css")} */\n`};const h={showInternalLayers:"Show internal layers"},c=t.i18n.registerUIStrings("panels/layer_viewer/LayerViewHost.ts",h),d=t.i18n.getLocalizedString.bind(void 0,c);class u{typeInternal;layerInternal;constructor(e,t){this.typeInternal=e,this.layerInternal=t}static isEqual(e,t){return e&&t?e.isEqual(t):e===t}type(){return this.typeInternal}layer(){return this.layerInternal}isEqual(e){return!1}}class p extends u{constructor(e){console.assert(Boolean(e),"LayerSelection with empty layer"),super("Layer",e)}isEqual(e){return"Layer"===e.typeInternal&&e.layer().id()===this.layer().id()}}class m extends u{scrollRectIndex;constructor(e,t){super("ScrollRect",e),this.scrollRectIndex=t}isEqual(e){return"ScrollRect"===e.typeInternal&&this.layer().id()===e.layer().id()&&this.scrollRectIndex===e.scrollRectIndex}}class g extends u{snapshotInternal;constructor(e,t){super("Snapshot",e),this.snapshotInternal=t}isEqual(e){return"Snapshot"===e.typeInternal&&this.layer().id()===e.layer().id()&&this.snapshotInternal===e.snapshotInternal}snapshot(){return this.snapshotInternal}}var y=Object.freeze({__proto__:null,LayerSelection:p,LayerView:class{},LayerViewHost:class{views;selectedObject;hoveredObject;showInternalLayersSettingInternal;snapshotLayers;target;constructor(){this.views=[],this.selectedObject=null,this.hoveredObject=null,this.showInternalLayersSettingInternal=e.Settings.Settings.instance().createSetting("layers-show-internal-layers",!1),this.snapshotLayers=new Map}registerView(e){this.views.push(e)}setLayerSnapshotMap(e){this.snapshotLayers=e}getLayerSnapshotMap(){return this.snapshotLayers}setLayerTree(e){if(!e)return;this.target=e.target();const t=this.selectedObject?.layer();t&&!e?.layerById(t.id())&&this.selectObject(null);const i=this.hoveredObject?.layer();i&&!e?.layerById(i.id())&&this.hoverObject(null);for(const t of this.views)t.setLayerTree(e)}hoverObject(e){if(u.isEqual(this.hoveredObject,e))return;this.hoveredObject=e;const t=e?.layer();this.toggleNodeHighlight(t?t.nodeForSelfOrAncestor():null);for(const t of this.views)t.hoverObject(e)}selectObject(e){if(!u.isEqual(this.selectedObject,e)){this.selectedObject=e;for(const t of this.views)t.selectObject(e)}}selection(){return this.selectedObject}showContextMenu(e,t){e.defaultSection().appendCheckboxItem(d(h.showInternalLayers),this.toggleShowInternalLayers.bind(this),{checked:this.showInternalLayersSettingInternal.get(),jslogContext:this.showInternalLayersSettingInternal.name});const i=t?.layer()?.nodeForSelfOrAncestor();i&&e.appendApplicableItems(i),e.show()}showInternalLayersSetting(){return this.showInternalLayersSettingInternal}toggleShowInternalLayers(){this.showInternalLayersSettingInternal.set(!this.showInternalLayersSettingInternal.get())}toggleNodeHighlight(e){e?e.highlightForTwoSeconds():i.OverlayModel.OverlayModel.hideDOMNodeHighlight()}},ScrollRectSelection:m,Selection:u,SnapshotSelection:g});const w={selectALayerToSeeItsDetails:"Select a layer to see its details",noLayerSelected:"No layer selected",scrollRectangleDimensions:"{PH1} {PH2} × {PH3} (at {PH4}, {PH5})",unnamed:"<unnamed>",stickyAncenstorLayersS:"{PH1}: {PH2} ({PH3})",stickyBoxRectangleDimensions:"Sticky Box {PH1} × {PH2} (at {PH3}, {PH4})",containingBlocRectangleDimensions:"Containing Block {PH1} × {PH2} (at {PH3}, {PH4})",nearestLayerShiftingStickyBox:"Nearest Layer Shifting Sticky Box",nearestLayerShiftingContaining:"Nearest Layer Shifting Containing Block",updateRectangleDimensions:"{PH1} × {PH2} (at {PH3}, {PH4})",size:"Size",compositingReasons:"Compositing Reasons",memoryEstimate:"Memory estimate",paintCount:"Paint count",slowScrollRegions:"Slow scroll regions",stickyPositionConstraint:"Sticky position constraint",paintProfiler:"Paint Profiler",nonFastScrollable:"Non fast scrollable",touchEventHandler:"Touch event handler",wheelEventHandler:"Wheel event handler",repaintsOnScroll:"Repaints on scroll",mainThreadScrollingReason:"Main thread scrolling reason"},f=t.i18n.registerUIStrings("panels/layer_viewer/LayerDetailsView.ts",w),v=t.i18n.getLocalizedString.bind(void 0,f),C=t.i18n.getLazilyComputedLocalizedString.bind(void 0,f);class b extends(e.ObjectWrapper.eventMixin(s.Widget.Widget)){layerViewHost;emptyWidget;layerSnapshotMap;tableElement;tbodyElement;sizeCell;compositingReasonsCell;memoryEstimateCell;paintCountCell;scrollRectsCell;stickyPositionConstraintCell;paintProfilerLink;selection;constructor(e){super(!0),this.registerRequiredCSS(l),this.element.setAttribute("jslog",`${r.pane("layers-details")}`),this.contentElement.classList.add("layer-details-container"),this.layerViewHost=e,this.layerViewHost.registerView(this),this.emptyWidget=new s.EmptyWidget.EmptyWidget(v(w.noLayerSelected),v(w.selectALayerToSeeItsDetails)),this.layerSnapshotMap=this.layerViewHost.getLayerSnapshotMap(),this.buildContent(),this.selection=null}hoverObject(e){}selectObject(e){this.selection=e,this.isShowing()&&this.update()}setLayerTree(e){}wasShown(){super.wasShown(),this.update()}onScrollRectClicked(e,t){1===t.which&&this.selection&&this.layerViewHost.selectObject(new m(this.selection.layer(),e))}invokeProfilerLink(){if(!this.selection)return;const e="Snapshot"===this.selection.type()?this.selection:this.layerSnapshotMap.get(this.selection.layer());e&&this.dispatchEventToListeners("PaintProfilerRequested",e)}createScrollRectElement(e,t){t&&s.UIUtils.createTextChild(this.scrollRectsCell,", ");const i=this.scrollRectsCell.createChild("span","scroll-rect");this.selection&&this.selection.scrollRectIndex===t&&i.classList.add("active"),i.textContent=v(w.scrollRectangleDimensions,{PH1:String(x.get(e.type)?.()),PH2:e.rect.width,PH3:e.rect.height,PH4:e.rect.x,PH5:e.rect.y}),i.addEventListener("click",this.onScrollRectClicked.bind(this,t),!1),i.setAttribute("jslog",`${r.action("layers.select-object").track({click:!0})}`)}formatStickyAncestorLayer(e,t){if(!t)return"";const i=t.nodeForSelfOrAncestor(),s=i?i.simpleSelector():v(w.unnamed);return v(w.stickyAncenstorLayersS,{PH1:e,PH2:s,PH3:t.id()})}createStickyAncestorChild(e,t){if(!t)return;s.UIUtils.createTextChild(this.stickyPositionConstraintCell,", ");this.stickyPositionConstraintCell.createChild("span").textContent=this.formatStickyAncestorLayer(e,t)}populateStickyPositionConstraintCell(e){if(this.stickyPositionConstraintCell.removeChildren(),!e)return;const t=e.stickyBoxRect();this.stickyPositionConstraintCell.createChild("span").textContent=v(w.stickyBoxRectangleDimensions,{PH1:t.width,PH2:t.height,PH3:t.x,PH4:t.y}),s.UIUtils.createTextChild(this.stickyPositionConstraintCell,", ");const i=e.containingBlockRect();this.stickyPositionConstraintCell.createChild("span").textContent=v(w.containingBlocRectangleDimensions,{PH1:i.width,PH2:i.height,PH3:i.x,PH4:i.y}),this.createStickyAncestorChild(v(w.nearestLayerShiftingStickyBox),e.nearestLayerShiftingStickyBox()),this.createStickyAncestorChild(v(w.nearestLayerShiftingContaining),e.nearestLayerShiftingContainingBlock())}update(){const e=this.selection?.layer();if(!e)return this.tableElement.remove(),this.paintProfilerLink.remove(),void this.emptyWidget.show(this.contentElement);this.emptyWidget.detach(),this.contentElement.appendChild(this.tableElement),this.contentElement.appendChild(this.paintProfilerLink),this.sizeCell.textContent=v(w.updateRectangleDimensions,{PH1:e.width(),PH2:e.height(),PH3:e.offsetX(),PH4:e.offsetY()}),this.paintCountCell.parentElement&&this.paintCountCell.parentElement.classList.toggle("hidden",!e.paintCount()),this.paintCountCell.textContent=String(e.paintCount()),this.memoryEstimateCell.textContent=t.ByteUtilities.bytesToString(e.gpuMemoryUsage()),e.requestCompositingReasons().then(this.updateCompositingReasons.bind(this)),this.scrollRectsCell.removeChildren(),e.scrollRects().forEach(this.createScrollRectElement.bind(this)),this.populateStickyPositionConstraintCell(e.stickyPositionConstraint());const i=this.selection&&"Snapshot"===this.selection.type()?this.selection.snapshot():null;this.paintProfilerLink.classList.toggle("hidden",!(this.layerSnapshotMap.has(e)||i))}buildContent(){this.tableElement=this.contentElement.createChild("table"),this.tbodyElement=this.tableElement.createChild("tbody"),this.sizeCell=this.createRow(v(w.size)),this.compositingReasonsCell=this.createRow(v(w.compositingReasons)),this.memoryEstimateCell=this.createRow(v(w.memoryEstimate)),this.paintCountCell=this.createRow(v(w.paintCount)),this.scrollRectsCell=this.createRow(v(w.slowScrollRegions)),this.stickyPositionConstraintCell=this.createRow(v(w.stickyPositionConstraint)),this.paintProfilerLink=this.contentElement.createChild("button","hidden devtools-link link-margin text-button link-style"),s.ARIAUtils.markAsLink(this.paintProfilerLink),this.paintProfilerLink.textContent=v(w.paintProfiler),this.paintProfilerLink.tabIndex=0,this.paintProfilerLink.addEventListener("click",(e=>{e.consume(!0),this.invokeProfilerLink()})),this.paintProfilerLink.setAttribute("jslog",`${r.action("layers.paint-profiler").track({click:!0,keydown:"Enter"})}`)}createRow(e){const t=this.tbodyElement.createChild("tr");return t.createChild("td").textContent=e,t.createChild("td")}updateCompositingReasons(e){if(!e?.length)return void(this.compositingReasonsCell.textContent="n/a");this.compositingReasonsCell.removeChildren();const t=this.compositingReasonsCell.createChild("ul");for(const i of e)t.createChild("li").textContent=i}}const x=new Map([["NonFastScrollable",C(w.nonFastScrollable)],["TouchEventHandler",C(w.touchEventHandler)],["WheelEventHandler",C(w.wheelEventHandler)],["RepaintsOnScroll",C(w.repaintsOnScroll)],["MainThreadScrollingReason",C(w.mainThreadScrollingReason)]]);var S=Object.freeze({__proto__:null,LayerDetailsView:b,slowScrollRectNames:x}),P={cssText:`.layer-summary{border-top:1px solid var(--sys-color-divider);justify-content:space-between;padding:4px 10px;flex-shrink:0}.layer-count{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.layer-tree-wrapper{flex-grow:1}\n/*# sourceURL=${import.meta.resolve("./layerTreeOutline.css")} */\n`};const T={layerCount:"{PH1} layers",layersTreePane:"Layers Tree Pane",showPaintProfiler:"Show Paint Profiler",updateChildDimension:" ({PH1} × {PH2})"},L=t.i18n.registerUIStrings("panels/layer_viewer/LayerTreeOutline.ts",T),E=t.i18n.getLocalizedString.bind(void 0,L);class R extends(e.ObjectWrapper.eventMixin(s.TreeOutline.TreeOutline)){layerViewHost;treeOutline;lastHoveredNode;layerCountElement;layerMemoryElement;element;layerTree;layerSnapshotMap;constructor(e){super(),this.layerViewHost=e,this.layerViewHost.registerView(this),this.treeOutline=new s.TreeOutline.TreeOutlineInShadow,this.treeOutline.element.classList.add("layer-tree","overflow-auto"),this.treeOutline.element.addEventListener("mousemove",this.onMouseMove.bind(this),!1),this.treeOutline.element.addEventListener("mouseout",this.onMouseMove.bind(this),!1),this.treeOutline.element.addEventListener("contextmenu",this.onContextMenu.bind(this),!0),s.ARIAUtils.setLabel(this.treeOutline.contentElement,E(T.layersTreePane)),this.lastHoveredNode=null;const t=document.createElement("div");t.classList.add("hbox","layer-summary"),this.layerCountElement=document.createElement("span"),this.layerCountElement.classList.add("layer-count"),this.layerMemoryElement=document.createElement("span"),t.appendChild(this.layerCountElement),t.appendChild(this.layerMemoryElement);const i=document.createElement("div");i.classList.add("vbox","layer-tree-wrapper"),i.appendChild(this.treeOutline.element),i.appendChild(t),this.element=i,n.ThemeSupport.instance().appendStyle(this.element,P),this.layerViewHost.showInternalLayersSetting().addChangeListener(this.update,this)}focus(){this.treeOutline.focus()}selectObject(e){this.hoverObject(null);const t=e?.layer(),i=t&&M.get(t);i?i.revealAndSelect(!0):this.treeOutline.selectedTreeElement&&this.treeOutline.selectedTreeElement.deselect()}hoverObject(e){const t=e?.layer(),i=t&&M.get(t);i!==this.lastHoveredNode&&(this.lastHoveredNode&&this.lastHoveredNode.setHovered(!1),i&&i.setHovered(!0),this.lastHoveredNode=i)}setLayerTree(e){this.layerTree=e,this.update()}update(){const e=this.layerViewHost.showInternalLayersSetting().get(),i=new Map;let s=null;this.layerTree&&(e||(s=this.layerTree.contentRoot()),s||(s=this.layerTree.root()));let r=0,n=0;s&&this.layerTree&&this.layerTree.forEachLayer(function(t){if(!t.drawsContent()&&!e)return;i.get(t)&&console.assert(!1,"Duplicate layer: "+t.id()),i.set(t,!0),r++,n+=t.gpuMemoryUsage();let a=M.get(t)||null,o=t.parent();for(;o&&o!==s&&!o.drawsContent()&&!e;)o=o.parent();const l=t===s?this.treeOutline.rootElement():o&&M.get(o);if(l)if(a){if(a.parent!==l){const e=this.treeOutline.selectedTreeElement;a.parent&&a.parent.removeChild(a),l.appendChild(a),e&&e!==this.treeOutline.selectedTreeElement&&e.select()}a.update()}else a=new I(this,t),l.appendChild(a),t.drawsContent()||a.expand();else console.assert(!1,"Parent is not in the tree")}.bind(this),s);for(let e=this.treeOutline.rootElement().firstChild();e instanceof I&&!e.root;)if(i.get(e.layer))e=e.traverseNextTreeElement(!1);else{const t=e.nextSibling||e.parent;e.parent&&e.parent.removeChild(e),e===this.lastHoveredNode&&(this.lastHoveredNode=null),e=t}if(!this.treeOutline.selectedTreeElement&&this.layerTree){const e=this.layerTree.contentRoot()||this.layerTree.root();if(e){const t=M.get(e);t&&t.revealAndSelect(!0)}}this.layerCountElement.textContent=E(T.layerCount,{PH1:r}),this.layerMemoryElement.textContent=t.ByteUtilities.bytesToString(n)}onMouseMove(e){const t=this.treeOutline.treeElementFromEvent(e);t!==this.lastHoveredNode&&this.layerViewHost.hoverObject(this.selectionForNode(t))}selectedNodeChanged(e){this.layerViewHost.selectObject(this.selectionForNode(e))}onContextMenu(e){const t=this.selectionForNode(this.treeOutline.treeElementFromEvent(e)),i=new s.ContextMenu.ContextMenu(e),r=t?.layer();t&&r&&(this.layerSnapshotMap=this.layerViewHost.getLayerSnapshotMap(),this.layerSnapshotMap.has(r)&&i.defaultSection().appendItem(E(T.showPaintProfiler),(()=>this.dispatchEventToListeners("PaintProfilerRequested",t)),{jslogContext:"layers.paint-profiler"})),this.layerViewHost.showContextMenu(i,t)}selectionForNode(e){return e?.layer?new p(e.layer):null}}class I extends s.TreeOutline.TreeElement{treeOutlineInternal;layer;constructor(e,t){super(),this.treeOutlineInternal=e,this.layer=t,M.set(t,this),this.update()}update(){const e=this.layer.nodeForSelfOrAncestor(),t=document.createDocumentFragment();s.UIUtils.createTextChild(t,e?e.simpleSelector():"#"+this.layer.id());t.createChild("span","dimmed").textContent=E(T.updateChildDimension,{PH1:this.layer.width(),PH2:this.layer.height()}),this.title=t}onselect(){return this.treeOutlineInternal.selectedNodeChanged(this),!1}setHovered(e){this.listItemElement.classList.toggle("hovered",e)}}const M=new WeakMap;var O=Object.freeze({__proto__:null,LayerTreeElement:I,LayerTreeOutline:R,layerToTreeElement:M}),H={cssText:`.layers-3d-view{overflow:hidden;user-select:none;> .empty-view-scroller{inset:0;position:absolute;background-color:var(--sys-color-cdt-base-container)}}devtools-toolbar{background-color:var(--sys-color-cdt-base-container);border-bottom:1px solid var(--sys-color-divider)}canvas{flex:1 1}.layers-3d-view > canvas:focus-visible{outline:auto 5px -webkit-focus-ring-color}\n/*# sourceURL=${import.meta.resolve("./layers3DView.css")} */\n`};const B={panModeX:"Pan mode (X)",rotateModeV:"Rotate mode (V)",resetTransform:"Reset transform (0)"},A=t.i18n.registerUIStrings("panels/layer_viewer/TransformController.ts",B),D=t.i18n.getLocalizedString.bind(void 0,A);class k extends e.ObjectWrapper.ObjectWrapper{mode;scaleInternal;offsetXInternal;offsetYInternal;rotateXInternal;rotateYInternal;oldRotateX;oldRotateY;originX;originY;element;minScale;maxScale;controlPanelToolbar;modeButtons;constructor(e,t){if(super(),this.scaleInternal=1,this.offsetXInternal=0,this.offsetYInternal=0,this.rotateXInternal=0,this.rotateYInternal=0,this.oldRotateX=0,this.oldRotateY=0,this.originX=0,this.originY=0,this.element=e,this.registerShortcuts(),s.UIUtils.installDragHandle(e,this.onDragStart.bind(this),this.onDrag.bind(this),this.onDragEnd.bind(this),"move",null),e.addEventListener("wheel",this.onMouseWheel.bind(this),!1),this.minScale=0,this.maxScale=1/0,this.controlPanelToolbar=document.createElement("devtools-toolbar"),this.controlPanelToolbar.classList.add("transform-control-panel"),this.controlPanelToolbar.setAttribute("jslog",`${r.toolbar()}`),this.modeButtons={},!t){const e=new s.Toolbar.ToolbarToggle(D(B.panModeX),"3d-pan",void 0,"layers.3d-pan",!1);e.addEventListener("Click",this.setMode.bind(this,"Pan")),this.modeButtons.Pan=e,this.controlPanelToolbar.appendToolbarItem(e);const t=new s.Toolbar.ToolbarToggle(D(B.rotateModeV),"3d-rotate",void 0,"layers.3d-rotate",!1);t.addEventListener("Click",this.setMode.bind(this,"Rotate")),this.modeButtons.Rotate=t,this.controlPanelToolbar.appendToolbarItem(t)}this.setMode("Pan");const i=new s.Toolbar.ToolbarButton(D(B.resetTransform),"3d-center",void 0,"layers.3d-center");i.addEventListener("Click",this.resetAndNotify.bind(this,void 0)),this.controlPanelToolbar.appendToolbarItem(i),this.reset()}toolbar(){return this.controlPanelToolbar}registerShortcuts(){s.ShortcutRegistry.ShortcutRegistry.instance().addShortcutListener(this.element,{"layers.reset-view":async()=>(this.resetAndNotify(),!0),"layers.pan-mode":async()=>(this.setMode("Pan"),!0),"layers.rotate-mode":async()=>(this.setMode("Rotate"),!0),"layers.zoom-in":this.onKeyboardZoom.bind(this,1.1),"layers.zoom-out":this.onKeyboardZoom.bind(this,1/1.1),"layers.up":this.onKeyboardPanOrRotate.bind(this,0,-1),"layers.down":this.onKeyboardPanOrRotate.bind(this,0,1),"layers.left":this.onKeyboardPanOrRotate.bind(this,-1,0),"layers.right":this.onKeyboardPanOrRotate.bind(this,1,0)})}postChangeEvent(){this.dispatchEventToListeners("TransformChanged")}reset(){this.scaleInternal=1,this.offsetXInternal=0,this.offsetYInternal=0,this.rotateXInternal=0,this.rotateYInternal=0}setMode(e){this.mode!==e&&(this.mode=e,this.updateModeButtons())}updateModeButtons(){for(const e in this.modeButtons)this.modeButtons[e].setToggled(e===this.mode)}resetAndNotify(e){this.reset(),this.postChangeEvent(),e&&e.preventDefault(),this.element.focus()}setScaleConstraints(e,t){this.minScale=e,this.maxScale=t,this.scaleInternal=a.NumberUtilities.clamp(this.scaleInternal,e,t)}clampOffsets(e,t,i,s){this.offsetXInternal=a.NumberUtilities.clamp(this.offsetXInternal,e,t),this.offsetYInternal=a.NumberUtilities.clamp(this.offsetYInternal,i,s)}scale(){return this.scaleInternal}offsetX(){return this.offsetXInternal}offsetY(){return this.offsetYInternal}rotateX(){return this.rotateXInternal}rotateY(){return this.rotateYInternal}onScale(e,t,i){e=a.NumberUtilities.clamp(this.scaleInternal*e,this.minScale,this.maxScale)/this.scaleInternal,this.scaleInternal*=e,this.offsetXInternal-=(t-this.offsetXInternal)*(e-1),this.offsetYInternal-=(i-this.offsetYInternal)*(e-1),this.postChangeEvent()}onPan(e,t){this.offsetXInternal+=e,this.offsetYInternal+=t,this.postChangeEvent()}onRotate(e,t){this.rotateXInternal=e,this.rotateYInternal=t,this.postChangeEvent()}async onKeyboardZoom(e){return this.onScale(e,this.element.clientWidth/2,this.element.clientHeight/2),!0}async onKeyboardPanOrRotate(e,t){return"Rotate"===this.mode?this.onRotate(this.rotateXInternal+5*t,this.rotateYInternal+5*e):this.onPan(6*e,6*t),!0}onMouseWheel(e){const t=e,i=Math.pow(1.1,-t.deltaY*(1/53));this.onScale(i,t.clientX-this.element.getBoundingClientRect().left,t.clientY-this.element.getBoundingClientRect().top)}onDrag(e){const{clientX:t,clientY:i}=e;"Rotate"===this.mode?this.onRotate(this.oldRotateX+(this.originY-i)/this.element.clientHeight*180,this.oldRotateY-(this.originX-t)/this.element.clientWidth*180):(this.onPan(t-this.originX,i-this.originY),this.originX=t,this.originY=i)}onDragStart(e){return this.element.focus(),this.originX=e.clientX,this.originY=e.clientY,this.oldRotateX=this.rotateXInternal,this.oldRotateY=this.rotateYInternal,!0}onDragEnd(){this.originX=0,this.originY=0,this.oldRotateX=0,this.oldRotateY=0}}var W=Object.freeze({__proto__:null,TransformController:k});const V={noLayerInformation:"No layers detected yet",layerExplanation:"On this page you will be able to view and inspect document layers.",dLayersView:"3D Layers View",cantDisplayLayers:"Can't display layers",webglSupportIsDisabledInYour:"WebGL support is disabled in your browser.",checkSForPossibleReasons:"Check {PH1} for possible reasons.",slowScrollRects:"Slow scroll rects",paints:"Paints",resetView:"Reset View",showPaintProfiler:"Show Paint Profiler"},U=t.i18n.registerUIStrings("panels/layer_viewer/Layers3DView.ts",V),_=t.i18n.getLocalizedString.bind(void 0,U),F=new Map,j=new Map,X=new Map,N=new Map,Y=new Map,z=new Map;class q extends(e.ObjectWrapper.eventMixin(s.Widget.VBox)){failBanner;layerViewHost;transformController;canvasElement;lastSelection;layerTree;textureManager;chromeTextures;rects;snapshotLayers;shaderProgram;oldTextureScale;depthByLayerId;visibleLayers;maxDepth;scale;layerTexture;projectionMatrix;whiteTexture;gl;dimensionsForAutoscale;needsUpdate;updateScheduled;panelToolbar;showSlowScrollRectsSetting;showPaintsSetting;mouseDownX;mouseDownY;constructor(e){super(!0),this.registerRequiredCSS(H),this.element.setAttribute("jslog",`${r.pane("layers-3d-view")}`),this.contentElement.classList.add("layers-3d-view"),this.failBanner=new s.EmptyWidget.EmptyWidget(_(V.noLayerInformation),_(V.layerExplanation)),this.layerViewHost=e,this.layerViewHost.registerView(this),this.transformController=new k(this.contentElement),this.transformController.addEventListener("TransformChanged",this.update,this),this.initToolbar(),this.canvasElement=this.contentElement.createChild("canvas"),this.canvasElement.tabIndex=0,this.canvasElement.addEventListener("dblclick",this.onDoubleClick.bind(this),!1),this.canvasElement.addEventListener("mousedown",this.onMouseDown.bind(this),!1),this.canvasElement.addEventListener("mouseup",this.onMouseUp.bind(this),!1),this.canvasElement.addEventListener("mouseleave",this.onMouseMove.bind(this),!1),this.canvasElement.addEventListener("mousemove",this.onMouseMove.bind(this),!1),this.canvasElement.addEventListener("contextmenu",this.onContextMenu.bind(this),!1),this.canvasElement.setAttribute("jslog",`${r.canvas("layers").track({click:!0,drag:!0})}`),s.ARIAUtils.setLabel(this.canvasElement,_(V.dLayersView)),this.lastSelection={},this.layerTree=null,this.updateScheduled=!1,this.textureManager=new le(this.update.bind(this)),this.chromeTextures=[],this.rects=[],this.snapshotLayers=new Map,this.layerViewHost.setLayerSnapshotMap(this.snapshotLayers),this.layerViewHost.showInternalLayersSetting().addChangeListener(this.update,this)}setLayerTree(e){this.layerTree=e,this.layerTexture=null,delete this.oldTextureScale,this.showPaints()&&this.textureManager.setLayerTree(e),this.update()}showImageForLayer(e,t){if(!t)return this.layerTexture=null,void this.update();s.UIUtils.loadImage(t).then((t=>{const i=t&&le.createTextureForImage(this.gl||null,t);this.layerTexture=i?{layer:e,texture:i}:null,this.update()}))}onResize(){this.resizeCanvas(),this.update()}willHide(){this.textureManager.suspend()}wasShown(){this.textureManager.resume(),this.needsUpdate&&(this.resizeCanvas(),this.update())}updateLayerSnapshot(e){this.textureManager.layerNeedsUpdate(e)}setOutline(e,t){this.lastSelection[e]=t,this.update()}hoverObject(e){this.setOutline(G.Hovered,e)}selectObject(e){this.setOutline(G.Hovered,null),this.setOutline(G.Selected,e)}snapshotForSelection(e){if("Snapshot"===e.type()){const t=e.snapshot();return t.snapshot.addReference(),Promise.resolve(t)}if(e.layer()){const t=e.layer().snapshots()[0];if(void 0!==t)return t}return Promise.resolve(null)}initGL(e){const t=e.getContext("webgl");return t?(t.blendFunc(t.SRC_ALPHA,t.ONE_MINUS_SRC_ALPHA),t.enable(t.BLEND),t.clearColor(0,0,0,0),t.enable(t.DEPTH_TEST),t):null}createShader(e,t){if(!this.gl)return;const i=this.gl.createShader(e);i&&this.shaderProgram&&(this.gl.shaderSource(i,t),this.gl.compileShader(i),this.gl.attachShader(this.shaderProgram,i))}initShaders(){if(!this.gl)return;if(this.shaderProgram=this.gl.createProgram(),!this.shaderProgram)return;this.createShader(this.gl.FRAGMENT_SHADER,K),this.createShader(this.gl.VERTEX_SHADER,$),this.gl.linkProgram(this.shaderProgram),this.gl.useProgram(this.shaderProgram);const e=this.gl.getAttribLocation(this.shaderProgram,"aVertexPosition");this.gl.enableVertexAttribArray(e),F.set(this.shaderProgram,e);const t=this.gl.getAttribLocation(this.shaderProgram,"aVertexColor");this.gl.enableVertexAttribArray(t),j.set(this.shaderProgram,t);const i=this.gl.getAttribLocation(this.shaderProgram,"aTextureCoord");this.gl.enableVertexAttribArray(i),X.set(this.shaderProgram,i);const s=this.gl.getUniformLocation(this.shaderProgram,"uPMatrix");N.set(this.shaderProgram,s);const r=this.gl.getUniformLocation(this.shaderProgram,"uSampler");Y.set(this.shaderProgram,r)}resizeCanvas(){this.canvasElement.width=this.canvasElement.offsetWidth*window.devicePixelRatio,this.canvasElement.height=this.canvasElement.offsetHeight*window.devicePixelRatio}updateTransformAndConstraints(){const e=this.dimensionsForAutoscale||{width:0,height:0},t=this.layerTree?this.layerTree.viewportSize():null,i=t?t.width:e.width,r=t?t.height:e.height,n=this.canvasElement.width,o=this.canvasElement.height,l=.1*n,h=.1*o,c=(n-2*l)/i,d=(o-2*h)/r,u=Math.min(c,d),p=Math.min(i/e.width,r/e.width)/2;this.transformController.setScaleConstraints(p,10/u);const m=this.transformController.scale(),g=this.transformController.rotateX(),y=this.transformController.rotateY();this.scale=m*u;const w=a.NumberUtilities.clamp(this.scale,.1,1);w!==this.oldTextureScale&&(this.oldTextureScale=w,this.textureManager.setScale(w),this.dispatchEventToListeners("ScaleChanged",w));const f=(new WebKitCSSMatrix).scale(m,m,m).translate(n/2,o/2,0).rotate(g,y,0).scale(u,u,u).translate(-i/2,-r/2,0);let v;for(let e=0;e<this.rects.length;++e)v=s.Geometry.boundsForTransformedPoints(f,this.rects[e].vertices,v);v&&this.transformController.clampOffsets((l-v.maxX)/window.devicePixelRatio,(n-l-v.minX)/window.devicePixelRatio,(h-v.maxY)/window.devicePixelRatio,(o-h-v.minY)/window.devicePixelRatio);const C=this.transformController.offsetX()*window.devicePixelRatio,b=this.transformController.offsetY()*window.devicePixelRatio;this.projectionMatrix=(new WebKitCSSMatrix).translate(C,b,0).multiply(f);const x=(new WebKitCSSMatrix).scale(1,-1,-1).translate(-1,-1,0).scale(2/this.canvasElement.width,2/this.canvasElement.height,1e-6).multiply(this.projectionMatrix);if(this.shaderProgram){const e=N.get(this.shaderProgram);this.gl&&e&&this.gl.uniformMatrix4fv(e,!1,this.arrayFromMatrix(x))}}arrayFromMatrix(e){return new Float32Array([e.m11,e.m12,e.m13,e.m14,e.m21,e.m22,e.m23,e.m24,e.m31,e.m32,e.m33,e.m34,e.m41,e.m42,e.m43,e.m44])}initWhiteTexture(){if(!this.gl)return;this.whiteTexture=this.gl.createTexture(),this.gl.bindTexture(this.gl.TEXTURE_2D,this.whiteTexture);const e=new Uint8Array([255,255,255,255]);this.gl.texImage2D(this.gl.TEXTURE_2D,0,this.gl.RGBA,1,1,0,this.gl.RGBA,this.gl.UNSIGNED_BYTE,e)}initChromeTextures(){function e(e,t){s.UIUtils.loadImage(t).then((t=>{this.chromeTextures[e]=t&&le.createTextureForImage(this.gl||null,t)||void 0}))}e.call(this,0,"Images/chromeLeft.avif"),e.call(this,1,"Images/chromeMiddle.avif"),e.call(this,2,"Images/chromeRight.avif")}initGLIfNecessary(){return this.gl?this.gl:(this.gl=this.initGL(this.canvasElement),this.gl?(this.initShaders(),this.initWhiteTexture(),this.initChromeTextures(),this.textureManager.setContext(this.gl),this.gl):null)}calculateDepthsAndVisibility(){this.depthByLayerId=new Map;let e=0;const t=this.layerViewHost.showInternalLayersSetting().get();if(!this.layerTree)return;const i=t?this.layerTree.root():this.layerTree.contentRoot()||this.layerTree.root();if(!i)return;const s=[i];for(this.depthByLayerId.set(i.id(),0),this.visibleLayers=new Set;s.length>0;){const i=s.shift();if(!i)break;(t||i.drawsContent())&&this.visibleLayers.add(i);const r=i.children();for(let t=0;t<r.length;++t)this.depthByLayerId.set(r[t].id(),++e),s.push(r[t])}this.maxDepth=e}depthForLayer(e){return(this.depthByLayerId.get(e.id())||0)*ae}calculateScrollRectDepth(e,t){return this.depthForLayer(e)+t*oe+1}updateDimensionsForAutoscale(e){this.dimensionsForAutoscale||(this.dimensionsForAutoscale={width:0,height:0}),this.dimensionsForAutoscale.width=Math.max(e.width(),this.dimensionsForAutoscale.width),this.dimensionsForAutoscale.height=Math.max(e.height(),this.dimensionsForAutoscale.height)}calculateLayerRect(e){if(!this.visibleLayers.has(e))return;const t=new p(e),i=new he(t);i.setVertices(e.quad(),this.depthForLayer(e)),this.appendRect(i),this.updateDimensionsForAutoscale(e)}appendRect(e){const t=e.relatedObject,i=u.isEqual(this.lastSelection[G.Selected],t),s=u.isEqual(this.lastSelection[G.Hovered],t);if(i)e.borderColor=Z;else if(s){e.borderColor=Q;const t=e.fillColor||[255,255,255,1],i=ie;e.fillColor=[t[0]*i[0]/255,t[1]*i[1]/255,t[2]*i[2]/255,t[3]*i[3]]}else e.borderColor=J;e.lineWidth=i?re:se,this.rects.push(e)}calculateLayerScrollRects(e){const t=e.scrollRects();for(let i=0;i<t.length;++i){const s=new m(e,i),r=new he(s);r.calculateVerticesFromRect(e,t[i].rect,this.calculateScrollRectDepth(e,i)),r.fillColor=te,this.appendRect(r)}}calculateLayerTileRects(e){const t=this.textureManager.tilesForLayer(e);for(let i=0;i<t.length;++i){const s=t[i];if(!s.texture)continue;const r=new g(e,{rect:s.rect,snapshot:s.snapshot}),n=new he(r);this.snapshotLayers.has(e)||this.snapshotLayers.set(e,r),n.calculateVerticesFromRect(e,s.rect,this.depthForLayer(e)+1),n.texture=s.texture,this.appendRect(n)}}calculateRects(){if(this.rects=[],this.snapshotLayers.clear(),this.dimensionsForAutoscale={width:0,height:0},this.layerTree&&this.layerTree.forEachLayer(this.calculateLayerRect.bind(this)),this.showSlowScrollRectsSetting&&this.showSlowScrollRectsSetting.get()&&this.layerTree&&this.layerTree.forEachLayer(this.calculateLayerScrollRects.bind(this)),this.layerTexture&&this.visibleLayers.has(this.layerTexture.layer)){const e=this.layerTexture.layer,t=new p(e),i=new he(t);i.setVertices(e.quad(),this.depthForLayer(e)),i.texture=this.layerTexture.texture,this.appendRect(i)}else this.showPaints()&&this.layerTree&&this.layerTree.forEachLayer(this.calculateLayerTileRects.bind(this))}makeColorsArray(e){let t=[];const i=[e[0]/255,e[1]/255,e[2]/255,e[3]];for(let e=0;e<4;e++)t=t.concat(i);return t}setVertexAttribute(e,t,i){const s=this.gl;if(!s)return;const r=s.createBuffer();s.bindBuffer(s.ARRAY_BUFFER,r),s.bufferData(s.ARRAY_BUFFER,new Float32Array(t),s.STATIC_DRAW),s.vertexAttribPointer(e,i,s.FLOAT,!1,0,0)}drawRectangle(e,t,i,s){const r=this.gl;if(i=i||[255,255,255,1],!this.shaderProgram)return;const n=F.get(this.shaderProgram),a=X.get(this.shaderProgram),o=j.get(this.shaderProgram);if(void 0!==n&&this.setVertexAttribute(n,e,3),void 0!==a&&this.setVertexAttribute(a,[0,1,1,1,1,0,0,0],2),void 0!==o&&this.setVertexAttribute(o,this.makeColorsArray(i),i.length),!r)return;const l=Y.get(this.shaderProgram);s?l&&(r.activeTexture(r.TEXTURE0),r.bindTexture(r.TEXTURE_2D,s),r.uniform1i(l,0)):this.whiteTexture&&r.bindTexture(r.TEXTURE_2D,this.whiteTexture);const h=e.length/3;r.drawArrays(t,0,h)}drawTexture(e,t,i){this.gl&&this.drawRectangle(e,this.gl.TRIANGLE_FAN,i,t)}drawViewportAndChrome(){if(!this.layerTree)return;const t=this.layerTree.viewportSize();if(!t)return;const i=!e.Settings.Settings.instance().moduleSetting("frame-viewer-hide-chrome-window").get()&&this.chromeTextures.length>=3&&this.chromeTextures.indexOf(void 0)<0,s=(this.maxDepth+1)*ae,r=Math.ceil(ne*this.scale);let n=[t.width,0,s,t.width,t.height,s,0,t.height,s,0,0,s];if(!this.gl)return;if(this.gl.lineWidth(r),this.drawRectangle(n,i?this.gl.LINE_STRIP:this.gl.LINE_LOOP,ee),!i)return;const a=this.layerTree.viewportSize();if(!a)return;const o=ne/2,l=a.width+2*o;if(this.chromeTextures[0]&&this.chromeTextures[2]){const e=z.get(this.chromeTextures[0])||{naturalHeight:0,naturalWidth:0},t=e.naturalHeight,i=z.get(this.chromeTextures[2])||{naturalHeight:0,naturalWidth:0},r=l-e.naturalWidth-i.naturalWidth;let a=-o;const h=-t;for(let e=0;e<this.chromeTextures.length;++e){const i=this.chromeTextures[e];if(!i)continue;const o=z.get(i);if(!o)continue;const c=1===e?r:o.naturalWidth;if(c<0||a+c>l)break;n=[a,h,s,a+c,h,s,a+c,h+t,s,a,h+t,s],this.drawTexture(n,this.chromeTextures[e]),a+=c}}}drawViewRect(e){if(!this.gl)return;const t=e.vertices;e.texture?this.drawTexture(t,e.texture,e.fillColor||void 0):e.fillColor&&this.drawRectangle(t,this.gl.TRIANGLE_FAN,e.fillColor),this.gl.lineWidth(e.lineWidth),e.borderColor&&this.drawRectangle(t,this.gl.LINE_LOOP,e.borderColor)}update(){this.isShowing()?this.updateScheduled||(this.updateScheduled=!0,requestAnimationFrame((()=>requestAnimationFrame((()=>{this.updateScheduled=!1,this.innerUpdate()}))))):this.needsUpdate=!0}innerUpdate(){if(!this.layerTree?.root())return void this.failBanner.show(this.contentElement);const e=this.initGLIfNecessary();if(!e)return this.failBanner.detach(),this.failBanner=this.webglDisabledBanner(),void this.failBanner.show(this.contentElement);this.failBanner.detach();const t=this.canvasElement.width,i=this.canvasElement.height;this.calculateDepthsAndVisibility(),this.calculateRects(),this.updateTransformAndConstraints(),e.viewport(0,0,t,i),e.clear(e.COLOR_BUFFER_BIT|e.DEPTH_BUFFER_BIT),this.rects.forEach(this.drawViewRect.bind(this)),this.drawViewportAndChrome()}webglDisabledBanner(){const e=new s.EmptyWidget.EmptyWidget(_(V.cantDisplayLayers),_(V.webglSupportIsDisabledInYour));return e.contentElement.appendChild(t.i18n.getFormatLocalizedString(U,V.checkSForPossibleReasons,{PH1:s.XLink.XLink.create("about:gpu",void 0,void 0,void 0,"about-gpu")})),e}selectionFromEventPoint(e){const t=e;if(!this.layerTree)return null;let i=1/0,s=null;const r=(new WebKitCSSMatrix).scale(1,-1,-1).translate(-1,-1,0).multiply(this.projectionMatrix),n=(t.clientX-this.canvasElement.getBoundingClientRect().left)*window.devicePixelRatio,a=-(t.clientY-this.canvasElement.getBoundingClientRect().top)*window.devicePixelRatio;return this.rects.forEach((function(e){if(!e.relatedObject)return;const t=e.intersectWithLine(r,n,a);t&&t<i&&(i=t,s=e.relatedObject)})),s}createVisibilitySetting(t,i,r,n){const a=e.Settings.Settings.instance().createSetting(i,r);return a.setTitle(t),a.addChangeListener(this.update,this),n.appendToolbarItem(new s.Toolbar.ToolbarSettingCheckbox(a)),a}initToolbar(){this.panelToolbar=this.transformController.toolbar(),this.contentElement.appendChild(this.panelToolbar),this.showPaintsSetting=this.createVisibilitySetting(_(V.paints),"frame-viewer-show-paints",!1,this.panelToolbar),this.showSlowScrollRectsSetting=this.createVisibilitySetting(_(V.slowScrollRects),"frame-viewer-show-slow-scroll-rects",!0,this.panelToolbar),this.showPaintsSetting.addChangeListener(this.updatePaints,this),e.Settings.Settings.instance().moduleSetting("frame-viewer-hide-chrome-window").addChangeListener(this.update,this)}onContextMenu(e){const t=new s.ContextMenu.ContextMenu(e);t.defaultSection().appendItem(_(V.resetView),(()=>this.transformController.resetAndNotify()),{jslogContext:"layers.3d-center"});const i=this.selectionFromEventPoint(e);i&&"Snapshot"===i.type()&&t.defaultSection().appendItem(_(V.showPaintProfiler),(()=>this.dispatchEventToListeners("PaintProfilerRequested",i)),{jslogContext:"layers.paint-profiler"}),this.layerViewHost.showContextMenu(t,i)}onMouseMove(e){e.which||this.layerViewHost.hoverObject(this.selectionFromEventPoint(e))}onMouseDown(e){const t=e;this.mouseDownX=t.clientX,this.mouseDownY=t.clientY}onMouseUp(e){const t=e;this.mouseDownX&&Math.abs(t.clientX-this.mouseDownX)<6&&Math.abs(t.clientY-(this.mouseDownY||0))<6&&(this.canvasElement.focus(),this.layerViewHost.selectObject(this.selectionFromEventPoint(e))),delete this.mouseDownX,delete this.mouseDownY}onDoubleClick(e){const t=this.selectionFromEventPoint(e);t&&("Snapshot"===t.type()||t.layer())&&this.dispatchEventToListeners("PaintProfilerRequested",t),e.stopPropagation()}updatePaints(){this.showPaints()?(this.textureManager.setLayerTree(this.layerTree),this.textureManager.forceUpdate()):this.textureManager.reset(),this.update()}showPaints(){return!!this.showPaintsSetting&&this.showPaintsSetting.get()}}var G;!function(e){e.Hovered="hovered",e.Selected="selected"}(G||(G={}));const K="precision mediump float;\nvarying vec4 vColor;\nvarying vec2 vTextureCoord;\nuniform sampler2D uSampler;\nvoid main(void)\n{\n gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.s, vTextureCoord.t)) * vColor;\n}",$="attribute vec3 aVertexPosition;\nattribute vec2 aTextureCoord;\nattribute vec4 aVertexColor;\nuniform mat4 uPMatrix;\nvarying vec2 vTextureCoord;\nvarying vec4 vColor;\nvoid main(void)\n{\ngl_Position = uPMatrix * vec4(aVertexPosition, 1.0);\nvColor = aVertexColor;\nvTextureCoord = aTextureCoord;\n}",Q=[0,0,255,1],Z=[0,255,0,1],J=[0,0,0,1],ee=[160,160,160,1],te=[178,100,100,.6],ie=[200,200,255,1],se=1,re=2,ne=3,ae=20,oe=4;class le{textureUpdatedCallback;throttler;scale;active;queue;tilesByLayer;gl;constructor(t){this.textureUpdatedCallback=t,this.throttler=new e.Throttler.Throttler(0),this.scale=0,this.active=!1,this.reset()}static createTextureForImage(e,t){if(!e)throw new Error("WebGLRenderingContext not provided");const i=e.createTexture();if(!i)throw new Error("Unable to create texture");return z.set(i,t),e.bindTexture(e.TEXTURE_2D,i),e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,1),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.bindTexture(e.TEXTURE_2D,null),i}reset(){this.tilesByLayer&&this.setLayerTree(null),this.tilesByLayer=new Map,this.queue=[]}setContext(e){this.gl=e,this.scale&&this.updateTextures()}suspend(){this.active=!1}resume(){this.active=!0,this.queue.length&&this.update()}setLayerTree(e){const t=new Set,i=Array.from(this.tilesByLayer.keys());e&&e.forEachLayer((e=>{e.drawsContent()&&(t.add(e),this.tilesByLayer.has(e)||(this.tilesByLayer.set(e,[]),this.layerNeedsUpdate(e)))})),i.length||this.forceUpdate();for(const e of i){if(t.has(e))continue;const i=this.tilesByLayer.get(e);i&&i.forEach((e=>e.dispose())),this.tilesByLayer.delete(e)}}setSnapshotsForLayer(e,t){const i=new Map((this.tilesByLayer.get(e)||[]).map((e=>[e.snapshot,e]))),s=[],r=[];for(const e of t){const t=i.get(e.snapshot);t?(r.push(t),i.delete(e.snapshot)):s.push(new ce(e))}this.tilesByLayer.set(e,r.concat(s));for(const e of i.values())e.dispose();const n=this.gl;return n&&this.scale?Promise.all(s.map((e=>e.update(n,this.scale)))).then(this.textureUpdatedCallback):Promise.resolve()}setScale(e){this.scale&&this.scale>=e||(this.scale=e,this.updateTextures())}tilesForLayer(e){return this.tilesByLayer.get(e)||[]}layerNeedsUpdate(e){this.queue.indexOf(e)<0&&this.queue.push(e),this.active&&this.throttler.schedule(this.update.bind(this))}forceUpdate(){this.queue.forEach((e=>this.updateLayer(e))),this.queue=[],this.update()}update(){const e=this.queue.shift();return e?(this.queue.length&&this.throttler.schedule(this.update.bind(this)),this.updateLayer(e)):Promise.resolve()}updateLayer(e){return Promise.all(e.snapshots()).then((t=>this.setSnapshotsForLayer(e,t.filter((e=>null!==e)))))}updateTextures(){if(this.gl&&this.scale)for(const e of this.tilesByLayer.values())for(const t of e){const e=t.updateScale(this.gl,this.scale);e&&e.then(this.textureUpdatedCallback)}}}class he{relatedObject;lineWidth;borderColor;fillColor;texture;vertices;constructor(e){this.relatedObject=e,this.lineWidth=1,this.borderColor=null,this.fillColor=null,this.texture=null}setVertices(e,t){this.vertices=[e[0],e[1],t,e[2],e[3],t,e[4],e[5],t,e[6],e[7],t]}calculatePointOnQuad(e,t,i){const s=e[0],r=e[1],n=e[2],a=e[3],o=e[4],l=e[5],h=e[6],c=e[7],d=s+t*(n-s),u=r+t*(a-r);return[d+i*(h+t*(o-h)-d),u+i*(c+t*(l-c)-u)]}calculateVerticesFromRect(e,t,i){const s=e.quad(),r=t.x/e.width(),n=(t.x+t.width)/e.width(),a=t.y/e.height(),o=(t.y+t.height)/e.height(),l=this.calculatePointOnQuad(s,r,a).concat(this.calculatePointOnQuad(s,n,a)).concat(this.calculatePointOnQuad(s,n,o)).concat(this.calculatePointOnQuad(s,r,o));this.setVertices(l,i)}intersectWithLine(e,t,i){let r;const n=[];for(r=0;r<4;++r)n[r]=s.Geometry.multiplyVectorByMatrixAndNormalize(new s.Geometry.Vector(this.vertices[3*r],this.vertices[3*r+1],this.vertices[3*r+2]),e);const a=s.Geometry.crossProduct(s.Geometry.subtract(n[1],n[0]),s.Geometry.subtract(n[2],n[1])),o=a.x,l=a.y,h=a.z,c=-(-(o*n[0].x+l*n[0].y+h*n[0].z)+o*t+l*i)/h,d=new s.Geometry.Vector(t,i,c),u=n.map(s.Geometry.subtract.bind(null,d));for(r=0;r<u.length;++r){if(s.Geometry.scalarProduct(a,s.Geometry.crossProduct(u[r],u[(r+1)%u.length]))<0)return}return c}}class ce{snapshot;rect;scale;texture;gl;constructor(e){this.snapshot=e.snapshot,this.rect=e.rect,this.scale=0,this.texture=null}dispose(){this.snapshot.release(),this.texture&&(this.gl.deleteTexture(this.texture),this.texture=null)}updateScale(e,t){return this.texture&&this.scale>=t?null:this.update(e,t)}async update(e,t){this.gl=e,this.scale=t;const i=await this.snapshot.replay(t),r=i?await s.UIUtils.loadImage(i):null;this.texture=r?le.createTextureForImage(e,r):null}}var de=Object.freeze({__proto__:null,BorderColor:J,BorderWidth:se,FragmentShader:K,HoveredBorderColor:Q,HoveredImageMaskColor:ie,LayerSpacing:ae,LayerTextureManager:le,Layers3DView:q,get OutlineType(){return G},Rectangle:he,ScrollRectBackgroundColor:te,ScrollRectSpacing:oe,SelectedBorderColor:Z,SelectedBorderWidth:re,Tile:ce,VertexShader:$,ViewportBorderColor:ee,ViewportBorderWidth:ne}),ue={cssText:`.paint-profiler-overview{background-color:var(--sys-color-cdt-base-container)}.paint-profiler-canvas-container{flex:auto;position:relative}.paint-profiler-pie-chart{width:60px!important;height:60px!important;padding:2px;overflow:hidden;font-size:10px}.paint-profiler-canvas-container canvas{z-index:200;background-color:var(--sys-color-cdt-base-container);opacity:95%;height:100%;width:100%}.paint-profiler-canvas-container .overview-grid-window-resizer{z-index:2000}\n/*# sourceURL=${import.meta.resolve("./paintProfiler.css")} */\n`};const pe={profiling:"Profiling…",shapes:"Shapes",bitmap:"Bitmap",text:"Text",misc:"Misc",profilingResults:"Profiling results",commandLog:"Command Log"},me=t.i18n.registerUIStrings("panels/layer_viewer/PaintProfilerView.ts",pe),ge=t.i18n.getLocalizedString.bind(void 0,me);let ye=null,we=null;class fe extends(e.ObjectWrapper.eventMixin(s.Widget.HBox)){canvasContainer;progressBanner;pieChart;showImageCallback;canvas;context;selectionWindowInternal;innerBarWidth;minBarHeight;barPaddingWidth;outerBarWidth;pendingScale;scale;samplesPerBar;log;snapshot;logCategories;profiles;updateImageTimer;constructor(e){super(!0),this.registerRequiredCSS(ue),this.contentElement.classList.add("paint-profiler-overview"),this.canvasContainer=this.contentElement.createChild("div","paint-profiler-canvas-container"),this.progressBanner=this.contentElement.createChild("div","full-widget-dimmed-banner hidden"),this.progressBanner.textContent=ge(pe.profiling),this.pieChart=new o.PieChart.PieChart,this.populatePieChart(0,[]),this.pieChart.classList.add("paint-profiler-pie-chart"),this.contentElement.appendChild(this.pieChart),this.showImageCallback=e,this.canvas=this.canvasContainer.createChild("canvas","fill"),this.context=this.canvas.getContext("2d"),this.selectionWindowInternal=new o.OverviewGrid.Window(this.canvasContainer),this.selectionWindowInternal.addEventListener("WindowChanged",this.onWindowChanged,this),this.innerBarWidth=4*window.devicePixelRatio,this.minBarHeight=window.devicePixelRatio,this.barPaddingWidth=2*window.devicePixelRatio,this.outerBarWidth=this.innerBarWidth+this.barPaddingWidth,this.pendingScale=1,this.scale=this.pendingScale,this.samplesPerBar=0,this.log=[],this.reset()}static categories(){return ye||(ye={shapes:new xe("shapes",ge(pe.shapes),"rgb(255, 161, 129)"),bitmap:new xe("bitmap",ge(pe.bitmap),"rgb(136, 196, 255)"),text:new xe("text",ge(pe.text),"rgb(180, 255, 137)"),misc:new xe("misc",ge(pe.misc),"rgb(206, 160, 255)")}),ye}static initLogItemCategories(){if(!we){const e=fe.categories(),t={};t.Clear=e.misc,t.DrawPaint=e.misc,t.DrawData=e.misc,t.SetMatrix=e.misc,t.PushCull=e.misc,t.PopCull=e.misc,t.Translate=e.misc,t.Scale=e.misc,t.Concat=e.misc,t.Restore=e.misc,t.SaveLayer=e.misc,t.Save=e.misc,t.BeginCommentGroup=e.misc,t.AddComment=e.misc,t.EndCommentGroup=e.misc,t.ClipRect=e.misc,t.ClipRRect=e.misc,t.ClipPath=e.misc,t.ClipRegion=e.misc,t.DrawPoints=e.shapes,t.DrawRect=e.shapes,t.DrawOval=e.shapes,t.DrawRRect=e.shapes,t.DrawPath=e.shapes,t.DrawVertices=e.shapes,t.DrawDRRect=e.shapes,t.DrawBitmap=e.bitmap,t.DrawBitmapRectToRect=e.bitmap,t.DrawBitmapMatrix=e.bitmap,t.DrawBitmapNine=e.bitmap,t.DrawSprite=e.bitmap,t.DrawPicture=e.bitmap,t.DrawText=e.text,t.DrawPosText=e.text,t.DrawPosTextH=e.text,t.DrawTextOnPath=e.text,we=t}return we}static categoryForLogItem(e){const t=a.StringUtilities.toTitleCase(e.method),i=fe.initLogItemCategories();let s=i[t];return s||(s=fe.categories().misc,i[t]=s),s}onResize(){this.update()}async setSnapshotAndLog(e,t,i){if(this.reset(),this.snapshot=e,this.snapshot&&this.snapshot.addReference(),this.log=t,this.logCategories=this.log.map(fe.categoryForLogItem),!e)return this.update(),this.populatePieChart(0,[]),void this.selectionWindowInternal.setResizeEnabled(!1);this.selectionWindowInternal.setResizeEnabled(!0),this.progressBanner.classList.remove("hidden"),this.updateImage();const s=await e.profile(i);this.progressBanner.classList.add("hidden"),this.profiles=s,this.update(),this.updatePieChart()}setScale(e){const t=e>this.scale;this.pendingScale=Math.min(1,2*e),t&&this.snapshot&&this.updateImage()}update(){if(this.canvas.width=this.canvasContainer.clientWidth*window.devicePixelRatio,this.canvas.height=this.canvasContainer.clientHeight*window.devicePixelRatio,this.samplesPerBar=0,!this.profiles?.length||!this.logCategories)return;const e=Math.floor((this.canvas.width-2*this.barPaddingWidth)/this.outerBarWidth),t=this.log.length;this.samplesPerBar=Math.ceil(t/e);let i=0;const s=[],r=[];let n={};for(let e=0,a=0,o=0;e<t;){let l=this.logCategories[e]?.name||"misc";const h=this.log[e].commandIndex;for(let e=0;e<this.profiles.length;e++){const t=this.profiles[e][h];o+=t,n[l]=(n[l]||0)+t}if(++e,e-a===this.samplesPerBar||e===t){const t=this.profiles.length*(e-a);for(l in o/=t,n)n[l]/=t;s.push(o),r.push(n),o>i&&(i=o),o=0,n={},a=e}}const a=4*window.devicePixelRatio,o=(this.canvas.height-a-this.minBarHeight)/i;for(let e=0;e<s.length;++e){for(const t in r[e])r[e][t]*=(s[e]*o+this.minBarHeight)/s[e];this.renderBar(e,r[e])}}renderBar(e,t){const i=fe.categories();let s=0;const r=this.barPaddingWidth+e*this.outerBarWidth;for(const e in i){if(!t[e])continue;s+=t[e];const n=this.canvas.height-s;this.context.fillStyle=i[e].color,this.context.fillRect(r,n,this.innerBarWidth,t[e])}}onWindowChanged(){this.dispatchEventToListeners("WindowChanged"),this.updatePieChart(),this.updateImageTimer||(this.updateImageTimer=window.setTimeout(this.updateImage.bind(this),100))}updatePieChart(){const{total:e,slices:t}=this.calculatePieChart();this.populatePieChart(e,t)}calculatePieChart(){const e=this.selectionWindow();if(!this.profiles?.length||!e)return{total:0,slices:[]};let t=0;const i={};for(let s=e.left;s<e.right;++s){const e=this.log[s],r=fe.categoryForLogItem(e);i[r.color]=i[r.color]||0;for(let s=0;s<this.profiles.length;++s){const n=this.profiles[s][e.commandIndex];t+=n,i[r.color]+=n}}const s=[];for(const e in i)s.push({value:i[e]/this.profiles.length,color:e,title:""});return{total:t/this.profiles.length,slices:s}}populatePieChart(e,t){this.pieChart.data={chartName:ge(pe.profilingResults),size:55,formatter:this.formatPieChartTime.bind(this),showLegend:!1,total:e,slices:t}}formatPieChartTime(e){return t.TimeUtilities.millisToString(1e3*e,!0)}selectionWindow(){if(!this.log)return null;const e=(this.selectionWindowInternal.windowLeftRatio||0)*this.canvas.width,t=(this.selectionWindowInternal.windowRightRatio||0)*this.canvas.width,i=Math.floor(e/this.outerBarWidth),s=Math.floor((t+this.innerBarWidth-this.barPaddingWidth/2)/this.outerBarWidth);return{left:a.NumberUtilities.clamp(i*this.samplesPerBar,0,this.log.length-1),right:a.NumberUtilities.clamp(s*this.samplesPerBar,0,this.log.length)}}updateImage(){let e,t;delete this.updateImageTimer;const i=this.selectionWindow();this.profiles?.length&&i&&(e=this.log[i.left].commandIndex,t=this.log[i.right-1].commandIndex);const s=this.pendingScale;this.snapshot&&this.snapshot.replay(s,e,t).then((e=>{e&&(this.scale=s,this.showImageCallback(e))}))}reset(){this.snapshot&