import{i18n as e}from"../i18n/i18n.js";import*as t from"../third_party/lit-html/lit-html.js";import{Directives as s}from"../third_party/lit-html/lit-html.js";import{assertNever as r}from"../platform/platform.js";import{GetStylesheet as n,SetCSSProperty as i}from"../component_helpers/component_helpers.js";import{SimpleHistoryManager as o}from"../common/common.js";import{RemoteObject as a,SDKModel as d,RuntimeModel as l,DebuggerModel as c}from"../sdk/sdk.js";import{Widget as h,TabbedPane as u,ViewManager as p}from"../ui/ui.js";const g={enterAddress:"Enter address",goBackInAddressHistory:"Go back in address history",goForwardInAddressHistory:"Go forward in address history",previousPage:"Previous page",nextPage:"Next page",refresh:"Refresh"},m=e.registerUIStrings("linear_memory_inspector/LinearMemoryNavigator.ts",g),y=e.getLocalizedString.bind(void 0,m),{render:v,html:f}=t;class b extends Event{constructor(e,t){super("address-input-changed"),this.data={address:e,mode:t}}}class w extends Event{constructor(e){super("page-navigation",{}),this.data=e}}class x extends Event{constructor(e){super("history-navigation",{}),this.data=e}}class _ extends Event{constructor(){super("refresh-requested",{})}}class E extends HTMLElement{constructor(){super(...arguments),this.shadow=this.attachShadow({mode:"open"}),this.address="0",this.error=void 0,this.valid=!0}set data(e){this.address=e.address,this.error=e.error,this.valid=e.valid,this.render();const t=this.shadow.querySelector(".address-input");t&&("Submitted"===e.mode?t.blur():"InvalidSubmit"===e.mode&&t.select())}render(){const e=f`
      <style>
        .navigator {
          min-height: 24px;
          display: flex;
          flex-wrap: nowrap;
          justify-content: space-between;
          overflow: hidden;
          align-items: center;
          background-color: var(--color-background);
          color: var(--color-text-primary);
        }

        .navigator-item {
          display: flex;
          white-space: nowrap;
          overflow: hidden;
        }

        .address-input {
          text-align: center;
          outline: none;
          color: var(--color-text-primary);
          border: 1px solid var(--color-background-elevation-2);
          background: transparent;
        }

        .address-input.invalid {
          color: var(--color-accent-red);
        }

        .navigator-button {
          display: flex;
          width: 20px;
          height: 20px;
          background: transparent;
          overflow: hidden;
          border: none;
          padding: 0;
          outline: none;
          justify-content: center;
          align-items: center;
          cursor: pointer;
        }

        .navigator-button devtools-icon {
          height: 14px;
          width: 14px;
          min-height: 14px;
          min-width: 14px;
        }

        .navigator-button:hover devtools-icon {
          --icon-color: var(--color-text-primary);
        }

        .navigator-button:focus devtools-icon {
          --icon-color: var(--color-text-secondary);
        }
        </style>
      <div class="navigator">
        <div class="navigator-item">
          ${this.createButton("ic_undo_16x16_icon",y(g.goBackInAddressHistory),new x("Backward"))}
          ${this.createButton("ic_redo_16x16_icon",y(g.goForwardInAddressHistory),new x("Forward"))}
        </div>
        <div class="navigator-item">
          ${this.createButton("ic_page_prev_16x16_icon",y(g.previousPage),new w("Backward"))}
          ${this.createAddressInput()}
          ${this.createButton("ic_page_next_16x16_icon",y(g.nextPage),new w("Forward"))}
        </div>
        ${this.createButton("refresh_12x12_icon",y(g.refresh),new _)}
      </div>
      `;v(e,this.shadow,{eventContext:this})}createAddressInput(){const e={"address-input":!0,invalid:!this.valid};return f`
      <input class=${s.classMap(e)} data-input="true" .value=${this.address}
        title=${this.valid?y(g.enterAddress):this.error} @change=${this.onAddressChange.bind(this,"Submitted")} @input=${this.onAddressChange.bind(this,"Edit")}/>`}onAddressChange(e,t){const s=t.target;this.dispatchEvent(new b(s.value,e))}createButton(e,t,s){return f`
      <button class="navigator-button"
        data-button=${s.type} title=${t}
        @click=${this.dispatchEvent.bind(this,s)}>
        <devtools-icon .data=${{iconName:e,color:"var(--color-text-secondary)",width:"14px"}}>
        </devtools-icon>
      </button>`}}customElements.define("devtools-linear-memory-inspector-navigator",E);var I=Object.freeze({__proto__:null,UIStrings:g,AddressInputChangedEvent:b,PageNavigationEvent:w,HistoryNavigationEvent:x,RefreshRequestedEvent:_,LinearMemoryNavigator:E});const T={dec:"dec",hex:"hex",oct:"oct",sci:"sci",none:"none",littleEndian:"Little Endian",bigEndian:"Big Endian",integerBit:"Integer 8-bit",integer16Bit:"Integer 16-bit",integer32Bit:"Integer 32-bit",integer64Bit:"Integer 64-bit",floatBit:"Float 32-bit",float64Bit:"Float 64-bit",string:"String"},S=e.registerUIStrings("linear_memory_inspector/ValueInterpreterDisplayUtils.ts",T),M=e.getLocalizedString.bind(void 0,S);function R(e){switch(e){case"dec":return M(T.dec);case"hex":return M(T.hex);case"oct":return M(T.oct);case"sci":return M(T.sci);case"none":return M(T.none);default:return r(e,"Unknown mode: "+e)}}function B(e){switch(e){case"Little Endian":return M(T.littleEndian);case"Big Endian":return M(T.bigEndian);default:return r(e,"Unknown endianness: "+e)}}function $(e){switch(e){case"Integer 8-bit":return M(T.integerBit);case"Integer 16-bit":return M(T.integer16Bit);case"Integer 32-bit":return M(T.integer32Bit);case"Integer 64-bit":return M(T.integer64Bit);case"Float 32-bit":return M(T.floatBit);case"Float 64-bit":return M(T.float64Bit);case"String":return M(T.string);default:return r(e,"Unknown value type: "+e)}}function A(e,t){switch(e){case"Integer 8-bit":case"Integer 16-bit":case"Integer 32-bit":case"Integer 64-bit":return"dec"===t||"hex"===t||"oct"===t;case"Float 32-bit":case"Float 64-bit":return"sci"===t||"dec"===t;case"String":return"none"===t;default:return r(e,"Unknown value type: "+e)}}function O(e){switch(e){case"Integer 8-bit":case"Integer 16-bit":case"Integer 32-bit":case"Integer 64-bit":case"Float 32-bit":case"Float 64-bit":return!0;default:return!1}}function P(e){const t=new DataView(e.buffer),s="Little Endian"===e.endianness;let n;try{switch(e.type){case"Integer 8-bit":return n=e.signed?t.getInt8(0):t.getUint8(0),C(n,e.mode);case"Integer 16-bit":return n=e.signed?t.getInt16(0,s):t.getUint16(0,s),C(n,e.mode);case"Integer 32-bit":return n=e.signed?t.getInt32(0,s):t.getUint32(0,s),C(n,e.mode);case"Integer 64-bit":return n=e.signed?t.getBigInt64(0,s):t.getBigUint64(0,s),C(n,e.mode);case"Float 32-bit":return n=t.getFloat32(0,s),L(n,e.mode);case"Float 64-bit":return n=t.getFloat64(0,s),L(n,e.mode);case"String":throw new Error(`Type ${e.type} is not yet implemented`);default:return r(e.type,"Unknown value type: "+e.type)}}catch(e){return"N/A"}}function L(e,t){switch(t){case"dec":return e.toFixed(2).toString();case"sci":return e.toExponential(2).toString();default:throw new Error(`Unknown mode for floats: ${t}.`)}}function C(e,t){switch(t){case"dec":return e.toString();case"hex":return e.toString(16);case"oct":return e.toString(8);default:throw new Error(`Unknown mode for integers: ${t}.`)}}var V=Object.freeze({__proto__:null,UIStrings:T,VALUE_INTEPRETER_MAX_NUM_BYTES:8,valueTypeModeToLocalizedString:R,endiannessToLocalizedString:B,valueTypeToLocalizedString:$,isValidMode:A,isNumber:O,format:P,formatFloat:L,formatInteger:C});const k={unsignedValue:"Unsigned value",signedValue:"Signed value"},U=e.registerUIStrings("linear_memory_inspector/ValueInterpreterDisplay.ts",k),j=e.getLocalizedString.bind(void 0,U),{render:z,html:F}=t,N=new Map([["Integer 8-bit","dec"],["Integer 16-bit","dec"],["Integer 32-bit","dec"],["Integer 64-bit","dec"],["Float 32-bit","dec"],["Float 64-bit","dec"],["String","none"]]),D=Array.from(N.keys());class H extends HTMLElement{constructor(){super(...arguments),this.shadow=this.attachShadow({mode:"open"}),this.endianness="Little Endian",this.buffer=new ArrayBuffer(0),this.valueTypes=new Set,this.valueTypeModeConfig=N}set data(e){this.buffer=e.buffer,this.endianness=e.endianness,this.valueTypes=e.valueTypes,this.valueTypeModeConfig=N,e.valueTypeModes&&e.valueTypeModes.forEach(((e,t)=>{A(t,e)&&this.valueTypeModeConfig.set(t,e)})),this.render()}render(){z(F`
      <style>
        :host {
          flex: auto;
          display: flex;
        }

        .mode-type {
          color: var(--text-highlight-color); /* stylelint-disable-line plugin/use_theme_colors */
          /* See: crbug.com/1152736 for color variable migration. */
        }

        .value-types {
          width: 100%;
          display: grid;
          grid-template-columns: auto auto 1fr;
          grid-column-gap: 24px;
          grid-row-gap: 4px;
          overflow: hidden;
          padding-left: 12px;
          padding-right: 12px;
        }

        .value-type-cell-multiple-values {
          gap: 5px;
        }

        .value-type-cell {
          height: 21px;
          text-overflow: ellipsis;
          white-space: nowrap;
          overflow: hidden;
          display: flex;
        }

        .value-type-cell-no-mode {
          grid-column: 1 / 3;
        }

      </style>
      <div class="value-types">
        ${D.map((e=>this.valueTypes.has(e)?this.showValue(e):""))}
      </div>
    `,this.shadow,{eventContext:this})}showValue(e){const t=this.valueTypeModeConfig.get(e);if(!t)throw new Error("No mode found for type "+e);const s=$(e),r=R(t),n=this.parse({type:e,signed:!1}),i=this.parse({type:e,signed:!0}),o=i!==n;return F`
      ${O(e)?F`
          <span class="value-type-cell">${s}</span>
          <span class="mode-type value-type-cell">${r}</span>`:F`
          <span class="value-type-cell-no-mode value-type-cell">${s}</span>`}

        ${o?F`
          <div class="value-type-cell-multiple-values value-type-cell">
            <span data-value="true" title=${j(k.unsignedValue)}>${n}</span>
            <span>/<span>
            <span data-value="true" title=${j(k.signedValue)}>${i}</span>
          </div>`:F`
          <span class="value-type-cell" data-value="true">${n}</span>`}
    `}parse(e){const t=this.valueTypeModeConfig.get(e.type);return t?P({buffer:this.buffer,type:e.type,endianness:this.endianness,signed:e.signed||!1,mode:t}):(console.error("No known way of showing value for "+e.type),"N/A")}}customElements.define("devtools-linear-memory-inspector-interpreter-display",H);var q=Object.freeze({__proto__:null,UIStrings:k,ValueInterpreterDisplay:H});const{render:G,html:Y}=t,W=new Map([["Integer",["Integer 8-bit","Integer 16-bit","Integer 32-bit","Integer 64-bit"]],["Floating point",["Float 32-bit","Float 64-bit"]]]);class Z extends Event{constructor(e,t){super("type-toggle"),this.data={type:e,checked:t}}}class K extends HTMLElement{constructor(){super(...arguments),this.shadow=this.attachShadow({mode:"open"}),this.valueTypes=new Set}set data(e){this.valueTypes=e.valueTypes,this.render()}render(){G(Y`
      <style>
        :host {
          flex: auto;
          display: flex;
          min-height: 20px;
        }

        .settings {
          display: flex;
          flex-wrap: wrap;
          margin: 0 12px 12px 12px;
          column-gap: 45px;
          row-gap: 15px;
        }

        .value-types-selection {
          display: flex;
          flex-direction: column;
        }

        .value-types-selection + .value-types-selection {
          margin-left: 45px;
        }

        .group {
          font-weight: bold;
          margin-bottom: 11px;
        }

        .type-label {
          white-space: nowrap;
        }

        .group + .type-label {
          margin-top: 5px;
        }

        .type-label input {
          margin: 0 6px 0 0;
          padding: 0;
        }

        .type-label + .type-label {
          margin-top: 6px;
        }
      </style>
      <div class="settings">
       ${[...W.keys()].map((e=>Y`
          <div class="value-types-selection">
            <span class="group">${e}</span>
            ${this.plotTypeSelections(e)}
          </div>
        `))}
      </div>
      `,this.shadow,{eventContext:this})}plotTypeSelections(e){const t=W.get(e);if(!t)throw new Error("Unknown group "+e);return Y`
      ${t.map((e=>Y`
          <label class="type-label" title=${$(e)}>
            <input data-input="true" type="checkbox" .checked=${this.valueTypes.has(e)} @change=${t=>this.onTypeToggle(e,t)}>
            <span data-title="true">${$(e)}</span>
          </label>
     `))}`}onTypeToggle(e,t){const s=t.target;this.dispatchEvent(new Z(e,s.checked))}}customElements.define("devtools-linear-memory-inspector-interpreter-settings",K);var X=Object.freeze({__proto__:null,TypeToggleEvent:Z,ValueInterpreterSettings:K});const J={toggleValueTypeSettings:"Toggle value type settings",changeEndianness:"Change Endianness"},Q=e.registerUIStrings("linear_memory_inspector/LinearMemoryValueInterpreter.ts",J),ee=e.getLocalizedString.bind(void 0,Q),{render:te,html:se}=t,re=n.getStyleSheets;class ne extends Event{constructor(e){super("endianness-changed"),this.data=e}}class ie extends Event{constructor(e,t){super("value-type-toggled"),this.data={type:e,checked:t}}}class oe extends HTMLElement{constructor(){super(),this.shadow=this.attachShadow({mode:"open"}),this.endianness="Little Endian",this.buffer=new ArrayBuffer(0),this.valueTypes=new Set,this.valueTypeModeConfig=new Map,this.showSettings=!1,this.shadow.adoptedStyleSheets=[...re("ui/inspectorCommon.css",{enableLegacyPatching:!0})]}set data(e){this.endianness=e.endianness,this.buffer=e.value,this.valueTypes=e.valueTypes,this.valueTypeModeConfig=e.valueTypeModes||new Map,this.render()}render(){te(se`
      <style>
        :host {
          flex: auto;
          display: flex;
        }

        .value-interpreter {
          --text-highlight-color: #80868b;

          border: var(--divider-border, 1px solid #d0d0d0); /* stylelint-disable-line plugin/use_theme_colors */
          /*See: crbug.com/1152736 for color variable migration.*/
          background-color: var(--toolbar-bg-color, #f3f3f3); /* stylelint-disable-line plugin/use_theme_colors */
          /*See: crbug.com/1152736 for color variable migration.*/
          overflow: hidden;
          width: 400px;
        }

        .settings-toolbar {
          min-height: 26px;
          display: flex;
          flex-wrap: nowrap;
          justify-content: space-between;
          padding-left: 12px;
          padding-right: 12px;
          align-items: center;
        }

        .settings-toolbar-button {
          display: flex;
          justify-content: center;
          align-items: center;
          width: 20px;
          height: 20px;
          border: none;
          background-color: transparent;
          cursor: pointer;
        }

        .settings-toolbar-button devtools-icon {
          height: 14px;
          width: 14px;
          min-height: 14px;
          min-width: 14px;
        }

        .settings-toolbar-button.active devtools-icon {
          --icon-color: var(--color-primary);
        }

        .divider {
          display: block;
          height: 1px;
          margin-bottom: 12px;
          background-color: var(--divider-color, #d0d0d0); /* stylelint-disable-line plugin/use_theme_colors */
          /*See: crbug.com/1152736 for color variable migration.*/
        }
      </style>
      <div class="value-interpreter">
        <div class="settings-toolbar">
          ${this.renderSetting()}
          <button data-settings="true" class="settings-toolbar-button ${this.showSettings?"active":""}" title=${ee(J.toggleValueTypeSettings)} @click=${this.onSettingsToggle}>
            <devtools-icon
              .data=${{iconName:"settings_14x14_icon",color:"var(--color-text-secondary)",width:"14px"}}>
            </devtools-icon>
          </button>
        </div>
        <span class="divider"></span>
        <div>
          ${this.showSettings?se`
              <devtools-linear-memory-inspector-interpreter-settings
                .data=${{valueTypes:this.valueTypes}}
                @type-toggle=${this.onTypeToggle}>
              </devtools-linear-memory-inspector-interpreter-settings>`:se`
              <devtools-linear-memory-inspector-interpreter-display
                .data=${{buffer:this.buffer,valueTypes:this.valueTypes,endianness:this.endianness,valueTypeModes:this.valueTypeModeConfig}}>
              </devtools-linear-memory-inspector-interpreter-display>`}
        </div>
      </div>
    `,this.shadow,{eventContext:this})}onEndiannessChange(e){e.preventDefault();const t=e.target.value;this.dispatchEvent(new ne(t))}renderSetting(){const e=this.onEndiannessChange.bind(this);return se`
    <label data-endianness-setting="true" title=${ee(J.changeEndianness)}>
      <select class="chrome-select" data-endianness="true" @change=${e}>
        ${["Little Endian","Big Endian"].map((e=>se`<option value=${e} .selected=${this.endianness===e}>${B(e)}</option>`))}
      </select>
    </label>
    `}onSettingsToggle(){this.showSettings=!this.showSettings,this.render()}onTypeToggle(e){this.dispatchEvent(new ie(e.data.type,e.data.checked))}}customElements.define("devtools-linear-memory-inspector-interpreter",oe);var ae=Object.freeze({__proto__:null,UIStrings:J,EndiannessChangedEvent:ne,ValueTypeToggledEvent:ie,LinearMemoryValueInterpreter:oe});const de=/^0x[a-fA-F0-9]+$/,le=/^0$|[1-9]\d*$/;function ce(e){const t=e.number.toString(16).padStart(e.pad,"0").toUpperCase();return e.prefix?"0x"+t:t}function he(e){return ce({number:e,pad:8,prefix:!0})}function ue(e){const t=e.match(de),s=e.match(le);let r=void 0;return t&&t[0].length===e.length?r=parseInt(e,16):s&&s[0].length===e.length&&(r=parseInt(e,10)),r}var pe=Object.freeze({__proto__:null,HEXADECIMAL_REGEXP:de,DECIMAL_REGEXP:le,toHexString:ce,formatAddress:he,parseAddress:ue});const{render:ge,html:me}=t;class ye extends Event{constructor(e){super("byte-selected"),this.data=e}}class ve extends Event{constructor(e){super("resize"),this.data=e}}class fe extends HTMLElement{constructor(){super(...arguments),this.shadow=this.attachShadow({mode:"open"}),this.resizeObserver=new ResizeObserver((()=>this.resize())),this.isObservingResize=!1,this.memory=new Uint8Array,this.address=0,this.memoryOffset=0,this.numRows=1,this.numBytesInRow=fe.BYTE_GROUP_SIZE,this.focusOnByte=!0,this.lastKeyUpdateSent=void 0}set data(e){if(e.address<e.memoryOffset||e.address>e.memoryOffset+e.memory.length||e.address<0)throw new Error("Address is out of bounds.");if(e.memoryOffset<0)throw new Error("Memory offset has to be greater or equal to zero.");this.memory=e.memory,this.address=e.address,this.memoryOffset=e.memoryOffset,this.focusOnByte=e.focus,this.update()}connectedCallback(){i.set(this,"--byte-group-margin",fe.BYTE_GROUP_MARGIN+"px")}disconnectedCallback(){this.isObservingResize=!1,this.resizeObserver.disconnect()}update(){this.updateDimensions(),this.render(),this.focusOnView(),this.engageResizeObserver()}focusOnView(){if(this.focusOnByte){const e=this.shadow.querySelector(".view");e&&e.focus()}}resize(){this.update(),this.dispatchEvent(new ve(this.numBytesInRow*this.numRows))}updateDimensions(){if(0===this.clientWidth||0===this.clientHeight||!this.shadowRoot)return this.numBytesInRow=fe.BYTE_GROUP_SIZE,void(this.numRows=1);const e=this.shadowRoot.querySelector(".byte-cell"),t=this.shadowRoot.querySelector(".text-cell"),s=this.shadowRoot.querySelector(".divider"),r=this.shadowRoot.querySelector(".row");if(!(e&&t&&s&&r))return this.numBytesInRow=fe.BYTE_GROUP_SIZE,void(this.numRows=1);const n=e.getBoundingClientRect().width,i=t.getBoundingClientRect().width,o=fe.BYTE_GROUP_SIZE*(n+i)+fe.BYTE_GROUP_MARGIN,a=s.getBoundingClientRect().width,d=this.clientWidth-(e.getBoundingClientRect().left-this.getBoundingClientRect().left)-a;if(d<o)return this.numBytesInRow=fe.BYTE_GROUP_SIZE,void(this.numRows=1);this.numBytesInRow=Math.floor(d/o)*fe.BYTE_GROUP_SIZE,this.numRows=Math.floor(this.clientHeight/r.clientHeight)}engageResizeObserver(){this.resizeObserver&&!this.isObservingResize&&(this.resizeObserver.observe(this),this.isObservingResize=!0)}render(){ge(me`
      <style>
        :host {
          flex: auto;
          display: flex;
          min-height: 20px;
        }

        .view {
          overflow: hidden;
          text-overflow: ellipsis;
          box-sizing: border-box;
          background: var(--color-background);
          outline: none;
        }

        .row {
          display: flex;
          height: 20px;
          align-items: center;
        }

        .cell {
          text-align: center;
          border: 1px solid transparent;
          border-radius: 2px;
        }

        .cell.selected {
          border-color: var(--color-syntax-3);
          color: var(--color-syntax-3);
          background-color: var(--item-selection-bg-color);
        }

        .byte-cell {
          min-width: 21px;
          color: var(--color-text-primary);
        }

        .byte-group-margin {
          margin-left: var(--byte-group-margin);
        }

        .text-cell {
          min-width: 14px;
          color: var(--color-syntax-3);
        }

        .address {
          color: var(--color-text-disabled);
        }

        .address.selected {
          font-weight: bold;
          color: var(--color-text-primary);
        }

        .divider {
          width: 1px;
          height: inherit;
          background-color: var(--divider-color);
          margin: 0 4px 0 4px;
        }
      </style>
      <div class="view" tabindex="0" @keydown=${this.onKeyDown}>
          ${this.renderView()}
      </div>
      `,this.shadow,{eventContext:this})}onKeyDown(e){const t=e;let s=void 0;"ArrowUp"===t.code?s=this.address-this.numBytesInRow:"ArrowDown"===t.code?s=this.address+this.numBytesInRow:"ArrowLeft"===t.code?s=this.address-1:"ArrowRight"===t.code?s=this.address+1:"PageUp"===t.code?s=this.address-this.numBytesInRow*this.numRows:"PageDown"===t.code&&(s=this.address+this.numBytesInRow*this.numRows),void 0!==s&&s!==this.lastKeyUpdateSent&&(this.lastKeyUpdateSent=s,this.dispatchEvent(new ye(s)))}renderView(){const e=[];for(let t=0;t<this.numRows;++t)e.push(this.renderRow(t));return me`${e}`}renderRow(e){const{startIndex:t,endIndex:r}={startIndex:e*this.numBytesInRow,endIndex:(e+1)*this.numBytesInRow},n={address:!0,selected:Math.floor((this.address-this.memoryOffset)/this.numBytesInRow)===e};return me`
    <div class="row">
      <span class="${s.classMap(n)}">${ce({number:t+this.memoryOffset,pad:8,prefix:!1})}</span>
      <span class="divider"></span>
      ${this.renderByteValues(t,r)}
      <span class="divider"></span>
      ${this.renderCharacterValues(t,r)}
    </div>
    `}renderByteValues(e,t){const r=[];for(let n=e;n<t;++n){const t={cell:!0,"byte-cell":!0,"byte-group-margin":n!==e&&(n-e)%fe.BYTE_GROUP_SIZE==0,selected:n===this.address-this.memoryOffset},i=n<this.memory.length,o=i?me`${ce({number:this.memory[n],pad:2,prefix:!1})}`:"",a=n+this.memoryOffset,d=i?this.onSelectedByte.bind(this,a):"";r.push(me`<span class="${s.classMap(t)}" @click=${d}>${o}</span>`)}return me`${r}`}renderCharacterValues(e,t){const r=[];for(let n=e;n<t;++n){const e={cell:!0,"text-cell":!0,selected:this.address-this.memoryOffset===n},t=n<this.memory.length,i=t?me`${this.toAscii(this.memory[n])}`:"",o=t?this.onSelectedByte.bind(this,n+this.memoryOffset):"";r.push(me`<span class="${s.classMap(e)}" @click=${o}>${i}</span>`)}return me`${r}`}toAscii(e){return e>=20&&e<=127?String.fromCharCode(e):"."}onSelectedByte(e){this.dispatchEvent(new ye(e))}}fe.BYTE_GROUP_MARGIN=8,fe.BYTE_GROUP_SIZE=4,customElements.define("devtools-linear-memory-inspector-viewer",fe);var be=Object.freeze({__proto__:null,ByteSelectedEvent:ye,ResizeEvent:ve,LinearMemoryViewer:fe});const{render:we,html:xe}=t,_e={addressHasToBeANumberBetweenSAnd:"Address has to be a number between {PH1} and {PH2}"},Ee=e.registerUIStrings("linear_memory_inspector/LinearMemoryInspector.ts",_e),Ie=e.getLocalizedString.bind(void 0,Ee);class Te{constructor(e,t){if(this.address=0,e<0)throw new Error("Address should be a greater or equal to zero");this.address=e,this.callback=t}valid(){return!0}reveal(){this.callback(this.address)}}class Se extends Event{constructor(e,t,s){super("memory-request"),this.data={start:e,end:t,address:s}}}class Me extends Event{constructor(e){super("address-changed"),this.data=e}}class Re extends HTMLElement{constructor(){super(...arguments),this.shadow=this.attachShadow({mode:"open"}),this.history=new o.SimpleHistoryManager(10),this.memory=new Uint8Array,this.memoryOffset=0,this.outerMemoryLength=0,this.address=0,this.currentNavigatorMode="Submitted",this.currentNavigatorAddressLine=""+this.address,this.numBytesPerPage=4,this.valueTypes=new Set(["Integer 8-bit","Float 32-bit"]),this.endianness="Little Endian"}set data(e){if(e.address<e.memoryOffset||e.address>e.memoryOffset+e.memory.length||e.address<0)throw new Error("Address is out of bounds.");if(e.memoryOffset<0)throw new Error("Memory offset has to be greater or equal to zero.");this.memory=e.memory,this.memoryOffset=e.memoryOffset,this.outerMemoryLength=e.outerMemoryLength,this.setAddress(e.address),this.render()}render(){const{start:e,end:t}=this.getPageRangeForAddress(this.address,this.numBytesPerPage),s="Submitted"===this.currentNavigatorMode?he(this.address):this.currentNavigatorAddressLine,r=this.isValidAddress(s),n=Ie(_e.addressHasToBeANumberBetweenSAnd,{PH1:he(0),PH2:he(this.outerMemoryLength)}),i=r?void 0:n;we(xe`
      <style>
        :host {
          flex: auto;
          display: flex;
        }

        .view {
          width: 100%;
          display: flex;
          flex: 1;
          flex-direction: column;
          font-family: var(--monospace-font-family);
          font-size: var(--monospace-font-size);
          padding: 9px 12px 9px 7px;
        }

        devtools-linear-memory-inspector-navigator + devtools-linear-memory-inspector-viewer {
          margin-top: 12px;
        }

        .value-interpreter {
          display: flex;
        }
      </style>
      <div class="view">
        <devtools-linear-memory-inspector-navigator
          .data=${{address:s,valid:r,mode:this.currentNavigatorMode,error:i}}
          @refresh-requested=${this.onRefreshRequest}
          @address-input-changed=${this.onAddressChange}
          @page-navigation=${this.navigatePage}
          @history-navigation=${this.navigateHistory}></devtools-linear-memory-inspector-navigator>
        <devtools-linear-memory-inspector-viewer
          .data=${{memory:this.memory.slice(e-this.memoryOffset,t-this.memoryOffset),address:this.address,memoryOffset:e,focus:"Submitted"===this.currentNavigatorMode}}
          @byte-selected=${this.onByteSelected}
          @resize=${this.resize}>
        </devtools-linear-memory-inspector-viewer>
      </div>
      <div class="value-interpreter">
        <devtools-linear-memory-inspector-interpreter
          .data=${{value:this.memory.slice(this.address-this.memoryOffset,this.address+8).buffer,valueTypes:this.valueTypes,endianness:this.endianness}}
          @value-type-toggled=${this.onValueTypeToggled}
          @endianness-changed=${this.onEndiannessChanged}>
        </devtools-linear-memory-inspector-interpreter/>
      </div>
      `,this.shadow,{eventContext:this})}onRefreshRequest(){const{start:e,end:t}=this.getPageRangeForAddress(this.address,this.numBytesPerPage);this.dispatchEvent(new Se(e,t,this.address))}onByteSelected(e){this.currentNavigatorMode="Submitted";const t=Math.max(0,Math.min(e.data,this.outerMemoryLength-1));this.jumpToAddress(t)}onEndiannessChanged(e){this.endianness=e.data,this.render()}isValidAddress(e){const t=ue(e);return void 0!==t&&t>=0&&t<this.outerMemoryLength}onAddressChange(e){const{address:t,mode:s}=e.data,r=this.isValidAddress(t),n=ue(t);if(this.currentNavigatorAddressLine=t,void 0!==n&&r)return this.currentNavigatorMode=s,void this.jumpToAddress(n);this.currentNavigatorMode="Submitted"!==s||r?"Edit":"InvalidSubmit",this.render()}onValueTypeToggled(e){const{type:t,checked:s}=e.data;s?this.valueTypes.add(t):this.valueTypes.delete(t),this.render()}navigateHistory(e){return"Forward"===e.data?this.history.rollover():this.history.rollback()}navigatePage(e){const t="Forward"===e.data?this.address+this.numBytesPerPage:this.address-this.numBytesPerPage,s=Math.max(0,Math.min(t,this.outerMemoryLength-1));this.jumpToAddress(s)}jumpToAddress(e){e<0||e>=this.outerMemoryLength?console.warn("Specified address is out of bounds: "+e):(this.setAddress(e),this.update())}getPageRangeForAddress(e,t){const s=Math.floor(e/t)*t;return{start:s,end:Math.min(s+t,this.outerMemoryLength)}}resize(e){this.numBytesPerPage=e.data,this.update()}update(){const{start:e,end:t}=this.getPageRangeForAddress(this.address,this.numBytesPerPage);e<this.memoryOffset||t>this.memoryOffset+this.memory.length?this.dispatchEvent(new Se(e,t,this.address)):this.render()}setAddress(e){const t=new Te(e,(()=>this.jumpToAddress(e)));this.history.push(t),this.address=e,this.dispatchEvent(new Me(this.address))}}customElements.define("devtools-linear-memory-inspector-inspector",Re);var Be=Object.freeze({__proto__:null,UIStrings:_e,MemoryRequestEvent:Se,AddressChangedEvent:Me,LinearMemoryInspector:Re});const $e={noOpenInspections:"No open inspections"},Ae=e.registerUIStrings("linear_memory_inspector/LinearMemoryInspectorPane.js",$e),Oe=e.getLocalizedString.bind(void 0,Ae);let Pe,Le;class Ce extends h.VBox{constructor(){super(),this.view=Ve.instance()}static instance(e={forceNew:null}){const{forceNew:t}=e;return Le&&!t||(Le=new Ce),Le}wasShown(){this.view.show(this.contentElement)}}class Ve extends h.VBox{constructor(){super(!1);const e=document.createElement("div");e.textContent=Oe($e.noOpenInspections),e.style.display="flex",this._tabbedPane=new u.TabbedPane,this._tabbedPane.setPlaceholderElement(e),this._tabbedPane.setCloseableTabs(!0),this._tabbedPane.setAllowTabReorder(!0,!0),this._tabbedPane.addEventListener(u.Events.TabClosed,this._tabClosed,this),this._tabbedPane.show(this.contentElement),this._tabIdToInspectorView=new Map}static instance(){return Pe||(Pe=new Ve),Pe}create(e,t,s,r){const n=new ke(s,r);this._tabIdToInspectorView.set(e,n),this._tabbedPane.appendTab(e,t,n,void 0,!1,!0),this._tabbedPane.selectTab(e)}close(e){this._tabbedPane.closeTab(e,!1)}reveal(e,t){const s=this._tabIdToInspectorView.get(e);if(!s)throw new Error("No linear memory inspector view for given tab id: "+e);void 0!==t&&s.updateAddress(t),this.refreshView(e),this._tabbedPane.selectTab(e)}refreshView(e){const t=this._tabIdToInspectorView.get(e);if(!t)throw new Error("View for specified tab id does not exist: "+e);t.refreshData()}_tabClosed(e){const t=e.data.tabId;this._tabIdToInspectorView.delete(t),this.dispatchEventToListeners("view-closed",t)}}class ke extends h.VBox{constructor(e,t){if(super(!1),t<0||t>=e.length())throw new Error("Requested address is out of bounds.");this._memoryWrapper=e,this._address=t,this._inspector=new Re,this._inspector.addEventListener("memory-request",(e=>{this._memoryRequested(e)})),this._inspector.addEventListener("address-changed",(e=>{this.updateAddress(e.data)})),this.contentElement.appendChild(this._inspector)}wasShown(){this.refreshData()}updateAddress(e){if(e<0||e>=this._memoryWrapper.length())throw new Error("Requested address is out of bounds.");this._address=e}refreshData(){Ne.getMemoryForAddress(this._memoryWrapper,this._address).then((({memory:e,offset:t})=>{this._inspector.data={memory:e,address:this._address,memoryOffset:t,outerMemoryLength:this._memoryWrapper.length()}}))}_memoryRequested(e){const{start:t,end:s,address:r}=e.data;if(r<t||r>=s)throw new Error("Requested address is out of bounds.");Ne.getMemoryRange(this._memoryWrapper,t,s).then((e=>{this._inspector.data={memory:e,address:r,memoryOffset:t,outerMemoryLength:this._memoryWrapper.length()}}))}}var Ue=Object.freeze({__proto__:null,UIStrings:$e,Wrapper:Ce,LinearMemoryInspectorPaneImpl:Ve});const je=["webassemblymemory","typedarray","dataview","arraybuffer"];let ze;class Fe{constructor(e){this.remoteArrayBuffer=e}length(){return this.remoteArrayBuffer.byteLength()}async getRange(e,t){const s=Math.min(t,this.length());if(e<0||e>s)return console.error(`Requesting invalid range of memory: (${e}, ${t})`),new Uint8Array(0);const r=await this.remoteArrayBuffer.bytes(e,s);return new Uint8Array(r)}}class Ne extends d.SDKModelObserver{constructor(){super(),this.paneInstance=Ve.instance(),this.bufferIdToRemoteObject=new Map,d.TargetManager.instance().observeModels(l.RuntimeModel,this),d.TargetManager.instance().addModelListener(c.DebuggerModel,c.Events.GlobalObjectCleared,this.onGlobalObjectClear,this),this.paneInstance.addEventListener("view-closed",this.viewClosed.bind(this)),d.TargetManager.instance().addModelListener(c.DebuggerModel,c.Events.DebuggerPaused,this.onDebuggerPause,this)}static instance(){return ze||(ze=new Ne,ze)}static async getMemoryForAddress(e,t){const s=Math.max(0,t-500),r=s+1e3;return{memory:await e.getRange(s,r),offset:s}}static async getMemoryRange(e,t,s){if(t<0||t>s||t>=e.length())throw new Error("Requested range is out of bounds.");const r=Math.max(s,t+1e3);return await e.getRange(t,r)}async openInspectorView(e,t){const s=await async function(e){console.assert("object"===e.type),console.assert(void 0!==e.subtype&&je.includes(e.subtype));const t=await e.runtimeModel()._agent.invoke_callFunctionOn({objectId:e.objectId,functionDeclaration:"function() { return this instanceof ArrayBuffer || this instanceof SharedArrayBuffer ? this : this.buffer; }",silent:!0,objectGroup:"linear-memory-inspector"}),s=t.getError();if(s)throw new Error("Remote object representing ArrayBuffer could not be retrieved: "+s);return e=e.runtimeModel().createRemoteObject(t.result),new a.RemoteArrayBuffer(e)}(e),{internalProperties:r}=await s.object().getOwnProperties(!1),n=r?.find((({name:e})=>"[[ArrayBufferData]]"===e))?.value?.value;if(!n)throw new Error("Unable to find backing store id for array buffer");const i=r?.find((({name:e})=>"[[WebAssemblyMemory]]"===e))?.value;if(this.bufferIdToRemoteObject.has(n))return this.paneInstance.reveal(n,t),void p.ViewManager.instance().showView("linear-memory-inspector");const o=String(i?i.description:s.object().description);this.bufferIdToRemoteObject.set(n,s.object());const d=new Fe(s);this.paneInstance.create(n,o,d,t),p.ViewManager.instance().showView("linear-memory-inspector")}modelRemoved(e){for(const[t,s]of this.bufferIdToRemoteObject)e===s.runtimeModel()&&(this.bufferIdToRemoteObject.delete(t),this.paneInstance.close(t))}onDebuggerPause(e){const t=e.data;for(const[e,s]of this.bufferIdToRemoteObject)t.runtimeModel()===s.runtimeModel()&&this.paneInstance.refreshView(e)}onGlobalObjectClear(e){const t=e.data;this.modelRemoved(t.runtimeModel())}viewClosed(e){const t=e.data,s=this.bufferIdToRemoteObject.get(t);s&&s.release(),this.bufferIdToRemoteObject.delete(e.data)}}var De=Object.freeze({__proto__:null,ACCEPTED_MEMORY_TYPES:je,RemoteArrayBufferWrapper:Fe,LinearMemoryInspectorController:Ne});export{Be as LinearMemoryInspector,De as LinearMemoryInspectorController,Ue as LinearMemoryInspectorPane,pe as LinearMemoryInspectorUtils,I as LinearMemoryNavigator,ae as LinearMemoryValueInterpreter,be as LinearMemoryViewer,q as ValueInterpreterDisplay,V as ValueInterpreterDisplayUtils,X as ValueInterpreterSettings};
