text: /**
   * @license
   * Copyright 2021 Google LLC. All Rights Reserved.
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   * http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   * =============================================================================
   */
  !function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("@tensorflow/tfjs-core")):"function"==typeof define&&define.amd?define(["exports","@tensorflow/tfjs-core"],n):n((e=e||self).tf=e.tf||{},e.tf)}(this,(function(e,n){"use strict";const t={},a={alpha:!1,antialias:!1,premultipliedAlpha:!1,preserveDrawingBuffer:!1,depth:!1,stencil:!1,failIfMajorPerformanceCaveat:!0};function r(e,n){t[e]=n}function o(e){if(!(e in t)){const n=function(e){if(1!==e&&2!==e)throw new Error("Cannot get WebGL rendering context, WebGL is disabled.");const n=function(e){if("undefined"!=typeof OffscreenCanvas&&2===e)return new OffscreenCanvas(300,150);if("undefined"!=typeof document)return document.createElement("canvas");throw new Error("Cannot create a canvas in this context")}(e);if(n.addEventListener("webglcontextlost",n=>{n.preventDefault(),delete t[e]},!1),1===e)return n.getContext("webgl",a)||n.getContext("experimental-webgl",a);return n.getContext("webgl2",a)}(e);if(null===n)return console.log("Could not get context for WebGL version",e),null;t[e]=n}const n=t[e];return n.isContextLost()?(delete t[e],o(e)):(n.disable(n.DEPTH_TEST),n.disable(n.STENCIL_TEST),n.disable(n.BLEND),n.disable(n.DITHER),n.disable(n.POLYGON_OFFSET_FILL),n.disable(n.SAMPLE_COVERAGE),n.enable(n.SCISSOR_TEST),n.enable(n.CULL_FACE),n.cullFace(n.BACK),t[e])}var s,i,u;function l(e,n){return[n,e]}function c(e){const t=n.util.sizeFromShape(e),a=Math.ceil(t/4);return n.util.sizeToSquarishShape(a)}function d(e,n){return[Math.max(1,Math.ceil(n/2)),Math.max(1,Math.ceil(e/2))]}function p(e,t){const a=e;let r,o,s,i,u,l,c,d,p,h;return 2===n.env().getNumber("WEBGL_VERSION")?(r=a.R32F,o=a.R16F,s=a.RGBA16F,i=a.RGBA32F,u=a.RED,c=4,d=1,p=a.HALF_FLOAT,h=a.FLOAT):(r=e.RGBA,o=e.RGBA,s=e.RGBA,i=a.RGBA,u=e.RGBA,c=4,d=4,p=null!=t?t.HALF_FLOAT_OES:null,h=e.FLOAT),l=e.RGBA,{internalFormatFloat:r,internalFormatHalfFloat:o,internalFormatPackedHalfFloat:s,internalFormatPackedFloat:i,textureFormatFloat:u,downloadTextureFormat:l,downloadUnpackNumChannels:c,defaultNumChannels:d,textureTypeHalfFloat:p,textureTypeFloat:h}}function h(e,t){const a=t();return n.env().getBool("DEBUG")&&function(e){const n=e.getError();if(n!==e.NO_ERROR)throw new Error("WebGL Error: "+x(e,n))}(e),a}!function(e){e[e.DENSE=0]="DENSE",e[e.SHARED_BATCH=1]="SHARED_BATCH"}(s||(s={})),function(e){e[e.RENDER=0]="RENDER",e[e.UPLOAD=1]="UPLOAD",e[e.PIXELS=2]="PIXELS",e[e.DOWNLOAD=3]="DOWNLOAD"}(i||(i={})),function(e){e[e.UNPACKED_FLOAT16=0]="UNPACKED_FLOAT16",e[e.UNPACKED_FLOAT32=1]="UNPACKED_FLOAT32",e[e.PACKED_4X1_UNSIGNED_BYTE=2]="PACKED_4X1_UNSIGNED_BYTE",e[e.PACKED_2X2_FLOAT32=3]="PACKED_2X2_FLOAT32",e[e.PACKED_2X2_FLOAT16=4]="PACKED_2X2_FLOAT16"}(u||(u={}));function f(e){return!!(n.env().getBool("WEBGL_RENDER_FLOAT32_ENABLED")||0===e||5.96e-8<Math.abs(e)&&Math.abs(e)<65504)}function x(e,n){switch(n){case e.NO_ERROR:return"NO_ERROR";case e.INVALID_ENUM:return"INVALID_ENUM";case e.INVALID_VALUE:return"INVALID_VALUE";case e.INVALID_OPERATION:return"INVALID_OPERATION";case e.INVALID_FRAMEBUFFER_OPERATION:return"INVALID_FRAMEBUFFER_OPERATION";case e.OUT_OF_MEMORY:return"OUT_OF_MEMORY";case e.CONTEXT_LOST_WEBGL:return"CONTEXT_LOST_WEBGL";default:return`Unknown error code ${n}`}}function g(e,n){return L(e,()=>e.getExtension(n),'Extension "'+n+'" not supported on this browser.')}function m(e,n){const t=L(e,()=>e.createShader(e.VERTEX_SHADER),"Unable to create vertex WebGLShader.");if(h(e,()=>e.shaderSource(t,n)),h(e,()=>e.compileShader(t)),!1===e.getShaderParameter(t,e.COMPILE_STATUS))throw console.log(e.getShaderInfoLog(t)),new Error("Failed to compile vertex shader.");return t}function b(e,t){const a=L(e,()=>e.createShader(e.FRAGMENT_SHADER),"Unable to create fragment WebGLShader.");if(h(e,()=>e.shaderSource(a,t)),h(e,()=>e.compileShader(a)),!1===e.getShaderParameter(a,e.COMPILE_STATUS))throw function(e,t){const a=v.exec(t);if(null==a)return console.log(`Couldn't parse line number in error: ${t}`),void console.log(e);const r=+a[1],o=e.split("\n"),s=o.length.toString().length+2,i=o.map((e,t)=>n.util.rightPad((t+1).toString(),s)+e);let u=0;for(let e=0;e<i.length;e++)u=Math.max(i[e].length,u);const l=i.slice(0,r-1),c=i.slice(r-1,r),d=i.slice(r);console.log(l.join("\n")),console.log(t.split("\n")[0]),console.log(`%c ${n.util.rightPad(c[0],u)}`,"border:1px solid red; background-color:#e3d2d2; color:#a61717"),console.log(d.join("\n"))}(t,e.getShaderInfoLog(a)),new Error("Failed to compile fragment shader.");return a}const v=/ERROR: [0-9]+:([0-9]+):/g;function C(e){return L(e,()=>e.createProgram(),"Unable to create WebGLProgram.")}function $(e,n){if(h(e,()=>e.linkProgram(n)),!1===e.getProgramParameter(n,e.LINK_STATUS))throw console.log(e.getProgramInfoLog(n)),new Error("Failed to link vertex and fragment shaders.")}function I(e,n){if(h(e,()=>e.validateProgram(n)),!1===e.getProgramParameter(n,e.VALIDATE_STATUS))throw console.log(e.getProgramInfoLog(n)),new Error("Shader program validation failed.")}function R(e,n){const t=L(e,()=>e.createBuffer(),"Unable to create WebGLBuffer");return h(e,()=>e.bindBuffer(e.ARRAY_BUFFER,t)),h(e,()=>e.bufferData(e.ARRAY_BUFFER,n,e.STATIC_DRAW)),t}function k(e,n){const t=L(e,()=>e.createBuffer(),"Unable to create WebGLBuffer");return h(e,()=>e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,t)),h(e,()=>e.bufferData(e.ELEMENT_ARRAY_BUFFER,n,e.STATIC_DRAW)),t}function y(e){return L(e,()=>e.createTexture(),"Unable to create WebGLTexture.")}function w(e,t){const a=n.env().getNumber("WEBGL_MAX_TEXTURE_SIZE");if(e<=0||t<=0){throw new Error("Requested texture size "+`[${e}x${t}]`+" is invalid.")}if(e>a||t>a){throw new Error("Requested texture size "+`[${e}x${t}]`+" greater than WebGL maximum on this browser / GPU "+`[${a}x${a}]`+".")}}function T(e){return L(e,()=>e.createFramebuffer(),"Unable to create WebGLFramebuffer.")}function E(e,n,t,a,r,o,s){const i=e.getAttribLocation(n,t);return-1!==i&&(h(e,()=>e.bindBuffer(e.ARRAY_BUFFER,a)),h(e,()=>e.vertexAttribPointer(i,r,e.FLOAT,!1,o,s)),h(e,()=>e.enableVertexAttribArray(i)),!0)}function N(e,n,t){B(e,t),h(e,()=>e.activeTexture(e.TEXTURE0+t)),h(e,()=>e.bindTexture(e.TEXTURE_2D,n))}function S(e,n,t){return L(e,()=>e.getUniformLocation(n,t),'uniform "'+t+'" not present in program.')}function A(e,n,t){return e.getUniformLocation(n,t)}function F(e,n,t,a){h(e,()=>N(e,n,a)),h(e,()=>e.uniform1i(t,a))}function _(e,n,t){h(e,()=>e.bindFramebuffer(e.FRAMEBUFFER,t)),h(e,()=>e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,n,0))}function O(e,n){h(e,()=>e.bindFramebuffer(e.FRAMEBUFFER,n)),h(e,()=>e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,null,0))}function D(e){const n=e.checkFramebufferStatus(e.FRAMEBUFFER);if(n!==e.FRAMEBUFFER_COMPLETE)throw new Error("Error binding framebuffer: "+P(e,n))}function P(e,n){switch(n){case e.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:return"FRAMEBUFFER_INCOMPLETE_ATTACHMENT";case e.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:return"FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT";case e.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:return"FRAMEBUFFER_INCOMPLETE_DIMENSIONS";case e.FRAMEBUFFER_UNSUPPORTED:return"FRAMEBUFFER_UNSUPPORTED";default:return`unknown error ${n}`}}function L(e,n,t){const a=h(e,()=>n());if(null==a)throw new Error(t);return a}function B(e,n){const t=e.MAX_COMBINED_TEXTURE_IMAGE_UNITS-1,a=n+e.TEXTURE0;if(a<e.TEXTURE0||a>t){throw new Error(`textureUnit must be in ${`[gl.TEXTURE0, gl.TEXTURE${t}]`}.`)}}function V(e,t=2){return n.util.sizeFromShape(e.slice(0,e.length-t))}function W(e){if(0===e.length)throw Error("Cannot get rows and columns of an empty shape array.");return[e.length>1?e[e.length-2]:1,e[e.length-1]]}function M(e){let n=[1,1,1];return 0===e.length||1===e.length&&1===e[0]||(n=[V(e),...W(e)]),n}function G(e,t=!1){let a=n.env().getNumber("WEBGL_MAX_TEXTURE_SIZE");if(t&&(a*=2,1===(e=e.map((t,a)=>a>=e.length-2?n.util.nearestLargerEven(e[a]):e[a])).length&&(e=[2,e[0]])),2!==e.length){const t=n.util.squeezeShape(e);e=t.newShape}let r=n.util.sizeFromShape(e);if(e.length<=1&&r<=a)return[1,r];if(2===e.length&&e[0]<=a&&e[1]<=a)return e;if(3===e.length&&e[0]*e[1]<=a&&e[2]<=a)return[e[0]*e[1],e[2]];if(3===e.length&&e[0]<=a&&e[1]*e[2]<=a)return[e[0],e[1]*e[2]];if(4===e.length&&e[0]*e[1]*e[2]<=a&&e[3]<=a)return[e[0]*e[1]*e[2],e[3]];if(4===e.length&&e[0]<=a&&e[1]*e[2]*e[3]<=a)return[e[0],e[1]*e[2]*e[3]];if(t){const t=V(e);let a=2,o=2;return e.length&&([a,o]=W(e)),r=t*(a/2)*(o/2),n.util.sizeToSquarishShape(r).map(e=>2*e)}return n.util.sizeToSquarishShape(r)}function U(e){return e%2==0}function z(e,t){if(e=e.slice(-2),t=t.slice(-2),n.util.arraysEqual(e,t))return!0;if(!e.length||!t.length)return!0;if(0===e[0]||0===e[1]||0===t[0]||0===t[1])return!0;if(e.length!==t.length){const n=e.slice(-1)[0],a=t.slice(-1)[0];if(n===a)return!0;if(U(n)&&U(a)&&(1===e[0]||1===t[0]))return!0}return e[1]===t[1]&&U(e[0])&&U(t[0])}let X,H;function j(e){if(null==X){const n=o(e);X=n.getParameter(n.MAX_TEXTURE_SIZE)}return X}function K(e){if(null==H){const n=o(e);H=n.getParameter(n.MAX_TEXTURE_IMAGE_UNITS)}return Math.min(16,H)}function q(e){if(0===e)return 0;let n;const t=o(e);return n=Y(t,"EXT_disjoint_timer_query_webgl2")&&2===e?2:Y(t,"EXT_disjoint_timer_query")?1:0,n}function Y(e,n){return null!=e.getExtension(n)}function Q(e){try{if(null!=o(e))return!0}catch(e){return console.log("Error when getting WebGL context: ",e),!1}return!1}function Z(e){if(0===e)return!1;const n=o(e);if(1===e){if(!Y(n,"OES_texture_float"))return!1}else if(!Y(n,"EXT_color_buffer_float"))return!1;return ee(n)}function J(e){if(0===e)return!1;const n=o(e);if(1!==e){if(Y(n,"EXT_color_buffer_float"))return ee(n);const e="EXT_color_buffer_half_float";if(Y(n,e)){const t=n.getExtension(e);return function(e,n){const t=p(e,n),a=e.createTexture();e.bindTexture(e.TEXTURE_2D,a);e.texImage2D(e.TEXTURE_2D,0,t.internalFormatHalfFloat,1,1,0,t.textureFormatFloat,t.textureTypeHalfFloat,null);const r=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,r),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,a,0);const o=e.checkFramebufferStatus(e.FRAMEBUFFER)===e.FRAMEBUFFER_COMPLETE;return e.bindTexture(e.TEXTURE_2D,null),e.bindFramebuffer(e.FRAMEBUFFER,null),e.deleteTexture(a),e.deleteFramebuffer(r),o}(n,t)}return!1}return!!Y(n,"OES_texture_float")&&(!!Y(n,"WEBGL_color_buffer_float")&&ee(n))}function ee(e){const n=p(e),t=e.createTexture();e.bindTexture(e.TEXTURE_2D,t);e.texImage2D(e.TEXTURE_2D,0,n.internalFormatFloat,1,1,0,n.textureFormatFloat,n.textureTypeFloat,null);const a=e.createFramebuffer();e.bindFramebuffer(e.FRAMEBUFFER,a),e.framebufferTexture2D(e.FRAMEBUFFER,e.COLOR_ATTACHMENT0,e.TEXTURE_2D,t,0);const r=e.checkFramebufferStatus(e.FRAMEBUFFER)===e.FRAMEBUFFER_COMPLETE;return e.bindTexture(e.TEXTURE_2D,null),e.bindFramebuffer(e.FRAMEBUFFER,null),e.deleteTexture(t),e.deleteFramebuffer(a),r}function ne(e){if(2!==e)return!1;return null!=o(e).fenceSync}function te(e,t){Array.isArray(e)||(e=[e]),e.forEach(e=>{null!=e&&n.util.assert("complex64"!==e.dtype,()=>`${t} does not support complex64 tensors `+"in the WebGL backend.")})}var ae=Object.freeze({__proto__:null,callAndCheck:h,canBeRepresented:f,getWebGLErrorMessage:x,getExtensionOrThrow:g,createVertexShader:m,createFragmentShader:b,createProgram:C,linkProgram:$,validateProgram:I,createStaticVertexBuffer:R,createStaticIndexBuffer:k,getNumChannels:function(){return 2===n.env().getNumber("WEBGL_VERSION")?1:4},createTexture:y,validateTextureSize:w,createFramebuffer:T,bindVertexBufferToProgramAttribute:E,bindTextureUnit:N,unbindTextureUnit:function(e,n){B(e,n),h(e,()=>e.activeTexture(e.TEXTURE0+n)),h(e,()=>e.bindTexture(e.TEXTURE_2D,null))},getProgramUniformLocationOrThrow:S,getProgramUniformLocation:A,bindTextureToProgramUniformSampler:F,bindCanvasToFramebuffer:function(e){h(e,()=>e.bindFramebuffer(e.FRAMEBUFFER,null)),h(e,()=>e.viewport(0,0,e.canvas.width,e.canvas.height)),h(e,()=>e.scissor(0,0,e.canvas.width,e.canvas.height))},bindColorTextureToFramebuffer:_,unbindColorTextureFromFramebuffer:O,validateFramebuffer:D,getFramebufferErrorMessage:P,getBatchDim:V,getRowsCols:W,getShapeAs3D:M,getTextureShapeFromLogicalShape:G,isReshapeFree:z,getWebGLMaxTextureSize:j,resetMaxTextureSize:function(){X=null},resetMaxTexturesInShader:function(){H=null},getMaxTexturesInShader:K,getWebGLDisjointQueryTimerVersion:q,hasExtension:Y,isWebGLVersionEnabled:Q,isCapableOfRenderingToFloatTexture:Z,isDownloadFloatTextureEnabled:J,isWebGLFenceEnabled:ne,assertNotComplex:te});const re=n.env();function oe(){let e,t,a,r,o,s,i,u,l,c;return 2===n.env().getNumber("WEBGL_VERSION")?(e="#version 300 es",t="in",a="out",r="in",o="texture",s="outputColor",i="out vec4 outputColor;",u="\n      bool isnan_custom(float val) {\n        return (val > 0.0 || val < 0.0) ? false : val != 0.0;\n      }\n\n      bvec4 isnan_custom(vec4 val) {\n        return bvec4(isnan_custom(val.x),\n          isnan_custom(val.y), isnan_custom(val.z), isnan_custom(val.w));\n      }\n\n      #define isnan(value) isnan_custom(value)\n    ",l="",c="\n      #define round(value) newRound(value)\n      int newRound(float value) {\n        return int(floor(value + 0.5));\n      }\n\n      ivec4 newRound(vec4 value) {\n        return ivec4(floor(value + vec4(0.5)));\n      }\n    "):(e="",t="attribute",a="varying",r="varying",o="texture2D",s="gl_FragColor",i="",u="\n      #define isnan(value) isnan_custom(value)\n      bool isnan_custom(float val) {\n        return (val > 0. || val < 1. || val == 0.) ? false : true;\n      }\n      bvec4 isnan_custom(vec4 val) {\n        return bvec4(isnan(val.x), isnan(val.y), isnan(val.z), isnan(val.w));\n      }\n    ",l="\n      uniform float INFINITY;\n\n      bool isinf(float val) {\n        return abs(val) == INFINITY;\n      }\n      bvec4 isinf(vec4 val) {\n        return equal(abs(val), vec4(INFINITY));\n      }\n    ",c="\n      int round(float value) {\n        return int(floor(value + 0.5));\n      }\n\n      ivec4 round(vec4 value) {\n        return ivec4(floor(value + vec4(0.5)));\n      }\n    "),{version:e,attribute:t,varyingVs:a,varyingFs:r,texture2D:o,output:s,defineOutput:i,defineSpecialNaN:u,defineSpecialInf:l,defineRound:c}}function se(e,t,a="index"){const r=n.util.computeStrides(t);return r.map((n,t)=>`${`int ${e[t]} = ${a} / ${n}`}; ${t===r.length-1?`int ${e[t+1]} = ${a} - ${e[t]} * ${n}`:`index -= ${e[t]} * ${n}`};`).join("")}function ie(e){const t=n.util.computeStrides(e).map(e=>e.toString());return`\n  int getFlatIndex(ivec3 coords) {\n    return coords.x * ${t[0]} + coords.y * ${t[1]} + coords.z;\n  }\n`}re.registerFlag("HAS_WEBGL",()=>re.getNumber("WEBGL_VERSION")>0),re.registerFlag("WEBGL_VERSION",()=>Q(2)?2:Q(1)?1:0),re.registerFlag("WEBGL_CHECK_NUMERICAL_PROBLEMS",()=>!1),re.registerFlag("WEBGL_BUFFER_SUPPORTED",()=>2===re.get("WEBGL_VERSION")),re.registerFlag("WEBGL_CPU_FORWARD",()=>!0),re.registerFlag("WEBGL_FORCE_F16_TEXTURES",()=>!1),re.registerFlag("WEBGL_PACK",()=>re.getBool("HAS_WEBGL")),re.registerFlag("WEBGL_PACK_NORMALIZATION",()=>re.getBool("WEBGL_PACK")),re.registerFlag("WEBGL_PACK_CLIP",()=>re.getBool("WEBGL_PACK")),re.registerFlag("WEBGL_PACK_DEPTHWISECONV",()=>!1),re.registerFlag("WEBGL_PACK_BINARY_OPERATIONS",()=>re.getBool("WEBGL_PACK")),re.registerFlag("WEBGL_PACK_UNARY_OPERATIONS",()=>re.getBool("WEBGL_PACK")),re.registerFlag("WEBGL_PACK_ARRAY_OPERATIONS",()=>re.getBool("WEBGL_PACK")),re.registerFlag("WEBGL_PACK_IMAGE_OPERATIONS",()=>re.getBool("WEBGL_PACK")),re.registerFlag("WEBGL_PACK_REDUCE",()=>re.getBool("WEBGL_PACK")),re.registerFlag("WEBGL_LAZILY_UNPACK",()=>re.getBool("WEBGL_PACK")),re.registerFlag("WEBGL_CONV_IM2COL",()=>re.getBool("WEBGL_PACK")),re.registerFlag("WEBGL_MAX_TEXTURE_SIZE",()=>j(re.getNumber("WEBGL_VERSION"))),re.registerFlag("WEBGL_MAX_TEXTURES_IN_SHADER",()=>K(re.getNumber("WEBGL_VERSION"))),re.registerFlag("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION",()=>{const e=re.getNumber("WEBGL_VERSION");return 0===e?0:q(e)}),re.registerFlag("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE",()=>re.getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0&&!n.device_util.isMobile()),re.registerFlag("WEBGL_RENDER_FLOAT32_CAPABLE",()=>Z(re.getNumber("WEBGL_VERSION"))),re.registerFlag("WEBGL_RENDER_FLOAT32_ENABLED",()=>!re.getBool("WEBGL_FORCE_F16_TEXTURES")&&re.getBool("WEBGL_RENDER_FLOAT32_CAPABLE")),re.registerFlag("WEBGL_DOWNLOAD_FLOAT_ENABLED",()=>J(re.getNumber("WEBGL_VERSION"))),re.registerFlag("WEBGL_FENCE_API_ENABLED",()=>ne(re.getNumber("WEBGL_VERSION"))),re.registerFlag("WEBGL_SIZE_UPLOAD_UNIFORM",()=>re.getBool("WEBGL_RENDER_FLOAT32_ENABLED")?4:0),re.registerFlag("WEBGL_DELETE_TEXTURE_THRESHOLD",()=>-1,e=>{if(e<0&&-1!==e)throw new Error("WEBGL_DELETE_TEXTURE_THRESHOLD must be -1 (indicating never "+`delete) or at least 0, but got ${e}.`)});const ue="\n  const float FLOAT_MAX = 1.70141184e38;\n  const float FLOAT_MIN = 1.17549435e-38;\n\n  lowp vec4 encode_float(highp float v) {\n    if (isnan(v)) {\n      return vec4(255, 255, 255, 255);\n    }\n\n    highp float av = abs(v);\n\n    if(av < FLOAT_MIN) {\n      return vec4(0.0, 0.0, 0.0, 0.0);\n    } else if(v > FLOAT_MAX) {\n      return vec4(0.0, 0.0, 128.0, 127.0) / 255.0;\n    } else if(v < -FLOAT_MAX) {\n      return vec4(0.0, 0.0,  128.0, 255.0) / 255.0;\n    }\n\n    highp vec4 c = vec4(0,0,0,0);\n\n    highp float e = floor(log2(av));\n    highp float m = exp2(fract(log2(av))) - 1.0;\n\n    c[2] = floor(128.0 * m);\n    m -= c[2] / 128.0;\n    c[1] = floor(32768.0 * m);\n    m -= c[1] / 32768.0;\n    c[0] = floor(8388608.0 * m);\n\n    highp float ebias = e + 127.0;\n    c[3] = floor(ebias / 2.0);\n    ebias -= c[3] * 2.0;\n    c[2] += floor(ebias) * 128.0;\n\n    c[3] += 128.0 * step(0.0, -v);\n\n    return c / 255.0;\n  }\n";class le{constructor(e){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0,this.outPackingScheme=s.DENSE;const n=c(e),t=oe();this.outputShape=e,this.userCode=`\n      ivec3 outCoordsFromFlatIndex(int index) {\n        ${se(["r","c","d"],e)}\n        return ivec3(r, c, d);\n      }\n\n      void main() {\n        ivec2 resTexRC = ivec2(resultUV.yx *\n          vec2(${n[0]}, ${n[1]}));\n        int index = 4 * (resTexRC.x * ${n[1]} + resTexRC.y);\n\n        vec4 result = vec4(0.);\n\n        for (int i=0; i<4; i++) {\n          int flatIndex = index + i;\n          ivec3 rc = outCoordsFromFlatIndex(flatIndex);\n          result[i] = getA(rc.x, rc.y, rc.z);\n        }\n\n        ${t.output} = result;\n      }\n    `}}class ce{constructor(e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outPackingScheme=s.DENSE;const n=c(e),t=oe();this.outputShape=e,this.userCode=`\n      ivec3 outCoordsFromFlatIndex(int index) {\n        ${se(["r","c","d"],e)}\n        return ivec3(r, c, d);\n      }\n\n      void main() {\n        ivec2 resTexRC = ivec2(resultUV.yx *\n          vec2(${n[0]}, ${n[1]}));\n        int index = 4 * (resTexRC.x * ${n[1]} + resTexRC.y);\n\n        vec4 result = vec4(0.);\n\n        for (int i=0; i<4; i++) {\n          int flatIndex = index + i;\n          ivec3 rc = outCoordsFromFlatIndex(flatIndex);\n          result[i] = getChannel(getA(rc.x, rc.y, rc.z), vec2(rc.y, rc.z));\n        }\n\n        ${t.output} = result;\n      }\n    `}}class de{constructor(e){this.variableNames=["A"],this.outTexUsage=i.DOWNLOAD;const n=oe();this.outputShape=e,this.userCode=`\n      ${ue}\n\n      void main() {\n        float x = getAAtOutCoords();\n        ${n.output} = encode_float(x);\n      }\n    `}}class pe{constructor(e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!1,this.outTexUsage=i.DOWNLOAD;const n=oe();this.outputShape=e,this.userCode=`\n      ${ue}\n\n      void main() {\n        ivec3 coords = getOutputCoords();\n        float x = getChannel(getAAtOutCoords(), vec2(coords.y, coords.z));\n        ${n.output} = encode_float(x);\n      }\n    `}}class he{constructor(e,n,t=!1){this.variableNames=["A"];const a=oe(),[r,o]=n;this.outputShape=e;let s="result";t&&(s="floor(result * 255. + 0.5)"),this.userCode=`\n      ${ie(e)}\n\n      void main() {\n        ivec3 coords = getOutputCoords();\n\n        int flatIndex = getFlatIndex(coords);\n        int offset = imod(flatIndex, 4);\n\n        flatIndex = idiv(flatIndex, 4, 1.);\n\n        int r = flatIndex / ${o};\n        int c = imod(flatIndex, ${o});\n        vec2 uv = (vec2(c, r) + halfCR) / vec2(${o}.0, ${r}.0);\n        vec4 values = ${a.texture2D}(A, uv);\n\n        float result;\n\n        if(offset == 0) {\n          result = values[0];\n        } else if(offset == 1) {\n          result = values[1];\n        } else if(offset == 2) {\n          result = values[2];\n        } else {\n          result = values[3];\n        }\n\n        ${a.output} = vec4(${s}, 0., 0., 0.);\n      }\n    `}}class fe{constructor(e,n,t=!1){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0;const a=oe(),[r,o]=n;this.outputShape=e;let s="",i="result";t&&(i="floor(result * 255. + 0.5)");for(let n=0;n<=1;n++)for(let t=0;t<=1;t++){const i=2*n+t;s+=`\n          localCoords = coords;\n          if(localCoords[2] + ${t} < ${e[2]}) {\n            localCoords[2] += ${t};\n            if(localCoords[1] + ${n} < ${e[1]}) {\n              localCoords[1] += ${n};\n\n              flatIndex = getFlatIndex(localCoords);\n              offset = imod(flatIndex, 4);\n\n              flatIndex = idiv(flatIndex, 4, 1.);\n\n              r = flatIndex / ${o};\n              c = imod(flatIndex, ${o});\n              uv = (vec2(c, r) + halfCR) / vec2(${o}.0, ${r}.0);\n              values = ${a.texture2D}(A, uv);\n\n              if(offset == 0) {\n                result[${i}] = values[0];\n              } else if(offset == 1) {\n                result[${i}] = values[1];\n              } else if(offset == 2) {\n                result[${i}] = values[2];\n              } else {\n                result[${i}] = values[3];\n              }\n            }\n          }\n        `}this.userCode=`\n      ${ie(e)}\n\n      void main() {\n        ivec3 coords = getOutputCoords();\n\n        vec4 result = vec4(0.);\n        int flatIndex, r, c, offset;\n        ivec3 localCoords;\n        vec2 uv;\n        vec4 values;\n\n        ${s}\n\n        ${a.output} = ${i};\n      }\n    `}}function xe(e){const n=oe();return m(e,`${n.version}\n    precision highp float;\n    ${n.attribute} vec3 clipSpacePos;\n    ${n.attribute} vec2 uv;\n    ${n.varyingVs} vec2 resultUV;\n\n    void main() {\n      gl_Position = vec4(clipSpacePos, 1);\n      resultUV = uv;\n    }`)}function ge(e){return R(e,new Float32Array([-1,1,0,0,1,-1,-1,0,0,0,1,1,0,1,1,1,-1,0,1,0]))}function me(e){return k(e,new Uint16Array([0,1,2,2,1,3]))}function be(e,n,t,a,r,o){w(n,t);const s=y(e),i=e.TEXTURE_2D;return h(e,()=>e.bindTexture(i,s)),h(e,()=>e.texParameteri(i,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE)),h(e,()=>e.texParameteri(i,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE)),h(e,()=>e.texParameteri(i,e.TEXTURE_MIN_FILTER,e.NEAREST)),h(e,()=>e.texParameteri(i,e.TEXTURE_MAG_FILTER,e.NEAREST)),h(e,()=>e.texImage2D(i,0,a,n,t,0,r,o,null)),h(e,()=>e.bindTexture(e.TEXTURE_2D,null)),s}function ve(e){return e.internalFormatFloat}function Ce(e,n,t,a){const[r,o]=l(n,t);return be(e,r,o,ve(a),a.textureFormatFloat,e.FLOAT)}function $e(e){return e.internalFormatHalfFloat}function Ie(e,n,t,a){const[r,o]=l(n,t);return be(e,r,o,$e(a),a.textureFormatFloat,a.textureTypeHalfFloat)}function Re(e){return e.downloadTextureFormat}function ke(e,n,t,a){const[r,o]=l(n,t);return be(e,r,o,Re(a),e.RGBA,e.UNSIGNED_BYTE)}function ye(e){return e.internalFormatPackedFloat}function we(e,n,t,a){const[r,o]=d(n,t);return be(e,r,o,ye(a),e.RGBA,e.FLOAT)}function Te(e){return e.internalFormatPackedHalfFloat}function Ee(e,n,t,a){const[r,o]=d(n,t);return be(e,r,o,Te(a),e.RGBA,a.textureTypeHalfFloat)}function Ne(e,n,t){return h(e,()=>e.bindBuffer(e.ARRAY_BUFFER,t)),E(e,n,"clipSpacePos",t,3,20,0)&&E(e,n,"uv",t,2,20,12)}function Se(e,n,t,a,r,o){let s,i,u;h(e,()=>e.bindTexture(e.TEXTURE_2D,n)),r instanceof Uint8Array?(s=new Uint8Array(t*a*4),i=e.UNSIGNED_BYTE,u=e.RGBA):(s=new Float32Array(t*a*4),i=e.FLOAT,u=o.internalFormatPackedFloat),s.set(r),h(e,()=>e.texImage2D(e.TEXTURE_2D,0,u,t,a,0,e.RGBA,i,s)),h(e,()=>e.bindTexture(e.TEXTURE_2D,null))}function Ae(e,n,t){h(e,()=>e.bindTexture(e.TEXTURE_2D,n)),t.data instanceof Uint8Array?h(e,()=>e.texImage2D(e.TEXTURE_2D,0,e.RGBA,t.width,t.height,0,e.RGBA,e.UNSIGNED_BYTE,t.data)):h(e,()=>e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t)),h(e,()=>e.bindTexture(e.TEXTURE_2D,null))}function Fe(e,n,t,a){const r=e.createBuffer();h(e,()=>e.bindBuffer(e.PIXEL_PACK_BUFFER,r));const o=16*n*t;return h(e,()=>e.bufferData(e.PIXEL_PACK_BUFFER,o,e.STREAM_READ)),h(e,()=>e.readPixels(0,0,t,n,e.RGBA,e.FLOAT,0)),h(e,()=>e.bindBuffer(e.PIXEL_PACK_BUFFER,null)),r}function _e(e,n,t){const a=e,r=new Float32Array(t);return a.bindBuffer(a.PIXEL_PACK_BUFFER,n),a.getBufferSubData(a.PIXEL_PACK_BUFFER,0,r),a.bindBuffer(a.PIXEL_PACK_BUFFER,null),r}function Oe(e,n,t,a){const[r,o]=l(n,t),s=new Uint8Array(n*t*4);return h(e,()=>e.readPixels(0,0,r,o,a.downloadTextureFormat,e.UNSIGNED_BYTE,s)),new Float32Array(s.buffer)}function De(e,n,t,a,r,o,s,i){const u=e,l=new Float32Array(function(e,n){const[t,a]=d(e,n);return t*a*4}(o,s));return u.bindBuffer(u.PIXEL_PACK_BUFFER,n),u.getBufferSubData(u.PIXEL_PACK_BUFFER,0,l),u.bindBuffer(u.PIXEL_PACK_BUFFER,null),l}function Pe(e,n,t){const a=new Float32Array(n*t*4);return h(e,()=>e.readPixels(0,0,t,n,e.RGBA,e.FLOAT,a)),a}var Le=Object.freeze({__proto__:null,createVertexShader:xe,createVertexBuffer:ge,createIndexBuffer:me,getInternalFormatForFloat32MatrixTexture:ve,createFloat32MatrixTexture:Ce,getInternalFormatForFloat16MatrixTexture:$e,createFloat16MatrixTexture:Ie,getInternalFormatForUnsignedBytesMatrixTexture:Re,createUnsignedBytesMatrixTexture:ke,getInternalFormatForPackedMatrixTexture:ye,createPackedMatrixTexture:we,getInternalFormatForFloat16PackedMatrixTexture:Te,createFloat16PackedMatrixTexture:Ee,bindVertexProgramAttributeStreams:Ne,uploadDenseMatrixToTexture:Se,uploadPixelDataToTexture:Ae,createBufferFromOutputTexture:Fe,downloadFloat32MatrixFromBuffer:_e,downloadByteEncodedFloatMatrixFromOutputTexture:Oe,downloadPackedMatrixFromBuffer:De,downloadMatrixFromPackedOutputTexture:Pe});class Be{constructor(e){this.outputTexture=null,this.program=null,this.disposed=!1,this.vertexAttrsAreBound=!1,this.itemsToPoll=[];const t=n.env().getNumber("WEBGL_VERSION");null!=e?(this.gl=e,r(t,e)):this.gl=o(t);let a="WEBGL_color_buffer_float";if(1===n.env().getNumber("WEBGL_VERSION")){const e="OES_texture_float",t="OES_texture_half_float";if(this.textureFloatExtension=g(this.gl,e),Y(this.gl,t))this.textureHalfFloatExtension=g(this.gl,t);else if(n.env().get("WEBGL_FORCE_F16_TEXTURES"))throw new Error("GL context does not support half float textures, yet the environment flag WEBGL_FORCE_F16_TEXTURES is set to true.");if(this.colorBufferFloatExtension=this.gl.getExtension(a),Y(this.gl,"EXT_color_buffer_half_float"))this.colorBufferHalfFloatExtension=g(this.gl,"EXT_color_buffer_half_float");else if(n.env().get("WEBGL_FORCE_F16_TEXTURES"))throw new Error("GL context does not support color renderable half floats, yet the environment flag WEBGL_FORCE_F16_TEXTURES is set to true.")}else if(a="EXT_color_buffer_float",Y(this.gl,a))this.colorBufferFloatExtension=this.gl.getExtension(a);else{if(!Y(this.gl,"EXT_color_buffer_half_float"))throw new Error("GL context does not support color renderable floats");this.colorBufferHalfFloatExtension=this.gl.getExtension("EXT_color_buffer_half_float")}this.vertexBuffer=ge(this.gl),this.indexBuffer=me(this.gl),this.framebuffer=T(this.gl),this.textureConfig=p(this.gl,this.textureHalfFloatExtension)}get debug(){return n.env().getBool("DEBUG")}dispose(){if(this.disposed)return;null!=this.program&&console.warn("Disposing a GPGPUContext that still has a bound WebGLProgram. This is probably a resource leak, delete the program with GPGPUContext.deleteProgram before disposing."),null!=this.outputTexture&&console.warn("Disposing a GPGPUContext that still has a bound output matrix texture.  This is probably a resource leak, delete the output matrix texture with GPGPUContext.deleteMatrixTexture before disposing.");const e=this.gl;h(e,()=>e.finish()),h(e,()=>e.bindFramebuffer(e.FRAMEBUFFER,null)),h(e,()=>e.deleteFramebuffer(this.framebuffer)),h(e,()=>e.bindBuffer(e.ARRAY_BUFFER,null)),h(e,()=>e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,null)),h(e,()=>e.deleteBuffer(this.indexBuffer)),this.disposed=!0}createFloat32MatrixTexture(e,n){return this.throwIfDisposed(),Ce(this.gl,e,n,this.textureConfig)}createFloat16MatrixTexture(e,n){return this.throwIfDisposed(),Ie(this.gl,e,n,this.textureConfig)}createUnsignedBytesMatrixTexture(e,n){return this.throwIfDisposed(),ke(this.gl,e,n,this.textureConfig)}uploadPixelDataToTexture(e,n){this.throwIfDisposed(),Ae(this.gl,e,n)}uploadDenseMatrixToTexture(e,n,t,a){this.throwIfDisposed(),Se(this.gl,e,n,t,a,this.textureConfig)}createFloat16PackedMatrixTexture(e,n){return this.throwIfDisposed(),Ee(this.gl,e,n,this.textureConfig)}createPackedMatrixTexture(e,n){return this.throwIfDisposed(),we(this.gl,e,n,this.textureConfig)}deleteMatrixTexture(e){this.throwIfDisposed(),this.outputTexture===e&&(O(this.gl,this.framebuffer),this.outputTexture=null),h(this.gl,()=>this.gl.deleteTexture(e))}downloadByteEncodedFloatMatrixFromOutputTexture(e,n,t){return this.downloadMatrixDriver(e,()=>Oe(this.gl,n,t,this.textureConfig))}downloadPackedMatrixFromBuffer(e,n,t,a,r,o){return De(this.gl,e,0,0,0,r,o,this.textureConfig)}downloadFloat32MatrixFromBuffer(e,n){return _e(this.gl,e,n)}createBufferFromTexture(e,n,t){this.bindTextureToFrameBuffer(e);const a=Fe(this.gl,n,t,this.textureConfig);return this.unbindTextureToFrameBuffer(),a}createAndWaitForFence(){const e=this.createFence(this.gl);return this.pollFence(e)}createFence(e){let t,a;if(n.env().getBool("WEBGL_FENCE_API_ENABLED")){const n=e,r=n.fenceSync(n.SYNC_GPU_COMMANDS_COMPLETE,0);e.flush(),a=()=>{const e=n.clientWaitSync(r,0,0);return e===n.ALREADY_SIGNALED||e===n.CONDITION_SATISFIED},t=r}else n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")>0?(t=this.beginQuery(),this.endQuery(),a=()=>this.isQueryAvailable(t,n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))):a=()=>!0;return{query:t,isFencePassed:a}}downloadMatrixFromPackedTexture(e,n,t){return this.downloadMatrixDriver(e,()=>Pe(this.gl,n,t))}createProgram(e){this.throwIfDisposed();const n=this.gl,t=b(n,e),a=xe(n),r=C(n);return h(n,()=>n.attachShader(r,a)),h(n,()=>n.attachShader(r,t)),$(n,r),this.debug&&I(n,r),this.vertexAttrsAreBound||(this.setProgram(r),this.vertexAttrsAreBound=Ne(n,this.program,this.vertexBuffer)),r}deleteProgram(e){this.throwIfDisposed(),e===this.program&&(this.program=null),null!=e&&h(this.gl,()=>this.gl.deleteProgram(e))}setProgram(e){this.throwIfDisposed(),this.program=e,null!=this.program&&this.debug&&I(this.gl,this.program),h(this.gl,()=>this.gl.useProgram(e))}getUniformLocation(e,n,t=!0){return this.throwIfDisposed(),t?S(this.gl,e,n):A(this.gl,e,n)}getAttributeLocation(e,n){return this.throwIfDisposed(),h(this.gl,()=>this.gl.getAttribLocation(e,n))}getUniformLocationNoThrow(e,n){return this.throwIfDisposed(),this.gl.getUniformLocation(e,n)}setInputMatrixTexture(e,n,t){this.throwIfDisposed(),this.throwIfNoProgram(),F(this.gl,e,n,t)}setOutputMatrixTexture(e,n,t){this.setOutputMatrixTextureDriver(e,t,n)}setOutputPackedMatrixTexture(e,n,t){this.throwIfDisposed();const[a,r]=d(n,t);this.setOutputMatrixTextureDriver(e,a,r)}setOutputMatrixWriteRegion(e,n,t,a){this.setOutputMatrixWriteRegionDriver(t,e,a,n)}setOutputPackedMatrixWriteRegion(e,n,t,a){throw new Error("setOutputPackedMatrixWriteRegion not implemented.")}debugValidate(){null!=this.program&&I(this.gl,this.program),D(this.gl)}executeProgram(){this.throwIfDisposed(),this.throwIfNoProgram();const e=this.gl;this.debug&&this.debugValidate(),h(e,()=>e.drawElements(e.TRIANGLES,6,e.UNSIGNED_SHORT,0))}blockUntilAllProgramsCompleted(){this.throwIfDisposed(),h(this.gl,()=>this.gl.finish())}getQueryTimerExtension(){return null==this.disjointQueryTimerExtension&&(this.disjointQueryTimerExtension=g(this.gl,2===n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")?"EXT_disjoint_timer_query_webgl2":"EXT_disjoint_timer_query")),this.disjointQueryTimerExtension}getQueryTimerExtensionWebGL2(){return this.getQueryTimerExtension()}getQueryTimerExtensionWebGL1(){return this.getQueryTimerExtension()}beginQuery(){if(2===n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")){const e=this.gl,n=this.getQueryTimerExtensionWebGL2(),t=e.createQuery();return e.beginQuery(n.TIME_ELAPSED_EXT,t),t}const e=this.getQueryTimerExtensionWebGL1(),t=e.createQueryEXT();return e.beginQueryEXT(e.TIME_ELAPSED_EXT,t),t}endQuery(){if(2===n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION")){const e=this.gl,n=this.getQueryTimerExtensionWebGL2();return void e.endQuery(n.TIME_ELAPSED_EXT)}const e=this.getQueryTimerExtensionWebGL1();e.endQueryEXT(e.TIME_ELAPSED_EXT)}async waitForQueryAndGetTime(e){return await n.util.repeatedTry(()=>this.disposed||this.isQueryAvailable(e,n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))),this.getQueryTime(e,n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_VERSION"))}getQueryTime(e,n){if(0===n)return null;if(2===n){const n=this.gl;return n.getQueryParameter(e,n.QUERY_RESULT)/1e6}{const n=this.getQueryTimerExtensionWebGL1();return n.getQueryObjectEXT(e,n.QUERY_RESULT_EXT)/1e6}}isQueryAvailable(e,n){if(0===n)return!0;if(2===n){const n=this.gl,t=this.getQueryTimerExtensionWebGL2(),a=n.getQueryParameter(e,n.QUERY_RESULT_AVAILABLE);return null==this.disjoint&&(this.disjoint=this.gl.getParameter(t.GPU_DISJOINT_EXT)),a&&!this.disjoint}{const n=this.getQueryTimerExtensionWebGL1(),t=n.getQueryObjectEXT(e,n.QUERY_RESULT_AVAILABLE_EXT);return null==this.disjoint&&(this.disjoint=this.gl.getParameter(n.GPU_DISJOINT_EXT)),t&&!this.disjoint}}pollFence(e){return new Promise(n=>{this.addItemToPoll(()=>e.isFencePassed(),()=>n())})}pollItems(){const e=function(e){let n=0;for(;n<e.length;++n){if(!e[n]())break}return n-1}(this.itemsToPoll.map(e=>e.isDoneFn));for(let n=0;n<=e;++n){const{resolveFn:e}=this.itemsToPoll[n];e()}this.itemsToPoll=this.itemsToPoll.slice(e+1)}addItemToPoll(e,t){this.itemsToPoll.push({isDoneFn:e,resolveFn:t}),this.itemsToPoll.length>1||n.util.repeatedTry(()=>(this.pollItems(),0===this.itemsToPoll.length))}bindTextureToFrameBuffer(e){this.throwIfDisposed(),_(this.gl,e,this.framebuffer),this.debug&&D(this.gl)}unbindTextureToFrameBuffer(){null!=this.outputTexture?(_(this.gl,this.outputTexture,this.framebuffer),this.debug&&D(this.gl)):O(this.gl,this.framebuffer)}downloadMatrixDriver(e,n){this.bindTextureToFrameBuffer(e);const t=n();return this.unbindTextureToFrameBuffer(),t}setOutputMatrixTextureDriver(e,n,t){this.throwIfDisposed();const a=this.gl;_(a,e,this.framebuffer),this.debug&&D(a),this.outputTexture=e,h(a,()=>a.viewport(0,0,n,t)),h(a,()=>a.scissor(0,0,n,t))}setOutputMatrixWriteRegionDriver(e,n,t,a){this.throwIfDisposed(),h(this.gl,()=>this.gl.scissor(e,n,t,a))}throwIfDisposed(){if(this.disposed)throw new Error("Attempted to use disposed GPGPUContext.")}throwIfNoProgram(){if(null==this.program)throw new Error("No GPU program is currently set.")}}const{getBroadcastDims:Ve}=n.backend_util;function We(e,t,a,r){const o=[];e.forEach(e=>{const t=n.util.sizeFromShape(e.shapeInfo.logicalShape);e.shapeInfo.isUniform?o.push(`uniform float ${e.name}${t>1?`[${t}]`:""};`):(o.push(`uniform sampler2D ${e.name};`),o.push(`uniform int offset${e.name};`))});const s=o.join("\n"),i=e.map(e=>function(e,t,a=!1){let r="";r+=a?Ge(e):Me(e);const o=e.shapeInfo.logicalShape,s=t.logicalShape;o.length<=s.length&&(r+=a?function(e,t){const a=e.name,r=a.charAt(0).toUpperCase()+a.slice(1),o="get"+r+"AtOutCoords",s=e.shapeInfo.logicalShape.length,i=t.logicalShape.length,u=Ve(e.shapeInfo.logicalShape,t.logicalShape),l=Ye(i),c=i-s;let d;const p=["x","y","z","w","u","v"];d=0===s?"":i<2&&u.length>=1?"coords = 0;":u.map(e=>`coords.${p[e+c]} = 0;`).join("\n");let h="";h=i<2&&s>0?"coords":e.shapeInfo.logicalShape.map((e,n)=>`coords.${p[n+c]}`).join(", ");let f="return outputValue;";const x=1===n.util.sizeFromShape(e.shapeInfo.logicalShape),g=1===n.util.sizeFromShape(t.logicalShape);if(1!==s||x||g){if(x&&!g)f=1===i?"\n        return vec4(outputValue.x, outputValue.x, 0., 0.);\n      ":"\n        return vec4(outputValue.x);\n      ";else if(u.length){const e=s-2,n=s-1;u.indexOf(e)>-1&&u.indexOf(n)>-1?f="return vec4(outputValue.x);":u.indexOf(e)>-1?f="return vec4(outputValue.x, outputValue.y, outputValue.x, outputValue.y);":u.indexOf(n)>-1&&(f="return vec4(outputValue.xx, outputValue.zz);")}}else f="\n      return vec4(outputValue.xy, outputValue.xy);\n    ";return`\n    vec4 ${o}() {\n      ${l} coords = getOutputCoords();\n      ${d}\n      vec4 outputValue = get${r}(${h});\n      ${f}\n    }\n  `}(e,t):function(e,t){const a=e.name,r=a.charAt(0).toUpperCase()+a.slice(1),o="get"+r+"AtOutCoords",s=t.texShape,i=e.shapeInfo.texShape,u=e.shapeInfo.logicalShape.length,l=t.logicalShape.length;if(!e.shapeInfo.isUniform&&u===l&&null==e.shapeInfo.flatOffset&&n.util.arraysEqual(i,s))return`\n      float ${o}() {\n        return sampleTexture(${a}, resultUV);\n      }\n    `;const c=Ye(l),d=Ve(e.shapeInfo.logicalShape,t.logicalShape),p=l-u;let h;const f=["x","y","z","w","u","v"];h=0===u?"":l<2&&d.length>=1?"coords = 0;":d.map(e=>`coords.${f[e+p]} = 0;`).join("\n");let x="";x=l<2&&u>0?"coords":e.shapeInfo.logicalShape.map((e,n)=>`coords.${f[n+p]}`).join(", ");return`\n    float ${o}() {\n      ${c} coords = getOutputCoords();\n      ${h}\n      return get${r}(${x});\n    }\n  `}(e,t));return r}(e,t,r)).join("\n"),u=t.texShape,l=oe(),c=function(e){return`\n    float sampleTexture(sampler2D textureSampler, vec2 uv) {\n      return ${e.texture2D}(textureSampler, uv).r;\n    }\n  `}(l);let d,p,h=function(e){return`${e.version}\n    precision highp float;\n    precision highp int;\n    precision highp sampler2D;\n    ${e.varyingFs} vec2 resultUV;\n    ${e.defineOutput}\n    const vec2 halfCR = vec2(0.5, 0.5);\n\n    struct ivec5\n    {\n      int x;\n      int y;\n      int z;\n      int w;\n      int u;\n    };\n\n    struct ivec6\n    {\n      int x;\n      int y;\n      int z;\n      int w;\n      int u;\n      int v;\n    };\n\n    uniform float NAN;\n    ${e.defineSpecialNaN}\n    ${e.defineSpecialInf}\n    ${e.defineRound}\n\n    int imod(int x, int y) {\n      return x - y * (x / y);\n    }\n\n    int idiv(int a, int b, float sign) {\n      int res = a / b;\n      int mod = imod(a, b);\n      if (sign < 0. && mod != 0) {\n        res -= 1;\n      }\n      return res;\n    }\n\n    //Based on the work of Dave Hoskins\n    //https://www.shadertoy.com/view/4djSRW\n    #define HASHSCALE1 443.8975\n    float random(float seed){\n      vec2 p = resultUV * seed;\n      vec3 p3  = fract(vec3(p.xyx) * HASHSCALE1);\n      p3 += dot(p3, p3.yzx + 19.19);\n      return fract((p3.x + p3.y) * p3.z);\n    }\n\n    ${Ue}\n    ${ze}\n    ${Xe}\n  `}(l);return t.isPacked?(d=function(e,t){switch(e.length){case 0:return je();case 1:return function(e,n){const t=[Math.ceil(n[0]/2),Math.ceil(n[1]/2)];if(1===t[0])return`\n      int getOutputCoords() {\n        return 2 * int(resultUV.x * ${t[1]}.0);\n      }\n    `;if(1===t[1])return`\n      int getOutputCoords() {\n        return 2 * int(resultUV.y * ${t[0]}.0);\n      }\n    `;return`\n    int getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${t[0]}, ${t[1]}));\n      return 2 * (resTexRC.x * ${t[1]} + resTexRC.y);\n    }\n  `}(0,t);case 2:return function(e,t){const a=[Math.ceil(t[0]/2),Math.ceil(t[1]/2)];if(n.util.arraysEqual(e,t))return`\n      ivec2 getOutputCoords() {\n        return 2 * ivec2(resultUV.yx * vec2(${a[0]}, ${a[1]}));\n      }\n    `;const r=Math.ceil(e[1]/2);return`\n    ivec2 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${a[0]}, ${a[1]}));\n\n      int index = resTexRC.x * ${a[1]} + resTexRC.y;\n      int r = 2 * (index / ${r});\n      int c = imod(index, ${r}) * 2;\n\n      return ivec2(r, c);\n    }\n  `}(e,t);case 3:return function(e,n){const t=[Math.ceil(n[0]/2),Math.ceil(n[1]/2)],a=Math.ceil(e[2]/2),r=a*Math.ceil(e[1]/2);return`\n    ivec3 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${t[0]}, ${t[1]}));\n      int index = resTexRC.x * ${t[1]} + resTexRC.y;\n\n      int b = index / ${r};\n      index -= b * ${r};\n\n      int r = 2 * (index / ${a});\n      int c = imod(index, ${a}) * 2;\n\n      return ivec3(b, r, c);\n    }\n  `}(e,t);default:return function(e,n){const t=[Math.ceil(n[0]/2),Math.ceil(n[1]/2)],a=Math.ceil(e[e.length-1]/2),r=a*Math.ceil(e[e.length-2]/2);let o=r,s="",i="b, r, c";for(let n=2;n<e.length-1;n++)o*=e[e.length-n-1],s=`\n      int b${n} = index / ${o};\n      index -= b${n} * ${o};\n    `+s,i=`b${n}, `+i;return`\n    ivec${e.length} getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${t[0]}, ${t[1]}));\n      int index = resTexRC.x * ${t[1]} + resTexRC.y;\n\n      ${s}\n\n      int b = index / ${r};\n      index -= b * ${r};\n\n      int r = 2 * (index / ${a});\n      int c = imod(index, ${a}) * 2;\n\n      return ivec${e.length}(${i});\n    }\n  `}(e,t)}}(t.logicalShape,u),p=function(e){return`\n    void setOutput(vec4 val) {\n      ${e.output} = val;\n    }\n  `}(l)):(d=function(e,t){switch(e.length){case 0:return je();case 1:return function(e,n){if(1===n[0])return`\n      int getOutputCoords() {\n        return int(resultUV.x * ${n[1]}.0);\n      }\n    `;if(1===n[1])return`\n      int getOutputCoords() {\n        return int(resultUV.y * ${n[0]}.0);\n      }\n    `;return`\n    int getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${n[0]}, ${n[1]}));\n      return resTexRC.x * ${n[1]} + resTexRC.y;\n    }\n  `}(0,t);case 2:return function(e,t){if(n.util.arraysEqual(e,t))return`\n      ivec2 getOutputCoords() {\n        return ivec2(resultUV.yx * vec2(${t[0]}, ${t[1]}));\n      }\n    `;if(1===e[1])return`\n      ivec2 getOutputCoords() {\n        ivec2 resTexRC = ivec2(resultUV.yx *\n                               vec2(${t[0]}, ${t[1]}));\n        int index = resTexRC.x * ${t[1]} + resTexRC.y;\n        return ivec2(index, 0);\n      }\n    `;if(1===e[0])return`\n      ivec2 getOutputCoords() {\n        ivec2 resTexRC = ivec2(resultUV.yx *\n                               vec2(${t[0]}, ${t[1]}));\n        int index = resTexRC.x * ${t[1]} + resTexRC.y;\n        return ivec2(0, index);\n      }\n    `;return`\n    ivec2 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${t[0]}, ${t[1]}));\n      int index = resTexRC.x * ${t[1]} + resTexRC.y;\n      int r = index / ${e[1]};\n      int c = index - r * ${e[1]};\n      return ivec2(r, c);\n    }\n  `}(e,t);case 3:return function(e,n){const t=se(["r","c","d"],e);return`\n    ivec3 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n                             vec2(${n[0]}, ${n[1]}));\n      int index = resTexRC.x * ${n[1]} + resTexRC.y;\n      ${t}\n      return ivec3(r, c, d);\n    }\n  `}(e,t);case 4:return function(e,n){const t=se(["r","c","d","d2"],e);return`\n    ivec4 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n        vec2(${n[0]}, ${n[1]}));\n      int index = resTexRC.x * ${n[1]} + resTexRC.y;\n      ${t}\n      return ivec4(r, c, d, d2);\n    }\n  `}(e,t);case 5:return function(e,n){const t=se(["r","c","d","d2","d3"],e);return`\n    ivec5 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx * vec2(${n[0]},\n                             ${n[1]}));\n\n      int index = resTexRC.x * ${n[1]} + resTexRC.y;\n\n      ${t}\n\n      ivec5 outShape = ivec5(r, c, d, d2, d3);\n      return outShape;\n    }\n  `}(e,t);case 6:return function(e,n){const t=se(["r","c","d","d2","d3","d4"],e);return`\n    ivec6 getOutputCoords() {\n      ivec2 resTexRC = ivec2(resultUV.yx *\n        vec2(${n[0]}, ${n[1]}));\n      int index = resTexRC.x * ${n[1]} + resTexRC.y;\n\n      ${t}\n\n      ivec6 result = ivec6(r, c, d, d2, d3, d4);\n      return result;\n    }\n  `}(e,t);default:throw new Error(`${e.length}-D output sampling is not yet supported`)}}(t.logicalShape,u),p=function(e){return`\n    void setOutput(float val) {\n      ${e.output} = vec4(val, 0, 0, 0);\n    }\n  `}(l)),r&&(h+=He),[h,c,p,s,d,i,a].join("\n")}function Me(e){const t=e.shapeInfo.logicalShape;switch(t.length){case 0:return function(e){const n=e.name,t="get"+n.charAt(0).toUpperCase()+n.slice(1);if(e.shapeInfo.isUniform)return`float ${t}() {return ${n};}`;const[a,r]=e.shapeInfo.texShape;if(1===a&&1===r)return`\n      float ${t}() {\n        return sampleTexture(${n}, halfCR);\n      }\n    `;const[o,s]=e.shapeInfo.texShape,i=Ke(n);return`\n    float ${t}() {\n      vec2 uv = uvFromFlat(${o}, ${s}, ${i});\n      return sampleTexture(${n}, uv);\n    }\n  `}(e);case 1:return function(e){const n=e.name,t="get"+n.charAt(0).toUpperCase()+n.slice(1);if(e.shapeInfo.isUniform)return`\n      float ${t}(int index) {\n        ${qe(e)}\n      }\n    `;const a=e.shapeInfo.texShape,r=a[0],o=a[1];if(1===o&&1===r)return`\n      float ${t}(int index) {\n        return sampleTexture(${n}, halfCR);\n      }\n    `;const s=Ke(n);if(1===o)return`\n      float ${t}(int index) {\n        vec2 uv = vec2(0.5, (float(index + ${s}) + 0.5) / ${r}.0);\n        return sampleTexture(${n}, uv);\n      }\n    `;if(1===r)return`\n      float ${t}(int index) {\n        vec2 uv = vec2((float(index + ${s}) + 0.5) / ${o}.0, 0.5);\n        return sampleTexture(${n}, uv);\n      }\n    `;return`\n    float ${t}(int index) {\n      vec2 uv = uvFromFlat(${r}, ${o}, index + ${s});\n      return sampleTexture(${n}, uv);\n    }\n  `}(e);case 2:return function(e){const t=e.shapeInfo.logicalShape,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),o=e.shapeInfo.texShape;if(null!=o&&n.util.arraysEqual(t,o)){const e=o[0],n=o[1];return`\n    float ${r}(int row, int col) {\n      vec2 uv = (vec2(col, row) + halfCR) / vec2(${n}.0, ${e}.0);\n      return sampleTexture(${a}, uv);\n    }\n  `}const{newShape:s,keptDims:i}=n.util.squeezeShape(t),u=s;if(u.length<t.length){const n=Qe(e,u),t=["row","col"];return`\n      ${Me(n)}\n      float ${r}(int row, int col) {\n        return ${r}(${Ze(t,i)});\n      }\n    `}if(e.shapeInfo.isUniform)return`\n      float ${r}(int row, int col) {\n        int index = round(dot(vec2(row, col), vec2(${t[1]}, 1)));\n        ${qe(e)}\n      }\n    `;const l=o[0],c=o[1],d=Ke(a);if(1===c)return`\n    float ${r}(int row, int col) {\n      float index = dot(vec3(row, col, ${d}), vec3(${t[1]}, 1, 1));\n      vec2 uv = vec2(0.5, (index + 0.5) / ${l}.0);\n      return sampleTexture(${a}, uv);\n    }\n  `;if(1===l)return`\n    float ${r}(int row, int col) {\n      float index = dot(vec3(row, col, ${d}), vec3(${t[1]}, 1, 1));\n      vec2 uv = vec2((index + 0.5) / ${c}.0, 0.5);\n      return sampleTexture(${a}, uv);\n    }\n  `;return`\n  float ${r}(int row, int col) {\n    // Explicitly use integer operations as dot() only works on floats.\n    int index = row * ${t[1]} + col + ${d};\n    vec2 uv = uvFromFlat(${l}, ${c}, index);\n    return sampleTexture(${a}, uv);\n  }\n`}(e);case 3:return function(e){const t=e.shapeInfo.logicalShape,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),o=t[1]*t[2],s=t[2],{newShape:i,keptDims:u}=n.util.squeezeShape(t),l=i;if(l.length<t.length){const n=Qe(e,l),t=["row","col","depth"];return`\n        ${Me(n)}\n        float ${r}(int row, int col, int depth) {\n          return ${r}(${Ze(t,u)});\n        }\n      `}if(e.shapeInfo.isUniform)return`\n      float ${r}(int row, int col, int depth) {\n        int index = round(dot(vec3(row, col, depth),\n                          vec3(${o}, ${s}, 1)));\n        ${qe(e)}\n      }\n    `;const c=e.shapeInfo.texShape,d=c[0],p=c[1],h=e.shapeInfo.flatOffset;if(p===o&&null==h)return`\n        float ${r}(int row, int col, int depth) {\n          float texR = float(row);\n          float texC = dot(vec2(col, depth), vec2(${s}, 1));\n          vec2 uv = (vec2(texC, texR) + halfCR) /\n                     vec2(${p}.0, ${d}.0);\n          return sampleTexture(${a}, uv);\n        }\n      `;if(p===s&&null==h)return`\n    float ${r}(int row, int col, int depth) {\n      float texR = dot(vec2(row, col), vec2(${t[1]}, 1));\n      float texC = float(depth);\n      vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${p}.0, ${d}.0);\n      return sampleTexture(${a}, uv);\n    }\n  `;const f=Ke(a);return`\n      float ${r}(int row, int col, int depth) {\n        // Explicitly use integer operations as dot() only works on floats.\n        int index = row * ${o} + col * ${s} + depth + ${f};\n        vec2 uv = uvFromFlat(${d}, ${p}, index);\n        return sampleTexture(${a}, uv);\n      }\n  `}(e);case 4:return function(e){const t=e.shapeInfo.logicalShape,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),o=t[3],s=t[2]*o,i=t[1]*s,{newShape:u,keptDims:l}=n.util.squeezeShape(t);if(u.length<t.length){const n=Qe(e,u),t=["row","col","depth","depth2"];return`\n      ${Me(n)}\n      float ${r}(int row, int col, int depth, int depth2) {\n        return ${r}(${Ze(t,l)});\n      }\n    `}if(e.shapeInfo.isUniform)return`\n      float ${r}(int row, int col, int depth, int depth2) {\n        int index = round(dot(vec4(row, col, depth, depth2),\n                          vec4(${i}, ${s}, ${o}, 1)));\n        ${qe(e)}\n      }\n    `;const c=e.shapeInfo.flatOffset,d=e.shapeInfo.texShape,p=d[0],h=d[1];if(h===i&&null==c)return`\n      float ${r}(int row, int col, int depth, int depth2) {\n        float texR = float(row);\n        float texC =\n            dot(vec3(col, depth, depth2),\n                vec3(${s}, ${o}, 1));\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                   vec2(${h}.0, ${p}.0);\n        return sampleTexture(${a}, uv);\n      }\n    `;if(h===o&&null==c)return`\n      float ${r}(int row, int col, int depth, int depth2) {\n        float texR = dot(vec3(row, col, depth),\n                         vec3(${t[1]*t[2]}, ${t[2]}, 1));\n        float texC = float(depth2);\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                  vec2(${h}.0, ${p}.0);\n        return sampleTexture(${a}, uv);\n      }\n    `;const f=Ke(a);return`\n    float ${r}(int row, int col, int depth, int depth2) {\n      // Explicitly use integer operations as dot() only works on floats.\n      int index = row * ${i} + col * ${s} +\n          depth * ${o} + depth2;\n      vec2 uv = uvFromFlat(${p}, ${h}, index + ${f});\n      return sampleTexture(${a}, uv);\n    }\n  `}(e);case 5:return function(e){const t=e.shapeInfo.logicalShape,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),o=t[4],s=t[3]*o,i=t[2]*s,u=t[1]*i,{newShape:l,keptDims:c}=n.util.squeezeShape(t);if(l.length<t.length){const n=Qe(e,l),t=["row","col","depth","depth2","depth3"];return`\n      ${Me(n)}\n      float ${r}(int row, int col, int depth, int depth2, int depth3) {\n        return ${r}(${Ze(t,c)});\n      }\n    `}if(e.shapeInfo.isUniform)return`\n      float ${r}(int row, int col, int depth, int depth2, int depth3) {\n        float index = dot(\n          vec4(row, col, depth, depth2),\n          vec4(${u}, ${i}, ${s}, ${o})) +\n          depth3;\n        ${qe(e)}\n      }\n    `;const d=e.shapeInfo.flatOffset,p=e.shapeInfo.texShape,h=p[0],f=p[1];if(f===u&&null==d)return`\n      float ${r}(int row, int col, int depth, int depth2, int depth3) {\n        int texR = row;\n        float texC = dot(vec4(col, depth, depth2, depth3),\n                         vec4(${i}, ${s}, ${o}, 1));\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                   vec2(${f}.0, ${h}.0);\n        return sampleTexture(${a}, uv);\n      }\n    `;if(f===o&&null==d)return`\n      float ${r}(int row, int col, int depth, int depth2, int depth3) {\n        float texR = dot(\n          vec4(row, col, depth, depth2),\n          vec4(${t[1]*t[2]*t[3]},\n               ${t[2]*t[3]}, ${t[3]}, 1));\n        int texC = depth3;\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                  vec2(${f}.0, ${h}.0);\n        return sampleTexture(${a}, uv);\n      }\n    `;const x=Ke(a);return`\n    float ${r}(int row, int col, int depth, int depth2, int depth3) {\n      // Explicitly use integer operations as dot() only works on floats.\n      int index = row * ${u} + col * ${i} + depth * ${s} +\n          depth2 * ${o} + depth3 + ${x};\n      vec2 uv = uvFromFlat(${h}, ${f}, index);\n      return sampleTexture(${a}, uv);\n    }\n  `}(e);case 6:return function(e){const t=e.shapeInfo.logicalShape,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),{newShape:o,keptDims:s}=n.util.squeezeShape(t);if(o.length<t.length){const n=Qe(e,o),t=["row","col","depth","depth2","depth3","depth4"];return`\n      ${Me(n)}\n      float ${r}(int row, int col, int depth,\n                    int depth2, int depth3, int depth4) {\n        return ${r}(${Ze(t,s)});\n      }\n    `}const i=t[5],u=t[4]*i,l=t[3]*u,c=t[2]*l,d=t[1]*c;if(e.shapeInfo.isUniform)return`\n      float ${r}(int row, int col, int depth,\n                  int depth2, int depth3, int depth4) {\n        int index = round(dot(\n          vec4(row, col, depth, depth2),\n          vec4(${d}, ${c}, ${l}, ${u})) +\n          dot(\n            vec2(depth3, depth4),\n            vec2(${i}, 1)));\n        ${qe(e)}\n      }\n    `;const p=e.shapeInfo.flatOffset,h=e.shapeInfo.texShape,f=h[0],x=h[1];if(x===d&&null==p)return`\n      float ${r}(int row, int col, int depth,\n                    int depth2, int depth3, int depth4) {\n        int texR = row;\n        float texC = dot(vec4(col, depth, depth2, depth3),\n          vec4(${c}, ${l}, ${u}, ${i})) +\n               float(depth4);\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                   vec2(${x}.0, ${f}.0);\n        return sampleTexture(${a}, uv);\n      }\n    `;if(x===i&&null==p)return`\n      float ${r}(int row, int col, int depth,\n                    int depth2, int depth3, int depth4) {\n        float texR = dot(vec4(row, col, depth, depth2),\n          vec4(${t[1]*t[2]*t[3]*t[4]},\n               ${t[2]*t[3]*t[4]},\n               ${t[3]*t[4]},\n               ${t[4]})) + float(depth3);\n        int texC = depth4;\n        vec2 uv = (vec2(texC, texR) + halfCR) /\n                  vec2(${x}.0, ${f}.0);\n        return sampleTexture(${a}, uv);\n      }\n    `;const g=Ke(a);return`\n    float ${r}(int row, int col, int depth,\n                  int depth2, int depth3, int depth4) {\n      // Explicitly use integer operations as dot() only works on floats.\n      int index = row * ${d} + col * ${c} + depth * ${l} +\n          depth2 * ${u} + depth3 * ${i} + depth4 + ${g};\n      vec2 uv = uvFromFlat(${f}, ${x}, index);\n      return sampleTexture(${a}, uv);\n    }\n  `}(e);default:throw new Error(`${t.length}-D input sampling`+" is not yet supported")}}function Ge(e){switch(e.shapeInfo.logicalShape.length){case 0:return function(e){const n=e.name,t="get"+n.charAt(0).toUpperCase()+n.slice(1),a=oe();return`\n    vec4 ${t}() {\n      return ${a.texture2D}(${n}, halfCR);\n    }\n  `}(e);case 1:return function(e){const n=e.name,t="get"+n.charAt(0).toUpperCase()+n.slice(1),a=e.shapeInfo.texShape,r=[Math.ceil(a[0]/2),Math.ceil(a[1]/2)],o=oe();return`\n    vec4 ${t}(int index) {\n      vec2 uv = packedUVfrom1D(\n        ${r[0]}, ${r[1]}, index);\n      return ${o.texture2D}(${n}, uv);\n    }\n  `}(e);case 2:return function(e){const t=e.shapeInfo.logicalShape,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),o=e.shapeInfo.texShape,s=o[0],i=o[1],u=oe();if(null!=o&&n.util.arraysEqual(t,o))return`\n      vec4 ${r}(int row, int col) {\n        vec2 uv = (vec2(col, row) + halfCR) / vec2(${i}.0, ${s}.0);\n\n        return ${u.texture2D}(${a}, uv);\n      }\n    `;const l=[Math.ceil(o[0]/2),Math.ceil(o[1]/2)],c=Math.ceil(t[1]/2);return`\n    vec4 ${r}(int row, int col) {\n      vec2 uv = packedUVfrom2D(${c}, ${l[0]}, ${l[1]}, row, col);\n      return ${u.texture2D}(${a}, uv);\n    }\n  `}(e);case 3:return function(e){const n=e.shapeInfo.logicalShape,t=e.name,a="get"+t.charAt(0).toUpperCase()+t.slice(1),r=e.shapeInfo.texShape,o=[Math.ceil(r[0]/2),Math.ceil(r[1]/2)];if(1===n[0]){const t=n.slice(1),r=[1,2],o=Qe(e,t),s=["b","row","col"];return`\n        ${Ge(o)}\n        vec4 ${a}(int b, int row, int col) {\n          return ${a}(${Ze(s,r)});\n        }\n      `}const s=o[0],i=o[1],u=Math.ceil(n[2]/2),l=u*Math.ceil(n[1]/2),c=oe();return`\n    vec4 ${a}(int b, int row, int col) {\n      vec2 uv = packedUVfrom3D(\n        ${s}, ${i}, ${l}, ${u}, b, row, col);\n      return ${c.texture2D}(${t}, uv);\n    }\n  `}(e);default:return function(e){const n=e.shapeInfo.logicalShape,t=n.length,a=e.name,r="get"+a.charAt(0).toUpperCase()+a.slice(1),o=e.shapeInfo.texShape,s=[Math.ceil(o[0]/2),Math.ceil(o[1]/2)],i=s[0],u=s[1],l=Math.ceil(n[t-1]/2);let c=l*Math.ceil(n[t-2]/2),d="int b, int row, int col",p=`b * ${c} + (row / 2) * ${l} + (col / 2)`;for(let e=2;e<t-1;e++)d=`int b${e}, `+d,c*=n[t-e-1],p=`b${e} * ${c} + `+p;const h=oe();return`\n    vec4 ${r}(${d}) {\n      int index = ${p};\n      int texR = index / ${u};\n      int texC = index - texR * ${u};\n      vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${u}, ${i});\n      return ${h.texture2D}(${a}, uv);\n    }\n  `}(e)}}const Ue="\nvec2 uvFromFlat(int texNumR, int texNumC, int index) {\n  int texR = index / texNumC;\n  int texC = index - texR * texNumC;\n  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\nvec2 packedUVfrom1D(int texNumR, int texNumC, int index) {\n  int texelIndex = index / 2;\n  int texR = texelIndex / texNumC;\n  int texC = texelIndex - texR * texNumC;\n  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n",ze="\nvec2 packedUVfrom2D(int texelsInLogicalRow, int texNumR,\n  int texNumC, int row, int col) {\n  int texelIndex = (row / 2) * texelsInLogicalRow + (col / 2);\n  int texR = texelIndex / texNumC;\n  int texC = texelIndex - texR * texNumC;\n  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n",Xe="\nvec2 packedUVfrom3D(int texNumR, int texNumC,\n    int texelsInBatch, int texelsInLogicalRow, int b,\n    int row, int col) {\n  int index = b * texelsInBatch + (row / 2) * texelsInLogicalRow + (col / 2);\n  int texR = index / texNumC;\n  int texC = index - texR * texNumC;\n  return (vec2(texC, texR) + halfCR) / vec2(texNumC, texNumR);\n}\n",He="\n  float getChannel(vec4 frag, vec2 innerDims) {\n    vec2 modCoord = mod(innerDims, 2.);\n    return modCoord.x == 0. ?\n      (modCoord.y == 0. ? frag.r : frag.g) :\n      (modCoord.y == 0. ? frag.b : frag.a);\n  }\n  float getChannel(vec4 frag, int dim) {\n    float modCoord = mod(float(dim), 2.);\n    return modCoord == 0. ? frag.r : frag.g;\n  }\n";function je(){return"\n    int getOutputCoords() {\n      return 0;\n    }\n  "}function Ke(e){return`offset${e}`}function qe(e){const t=e.name,a=n.util.sizeFromShape(e.shapeInfo.logicalShape);return a<2?`return ${t};`:`\n    for (int i = 0; i < ${a}; i++) {\n      if (i == index) {\n        return ${t}[i];\n      }\n    }\n  `}function Ye(e){if(e<=1)return"int";if(2===e)return"ivec2";if(3===e)return"ivec3";if(4===e)return"ivec4";if(5===e)return"ivec5";if(6===e)return"ivec6";throw Error(`GPU for rank ${e} is not yet supported`)}function Qe(e,n){const t=JSON.parse(JSON.stringify(e));return t.shapeInfo.logicalShape=n,t}function Ze(e,n){return n.map(n=>e[n]).join(", ")}function Je(e,t){if(e.length!==t.length)throw Error(`Binary was compiled with ${e.length} inputs, but `+`was executed with ${t.length} inputs`);e.forEach((e,a)=>{const r=e.logicalShape,o=t[a],s=o.shape;if(!n.util.arraysEqual(r,s))throw Error("Binary was compiled with different shapes than "+`the current args. Shapes ${r} and ${s} must match`);if(e.isUniform&&o.isUniform)return;const i=e.texShape,u=o.isUniform?null:o.texData.texShape;if(!n.util.arraysEqual(i,u))throw Error("Binary was compiled with different texture shapes than the"+` current args. Shape ${i} and ${u} must match`)})}function en(e){return(t,a,r,o,s)=>{const i=n.backend_util.assertAndGetBroadcastShape(t,a),u=i.length,l=n.util.computeStrides(i),c=n.util.sizeFromShape(i),d=n.util.getTypedArrayFromDType(s,c),p=t.length,h=a.length,f=n.util.computeStrides(t),x=n.util.computeStrides(a),g=n.backend_util.getBroadcastDims(t,i),m=n.backend_util.getBroadcastDims(a,i);if(g.length+m.length===0)for(let n=0;n<d.length;++n)d[n]=e(r[n%r.length],o[n%o.length]);else for(let t=0;t<d.length;++t){const a=n.util.indexToLoc(t,u,l),s=a.slice(-p);g.forEach(e=>s[e]=0);const i=n.util.locToIndex(s,p,f),c=a.slice(-h);m.forEach(e=>c[e]=0);const b=n.util.locToIndex(c,h,x);d[t]=e(r[i],o[b])}return[d,i]}}const nn=en((e,n)=>e+n);function tn(e){return(t,a,r)=>{const o=n.util.getTypedArrayFromDType(a,t.length);for(let n=0;n<t.length;++n)o[n]=e(t[n],r);return o}}const an=tn(e=>Math.ceil(e));const rn=tn(e=>Math.exp(e)),on=tn(e=>Math.expm1(e)),sn=tn(e=>Math.floor(e));const un=en((e,n)=>e>n?1:0),ln=en((e,n)=>e<n?1:0);const cn=tn(e=>Math.log(e));const dn=en((e,n)=>Math.max(e,n)),pn=en((e,n)=>Math.min(e,n)),hn=en((e,n)=>e*n);const fn=en((e,n)=>e!==n?1:0);const xn=tn(e=>1/Math.sqrt(e));const gn=en((e,n)=>{const t=e-n;return t*t});const mn=en((e,n)=>e-n);var bn=Object.freeze({__proto__:null,simpleAbsImpl:function(e){const n=new Float32Array(e.length);for(let t=0;t<e.length;++t)n[t]=Math.abs(e[t]);return n},addImpl:nn,bincountImpl:function(e,t,a,r,o){const s=n.util.sizeFromShape(r),i=n.util.makeZerosTypedArray(o,a);for(let n=0;n<e.length;n++){const a=e[n];if(a<0)throw new Error("Input x must be non-negative!");a>=o||(i[a]+=s>0?t[n]:1)}return i},bincountReduceImpl:function(e,t,a,r=!1){const o=e.shape[0],s=e.shape[1],i=n.buffer([o,a],t.dtype);for(let n=0;n<o;n++)for(let o=0;o<s;o++){const s=e.get(n,o);if(s<0)throw new Error("Input x must be non-negative!");s>=a||(r?i.set(1,n,s):t.size>0?i.set(i.get(n,s)+t.get(n,o),n,s):i.set(i.get(n,s)+1,n,s))}return i},ceilImpl:an,concatImpl:function(e,t,a,r){const o=n.util.getArrayFromDType(a,n.util.sizeFromShape(t));if(r&&"string"!==a){let t=0;e.forEach(e=>{const a=n.util.sizeFromShape(e.shape);o.set(e.vals,t),t+=a})}else{let r=0;e.forEach(e=>{const s="string"===a?n.backend_util.fromUint8ToStringArray(e.vals):e.vals;let i=0;for(let n=0;n<e.shape[0];++n){const a=n*t[1]+r;for(let n=0;n<e.shape[1];++n)o[a+n]=s[i++]}r+=e.shape[1]})}return o},expImpl:rn,expm1Impl:on,floorImpl:sn,gatherV2Impl:function(e,t,a){const r=n.buffer(a,e.dtype);for(let n=0;n<r.size;++n){const a=r.indexToLoc(n).slice(),o=a[0],s=a[2],i=t.locToIndex([o,s]);a[2]=t.values[i];const u=e.locToIndex(a);r.values[n]=e.values[u]}return r},greaterImpl:un,lessImpl:ln,linSpaceImpl:function(e,t,a){const r=(t-e)/(a-1),o=n.util.makeZerosTypedArray(a,"float32");o[0]=e;for(let e=1;e<o.length;e++)o[e]=o[e-1]+r;return o},logImpl:cn,maxImpl:function(e,t,a,r){const o=n.util.getTypedArrayFromDType(r,n.util.sizeFromShape(a));for(let n=0;n<o.length;++n){const a=n*t;let r=e[a];for(let n=0;n<t;++n){const t=e[a+n];t>r&&(r=t)}o[n]=r}return o},maximumImpl:dn,minimumImpl:pn,multiplyImpl:hn,negImpl:function(e,t,a){const r=n.util.createScalarValue(-1,a);return hn([],t,r,e,a)},notEqualImpl:fn,prodImpl:function(e,t,a,r){const[o,s]=n.backend_util.computeOutAndReduceShapes(e,r),i=n.upcastType(t,"int32"),u=n.util.makeZerosTypedArray(n.util.sizeFromShape(o),i),l=n.util.sizeFromShape(s);for(let e=0;e<u.length;++e){const n=e*l;let t=1;for(let e=0;e<l;++e)t*=a[n+e];u[e]=t}return{outVals:u,outShape:o,outDtype:i}},rangeImpl:function(e,t,a,r){if(e===t||e<t&&a<0||t<e&&a>1)return n.util.makeZerosTypedArray(0,r);const o=Math.abs(Math.ceil((t-e)/a)),s=n.util.makeZerosTypedArray(o,r);t<e&&1===a&&(a=-1),s[0]=e;for(let e=1;e<s.length;e++)s[e]=s[e-1]+a;return s},rsqrtImpl:xn,sliceImpl:function(e,t,a,r,o){const s=n.slice_util.isSliceContinous(r,t,a),i=n.util.sizeFromShape(a),u=n.util.computeStrides(r);if(s){const a=n.slice_util.computeFlatOffset(t,u);return"string"===o?e.slice(a,a+i):e.subarray(a,a+i)}const l="string"===o?n.backend_util.fromUint8ToStringArray(e):e,c=n.buffer(r,o,l),d=n.buffer(a,o);for(let e=0;e<d.size;++e){const n=d.indexToLoc(e),a=n.map((e,n)=>e+t[n]);d.set(c.get(...a),...n)}return"string"===o?n.backend_util.fromStringArrayToUint8(d.values):d.values},squaredDifferenceImpl:gn,stridedSliceImpl:function(e,t,a,r){const o=n.buffer(e,t.dtype);for(let e=0;e<o.size;e++){const n=o.indexToLoc(e),s=new Array(n.length);for(let e=0;e<s.length;e++)s[e]=n[e]*a[e]+r[e];o.set(t.get(...s),...n)}return o},subImpl:mn,tileImpl:function(e,t){const a=new Array(e.rank);for(let n=0;n<a.length;n++)a[n]=e.shape[n]*t[n];const r=n.buffer(a,e.dtype);for(let n=0;n<r.values.length;++n){const t=r.indexToLoc(n),a=new Array(e.rank);for(let n=0;n<a.length;n++)a[n]=t[n]%e.shape[n];const o=e.locToIndex(a);r.values[n]=e.values[o]}return r},topKImpl:function(e,t,a,r,o){const s=t[t.length-1],[i,u]=[e.length/s,s],l=n.util.getTypedArrayFromDType(a,i*r),c=n.util.getTypedArrayFromDType("int32",i*r);for(let n=0;n<i;n++){const t=n*u,a=e.subarray(t,t+u),o=[];for(let e=0;e<a.length;e++)o.push({value:a[e],index:e});o.sort((e,n)=>n.value-e.value);const s=n*r,i=l.subarray(s,s+r),d=c.subarray(s,s+r);for(let e=0;e<r;e++)i[e]=o[e].value,d[e]=o[e].index}const d=t.slice();return d[d.length-1]=r,[n.buffer(d,a,l),n.buffer(d,"int32",c)]},transposeImpl:function(e,t,a,r,o){const s=t.length,i=n.util.sizeFromShape(t),u=n.util.computeStrides(t),l=n.util.computeStrides(o),c=n.util.getTypedArrayFromDType(a,n.util.sizeFromShape(o));for(let t=0;t<i;++t){const a=n.util.indexToLoc(t,s,u),o=new Array(a.length);for(let e=0;e<o.length;e++)o[e]=a[r[e]];c[n.util.locToIndex(o,s,l)]=e[t]}return c},uniqueImpl:function(e,t,a,r){const o=n.util.parseAxisParam(t,a)[0],s=[1,a[0],1];for(let e=0;e<o;e++)s[0]*=a[e];s[1]=a[o];for(let e=o+1;e<a.length;e++)s[2]*=a[e];const i={},u=new Int32Array(a[o]),l=new n.TensorBuffer(s,r,e),c=[],d=1===s[0]&&1===s[2];for(let n=0;n<a[o];n++){let t;if(d)t=e[n].toString();else{const e=[];for(let t=0;t<s[0];t++)for(let a=0;a<s[2];a++)e.push(l.get(t,n,a));t=e.join(",")}if(void 0!==i[t])u[n]=i[t];else{const e=Object.keys(i).length;i[t]=e,u[n]=e,c.push(n)}}const p=s.slice();p[1]=Object.keys(i).length;const h=new n.TensorBuffer(p,r);c.forEach((e,n)=>{for(let t=0;t<s[0];t++)for(let a=0;a<s[2];a++)h.set(l.get(t,e,a),t,n,a)});const f=a.slice();return f[o]=p[1],{outputValues:h.values,outputShape:f,indices:u}}});const{addImpl:vn,bincountImpl:Cn,bincountReduceImpl:$n,ceilImpl:In,concatImpl:Rn,expImpl:kn,expm1Impl:yn,floorImpl:wn,gatherV2Impl:Tn,greaterImpl:En,lessImpl:Nn,linSpaceImpl:Sn,logImpl:An,maxImpl:Fn,maximumImpl:_n,minimumImpl:On,multiplyImpl:Dn,negImpl:Pn,prodImpl:Ln,rangeImpl:Bn,rsqrtImpl:Vn,simpleAbsImpl:Wn,sliceImpl:Mn,stridedSliceImpl:Gn,subImpl:Un,tileImpl:zn,topKImpl:Xn,transposeImpl:Hn,uniqueImpl:jn}=bn;function Kn(e,n){return["x","y","z","w","u","v"].slice(0,n).map(n=>`${e}.${n}`)}function qn(e,n){return 1===n?[e]:Kn(e,n)}class Yn{constructor(e){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0,this.outputShape=e;const n=e.length;if(0===n)this.userCode="\n        void main() {\n          setOutput(vec4(getA(), 0., 0., 0.));\n        }\n      ";else{const t=qn("rc",n),a=Ye(n),r=function(e,n,t){if(1===e)return`rc > ${n[0]}`;let a="";for(let r=e-2;r<e;r++)a+=`${t[r]} >= ${n[r]}`,r<e-1&&(a+="||");return a}(n,e,t),o=function(e,n,t,a){if(1===e)return"";const r=a.slice(-2);return`\n    int r = ${r[0]};\n    int c = ${r[1]};\n    int rp1 = r + 1;\n    int cp1 = c + 1;\n\n    bool cEdge = cp1 >= ${n};\n    bool rEdge = rp1 >= ${t};\n  `}(n,e[e.length-1],e[e.length-2],t),s=function(e,n){const t=e.length,a=function(e,n){const t=[];for(let a=0;a<=1;a++)for(let r=0;r<=1;r++){let o=`${0===a?"r":"rp1"}, ${0===r?"c":"cp1"}`;for(let t=2;t<e;t++)o=`${n[n.length-1-t]},`+o;t.push(o)}return t}(t,n);if(1===t)return`getA(rc),\n            rc + 1 >= ${e[0]} ? 0. : getA(rc + 1),\n            0, 0`;return`getA(${a[0]}),\n          cEdge ? 0. : getA(${a[1]}),\n          rEdge ? 0. : getA(${a[2]}),\n          rEdge || cEdge ? 0. : getA(${a[3]})`}(e,t);this.userCode=`\n        void main() {\n          ${a} rc = getOutputCoords();\n\n          if(${r}) {\n            setOutput(vec4(0));\n          } else {\n            ${o}\n\n            setOutput(vec4(${s}));\n          }\n        }\n      `}}}class Qn{constructor(e,n){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e;let t="";for(let e=0;e<4;e++){let n="thisRC = rc;";e%2==1&&(n+="thisRC.z += 1;"),e>1&&(n+="thisRC.y += 1;"),t+=`\n        ${n}\n        ${e>0?"if(thisRC.y < rows && thisRC.z < cols){":""}\n          int flatIndex = getFlatIndex(thisRC);\n\n          ivec3 inputRC = inputCoordsFromReshapedOutCoords(flatIndex);\n          vec2 inputRCInnerDims = vec2(float(inputRC.y),float(inputRC.z));\n\n          result[${e}] =\n            getChannel(getA(inputRC.x, inputRC.y, inputRC.z), inputRCInnerDims);\n        ${e>0?"}":""}\n      `}var a;this.userCode=`\n      ${a=n,`\n    ivec3 inputCoordsFromReshapedOutCoords(int index) {\n      ${se(["r","c","d"],a)}\n      return ivec3(r, c, d);\n    }\n  `}\n      ${ie(e)}\n\n      void main() {\n        ivec3 rc = getOutputCoords();\n\n        vec4 result = vec4(0.);\n\n        ivec3 thisRC;\n        int rows = ${e[1]};\n        int cols = ${e[2]};\n\n        ${t}\n\n        setOutput(result);\n      }\n    `}}class Zn{constructor(e){this.gpgpu=e,this.numUsedTextures=0,this.numFreeTextures=0,this._numBytesAllocated=0,this._numBytesFree=0,this.freeTextures={},this.logEnabled=!1,this.usedTextures={}}acquireTexture(e,n,t){const a=et(n,t),r=nt(e,a,t);r in this.freeTextures||(this.freeTextures[r]=[]),r in this.usedTextures||(this.usedTextures[r]=[]);const o=Jn(e,a,this.gpgpu.gl,this.gpgpu.textureConfig,t);if(this.freeTextures[r].length>0){this.numFreeTextures--,this.numUsedTextures++,this._numBytesFree-=o,this.log();const e=this.freeTextures[r].shift();return this.usedTextures[r].push(e),e}let s;return a===u.PACKED_2X2_FLOAT32?s=this.gpgpu.createPackedMatrixTexture(e[0],e[1]):a===u.PACKED_2X2_FLOAT16?s=this.gpgpu.createFloat16PackedMatrixTexture(e[0],e[1]):a===u.UNPACKED_FLOAT32?s=this.gpgpu.createFloat32MatrixTexture(e[0],e[1]):a===u.UNPACKED_FLOAT16?s=this.gpgpu.createFloat16MatrixTexture(e[0],e[1]):a===u.PACKED_4X1_UNSIGNED_BYTE&&(s=this.gpgpu.createUnsignedBytesMatrixTexture(e[0],e[1])),this.usedTextures[r].push(s),this.numUsedTextures++,this._numBytesAllocated+=o,this.log(),s}releaseTexture(e,t,a,r){if(null==this.freeTextures)return;const o=et(a,r),s=nt(t,o,r);s in this.freeTextures||(this.freeTextures[s]=[]);const i=Jn(t,o,this.gpgpu.gl,this.gpgpu.textureConfig,r),u=n.env().get("WEBGL_DELETE_TEXTURE_THRESHOLD");-1!==u&&this._numBytesAllocated>u?(this.gpgpu.deleteMatrixTexture(e),this._numBytesAllocated-=i):(this.freeTextures[s].push(e),this.numFreeTextures++,this._numBytesFree+=i),this.numUsedTextures--;const l=this.usedTextures[s],c=l.indexOf(e);if(c<0)throw new Error("Cannot release a texture that was never provided by this texture manager");l.splice(c,1),this.log()}log(){if(!this.logEnabled)return;const e=this.numFreeTextures+this.numUsedTextures;console.log("Free/Used",`${this.numFreeTextures} / ${this.numUsedTextures}`,`(${e})`);const n=this._numBytesFree/this._numBytesAllocated;console.log(`Bytes allocated: ${this._numBytesAllocated}`),console.log(`Bytes unused: ${this._numBytesFree} (${Math.round(100*n)}%)`)}get numBytesAllocated(){return this._numBytesAllocated}get numBytesFree(){return this._numBytesFree}getNumUsedTextures(){return this.numUsedTextures}getNumFreeTextures(){return this.numFreeTextures}dispose(){if(null!=this.freeTextures){for(const e in this.freeTextures)this.freeTextures[e].forEach(e=>{this.gpgpu.deleteMatrixTexture(e)});for(const e in this.usedTextures)this.usedTextures[e].forEach(e=>{this.gpgpu.deleteMatrixTexture(e)});this.freeTextures=null,this.usedTextures=null,this.numUsedTextures=0,this.numFreeTextures=0,this._numBytesAllocated=0,this._numBytesFree=0}}}function Jn(e,n,t,a,r){const o=function(e,n){switch(e){case u.PACKED_2X2_FLOAT32:return ye(n);case u.PACKED_2X2_FLOAT16:return Te(n);case u.UNPACKED_FLOAT32:return ve(n);case u.UNPACKED_FLOAT16:return $e(n);case u.PACKED_4X1_UNSIGNED_BYTE:return Re(n);default:throw new Error(`Unknown physical texture type ${e}`)}}(n,a);let s;if(r){const[n,t]=d(e[0],e[1]);s=n*t}else{const[n,t]=l(e[0],e[1]);s=n*t}return s*function(e,n){const t=e;if(n===t.R32F)return 4;if(n===t.R16F)return 2;if(n===t.RGBA32F)return 16;if(n===e.RGBA)return 16;if(n===t.RGBA16F)return 8;throw new Error(`Unknown internal format ${n}`)}(t,o)}function et(e,t){if(e===i.UPLOAD)return u.PACKED_2X2_FLOAT32;if(e===i.RENDER||null==e)return function(e){return n.env().getBool("WEBGL_RENDER_FLOAT32_ENABLED")?e?u.PACKED_2X2_FLOAT32:u.UNPACKED_FLOAT32:e?u.PACKED_2X2_FLOAT16:u.UNPACKED_FLOAT16}(t);if(e===i.DOWNLOAD||e===i.PIXELS)return u.PACKED_4X1_UNSIGNED_BYTE;throw new Error(`Unknown logical texture type ${e}`)}function nt(e,n,t){return`${e[0]}_${e[1]}_${n}_${t}`}class tt{constructor(e,n){this.variableNames=["A"],this.outputShape=e,this.userCode=`\n      float unaryOperation(float x) {\n        ${n}\n      }\n\n      void main() {\n        float x = getAAtOutCoords();\n        float y = unaryOperation(x);\n\n        setOutput(y);\n      }\n    `}}const at="if (isnan(x)) return x;",rt="return abs(x);",ot="return x;";class st{constructor(e,n){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e,this.userCode=`\n      vec4 unaryOperation(vec4 x) {\n        ${n}\n      }\n\n      void main() {\n        vec4 x = getAAtOutCoords();\n        vec4 y = unaryOperation(x);\n\n        setOutput(y);\n      }\n    `}}class it{constructor(e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!1,this.outputShape=e;const n=e.length,t=qn("rc",n),a=Ye(n),r=function(e,n){if(1===e)return"rc";let t="";for(let a=0;a<e;a++)t+=n[a],a<e-1&&(t+=",");return t}(n,t),o=t.slice(-2),s=n<=1?"rc":`vec2(${o.join(",")})`;this.userCode=`\n      void main() {\n        ${a} rc = getOutputCoords();\n        vec4 packedInput = getA(${r});\n\n        setOutput(getChannel(packedInput, ${s}));\n      }\n    `}}const ut=n.kernel_impls.whereImpl,lt={};class ct extends n.KernelBackend{constructor(e){if(super(),this.pendingRead=new WeakMap,this.pendingDisposal=new WeakSet,this.dataRefCount=new WeakMap,this.numBytesInGPU=0,this.uploadWaitMs=0,this.downloadWaitMs=0,this.warnedAboutMemory=!1,this.warnedAboutCPUBackend=!1,this.pendingDeletes=0,this.disposed=!1,!n.env().getBool("HAS_WEBGL"))throw new Error("WebGL is not supported on this device");if(null==e){const e=o(n.env().getNumber("WEBGL_VERSION"));this.binaryCache=((t=n.env().getNumber("WEBGL_VERSION"))in lt||(lt[t]={}),lt[t]),this.gpgpu=new Be(e),this.canvas=e.canvas,this.gpgpuCreatedLocally=!0}else this.gpgpu=e,this.binaryCache={},this.gpgpuCreatedLocally=!1,this.canvas=e.gl.canvas;var t;this.textureManager=new Zn(this.gpgpu),this.numMBBeforeWarning=null==n.env().global.screen?1024:n.env().global.screen.height*n.env().global.screen.width*window.devicePixelRatio*600/1024/1024,this.texData=new n.DataStorage(this,n.engine())}numDataIds(){return this.texData.numDataIds()+(this.cpuBackend?this.cpuBackend.numDataIds():0)-this.pendingDeletes}write(e,t,a){if((n.env().getBool("WEBGL_CHECK_NUMERICAL_PROBLEMS")||n.env().getBool("DEBUG"))&&this.checkNumericalProblems(e),"complex64"===a&&null!=e)throw new Error("Cannot write to a complex64 dtype. Please use tf.complex(real, imag).");const r={};return this.texData.set(r,{shape:t,dtype:a,values:e,usage:i.UPLOAD,refCount:1,complexParentRefCount:0}),r}incRef(e){this.texData.get(e).refCount++}decRef(e){if(this.texData.has(e)){this.texData.get(e).refCount--}}decComplexRef(e){if(this.texData.has(e)){const n=this.texData.get(e);n.complexParentRefCount>0&&n.refCount--}}move(e,t,a,r){if(n.env().getBool("DEBUG")&&this.checkNumericalProblems(t),"complex64"===r)throw new Error("Cannot write to a complex64 dtype. Please use tf.complex(real, imag).");this.texData.set(e,{shape:a,dtype:r,values:t,usage:i.UPLOAD,refCount:1,complexParentRefCount:0})}disposeIntermediateTensorInfo(e){const n=e.dataId;if(this.texData.has(n)){const e=this.texData.get(n);e.refCount--,e.refCount<1&&this.disposeData(n)}}readSync(e){const t=this.texData.get(e),{values:a,dtype:r,complexTensorInfos:o,slice:s,shape:i,isPacked:u}=t;if(null!=s){let n;n=u?new st(i,ot):new tt(i,ot);const t=this.runWebGLProgram(n,[{dataId:e,shape:i,dtype:r}],r),a=this.readSync(t.dataId);return this.disposeIntermediateTensorInfo(t),a}if(null!=a)return this.convertAndCacheOnCPU(e);if("string"===r)return a;const l=null!=this.activeTimers;let c,d;if(l&&(c=n.util.now()),"complex64"===r){const e=this.readSync(o.real.dataId),t=this.readSync(o.imag.dataId);d=n.backend_util.mergeRealAndImagArrays(e,t)}else d=this.getValuesFromTexture(e);return l&&(this.downloadWaitMs+=n.util.now()-c),this.convertAndCacheOnCPU(e,d)}async read(e){if(this.pendingRead.has(e)){const n=this.pendingRead.get(e);return new Promise(e=>n.push(e))}const t=this.texData.get(e),{values:a,shape:r,slice:o,dtype:s,complexTensorInfos:i,isPacked:u}=t;if(null!=o){let n;n=u?new st(r,ot):new tt(r,ot);const t=this.runWebGLProgram(n,[{dataId:e,shape:r,dtype:s}],s),a=this.read(t.dataId);return this.disposeIntermediateTensorInfo(t),a}if(null!=a)return this.convertAndCacheOnCPU(e);if(!n.env().getBool("WEBGL_DOWNLOAD_FLOAT_ENABLED")&&2===n.env().getNumber("WEBGL_VERSION"))throw new Error("tensor.data() with WEBGL_DOWNLOAD_FLOAT_ENABLED=false and WEBGL_VERSION=2 not yet supported.");let l,d,p=null;if("complex64"!==s&&n.env().get("WEBGL_BUFFER_SUPPORTED")){l=this.decode(e);const n=this.texData.get(l.dataId);p=this.gpgpu.createBufferFromTexture(n.texture,...c(r))}if(this.pendingRead.set(e,[]),"complex64"!==s&&await this.gpgpu.createAndWaitForFence(),"complex64"===s){const e=await Promise.all([this.read(i.real.dataId),this.read(i.imag.dataId)]),t=e[0],a=e[1];d=n.backend_util.mergeRealAndImagArrays(t,a)}else if(null==p)d=this.getValuesFromTexture(e);else{const e=n.util.sizeFromShape(r);d=this.gpgpu.downloadFloat32MatrixFromBuffer(p,e)}null!=l&&this.disposeIntermediateTensorInfo(l);const h=this.convertAndCacheOnCPU(e,d),f=this.pendingRead.get(e);return this.pendingRead.delete(e),f.forEach(e=>e(h)),this.pendingDisposal.has(e)&&(this.pendingDisposal.delete(e),this.disposeData(e),this.pendingDeletes--),h}bufferSync(e){const t=this.readSync(e.dataId);let a=t;if("string"===e.dtype)try{a=t.map(e=>n.util.decodeString(e))}catch(e){throw new Error("Failed to decode encoded string bytes into utf-8")}return n.buffer(e.shape,e.dtype,a)}checkNumericalProblems(e){if(null!=e)for(let t=0;t<e.length;t++){const a=e[t];if(!f(a)){if(n.env().getBool("WEBGL_RENDER_FLOAT32_CAPABLE"))throw Error(`The value ${a} cannot be represented with your `+"current settings. Consider enabling float32 rendering: 'tf.env().set('WEBGL_RENDER_FLOAT32_ENABLED', true);'");throw Error(`The value ${a} cannot be represented on this device.`)}}}getValuesFromTexture(e){const{shape:t,dtype:a,isPacked:r}=this.texData.get(e),o=n.util.sizeFromShape(t);if(n.env().getBool("WEBGL_DOWNLOAD_FLOAT_ENABLED")){const n=this.decode(e),a=this.texData.get(n.dataId),r=this.gpgpu.downloadMatrixFromPackedTexture(a.texture,...c(t)).subarray(0,o);return this.disposeIntermediateTensorInfo(n),r}const s=n.env().getBool("WEBGL_PACK")&&!0===r,i=s?M(t):t,u=s?new pe(i):new de(i),l=this.runWebGLProgram(u,[{shape:i,dtype:a,dataId:e}],"float32"),d=this.texData.get(l.dataId),p=this.gpgpu.downloadByteEncodedFloatMatrixFromOutputTexture(d.texture,d.texShape[0],d.texShape[1]).subarray(0,o);return this.disposeIntermediateTensorInfo(l),p}async time(e){const t=this.activeTimers,a=[];let r=!1;null==this.programTimersStack?(this.programTimersStack=a,r=!0):this.activeTimers.push(a),this.activeTimers=a,e();const o=n.util.flatten(this.activeTimers.map(e=>e.query)).filter(e=>null!=e),s=n.util.flatten(this.activeTimers.map(e=>e.name)).filter(e=>null!=e);this.activeTimers=t,r&&(this.programTimersStack=null);const i={uploadWaitMs:this.uploadWaitMs,downloadWaitMs:this.downloadWaitMs,kernelMs:null,wallMs:null};if(n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE")>0){const e=await Promise.all(o);i.kernelMs=n.util.sum(e),i.getExtraProfileInfo=()=>e.map((e,n)=>({name:s[n],ms:e})).map(e=>`${e.name}: ${e.ms}`).join(", ")}else i.kernelMs={error:"WebGL query timers are not supported in this environment."};return this.uploadWaitMs=0,this.downloadWaitMs=0,i}memory(){return{unreliable:!1,numBytesInGPU:this.numBytesInGPU,numBytesInGPUAllocated:this.textureManager.numBytesAllocated,numBytesInGPUFree:this.textureManager.numBytesFree}}startTimer(){return n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE")>0?this.gpgpu.beginQuery():{startMs:n.util.now(),endMs:null}}endTimer(e){return n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE")>0?(this.gpgpu.endQuery(),e):(e.endMs=n.util.now(),e)}async getQueryTime(e){if(n.env().getNumber("WEBGL_DISJOINT_QUERY_TIMER_EXTENSION_RELIABLE")>0)return this.gpgpu.waitForQueryAndGetTime(e);const t=e;return t.endMs-t.startMs}disposeData(e){if(this.pendingDisposal.has(e))return;if(this.pendingRead.has(e))return this.pendingDisposal.add(e),void this.pendingDeletes++;if(!this.texData.has(e))return;if(this.texData.get(e).complexParentRefCount>0)return void this.texData.get(e).refCount--;this.releaseGPUData(e);const{complexTensorInfos:n}=this.texData.get(e);null!=n&&(this.texData.get(n.real.dataId).complexParentRefCount--,this.disposeIntermediateTensorInfo(n.real),this.texData.get(n.imag.dataId).complexParentRefCount--,this.disposeIntermediateTensorInfo(n.imag)),this.texData.delete(e)}releaseGPUData(e){const{texture:n,dtype:t,texShape:a,usage:r,isPacked:o,slice:s}=this.texData.get(e),i=s&&s.origDataId||e,u=this.dataRefCount.get(i);u>1?this.dataRefCount.set(i,u-1):(this.dataRefCount.delete(i),null!=n&&(this.numBytesInGPU-=this.computeBytes(a,t),this.textureManager.releaseTexture(n,a,r,o)));const l=this.texData.get(e);l.texture=null,l.texShape=null,l.isPacked=!1,l.slice=null}getTexture(e){return this.uploadToGPU(e),this.texData.get(e).texture}getDataInfo(e){return this.texData.get(e)}getCPUBackend(){return n.env().getBool("WEBGL_CPU_FORWARD")?(null==this.cpuBackend&&(this.cpuBackend=n.engine().findBackend("cpu")),this.cpuBackend):null}shouldExecuteOnCPU(e,t=128){const a=this.getCPUBackend();return n.env().getBool("IS_TEST")||this.warnedAboutCPUBackend||null!=a||(console.warn("Your application contains ops that are small enough to be executed on the CPU backend, however the CPU backend cannot be found. Consider importing the CPU backend (@tensorflow/tfjs-backend-cpu) for better performance."),this.warnedAboutCPUBackend=!0),null!=a&&e.every(e=>null==this.texData.get(e.dataId).texture&&n.util.sizeFromShape(e.shape)<t)}getGPGPUContext(){return this.gpgpu}where(e){n.backend_util.warn("tf.where() in webgl locks the UI thread. Call tf.whereAsync() instead");const t=e.dataSync();return ut(e.shape,t)}packedUnaryOp(e,n,t){const a=new st(e.shape,n);return this.compileAndRun(a,[e],t)}abs(e){if(this.shouldExecuteOnCPU([e])&&"complex64"!==e.dtype){const n=Wn(this.texData.get(e.dataId).values);return this.makeOutput(e.shape,e.dtype,n)}if(n.env().getBool("WEBGL_PACK_UNARY_OPERATIONS"))return this.packedUnaryOp(e,rt,e.dtype);const t=new tt(e.shape,rt);return this.compileAndRun(t,[e])}makeTensorInfo(e,t,a){let r;if("string"===t&&null!=a&&a.length>0&&n.util.isString(a[0])){const o=a.map(e=>n.util.encodeString(e));r=this.write(o,e,t)}else r=this.write(a,e,t);return this.texData.get(r).usage=null,{dataId:r,shape:e,dtype:t}}makeOutput(e,t,a){const{dataId:r}=this.makeTensorInfo(e,t,a);return n.engine().makeTensorFromDataId(r,e,t,this)}unpackTensor(e){const n=new it(e.shape);return this.runWebGLProgram(n,[e],e.dtype)}packTensor(e){const n=new Yn(e.shape);return this.runWebGLProgram(n,[e],e.dtype,null,!0)}packedReshape(e,n){const t=[V(e.shape),...W(e.shape)],a={dtype:e.dtype,shape:t,dataId:e.dataId},r=[V(n),...W(n)],o=new Qn(r,t),s=this.runWebGLProgram(o,[a],e.dtype,null,!0);return{dataId:s.dataId,shape:n,dtype:s.dtype}}decode(e){const n=this.texData.get(e),{isPacked:t,shape:a,dtype:r}=n,o=M(a);let s;s=t?new ce(o):new le(o);return{dtype:r,shape:a,dataId:this.runWebGLProgram(s,[{shape:o,dtype:r,dataId:e}],r,null,!0).dataId}}runWebGLProgram(e,t,a,r,o=!1){const i=this.makeTensorInfo(e.outputShape,a),u=this.texData.get(i.dataId);if(e.packedOutput&&(u.isPacked=!0),e.outPackingScheme===s.DENSE){const n=c(e.outputShape);u.texShape=n.map(e=>2*e)}if(null!=e.outTexUsage&&(u.usage=e.outTexUsage),0===n.util.sizeFromShape(i.shape))return u.values=n.util.getTypedArrayFromDType(i.dtype,0),i;const l=[],d=t.map(t=>{if("complex64"===t.dtype)throw new Error("GPGPUProgram does not support complex64 input. For complex64 dtypes, please separate the program into real and imaginary parts.");let a=this.texData.get(t.dataId);if(null==a.texture){if(!e.packedInputs&&n.util.sizeFromShape(t.shape)<=n.env().getNumber("WEBGL_SIZE_UPLOAD_UNIFORM"))return{shape:t.shape,texData:null,isUniform:!0,uniformValues:a.values};e.packedInputs&&(a.isPacked=!0,a.shape=t.shape)}else if(!!a.isPacked!=!!e.packedInputs)t=a.isPacked?this.unpackTensor(t):this.packTensor(t),l.push(t),a=this.texData.get(t.dataId);else if(a.isPacked&&!z(a.shape,t.shape)){const e=t,n=t.shape;t.shape=a.shape,t=this.packedReshape(t,n),l.push(t),a=this.texData.get(t.dataId),e.shape=n}return this.uploadToGPU(t.dataId),{shape:t.shape,texData:a,isUniform:!1}});this.uploadToGPU(i.dataId);const p={shape:i.shape,texData:u,isUniform:!1},h=function(e,n,t){let a="";n.concat(t).forEach(e=>{const n=null!=e.texData&&null!=e.texData.slice&&e.texData.slice.flatOffset>0,t=e.isUniform?"uniform":e.texData.texShape;a+=`${e.shape}_${t}_${n}`});const r=e.userCode;let o=e.constructor.name;return o+="_"+a+"_"+r,o}(e,d,p),f=this.getAndSaveBinary(h,()=>function(e,t,a,r){const o=t.userCode,s=a.map((e,n)=>{const a={logicalShape:e.shape,texShape:e.isUniform?null:e.texData.texShape,isUniform:e.isUniform,isPacked:!e.isUniform&&e.texData.isPacked,flatOffset:null};return null!=e.texData&&null!=e.texData.slice&&e.texData.slice.flatOffset>0&&(a.flatOffset=e.texData.slice.flatOffset),{name:t.variableNames[n],shapeInfo:a}}),i=s.map(e=>e.shapeInfo),u={logicalShape:r.shape,texShape:r.texData.texShape,isUniform:!1,isPacked:r.texData.isPacked,flatOffset:null},l=We(s,u,o,t.packedInputs),c=e.createProgram(l);let d=null;const p=e.getUniformLocation(c,"NAN",!1);1===n.env().getNumber("WEBGL_VERSION")&&(d=e.getUniformLocation(c,"INFINITY",!1));const h={};for(let n=0;n<t.variableNames.length;n++){const a=t.variableNames[n],r=!1;h[a]=e.getUniformLocation(c,a,r),h[`offset${a}`]=e.getUniformLocation(c,`offset${a}`,r)}return{program:t,source:l,webGLProgram:c,uniformLocations:h,inShapeInfos:i,outShapeInfo:u,infLoc:d,nanLoc:p}}(this.gpgpu,e,d,p)),x=null!=this.activeTimers;let g;if(x&&(g=this.startTimer()),function(e,t,a,r,o){Je(t.inShapeInfos,a),Je([t.outShapeInfo],[r]);const s=r.texData.texture,i=r.texData.texShape;r.texData.isPacked?e.setOutputPackedMatrixTexture(s,i[0],i[1]):e.setOutputMatrixTexture(s,i[0],i[1]),e.setProgram(t.webGLProgram),1===n.env().getNumber("WEBGL_VERSION")&&null!==t.infLoc&&e.gl.uniform1f(t.infLoc,1/0),null!==t.nanLoc&&e.gl.uniform1f(t.nanLoc,NaN),a.forEach((a,r)=>{const o=t.program.variableNames[r],s=t.uniformLocations[o],i=t.uniformLocations[`offset${o}`];if(null!=s)if(a.isUniform)if(n.util.sizeFromShape(a.shape)<2)e.gl.uniform1f(s,a.uniformValues[0]);else{let n=a.uniformValues;n instanceof Float32Array||(n=new Float32Array(n)),e.gl.uniform1fv(s,n)}else null!=a.texData.slice&&null!=i&&e.gl.uniform1i(i,a.texData.slice.flatOffset),e.setInputMatrixTexture(a.texData.texture,s,r)}),null!=o&&o(e,t.webGLProgram),e.executeProgram()}(this.gpgpu,f,d,p,r),l.forEach(e=>this.disposeIntermediateTensorInfo(e)),x&&(g=this.endTimer(g),this.activeTimers.push({name:e.constructor.name,query:this.getQueryTime(g)})),!n.env().getBool("WEBGL_LAZILY_UNPACK")&&u.isPacked&&!1===o){const e=this.unpackTensor(i);return this.disposeIntermediateTensorInfo(i),e}return i}compileAndRun(e,t,a,r,o=!1){a=a||t[0].dtype;const s=this.runWebGLProgram(e,t,a,r,o);return n.engine().makeTensorFromDataId(s.dataId,s.shape,s.dtype)}getAndSaveBinary(e,n){return e in this.binaryCache||(this.binaryCache[e]=n()),this.binaryCache[e]}getTextureManager(){return this.textureManager}dispose(){if(!this.disposed){if(!n.env().getBool("IS_TEST")){Object.keys(this.binaryCache).forEach(e=>{this.gpgpu.deleteProgram(this.binaryCache[e].webGLProgram),delete this.binaryCache[e]})}this.textureManager.dispose(),null!=this.canvas&&"undefined"!=typeof HTMLCanvasElement&&this.canvas instanceof HTMLCanvasElement?this.canvas.remove():this.canvas=null,this.gpgpuCreatedLocally&&(this.gpgpu.program=null,this.gpgpu.dispose()),this.disposed=!0}}floatPrecision(){return null==this.floatPrecisionValue&&(this.floatPrecisionValue=n.tidy(()=>{if(!n.env().get("WEBGL_RENDER_FLOAT32_ENABLED")){const e=n.env().getBool("DEBUG");n.env().set("DEBUG",!1);const t=this.abs(n.scalar(1e-8)).dataSync()[0];if(n.env().set("DEBUG",e),t>0)return 32}return 16})),this.floatPrecisionValue}epsilon(){return 32===this.floatPrecision()?1e-7:1e-4}uploadToGPU(e){const t=this.texData.get(e),{shape:a,dtype:r,values:o,texture:s,usage:u,isPacked:l}=t;if(null!=s)return;const c=null!=this.activeTimers;let p;c&&(p=n.util.now());let h=t.texShape;if(null==h&&(h=G(a,l),t.texShape=h),null!=o){const e=M(a);let s,u=h[1],f=h[0];const x=o instanceof Uint8Array;l?([u,f]=d(h[0],h[1]),s=new fe(e,[f,u],x)):s=new he(e,[f,u],x);const g=this.makeTensorInfo([f,u],r);this.texData.get(g.dataId).usage=x?i.PIXELS:i.UPLOAD,this.gpgpu.uploadDenseMatrixToTexture(this.getTexture(g.dataId),u,f,o);const m=!0,b=this.runWebGLProgram(s,[g],r,null,m),v=this.texData.get(b.dataId);t.texture=v.texture,t.texShape=v.texShape,t.isPacked=v.isPacked,t.usage=v.usage,this.disposeIntermediateTensorInfo(g),this.texData.delete(b.dataId),t.values=null,c&&(this.uploadWaitMs+=n.util.now()-p)}else{const e=this.acquireTexture(h,u,r,l);t.texture=e}}convertAndCacheOnCPU(e,n){const t=this.texData.get(e),{dtype:a}=t;return this.releaseGPUData(e),null!=n&&(t.values=function(e,n){if("float32"===n||"complex64"===n)return e;if("int32"===n||"bool"===n){const t="int32"===n?new Int32Array(e.length):new Uint8Array(e.length);for(let n=0;n<t.length;++n)t[n]=Math.round(e[n]);return t}throw new Error(`Unknown dtype ${n}`)}(n,a)),t.values}acquireTexture(e,n,t,a){if(this.numBytesInGPU+=this.computeBytes(e,t),!this.warnedAboutMemory&&this.numBytesInGPU>1024*this.numMBBeforeWarning*1024){const e=(this.numBytesInGPU/1024/1024).toFixed(2);this.warnedAboutMemory=!0,console.warn(`High memory usage in GPU: ${e} MB, `+"most likely due to a memory leak")}return this.textureManager.acquireTexture(e,n,a)}computeBytes(e,t){return e[0]*e[1]*n.util.bytesPerElement(t)}}function dt(){n.env().set("WEBGL_FORCE_F16_TEXTURES",!0)}n.device_util.isBrowser()&&n.registerBackend("webgl",()=>new ct,2);const pt={forceHalfFloat:dt};class ht{constructor(e,t,a){this.variableNames=["A","B"],this.outputShape=n.backend_util.assertAndGetBroadcastShape(t,a),this.userCode=`\n      float binaryOperation(float a, float b) {\n        ${e}\n      }\n\n      void main() {\n        float a = getAAtOutCoords();\n        float b = getBAtOutCoords();\n        setOutput(binaryOperation(a, b));\n      }\n    `}}class ft{constructor(e,t,a,r=!1){this.variableNames=["A","B"],this.supportsBroadcasting=!0,this.packedInputs=!0,this.packedOutput=!0,this.outputShape=n.backend_util.assertAndGetBroadcastShape(t,a);const o=this.outputShape.length;let s="";if(r)if(0===o||1===n.util.sizeFromShape(this.outputShape))s="\n          result.y = 0.;\n          result.z = 0.;\n          result.w = 0.;\n        ";else{if(s=`\n          ${Ye(o)} coords = getOutputCoords();\n        `,1===o)s+=`\n            result.y = (coords + 1) >= ${this.outputShape[0]} ? 0. : result.y;\n            result.z = 0.;\n            result.w = 0.;\n          `;else{const e=qn("coords",o);s+=`\n            bool nextRowOutOfBounds =\n              (${e[o-2]} + 1) >= ${this.outputShape[o-2]};\n            bool nextColOutOfBounds =\n              (${e[o-1]} + 1) >= ${this.outputShape[o-1]};\n            result.y = nextColOutOfBounds ? 0. : result.y;\n            result.z = nextRowOutOfBounds ? 0. : result.z;\n            result.w = nextColOutOfBounds || nextRowOutOfBounds ? 0. : result.w;\n          `}}this.userCode=`\n      vec4 binaryOperation(vec4 a, vec4 b) {\n        ${e}\n      }\n\n      void main() {\n        vec4 a = getAAtOutCoords();\n        vec4 b = getBAtOutCoords();\n\n        vec4 result = binaryOperation(a, b);\n        ${s}\n\n        setOutput(result);\n      }\n    `}}function xt(e){const{inputs:n,backend:t}=e,{x:a}=n;return t.incRef(a.dataId),{dataId:a.dataId,shape:a.shape,dtype:a.dtype}}const gt={kernelName:n.Identity,backendName:"webgl",kernelFunc:xt};function mt(e){const{inputs:n,backend:t}=e,{real:a,imag:r}=n,o=t.makeTensorInfo(a.shape,"complex64"),s=t.texData.get(o.dataId),i=xt({inputs:{x:a},backend:t});t.texData.get(i.dataId).complexParentRefCount++;const u=xt({inputs:{x:r},backend:t});return t.texData.get(u.dataId).complexParentRefCount++,s.complexTensorInfos={real:i,imag:u},o}const bt={kernelName:n.Complex,backendName:"webgl",kernelFunc:mt},vt="return (a < 0.) ? b * a : a;",Ct="\n  vec4 aLessThanZero = vec4(lessThan(a, vec4(0.)));\n  return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a);\n";const $t={kernelName:n.LeakyRelu,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{alpha:s}=r,i=a.makeTensorInfo([],"float32",n.util.createScalarValue(s,"float32")),u=n.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new ft(Ct,o.shape,i.shape):new ht(vt,o.shape,i.shape),l=a.runWebGLProgram(u,[o,i],o.dtype);return a.disposeIntermediateTensorInfo(i),l}},It="return (a < 0.) ? b * a : a;",Rt="\n  vec4 aLessThanZero = vec4(lessThan(a, vec4(0.)));\n  return (aLessThanZero * (b * a)) + ((vec4(1.0) - aLessThanZero) * a);\n";const kt={kernelName:n.Prelu,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a}=e,{x:r,alpha:o}=t,s=n.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new ft(Rt,r.shape,o.shape):new ht(It,r.shape,o.shape);return a.runWebGLProgram(s,[r,o],r.dtype)}};function yt({opSnippet:e,packedOpSnippet:t,cpuKernelImpl:a,dtype:r}){return({inputs:o,backend:s})=>{const{x:i}=o,u=s,l=r||i.dtype;if(u.shouldExecuteOnCPU([i])&&null!=a){const e=u.texData.get(i.dataId),n=a(e.values,l);return u.makeTensorInfo(i.shape,l,n)}let c;return c=n.env().getBool("WEBGL_PACK_UNARY_OPERATIONS")&&null!=t?new st(i.shape,t):new tt(i.shape,e),u.runWebGLProgram(c,[i],l)}}function wt({opSnippet:e,packedOpSnippet:t,checkOutOfBounds:a=!1,supportsComplex:r=!1,cpuKernelImpl:o,dtype:s}){return({inputs:i,backend:u})=>{const{a:l,b:c}=i,d=u;if(r&&"complex64"===l.dtype){const t=d.texData.get(l.dataId),a=d.texData.get(c.dataId),[r,o]=[[t.complexTensorInfos.real,a.complexTensorInfos.real],[t.complexTensorInfos.imag,a.complexTensorInfos.imag]].map(t=>{const[a,r]=t,o={dataId:a.dataId,dtype:a.dtype,shape:l.shape},s={dataId:r.dataId,dtype:r.dtype,shape:c.shape},i=new ht(e,l.shape,c.shape);return d.runWebGLProgram(i,[o,s],n.upcastType(a.dtype,r.dtype))}),s=mt({inputs:{real:r,imag:o},backend:d});return d.disposeIntermediateTensorInfo(r),d.disposeIntermediateTensorInfo(o),s}const p=s||n.upcastType(l.dtype,c.dtype);if(d.shouldExecuteOnCPU([l,c])&&null!=o){const e=d.texData.get(l.dataId),n=d.texData.get(c.dataId),[t,a]=o(l.shape,c.shape,e.values,n.values,p),r=d.makeTensorInfo(a,p);return d.texData.get(r.dataId).values=t,r}let h;return h=n.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")&&null!=t?new ft(t,l.shape,c.shape,a):new ht(e,l.shape,c.shape),d.runWebGLProgram(h,[l,c],p)}}function Tt(e,n=!1){if("linear"===e)return"return x;";if("relu"===e)return n?"\n  vec4 result = x * vec4(greaterThanEqual(x, vec4(0.0)));\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n":"if (isnan(x)) return x;\n  return (x < 0.0) ? 0.0 : x;\n";if("elu"===e)return n?"\n  vec4 result;\n\n  result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0);\n  result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0);\n  result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0);\n  result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0);\n\n  return result;\n":"return (x >= 0.0) ? x : (exp(x) - 1.0);";if("relu6"===e)return n?"\n  vec4 result = min(x, vec4(6.)) * vec4(greaterThanEqual(x, vec4(0.0)));\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n":"if (isnan(x)) return x;\n  return (x < 0.0) ? 0.0 : min(6.0, x);\n";if("prelu"===e)return n?Rt:It;if("leakyrelu"===e)return n?Ct:vt;throw new Error(`Activation ${e} has not been implemented for the WebGL backend.`)}class Et{constructor(e,n,t,a=!1,r=!1,o=!1,s=null,i=!1,u=!1){this.variableNames=["matrixA","matrixB"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=t;const l=a?e[1]:e[2],c=Math.ceil(l/2),d=a?"i * 2, rc.y":"rc.y, i * 2",p=r?"rc.z, i * 2":"i * 2, rc.z",h=a?["a.xxyy","a.zzww"]:["a.xxzz","a.yyww"],f=r?["b.xzxz","b.ywyw"]:["b.xyxy","b.zwzw"];let x="",g="";s&&(x=i?`vec4 activation(vec4 a) {\n          vec4 b = getPreluActivationWeightsAtOutCoords();\n          ${s}\n        }`:u?`vec4 activation(vec4 a) {\n          vec4 b = getLeakyreluAlphaAtOutCoords();\n          ${s}\n        }`:`vec4 activation(vec4 x) {\n          ${s}\n        }`,g="result = activation(result);");const m=o?"result += getBiasAtOutCoords();":"";o&&this.variableNames.push("bias"),i&&this.variableNames.push("preluActivationWeights"),u&&this.variableNames.push("leakyreluAlpha");let b="rc.x",v="rc.x";e[0]<n[0]?b=`int(min(float(rc.x), ${e[0]-1}.))`:n[0]<e[0]&&(v=`int(min(float(rc.x), ${n[0]-1}.))`),this.userCode=`\n      ${x}\n\n      const float sharedDimension = ${c}.0;\n\n      vec4 dot2x2ARowBCol(ivec3 rc) {\n        vec4 result = vec4(0);\n        for (int i = 0; i < ${c}; i++) {\n          int batchA = ${b};\n          int batchB = ${v};\n          vec4 a = getMatrixA(batchA, ${d});\n          vec4 b = getMatrixB(batchB, ${p});\n\n          // These swizzled products need to be separately added.\n          // See: https://github.com/tensorflow/tfjs/issues/1735\n          result += (${h[0]} * ${f[0]});\n          result += (${h[1]} * ${f[1]});\n        }\n        return result;\n      }\n\n      void main() {\n        ivec3 rc = getOutputCoords();\n        vec4 result = dot2x2ARowBCol(rc);\n\n        ${m}\n\n        ${g}\n\n        setOutput(result);\n      }\n    `}}const Nt="return areal * breal - aimag * bimag;",St="return areal * bimag + aimag * breal;";class At{constructor(e,t,a){this.variableNames=["AReal","AImag","BReal","BImag"],this.outputShape=n.backend_util.assertAndGetBroadcastShape(t,a),this.userCode=`\n      float binaryOpComplex(\n          float areal, float aimag, float breal, float bimag) {\n        ${e}\n      }\n\n      void main() {\n        float areal = getARealAtOutCoords();\n        float aimag = getAImagAtOutCoords();\n        float breal = getBRealAtOutCoords();\n        float bimag = getBImagAtOutCoords();\n        setOutput(binaryOpComplex(areal, aimag, breal, bimag));\n      }\n    `}}const Ft="return a * b;";function _t(e){const{inputs:t,backend:a}=e,{a:r,b:o}=t,s=n.backend_util.upcastType(r.dtype,o.dtype);if("complex64"===r.dtype){const e=a.texData.get(r.dataId),n=a.texData.get(o.dataId),t=new At(Nt,r.shape,o.shape),s=new At(St,r.shape,o.shape),i=[{dataId:e.complexTensorInfos.real.dataId,dtype:e.complexTensorInfos.real.dtype,shape:r.shape},{dataId:e.complexTensorInfos.imag.dataId,dtype:e.complexTensorInfos.imag.dtype,shape:r.shape},{dataId:n.complexTensorInfos.real.dataId,dtype:n.complexTensorInfos.real.dtype,shape:o.shape},{dataId:n.complexTensorInfos.imag.dataId,dtype:n.complexTensorInfos.imag.dtype,shape:o.shape}],u=a.runWebGLProgram(t,i,"float32"),l=a.runWebGLProgram(s,i,"float32"),c=mt({inputs:{real:u,imag:l},backend:a});return a.disposeIntermediateTensorInfo(u),a.disposeIntermediateTensorInfo(l),c}if(a.shouldExecuteOnCPU([r,o])){const e=a.texData.get(r.dataId),n=a.texData.get(o.dataId),[t,i]=Dn(r.shape,o.shape,e.values,n.values,s),u=a.makeTensorInfo(i,s);return a.texData.get(u.dataId).values=t,u}let i;return i=n.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new ft(Ft,r.shape,o.shape):new ht(Ft,r.shape,o.shape),a.runWebGLProgram(i,[r,o],s)}const Ot={kernelName:n.Multiply,backendName:"webgl",kernelFunc:_t};function Dt(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{shape:s}=r,i=a,u=n.util.sizeFromShape(o.shape),l=n.util.inferFromImplicitShape(s,u),c=n.util.sizeFromShape(l);n.util.assert(u===c,()=>`The new shape (${l}) has ${c} elements and the old `+`shape (${o.shape}) has ${u} elements. The new shape and old `+"shape must have the same number of elements.");const d=i.texData.get(o.dataId);return!d.isPacked||z(o.shape,l)||null!==d.texture&&z(d.shape,l)?(i.incRef(o.dataId),{dataId:o.dataId,shape:l,dtype:o.dtype}):function(e,n,t){const a=[V(e.shape),...W(e.shape)],r={dtype:e.dtype,shape:a,dataId:e.dataId},o=[V(n),...W(n)],s=new Qn(o,a),i=t.runWebGLProgram(s,[r],e.dtype,null,!0);return{dataId:i.dataId,shape:n,dtype:i.dtype}}(o,l,i)}const Pt={kernelName:n.Reshape,backendName:"webgl",kernelFunc:Dt};class Lt{constructor(e,t){this.variableNames=["x"];const{windowSize:a,batchSize:r,inSize:o,outSize:s}=e;this.outputShape=[r,s];const i=4*Math.floor(a/4),u=a%4;let l="sumValue += dot(values, ones);";if(null!=t){const e=1/t;l=`sumValue += dot(values * ${n.util.isInt(e)?e.toPrecision(2):e}, ones);`}let c="";o%a>0&&(c=`\n        if (inIdx < 0 || inIdx >= ${o}) {\n          return 0.0;\n        }\n      `),this.userCode=`\n      const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n      float getValue(int batch, int inIdx) {\n        ${c}\n        return getX(batch, inIdx);\n      }\n\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n        int outIdx = coords[1];\n        int inOffset = outIdx * ${a};\n\n        float sumValue = 0.0;\n\n        for (int i = 0; i < ${i}; i += 4) {\n          int inIdx = inOffset + i;\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            getValue(batch, inIdx + 3)\n          );\n\n          ${l}\n        }\n\n        int inIdx = inOffset + ${i};\n        if (${1===u}) {\n          vec4 values = vec4(getValue(batch, inIdx), 0.0, 0.0, 0.0);\n\n          ${l}\n        } else if (${2===u}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1), 0.0, 0.0);\n\n          ${l}\n        } else if (${3===u}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2), 0.0);\n\n          ${l}\n        }\n        setOutput(sumValue);\n      }\n    `}}class Bt{constructor(e,n){this.variableNames=["x"];const{windowSize:t,batchSize:a,inSize:r,outSize:o}=e;this.outputShape=[a,o];let s="0.0",i="";"prod"===n?s="1.0":"min"===n?(s="1.0 / 1e-20",i="min"):"max"===n&&(s="-1.0 / 1e-20",i="max");let u=`${n}(${n}(${n}(`+"minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])";"sum"===n?u="sumValue":"prod"===n?u="prodValue":"all"===n?u="allValue":"any"===n&&(u="anyValue");const l=4*Math.floor(t/4),c=t%4;let d=`\n      if (${"sum"===n}) {\n        sumValue += dot(values, ones);\n      } else if (${"prod"===n}) {\n        vec2 tmp = vec2(values[0], values[1]) * vec2(values[2], values[3]);\n        prodValue *= tmp[0] * tmp[1];\n      } else {\n        minMaxValue = ${i}(values, minMaxValue);\n      }\n    `,p="vec4";"all"===n?(s="1.0",d="\n        bool reducedAllValue = all(values);\n        float floatedReducedAllValue = float(reducedAllValue);\n        allValue = float(allValue >= 1.0 && floatedReducedAllValue >= 1.0);\n      ",p="bvec4"):"any"===n&&(s="0.0",d="\n        bool reducedAnyValue = any(values);\n        float floatedReducedAnyValue = float(reducedAnyValue);\n        anyValue = float(anyValue >= 1.0 || floatedReducedAnyValue >= 1.0);\n      ",p="bvec4");let h="";r%t>0&&(h=`\n        if (inIdx < 0 || inIdx >= ${r}) {\n          return initializationValue;\n        }\n      `),this.userCode=`\n      const float initializationValue = ${s};\n      const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n      float getValue(int batch, int inIdx) {\n        ${h}\n        return getX(batch, inIdx);\n      }\n\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n        int outIdx = coords[1];\n        int inOffset = outIdx * ${t};\n\n        vec4 minMaxValue = vec4(${s});\n        float prodValue = 1.0;\n        float sumValue = 0.0;\n        float allValue = 1.0;\n        float anyValue = 0.0;\n\n        for (int i = 0; i < ${l}; i += 4) {\n          int inIdx = inOffset + i;\n          ${p} values = ${p}(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            getValue(batch, inIdx + 3)\n          );\n\n          ${d}\n        }\n\n        int inIdx = inOffset + ${l};\n        if (${1===c}) {\n          ${p} values = ${p}(\n            getValue(batch, inIdx),\n            initializationValue,\n            initializationValue,\n            initializationValue\n          );\n\n          ${d}\n        } else if (${2===c}) {\n          ${p} values = ${p}(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            initializationValue,\n            initializationValue\n          );\n\n          ${d}\n        } else if (${3===c}) {\n          ${p} values = ${p}(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            initializationValue\n          );\n\n          ${d}\n        }\n        setOutput(${u});\n      }\n    `}}function Vt(e,t,a,r){const o=function(e){const t=[];for(;0===t.length||1!==t[t.length-1].outSize;){const a=t.length?t[t.length-1].outSize:e[1],r=n.backend_util.computeOptimalWindowSize(a);t.push({inSize:a,windowSize:r,outSize:Math.ceil(a/r)})}return t}(e.shape);let s=e;for(let n=0;n<o.length;n++){const{inSize:i,windowSize:u,outSize:l}=o[n];let c,d;c="mean"===a?0===n?new Lt({windowSize:u,inSize:i,batchSize:e.shape[0],outSize:l},i):new Lt({windowSize:u,inSize:i,batchSize:e.shape[0],outSize:l}):new Bt({windowSize:u,inSize:i,batchSize:e.shape[0],outSize:l},a),d=s,s=r.runWebGLProgram(c,[s],t),d.dataId!==e.dataId&&r.disposeIntermediateTensorInfo(d)}return s}class Wt{constructor(e,n){this.variableNames=["A"];const t=new Array(e.length);for(let a=0;a<t.length;a++)t[a]=e[n[a]];this.outputShape=t,this.rank=t.length;const a=Ye(this.rank),r=function(e){const n=e.length;if(n>6)throw Error(`Transpose for rank ${n} is not yet supported`);const t=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u","resRC.v"],a=new Array(n);for(let n=0;n<e.length;n++)a[e[n]]=t[n];return a.join()}(n);this.userCode=`\n    void main() {\n      ${a} resRC = getOutputCoords();\n      setOutput(getA(${r}));\n    }\n    `}}class Mt{constructor(e,n){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0;const t=new Array(e.length);for(let a=0;a<t.length;a++)t[a]=e[n[a]];if(this.outputShape=t,this.rank=t.length,this.rank>6)throw Error(`Packed transpose for rank ${this.rank} is not yet supported.`);const a=Ye(this.rank),r=Kn("rc",this.rank),o=new Array(this.rank);for(let e=0;e<n.length;e++)o[n[e]]=r[e];const s=`vec2(${o.slice(-2).join()})`,i=`++${r[this.rank-1]} < ${t[this.rank-1]}`,u=`getChannel(getA(${o.join()}), ${s})`;this.userCode=`\n    void main() {\n      ${a} rc = getOutputCoords();\n      vec4 result = vec4(0.);\n      result[0] = ${u};\n      if(${i}) {\n        result[1] = ${u};\n      }\n      --${r[this.rank-1]};\n      if(++${r[this.rank-2]} < ${t[this.rank-2]}) {\n        result[2] = ${u};\n        if(${i}) {\n          result[3] = ${u};\n        }\n      }\n      setOutput(result);\n    }\n    `}}function Gt(e,t,a){const r=n.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new Mt(e.shape,t):new Wt(e.shape,t);return a.runWebGLProgram(r,[e],e.dtype)}function Ut(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{axis:s,keepDims:i}=r;return function(e,t,a,r){const o=t,s=e.shape.length,i=n.util.parseAxisParam(o,e.shape);let u=i;const l=n.backend_util.getAxesPermutation(u,s),c=null!=l;let d=e;c&&(d=Gt(e,l,r),u=n.backend_util.getInnerMostAxes(u.length,s)),n.backend_util.assertAxesAreInnerMostDims("sum",u,s);const[p,h]=n.backend_util.computeOutAndReduceShapes(d.shape,u);let f=p;a&&(f=n.backend_util.expandShapeToKeepDim(p,i));const x=n.util.sizeFromShape(h),g=Dt({inputs:{x:d},attrs:{shape:[n.util.sizeFromShape(e.shape)/x,x]},backend:r}),m=Vt(g,n.sumOutType(e.dtype),"sum",r),b=Dt({inputs:{x:m},attrs:{shape:f},backend:r});return r.disposeIntermediateTensorInfo(g),r.disposeIntermediateTensorInfo(m),c&&r.disposeIntermediateTensorInfo(d),b}(o,s,i,a)}const zt={kernelName:n.Sum,backendName:"webgl",kernelFunc:Ut};function Xt(e){const{inputs:n,backend:t,attrs:a}=e,{x:r}=n,{perm:o}=a,s=t,i=r.shape.length,u=new Array(i);for(let e=0;e<u.length;e++)u[e]=r.shape[o[e]];let l;if(s.shouldExecuteOnCPU([r])){const e=s.texData.get(r.dataId).values,n=Hn(e,r.shape,r.dtype,o,u);l=s.makeTensorInfo(u,r.dtype),s.texData.get(l.dataId).values=n}else l=Gt(r,o,s);return l}const Ht={kernelName:n.Transpose,backendName:"webgl",kernelFunc:Xt};function jt({a:e,b:t,transposeA:a,transposeB:r,backend:o,bias:s=null,preluActivationWeights:i=null,leakyreluAlpha:u=0,activation:l=null}){const c=e.shape.length,d=t.shape.length,p=a?e.shape[c-2]:e.shape[c-1],h=r?t.shape[d-1]:t.shape[d-2],f=a?e.shape[c-1]:e.shape[c-2],x=r?t.shape[d-2]:t.shape[d-1],g=e.shape.slice(0,-2),m=t.shape.slice(0,-2),b=n.util.sizeFromShape(g),v=n.util.sizeFromShape(m),C=b===v||1===b||1===v;n.util.assert(c>=2&&d>=2&&C,()=>"Error in matMul: the input batch dimensions must either be the same or at least one input batch dimension must be 1. Got input "+`batch dimensions of (${g}) and (${m}).`);const $=(b>v?e.shape.slice(0,-2):t.shape.slice(0,-2)).concat([f,x]);n.util.assert(p===h,()=>`Error in matMul: inner shapes (${p}) and (`+`${h}) of Tensors with shapes ${e.shape} and `+`${t.shape} and transposeA=${a}`+` and transposeB=${r} must match.`);const I=a?[b,p,f]:[b,f,p],R=r?[v,x,h]:[v,h,x],k=Dt({inputs:{x:e},backend:o,attrs:{shape:I}}),y=Dt({inputs:{x:t},backend:o,attrs:{shape:R}}),w=[k,y],T=Math.max(b,v),E=a?k.shape[1]:k.shape[2],N=null!=s,S=null!=i,A="leakyrelu"===l,F=null!=l?Tt(l,!0):null;let _;if((1===f||1===x)&&E>1e3&&!1===(N||S||A||null!=F)){let e=k,n=y;a&&(e=Xt({inputs:{x:k},backend:o,attrs:{perm:[0,2,1]}}),w.push(e)),r&&(n=Xt({inputs:{x:y},backend:o,attrs:{perm:[0,2,1]}}),w.push(n));const t=1===x;let s=e;1!==x&&(s=Dt({inputs:{x:e},backend:o,attrs:{shape:[T,E,1]}}),w.push(s));const i=1===x?2:1;let u=n;t&&(u=Dt({inputs:{x:n},backend:o,attrs:{shape:[T,1,E]}}),w.push(u));const l=_t({inputs:{a:s,b:u},backend:o});_=Ut({inputs:{x:l},backend:o,attrs:{axis:i,keepDims:!0}}),w.push(l)}else{const l=n.upcastType(e.dtype,t.dtype),c=new Et(I,R,[T,f,x],a,r,N,F,S,A),d=[k,y];if(null!=s&&d.push(s),S&&d.push(i),A){const e=o.makeTensorInfo([],"float32",n.util.createScalarValue(u,"float32"));d.push(e),w.push(e)}_=o.runWebGLProgram(c,d,l)}const O=Dt({inputs:{x:_},backend:o,attrs:{shape:$}});w.push(_);for(const e of w)o.disposeIntermediateTensorInfo(e);return O}const Kt={kernelName:n._FusedMatMul,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{a:r,b:o,bias:s,preluActivationWeights:i}=n,{transposeA:u,transposeB:l,activation:c,leakyreluAlpha:d}=a;return jt({a:r,b:o,transposeA:u,transposeB:l,backend:t,bias:s,preluActivationWeights:i,leakyreluAlpha:d,activation:c})}};const qt={kernelName:n.Abs,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a}=e,{x:r}=t;if(a.shouldExecuteOnCPU([r])&&"complex64"!==r.dtype){const e=a.texData.get(r.dataId),n=Wn(e.values);return a.makeTensorInfo(r.shape,r.dtype,n)}let o;return o=n.env().getBool("WEBGL_PACK_UNARY_OPERATIONS")?new st(r.shape,"return abs(x);"):new tt(r.shape,"return abs(x);"),a.runWebGLProgram(o,[r],r.dtype)}},Yt=yt({opSnippet:"if (isnan(x)) return x;\n  if (abs(x) > 1.) {\n    return NAN;\n  }\n  return acos(x);\n"}),Qt={kernelName:n.Acos,backendName:"webgl",kernelFunc:Yt},Zt=yt({opSnippet:"if (isnan(x)) return x;\n  if (x < 1.0) return NAN;\nreturn log(x + sqrt(x * x - 1.0));"}),Jt={kernelName:n.Acosh,backendName:"webgl",kernelFunc:Zt},ea="return a + b;",na=wt({opSnippet:ea,packedOpSnippet:ea,supportsComplex:!0,cpuKernelImpl:vn}),ta={kernelName:n.Add,backendName:"webgl",kernelFunc:na};class aa{constructor(e,n){this.outputShape=[],this.outputShape=e,this.variableNames=n.map((e,n)=>`T${n}`);const t=[];this.variableNames.forEach(e=>{t.push(`float v${e} = get${e}AtOutCoords();`)});const a=this.variableNames.map(e=>`v${e}`).join(" + ");this.userCode=`\n      void main() {\n        ${t.join("\n        ")}\n\n        float result = ${a};\n        setOutput(result);\n      }\n    `}}class ra{constructor(e,n){this.outputShape=[],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e,this.variableNames=n.map((e,n)=>`T${n}`);const t=[];this.variableNames.forEach(e=>{t.push(`vec4 v${e} = get${e}AtOutCoords();`)});const a=this.variableNames.map(e=>`v${e}`).join(" + ");this.userCode=`\n      void main() {\n        ${t.join("\n        ")}\n\n        vec4 result = ${a};\n        setOutput(result);\n      }\n    `}}const oa={kernelName:n.AddN,backendName:"webgl",kernelFunc:function e(t){const{inputs:a,backend:r}=t,o=a;if(1===o.length)return xt({inputs:{x:o[0]},backend:r});if(o.length>n.env().get("WEBGL_MAX_TEXTURES_IN_SHADER")){const n=Math.floor(o.length/2),t=e({inputs:o.slice(0,n),backend:r}),a=e({inputs:o.slice(n),backend:r});return e({inputs:[t,a],backend:r})}const s=o.map(e=>e.dtype).reduce((e,t)=>n.upcastType(e,t)),i=o.map(e=>e.shape),u=n.env().getBool("WEBGL_PACK")?new ra(o[0].shape,i):new aa(o[0].shape,i);return r.runWebGLProgram(u,o,s)}};const sa={kernelName:n.All,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{axis:s,keepDims:i}=r,u=o.shape.length,l=n.util.parseAxisParam(s,o.shape);let c=l;const d=n.backend_util.getAxesPermutation(c,u);let p=o;null!=d&&(p=Xt({inputs:{x:o},backend:a,attrs:{perm:d}}),c=n.backend_util.getInnerMostAxes(c.length,u)),n.backend_util.assertAxesAreInnerMostDims("all",c,u);const[h,f]=n.backend_util.computeOutAndReduceShapes(p.shape,c),x=Dt({inputs:{x:p},backend:a,attrs:{shape:[-1,n.util.sizeFromShape(f)]}}),g=Vt(x,x.dtype,"all",a);let m;if(i){m=Dt({inputs:{x:g},backend:a,attrs:{shape:n.backend_util.expandShapeToKeepDim(h,l)}})}else m=Dt({inputs:{x:g},backend:a,attrs:{shape:h}});return a.disposeIntermediateTensorInfo(x),a.disposeIntermediateTensorInfo(g),null!=d&&a.disposeIntermediateTensorInfo(p),m}};const ia={kernelName:n.Any,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{axis:s,keepDims:i}=r,u=o.shape.length,l=n.util.parseAxisParam(s,o.shape);let c=l;const d=n.backend_util.getAxesPermutation(c,u);let p=o;null!=d&&(p=Xt({inputs:{x:o},backend:a,attrs:{perm:d}}),c=n.backend_util.getInnerMostAxes(c.length,u)),n.backend_util.assertAxesAreInnerMostDims("any",c,u);const[h,f]=n.backend_util.computeOutAndReduceShapes(p.shape,c),x=Dt({inputs:{x:p},backend:a,attrs:{shape:[-1,n.util.sizeFromShape(f)]}}),g=Vt(x,x.dtype,"any",a);let m;if(i){m=Dt({inputs:{x:g},backend:a,attrs:{shape:n.backend_util.expandShapeToKeepDim(h,l)}})}else m=Dt({inputs:{x:g},backend:a,attrs:{shape:h}});return a.disposeIntermediateTensorInfo(x),a.disposeIntermediateTensorInfo(g),null!=d&&a.disposeIntermediateTensorInfo(p),m}};class ua{constructor(e,n,t){this.variableNames=["A"];const{windowSize:a,batchSize:r,outSize:o}=e;t||this.variableNames.push("bestIndicesA"),this.outputShape=[r,o];const s="max"===n?">":"<",i=t?"inOffset + i;":"round(getBestIndicesA(batch, inOffset + i));";this.userCode=`\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n        int outIdx = coords[1];\n        int inOffset = outIdx * ${a};\n\n        int bestIndex = inOffset;\n        float bestValue = getA(batch, bestIndex);\n\n        for (int i = 0; i < ${a}; i++) {\n          int inIdx = ${i};\n          float candidate = getA(batch, inIdx);\n          if (candidate ${s} bestValue) {\n            bestValue = candidate;\n            bestIndex = inIdx;\n          }\n        }\n        setOutput(float(bestIndex));\n      }\n    `}}class la{constructor(e,t,a,r){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,n.util.assert(e.length>2,()=>`Packed arg${a.charAt(0).toUpperCase()+a.slice(1)} supports only inputs with rank above 2.`);const o=e[e.length-1],s=Math.ceil(o/t);this.outputShape=e.slice(0,-1),s>1&&this.outputShape.push(s),r||this.variableNames.push("bestIndicesA");const i=this.outputShape,u=i.length,l=Ye(u),c=qn("coords",u);let d,p;if(1===s){p=u+1;const e=Ye(p);d=`\n        ${e} sourceLocR = ${e}(${c.join()}, 0);\n        ++${c[u-1]};\n        ${e} sourceLocG = ${e}(${c.join()}, 0);\n        ++${c[u-2]};\n        ${e} sourceLocA = ${e}(${c.join()}, 0);\n        --${c[u-1]};\n        ${e} sourceLocB = ${e}(${c.join()}, 0);\n        --${c[u-2]};`}else p=u,d=`\n        ${l} sourceLocR = coords;\n        ++${c[u-1]};\n        ${l} sourceLocG = coords;\n        ++${c[u-2]};\n        ${l} sourceLocA = coords;\n        --${c[u-1]};\n        ${l} sourceLocB = coords;\n        --${c[u-2]};`;const h=["x","y","z","w","u","v"].slice(0,p),f="."+h[p-1],x=h.map(e=>"int "+e),g=qn("sourceLocR",p-1).concat("inIdx.r"),m=qn("sourceLocG",p-1).concat("inIdx.g"),b=qn("sourceLocB",p-1).concat("inIdx.b"),v=qn("sourceLocA",p-1).concat("inIdx.a"),C="max"===a?"greaterThan":"lessThan",$=r?"":`\n          inIdx = round(vec4(getBestIndicesAChannel(${g.join()}),\n                             getBestIndicesAChannel(${m.join()}),\n                             getBestIndicesAChannel(${b.join()}),\n                             getBestIndicesAChannel(${v.join()})));`,I=`vec4(\n            getAChannel(${g.join()}),\n            hasNextCol ? getAChannel(${m.join()}) : 0.,\n            hasNextRow ? getAChannel(${b.join()}) : 0.,\n            hasNextRow && hasNextCol ? getAChannel(${v.join()}) : 0.)`,R=r?"":`\n      float getBestIndicesAChannel(${x.join()}) {\n        return getChannel(getBestIndicesA(${h.join()}),\n                                          vec2(${h.slice(-2).join()}));\n      }`;this.userCode=`\n      float getAChannel(${x.join()}) {\n        return getChannel(getA(${h.join()}),\n                               vec2(${h.slice(-2).join()}));\n      }\n      ${R}\n      void main() {\n        ${l} coords = getOutputCoords();\n        bool hasNextCol = ${c[u-1]} < ${i[u-1]-1};\n        bool hasNextRow = ${c[u-2]} < ${i[u-2]-1};\n        ${d}\n        ivec4 srcIdx = ivec4(sourceLocR${f}, sourceLocG${f},\n          sourceLocB${f}, sourceLocA${f}) * ${t};\n        ivec4 inIdx = srcIdx;\n        vec4 bestIndex = vec4(inIdx);\n        vec4 bestValue = ${I};\n\n        for (int i = 0; i < ${t}; i++) {\n          inIdx = srcIdx;\n          ${$}\n          vec4 candidate = ${I};\n          bvec4 nan = isnan(candidate);\n          bvec4 replace = bvec4(\n            vec4(${C}(candidate, bestValue)) * (vec4(1.0) - vec4(nan)));\n\n          bestValue = vec4(replace.x  ? candidate.x : bestValue.x,\n                           replace.y  ? candidate.y : bestValue.y,\n                           replace.z  ? candidate.z : bestValue.z,\n                           replace.w  ? candidate.w : bestValue.w);\n          bestIndex = mix(bestIndex, vec4(inIdx), vec4(replace));\n          srcIdx++;\n        }\n        setOutput(bestIndex);\n      }\n    `}}function ca(e,t,a,r){const o=[a];if(n.backend_util.assertAxesAreInnerMostDims("arg"+r.charAt(0).toUpperCase()+r.slice(1),o,t.shape.length),!n.env().getBool("WEBGL_PACK_REDUCE")||t.shape.length<=2){const a=[],[s,i]=n.backend_util.computeOutAndReduceShapes(t.shape,o),u=n.util.sizeFromShape(i),l=Dt({inputs:{x:t},backend:e,attrs:{shape:[-1,u]}});a.push(l);const c=function e(t,a,r,o=null){let s=a.shape[0],i=a.shape[1];null!=o&&(s=o.shape[0],i=o.shape[1]);const u=n.backend_util.computeOptimalWindowSize(i),l={windowSize:u,inSize:i,batchSize:s,outSize:Math.ceil(i/u)},c=new ua(l,r,null==o),d=[a];null!=o&&d.push(o);const p=t.runWebGLProgram(c,d,"int32");if(1===p.shape[1])return p;const h=e(t,a,r,p);return t.disposeIntermediateTensorInfo(p),h}(e,l,r);a.push(c);const d=Dt({inputs:{x:c},backend:e,attrs:{shape:s}});return a.forEach(n=>e.disposeIntermediateTensorInfo(n)),d}return function e(t,a,r,o=null){const s=null!=o?o.shape:a.shape,i=s[s.length-1],u=n.backend_util.computeOptimalWindowSize(i),l=new la(s,u,r,null==o),c=null==o?[a]:[a,o],d=t.runWebGLProgram(l,c,"int32");if(d.shape.length===a.shape.length){const n=e(t,a,r,d);return t.disposeIntermediateTensorInfo(d),n}return d}(e,t,r)}const da={kernelName:n.ArgMax,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{axis:s}=r;let i=n.util.parseAxisParam(s,o.shape);const u=n.backend_util.getAxesPermutation(i,o.shape.length);let l=o;const c=[];null!=u&&(l=Xt({inputs:{x:o},backend:a,attrs:{perm:u}}),c.push(l),i=n.backend_util.getInnerMostAxes(i.length,l.shape.length)),n.backend_util.assertAxesAreInnerMostDims("argMax",[i[0]],l.shape.length);const d=ca(a,l,i[0],"max");return c.forEach(e=>a.disposeIntermediateTensorInfo(e)),d}};const pa={kernelName:n.ArgMin,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{axis:s}=r;let i=n.util.parseAxisParam(s,o.shape);const u=n.backend_util.getAxesPermutation(i,o.shape.length);let l=o;const c=[];null!=u&&(l=Xt({inputs:{x:o},backend:a,attrs:{perm:u}}),c.push(l),i=n.backend_util.getInnerMostAxes(i.length,l.shape.length)),n.backend_util.assertAxesAreInnerMostDims("argMin",[i[0]],l.shape.length);const d=ca(a,l,i[0],"min");return c.forEach(e=>a.disposeIntermediateTensorInfo(e)),d}},ha=yt({opSnippet:"if (isnan(x)) return x;\n  if (abs(x) > 1.) {\n    return NAN;\n  }\n  return asin(x);\n"}),fa={kernelName:n.Asin,backendName:"webgl",kernelFunc:ha},xa=yt({opSnippet:"if (isnan(x)) return x;return log(x + sqrt(x * x + 1.0));"}),ga={kernelName:n.Asinh,backendName:"webgl",kernelFunc:xa},ma=yt({opSnippet:"if (isnan(x)) return x;\n  return atan(x);\n"}),ba={kernelName:n.Atan,backendName:"webgl",kernelFunc:ma},va=wt({opSnippet:"\n  if (isnan(a)) return a;\n  if (isnan(b)) return b;\n\n  return atan(a, b);\n",packedOpSnippet:"\n  vec4 result = atan(a, b);\n  vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));\n  \n  result.r = isNaN.r > 0. ? NAN : result.r;\n  result.g = isNaN.g > 0. ? NAN : result.g;\n  result.b = isNaN.b > 0. ? NAN : result.b;\n  result.a = isNaN.a > 0. ? NAN : result.a;\n\n  return result;\n"}),Ca={kernelName:n.Atan2,backendName:"webgl",kernelFunc:va},$a=yt({opSnippet:"if (isnan(x)) return x;\n  if ((x < -1.0) || (x > 1.0)) return NAN;\nreturn (log(1.0 + x) - log(1.0 - x)) / 2.0;"}),Ia={kernelName:n.Atanh,backendName:"webgl",kernelFunc:$a};class Ra{constructor(e,n,t,a=!1,r=!1){if(this.variableNames=["x"],"avg"===n&&t)throw new Error("Cannot compute positions for average pool.");const o=e.filterWidth,s=e.strideHeight,i=e.strideWidth,u=e.dilationHeight,l=e.dilationWidth,c=e.effectiveFilterHeight,d=e.effectiveFilterWidth,p=e.padInfo.top,h=e.padInfo.left;this.outputShape=e.outShape;const f="avg"===n,x=`((batch  * ${e.inHeight} + xR) * ${e.inWidth} + xC) * ${e.inChannels} + d`,g=`(xR * ${e.inWidth} + xC) * ${e.inChannels} + d`;let m="0.0";if(f||(m="-1.0 / 1e-20"),t){const n=">=";return void(this.userCode=`\n        const ivec2 strides = ivec2(${s}, ${i});\n        const ivec2 pads = ivec2(${p}, ${h});\n\n        void main() {\n          ivec4 coords = getOutputCoords();\n          int batch = coords[0];\n          int d = coords[3];\n\n          ivec2 xRCCorner = coords.yz * strides - pads;\n          int xRCorner = xRCCorner.x;\n          int xCCorner = xRCCorner.y;\n\n          // max/min x(?, ?, d) to get y(yR, yC, d).\n          // ? = to be determined\n          float minMaxValue = 0.0;\n          float minMaxValueFound = 0.0;\n          int minMaxPosition = 0;\n          float avgValue = 0.0;\n\n          for (int wR = 0; wR < ${c};\n              wR += ${u}) {\n            int xR = xRCorner + wR;\n\n            if (xR < 0 || xR >= ${e.inHeight}) {\n              continue;\n            }\n\n            for (int wC = 0; wC < ${d};\n                wC += ${l}) {\n              int xC = xCCorner + wC;\n\n              if (xC < 0 || xC >= ${e.inWidth}) {\n                continue;\n              }\n\n              float value = getX(batch, xR, xC, d);\n\n              // If a min / max value has already been found, use it. If not,\n              // use the current value.\n              float currMinMaxValue = mix(\n                  value, minMaxValue, minMaxValueFound);\n              if (value ${n} currMinMaxValue) {\n                minMaxValue = value;\n                minMaxValueFound = 1.0;\n                minMaxPosition = ${a?r?x:g:`wR * ${d} + wC`};\n              }\n            }\n          }\n          setOutput(float(minMaxPosition));\n        }\n      `)}let b=`${n}(${n}(${n}(`+"minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])";"avg"===n&&(b="avgValue / count");const v=4*Math.floor(o/4),C=o%4,$=`\n      if (${f}) {\n        avgValue += dot(values, ones);\n      } else {\n        minMaxValue = max(values, minMaxValue);\n      }\n    `;this.userCode=`\n      const ivec2 strides = ivec2(${s}, ${i});\n      const ivec2 pads = ivec2(${p}, ${h});\n      const float initializationValue = ${m};\n      const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n      float count = 0.0;\n\n      float getValue(int batch, int xR, int xC, int d) {\n        if (xC < 0 || xC >= ${e.inWidth}) {\n          return initializationValue;\n        }\n        count += 1.0;\n        return getX(batch, xR, xC, d);\n      }\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords[0];\n        int d = coords[3];\n\n        ivec2 xRCCorner = coords.yz * strides - pads;\n        int xRCorner = xRCCorner.x;\n        int xCCorner = xRCCorner.y;\n\n        // max/min x(?, ?, d) to get y(yR, yC, d).\n        // ? = to be determined\n        vec4 minMaxValue = vec4(${m});\n        float avgValue = 0.0;\n        count = 0.0;\n\n        for (int wR = 0; wR < ${c};\n            wR += ${u}) {\n          int xR = xRCorner + wR;\n\n          if (xR < 0 || xR >= ${e.inHeight}) {\n            continue;\n          }\n\n          for (int wC = 0; wC < ${v}; wC += 4) {\n            int xC = xCCorner + wC * ${l};\n\n            vec4 values = vec4(\n              getValue(batch, xR, xC, d),\n              getValue(batch, xR, xC + ${l}, d),\n              getValue(batch, xR, xC + 2 * ${l}, d),\n              getValue(batch, xR, xC + 3 * ${l}, d)\n            );\n\n            ${$}\n          }\n\n          int xC = xCCorner + ${v};\n          if (${1===C}) {\n            vec4 values = vec4(\n              getValue(batch, xR, xC, d),\n              initializationValue,\n              initializationValue,\n              initializationValue\n            );\n\n            ${$}\n          } else if (${2===C}) {\n            vec4 values = vec4(\n              getValue(batch, xR, xC, d),\n              getValue(batch, xR, xC + ${l}, d),\n              initializationValue,\n              initializationValue\n            );\n\n            ${$}\n          } else if (${3===C}) {\n            vec4 values = vec4(\n              getValue(batch, xR, xC, d),\n              getValue(batch, xR, xC + ${l}, d),\n              getValue(batch, xR, xC + 2 * ${l}, d),\n              initializationValue\n            );\n\n            ${$}\n          }\n        }\n        setOutput(${b});\n      }\n    `}}class ka{constructor(e,n,t,a=!1,r=!1){if(this.variableNames=["x"],"avg"===n&&t)throw new Error("Cannot compute positions for average pool.");const o=e.filterWidth,s=e.strideDepth,i=e.strideHeight,u=e.strideWidth,l=e.dilationDepth,c=e.dilationHeight,d=e.dilationWidth,p=e.effectiveFilterDepth,h=e.effectiveFilterHeight,f=e.effectiveFilterWidth,x=e.padInfo.front,g=e.padInfo.top,m=e.padInfo.left;this.outputShape=e.outShape;const b="avg"===n;let v="0.0";if(b||(v="-1.0 / 1e-20"),t){const n=">=";return void(this.userCode=`\n        const ivec3 strides =\n            ivec3(${s}, ${i}, ${u});\n        const ivec3 pads = ivec3(${x}, ${g}, ${m});\n\n        void main() {\n          ivec5 coords = getOutputCoords();\n          int batch = coords.x;\n          int ch = coords.u;\n\n          ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n          int xDCorner = xCorner.x;\n          int xRCorner = xCorner.y;\n          int xCCorner = xCorner.z;\n\n          // max/min x(?, ?, ?, ch) to get y(yD, yR, yC, ch).\n          // ? = to be determined\n          float minMaxValue = 0.0;\n          float minMaxValueFound = 0.0;\n          int minMaxPosition = 0;\n\n          for (int wD = 0; wD < ${p};\n              wD += ${l}) {\n            int xD = xDCorner + wD;\n\n            if (xD < 0 || xD >= ${e.inDepth}) {\n              continue;\n            }\n\n            for (int wR = 0; wR < ${h};\n                wR += ${c}) {\n              int xR = xRCorner + wR;\n\n              if (xR < 0 || xR >= ${e.inHeight}) {\n                continue;\n              }\n\n              for (int wC = 0; wC < ${f};\n                  wC += ${d}) {\n                int xC = xCCorner + wC;\n\n                if (xC < 0 || xC >= ${e.inWidth}) {\n                  continue;\n                }\n\n                float value = getX(batch, xD, xR, xC, ch);\n\n                // If a min / max value has already been found, use it. If not,\n                // use the current value.\n                float currMinMaxValue = mix(\n                    value, minMaxValue, minMaxValueFound);\n                if (value ${n} currMinMaxValue) {\n                  minMaxValue = value;\n                  minMaxValueFound = 1.0;\n                  minMaxPosition = ${a?r?`(((batch * ${e.inDepth} + xD) * ${e.inHeight} + xR) * ${e.inWidth} + xC) * ${e.inChannels} + ch`:`((xD * ${e.inHeight} + xR) * ${e.inWidth} + xC) * ${e.inChannels} + ch`:`wD * ${h} * ${f} +\n                      wR * ${f} + wC`};\n                }\n              }\n            }\n          }\n          setOutput(float(minMaxPosition));\n        }\n      `)}let C=`${n}(${n}(${n}(`+"minMaxValue[0], minMaxValue[1]), minMaxValue[2]), minMaxValue[3])";"avg"===n&&(C="avgValue / count");const $=4*Math.floor(o/4),I=o%4,R=`\n      if (${b}) {\n        avgValue += dot(values, ones);\n      } else {\n        minMaxValue = max(values, minMaxValue);\n      }\n    `;this.userCode=`\n      const ivec3 strides =\n        ivec3(${s}, ${i}, ${u});\n      const ivec3 pads = ivec3(${x}, ${g}, ${m});\n      const float initializationValue = ${v};\n      const vec4 ones = vec4(1.0, 1.0, 1.0, 1.0);\n\n      float count = 0.0;\n\n      float getValue(int batch, int xD, int xR, int xC, int ch) {\n        if (xC < 0 || xC >= ${e.inWidth}) {\n          return initializationValue;\n        }\n        count += 1.0;\n        return getX(batch, xD, xR, xC, ch);\n      }\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int ch = coords.u;\n\n        ivec3 xCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n        int xDCorner = xCorner.x;\n        int xRCorner = xCorner.y;\n        int xCCorner = xCorner.z;\n\n        // max/min x(?, ?, ?, d) to get y(yD, yR, yC, ch).\n        // ? = to be determined\n        vec4 minMaxValue = vec4(${v});\n        float avgValue = 0.0;\n        count = 0.0;\n\n        for (int wD = 0; wD < ${p};\n            wD += ${l}) {\n          int xD = xDCorner + wD;\n\n          if (xD < 0 || xD >= ${e.inDepth}) {\n            continue;\n          }\n\n          for (int wR = 0; wR < ${h};\n            wR += ${c}) {\n            int xR = xRCorner + wR;\n\n            if (xR < 0 || xR >= ${e.inHeight}) {\n              continue;\n            }\n\n            for (int wC = 0; wC < ${$}; wC += 4) {\n              int xC = xCCorner + wC * ${d};\n\n              vec4 values = vec4(\n                getValue(batch, xD, xR, xC, ch),\n                getValue(batch, xD, xR, xC + ${d}, ch),\n                getValue(batch, xD, xR, xC + 2 * ${d}, ch),\n                getValue(batch, xD, xR, xC + 3 * ${d}, ch)\n              );\n\n              ${R}\n            }\n\n            int xC = xCCorner + ${$};\n            if (${1===I}) {\n              vec4 values = vec4(\n                getValue(batch, xD, xR, xC, ch),\n                initializationValue,\n                initializationValue,\n                initializationValue\n              );\n\n              ${R}\n            } else if (${2===I}) {\n              vec4 values = vec4(\n                getValue(batch, xD, xR, xC, ch),\n                getValue(batch, xD, xR, xC + ${d}, ch),\n                initializationValue,\n                initializationValue\n              );\n\n              ${R}\n            } else if (${3===I}) {\n              vec4 values = vec4(\n                getValue(batch, xD, xR, xC, ch),\n                getValue(batch, xD, xR, xC + ${d}, ch),\n                getValue(batch, xD, xR, xC + 2 * ${d}, ch),\n                initializationValue\n              );\n\n              ${R}\n            }\n          }\n          setOutput(${C});\n        }\n      }\n    `}}const ya={kernelName:n.AvgPool,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t;te(o,"avgPool");const{filterSize:s,strides:i,pad:u,dimRoundingMode:l}=r;n.util.assert(n.backend_util.eitherStridesOrDilationsAreOne(i,1),()=>"Error in avgPool: Either strides or dilations must be 1. "+`Got strides ${i} and dilations '1'`);const c=n.backend_util.computePool2DInfo(o.shape,s,i,1,u,l);if(1===c.filterWidth&&1===c.filterHeight&&n.util.arraysEqual(c.inShape,c.outShape))return xt({inputs:{x:o},backend:a});const d=new Ra(c,"avg",!1);return a.runWebGLProgram(d,[o],"float32")}};const wa={kernelName:n.AvgPool3D,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{filterSize:s,strides:i,pad:u,dimRoundingMode:l,dataFormat:c}=r,d=n.backend_util.computePool3DInfo(o.shape,s,i,[1,1,1],u,l,c),p=new ka(d,"avg",!1);return a.runWebGLProgram(p,[o],"float32")}};class Ta{constructor(e){this.variableNames=["dy"],this.outputShape=e.inShape;const n=e.filterHeight,t=e.filterWidth,a=e.strideHeight,r=e.strideWidth,o=e.dilationHeight,s=e.dilationWidth,i=e.effectiveFilterHeight,u=e.effectiveFilterWidth,l=i-1-e.padInfo.top,c=u-1-e.padInfo.left,d=1/(n*t);this.userCode=`\n      const ivec2 pads = ivec2(${l}, ${c});\n      const float avgMultiplier = float(${d});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n\n        ivec2 dyRCCorner = coords.yz - pads;\n        int dyRCorner = dyRCCorner.x;\n        int dyCCorner = dyRCCorner.y;\n\n        // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        for (int wR = 0; wR < ${i};\n            wR += ${o}) {\n          float dyR = float(dyRCorner + wR) / ${a}.0;\n\n          if (dyR < 0.0 || dyR >= ${e.outHeight}.0 || fract(dyR) > 0.0) {\n            continue;\n          }\n          int idyR = int(dyR);\n\n          for (int wC = 0; wC < ${u};\n            wC+= ${s}) {\n            float dyC = float(dyCCorner + wC) / ${r}.0;\n\n            if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n                fract(dyC) > 0.0) {\n              continue;\n            }\n            int idyC = int(dyC);\n\n            float dyValue = getDy(b, idyR, idyC, d);\n\n            dotProd += dyValue * avgMultiplier;\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}class Ea{constructor(e){this.variableNames=["dy"],this.outputShape=e.inShape;const n=e.filterDepth,t=e.filterHeight,a=e.filterWidth,r=e.strideDepth,o=e.strideHeight,s=e.strideWidth,i=e.dilationDepth,u=e.dilationHeight,l=e.dilationWidth,c=e.effectiveFilterDepth,d=e.effectiveFilterHeight,p=e.effectiveFilterWidth,h=c-1-e.padInfo.front,f=d-1-e.padInfo.top,x=p-1-e.padInfo.left,g=1/(n*t*a);this.userCode=`\n      const ivec3 pads = ivec3(${h}, ${f}, ${x});\n      const float avgMultiplier = float(${g});\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int ch = coords.u;\n\n        ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n        int dyDCorner = dyCorner.x;\n        int dyRCorner = dyCorner.y;\n        int dyCCorner = dyCorner.z;\n\n        // Convolve dy(?, ?, ?, d) with pos mask(:, :, :, ch) to get\n        // dx(xD, xR, xC, ch).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n\n        for (int wD = 0; wD < ${c};\n            wD += ${i}) {\n          float dyD = float(dyDCorner + wD) / ${r}.0;\n\n          if (dyD < 0.0 || dyD >= ${e.outDepth}.0 || fract(dyD) > 0.0) {\n            continue;\n          }\n          int idyD = int(dyD);\n\n          for (int wR = 0; wR < ${d};\n              wR += ${u}) {\n            float dyR = float(dyRCorner + wR) / ${o}.0;\n\n            if (dyR < 0.0 || dyR >= ${e.outHeight}.0 ||\n                fract(dyR) > 0.0) {\n              continue;\n            }\n            int idyR = int(dyR);\n\n            for (int wC = 0; wC < ${p};\n                wC += ${l}) {\n              float dyC = float(dyCCorner + wC) / ${s}.0;\n\n              if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n                  fract(dyC) > 0.0) {\n                continue;\n              }\n              int idyC = int(dyC);\n\n              float dyValue = getDy(batch, idyD, idyR, idyC, ch);\n\n              dotProd += dyValue * avgMultiplier;\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}const Na={kernelName:n.AvgPool3DGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{dy:o,input:s}=t,i=s,{filterSize:u,strides:l,pad:c,dimRoundingMode:d}=r,p=n.backend_util.computePool3DInfo(i.shape,u,l,[1,1,1],c,d),h=new Ea(p);return a.runWebGLProgram(h,[o],i.dtype)}};const Sa={kernelName:n.AvgPoolGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{dy:o,input:s}=t,i=s;te([o,s],"avgPoolGrad");const{filterSize:u,strides:l,pad:c}=r,d=n.backend_util.computePool2DInfo(i.shape,u,l,1,c),p=new Ta(d);return a.runWebGLProgram(p,[o],i.dtype)}};const Aa={kernelName:n.BatchMatMul,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{a:r,b:o}=n,{transposeA:s,transposeB:i}=a;return jt({a:r,b:o,transposeA:s,transposeB:i,backend:t})}};class Fa{constructor(e,t,a,r,o,s){this.outputShape=[],this.variableNames=["x","mean","variance"],n.backend_util.assertAndGetBroadcastShape(e,t),n.backend_util.assertAndGetBroadcastShape(e,a);let i="0.0";null!=r&&(n.backend_util.assertAndGetBroadcastShape(e,r),this.variableNames.push("offset"),i="getOffsetAtOutCoords()");let u="1.0";null!=o&&(n.backend_util.assertAndGetBroadcastShape(e,o),this.variableNames.push("scale"),u="getScaleAtOutCoords()"),this.outputShape=e,this.userCode=`\n      void main() {\n        float x = getXAtOutCoords();\n        float mean = getMeanAtOutCoords();\n        float variance = getVarianceAtOutCoords();\n        float offset = ${i};\n        float scale = ${u};\n        float inv = scale * inversesqrt(variance + float(${s}));\n        setOutput(dot(vec3(x, -mean, offset), vec3(inv, inv, 1)));\n      }\n    `}}class _a{constructor(e,t,a,r,o,s){this.packedInputs=!0,this.packedOutput=!0,this.variableNames=["x","mean","variance"],n.backend_util.assertAndGetBroadcastShape(e,t),n.backend_util.assertAndGetBroadcastShape(e,a);let i="vec4(0.0)";null!=r&&(n.backend_util.assertAndGetBroadcastShape(e,r),this.variableNames.push("offset"),i="getOffsetAtOutCoords()");let u="vec4(1.0)";null!=o&&(n.backend_util.assertAndGetBroadcastShape(e,o),this.variableNames.push("scale"),u="getScaleAtOutCoords()"),this.outputShape=e,this.userCode=`\n      void main() {\n        vec4 offset = ${i};\n        vec4 scale = ${u};\n\n        vec4 x = getXAtOutCoords();\n        vec4 mean = getMeanAtOutCoords();\n        vec4 variance = getVarianceAtOutCoords();\n\n        vec4 inv = scale * inversesqrt(variance + vec4(${s}));\n\n        setOutput((x - mean) * inv + offset);\n      }\n    `}}const Oa={kernelName:n.FusedBatchNorm,backendName:"webgl",kernelFunc:({inputs:e,backend:t,attrs:a})=>{const{x:r,mean:o,variance:s,offset:i,scale:u}=e;n.util.assert(o.shape.length===s.shape.length,()=>"Batch normalization gradient requires mean and variance to have equal ranks."),n.util.assert(null==i||o.shape.length===i.shape.length,()=>"Batch normalization gradient requires mean and offset to have equal ranks."),n.util.assert(null==u||o.shape.length===u.shape.length,()=>"Batch normalization gradient requires mean and scale to have equal ranks.");let{varianceEpsilon:l}=a;null==l&&(l=.001);const c=[r,o,s];let d=null;null!=i&&(d=i.shape,c.push(i));let p=null;null!=u&&(p=u.shape,c.push(u));const h=n.env().getBool("WEBGL_PACK_NORMALIZATION")?new _a(r.shape,o.shape,s.shape,d,p,l):new Fa(r.shape,o.shape,s.shape,d,p,l);return t.runWebGLProgram(h,c,c[0].dtype)}};class Da{constructor(e){this.variableNames=["source"],this.outputShape=e,this.rank=e.length;const n=Ye(this.rank),t=`uniform int start[${this.rank}];`,a=function(e){if(1===e)return"sourceLoc";if(e<=6)return Pa.slice(0,e).map(e=>"sourceLoc."+e).join(",");throw Error(`Slicing for rank ${e} is not yet supported`)}(this.rank);let r;r=`\n        ${n} sourceLoc;\n        ${n} coords = getOutputCoords();\n        ${e.map((e,n)=>`sourceLoc.${Pa[n]} = start[${n}] + coords.${Pa[n]};`).join("\n")}\n      `,this.userCode=`\n      ${t}\n      void main() {\n        ${r}\n        setOutput(getSource(${a}));\n      }\n    `}getCustomSetupFunc(e){if(e.length!==this.rank)throw Error(`The rank (${this.rank}) of the program must match the `+`length of start (${e.length})`);return(n,t)=>{null==this.startLoc&&(this.startLoc=n.getUniformLocationNoThrow(t,"start"),null==this.startLoc)||n.gl.uniform1iv(this.startLoc,e)}}}const Pa=["x","y","z","w","u","v"];class La{constructor(e){this.variableNames=["source"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e,this.rank=e.length;const n=Ye(this.rank),t=qn("coords",this.rank),a=qn("sourceLoc",this.rank),r=1===this.rank?"sourceLoc":`vec2(${a.slice(-2).join()})`,o=`getChannel(getSource(${a.join()}), ${r})`,s=`\n      result.x = ${o};\n      if (++${t[this.rank-1]} < ${e[this.rank-1]}) {\n        ++${a[this.rank-1]};\n        result.y = ${o};\n        --${a[this.rank-1]};\n      }\n    `,i=1===this.rank?"":`\n      --${t[this.rank-1]};\n      if (++${t[this.rank-2]} < ${e[this.rank-2]}) {\n        ++${a[this.rank-2]};\n        result.z = ${o};\n        if (++${t[this.rank-1]} < ${e[this.rank-1]}) {\n          ++${a[this.rank-1]};\n          result.w = ${o};\n        }\n      }\n    `,u=this.rank<=4?`sourceLoc = coords +\n            ${n}(${e.map((e,n)=>`start[${n}]`).join()});`:e.map((e,n)=>`${a[n]} = ${t[n]} + start[${n}];`).join("\n");this.userCode=`\n      uniform int start[${this.rank}];\n      void main() {\n        ${n} coords = getOutputCoords();\n        ${n} sourceLoc;\n        ${u}\n        vec4 result = vec4(0.);\n        ${s}\n        ${i}\n        setOutput(result);\n      }\n    `}getCustomSetupFunc(e){if(e.length!==this.rank)throw Error(`The rank (${this.rank}) of the program must match the `+`length of start (${e.length})`);return(n,t)=>{null==this.startLoc&&(this.startLoc=n.getUniformLocationNoThrow(t,"start"),null==this.startLoc)||n.gl.uniform1iv(this.startLoc,e)}}}function Ba(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{begin:s,size:i}=r,[u,l]=n.slice_util.parseSliceParams(o,s,i);if(n.slice_util.assertParamsValid(o,u,l),0===n.util.sizeFromShape(l))return a.makeTensorInfo(l,o.dtype,[]);if(a.shouldExecuteOnCPU([o])||"string"===o.dtype){const e=a.texData.get(o.dataId),n=Mn(e.values,u,l,o.shape,o.dtype);return a.makeTensorInfo(l,o.dtype,n)}const{isPacked:c}=a.texData.get(o.dataId),d=n.slice_util.isSliceContinous(o.shape,u,l);if(c||!d){const e=n.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new La(l):new Da(l),t=e.getCustomSetupFunc(u);return a.runWebGLProgram(e,[o],o.dtype,t)}return a.uploadToGPU(o.dataId),function(e,t,a,r){const o=r.texData.get(e.dataId),s=r.makeTensorInfo(a,e.dtype),i=r.texData.get(s.dataId);Object.assign(i,o),i.complexParentRefCount=0,i.refCount=1,i.shape=a,i.dtype=e.dtype;let u=n.slice_util.computeFlatOffset(t,n.util.computeStrides(e.shape));o.slice&&(u+=o.slice.flatOffset),i.slice={flatOffset:u,origDataId:o.slice&&o.slice.origDataId||e.dataId};const l=r.dataRefCount.get(i.slice.origDataId)||1;return r.dataRefCount.set(i.slice.origDataId,l+1),s}(o,u,l,a)}const Va={kernelName:n.Slice,backendName:"webgl",kernelFunc:Ba},Wa={kernelName:n.BatchToSpaceND,backendName:"webgl",kernelFunc:e=>{const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{blockShape:s,crops:i}=r;n.util.assert(o.shape.length<=4,()=>"batchToSpaceND for rank > 4 with a WebGL backend not implemented yet");const u=s.reduce((e,n)=>e*n),l=n.backend_util.getReshaped(o.shape,s,u),c=n.backend_util.getPermuted(l.length,s.length),d=n.backend_util.getReshapedPermuted(o.shape,s,u),p=n.backend_util.getSliceBeginCoords(i,s.length),h=n.backend_util.getSliceSize(d,i,s.length),f=[],x=Dt({inputs:{x:o},backend:a,attrs:{shape:l}}),g=Xt({inputs:{x:x},backend:a,attrs:{perm:c}}),m=Dt({inputs:{x:g},backend:a,attrs:{shape:d}}),b=Ba({inputs:{x:m},backend:a,attrs:{begin:p,size:h}});return f.push(x),f.push(g),f.push(m),f.forEach(e=>a.disposeIntermediateTensorInfo(e)),b}};const Ma={kernelName:n.Bincount,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{x:r,weights:o}=n,{size:s}=a,i=t.readSync(r.dataId),u=t.readSync(o.dataId),l=Cn(i,u,o.dtype,o.shape,s);return t.makeTensorInfo([s],o.dtype,l)}},Ga=wt({opSnippet:"return float(a != b);",dtype:"bool"}),Ua={kernelName:n.NotEqual,backendName:"webgl",kernelFunc:Ga};function za(e){const{inputs:n,backend:t}=e,{input:a}=n;return xt({inputs:{x:t.texData.get(a.dataId).complexTensorInfos.real},backend:t})}const Xa={kernelName:n.Real,backendName:"webgl",kernelFunc:za};const Ha={kernelName:n.Cast,backendName:"webgl",kernelFunc:function e(t){const{inputs:a,backend:r,attrs:o}=t,{x:s}=a,{dtype:i}=o;if("complex64"===i){if("complex64"===s.dtype)return xt({inputs:{x:s},backend:r});const t=n.zeros(s.shape),a=e({inputs:{x:s},backend:r,attrs:{dtype:"float32"}}),o=mt({inputs:{real:a,imag:t},backend:r});return t.dispose(),r.disposeIntermediateTensorInfo(a),o}if("complex64"===s.dtype){const n=za({inputs:{input:s},backend:r}),t=e({inputs:{x:n},backend:r,attrs:{dtype:i}});return r.disposeIntermediateTensorInfo(n),t}if(!n.util.hasEncodingLoss(s.dtype,i)){const e=xt({inputs:{x:s},backend:r});return{dataId:e.dataId,shape:e.shape,dtype:i}}if("int32"===i)return function(e,n){const t=new tt(e.shape,"return float(int(x));"),a=n.runWebGLProgram(t,[e],"int32");return{dataId:a.dataId,shape:a.shape,dtype:a.dtype}}(s,r);if("bool"===i){const e=r.makeTensorInfo([],"bool",n.util.getTypedArrayFromDType("bool",1)),t=Ga({inputs:{a:s,b:e},backend:r});return r.disposeIntermediateTensorInfo(e),t}throw new Error(`Error in Cast: failed to cast ${s.dtype} to ${i}`)}},ja="return ceil(x);",Ka=yt({opSnippet:ja,packedOpSnippet:ja,cpuKernelImpl:In}),qa={kernelName:n.Ceil,backendName:"webgl",kernelFunc:Ka};class Ya{constructor(e){this.variableNames=["A"],this.outputShape=e,this.userCode="\n      uniform float minVal;\n      uniform float maxVal;\n\n      void main() {\n        float value = getAAtOutCoords();\n        if (isnan(value)) {\n          setOutput(value);\n          return;\n        }\n\n        setOutput(clamp(value, minVal, maxVal));\n      }\n    "}getCustomSetupFunc(e,n){return(t,a)=>{null==this.minLoc&&(this.minLoc=t.getUniformLocationNoThrow(a,"minVal"),this.maxLoc=t.getUniformLocationNoThrow(a,"maxVal")),t.gl.uniform1f(this.minLoc,e),t.gl.uniform1f(this.maxLoc,n)}}}class Qa{constructor(e){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e,this.userCode="\n      uniform float minVal;\n      uniform float maxVal;\n\n      void main() {\n        vec4 value = getAAtOutCoords();\n\n        if (any(isnan(value))) {\n          setOutput(value);\n          return;\n        }\n\n        setOutput(clamp(value, vec4(minVal), vec4(maxVal)));\n      }\n    "}getCustomSetupFunc(e,n){return(t,a)=>{null==this.minLoc&&(this.minLoc=t.getUniformLocationNoThrow(a,"minVal"),this.maxLoc=t.getUniformLocationNoThrow(a,"maxVal")),t.gl.uniform1f(this.minLoc,e),t.gl.uniform1f(this.maxLoc,n)}}}const Za={kernelName:n.ClipByValue,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{clipValueMin:s,clipValueMax:i}=r;let u;u=n.env().getBool("WEBGL_PACK_CLIP")?new Qa(o.shape):new Ya(o.shape);const l=u.getCustomSetupFunc(s,i);return a.runWebGLProgram(u,[o],o.dtype,l)}};class Ja{constructor(e){this.variableNames=["real","imag"],this.outputShape=e,this.userCode="\n      void main() {\n        float re = abs(getRealAtOutCoords());\n        float im = abs(getImagAtOutCoords());\n        float mx = max(re, im);\n\n        // sadly the length function in glsl is not underflow-safe\n        // (at least not on Intel GPUs). So the safe solution is\n        // to ensure underflow-safety in all cases.\n        setOutput(\n          mx == 0.0 ? 0.0 : mx * length(vec2(1, min(re, im)/mx))\n        );\n      }\n    "}}function er(e,n){return{dataId:n.dataId,dtype:n.dtype,shape:e.shape}}const nr={kernelName:n.ComplexAbs,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t}=e,{x:a}=n,r=t.texData.get(a.dataId),o=new Ja(a.shape),s=[er(a,r.complexTensorInfos.real),er(a,r.complexTensorInfos.imag)];return t.runWebGLProgram(o,s,s[0].dtype)}};class tr{constructor(e){this.outputShape=[],this.outputShape=n.backend_util.computeOutShape(e,1),this.variableNames=e.map((e,n)=>`T${n}`);const t=new Array(e.length-1);t[0]=e[0][1];for(let n=1;n<t.length;n++)t[n]=t[n-1]+e[n][1];const a=[`if (yC < ${t[0]}) setOutput(getT0(yR, yC));`];for(let e=1;e<t.length;e++){const n=t[e-1];a.push(`else if (yC < ${t[e]}) `+`setOutput(getT${e}(yR, yC-${n}));`)}const r=t.length,o=t[t.length-1];a.push(`else setOutput(getT${r}(yR, yC-${o}));`),this.userCode=`\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int yR = coords.x;\n        int yC = coords.y;\n\n        ${a.join("\n        ")}\n      }\n    `}}class ar{constructor(e,t){this.packedInputs=!0,this.packedOutput=!0,this.outputShape=[],this.outputShape=n.backend_util.computeOutShape(e,t);const a=this.outputShape,r=a.length,o=Ye(r),s=qn("coords",r),i=["x","y","z","w","u","v"].slice(0,r);this.variableNames=e.map((e,n)=>`T${n}`);const u=new Array(e.length-1);u[0]=e[0][t];for(let n=1;n<u.length;n++)u[n]=u[n-1]+e[n][t];const l=i[t],c=i.slice(-2),d=i.join();let p=`if (${l} < ${u[0]}) {\n        return getChannel(\n            getT0(${d}), vec2(${c.join()}));\n        }`;for(let e=1;e<u.length;e++){const n=u[e-1];p+=`\n        if (${l} < ${u[e]}  && ${l} >= ${u[e-1]}) {\n          return getChannel(\n            getT${e}(${rr(i,l,n)}),\n            vec2(${rr(c,l,n)}));\n        }`}const h=u.length,f=u[u.length-1];p+=`\n        return getChannel(\n          getT${h}(${rr(i,l,f)}),\n          vec2(${rr(c,l,f)}));`,this.userCode=`\n      float getValue(${i.map(e=>"int "+e)}) {\n        ${p}\n      }\n\n      void main() {\n        ${o} coords = getOutputCoords();\n        vec4 result = vec4(getValue(${s}), 0., 0., 0.);\n\n        ${s[r-1]} = ${s[r-1]} + 1;\n        if (${s[r-1]} < ${a[r-1]}) {\n          result.g = getValue(${s});\n        }\n\n        ${s[r-2]} = ${s[r-2]} + 1;\n        if (${s[r-2]} < ${a[r-2]}) {\n          result.a = getValue(${s});\n        }\n\n        ${s[r-1]} = ${s[r-1]} - 1;\n        if (${s[r-2]} < ${a[r-2]} &&\n            ${s[r-1]} < ${a[r-1]}) {\n          result.b = getValue(${s});\n        }\n        setOutput(result);\n      }\n    `}}function rr(e,n,t){const a=e.indexOf(n);return e.map((e,n)=>n===a?`${e} - ${t}`:e).join()}function or(e){const{inputs:n,backend:t}=e,{input:a}=n;return xt({inputs:{x:t.texData.get(a.dataId).complexTensorInfos.imag},backend:t})}const sr={kernelName:n.Imag,backendName:"webgl",kernelFunc:or};function ir(e,t,a){const r=n.backend_util.computeOutShape(e.map(e=>e.shape),t);return{tensors2D:e.map(e=>Dt({inputs:{x:e},attrs:{shape:[-1,n.util.sizeFromShape(e.shape.slice(t))]},backend:a})),outShape:r}}function ur(e){const{inputs:t,backend:a,attrs:r}=e,{axis:o}=r,s=n.util.parseAxisParam(o,t[0].shape)[0],i=n.backend_util.computeOutShape(t.map(e=>e.shape),s);if(0===n.util.sizeFromShape(i))return a.makeTensorInfo(i,t[0].dtype,[]);const u=t.filter(e=>n.util.sizeFromShape(e.shape)>0);if(1===u.length)return xt({inputs:{x:u[0]},backend:a});const l=u.map(e=>e.shape);return n.backend_util.assertParamsConsistent(l,s),function e(t,a,r){const o=t[0].dtype;if("complex64"===o){const n=t.map(e=>za({inputs:{input:e},backend:r})),o=t.map(e=>or({inputs:{input:e},backend:r})),s=e(n,a,r),i=e(o,a,r),u=mt({inputs:{real:s,imag:i},backend:r});return n.forEach(e=>r.disposeIntermediateTensorInfo(e)),o.forEach(e=>r.disposeIntermediateTensorInfo(e)),r.disposeIntermediateTensorInfo(s),r.disposeIntermediateTensorInfo(i),u}if("string"===o){const{tensors2D:e,outShape:s}=ir(t,a,r),i=e.map(e=>({vals:r.readSync(e.dataId),shape:e.shape})),u=1===e[0].shape[0],l=Rn(i,s,o,u),c=n.backend_util.computeOutShape(t.map(e=>e.shape),a),d=r.makeTensorInfo(c,o,l);return e.forEach(e=>r.disposeIntermediateTensorInfo(e)),d}if(t.length>n.env().getNumber("WEBGL_MAX_TEXTURES_IN_SHADER")){const n=Math.floor(t.length/2),o=e(t.slice(0,n),a,r),s=e(t.slice(n),a,r),i=e([o,s],a,r);return r.disposeIntermediateTensorInfo(o),r.disposeIntermediateTensorInfo(s),i}if(n.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")&&t[0].shape.length>1){const e=new ar(t.map(e=>e.shape),a);return r.runWebGLProgram(e,t,o)}const{tensors2D:s,outShape:i}=ir(t,a,r),u=new tr(s.map(e=>e.shape)),l=r.runWebGLProgram(u,s,o);s.forEach(e=>r.disposeIntermediateTensorInfo(e));const c=Dt({inputs:{x:l},attrs:{shape:i},backend:r});return r.disposeIntermediateTensorInfo(l),c}(u,s,a)}const lr={kernelName:n.Concat,backendName:"webgl",kernelFunc:ur};class cr{constructor(e,n=!1,t=null,a=!1,r=!1){this.variableNames=["x","W"],this.outputShape=e.outShape;const o=e.padInfo.top,s=e.padInfo.left,i=e.strideHeight,u=e.strideWidth,l=e.dilationHeight,c=e.dilationWidth,d=e.filterHeight,p=e.filterWidth,h=4*Math.floor(e.inChannels/4),f=e.inChannels%4,x="channelsLast"===e.dataFormat,g=x?1:2,m=x?2:3,b=x?3:1;let v="",C="";t&&(v=a?`float activation(float a) {\n          float b = getPreluActivationWeightsAtOutCoords();\n          ${t}\n        }`:r?`float activation(float a) {\n          float b = getLeakyreluAlphaAtOutCoords();\n          ${t}\n        }`:`\n          float activation(float x) {\n            ${t}\n          }\n        `,C="result = activation(result);");const $=n?"result += getBiasAtOutCoords();":"";n&&this.variableNames.push("bias"),a&&this.variableNames.push("preluActivationWeights"),r&&this.variableNames.push("leakyreluAlpha"),this.userCode=`\n      ${v}\n\n      const ivec2 strides = ivec2(${i}, ${u});\n      const ivec2 pads = ivec2(${o}, ${s});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords[0];\n        int d2 = coords[${b}];\n\n        ivec2 xRCCorner =\n            ivec2(coords[${g}], coords[${m}]) * strides - pads;\n        int xRCorner = xRCCorner.x;\n        int xCCorner = xRCCorner.y;\n\n        // Convolve x(?, ?, d1) with w(:, :, d1, d2) to get y(yR, yC, d2).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        for (int wR = 0; wR < ${d}; wR++) {\n          int xR = xRCorner + wR * ${l};\n\n          if (xR < 0 || xR >= ${e.inHeight}) {\n            continue;\n          }\n\n          for (int wC = 0; wC < ${p}; wC++) {\n            int xC = xCCorner + wC * ${c};\n\n            if (xC < 0 || xC >= ${e.inWidth}) {\n              continue;\n            }\n\n            for (int d1 = 0; d1 < ${h}; d1 += 4) {\n              vec4 wValues = vec4(\n                getW(wR, wC, d1, d2),\n                getW(wR, wC, d1 + 1, d2),\n                getW(wR, wC, d1 + 2, d2),\n                getW(wR, wC, d1 + 3, d2)\n              );\n\n              if (${x}) {\n                vec4 xValues = vec4(\n                  getX(batch, xR, xC, d1),\n                  getX(batch, xR, xC, d1 + 1),\n                  getX(batch, xR, xC, d1 + 2),\n                  getX(batch, xR, xC, d1 + 3)\n                );\n                dotProd += dot(xValues, wValues);\n              } else {\n                vec4 xValues = vec4(\n                  getX(batch, d1, xR, xC),\n                  getX(batch, d1 + 1, xR, xC),\n                  getX(batch, d1 + 2, xR, xC),\n                  getX(batch, d1 + 3, xR, xC)\n                );\n                dotProd += dot(xValues, wValues);\n              }\n            }\n\n            if (${1===f}) {\n\n              if (${x}) {\n                dotProd +=\n                    getX(batch, xR, xC, ${h}) *\n                    getW(wR, wC, ${h}, d2);\n              } else {\n                dotProd +=\n                    getX(batch, ${h}, xR, xC) *\n                    getW(wR, wC, ${h}, d2);\n              }\n\n            } else if (${2===f}) {\n              vec2 wValues = vec2(\n                getW(wR, wC, ${h}, d2),\n                getW(wR, wC, ${h} + 1, d2)\n              );\n\n              if (${x}) {\n                vec2 xValues = vec2(\n                  getX(batch, xR, xC, ${h}),\n                  getX(batch, xR, xC, ${h} + 1)\n                );\n                dotProd += dot(xValues, wValues);\n              } else {\n                vec2 xValues = vec2(\n                  getX(batch, ${h}, xR, xC),\n                  getX(batch, ${h} + 1, xR, xC)\n                );\n                dotProd += dot(xValues, wValues);\n              }\n\n            } else if (${3===f}) {\n              vec3 wValues = vec3(\n                getW(wR, wC, ${h}, d2),\n                getW(wR, wC, ${h} + 1, d2),\n                getW(wR, wC, ${h} + 2, d2)\n              );\n\n              if (${x}) {\n                vec3 xValues = vec3(\n                  getX(batch, xR, xC, ${h}),\n                  getX(batch, xR, xC, ${h} + 1),\n                  getX(batch, xR, xC, ${h} + 2)\n                );\n                dotProd += dot(xValues, wValues);\n              } else {\n                vec3 xValues = vec3(\n                  getX(batch, ${h}, xR, xC),\n                  getX(batch, ${h} + 1, xR, xC),\n                  getX(batch, ${h} + 2, xR, xC)\n                );\n                dotProd += dot(xValues, wValues);\n              }\n\n            }\n          }\n        }\n\n        float result = dotProd;\n        ${$}\n        ${C}\n        setOutput(result);\n      }\n    `}}class dr{constructor(e){this.variableNames=["x","W"],this.outputShape=e.outShape;const n=e.padInfo.front,t=e.padInfo.top,a=e.padInfo.left,r=e.strideDepth,o=e.strideHeight,s=e.strideWidth,i=e.dilationDepth,u=e.dilationHeight,l=e.dilationWidth,c=e.filterDepth,d=e.filterHeight,p=e.filterWidth,h=4*Math.floor(e.inChannels/4),f=e.inChannels%4;this.userCode=`\n      const ivec3 strides = ivec3(${r}, ${o}, ${s});\n      const ivec3 pads = ivec3(${n}, ${t}, ${a});\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int d2 = coords.u;\n\n        ivec3 xFRCCorner = ivec3(coords.y, coords.z, coords.w) * strides - pads;\n        int xFCorner = xFRCCorner.x;\n        int xRCorner = xFRCCorner.y;\n        int xCCorner = xFRCCorner.z;\n\n        // Convolve x(?, ?, ?, d1) with w(:, :, :, d1, d2) to get\n        // y(yF, yR, yC, d2). ? = to be determined. : = across all\n        // values in that axis.\n        float dotProd = 0.0;\n        for (int wF = 0; wF < ${c}; wF++) {\n          int xF = xFCorner + wF * ${i};\n\n          if (xF < 0 || xF >= ${e.inDepth}) {\n            continue;\n          }\n\n          for (int wR = 0; wR < ${d}; wR++) {\n            int xR = xRCorner + wR * ${u};\n\n            if (xR < 0 || xR >= ${e.inHeight}) {\n              continue;\n            }\n\n            for (int wC = 0; wC < ${p}; wC++) {\n              int xC = xCCorner + wC * ${l};\n\n              if (xC < 0 || xC >= ${e.inWidth}) {\n                continue;\n              }\n\n              for (int d1 = 0; d1 < ${h}; d1 += 4) {\n                vec4 xValues = vec4(\n                  getX(batch, xF, xR, xC, d1),\n                  getX(batch, xF, xR, xC, d1 + 1),\n                  getX(batch, xF, xR, xC, d1 + 2),\n                  getX(batch, xF, xR, xC, d1 + 3)\n                );\n                vec4 wValues = vec4(\n                  getW(wF, wR, wC, d1, d2),\n                  getW(wF, wR, wC, d1 + 1, d2),\n                  getW(wF, wR, wC, d1 + 2, d2),\n                  getW(wF, wR, wC, d1 + 3, d2)\n                );\n\n                dotProd += dot(xValues, wValues);\n              }\n\n              if (${1===f}) {\n                dotProd +=\n                  getX(batch, xF, xR, xC, ${h}) *\n                  getW(wF, wR, wC, ${h}, d2);\n              } else if (${2===f}) {\n                vec2 xValues = vec2(\n                  getX(batch, xF, xR, xC, ${h}),\n                  getX(batch, xF, xR, xC, ${h} + 1)\n                );\n                vec2 wValues = vec2(\n                  getW(wF, wR, wC, ${h}, d2),\n                  getW(wF, wR, wC, ${h} + 1, d2)\n                );\n                dotProd += dot(xValues, wValues);\n              } else if (${3===f}) {\n                vec3 xValues = vec3(\n                  getX(batch, xF, xR, xC, ${h}),\n                  getX(batch, xF, xR, xC, ${h} + 1),\n                  getX(batch, xF, xR, xC, ${h} + 2)\n                );\n                vec3 wValues = vec3(\n                  getW(wF, wR, wC, ${h}, d2),\n                  getW(wF, wR, wC, ${h} + 1, d2),\n                  getW(wF, wR, wC, ${h} + 2, d2)\n                );\n                dotProd += dot(xValues, wValues);\n              }\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}class pr{constructor(e,n,t){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e;const{filterWidth:a,inChannels:r,strideWidth:o,strideHeight:s,padInfo:i,outWidth:u,dilationWidth:l,dilationHeight:c,dataFormat:d}=t,{left:p,top:h}=i,f=r*a,x=oe(),g="channelsLast"===d,m=g?0:1,b=g?1:2;let v="";for(let t=0;t<=1;t++)for(let a=0;a<=1;a++)v+=`\n          blockIndex = rc.y + ${a};\n          pos = rc.x + ${t};\n\n          if(blockIndex < ${e[1]} && pos < ${e[0]}) {\n            offsetY = int(blockIndex / (${u})) * ${s} - ${h};\n            d0 = offsetY + ${c} * (pos / ${f});\n\n            if(d0 < ${n[m]} && d0 >= 0) {\n\n              offsetX = int(mod(float(blockIndex), ${u}.) * ${o}. - ${p}.);\n              d1 = offsetX + ${l} * (int(mod(float(pos), ${f}.) / ${r}.));\n\n              if(d1 < ${n[b]} && d1 >= 0) {\n\n                ch = int(mod(float(pos), ${r}.));\n\n                if (${g}) {\n                  innerDims = vec2(d1, ch);\n                  result[${2*t+a}] = getChannel(\n                    getA(d0, int(innerDims.x),\n                    int(innerDims.y)), innerDims);\n                } else {\n                  innerDims = vec2(d0, d1);\n                  result[${2*t+a}] = getChannel(\n                    getA(ch, int(innerDims.x),\n                    int(innerDims.y)), innerDims);\n                }\n              }\n            }\n          }\n        `;this.userCode=`\n      void main() {\n        ivec2 rc = getOutputCoords();\n\n        vec4 result = vec4(0);\n\n        int blockIndex, pos, offsetY, d0, offsetX, d1, ch;\n        vec2 innerDims;\n\n        ${v}\n\n        ${x.output} = result;\n      }\n    `}}function hr({x:e,filter:t,convInfo:a,backend:r,bias:o=null,preluActivationWeights:s=null,leakyreluAlpha:i=0,activation:u=null}){const l=e.shape,c=r.texData.get(e.dataId),d=a.inChannels,p=l[0]*l[1]*l[2],h=a.outChannels,f="channelsLast"===a.dataFormat;let x;const g=[],m=(1===p||1===h)&&d>1e3,b=l[2]%2!=0&&!!c.isPacked;if(!m&&n.env().getBool("WEBGL_LAZILY_UNPACK")&&n.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")&&b){const d=f?l[0]*l[1]*(l[2]+1):l[0]*l[2]*(l[3]+1),p={dataId:e.dataId,shape:[1,d,a.inChannels],dtype:e.dtype},h=c.shape;c.shape=c.shape.slice(),c.shape[c.shape.length-2]++,n.util.assert(z(c.shape,p.shape),()=>`packed reshape ${c.shape} to ${p.shape} isn't free`);const m=Dt({inputs:{x:t},backend:r,attrs:{shape:[1,a.inChannels,a.outChannels]}});g.push(m);const b=jt({a:p,b:m,backend:r,transposeA:!1,transposeB:!1,bias:o,activation:u,preluActivationWeights:s,leakyreluAlpha:i}),v=r.texData.get(b.dataId);n.util.assert(v.isPacked,()=>"batchMatMul result is expected to be packed"),c.shape=h,v.shape=a.outShape,x=xt({inputs:{x:b},backend:r}),x.shape=a.outShape,g.push(b)}else{const n=Dt({inputs:{x:e},backend:r,attrs:{shape:[1,f?l[0]*l[1]*l[2]:l[0]*l[2]*l[3],a.inChannels]}}),c=Dt({inputs:{x:t},backend:r,attrs:{shape:[1,a.inChannels,a.outChannels]}}),d=jt({a:n,b:c,transposeA:!1,transposeB:!1,backend:r,bias:o,activation:u,preluActivationWeights:s,leakyreluAlpha:i});x=Dt({inputs:{x:d},backend:r,attrs:{shape:a.outShape}}),g.push(n),g.push(c),g.push(d)}for(const e of g)r.disposeIntermediateTensorInfo(e);return x}function fr({x:e,filter:t,convInfo:a,backend:r,bias:o=null,preluActivationWeights:s=null,leakyreluAlpha:i=0,activation:u=null}){const{filterWidth:l,filterHeight:c,inChannels:d,outWidth:p,outHeight:h,dataFormat:f}=a,x="channelsLast"===f,g=l*c*d,m=h*p,b=[g,m],v=[],C=Dt({inputs:{x:e},backend:r,attrs:{shape:e.shape.slice(1)}}),$=Dt({inputs:{x:t},backend:r,attrs:{shape:[1,g,n.util.sizeFromShape(t.shape)/g]}});v.push(C),v.push($);const I=new pr(b,C.shape,a),R=r.runWebGLProgram(I,[C],"float32"),k=Dt({inputs:{x:R},backend:r,attrs:{shape:[1,b[0],b[1]]}});v.push(R),v.push(k);const y=null!=o,w=null!=s,T="leakyrelu"===u,E=u?Tt(u,!0):null,N=new Et(k.shape,$.shape,[1,m,a.outChannels],!0,!1,y,E,w,T),S=[k,$];if(o&&S.push(o),w&&S.push(s),T){const e=r.makeTensorInfo([],"float32",n.util.createScalarValue(i,"float32"));S.push(e),v.push(e)}const A=r.runWebGLProgram(N,S,"float32"),F=Dt({inputs:{x:A},backend:r,attrs:{shape:x?[1,h,p,a.outChannels]:[1,a.outChannels,h,p]}});v.push(A);for(const e of v)r.disposeIntermediateTensorInfo(e);return F}const xr={kernelName:n.Conv2D,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,filter:s}=t,{strides:i,pad:u,dataFormat:l,dilations:c,dimRoundingMode:d}=r,p=n.backend_util.convertConv2DDataFormat(l),h=n.backend_util.computeConv2DInfo(o.shape,s.shape,i,c,u,d,!1,p);let f;if(1!==h.filterHeight||1!==h.filterWidth||1!==h.dilationHeight||1!==h.dilationWidth||1!==h.strideHeight||1!==h.strideWidth||"SAME"!==h.padInfo.type&&"VALID"!==h.padInfo.type)if(n.env().getBool("WEBGL_CONV_IM2COL")&&1===o.shape[0])f=fr({x:o,filter:s,convInfo:h,backend:a});else{const e=new cr(h);f=a.runWebGLProgram(e,[o,s],"float32")}else f=hr({x:o,filter:s,convInfo:h,backend:a});const x=Dt({inputs:{x:f},backend:a,attrs:{shape:h.outShape}});return a.disposeIntermediateTensorInfo(f),x}};class gr{constructor(e){this.variableNames=["x","dy"],this.outputShape=e.filterShape;const n=e.strideHeight,t=e.strideWidth,a=e.padInfo.top,r=e.padInfo.left,o="channelsLast"===e.dataFormat;this.userCode=`\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int wR = coords.x;\n        int wC = coords.y;\n        int d1 = coords.z;\n        int d2 = coords.w;\n\n        // Convolve x(?, ?, d1) with dy(:, :, d2) to get dw(wR, wC, d1, d2).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n\n        for (int b = 0; b < ${e.batchSize}; b++) {\n          for (int yR = 0; yR < ${e.outHeight}; yR++) {\n            int xR = wR + yR * ${n} - ${a};\n\n            if (xR < 0 || xR >= ${e.inHeight}) {\n              continue;\n            }\n\n            for (int yC = 0; yC < ${e.outWidth}; yC++) {\n              int xC = wC + yC * ${t} - ${r};\n\n              if (xC < 0 || xC >= ${e.inWidth}) {\n                continue;\n              }\n\n              if (${o}) {\n                float dyValue = getDy(b, yR, yC, d2);\n                float xValue = getX(b, xR, xC, d1);\n                dotProd += (xValue * dyValue);\n              } else {\n                float dyValue = getDy(b, d2, yR, yC);\n                float xValue = getX(b, d1, xR, xC);\n                dotProd += (xValue * dyValue);\n              }\n\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}class mr{constructor(e){this.variableNames=["dy","W"],this.outputShape=e.inShape;const n=e.filterHeight,t=e.filterWidth,a=e.strideHeight,r=e.strideWidth,o="channelsLast"===e.dataFormat,s=n-1-e.padInfo.top,i=t-1-e.padInfo.left,u=o?1:2,l=o?2:3,c=o?3:1;this.userCode=`\n      const ivec2 pads = ivec2(${s}, ${i});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords[0];\n        int d1 = coords[${c}];\n\n        ivec2 dyCorner = ivec2(coords[${u}], coords[${l}]) - pads;\n        int dyRCorner = dyCorner.x;\n        int dyCCorner = dyCorner.y;\n\n        // Convolve dy(?, ?, d2) with w(:, :, d1, d2) to compute dx(xR, xC, d1).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        for (int wR = 0; wR < ${n}; wR++) {\n          float dyR = float(dyRCorner + wR) / ${a}.0;\n\n          if (dyR < 0.0 || dyR >= ${e.outHeight}.0 || fract(dyR) > 0.0) {\n            continue;\n          }\n          int idyR = int(dyR);\n\n          int wRPerm = ${n} - 1 - wR;\n\n          for (int wC = 0; wC < ${t}; wC++) {\n            float dyC = float(dyCCorner + wC) / ${r}.0;\n\n            if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n                fract(dyC) > 0.0) {\n              continue;\n            }\n            int idyC = int(dyC);\n\n            int wCPerm = ${t} - 1 - wC;\n\n            for (int d2 = 0; d2 < ${e.outChannels}; d2++) {\n\n              if (${o}) {\n                float xValue = getDy(batch, idyR, idyC, d2);\n                float wValue = getW(wRPerm, wCPerm, d1, d2);\n                dotProd += xValue * wValue;\n              } else {\n                float xValue = getDy(batch, d2, idyR, idyC);\n                float wValue = getW(wRPerm, wCPerm, d1, d2);\n                dotProd += xValue * wValue;\n              }\n\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}class br{constructor(e){this.variableNames=["x","dy"],this.outputShape=e.filterShape;const n=e.strideDepth,t=e.strideHeight,a=e.strideWidth,r=e.padInfo.front,o=e.padInfo.top,s=e.padInfo.left;this.userCode=`\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int wF = coords.x;\n        int wR = coords.y;\n        int wC = coords.z;\n        int d1 = coords.w;\n        int d2 = coords.u;\n\n        float dotProd = 0.0;\n\n        for (int b = 0; b < ${e.batchSize}; b++) {\n          for (int yF = 0; yF < ${e.outDepth}; yF++) {\n            int xF = wF + yF * ${n} - ${r};\n\n            if (xF < 0 || xF >= ${e.inDepth}) {\n              continue;\n            }\n\n            for (int yR = 0; yR < ${e.outHeight}; yR++) {\n              int xR = wR + yR * ${t} - ${o};\n\n              if (xR < 0 || xR >= ${e.inHeight}) {\n                continue;\n              }\n\n              for (int yC = 0; yC < ${e.outWidth}; yC++) {\n                int xC = wC + yC * ${a} - ${s};\n\n                if (xC < 0 || xC >= ${e.inWidth}) {\n                  continue;\n                }\n\n                float dyValue = getDy(b, yF, yR, yC, d2);\n                float xValue = getX(b, xF, xR, xC, d1);\n                dotProd += (xValue * dyValue);\n              }\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}class vr{constructor(e){this.variableNames=["dy","W"],this.outputShape=e.inShape;const n=e.filterDepth,t=e.filterHeight,a=e.filterWidth,r=e.strideDepth,o=e.strideHeight,s=e.strideWidth,i=n-1-e.padInfo.front,u=t-1-e.padInfo.top,l=a-1-e.padInfo.left;this.userCode=`\n      const ivec3 pads = ivec3(${i}, ${u}, ${l});\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int d1 = coords.u;\n\n\n        ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n        int dyFCorner = dyCorner.x;\n        int dyRCorner = dyCorner.y;\n        int dyCCorner = dyCorner.z;\n\n        float dotProd = 0.0;\n        for (int wF = 0; wF < ${n}; wF++) {\n          float dyF = float(dyFCorner + wF) / ${r}.0;\n\n          if (dyF < 0.0 || dyF >= ${e.outDepth}.0 || fract(dyF) > 0.0) {\n            continue;\n          }\n          int idyF = int(dyF);\n\n          int wFPerm = ${n} - 1 - wF;\n\n          for (int wR = 0; wR < ${t}; wR++) {\n            float dyR = float(dyRCorner + wR) / ${o}.0;\n\n            if (dyR < 0.0 || dyR >= ${e.outHeight}.0 ||\n              fract(dyR) > 0.0) {\n              continue;\n            }\n            int idyR = int(dyR);\n\n            int wRPerm = ${t} - 1 - wR;\n\n            for (int wC = 0; wC < ${a}; wC++) {\n              float dyC = float(dyCCorner + wC) / ${s}.0;\n\n              if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n                  fract(dyC) > 0.0) {\n                continue;\n              }\n              int idyC = int(dyC);\n\n              int wCPerm = ${a} - 1 - wC;\n\n              for (int d2 = 0; d2 < ${e.outChannels}; d2++) {\n                float xValue = getDy(batch, idyF, idyR, idyC, d2);\n                float wValue = getW(wFPerm, wRPerm, wCPerm, d1, d2);\n                dotProd += xValue * wValue;\n              }\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}const Cr={kernelName:n.Conv2DBackpropFilter,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,dy:s}=t,{strides:i,pad:u,dataFormat:l,dimRoundingMode:c,filterShape:d}=r,p=n.backend_util.convertConv2DDataFormat(l),h=n.backend_util.computeConv2DInfo(o.shape,d,i,1,u,c,!1,p),f=new gr(h);return a.runWebGLProgram(f,[o,s],"float32")}};const $r={kernelName:n.Conv2DBackpropInput,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{dy:o,filter:s}=t,{inputShape:i,strides:u,pad:l,dataFormat:c,dimRoundingMode:d}=r,p=n.backend_util.convertConv2DDataFormat(c),h=n.backend_util.computeConv2DInfo(i,s.shape,u,1,l,d,!1,p),f=new mr(h);return a.runWebGLProgram(f,[o,s],"float32")}};const Ir={kernelName:n.Conv3D,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,filter:s}=t,{strides:i,pad:u,dilations:l}=r,c=n.backend_util.computeConv3DInfo(o.shape,s.shape,i,l,u),d=new dr(c);return a.runWebGLProgram(d,[o,s],"float32")}};const Rr={kernelName:n.Conv3DBackpropFilterV2,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,dy:s}=t,{strides:i,pad:u,filterShape:l}=r,c=n.backend_util.computeConv3DInfo(o.shape,l,i,1,u),d=new br(c);return a.runWebGLProgram(d,[o,s],"float32")}};const kr={kernelName:n.Conv3DBackpropInputV2,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{dy:o,filter:s}=t,{pad:i,strides:u,inputShape:l}=r,c=n.backend_util.computeConv3DInfo(l,s.shape,u,1,i),d=new vr(c);return a.runWebGLProgram(d,[o,s],"float32")}},yr=yt({opSnippet:"if (isnan(x)) return x;\n  return cos(x);\n"}),wr={kernelName:n.Cos,backendName:"webgl",kernelFunc:yr},Tr=yt({opSnippet:"\n  float e2x = exp(-x);\n  return (e2x + 1.0 / e2x) / 2.0;\n"}),Er={kernelName:n.Cosh,backendName:"webgl",kernelFunc:Tr};class Nr{constructor(e,n,t,a,r){this.variableNames=["Image","Boxes","BoxInd"],this.outputShape=[];const[o,s,i,u]=e,[l]=n,[c,d]=t;this.outputShape=[l,c,d,u];const p="bilinear"===a?1:0,[h,f]=[`${s-1}.0`,`${i-1}.0`],[x,g,m]=c>1?[`${(s-1)/(c-1)}`,"(y2-y1) * height_ratio",`y1*${h} + float(y)*(height_scale)`]:["0.0","0.0",`0.5 * (y1+y2) * ${h}`],[b,v,C]=d>1?[`${(i-1)/(d-1)}`,"(x2-x1) * width_ratio",`x1*${f} + float(x)*(width_scale)`]:["0.0","0.0",`0.5 * (x1+x2) * ${f}`];this.userCode=`\n      const float height_ratio = float(${x});\n      const float width_ratio = float(${b});\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int y = coords[1];\n        int x = coords[2];\n        int d = coords[3];\n\n        // get box vals\n        float y1 = getBoxes(b,0);\n        float x1 = getBoxes(b,1);\n        float y2 = getBoxes(b,2);\n        float x2 = getBoxes(b,3);\n\n        // get image in batch index\n        int bInd = round(getBoxInd(b));\n        if(bInd < 0 || bInd >= ${o}) {\n          return;\n        }\n\n        float height_scale = ${g};\n        float width_scale = ${v};\n\n        float in_y = ${m};\n        if( in_y < 0.0 || in_y > ${h} ) {\n          setOutput(float(${r}));\n          return;\n        }\n        float in_x = ${C};\n        if( in_x < 0.0 || in_x > ${f} ) {\n          setOutput(float(${r}));\n          return;\n        }\n\n        vec2 sourceFracIndexCR = vec2(in_x,in_y);\n        if(${p} == 1) {\n          // Compute the four integer indices.\n          ivec2 sourceFloorCR = ivec2(sourceFracIndexCR);\n          ivec2 sourceCeilCR = ivec2(ceil(sourceFracIndexCR));\n\n          float topLeft = getImage(b, sourceFloorCR.y, sourceFloorCR.x, d);\n          float bottomLeft = getImage(b, sourceCeilCR.y, sourceFloorCR.x, d);\n          float topRight = getImage(b, sourceFloorCR.y, sourceCeilCR.x, d);\n          float bottomRight = getImage(b, sourceCeilCR.y, sourceCeilCR.x, d);\n\n          vec2 fracCR = sourceFracIndexCR - vec2(sourceFloorCR);\n\n          float top = topLeft + (topRight - topLeft) * fracCR.x;\n          float bottom = bottomLeft + (bottomRight - bottomLeft) * fracCR.x;\n          float newValue = top + (bottom - top) * fracCR.y;\n          setOutput(newValue);\n        } else {\n          // Compute the coordinators of nearest neighbor point.\n          ivec2 sourceNearestCR = ivec2(floor(\n            sourceFracIndexCR + vec2(0.5,0.5)));\n          float newValue = getImage(b, sourceNearestCR.y, sourceNearestCR.x, d);\n          setOutput(newValue);\n        }\n      }\n    `}}const Sr={kernelName:n.CropAndResize,backendName:"webgl",kernelFunc:e=>{const{inputs:n,backend:t,attrs:a}=e,{image:r,boxes:o,boxInd:s}=n,{cropSize:i,method:u,extrapolationValue:l}=a,c=new Nr(r.shape,o.shape,i,u,l);return t.runWebGLProgram(c,[r,o,s],"float32")}};class Ar{constructor(e,n,t){this.variableNames=["x"],this.outputShape=e;const a=e.length,r=n?"0.0":`getX(${Fr(a,"coords")})`,o=e[e.length-1];let s="",i="";n?(s=t?`end != ${o-1}`:"end != 0",i=t?"end + 1":"end - 1"):(s=t?`end + pow2 < ${o}`:"end >= pow2",i=t?"end + pow2":"end - pow2"),this.userCode=`\n      uniform float index;\n      void main() {\n        ${Ye(a)} coords = getOutputCoords();\n        int end = ${_r(a,"coords")};\n        float val = ${r};\n        int pow2 = int(pow(2.0, index));\n        if (${s}) {\n          int idx = ${i};\n          ${_r(a,"coords")} = idx;\n          val += getX(${Fr(a,"coords")});\n        }\n        setOutput(val);\n      }\n    `}getCustomSetupFunc(e){return(n,t)=>{null==this.index&&(this.index=n.getUniformLocation(t,"index")),n.gl.uniform1f(this.index,e)}}}function Fr(e,n){if(1===e)return`${n}`;if(2===e)return`${n}.x, ${n}.y`;if(3===e)return`${n}.x, ${n}.y, ${n}.z`;if(4===e)return`${n}.x, ${n}.y, ${n}.z, ${n}.w`;throw Error(`Cumulative sum for rank ${e} is not yet supported`)}function _r(e,n){if(1===e)return`${n}`;if(2===e)return`${n}.y`;if(3===e)return`${n}.z`;if(4===e)return`${n}.w`;throw Error(`Cumulative sum for rank ${e} is not yet supported`)}const Or={kernelName:n.Cumsum,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{axis:s,exclusive:i,reverse:u}=r,l=o.shape.length,c=n.backend_util.getAxesPermutation([s],l);let d=o;null!=c&&(d=Xt({inputs:{x:o},backend:a,attrs:{perm:c}}));const p=n.backend_util.getInnerMostAxes(1,l)[0];if(p!==l-1)throw new Error(`WebGL cumsum shader expects an inner-most axis=${o.shape.length-1} `+`but got axis=${s}`);const h=o.shape[p];let f=xt({inputs:{x:d},backend:a});for(let e=0;e<=Math.ceil(Math.log2(h))-1;e++){const n=new Ar(d.shape,!1,u),t=n.getCustomSetupFunc(e),r=f;f=a.runWebGLProgram(n,[f],f.dtype,t),a.disposeIntermediateTensorInfo(r)}if(i){const e=new Ar(d.shape,i,u),n=f;f=a.runWebGLProgram(e,[f],f.dtype),a.disposeIntermediateTensorInfo(n)}if(null!=c){const e=Xt({inputs:{x:f},backend:a,attrs:{perm:n.backend_util.getUndoAxesPermutation(c)}});return a.disposeIntermediateTensorInfo(f),a.disposeIntermediateTensorInfo(d),e}return f}};const Dr={kernelName:n.DenseBincount,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{x:r,weights:o}=n,{size:s,binaryOutput:i}=a;if(1===r.shape.length){const e=t.readSync(r.dataId),n=t.readSync(o.dataId),a=Cn(e,n,o.dtype,o.shape,s);return t.makeTensorInfo([s],o.dtype,a)}if(2===r.shape.length){const e=t.bufferSync(r),n=t.bufferSync(o),a=$n(e,n,s,i);return t.makeTensorInfo(a.shape,o.dtype,a.values)}throw new Error("Error in denseBincount: input must be at most rank 2, but got rank"+`${r.shape.length}.`)}};class Pr{constructor(e,n,t){this.variableNames=["x"],this.outputShape=[],this.outputShape=e,this.blockSize=n,this.dataFormat=t,this.userCode=`\n    void main() {\n      ivec4 coords = getOutputCoords();\n      int b = coords[0];\n      int h = ${this.getHeightCoordString()};\n      int w = ${this.getWidthCoordString()};\n      int d = ${this.getDepthCoordString()};\n\n      int in_h = h / ${n};\n      int offset_h = imod(h, ${n});\n      int in_w = w / ${n};\n      int offset_w = imod(w, ${n});\n      int offset_d = (offset_h * ${n} + offset_w) *\n        ${this.getOutputDepthSize()};\n      int in_d = d + offset_d;\n\n      float result = ${this.getInputSamplingString()};\n      setOutput(result);\n    }\n  `}getHeightCoordString(){return"NHWC"===this.dataFormat?"coords[1]":"coords[2]"}getWidthCoordString(){return"NHWC"===this.dataFormat?"coords[2]":"coords[3]"}getDepthCoordString(){return"NHWC"===this.dataFormat?"coords[3]":"coords[1]"}getOutputDepthSize(){return"NHWC"===this.dataFormat?this.outputShape[3]:this.outputShape[1]}getInputSamplingString(){return"NHWC"===this.dataFormat?"getX(b, in_h, in_w, in_d)":"getX(b, in_d, in_h, in_w)"}}const Lr={kernelName:n.DepthToSpace,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{blockSize:s,dataFormat:i}=r;n.util.assert(s>1,()=>`blockSize should be > 1 for depthToSpace, but was: ${s}`);const u=o.shape[0],l="NHWC"===i?o.shape[1]:o.shape[2],c="NHWC"===i?o.shape[2]:o.shape[3],d="NHWC"===i?o.shape[3]:o.shape[1],p=l*s,h=c*s,f=d/(s*s),x=new Pr("NHWC"===i?[u,p,h,f]:[u,f,p,h],s,i);return a.runWebGLProgram(x,[o],o.dtype)}};class Br{constructor(e,n=!1,t=null,a=!1,r=!1){this.variableNames=["x","W"],this.outputShape=e.outShape;const o=e.inHeight,s=e.inWidth,i=e.padInfo.top,u=e.padInfo.left,l=e.strideHeight,c=e.strideWidth,d=e.dilationHeight,p=e.dilationWidth,h=e.filterHeight,f=e.filterWidth,x=e.outChannels/e.inChannels;let g="",m="";t&&(g=a?`float activation(float a) {\n          float b = getPreluActivationWeightsAtOutCoords();\n          ${t}\n        }`:r?`float activation(float a) {\n          float b = getLeakyreluAlphaAtOutCoords();\n          ${t}\n        }`:`\n          float activation(float x) {\n            ${t}\n          }\n        `,m="result = activation(result);");const b=n?"result += getBiasAtOutCoords();":"";n&&this.variableNames.push("bias"),a&&this.variableNames.push("preluActivationWeights"),r&&this.variableNames.push("leakyreluAlpha"),this.userCode=`\n      ${g}\n\n      const ivec2 strides = ivec2(${l}, ${c});\n      const ivec2 pads = ivec2(${i}, ${u});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords.x;\n        ivec2 xRCCorner = coords.yz * strides - pads;\n        int d2 = coords.w;\n        int d1 = d2 / ${x};\n        int q = d2 - d1 * ${x};\n\n        int xRCorner = xRCCorner.x;\n        int xCCorner = xRCCorner.y;\n\n        // Convolve x(?, ?, d1) with w(:, :, d1, q) to get y(yR, yC, d2).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        // TO DO(dsmilkov): Flatten the two for loops and vec4 the operations.\n        for (int wR = 0; wR < ${h}; wR++) {\n          int xR = xRCorner + wR * ${d};\n\n          if (xR < 0 || xR >= ${o}) {\n            continue;\n          }\n\n          for (int wC = 0; wC < ${f}; wC++) {\n            int xC = xCCorner + wC * ${p};\n\n            if (xC < 0 || xC >= ${s}) {\n              continue;\n            }\n\n            float xVal = getX(batch, xR, xC, d1);\n            float wVal = getW(wR, wC, d1, q);\n            dotProd += xVal * wVal;\n          }\n        }\n\n        float result = dotProd;\n        ${b}\n        ${m}\n        setOutput(result);\n      }\n    `}}class Vr{constructor(e,t=!1,a=null,r=!1,o=!1){this.variableNames=["x","W"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=e.outShape;const s=e.inHeight,i=e.inWidth,u=e.padInfo.top,l=e.padInfo.left,c=e.strideHeight,d=e.strideWidth,p=e.dilationHeight,h=e.dilationWidth,f=e.filterHeight,x=e.filterWidth,g=x;let m="int xR; int xC; int xCOffset;";for(let e=0;e<f;e++)for(let n=0;n<x;n++)m+=`\n          vec4 xTexelR${e}C${2*n} = vec4(0.);\n          vec4 wR${e}C${n} = vec4(0.);\n          vec4 xR${e}C${n} = vec4(0.);`;for(let e=0;e<f;e++)for(let t=0;t<g;t++){const a=2*t;if(m+=`\n          xR = xRCorner + ${e*p};\n          xC = xCCorner + ${a*h};\n        `,1===d){if(a<x&&(m+=l%2==1?`\n                xCOffset = xC + 1;\n                if(xR >= 0 && xR < ${s} && xCOffset >= 0 && xCOffset < ${i}) {\n                  xTexelR${e}C${a} = getX(batch, xR, xCOffset, d1);\n\n                  // Need to manually clear unused channels in case\n                  // we're reading from recycled texture.\n                  if(xCOffset + 1 >= ${i}) {\n                    xTexelR${e}C${a}.zw = vec2(0.);\n                  }\n                } else {\n                  xTexelR${e}C${a} = vec4(0.);\n                }\n\n                xCOffset = xC + 1 - 2;\n                if(xR >= 0 && xR < ${s} && xCOffset >= 0 && xCOffset < ${i}) {\n                  vec4 previous = getX(batch, xR, xCOffset, d1);\n\n                  // Need to manually clear unused channels in case\n                  // we're reading from recycled texture.\n                  if(xCOffset + 1 >= ${i}) {\n                    previous.zw = vec2(0.);\n                  }\n\n                  xR${e}C${a} = vec4(previous.zw, xTexelR${e}C${a}.xy);\n                } else {\n                  xR${e}C${a} = vec4(0, 0, xTexelR${e}C${a}.xy);\n                }\n              `:`\n                if(xR >= 0 && xR < ${s} && xC >= 0 && xC < ${i}) {\n                  xTexelR${e}C${a} = getX(batch, xR, xC, d1);\n                } else {\n                  xTexelR${e}C${a} = vec4(0.);\n                }\n\n                xR${e}C${a} = xTexelR${e}C${a};\n              `,a+1<x)){const t=l%2==0?n.util.nearestLargerEven(h):h;h%2==0&&l%2==1||h%2!=0&&l%2!=1?(m+=`\n                  xCOffset = xC + ${l%2} + ${t};\n\n                  if(xR >= 0 && xR < ${s} &&\n                    xCOffset >= 0 && xCOffset < ${i}) {\n                    xTexelR${e}C${a+2} = getX(batch, xR, xCOffset, d1);\n                  }\n                `,h>1&&(m+=`\n                    xCOffset -= 2;\n                    if(xR >= 0 && xR < ${s} &&\n                      xCOffset >= 0 && xCOffset < ${i}) {\n                      xTexelR${e}C${a} = getX(batch, xR, xCOffset, d1);\n                    } else {\n                      xTexelR${e}C${a} = vec4(0.);\n                    }\n                  `),m+=`\n                  xR${e}C${a+1} = vec4(\n                    xTexelR${e}C${a}.zw, xTexelR${e}C${a+2}.xy);\n                `):m+=`\n                  xCOffset = xC + ${t};\n\n                  if(xR >= 0 && xR < ${s} &&\n                    xCOffset >= 0 && xCOffset < ${i}) {\n                    xTexelR${e}C${a+2} = getX(batch, xR, xCOffset, d1);\n                  }\n\n                  xR${e}C${a+1} = xTexelR${e}C${a+2};\n                `}}else a<x&&(m+=`\n              if(xR >= 0 && xR < ${s}) {\n            `,l%2==1?(m+=`\n                xCOffset = xC + 1 - ${d};\n                if(xCOffset >= 0 && xCOffset < ${i}) {\n                  xTexelR${e}C${a} = getX(batch, xR, xCOffset, d1);\n                } else {\n                  xTexelR${e}C${a} = vec4(0.);\n                }\n\n                if(xC + 1 >= 0 && xC + 1 < ${i}) {\n                  xTexelR${e}C${a+2} = getX(batch, xR, xC + 1, d1);\n                } else {\n                  xTexelR${e}C${a+2} = vec4(0.);\n                }\n\n                xR${e}C${a} = vec4(\n                  xTexelR${e}C${a}.zw, xTexelR${e}C${a+2}.zw);\n              `,a+1<x&&(m+=`\n                  vec4 final = vec4(0.);\n                  xCOffset = xC + 1 + ${d};\n                  if(xCOffset >= 0 && xCOffset < ${i}) {\n                    final = getX(batch, xR, xCOffset, d1);\n                  }\n                  xR${e}C${a+1} = vec4(xTexelR${e}C${a+2}.xy, final.xy);\n                `)):(m+=`\n                if(xC >= 0 && xC < ${i}) {\n                  xTexelR${e}C${a} = getX(batch, xR, xC, d1);\n                } else {\n                  xTexelR${e}C${a} = vec4(0.);\n                }\n\n                xCOffset = xC + ${d};\n                if(xCOffset >= 0 && xCOffset < ${i}) {\n                  xTexelR${e}C${a+2} = getX(batch, xR, xCOffset, d1);\n                } else {\n                  xTexelR${e}C${a+2} = vec4(0.);\n                }\n\n                xR${e}C${a} = vec4(\n                  xTexelR${e}C${a}.xy, xTexelR${e}C${a+2}.xy);\n              `,a+1<x&&(m+=`\n                  xR${e}C${a+1} = vec4(\n                    xTexelR${e}C${a}.zw, xTexelR${e}C${a+2}.zw);\n                `)),m+="}");a<x&&(m+=`\n            vec4 wTexelR${e}C${a} = getW(${e}, ${a}, d1, q);\n            wR${e}C${a} = vec4(wTexelR${e}C${a}.xz, wTexelR${e}C${a}.xz);\n          `,a+1<x&&(m+=`\n              vec4 wTexelR${e}C${a+1} = getW(${e}, ${a+1}, d1, q);\n              wR${e}C${a+1} =\n                vec4(wTexelR${e}C${a+1}.xz, wTexelR${e}C${a+1}.xz);`))}for(let e=0;e<f;e++)for(let n=0;n<x;n++)m+=`dotProd += xR${e}C${n} * wR${e}C${n};`;let b="",v="";a&&(b=r?`vec4 activation(vec4 a) {\n          vec4 b = getPreluActivationWeightsAtOutCoords();\n          ${a}\n        }`:o?`vec4 activation(vec4 a) {\n          vec4 b = getLeakyreluAlphaAtOutCoords();\n          ${a}\n        }`:`vec4 activation(vec4 x) {\n          ${a}\n        }`,v="result = activation(result);");const C=t?"result += getBiasAtOutCoords();":"";t&&this.variableNames.push("bias"),r&&this.variableNames.push("preluActivationWeights"),o&&this.variableNames.push("leakyreluAlpha"),this.userCode=`\n      ${b}\n\n      const ivec2 strides = ivec2(${c}, ${d});\n      const ivec2 pads = ivec2(${u}, ${l});\n\n      void main() {\n\n        ivec4 coords = getOutputCoords();\n        int batch = coords.x;\n        ivec2 xRCCorner = coords.yz * strides - pads;\n        int d2 = coords.w;\n        int d1 = d2;\n        int q = 0;\n        int xRCorner = xRCCorner.x;\n        int xCCorner = xRCCorner.y;\n\n        vec4 dotProd = vec4(0.);\n\n        ${m}\n\n        vec4 result = dotProd;\n        ${C}\n        ${v}\n        setOutput(result);\n      }\n    `}}const Wr={kernelName:n.DepthwiseConv2dNative,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,filter:s}=t,{strides:i,pad:u,dilations:l,dimRoundingMode:c}=r;let d=l;null==d&&(d=[1,1]),n.util.assert(n.backend_util.eitherStridesOrDilationsAreOne(i,d),()=>"Error in depthwiseConv2d: Either strides or dilations must be "+`1. Got strides ${i} and dilations '${d}'`);const p=n.backend_util.computeConv2DInfo(o.shape,s.shape,i,d,u,c,!0);let h;return h=n.env().getBool("WEBGL_PACK_DEPTHWISECONV")&&p.strideWidth<=2&&p.outChannels/p.inChannels==1?new Vr(p):new Br(p),a.runWebGLProgram(h,[o,s],"float32")}};class Mr{constructor(e){this.variableNames=["x","dy"],this.outputShape=e.filterShape;const n=e.strideHeight,t=e.strideWidth,a=e.padInfo.top,r=e.padInfo.left,o=e.outChannels/e.inChannels;this.userCode=`\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int wR = coords.x;\n        int wC = coords.y;\n        int d1 = coords.z;\n        int dm = coords.w;\n        int d2 = d1 * ${o} + dm;\n\n        float dotProd = 0.0;\n\n        // TO DO: Vec4 over the batch size\n        for (int b = 0; b < ${e.batchSize}; b++) {\n          for (int yR = 0; yR < ${e.outHeight}; yR++) {\n            int xR = wR + yR * ${n} - ${a};\n\n            if (xR < 0 || xR >= ${e.inHeight}) {\n              continue;\n            }\n\n            for (int yC = 0; yC < ${e.outWidth}; yC++) {\n              int xC = wC + yC * ${t} - ${r};\n\n              if (xC < 0 || xC >= ${e.inWidth}) {\n                continue;\n              }\n\n              float dyValue = getDy(b, yR, yC, d2);\n              float xValue = getX(b, xR, xC, d1);\n              dotProd += (xValue * dyValue);\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}class Gr{constructor(e){this.variableNames=["dy","W"],this.outputShape=e.inShape;const n=e.filterHeight,t=e.filterWidth,a=e.strideHeight,r=e.strideWidth,o=n-1-e.padInfo.top,s=t-1-e.padInfo.left,i=e.outChannels/e.inChannels;this.userCode=`\n      const ivec2 pads = ivec2(${o}, ${s});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords[0];\n        int d1 = coords[3];\n        ivec2 dyCorner = coords.yz - pads;\n        int dyRCorner = dyCorner.x;\n        int dyCCorner = dyCorner.y;\n\n        float dotProd = 0.0;\n\n        for (int wR = 0; wR < ${n}; wR++) {\n          float dyR = float(dyRCorner + wR) / ${a}.0;\n\n          if (dyR < 0.0 || dyR >= ${e.outHeight}.0 || fract(dyR) > 0.0) {\n            continue;\n          }\n          int idyR = int(dyR);\n\n          int wRPerm = ${n} - 1 - wR;\n\n          for (int wC = 0; wC < ${t}; wC++) {\n            float dyC = float(dyCCorner + wC) / ${r}.0;\n\n            if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n                fract(dyC) > 0.0) {\n              continue;\n            }\n            int idyC = int(dyC);\n\n            int wCPerm = ${t} - 1 - wC;\n\n            // TO DO: Vec4 over the channelMul\n            for (int dm = 0; dm < ${i}; dm++) {\n              int d2 = d1 * ${i} + dm;\n              float xValue = getDy(batch, idyR, idyC, d2);\n              float wValue = getW(wRPerm, wCPerm, d1, dm);\n              dotProd += xValue * wValue;\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}const Ur={kernelName:n.DepthwiseConv2dNativeBackpropFilter,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,dy:s}=t,{strides:i,dilations:u,pad:l,dimRoundingMode:c,filterShape:d}=r,p=n.backend_util.computeConv2DInfo(o.shape,d,i,u,l,c,!0),h=new Mr(p);return a.runWebGLProgram(h,[o,s],"float32")}};const zr={kernelName:n.DepthwiseConv2dNativeBackpropInput,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{dy:o,filter:s}=t,{strides:i,dilations:u,pad:l,dimRoundingMode:c,inputShape:d}=r,p=n.backend_util.computeConv2DInfo(d,s.shape,i,u,l,c,!0),h=new Gr(p);return a.runWebGLProgram(h,[o,s],"float32")}};class Xr{constructor(e){this.variableNames=["X"],this.outputShape=[e,e],this.userCode="\n      void main() {\n          ivec2 coords = getOutputCoords();\n          float val = coords[0] == coords[1] ? getX(coords[0]) : 0.0;\n          setOutput(val);\n      }\n    "}}const Hr={kernelName:n.Diag,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a}=e,{x:r}=t,o=[...r.shape,...r.shape],s=n.util.sizeFromShape(r.shape),i=Dt({inputs:{x:r},backend:a,attrs:{shape:[s]}}),u=new Xr(s),l=a.runWebGLProgram(u,[i],i.dtype),c=Dt({inputs:{x:l},backend:a,attrs:{shape:o}});return a.disposeIntermediateTensorInfo(i),a.disposeIntermediateTensorInfo(l),c}};class jr{constructor(e){this.variableNames=["x","W"],this.outputShape=e.outShape;const{inHeight:n,inWidth:t,padInfo:a,strideHeight:r,strideWidth:o,filterHeight:s,filterWidth:i,dilationHeight:u,dilationWidth:l}=e,{top:c,left:d}=a;this.userCode=`\n      const ivec2 strides = ivec2(${r}, ${o});\n      const ivec2 pads = ivec2(${c}, ${d});\n      const float neg_infinity = -3.4e38;\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int batch = coords.x;\n        int d1 = coords.w;\n        ivec2 outTopLeftCorner =\n            coords.yz * strides - pads;\n        int hBeg = outTopLeftCorner.x;\n        int wBeg = outTopLeftCorner.y;\n\n        float curVal = neg_infinity;\n        for (int h = 0; h < ${s}; h++) {\n          int hIn = hBeg + h * ${u};\n\n          if (hIn >= 0 && hIn < ${n}) {\n            for (int w = 0; w < ${i}; w++) {\n              int wIn = wBeg + w * ${l};\n\n              if (wIn >= 0 && wIn < ${t}) {\n                float xVal = getX(batch, hIn, wIn, d1);\n                float wVal = getW(h, w, d1);\n\n                float val = xVal + wVal;\n                if (val > curVal) {\n                  curVal = val;\n                }\n              }\n            }\n          }\n        }\n\n        float result = curVal;\n        setOutput(result);\n      }\n    `}}const Kr={kernelName:n.Dilation2D,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,filter:s}=t,{strides:i,pad:u,dilations:l}=r,c=n.backend_util.computeDilation2DInfo(o.shape,s.shape,i,u,"NHWC",l);let d;const p=new jr(c);d=a.runWebGLProgram(p,[o,s],"float32");const h=Dt({inputs:{x:d},backend:a,attrs:{shape:c.outShape}});return a.disposeIntermediateTensorInfo(d),h}},qr=yt({opSnippet:"return (x >= 0.0) ? x : (exp(x) - 1.0);",packedOpSnippet:"\n  vec4 result;\n\n  result.r = (x.r >= 0.0) ? x.r : (exp(x.r) - 1.0);\n  result.g = (x.g >= 0.0) ? x.g : (exp(x.g) - 1.0);\n  result.b = (x.b >= 0.0) ? x.b : (exp(x.b) - 1.0);\n  result.a = (x.a >= 0.0) ? x.a : (exp(x.a) - 1.0);\n\n  return result;\n"}),Yr={kernelName:n.Elu,backendName:"webgl",kernelFunc:qr},Qr={kernelName:n.EluGrad,backendName:"webgl",kernelFunc:e=>{const{inputs:t,backend:a}=e,{dy:r,y:o}=t,s=n.env().getBool("WEBGL_PACK_BINARY_OPERATIONS")?new ft("\n  vec4 bGTEZero = vec4(greaterThanEqual(b, vec4(0.)));\n  return (bGTEZero * a) + ((vec4(1.0) - bGTEZero) * (a * (b + vec4(1.0))));\n",r.shape,o.shape):new ht("return (b >= 1.0) ? a : a * (b + 1.0);",r.shape,o.shape);return a.runWebGLProgram(s,[r,o],r.dtype)}},Zr=wt({opSnippet:"return float(a == b);",packedOpSnippet:"\n  return vec4(equal(a, b));\n",dtype:"bool"}),Jr={kernelName:n.Equal,backendName:"webgl",kernelFunc:Zr},eo=yt({opSnippet:`\n  // Error function is calculated approximately with elementary function.\n  // See "Handbook of Mathematical Functions with Formulas,\n  // Graphs, and Mathematical Tables", Abramowitz and Stegun.\n  float p = ${n.backend_util.ERF_P};\n  float a1 = ${n.backend_util.ERF_A1};\n  float a2 = ${n.backend_util.ERF_A2};\n  float a3 = ${n.backend_util.ERF_A3};\n  float a4 = ${n.backend_util.ERF_A4};\n  float a5 = ${n.backend_util.ERF_A5};\n\n  float sign = sign(x);\n  x = abs(x);\n  float t = 1.0 / (1.0 + p * x);\n  return sign * (1.0 - (((((a5*t + a4)*t) + a3)*t + a2)*t + a1)*t*exp(-x*x));\n`}),no={kernelName:n.Erf,backendName:"webgl",kernelFunc:eo},to="return exp(x);",ao=yt({opSnippet:to,packedOpSnippet:to,cpuKernelImpl:kn}),ro={kernelName:n.Exp,backendName:"webgl",kernelFunc:ao};function oo(e){const{inputs:t,attrs:a,backend:r}=e,{dim:o}=a,{input:s}=t,i=s.shape.length,u=s.shape.slice();let l=o;return o<0&&(n.util.assert(-(i+1)<=o,()=>`Axis must be in the interval [${-(i+1)}, ${i}]`),l=i+o+1),u.splice(l,0,1),Dt({inputs:{x:s},backend:r,attrs:{shape:u}})}const so={kernelName:n.ExpandDims,backendName:"webgl",kernelFunc:oo},io="return exp(x) - 1.0;",uo=yt({opSnippet:io,packedOpSnippet:io,cpuKernelImpl:yn}),lo={kernelName:n.Expm1,backendName:"webgl",kernelFunc:uo};class co{constructor(e,n,t){this.variableNames=["real","imag"];const a=n[1];this.outputShape=n;const r=t?`2.0 * ${Math.PI}`:`-2.0 * ${Math.PI}`,o=t?`${a}.0`:"1.0";let s;if("real"===e)s="return real * expR - imag * expI;";else{if("imag"!==e)throw new Error(`FFT component must be either "real" or "imag", got ${e}.`);s="return real * expI + imag * expR;"}this.userCode=`\n      const float exponentMultiplier = ${r};\n\n      float unaryOpComplex(float real, float expR, float imag, float expI) {\n        ${s}\n      }\n\n      float mulMatDFT(int batch, int index) {\n        float indexRatio = float(index) / float(${a});\n        float exponentMultiplierTimesIndexRatio =\n            exponentMultiplier * indexRatio;\n\n        float result = 0.0;\n\n        for (int i = 0; i < ${a}; i++) {\n          // x = (-2|2 * PI / N) * index * i;\n          float x = exponentMultiplierTimesIndexRatio * float(i);\n          float expR = cos(x);\n          float expI = sin(x);\n          float real = getReal(batch, i);\n          float imag = getImag(batch, i);\n\n          result +=\n              unaryOpComplex(real, expR, imag, expI) / ${o};\n        }\n\n        return result;\n      }\n\n      void main() {\n        ivec2 coords = getOutputCoords();\n        setOutput(mulMatDFT(coords[0], coords[1]));\n      }\n    `}}function po(e,t,a){const r=a.texData.get(e.dataId),o=n.util.sizeFromShape(e.shape),s=e.shape[e.shape.length-1],i=Dt({inputs:{x:e},backend:a,attrs:{shape:[o/s,s]}}),u=i.shape,l=new co("real",u,t),c=new co("imag",u,t),d=[{dataId:r.complexTensorInfos.real.dataId,dtype:r.complexTensorInfos.real.dtype,shape:u},{dataId:r.complexTensorInfos.imag.dataId,dtype:r.complexTensorInfos.imag.dtype,shape:u}],p=a.runWebGLProgram(l,d,"float32"),h=a.runWebGLProgram(c,d,"float32"),f=mt({inputs:{real:p,imag:h},backend:a});a.disposeIntermediateTensorInfo(p),a.disposeIntermediateTensorInfo(h);const x=Dt({inputs:{x:f},backend:a,attrs:{shape:e.shape}});return a.disposeIntermediateTensorInfo(i),a.disposeIntermediateTensorInfo(f),x}const ho={kernelName:n.FFT,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t}=e,{input:a}=n;return po(a,!1,t)}};class fo{constructor(e,n){this.outputShape=[],this.variableNames=["x"],this.outputShape=e,this.userCode="\n      uniform float value;\n      void main() {\n        // Input can be obtained from uniform value.\n        setOutput(value);\n      }\n    "}getCustomSetupFunc(e){return(n,t)=>{null==this.valueLoc&&(this.valueLoc=n.getUniformLocationNoThrow(t,"value")),n.gl.uniform1f(this.valueLoc,e)}}}function xo(e){const{backend:t,attrs:a}=e,{shape:r,value:o}=a;let{dtype:s}=a;if(s=s||n.util.inferDtype(o),"string"===s){const e=n.util.getArrayFromDType(s,n.util.sizeFromShape(r));return e.fill(o),t.makeTensorInfo(r,s,e)}{const e=new fo(r,o),n=e.getCustomSetupFunc(o);return t.runWebGLProgram(e,[],s,n)}}const go={kernelName:n.Fill,backendName:"webgl",kernelFunc:xo};class mo{constructor(e){this.variableNames=["Image"],this.outputShape=[];const n=e[2];this.outputShape=e,this.userCode=`\n        void main() {\n          ivec4 coords = getOutputCoords();\n          int x = coords[2];\n\n          int coordX = ${n} - x;\n          float outputValue;\n          if(coordX >= 0 && coordX < ${n}) {\n            outputValue = getImage(coords[0], coords[1], coordX, coords[3]);\n          } else {\n            outputValue = getImage(coords[0], coords[1], coords[2], coords[3]);\n          }\n          setOutput(outputValue);\n        }\n    `}}const bo={kernelName:n.FlipLeftRight,backendName:"webgl",kernelFunc:({inputs:e,backend:n})=>{const{image:t}=e,a=n,r=new mo(t.shape);return a.runWebGLProgram(r,[t],t.dtype)}},vo="return floor(x);",Co=yt({opSnippet:vo,packedOpSnippet:vo,cpuKernelImpl:wn}),$o={kernelName:n.Floor,backendName:"webgl",kernelFunc:Co},Io=wt({opSnippet:"\n  float s = sign(a) * sign(b);\n  int ia = round(a);\n  int ib = round(b);\n  if (ib != 0) {\n    // Windows (D3D) wants guaranteed non-zero int division at compile-time.\n    return float(idiv(ia, ib, s));\n  } else {\n    return NAN;\n  }\n",packedOpSnippet:"\n  ivec4 ia = round(a);\n  ivec4 ib = round(b);\n  bvec4 cond = notEqual(ib, ivec4(0));\n  ivec4 result = ivec4(0);\n  vec4 s = sign(a) * sign(b);\n\n  // Windows (D3D) wants guaranteed non-zero int division at compile-time.\n  if (cond[0]) {\n    result[0] = idiv(ia[0], ib[0], s[0]);\n  }\n  if (cond[1]) {\n    result[1] = idiv(ia[1], ib[1], s[1]);\n  }\n  if (cond[2]) {\n    result[2] = idiv(ia[2], ib[2], s[2]);\n  }\n  if (cond[3]) {\n    result[3] = idiv(ia[3], ib[3], s[3]);\n  }\n  return vec4(result);\n",dtype:"int32"}),Ro={kernelName:n.FloorDiv,backendName:"webgl",kernelFunc:Io};class ko{constructor(e){this.variableNames=["A"];const n=oe(),[t,a]=e;this.outputShape=e,this.userCode=`\n      void main() {\n        ivec3 coords = getOutputCoords();\n        int texR = coords[0];\n        int texC = coords[1];\n        int depth = coords[2];\n        vec2 uv = (vec2(texC, texR) + halfCR) / vec2(${a}.0, ${t}.0);\n\n        vec4 values = ${n.texture2D}(A, uv);\n        float value;\n        if (depth == 0) {\n          value = values.r;\n        } else if (depth == 1) {\n          value = values.g;\n        } else if (depth == 2) {\n          value = values.b;\n        } else if (depth == 3) {\n          value = values.a;\n        }\n\n        setOutput(floor(value * 255.0 + 0.5));\n      }\n    `}}class yo{constructor(e){this.variableNames=["A"],this.packedInputs=!1,this.packedOutput=!0;const n=oe(),[t,a]=e;this.outputShape=e,this.userCode=`\n      void main() {\n        ivec3 coords = getOutputCoords();\n        int texR = coords[0];\n        int texC = coords[1];\n        int depth = coords[2];\n\n        vec4 result = vec4(0.);\n\n        for(int row=0; row<=1; row++) {\n          for(int col=0; col<=1; col++) {\n            texC = coords[1] + row;\n            depth = coords[2] + col;\n\n            vec2 uv = (vec2(texC, texR) + halfCR) /\n                       vec2(${a}.0, ${t}.0);\n            vec4 values = ${n.texture2D}(A, uv);\n            float value;\n            if (depth == 0) {\n              value = values.r;\n            } else if (depth == 1) {\n              value = values.g;\n            } else if (depth == 2) {\n              value = values.b;\n            } else if (depth == 3) {\n              value = values.a;\n            }\n\n            result[row * 2 + col] = floor(value * 255.0 + 0.5);\n          }\n        }\n\n        ${n.output} = result;\n      }\n    `}}const wo={kernelName:n.FromPixels,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e;let{pixels:o}=t;const{numChannels:s}=r,u="undefined"!=typeof HTMLVideoElement&&o instanceof HTMLVideoElement,l="undefined"!=typeof HTMLImageElement&&o instanceof HTMLImageElement,c="undefined"!=typeof ImageBitmap&&o instanceof ImageBitmap,[d,p]=u?[o.videoWidth,o.videoHeight]:[o.width,o.height],h=[p,d],f=[p,d,s];(l||u||c)&&(null==To&&(To=document.createElement("canvas").getContext("2d")),To.canvas.width=d,To.canvas.height=p,To.drawImage(o,0,0,d,p),o=To.canvas);const x=a.makeTensorInfo(h,"int32");a.texData.get(x.dataId).usage=i.PIXELS,a.gpgpu.uploadPixelDataToTexture(a.getTexture(x.dataId),o);const g=n.env().getBool("WEBGL_PACK")?new yo(f):new ko(f),m=a.runWebGLProgram(g,[x],"int32");return a.disposeData(x.dataId),m}};let To;const Eo={kernelName:n.FusedConv2D,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,filter:s,bias:i,preluActivationWeights:u}=t,{strides:l,pad:c,dataFormat:d,dilations:p,dimRoundingMode:h,activation:f,leakyreluAlpha:x}=r,g=n.backend_util.convertConv2DDataFormat(d),m=n.backend_util.computeConv2DInfo(o.shape,s.shape,l,p,c,h,!1,g);let b;const v=[];if(1!==m.filterHeight||1!==m.filterWidth||1!==m.dilationHeight||1!==m.dilationWidth||1!==m.strideHeight||1!==m.strideWidth||"SAME"!==m.padInfo.type&&"VALID"!==m.padInfo.type)if(n.env().getBool("WEBGL_CONV_IM2COL")&&1===o.shape[0])b=fr({x:o,filter:s,convInfo:m,backend:a,bias:i,activation:f,preluActivationWeights:u,leakyreluAlpha:x});else{const e=null!=i,t=null!=u,r="leakyrelu"===f,l=f?Tt(f,!1):null,c=new cr(m,e,l,t,r),d=[o,s];if(i&&d.push(i),u&&d.push(u),r){const e=a.makeTensorInfo([],"float32",n.util.createScalarValue(x,"float32"));d.push(e),v.push(e)}b=a.runWebGLProgram(c,d,"float32")}else b=hr({x:o,filter:s,convInfo:m,backend:a,bias:i,activation:f,preluActivationWeights:u,leakyreluAlpha:x});const C=Dt({inputs:{x:b},backend:a,attrs:{shape:m.outShape}});return v.push(b),v.forEach(e=>a.disposeIntermediateTensorInfo(e)),C}};const No={kernelName:n.FusedDepthwiseConv2D,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,filter:s,bias:i,preluActivationWeights:u}=t,{strides:l,pad:c,dilations:d,dimRoundingMode:p,activation:h,leakyreluAlpha:f}=r,x=[];let g=d;null==g&&(g=[1,1]),n.util.assert(n.backend_util.eitherStridesOrDilationsAreOne(l,g),()=>"Error in depthwiseConv2d: Either strides or dilations must be "+`1. Got strides ${l} and dilations '${g}'`);const m=n.backend_util.computeConv2DInfo(o.shape,s.shape,l,g,c,p,!0),b=n.env().getBool("WEBGL_PACK_DEPTHWISECONV")&&m.strideWidth<=2&&m.outChannels/m.inChannels==1,v=h?Tt(h,b):null,C=[o,s],$=null!=i,I=null!=u,R="leakyrelu"===h;if($&&C.push(i),I&&C.push(u),R){const e=a.makeTensorInfo([],"float32",n.util.createScalarValue(f,"float32"));C.push(e),x.push(e)}let k;k=b?new Vr(m,$,v,I,R):new Br(m,$,v,I,R);const y=a.runWebGLProgram(k,C,"float32");return x.forEach(e=>a.disposeIntermediateTensorInfo(e)),y}};class So{constructor(e,n,t){this.sliceDim=e,this.strides=n,this.variableNames=["x","indices"],this.outputShape=t;const a=Ye(n.length),r=Ye(t.length),o=this.sliceDim>1?"strides[j]":"strides";this.userCode=`\n        ${a} strides = ${a}(${this.strides});\n         void main() {\n          ${r} coords = getOutputCoords();\n          int flattenIndex = 0;\n          for (int j = 0; j < ${this.sliceDim}; j++) {\n            int index = round(getIndices(coords[0], j));\n            flattenIndex += index * ${o};\n          }\n          setOutput(getX(flattenIndex, coords[1]));\n        }\n      `}}const Ao={kernelName:n.GatherNd,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a}=e,{params:r,indices:o}=t,s=o.shape,i=s[s.length-1],[u,l,c,d]=n.backend_util.prepareAndValidate(r,o),p=Dt({inputs:{x:o},backend:a,attrs:{shape:[l,i]}}),h=Dt({inputs:{x:r},backend:a,attrs:{shape:[n.util.sizeFromShape(r.shape)/c,c]}}),f=new So(i,d,[l,c]),x=a.runWebGLProgram(f,[h,p],h.dtype),g=Dt({inputs:{x:x},backend:a,attrs:{shape:u}});return a.disposeIntermediateTensorInfo(p),a.disposeIntermediateTensorInfo(h),a.disposeIntermediateTensorInfo(x),g}};class Fo{constructor(e,n){this.variableNames=["A","indices"],this.outputShape=n,this.rank=n.length;const t=Ye(this.rank),a=function(e,n){const t=["resRC.x","resRC.y","resRC.z","resRC.w"],a=[];for(let n=0;n<e.length;n++)2===n?a.push("int(getIndices(resRC.x, resRC.z))"):a.push(`${t[n]}`);return a.join()}(e);this.userCode=`\n      void main() {\n        ${t} resRC = getOutputCoords();\n        setOutput(getA(${a}));\n      }\n    `}}const _o={kernelName:n.GatherV2,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,indices:s}=t,{axis:i,batchDims:u}=r,l=n.util.parseAxisParam(i,o.shape)[0],c=n.backend_util.segment_util.collectGatherOpShapeInfo(o,s,l,u),d=n.util.sizeFromShape(s.shape),p=[],h=Dt({inputs:{x:o},backend:a,attrs:{shape:[c.batchSize,c.outerSize,c.dimSize,c.sliceSize]}}),f=Dt({inputs:{x:s},backend:a,attrs:{shape:[c.batchSize,d/c.batchSize]}});p.push(h),p.push(f);const x=[c.batchSize,c.outerSize,d/c.batchSize,c.sliceSize];if(a.shouldExecuteOnCPU([o,s])||"string"===o.dtype){const e=a.bufferSync(f),n=a.bufferSync(h),t=Tn(n,e,x);return p.forEach(e=>a.disposeIntermediateTensorInfo(e)),a.makeTensorInfo(c.outputShape,t.dtype,t.values)}const g=new Fo(h.shape,x),m=a.runWebGLProgram(g,[h,f],h.dtype);p.push(m);const b=Dt({inputs:{x:m},backend:a,attrs:{shape:c.outputShape}});return p.forEach(e=>a.disposeIntermediateTensorInfo(e)),b}},Oo=wt({opSnippet:"return float(a > b);",packedOpSnippet:"\n  return vec4(greaterThan(a, b));\n",cpuKernelImpl:En,dtype:"bool"}),Do={kernelName:n.Greater,backendName:"webgl",kernelFunc:Oo},Po=wt({opSnippet:"return float(a >= b);",packedOpSnippet:"\n  return vec4(greaterThanEqual(a, b));\n",dtype:"bool"}),Lo={kernelName:n.GreaterEqual,backendName:"webgl",kernelFunc:Po};const Bo={kernelName:n.IFFT,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t}=e,{input:a}=n;return po(a,!0,t)}},Vo=yt({opSnippet:"return float(!isnan(x) && !isinf(x));",dtype:"bool"}),Wo={kernelName:n.IsFinite,backendName:"webgl",kernelFunc:Vo},Mo=yt({opSnippet:"return float(isinf(x));",dtype:"bool"}),Go={kernelName:n.IsInf,backendName:"webgl",kernelFunc:Mo},Uo=yt({opSnippet:"return float(isnan(x));",dtype:"bool"}),zo={kernelName:n.IsNan,backendName:"webgl",kernelFunc:Uo},Xo=wt({opSnippet:"return float(a < b);",packedOpSnippet:"\n  return vec4(lessThan(a, b));\n",cpuKernelImpl:Nn,dtype:"bool"}),Ho={kernelName:n.Less,backendName:"webgl",kernelFunc:Xo},jo=wt({opSnippet:"return float(a <= b);",packedOpSnippet:"\n  return vec4(lessThanEqual(a, b));\n",dtype:"bool"}),Ko={kernelName:n.LessEqual,backendName:"webgl",kernelFunc:jo};const qo={kernelName:n.LinSpace,backendName:"webgl",kernelFunc:function(e){const{backend:n,attrs:t}=e,{start:a,stop:r,num:o}=t,s=Sn(a,r,o);return n.makeTensorInfo([s.length],"float32",s)}},Yo=yt({opSnippet:"if (x < 0.0) return NAN;\n  return log(x);",packedOpSnippet:"\n  vec4 result = log(x);\n  vec4 isNaN = vec4(lessThan(x, vec4(0.0)));\n  result.r = isNaN.r == 1.0 ? NAN : result.r;\n  result.g = isNaN.g == 1.0 ? NAN : result.g;\n  result.b = isNaN.b == 1.0 ? NAN : result.b;\n  result.a = isNaN.a == 1.0 ? NAN : result.a;\n\n  return result;\n",cpuKernelImpl:An}),Qo={kernelName:n.Log,backendName:"webgl",kernelFunc:Yo},Zo=yt({opSnippet:"return log(1.0 + x);"}),Jo={kernelName:n.Log1p,backendName:"webgl",kernelFunc:Zo},es=wt({opSnippet:"return float(a >= 1.0 && b >= 1.0);",packedOpSnippet:"\n  return vec4(\n    vec4(greaterThanEqual(a, vec4(1.0))) *\n    vec4(greaterThanEqual(b, vec4(1.0))));\n",dtype:"bool"}),ns={kernelName:n.LogicalAnd,backendName:"webgl",kernelFunc:es},ts=yt({opSnippet:"return float(!(x >= 1.0));"}),as={kernelName:n.LogicalNot,backendName:"webgl",kernelFunc:ts},rs=wt({opSnippet:"return float(a >= 1.0 || b >= 1.0);",packedOpSnippet:"\n  return min(\n    vec4(greaterThanEqual(a, vec4(1.0))) +\n    vec4(greaterThanEqual(b, vec4(1.0))),\n    vec4(1.0));\n",dtype:"bool"}),os={kernelName:n.LogicalOr,backendName:"webgl",kernelFunc:rs};class ss{constructor(e,n,t,a,r){this.variableNames=["x"],this.outputShape=[];const o=n,s=e[3]-1;let i;this.outputShape=e;const u=`float(${t}) + float(${a}) * sum`;i=.5===r?`inversesqrt(${u})`:1===r?`1.0/(${u})`:`exp(log(${u}) * float(-${r}));`,this.userCode=`\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int r = coords[1];\n        int c = coords[2];\n        int d = coords[3];\n        float x = getX(b, r, c, d);\n        float sum = 0.0;\n        for (int j = -${o}; j <= ${o}; j++) {\n          int idx = d + j;\n          if (idx >= 0 && idx <=  ${s}) {\n            float z = getX(b, r, c, idx);\n            sum += z * z;\n          }\n        }\n        float val = x * ${i};\n        setOutput(val);\n      }\n    `}}class is{constructor(e,n,t,a,r){this.variableNames=["x"],this.outputShape=[],this.packedInputs=!0,this.packedOutput=!0;const o=n,s=e[3]-1;let i;this.outputShape=e;const u=`float(${t}) + float(${a}) * sum`;i=.5===r?`inversesqrt(${u})`:1===r?`1.0/(${u})`:`exp(log(${u}) * float(-${r}));`,this.userCode=`\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords.x;\n        int r = coords.y;\n        int c = coords.z;\n        int d = coords.w;\n\n        bool hasNextCol = d < ${this.outputShape[3]};\n        bool hasNextRow = c < ${this.outputShape[2]};\n\n        vec4 sum = vec4(0.);\n        vec4 xFragAtOutputCoords = getX(b, r, c, d);\n\n        vec4 xAtOutputCoords = vec4(\n          getChannel(xFragAtOutputCoords, vec2(c, d)),\n          hasNextCol ?\n            getChannel(xFragAtOutputCoords, vec2(c, d + 1)) : 0.0,\n          hasNextRow ?\n            getChannel(xFragAtOutputCoords , vec2(c + 1, d)) : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getChannel(xFragAtOutputCoords, vec2(c + 1, d + 1)) : 0.0\n        );\n\n        int firstChannel = d - ${o};\n        vec2 cache = vec2(0.);\n        if(firstChannel >= 0){\n          vec4 firstChannelFrag = getX(b, r, c, firstChannel);\n          cache.x = getChannel(firstChannelFrag, vec2(c, firstChannel));\n            if(hasNextRow){\n              cache.y = getChannel(firstChannelFrag, vec2(c + 1, firstChannel));\n            }\n        }\n\n        ivec2 depth = ivec2(d, d + 1);\n        for (int j = - ${o}; j <= ${o}; j++) {\n          ivec2 idx = depth + j;\n          bvec2 aboveLowerBound = greaterThanEqual(idx, ivec2(0));\n          bvec2 belowUpperBound = lessThanEqual(idx, ivec2(${s}));\n\n          bool depthInRange = aboveLowerBound.x && belowUpperBound.x;\n          bool depthPlusOneInRange = aboveLowerBound.y && belowUpperBound.y;\n\n          if(depthInRange || depthPlusOneInRange){\n            vec4 z = vec4(0.);\n            vec4 xFragAtCurrentDepth;\n            z.xz = cache.xy;\n            if(depthPlusOneInRange && hasNextCol){\n              xFragAtCurrentDepth = idx.y != d ?\n                getX(b, r, c, idx.y) : xFragAtOutputCoords;\n              z.y = getChannel(xFragAtCurrentDepth, vec2(c, idx.y));\n              if(hasNextRow){\n                z.w = getChannel(xFragAtCurrentDepth, vec2(c + 1, idx.y));\n              }\n            }\n            cache.xy = z.yw;\n            sum += z * z;\n          }\n        }\n        vec4 result = xAtOutputCoords * ${i};\n        setOutput(result);\n      }\n    `}}const us={kernelName:n.LRN,backendName:"webgl",kernelFunc:e=>{const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{depthRadius:s,bias:i,alpha:u,beta:l}=r,c=n.env().getBool("WEBGL_PACK_NORMALIZATION")?new is(o.shape,s,i,u,l):new ss(o.shape,s,i,u,l);return a.runWebGLProgram(c,[o],o.dtype)}};class ls{constructor(e,n,t,a,r){this.variableNames=["inputImage","outputImage","dy"],this.outputShape=[],this.outputShape=e,this.depth=e[3],this.depthRadius=n,this.bias=t,this.alpha=a,this.beta=r,this.userCode=`\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int r = coords[1];\n        int c = coords[2];\n\n        float result = 0.0;\n        for (int d = 0; d < ${this.depth}; ++d) {\n          int depthBegin = int(max(0.0, float(d - ${n})));\n          int depthEnd = int(min(float(${this.depth}),\n              float(d + ${n} + 1)));\n\n          const int MIN_DEPTH_BEGIN = 0;\n          const int MAX_DEPTH_END = ${this.depth};\n\n          float norm = 0.0;\n          for (int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k) {\n            if (k < depthBegin){\n              continue;\n            }\n            else if (k >= depthBegin && k < depthEnd) {\n              norm += getInputImage(b, r, c, k) * getInputImage(b, r, c, k);\n            }\n            else {\n              break;\n            }\n          }\n\n          norm = float(${a}) * norm + float(${t});\n\n          for(int k = MIN_DEPTH_BEGIN; k < MAX_DEPTH_END; ++k){\n            if (k < depthBegin){\n              continue;\n            }\n            else if (k >= depthBegin && k < depthEnd){\n              float dyi = -2.0 * float(${a})\n                * float(${r})\n                * getInputImage(b ,r ,c, k) * getOutputImage(b, r, c, d)\n                / norm;\n              if (k == d) {\n                dyi += pow(norm, -1.0 * ${r});\n              }\n              if (k == coords[3]) {\n                dyi *= getDy(b, r, c, d);\n                result += dyi;\n              }\n            }\n            else {\n              break;\n            }\n          }\n      }\n      setOutput(result);\n      }\n    `}}const cs={kernelName:n.LRNGrad,backendName:"webgl",kernelFunc:e=>{const{inputs:n,backend:t,attrs:a}=e,{x:r,y:o,dy:s}=n,{depthRadius:i,bias:u,alpha:l,beta:c}=a,d=new ls(r.shape,i,u,l,c);return t.runWebGLProgram(d,[r,o,s],r.dtype)}};function ds(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{reductionIndices:s,keepDims:i}=r,u=o.shape.length,l=n.util.parseAxisParam(s,o.shape);let c=l;const d=n.backend_util.getAxesPermutation(c,u),p=null!=d,h=a.shouldExecuteOnCPU([o]);let f=o;if(p){if(h){const e=a.texData.get(f.dataId).values,n=new Array(u);for(let e=0;e<n.length;e++)n[e]=o.shape[d[e]];const t=Hn(e,o.shape,o.dtype,d,n);f=a.makeTensorInfo(n,o.dtype),a.texData.get(f.dataId).values=t}else f=Gt(o,d,a);c=n.backend_util.getInnerMostAxes(c.length,u)}n.backend_util.assertAxesAreInnerMostDims("max",c,u);const[x,g]=n.backend_util.computeOutAndReduceShapes(f.shape,c);let m,b=x;if(i&&(b=n.backend_util.expandShapeToKeepDim(x,l)),h){const e=a.texData.get(f.dataId).values,t=Fn(e,n.util.sizeFromShape(g),b,o.dtype);m=a.makeTensorInfo(b,o.dtype),a.texData.get(m.dataId).values=t}else m=function(e,t,a,r){const o=n.util.sizeFromShape(t),s=Dt({inputs:{x:e},attrs:{shape:[n.util.sizeFromShape(e.shape)/o,o]},backend:r}),i=Vt(s,e.dtype,"max",r),u=Dt({inputs:{x:i},attrs:{shape:a},backend:r});return r.disposeIntermediateTensorInfo(s),r.disposeIntermediateTensorInfo(i),u}(f,g,b,a);return p&&a.disposeIntermediateTensorInfo(f),m}const ps={kernelName:n.Max,backendName:"webgl",kernelFunc:ds},hs=wt({opSnippet:"\n  if (isnan(a)) return a;\n  if (isnan(b)) return b;\n\n  return max(a, b);\n",packedOpSnippet:"\n  vec4 result = vec4(max(a, b));\n  vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));\n  \n  result.r = isNaN.r > 0. ? NAN : result.r;\n  result.g = isNaN.g > 0. ? NAN : result.g;\n  result.b = isNaN.b > 0. ? NAN : result.b;\n  result.a = isNaN.a > 0. ? NAN : result.a;\n\n  return result;\n",cpuKernelImpl:_n}),fs={kernelName:n.Maximum,backendName:"webgl",kernelFunc:hs};const xs={kernelName:n.MaxPool,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t;te(o,"maxPool");const{filterSize:s,strides:i,pad:u,dimRoundingMode:l}=r;n.util.assert(n.backend_util.eitherStridesOrDilationsAreOne(i,1),()=>"Error in maxPool: Either strides or dilations must be 1. "+`Got strides ${i} and dilations '1'`);const c=n.backend_util.computePool2DInfo(o.shape,s,i,1,u,l);if(1===c.filterWidth&&1===c.filterHeight&&n.util.arraysEqual(c.inShape,c.outShape))return xt({inputs:{x:o},backend:a});const d=new Ra(c,"max",!1);return a.runWebGLProgram(d,[o],o.dtype)}};const gs={kernelName:n.MaxPool3D,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{filterSize:s,strides:i,pad:u,dataFormat:l,dimRoundingMode:c}=r,d=n.backend_util.computePool3DInfo(o.shape,s,i,[1,1,1],u,c,l),p=new ka(d,"max",!1);return a.runWebGLProgram(p,[o],o.dtype)}};class ms{constructor(e){this.variableNames=["dy","maxPos"],this.outputShape=e.inShape;const n=e.strideHeight,t=e.strideWidth,a=e.dilationHeight,r=e.effectiveFilterHeight,o=e.effectiveFilterWidth,s=r-1-e.padInfo.top,i=o-1-e.padInfo.left,u=r*o-1;this.userCode=`\n      const ivec2 pads = ivec2(${s}, ${i});\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n\n        ivec2 dyRCCorner = coords.yz - pads;\n        int dyRCorner = dyRCCorner.x;\n        int dyCCorner = dyRCCorner.y;\n\n        // Convolve dy(?, ?, d) with pos mask(:, :, d) to get dx(xR, xC, d).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n        for (int wR = 0; wR < ${r};\n          wR += ${a}) {\n          float dyR = float(dyRCorner + wR) / ${n}.0;\n\n          if (dyR < 0.0 || dyR >= ${e.outHeight}.0 || fract(dyR) > 0.0) {\n            continue;\n          }\n          int idyR = int(dyR);\n\n          for (int wC = 0; wC < ${o}; wC++) {\n            float dyC = float(dyCCorner + wC) / ${t}.0;\n\n            if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n                fract(dyC) > 0.0) {\n              continue;\n            }\n            int idyC = int(dyC);\n\n            float dyValue = getDy(b, idyR, idyC, d);\n            int maxPosValue = ${u} - int(getMaxPos(b, idyR, idyC, d));\n\n            // Get the current value, check it against the value from the\n            // position matrix.\n            int curPosValue = wR * ${o} + wC;\n            float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n            dotProd += dyValue * mask;\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}class bs{constructor(e){this.variableNames=["dy","maxPos"],this.outputShape=e.inShape;const n=e.strideDepth,t=e.strideHeight,a=e.strideWidth,r=e.dilationDepth,o=e.dilationHeight,s=e.dilationWidth,i=e.effectiveFilterDepth,u=e.effectiveFilterHeight,l=e.effectiveFilterWidth,c=i-1-e.padInfo.front,d=u-1-e.padInfo.top,p=l-1-e.padInfo.left,h=i*u*l-1;this.userCode=`\n      const ivec3 pads = ivec3(${c}, ${d}, ${p});\n\n      void main() {\n        ivec5 coords = getOutputCoords();\n        int batch = coords.x;\n        int ch = coords.u;\n\n        ivec3 dyCorner = ivec3(coords.y, coords.z, coords.w) - pads;\n        int dyDCorner = dyCorner.x;\n        int dyRCorner = dyCorner.y;\n        int dyCCorner = dyCorner.z;\n\n        // Convolve dy(?, ?, ?, ch) with pos mask(:, :, :, d) to get\n        // dx(xD, xR, xC, ch).\n        // ? = to be determined. : = across all values in that axis.\n        float dotProd = 0.0;\n\n        for (int wD = 0; wD < ${i};\n           wD += ${r}) {\n          float dyD = float(dyDCorner + wD) / ${n}.0;\n\n          if (dyD < 0.0 || dyD >= ${e.outDepth}.0 || fract(dyD) > 0.0) {\n            continue;\n          }\n          int idyD = int(dyD);\n\n          for (int wR = 0; wR < ${u};\n              wR += ${o}) {\n            float dyR = float(dyRCorner + wR) / ${t}.0;\n\n            if (dyR < 0.0 || dyR >= ${e.outHeight}.0 ||\n                fract(dyR) > 0.0) {\n              continue;\n            }\n            int idyR = int(dyR);\n\n            for (int wC = 0; wC < ${l};\n                wC += ${s}) {\n              float dyC = float(dyCCorner + wC) / ${a}.0;\n\n              if (dyC < 0.0 || dyC >= ${e.outWidth}.0 ||\n                  fract(dyC) > 0.0) {\n                continue;\n              }\n              int idyC = int(dyC);\n\n              float dyValue = getDy(batch, idyD, idyR, idyC, ch);\n              int maxPosValue = ${h} -\n                  int(getMaxPos(batch, idyD, idyR, idyC, ch));\n\n              // Get the current value, check it against the value from the\n              // position matrix.\n              int curPosValue =\n                  wD * ${u} * ${l} +\n                  wR * ${l} + wC;\n              float mask = float(maxPosValue == curPosValue ? 1.0 : 0.0);\n\n              dotProd += dyValue * mask;\n            }\n          }\n        }\n        setOutput(dotProd);\n      }\n    `}}const vs={kernelName:n.MaxPool3DGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{dy:o,input:s}=t,i=s,{filterSize:u,strides:l,pad:c,dimRoundingMode:d}=r,p=n.backend_util.computePool3DInfo(i.shape,u,l,[1,1,1],c,d),h=new ka(p,"max",!0),f=a.runWebGLProgram(h,[i],i.dtype),x=new bs(p),g=a.runWebGLProgram(x,[o,f],i.dtype);return a.disposeIntermediateTensorInfo(f),g}};const Cs={kernelName:n.MaxPoolGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{dy:o,input:s,output:i}=t,u=s;te([s,i],"maxPoolGrad");const{filterSize:l,strides:c,pad:d,dimRoundingMode:p}=r,h=n.backend_util.computePool2DInfo(u.shape,l,c,1,d,p),f=new Ra(h,"max",!0),x=a.runWebGLProgram(f,[u],u.dtype),g=new ms(h),m=a.runWebGLProgram(g,[o,x],u.dtype);return a.disposeIntermediateTensorInfo(x),m}};const $s={kernelName:n.MaxPoolWithArgmax,backendName:"webgl",kernelFunc:({inputs:e,attrs:t,backend:a})=>{const{x:r}=e,{filterSize:o,strides:s,pad:i,includeBatchInIndex:u}=t,l=a;n.util.assert(4===r.shape.length,()=>`Error in maxPool: input must be rank 4 but got rank ${r.shape.length}.`);const c=[1,1];n.util.assert(n.backend_util.eitherStridesOrDilationsAreOne(s,c),()=>"Error in maxPool: Either strides or dilations must be 1. "+`Got strides ${s} and dilations '${c}'`);const d=n.backend_util.computePool2DInfo(r.shape,o,s,c,i),[p,h]=function(e,n,t,a){let r=new Ra(t,"max",!1);const o=a.runWebGLProgram(r,[e],"float32");return r=new Ra(t,"max",!0,!0,n),[o,a.runWebGLProgram(r,[e],"float32")]}(r,u,d,l);return[p,h]}};const Is={kernelName:n.Mean,backendName:"webgl",kernelFunc:({inputs:e,attrs:t,backend:a})=>{const{x:r}=e,{keepDims:o,axis:s}=t,i=a,u=r.shape.length,l=n.util.parseAxisParam(s,r.shape);let c=l;const d=n.backend_util.getAxesPermutation(c,u),p=null!=d,h=i.shouldExecuteOnCPU([r]),f=[];let x=r;if(p){if(h){const e=i.texData.get(x.dataId).values,n=new Array(u);for(let e=0;e<n.length;e++)n[e]=r.shape[d[e]];const t=Hn(e,r.shape,r.dtype,d,n);x=i.makeTensorInfo(n,r.dtype),i.texData.get(x.dataId).values=t}else x=Gt(r,d,i);f.push(x),c=n.backend_util.getInnerMostAxes(c.length,u)}n.backend_util.assertAxesAreInnerMostDims("sum",c,u);const[g,m]=n.backend_util.computeOutAndReduceShapes(x.shape,c);let b=g;o&&(b=n.backend_util.expandShapeToKeepDim(g,l));const v=function(e,t,a,r){const o=n.util.sizeFromShape(t),s=Dt({inputs:{x:e},attrs:{shape:[n.util.sizeFromShape(e.shape)/o,o]},backend:r}),i=Vt(s,"float32","mean",r),u=Dt({inputs:{x:i},attrs:{shape:a},backend:r});return r.disposeIntermediateTensorInfo(s),r.disposeIntermediateTensorInfo(i),u}(x,m,b,i);for(const e of f)i.disposeIntermediateTensorInfo(e);return v}};const Rs={kernelName:n.Min,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{axis:s,keepDims:i}=r,u=o.shape.length,l=n.util.parseAxisParam(s,o.shape);let c=l;const d=n.backend_util.getAxesPermutation(c,u);let p=o;null!=d&&(p=Xt({inputs:{x:o},backend:a,attrs:{perm:d}}),c=n.backend_util.getInnerMostAxes(c.length,o.shape.length)),n.backend_util.assertAxesAreInnerMostDims("min",c,u);const[h,f]=n.backend_util.computeOutAndReduceShapes(p.shape,c),x=Dt({inputs:{x:p},backend:a,attrs:{shape:[-1,n.util.sizeFromShape(f)]}}),g=Vt(x,x.dtype,"min",a);let m;if(i){m=Dt({inputs:{x:g},backend:a,attrs:{shape:n.backend_util.expandShapeToKeepDim(h,l)}})}else m=Dt({inputs:{x:g},backend:a,attrs:{shape:h}});return a.disposeIntermediateTensorInfo(x),a.disposeIntermediateTensorInfo(g),null!=d&&a.disposeIntermediateTensorInfo(p),m}},ks=wt({opSnippet:"\n  if (isnan(a)) return a;\n  if (isnan(b)) return b;\n\n  return min(a, b);\n",packedOpSnippet:"\n  vec4 result = vec4(min(a, b));\n  vec4 isNaN = min(vec4(isnan(a)) + vec4(isnan(b)), vec4(1.0));\n  \n  result.r = isNaN.r > 0. ? NAN : result.r;\n  result.g = isNaN.g > 0. ? NAN : result.g;\n  result.b = isNaN.b > 0. ? NAN : result.b;\n  result.a = isNaN.a > 0. ? NAN : result.a;\n\n  return result;\n",cpuKernelImpl:On}),ys={kernelName:n.Minimum,backendName:"webgl",kernelFunc:ks};class ws{constructor(e,n,t){this.variableNames=["x"],this.outputShape=n.map((n,t)=>n[0]+e[t]+n[1]);const a=e.length,r=Ye(a),o=n.map(e=>e[0]).join(","),s=n.map((n,t)=>n[0]+e[t]).join(","),i=["coords[0]","coords[1]","coords[2]","coords[3]"].slice(0,a),u="reflect"===t?0:1;this.userCode=1!==a?`\n      ${r} start = ${r}(${o});\n      ${r} end = ${r}(${s});\n\n      void main() {\n        ${r} outC = getOutputCoords();\n        for (int i = 0; i < ${a}; i++) {\n          if (outC[i] < start[i]) {\n            outC[i] = start[i] * 2 - outC[i] - ${u};\n          } else if(outC[i] >= end[i]) {\n            outC[i] = (end[i] - 1) * 2 - outC[i] + ${u};\n          }\n        }\n        ${r} coords = outC - start;\n        setOutput(getX(${i}));\n      }\n    `:`\n        int start = ${o};\n        int end = ${s};\n\n        void main() {\n          int outC = getOutputCoords();\n          if (outC < start) {\n            outC = start * 2 - outC - ${u};\n          } else if(outC >= end) {\n            outC = (end - 1) * 2 - outC + ${u};\n          }\n          setOutput(getX(outC - start));\n        }\n      `}}class Ts{constructor(e,n,t){this.variableNames=["x"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=n.map((n,t)=>n[0]+e[t]+n[1]);const a=e.length,r=Ye(a),o=n.map(e=>e[0]).join(","),s=n.map((n,t)=>n[0]+e[t]).join(","),i=qn("rc",a),u=qn("source",a),l=`${i[a-1]} < ${this.outputShape[a-1]}`,c=1===a?"source":`vec2(${u.slice(-2).join()})`,d="reflect"===t?0:1;let p="";if(1===a){const e=`\n        ${r} source = rc;\n        if (source < start) {\n          source = start * 2 - source - ${d};\n        } else if (source >= end) {\n          source = (end - 1) * 2 - source + ${d};\n        }\n        source -= start;\n      `;p=`\n        ${r} rc = outputLoc;\n        ${e}\n        result[0] = getChannel(getX(${u.join()}), ${c});\n        ${i[a-1]} += 1;\n        if(${l}) {\n          ${e}\n          result[1] = getChannel(getX(${u.join()}), ${c});\n        }\n      `}else{const e=`\n        ${r} source = rc;\n        ${r} lt = ${r}(lessThan(source, start));\n        ${r} gte = ${r}(greaterThanEqual(source, end));\n        ${r} orig = 1 - (lt + gte);\n        source = orig * source +\n                lt * (start * 2 - source - ${d}) +\n                gte * ((end - 1) * 2 - source + ${d});\n        source -= start;\n      `;p=`\n        ${r} rc = outputLoc;\n        ${e}\n        result[0] = getChannel(getX(${u.join()}), ${c});\n        ${i[a-1]} += 1;\n        if(${l}) {\n          ${e}\n          result[1] = getChannel(getX(${u.join()}), ${c});\n        }\n        rc = outputLoc;\n        ${i[a-2]} += 1;\n        if(${i[a-2]} < ${this.outputShape[a-2]}) {\n          ${e}\n          result[2] = getChannel(getX(${u.join()}), ${c});\n          ${i[a-1]} += 1;\n          if(${l}) {\n            ${e}\n            result[3] = getChannel(getX(${u.join()}), ${c});\n          }\n        }\n      `}this.userCode=`\n      const ${r} start = ${r}(${o});\n      const ${r} end = ${r}(${s});\n\n      void main() {\n        ${r} outputLoc = getOutputCoords();\n        vec4 result = vec4(0.);\n        ${p}\n        setOutput(result);\n      }\n    `}}const Es={kernelName:n.MirrorPad,backendName:"webgl",kernelFunc:({inputs:e,backend:t,attrs:a})=>{const{x:r}=e,{paddings:o,mode:s}=a,i=n.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new Ts(r.shape,o,s):new ws(r.shape,o,s);return t.runWebGLProgram(i,[r],r.dtype)}},Ns=wt({opSnippet:"if (b == 0.0) return NAN;\n  return mod(a, b);",packedOpSnippet:"\n  vec4 result = mod(a, b);\n  vec4 isNaN = vec4(equal(b, vec4(0.0)));\n  \n  result.r = isNaN.r > 0. ? NAN : result.r;\n  result.g = isNaN.g > 0. ? NAN : result.g;\n  result.b = isNaN.b > 0. ? NAN : result.b;\n  result.a = isNaN.a > 0. ? NAN : result.a;\n\n  return result;\n"}),Ss={kernelName:n.Mod,backendName:"webgl",kernelFunc:Ns};class As{constructor(e,n,t){this.variableNames=["probs"],this.outputShape=[e,t],this.userCode=`\n      uniform float seed;\n\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n\n        float r = random(seed);\n        float cdf = 0.0;\n\n        for (int i = 0; i < ${n-1}; i++) {\n          cdf += getProbs(batch, i);\n\n          if (r < cdf) {\n            setOutput(float(i));\n            return;\n          }\n        }\n\n        // If no other event happened, last event happened.\n        setOutput(float(${n-1}));\n      }\n    `}getCustomSetupFunc(e){return(n,t)=>{null==this.seedLoc&&(this.seedLoc=n.getUniformLocation(t,"seed")),n.gl.uniform1f(this.seedLoc,e)}}}const Fs=wt({opSnippet:"\nif (a == b) {\n  return 1.0;\n};\nreturn a / b;",packedOpSnippet:"\n  // vec4 one = vec4(equal(a, b));\n  // return one + (vec4(1.0) - one) * a / b;\n  vec4 result = a / b;\n  if(a.x == b.x) {\n    result.x = 1.;\n  }\n  if(a.y == b.y) {\n    result.y = 1.;\n  }\n  if(a.z == b.z) {\n    result.z = 1.;\n  }\n  if(a.w == b.w) {\n    result.w = 1.;\n  }\n\n  return result;\n",checkOutOfBounds:!0}),_s={kernelName:n.RealDiv,backendName:"webgl",kernelFunc:Fs},Os="return a - b;",Ds=wt({opSnippet:Os,packedOpSnippet:Os,supportsComplex:!0,cpuKernelImpl:Un}),Ps={kernelName:n.Sub,backendName:"webgl",kernelFunc:Ds};function Ls(e){const{inputs:t,backend:a,attrs:r}=e,{logits:o}=t,{dim:s}=r,i=n.util.parseAxisParam([s],o.shape),u=ds({inputs:{x:o},backend:a,attrs:{reductionIndices:i,keepDims:!1}}),l=n.backend_util.expandShapeToKeepDim(u.shape,i),c=Dt({inputs:{x:u},backend:a,attrs:{shape:l}}),d=Ds({inputs:{a:o,b:c},backend:a}),p=ao({inputs:{x:d},backend:a}),h=Ut({inputs:{x:p},backend:a,attrs:{axis:i,keepDims:!1}}),f=Dt({inputs:{x:h},backend:a,attrs:{shape:l}}),x=Fs({inputs:{a:p,b:f},backend:a});return a.disposeIntermediateTensorInfo(u),a.disposeIntermediateTensorInfo(c),a.disposeIntermediateTensorInfo(d),a.disposeIntermediateTensorInfo(p),a.disposeIntermediateTensorInfo(h),a.disposeIntermediateTensorInfo(f),x}const Bs={kernelName:n.Softmax,backendName:"webgl",kernelFunc:Ls};const Vs={kernelName:n.Multinomial,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{logits:r}=n,{numSamples:o,seed:s,normalized:i}=a,u=i?r:Ls({inputs:{logits:r},backend:t,attrs:{dim:r.shape.length-1}}),l=u.shape[0],c=u.shape[1],d=new As(l,c,o),p=d.getCustomSetupFunc(s),h=t.runWebGLProgram(d,[u],"int32",p);return i||t.disposeIntermediateTensorInfo(u),h}},Ws="return -x;";const Ms={kernelName:n.Neg,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a}=e,{x:r}=t;if(a.shouldExecuteOnCPU([r])){const e=a.texData.get(r.dataId),[n,t]=Pn(e.values,r.shape,r.dtype);return a.makeTensorInfo(t,r.dtype,n)}let o;return o=n.env().getBool("WEBGL_PACK_UNARY_OPERATIONS")?new st(r.shape,Ws):new tt(r.shape,Ws),a.runWebGLProgram(o,[r],r.dtype)}},Gs=n.kernel_impls.nonMaxSuppressionV3Impl;const Us={kernelName:n.NonMaxSuppressionV3,backendName:"webgl",kernelFunc:function(e){n.backend_util.warn("tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead");const{inputs:t,backend:a,attrs:r}=e,{boxes:o,scores:s}=t,{maxOutputSize:i,iouThreshold:u,scoreThreshold:l}=r,c=a.readSync(o.dataId),d=a.readSync(s.dataId),{selectedIndices:p}=Gs(c,d,i,u,l);return a.makeTensorInfo([p.length],"int32",new Int32Array(p))}},zs=n.kernel_impls.nonMaxSuppressionV4Impl;const Xs={kernelName:n.NonMaxSuppressionV4,backendName:"webgl",kernelFunc:function(e){n.backend_util.warn("tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead");const{inputs:t,backend:a,attrs:r}=e,{boxes:o,scores:s}=t,{maxOutputSize:i,iouThreshold:u,scoreThreshold:l,padToMaxOutputSize:c}=r,d=a.readSync(o.dataId),p=a.readSync(s.dataId),{selectedIndices:h,validOutputs:f}=zs(d,p,i,u,l,c);return[a.makeTensorInfo([h.length],"int32",new Int32Array(h)),a.makeTensorInfo([],"int32",new Int32Array([f]))]}},Hs=n.kernel_impls.nonMaxSuppressionV5Impl;const js={kernelName:n.NonMaxSuppressionV5,backendName:"webgl",kernelFunc:function(e){n.backend_util.warn("tf.nonMaxSuppression() in webgl locks the UI thread. Call tf.nonMaxSuppressionAsync() instead");const{inputs:t,backend:a,attrs:r}=e,{boxes:o,scores:s}=t,{maxOutputSize:i,iouThreshold:u,scoreThreshold:l,softNmsSigma:c}=r,d=a.readSync(o.dataId),p=a.readSync(s.dataId),h=i,f=u,x=l,g=c,{selectedIndices:m,selectedScores:b}=Hs(d,p,h,f,x,g);return[a.makeTensorInfo([m.length],"int32",new Int32Array(m)),a.makeTensorInfo([b.length],"float32",new Float32Array(b))]}};class Ks{constructor(e,n,t,a){this.variableNames=["indices"],this.outputShape=[e,n],this.userCode=`\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int index = round(getIndices(coords.x));\n        setOutput(mix(float(${a}), float(${t}),\n                      float(index == coords.y)));\n      }\n    `}}const qs={kernelName:n.OneHot,backendName:"webgl",kernelFunc:e=>{const{inputs:t,backend:a,attrs:r}=e,{indices:o}=t,{depth:s,onValue:i,offValue:u}=r,l=n.util.sizeFromShape(o.shape),c=new Ks(l,s,i,u),d=Dt({inputs:{x:o},backend:a,attrs:{shape:[l]}}),p=a.runWebGLProgram(c,[d],o.dtype);a.disposeIntermediateTensorInfo(d);const h=Dt({inputs:{x:p},backend:a,attrs:{shape:[...o.shape,s]}});return a.disposeIntermediateTensorInfo(p),h}};function Ys(e){const{inputs:n,backend:t}=e,{x:a}=n;if("complex64"===a.dtype){const e=za({inputs:{input:a},backend:t}),n=Ys({inputs:{x:e},backend:t}),r=or({inputs:{input:a},backend:t}),o=Ys({inputs:{x:r},backend:t}),s=mt({inputs:{real:n,imag:o},backend:t});return t.disposeIntermediateTensorInfo(e),t.disposeIntermediateTensorInfo(n),t.disposeIntermediateTensorInfo(r),t.disposeIntermediateTensorInfo(o),s}return xo({attrs:{shape:a.shape,dtype:a.dtype,value:"string"===a.dtype?"":0},backend:t})}const Qs={kernelName:n.ZerosLike,backendName:"webgl",kernelFunc:Ys};const Zs={kernelName:n.OnesLike,backendName:"webgl",kernelFunc:function e(n){const{inputs:t,backend:a}=n,{x:r}=t;if("string"===r.dtype)throw new Error("onesLike is not supported under string dtype");if("complex64"===r.dtype){const n=za({inputs:{input:r},backend:a}),t=e({inputs:{x:n},backend:a}),o=or({inputs:{input:r},backend:a}),s=Ys({inputs:{x:o},backend:a}),i=mt({inputs:{real:t,imag:s},backend:a});return a.disposeIntermediateTensorInfo(n),a.disposeIntermediateTensorInfo(t),a.disposeIntermediateTensorInfo(o),a.disposeIntermediateTensorInfo(s),i}return xo({attrs:{shape:r.shape,dtype:r.dtype,value:1},backend:a})}};const Js={kernelName:n.Pack,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{axis:o}=r;if(1===t.length)return oo({inputs:{input:t[0]},backend:a,attrs:{dim:o}});const s=t[0].shape,i=t[0].dtype;t.forEach(e=>{n.util.assertShapesMatch(s,e.shape,"All tensors passed to stack must have matching shapes"),n.util.assert(i===e.dtype,()=>"All tensors passed to stack must have matching dtypes")});const u=[],l=ur({inputs:t.map(e=>{const n=oo({inputs:{input:e},backend:a,attrs:{dim:o}});return u.push(n),n}),backend:a,attrs:{axis:o}});return u.forEach(e=>a.disposeIntermediateTensorInfo(e)),l}};class ei{constructor(e,n,t){this.variableNames=["x"],this.outputShape=n.map((n,t)=>n[0]+e[t]+n[1]);const a=e.length,r=Ye(a),o=n.map(e=>e[0]).join(","),s=n.map((n,t)=>n[0]+e[t]).join(","),i=["coords[0]","coords[1]","coords[2]","coords[3]"].slice(0,a);this.userCode=1!==a?`\n      ${r} start = ${r}(${o});\n      ${r} end = ${r}(${s});\n\n      void main() {\n        ${r} outC = getOutputCoords();\n        if (any(lessThan(outC, start)) || any(greaterThanEqual(outC, end))) {\n          setOutput(float(${t}));\n        } else {\n          ${r} coords = outC - start;\n          setOutput(getX(${i}));\n        }\n      }\n    `:`\n        int start = ${o};\n        int end = ${s};\n\n        void main() {\n          int outC = getOutputCoords();\n          if (outC < start || outC >= end) {\n            setOutput(float(${t}));\n          } else {\n            setOutput(getX(outC - start));\n          }\n        }\n      `}}class ni{constructor(e,n,t){this.variableNames=["x"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=n.map((n,t)=>n[0]+e[t]+n[1]);const a=e.length,r=Ye(a),o=n.map(e=>e[0]).join(","),s=n.map((n,t)=>n[0]+e[t]).join(","),i=qn("rc",a),u=qn("source",a),l=`${i[a-1]} < ${this.outputShape[a-1]}`,c=1===a?"source":`vec2(${u.slice(-2).join()})`,d=[`${r} rc = outputLoc;`,`${i[a-1]} += 1;\n       if(${l}) {\n      `,1===a?"":`}\n       rc = outputLoc;\n       ${i[a-2]} += 1;\n       if(${i[a-2]} < ${this.outputShape[a-2]}) {`,1===a?"":`  ${i[a-1]} += 1;\n         if(${l}) {`],p=1===a?"rc < start || rc >= end":"any(lessThan(rc, start)) || any(greaterThanEqual(rc, end))";let h="";for(let e=0,n=1===a?2:4;e<n;e++)h+=`\n        ${d[e]}\n        if (${p}) {\n          result[${e}] = float(${t});\n        } else {\n          ${r} source = rc - start;\n          result[${e}] = getChannel(getX(${u.join()}), ${c});\n        }\n      `;h+=1===a?"} ":"}}",this.userCode=`\n      const ${r} start = ${r}(${o});\n      const ${r} end = ${r}(${s});\n\n      void main() {\n        ${r} outputLoc = getOutputCoords();\n        vec4 result = vec4(0.);\n        ${h}\n        setOutput(result);\n      }\n    `}}const ti=e=>{const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{paddings:s,constantValue:i}=r,u=n.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new ni(o.shape,s,i):new ei(o.shape,s,i);return a.runWebGLProgram(u,[o],o.dtype)},ai={kernelName:n.PadV2,backendName:"webgl",kernelFunc:ti},ri=wt({opSnippet:"\n  if(a < 0.0 && floor(b) < b){\n    return NAN;\n  }\n  if (b == 0.0) {\n    return 1.0;\n  }\n  return (round(mod(b, 2.0)) != 1) ?\n      pow(abs(a), b) : sign(a) * pow(abs(a), b);\n",packedOpSnippet:"\n  // isModRound1 has 1 for components with round(mod(b, 2.0)) == 1, 0 otherwise.\n  vec4 isModRound1 = vec4(equal(round(mod(b, 2.0)), ivec4(1)));\n  vec4 multiplier = sign(a) * isModRound1 + (vec4(1.0) - isModRound1);\n  vec4 result = multiplier * pow(abs(a), b);\n\n  // Ensure that a^0 = 1, including 0^0 = 1 as this correspond to TF and JS\n  bvec4 isExpZero = equal(b, vec4(0.0));\n  result.r = isExpZero.r ? 1.0 : result.r;\n  result.g = isExpZero.g ? 1.0 : result.g;\n  result.b = isExpZero.b ? 1.0 : result.b;\n  result.a = isExpZero.a ? 1.0 : result.a;\n\n  vec4 isNaN = vec4(lessThan(a, vec4(0.0))) * vec4(lessThan(floor(b), b));\n  \n  result.r = isNaN.r > 0. ? NAN : result.r;\n  result.g = isNaN.g > 0. ? NAN : result.g;\n  result.b = isNaN.b > 0. ? NAN : result.b;\n  result.a = isNaN.a > 0. ? NAN : result.a;\n\n  return result;\n"}),oi={kernelName:n.Pow,backendName:"webgl",kernelFunc:ri};const si={kernelName:n.Prod,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{axis:s,keepDims:i}=r,u=o.shape.length,l=[],c=n.util.parseAxisParam(s,o.shape);let d=c;const p=n.backend_util.getAxesPermutation(d,u);let h,f=o;if(null!=p&&(f=Xt({inputs:{x:o},backend:a,attrs:{perm:p}}),d=n.backend_util.getInnerMostAxes(d.length,u),l.push(f)),n.backend_util.assertAxesAreInnerMostDims("prod",d,u),a.shouldExecuteOnCPU([f])){const e=a.texData.get(f.dataId).values,{outVals:n,outShape:t,outDtype:r}=Ln(f.shape,f.dtype,e,d);h=a.makeTensorInfo(t,r,n)}else{const[e,t]=n.backend_util.computeOutAndReduceShapes(f.shape,d),r=n.util.sizeFromShape(t),s=Dt({inputs:{x:f},backend:a,attrs:{shape:[-1,r]}}),i=Vt(s,n.sumOutType(o.dtype),"prod",a);h=Dt({inputs:{x:i},backend:a,attrs:{shape:e}}),l.push(s),l.push(i)}if(i){l.push(h);const e=n.backend_util.expandShapeToKeepDim(h.shape,c);h=Dt({inputs:{x:h},backend:a,attrs:{shape:e}})}return l.forEach(e=>a.disposeIntermediateTensorInfo(e)),h}},ii=e=>{const{backend:n,attrs:t}=e,{start:a,stop:r,step:o,dtype:s}=t,i=Bn(a,r,o,s);return n.makeTensorInfo([i.length],s,i)},ui={kernelName:n.Range,backendName:"webgl",kernelFunc:ii},li=yt({opSnippet:"return 1.0 / x;"}),ci={kernelName:n.Reciprocal,backendName:"webgl",kernelFunc:li},di=yt({opSnippet:"if (isnan(x)) return x;\n  return (x < 0.0) ? 0.0 : x;\n",packedOpSnippet:"\n  vec4 result = x * vec4(greaterThanEqual(x, vec4(0.0)));\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n"}),pi={kernelName:n.Relu,backendName:"webgl",kernelFunc:di},hi=yt({opSnippet:"if (isnan(x)) return x;\n  return (x < 0.0) ? 0.0 : min(6.0, x);\n",packedOpSnippet:"\n  vec4 result = min(x, vec4(6.)) * vec4(greaterThanEqual(x, vec4(0.0)));\n  bvec4 isNaN = isnan(x);\n\n  result.r = isNaN.r ? x.r : result.r;\n  result.g = isNaN.g ? x.g : result.g;\n  result.b = isNaN.b ? x.b : result.b;\n  result.a = isNaN.a ? x.a : result.a;\n\n  return result;\n"}),fi={kernelName:n.Relu6,backendName:"webgl",kernelFunc:hi};class xi{constructor(e,n,t,a,r){this.variableNames=["A"],this.outputShape=[];const[o,s,i,u]=e;this.outputShape=[o,n,t,u];const l=[a&&n>1?s-1:s,a&&t>1?i-1:i],c=[a&&n>1?n-1:n,a&&t>1?t-1:t];let d;d=r?"(vec2(yRC) + vec2(0.5)) * effectiveInputOverOutputRatioRC - vec2(0.5)":"vec2(yRC) * effectiveInputOverOutputRatioRC",this.userCode=`\n      const vec2 effectiveInputOverOutputRatioRC = vec2(\n          ${l[0]/c[0]},\n          ${l[1]/c[1]});\n      const vec2 inputShapeRC = vec2(${s}.0, ${i}.0);\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        ivec2 yRC = coords.yz;\n\n        // Fractional source index.\n        vec2 sourceFracIndexRC = ${d};\n\n        // Compute the four integer indices.\n        ivec2 sourceFloorRC = ivec2(max(sourceFracIndexRC, vec2(0.0)));\n        ivec2 sourceCeilRC = ivec2(\n          min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));\n\n        float topLeft = getA(b, sourceFloorRC.x, sourceFloorRC.y, d);\n        float bottomLeft = getA(b, sourceCeilRC.x, sourceFloorRC.y, d);\n        float topRight = getA(b, sourceFloorRC.x, sourceCeilRC.y, d);\n        float bottomRight = getA(b, sourceCeilRC.x, sourceCeilRC.y, d);\n\n        vec2 fracRC = sourceFracIndexRC - vec2(sourceFloorRC);\n\n        float top = topLeft + (topRight - topLeft) * fracRC.y;\n        float bottom = bottomLeft + (bottomRight - bottomLeft) * fracRC.y;\n        float newValue = top + (bottom - top) * fracRC.x;\n\n        setOutput(newValue);\n      }\n    `}}class gi{constructor(e,n,t,a,r){this.variableNames=["A"],this.packedInputs=!0,this.packedOutput=!0,this.outputShape=[];const[o,s,i,u]=e;this.outputShape=[o,n,t,u];const l=[a&&n>1?s-1:s,a&&t>1?i-1:i],c=[a&&n>1?n-1:n,a&&t>1?t-1:t];let d;d=r?"(vec3(yRC) + vec3(0.5)) * effectiveInputOverOutputRatioRC - vec3(0.5)":"vec3(yRC) * effectiveInputOverOutputRatioRC",this.userCode=`\n      const vec3 effectiveInputOverOutputRatioRC = vec3(\n          ${l[0]/c[0]},\n          ${l[1]/c[1]},\n          ${l[1]/c[1]});\n      const vec3 inputShapeRC = vec3(${s}.0, ${i}.0,\n                                     ${i}.0);\n\n      float getAValue(int b, int r, int c, int d) {\n        return getChannel(getA(b, r, c, d), vec2(c, d));\n      }\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        // Calculate values for next column in yRC.z.\n        ivec3 yRC = coords.yzz + ivec3(0, 0, 1);\n\n        // Fractional source index.\n        vec3 sourceFracIndexRC = ${d};\n\n        // Compute the four integer indices.\n        ivec3 sourceFloorRC = ivec3(max(sourceFracIndexRC, vec3(0.0)));\n        ivec3 sourceCeilRC = ivec3(\n          min(inputShapeRC - 1.0, ceil(sourceFracIndexRC)));\n\n        // Should we calculate next column and row elements in 2x2 packed cell.\n        bool hasNextCol = d < ${u-1};\n        bool hasNextRow = coords.z < ${t-1};\n\n        // In parallel, construct four corners for all four components in\n        // packed 2x2 cell.\n        vec4 topLeft = vec4(\n          getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d),\n          hasNextCol ? getAValue(b, sourceFloorRC.x, sourceFloorRC.y, d + 1)\n                     : 0.0,\n          hasNextRow ? getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d)\n                     : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getAValue(b, sourceFloorRC.x, sourceFloorRC.z, d + 1) : 0.0);\n\n        vec4 bottomLeft = vec4(\n          getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d),\n          hasNextCol ? getAValue(b, sourceCeilRC.x, sourceFloorRC.y, d + 1)\n                     : 0.0,\n          hasNextRow ? getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d)\n                     : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getAValue(b, sourceCeilRC.x, sourceFloorRC.z, d + 1) : 0.0);\n\n        vec4 topRight = vec4(\n          getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d),\n          hasNextCol ? getAValue(b, sourceFloorRC.x, sourceCeilRC.y, d + 1)\n                     : 0.0,\n          hasNextRow ? getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d)\n                     : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getAValue(b, sourceFloorRC.x, sourceCeilRC.z, d + 1) : 0.0);\n\n        vec4 bottomRight = vec4(\n          getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d),\n          hasNextCol ? getAValue(b, sourceCeilRC.x, sourceCeilRC.y, d + 1)\n                     : 0.0,\n          hasNextRow ? getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d)\n                     : 0.0,\n          (hasNextRow && hasNextCol) ?\n            getAValue(b, sourceCeilRC.x, sourceCeilRC.z, d + 1) : 0.0);\n\n        vec3 fracRC = sourceFracIndexRC - vec3(sourceFloorRC);\n\n        vec4 top = mix(topLeft, topRight, fracRC.yyzz);\n        vec4 bottom = mix(bottomLeft, bottomRight, fracRC.yyzz);\n        vec4 newValue = mix(top, bottom, fracRC.x);\n\n        setOutput(newValue);\n      }\n    `}}const mi={kernelName:n.ResizeBilinear,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{images:o}=t,{alignCorners:s,halfPixelCenters:i,size:u}=r,[l,c]=u,d=n.env().getBool("WEBGL_PACK_IMAGE_OPERATIONS")?new gi(o.shape,l,c,s,i):new xi(o.shape,l,c,s,i);return a.runWebGLProgram(d,[o],"float32")}};class bi{constructor(e,n,t){this.variableNames=["dy"],this.outputShape=[],this.outputShape=n;const[,a,r]=n,[,o,s]=e,i=[t&&o>1?a-1:a,t&&s>1?r-1:r],u=[t&&o>1?o-1:o,t&&s>1?s-1:s],l=i[0]/u[0],c=i[1]/u[1],d=1/l,p=1/c,h=2*Math.ceil(d)+2,f=2*Math.ceil(p)+2;this.userCode=`\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        int r = coords[1];\n        int c = coords[2];\n\n        float accumulator = 0.0;\n\n        const float heightScale = float(${l});\n        const float widthScale = float(${c});\n\n        const float invHeightScale = float(${d});\n        const float invWidthScale = float(${p});\n\n        const int winHeight = int(${h});\n        const int winWidth = int(${f});\n\n        // Compute bounds for where in dy we will look\n        float startRLerp = floor(float(r) * invHeightScale);\n        int startDyR = int(startRLerp - float(winHeight / 2));\n\n        float startCLerp = floor(float(c) * invWidthScale);\n        int startDyC = int(startCLerp - float(winWidth / 2));\n\n        // Loop over dy\n        for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {\n          int dyR = dyROffset + startDyR;\n\n          // Guard against the window exceeding the bounds of dy\n          if (dyR < 0 || dyR >= ${o}) {\n            continue;\n          }\n\n          for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {\n            int dyC = dyCOffset + startDyC;\n\n            // Guard against the window exceeding the bounds of dy\n            if (dyC < 0 || dyC >= ${s}) {\n              continue;\n            }\n\n            float dxR = float(dyR) * heightScale;\n            int topDxRIndex = int(floor(dxR));\n            int bottomDxRIndex = int(min(ceil(dxR), ${a-1}.0));\n            float dxRLerp = dxR - float(topDxRIndex);\n            float inverseDxRLerp = 1.0 - dxRLerp;\n\n            float dxC = float(dyC) * widthScale;\n            int leftDxCIndex = int(floor(dxC));\n            int rightDxCIndex = int(min(ceil(dxC), ${r-1}.0));\n            float dxCLerp = dxC - float(leftDxCIndex);\n            float inverseDxCLerp = 1.0 - dxCLerp;\n\n            if (r == topDxRIndex && c == leftDxCIndex) {\n              // topLeft\n              accumulator +=\n                getDy(b, dyR, dyC, d) * inverseDxRLerp * inverseDxCLerp;\n            }\n\n            if (r == topDxRIndex && c == rightDxCIndex) {\n              // topRight\n              accumulator += getDy(b, dyR, dyC, d) * inverseDxRLerp * dxCLerp;\n            }\n\n            if (r == bottomDxRIndex && c == leftDxCIndex) {\n              // bottomLeft\n              accumulator += getDy(b, dyR, dyC, d) * dxRLerp * inverseDxCLerp;\n            }\n\n            if (r == bottomDxRIndex && c == rightDxCIndex) {\n              // bottomRight\n              accumulator += getDy(b, dyR, dyC, d) * dxRLerp * dxCLerp;\n            }\n          }\n        }\n        // End loop over dy\n\n        setOutput(accumulator);\n      }\n    `}}const vi={kernelName:n.ResizeBilinearGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{images:r,dy:o}=n,{alignCorners:s}=a,i=new bi(o.shape,r.shape,s);return t.runWebGLProgram(i,[o],o.dtype)}};class Ci{constructor(e,n,t,a,r){this.variableNames=["A"],this.outputShape=[];const[o,s,i,u]=e;this.outputShape=[o,n,t,u];const l=[a&&n>1?s-1:s,a&&t>1?i-1:i],c=[a&&n>1?n-1:n,a&&t>1?t-1:t],d=a?"0.5":"0.0";let p;p=r?"max((vec2(yRC) + vec2(0.5)) * effectiveInputOverOutputRatioRC, vec2(0.0))":"vec2(yRC) * effectiveInputOverOutputRatioRC",this.userCode=`\n      const vec2 effectiveInputOverOutputRatioRC = vec2(\n          ${l[0]/c[0]},\n          ${l[1]/c[1]});\n      const vec2 inputShapeRC = vec2(${s}.0, ${i}.0);\n\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        ivec2 yRC = coords.yz;\n\n        // Fractional source index.\n        vec2 sourceFracIndexRC = ${p};\n\n        // Compute the coordinators of nearest neighbor point.\n        ivec2 sourceNearestRC = ivec2(\n          min(inputShapeRC - 1.0, floor(sourceFracIndexRC + ${d})));\n        float newValue = getA(b, sourceNearestRC.x, sourceNearestRC.y, d);\n\n        setOutput(newValue);\n      }\n    `}}const $i={kernelName:n.ResizeNearestNeighbor,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{images:r}=n,{alignCorners:o,halfPixelCenters:s,size:i}=a,[u,l]=i,c=new Ci(r.shape,u,l,o,s);return t.runWebGLProgram(c,[r],r.dtype)}};class Ii{constructor(e,n,t){this.variableNames=["dy"],this.outputShape=[],this.outputShape=n;const[,a,r]=n,[,o,s]=e,i=[t&&o>1?a-1:a,t&&s>1?r-1:r],u=[t&&o>1?o-1:o,t&&s>1?s-1:s],l=i[0]/u[0],c=i[1]/u[1],d=1/l,p=1/c,h=2*Math.ceil(d)+2,f=2*Math.ceil(p)+2;this.userCode=`\n      void main() {\n        ivec4 coords = getOutputCoords();\n        int b = coords[0];\n        int d = coords[3];\n        int r = coords[1];\n        int c = coords[2];\n\n        float accumulator = 0.0;\n\n        const float heightScale = float(${l});\n        const float widthScale = float(${c});\n\n        const float invHeightScale = float(${d});\n        const float invWidthScale = float(${p});\n\n        const int winHeight = int(${h});\n        const int winWidth = int(${f});\n\n        // Compute bounds for where in dy we will look\n        float startRLerp = floor(float(r) * invHeightScale);\n        int startDyR = int(floor(startRLerp - float(winHeight / 2)));\n\n        float startCLerp = floor(float(c) * invWidthScale);\n        int startDyC = int(floor(startCLerp - float(winWidth / 2)));\n\n        // Loop over dy\n        for (int dyROffset = 0; dyROffset < winHeight; dyROffset++) {\n          int dyR = dyROffset + startDyR;\n\n          // Guard against the window exceeding the bounds of dy\n          if (dyR < 0 || dyR >= ${o}) {\n            continue;\n          }\n\n          for (int dyCOffset = 0; dyCOffset < winWidth; dyCOffset++) {\n            int dyC = dyCOffset + startDyC;\n\n            // Guard against the window exceeding the bounds of dy\n            if (dyC < 0 || dyC >= ${s}) {\n              continue;\n            }\n\n            float sourceFracRow =\n              float(${i[0]}) *\n                (float(dyR) / float(${u[0]}));\n\n            float sourceFracCol =\n                float(${i[1]}) *\n                  (float(dyC) / float(${u[1]}));\n\n            int sourceNearestRow = int(min(\n                float(int(${a}) - 1),\n                ${t} ? float(round(sourceFracRow)) :\n                                  float(floor(sourceFracRow))));\n\n            int sourceNearestCol = int(min(\n                float(int(${r}) - 1),\n                ${t} ? float(round(sourceFracCol)) :\n                                  float(floor(sourceFracCol))));\n\n            if (r == sourceNearestRow && c == sourceNearestCol) {\n              accumulator += getDy(b, dyR, dyC, d);\n            }\n          }\n        }\n        // End loop over dy\n\n        setOutput(accumulator);\n      }\n    `}}const Ri={kernelName:n.ResizeNearestNeighborGrad,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{images:r,dy:o}=n,{alignCorners:s}=a,i=new Ii(o.shape,r.shape,s);return t.runWebGLProgram(i,[o],o.dtype)}};class ki{constructor(e,n){this.variableNames=["x"];const t=e.length;if(t>4)throw new Error(`WebGL backend: Reverse of rank-${t} tensor is not yet supported`);if(this.outputShape=e,1===t)return void(this.userCode=`\n        void main() {\n          int coord = getOutputCoords();\n          setOutput(getX(${e[0]} - coord - 1));\n        }\n      `);const a=e.map((t,a)=>(t=>-1!==n.indexOf(t)&&1!==e[t]?`${e[t]} - coords[${t}] - 1`:`coords[${t}]`)(a)).join(","),r=Ye(t);this.userCode=`\n      void main() {\n        ${r} coords = getOutputCoords();\n        setOutput(getX(${a}));\n      }\n    `}}class yi{constructor(e,n){this.variableNames=["x"],this.packedInputs=!0,this.packedOutput=!0;const t=e.length;if(t>4)throw new Error(`WebGL backend: Reverse of rank-${t} tensor is not yet supported`);this.outputShape=e;const a=qn("rc",t),r=`${a[t-1]} + 1 < ${this.outputShape[t-1]}`,o=`${a[t-2]} + 1 < ${this.outputShape[t-2]}`,s=Ye(t);function i(t){const a=e.map((a,r)=>function(t,a){return-1!==n.indexOf(t)&&1!==e[t]?`${e[t]} - ${a[t]} - 1`:`${a[t]}`}(r,t));return`getChannel(getX(${a.join(",")}), vec2(${a.slice(-2).join(",")}))`}this.userCode=1===t?`\n        void main(){\n          int rc = getOutputCoords();\n          vec4 result = vec4(0.);\n          result.r = getChannel(getX(${e[0]} - rc - 1),\n            ${e[0]} - rc - 1);\n          if(${r}){\n              result.g = getChannel(getX(${e[0]} - (rc  + 1) - 1),\n                ${e[0]} - (rc  + 1) - 1);\n          }\n          setOutput(result);\n        }\n      `:`\n        void main() {\n          ${s} rc = getOutputCoords();\n          vec4 result = vec4(0.);\n          result.r = ${function(e){return i(e)}(a.slice())};\n          if(${r}){\n            result.g = ${function(e){return e[t-1]="("+e[t-1]+" + 1)",i(e)}(a.slice())};\n          }\n          if(${o}) {\n            result.b = ${function(e){return e[t-2]="("+e[t-2]+" + 1)",i(e)}(a.slice())};\n            if(${r}) {\n              result.a = ${function(e){return e[t-1]="("+e[t-1]+" + 1)",e[t-2]="("+e[t-2]+" + 1)",i(e)}(a.slice())};\n            }\n          }\n          setOutput(result);\n        }\n    `}}const wi={kernelName:n.Reverse,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{dims:s}=r,i=o.shape.length,u=n.util.parseAxisParam(s,o.shape);if(0===i)return xt({inputs:{x:o},backend:a});const l=n.env().getBool("WEBGL_PACK_ARRAY_OPERATIONS")?new yi(o.shape,u):new ki(o.shape,u);return a.runWebGLProgram(l,[o],o.dtype)}};class Ti{constructor(e,t,a,r){this.variableNames=["Image"],this.outputShape=[];const o=e[1],s=e[2],i=Math.sin(t).toFixed(3),u=Math.cos(t).toFixed(3);this.outputShape=e;const[l,c]=n.backend_util.getImageCenter(r,o,s),d=l.toFixed(3),p=c.toFixed(3);let h="";h="number"==typeof a?`float outputValue = ${a.toFixed(2)};`:`\n        vec3 fill = vec3(${a.join(",")});\n        float outputValue = fill[coords[3]];`,this.userCode=`\n        void main() {\n          ivec4 coords = getOutputCoords();\n          int x = coords[2];\n          int y = coords[1];\n          float coordXFloat = (float(x) - ${d}) * ${u} - (float(y) - ${p}) * ${i};\n          float coordYFloat = (float(x) - ${d}) * ${i} + (float(y) - ${p}) * ${u};\n          int coordX = int(round(coordXFloat + ${d}));\n          int coordY = int(round(coordYFloat + ${p}));\n          ${h}\n          if(coordX >= 0 && coordX < ${s} && coordY >= 0 && coordY < ${o}) {\n            outputValue = getImage(coords[0], coordY, coordX, coords[3]);\n          }\n          setOutput(outputValue);\n        }\n    `}}const Ei={kernelName:n.RotateWithOffset,backendName:"webgl",kernelFunc:({inputs:e,attrs:n,backend:t})=>{const{image:a}=e,{radians:r,fillValue:o,center:s}=n,i=t,u=new Ti(a.shape,r,o,s);return i.runWebGLProgram(u,[a],a.dtype)}},Ni=yt({opSnippet:"\n  // OpenGL ES does not support round function.\n  // The algorithm is based on banker's rounding.\n  float base = floor(x);\n  if ((x - base) < 0.5) {\n    return floor(x);\n  } else if ((x - base) > 0.5) {\n    return ceil(x);\n  } else {\n    if (mod(base, 2.0) == 0.0) {\n      return base;\n    } else {\n      return base + 1.0;\n    }\n  }\n"}),Si={kernelName:n.Round,backendName:"webgl",kernelFunc:Ni},Ai=yt({opSnippet:"return inversesqrt(x);",cpuKernelImpl:Vn}),Fi={kernelName:n.Rsqrt,backendName:"webgl",kernelFunc:Ai};class _i{constructor(e,n,t,a,r,o,s=!0){this.variableNames=["updates","indices","defaultValue"],this.outputShape=o;const i=Ye(r.length),u=Ye(o.length);let l="";1===t?l="i":2===t&&(l="i, j");const c=`getIndices(${l})`;let d="";1===a?d="i":2===a&&(d="i, coords[1]");const p=`getUpdates(${d})`,h=n>1?"strides[j]":"strides";this.userCode=`\n        ${i} strides = ${i}(${r});\n\n        void main() {\n          ${u} coords = getOutputCoords();\n          float sum = 0.0;\n          bool found = false;\n          for (int i = 0; i < ${e}; i++) {\n            int flattenedIndex = 0;\n            for (int j = 0; j < ${n}; j++) {\n              int index = round(${c});\n              flattenedIndex += index * ${h};\n            }\n            if (flattenedIndex == coords[0]) {\n              sum += ${p};\n              found = true;\n            }\n          }\n          setOutput(mix(getDefaultValue(), sum, float(found)));\n        }\n      `}}const Oi={kernelName:n.ScatterNd,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{indices:o,updates:s}=t,{shape:i}=r,{sliceRank:u,numUpdates:l,sliceSize:c,strides:d,outputSize:p}=n.backend_util.calculateShapes(s,o,i),h=[p/c,c];if(0===p)return a.makeTensorInfo(i,o.dtype);const f=Dt({inputs:{x:o},backend:a,attrs:{shape:[l,u]}}),x=Dt({inputs:{x:s},backend:a,attrs:{shape:[l,c]}}),g=a.makeTensorInfo([],"float32",new Float32Array([0])),m=new _i(l,u,f.shape.length,x.shape.length,d,h),b=a.runWebGLProgram(m,[x,f,g],x.dtype),v=Dt({inputs:{x:b},backend:a,attrs:{shape:i}});return a.disposeIntermediateTensorInfo(f),a.disposeIntermediateTensorInfo(x),a.disposeIntermediateTensorInfo(b),a.disposeIntermediateTensorInfo(g),v}};class Di{constructor(e,n,t){let a,r;if(this.variableNames=["c","a","b"],this.outputShape=n,t>4)throw Error(`Where for rank ${t} is not yet supported`);if(1===t)r="resRC",a="resRC";else{const t=["resRC.x","resRC.y","resRC.z","resRC.w"],o=[],s=[];for(let a=0;a<n.length;a++)s.push(`${t[a]}`),a<e&&o.push(`${t[a]}`);a=o.join(),r=s.join()}const o=Ye(t);this.userCode=`\n      void main() {\n        ${o} resRC = getOutputCoords();\n        float cVal = getC(${a});\n        if (cVal >= 1.0) {\n          setOutput(getA(${r}));\n        } else {\n          setOutput(getB(${r}));\n        }\n      }\n    `}}const Pi={kernelName:n.Select,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a}=e,{condition:r,t:o,e:s}=t,i=new Di(r.shape.length,o.shape,o.shape.length);return a.runWebGLProgram(i,[r,o,s],n.upcastType(o.dtype,s.dtype))}},Li=yt({opSnippet:`\n  // Stable and Attracting Fixed Point (0, 1) for Normalized Weights.\n  // see: https://arxiv.org/abs/1706.02515\n  float scaleAlpha = ${n.backend_util.SELU_SCALEALPHA};\n  float scale = ${n.backend_util.SELU_SCALE};\n  return (x >= 0.0) ? scale * x : scaleAlpha * (exp(x) - 1.0);\n`}),Bi={kernelName:n.Selu,backendName:"webgl",kernelFunc:Li},Vi=yt({opSnippet:"return 1.0 / (1.0 + exp(-1.0 * x));"}),Wi={kernelName:n.Sigmoid,backendName:"webgl",kernelFunc:Vi},Mi=yt({opSnippet:"\n  if (isnan(x)) { return 0.0; }\n  return sign(x);\n"}),Gi={kernelName:n.Sign,backendName:"webgl",kernelFunc:Mi},Ui=yt({opSnippet:"if (isnan(x)) return x;\n  return sin(x);\n"}),zi={kernelName:n.Sin,backendName:"webgl",kernelFunc:Ui},Xi=yt({opSnippet:"\n  float e2x = exp(x);\n  return (e2x - 1.0 / e2x) / 2.0;\n"}),Hi={kernelName:n.Sinh,backendName:"webgl",kernelFunc:Xi},ji=yt({opSnippet:"\n  float epsilon = 1.1920928955078125e-7;\n  float threshold = log(epsilon) + 2.0;\n\n  bool too_large = x > -threshold;\n  bool too_small = x < threshold;\n\n  float result;\n  float exp_x = exp(x);\n\n  if (too_large){\n    result = x;\n  }\n  else if (too_small){\n    result = exp_x;\n  }\n  else{\n    result = log(exp_x + 1.0);\n  }\n  return result;\n"}),Ki={kernelName:n.Softplus,backendName:"webgl",kernelFunc:ji},qi={kernelName:n.SpaceToBatchND,backendName:"webgl",kernelFunc:e=>{const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{blockShape:s,paddings:i}=r;n.util.assert(o.shape.length<=4,()=>"spaceToBatchND for rank > 4 with a WebGL backend not implemented yet");const u=s.reduce((e,n)=>e*n),l=[[0,0]];l.push(...i);for(let e=1+s.length;e<o.shape.length;++e)l.push([0,0]);const c=[],d=ti({inputs:{x:o},backend:a,attrs:{paddings:l,constantValue:0}}),p=n.backend_util.getReshaped(d.shape,s,u,!1),h=n.backend_util.getPermuted(p.length,s.length,!1),f=n.backend_util.getReshapedPermuted(d.shape,s,u,!1),x=Dt({inputs:{x:d},backend:a,attrs:{shape:p}}),g=Xt({inputs:{x:x},backend:a,attrs:{perm:h}}),m=Dt({inputs:{x:g},backend:a,attrs:{shape:f}});return c.push(d),c.push(x),c.push(g),c.forEach(e=>a.disposeIntermediateTensorInfo(e)),m}};const Yi={kernelName:n.SparseToDense,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{sparseIndices:o,sparseValues:s,defaultValue:i}=t,{outputShape:u}=r,{sliceRank:l,numUpdates:c,strides:d,outputSize:p}=n.backend_util.calculateShapes(s,o,u),h=new _i(c,l,o.shape.length,s.shape.length,d,[p,1],!1),f=a.runWebGLProgram(h,[s,o,i],s.dtype),x=Dt({inputs:{x:f},backend:a,attrs:{shape:u}});return a.disposeIntermediateTensorInfo(f),x}};const Qi={kernelName:n.SplitV,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{numOrSizeSplits:s,axis:i}=r,u=n.util.parseAxisParam(i,o.shape)[0],l=n.backend_util.prepareSplitSize(o,s,u),c=o.shape.length,d=new Array(c).fill(0),p=o.shape.slice();return l.map(e=>{const n=[...p];n[u]=e;const t=Ba({inputs:{x:o},backend:a,attrs:{begin:d,size:n}});return d[u]+=e,t})}},Zi=yt({opSnippet:"return sqrt(x);"}),Ji={kernelName:n.Sqrt,backendName:"webgl",kernelFunc:Zi},eu=yt({opSnippet:"return x * x;"}),nu={kernelName:n.Square,backendName:"webgl",kernelFunc:eu},tu=wt({opSnippet:"return (a - b) * (a - b);",packedOpSnippet:"return (a - b) * (a - b);"}),au={kernelName:n.SquaredDifference,backendName:"webgl",kernelFunc:tu};const ru={kernelName:n.Step,backendName:"webgl",kernelFunc:function({inputs:e,attrs:n,backend:t}){const{x:a}=e,r=at+`\n    return x > 0.0 ? 1.0 : float(${n.alpha});\n  `,o=new tt(a.shape,r);return t.runWebGLProgram(o,[a],a.dtype)}};class ou{constructor(e,n,t){this.variableNames=["x"],this.outputShape=t;const a=t.length,r=Ye(t.length),o=Ye(t.length);let s="";if(1===a)s="coords * strides + begin";else{let e=0;s=t.map((n,a)=>(e++,1===t.length?`coords * strides[${a}] + begin[${a}]`:`coords[${e-1}] * strides[${a}] + begin[${a}]`)).join(",")}this.userCode=`\n      ${r} begin = ${r}(${e});\n      ${r} strides = ${r}(${n});\n\n      void main() {\n        ${o} coords = getOutputCoords();\n        setOutput(getX(${s}));\n      }\n    `}}const su={kernelName:n.StridedSlice,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{begin:s,end:i,strides:u,beginMask:l,endMask:c,ellipsisMask:d,newAxisMask:p,shrinkAxisMask:h}=r,{nonStrided:f,$begin:x,$strides:g,size:m,newShape:b,outShape:v}=n.slice_util.sliceInfo(o.shape,s,i,u,l,c,d,p,h),C=Dt({inputs:{x:o},backend:a,attrs:{shape:b}});let $;if(f){const e=Ba({inputs:{x:C},backend:a,attrs:{begin:x,size:m}});$=Dt({inputs:{x:e},backend:a,attrs:{shape:v}}),a.disposeIntermediateTensorInfo(e)}else if(v.some(e=>0===e))$=a.makeTensorInfo(v,o.dtype,[]);else{if(a.shouldExecuteOnCPU([C])){const e=a.texData.get(C.dataId).values,t=n.buffer(C.shape,C.dtype,e),r=Gn(v,t,g,x);$=a.makeTensorInfo(v,C.dtype,r.values)}else{const e=new ou(x,g,v);$=a.runWebGLProgram(e,[C],C.dtype)}}const I=Dt({inputs:{x:$},backend:a,attrs:{shape:v}});return a.disposeIntermediateTensorInfo(C),a.disposeIntermediateTensorInfo($),I}},iu=yt({opSnippet:"return tan(x);"}),uu={kernelName:n.Tan,backendName:"webgl",kernelFunc:iu},lu=yt({opSnippet:"\n  float e2x = exp(-2.0 * abs(x));\n  return sign(x) * (1.0 - e2x) / (1.0 + e2x);\n"}),cu={kernelName:n.Tanh,backendName:"webgl",kernelFunc:lu};class du{constructor(e,n){this.variableNames=["A"];const t=new Array(e.length);for(let a=0;a<t.length;a++)t[a]=e[a]*n[a];this.outputShape=t,this.rank=t.length;const a=Ye(this.rank),r=function(e){const n=e.length;if(n>5)throw Error(`Tile for rank ${n} is not yet supported`);if(1===n)return`imod(resRC, ${e[0]})`;const t=["resRC.x","resRC.y","resRC.z","resRC.w","resRC.u"],a=[];for(let n=0;n<e.length;n++)a.push(`imod(${t[n]}, ${e[n]})`);return a.join()}(e);this.userCode=`\n      void main() {\n        ${a} resRC = getOutputCoords();\n        setOutput(getA(${r}));\n      }\n    `}}function pu(e){const{inputs:t,backend:a,attrs:r}=e,{x:o}=t,{reps:s}=r;if("string"===o.dtype){const e=a.readSync(o.dataId).map(e=>n.util.decodeString(e)),t=n.buffer(o.shape,o.dtype,e),r=zn(t,s);return a.makeTensorInfo(r.shape,r.dtype,r.values)}const i=new du(o.shape,s);return a.runWebGLProgram(i,[o],o.dtype)}const hu={kernelName:n.Tile,backendName:"webgl",kernelFunc:pu};const fu={kernelName:n.TopK,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{x:r}=n,{k:o,sorted:s}=a,i=t.readSync(r.dataId),[u,l]=Xn(i,r.shape,r.dtype,o,s);return[t.makeTensorInfo(u.shape,u.dtype,u.values),t.makeTensorInfo(l.shape,l.dtype,l.values)]}};const xu={kernelName:n.Unique,backendName:"webgl",kernelFunc:function(e){const{inputs:n,attrs:t,backend:a}=e,{axis:r}=t,{x:o}=n;te(o,"unique"),console.warn("WARNING: ","UI might be locked temporarily as data is being downloaded");const s=a.readSync(o.dataId),{outputValues:i,outputShape:u,indices:l}=jn(s,r,o.shape,o.dtype);return[a.makeTensorInfo(u,o.dtype,i),a.makeTensorInfo([l.length],"int32",l)]}};const gu={kernelName:n.Unpack,backendName:"webgl",kernelFunc:function(e){const{inputs:n,backend:t,attrs:a}=e,{value:r}=n;let{axis:o}=a;o<0&&(o+=r.shape.length);const s=r,i=s.shape.length,u=r.shape[o],l=new Array(i-1);let c=0;for(let e=0;e<i;e++)e!==o&&(l[c++]=s.shape[e]);const d=[],p=new Array(i).fill(0),h=s.shape.slice();h[o]=1;const f=new Array(u);for(let e=0;e<f.length;e++){p[o]=e;const n=Ba({inputs:{x:s},backend:t,attrs:{begin:p,size:h}}),a=Dt({inputs:{x:n},backend:t,attrs:{shape:l}});f[e]=a,d.push(n)}return d.forEach(e=>t.disposeIntermediateTensorInfo(e)),f}};class mu{constructor(e,n){this.variableNames=["x","segmentIds"];const t=e.windowSize,a=e.batchSize,r=e.inSize,o=e.numSegments,s=o*Math.ceil(r/t);this.outputShape=[a,s];const i=4*Math.floor(t/4),u=t%4,l="\n        sumValue += dot(values, segFilter);\n    ";let c="";r%t>0&&(c=`\n        if (inIdx < 0 || inIdx >= ${r}) {\n          return initializationValue;\n        }\n      `);let d="";r%t>0&&(d=`\n        if (inIdx < 0 || inIdx >= ${r}) {\n          return -1.0;\n        }\n      `),this.userCode=`\n      const float initializationValue = 0.0;\n\n      float getValue(int batch, int inIdx) {\n        ${c}\n        return getX(batch, inIdx);\n      }\n\n      float getSegmentIdAtIndex(int inIdx) {\n        ${d}\n        return getSegmentIds(inIdx);\n      }\n\n      void main() {\n        ivec2 coords = getOutputCoords();\n        int batch = coords[0];\n        int outIdx = coords[1];\n        int inOffset = int(floor(float(outIdx) / float(\n          ${o})) * float(${t}));\n        int currentSeg = int(mod(float(outIdx), float(${o})));\n\n        float sumValue = 0.0;\n\n        for (int i = 0; i < ${i}; i += 4) {\n          int inIdx = inOffset + i;\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            getValue(batch, inIdx + 3)\n          );\n\n          vec4 segFilter = vec4(\n            int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 3)) == currentSeg ? 1 : 0\n          );\n\n          ${l}\n        }\n\n        int inIdx = inOffset + ${i};\n        if (${1===u}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            initializationValue,\n            initializationValue,\n            initializationValue\n          );\n\n          int inIdxSeg = int(getSegmentIdAtIndex(inIdx));\n\n          vec4 segFilter = vec4(\n            int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n            0,\n            0,\n            0\n          );\n\n          ${l}\n        } else if (${2===u}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            initializationValue,\n            initializationValue\n          );\n\n          vec4 segFilter = vec4(\n            int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n              0,\n              0\n          );\n\n          ${l}\n        } else if (${3===u}) {\n          vec4 values = vec4(\n            getValue(batch, inIdx),\n            getValue(batch, inIdx + 1),\n            getValue(batch, inIdx + 2),\n            initializationValue\n          );\n\n          vec4 segFilter = vec4(\n            int(getSegmentIdAtIndex(inIdx)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 1)) == currentSeg ? 1 : 0,\n            int(getSegmentIdAtIndex(inIdx + 2)) == currentSeg ? 1 : 0,\n            0\n          );\n\n          ${l}\n        }\n        setOutput(sumValue);\n      }\n    `}}const bu=[us,cs,Kt,qt,Qt,Jt,ta,oa,sa,ia,da,pa,fa,ga,Ca,ba,Ia,wa,ya,Na,Sa,Aa,Oa,Wa,Ma,Ha,qa,Za,nr,bt,lr,Cr,$r,xr,Rr,kr,Ir,wr,Er,Sr,Or,Dr,Lr,Ur,zr,Wr,Hr,Kr,Yr,Qr,Jr,no,ro,so,lo,ho,go,bo,$o,Ro,wo,Eo,No,Ao,_o,Do,Lo,gt,Bo,sr,Wo,Go,zo,$t,Ho,Ko,qo,Jo,Qo,ns,as,os,ps,gs,xs,vs,Cs,$s,fs,Is,Rs,ys,Es,Ss,Vs,Ot,Ms,Us,Xs,js,Ua,qs,Zs,Js,ai,oi,kt,si,ui,Xa,_s,ci,fi,pi,Pt,mi,vi,$i,Ri,wi,Ei,Si,Fi,Oi,Pi,Bi,Wi,Gi,zi,Hi,Va,Bs,Ki,qi,Yi,Qi,Ji,nu,au,ru,su,Ps,zt,uu,cu,hu,fu,Ht,xu,gu,{kernelName:n.UnsortedSegmentSum,backendName:"webgl",kernelFunc:function(e){const{inputs:t,backend:a,attrs:r}=e,{x:o,segmentIds:s}=t,{numSegments:i}=r,u=o.shape.length,l=[];let c=0;const d=n.backend_util.getAxesPermutation([c],u);let p=o;null!=d&&(p=Xt({inputs:{x:o},backend:a,attrs:{perm:d}}),l.push(p),c=n.backend_util.getInnerMostAxes(1,u)[0]);const h=n.backend_util.segment_util.computeOutShape(p.shape,c,i),f=n.util.sizeFromShape([p.shape[c]]),x=Dt({inputs:{x:p},backend:a,attrs:{shape:[-1,f]}});l.push(x);const g=n.sumOutType(o.dtype),m=(e,t,r,o,s)=>{const i=e.shape[0],u=e.shape[1],c=n.backend_util.segment_util.segOpComputeOptimalWindowSize(u,s),d=new mu({windowSize:c,inSize:u,batchSize:i,numSegments:s},t),p=a.compileAndRun(d,[e,r],o);if(l.push(p),p.shape[1]===s)return p;const h=ii({backend:a,attrs:{start:0,stop:s,step:1,dtype:"float32"}}),f=pu({inputs:{x:h},backend:a,attrs:{reps:[u/c]}});return l.push(h),l.push(f),m(p,t,f,o,s)},b=Dt({inputs:{x:m(x,"unsortedSegmentSum",s,g,i)},backend:a,attrs:{shape:h}});let v=b;if(null!=d){l.push(b);const e=n.backend_util.getUndoAxesPermutation(d);v=Xt({inputs:{x:v},backend:a,attrs:{perm:e}})}return l.forEach(e=>a.disposeIntermediateTensorInfo(e)),v}},Qs];for(const e of bu)n.registerKernel(e);e.GPGPUContext=Be,e.MathBackendWebGL=ct,e.forceHalfFloat=dt,e.gpgpu_util=Le,e.setWebGLContext=r,e.version_webgl="3.0.0",e.webgl=pt,e.webgl_util=ae,Object.defineProperty(e,"__esModule",{value:!0})}));
  //# sourceMappingURL=tf-backend-webgl.es2017.min.js.map
  