UNPKG

@tensorflow/tfjs-core

Version:

Hardware-accelerated JavaScript library for machine intelligence

17 lines 211 kB
/** * @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,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e=e||self).tf=e.tf||{})}(this,(function(e){"use strict";class t{refCount(e){return n("refCount")}incRef(e){return n("incRef")}timerAvailable(){return!0}time(e){return n("time")}read(e){return n("read")}readSync(e){return n("readSync")}numDataIds(){return n("numDataIds")}disposeData(e,t){return n("disposeData")}write(e,t,r){return n("write")}move(e,t,r,s,o){return n("move")}memory(){return n("memory")}floatPrecision(){return n("floatPrecision")}epsilon(){return 32===this.floatPrecision()?1e-7:1e-4}dispose(){return n("dispose")}}function n(e){throw new Error(`'${e}' not yet implemented or not found in the registry. This kernel may not be supported by the tfjs backend you have chosen`)}function r(e){let t=e.length,n=0,r=0;for(;t>0;)r=Math.random()*t|0,t--,n=e[t],e[t]=e[r],e[r]=n}function s(e,t,n){return Math.max(e,Math.min(t,n))}function o(e,t){if(!e)throw new Error("string"==typeof t?t:t())}function a(e,t,n=""){o(c(e,t),()=>n+` Shapes ${e} and ${t} must match`)}function i(e){o(null!=e,()=>"The input to the tensor constructor must be a non-null value.")}function l(e,t=[],n=!1){if(null==t&&(t=[]),Array.isArray(e)||w(e)&&!n)for(let r=0;r<e.length;++r)l(e[r],t,n);else t.push(e);return t}function u(e){if(0===e.length)return 1;let t=e[0];for(let n=1;n<e.length;n++)t*=e[n];return t}function c(e,t){if(e===t)return!0;if(null==e||null==t)return!1;if(e.length!==t.length)return!1;for(let n=0;n<e.length;n++)if(e[n]!==t[n])return!1;return!0}function h(e){return e%1==0}function d(e,t){return t<=e.length?e:e+" ".repeat(t-e.length)}function p(e,t){const n=t.length;return o((e=null==e?t.map((e,t)=>t):[].concat(e)).every(e=>e>=-n&&e<n),()=>`All values in axis param must be in range [-${n}, ${n}) but got axis `+e),o(e.every(e=>h(e)),()=>"All values in axis param must be integers but got axis "+e),e.map(e=>e<0?n+e:e)}function f(e,t){const n=[],r=[],s=null!=t&&Array.isArray(t)&&0===t.length,o=null==t||s?null:p(t,e).sort();let a=0;for(let t=0;t<e.length;++t){if(null!=o){if(o[a]===t&&1!==e[t])throw new Error(`Can't squeeze axis ${t} since its dim '${e[t]}' is not 1`);(null==o[a]||o[a]>t)&&1===e[t]&&(n.push(e[t]),r.push(t)),o[a]<=t&&a++}1!==e[t]&&(n.push(e[t]),r.push(t))}return{newShape:n,keptDims:r}}function m(e,t){let n=null;if(null==e||"float32"===e)n=new Float32Array(t);else if("int32"===e)n=new Int32Array(t);else{if("bool"!==e)throw new Error("Unknown data type "+e);n=new Uint8Array(t)}return n}function g(e,t){let n=null;if(null==e||"float32"===e)n=new Float32Array(t);else if("int32"===e)n=new Int32Array(t);else if("bool"===e)n=new Uint8Array(t);else{if("string"!==e)throw new Error("Unknown data type "+e);n=new Array(t)}return n}function b(e,t){for(let n=0;n<e.length;n++){const r=e[n];if(isNaN(r)||!isFinite(r))throw Error(`A tensor of type ${t} being uploaded contains ${r}.`)}}function y(e){return"bool"===e||"complex64"===e||"float32"===e||"int32"===e||"string"===e}function w(e){return e instanceof Float32Array||e instanceof Int32Array||e instanceof Uint8Array}function k(e){if("float32"===e||"int32"===e)return 4;if("complex64"===e)return 8;if("bool"===e)return 1;throw new Error("Unknown dtype "+e)}function v(e){if(null==e)return 0;let t=0;return e.forEach(e=>t+=e.length),t}function x(e){return"string"==typeof e||e instanceof String}function E(e){return"boolean"==typeof e}function S(e){return"number"==typeof e}function A(e){return Array.isArray(e)?A(e[0]):e instanceof Float32Array?"float32":e instanceof Int32Array||e instanceof Uint8Array?"int32":S(e)?"float32":x(e)?"string":E(e)?"bool":"float32"}function M(e){return!!(e&&e.constructor&&e.call&&e.apply)}function N(e,t){for(let n=t;n<e;++n)if(e%n==0)return n;return e}function I(e){const t=e.length;if(t<2)return[];const n=new Array(t-1);n[t-2]=e[t-1];for(let r=t-3;r>=0;--r)n[r]=n[r+1]*e[r+1];return n}function _(e,t){if(0===e.length)return t[0];const n=e.reduce((e,t)=>e*t);if(0===n)return[];if(n!==t.length)throw new Error(`[${e}] does not match the input size ${t.length}.`);return function e(t,n,r){const s=new Array;if(1===n.length){const e=n[0];for(let n=0;n<e;n++)s[n]=r[t+n]}else{const o=n[0],a=n.slice(1),i=a.reduce((e,t)=>e*t);for(let n=0;n<o;n++)s[n]=e(t+n*i,a,r)}return s}(0,e,t)}function $(e,t){const n=T(e,t);for(let e=0;e<n.length;e++)n[e]=1;return n}function T(e,t){if(null==t||"float32"===t||"complex64"===t)return new Float32Array(e);if("int32"===t)return new Int32Array(e);if("bool"===t)return new Uint8Array(e);throw new Error("Unknown data type "+t)}function D(e){e.forEach(t=>{o(Number.isInteger(t)&&t>=0,()=>`Tensor must have a shape comprised of positive integers but got shape [${e}].`)})}function R(e){return e&&e.then&&"function"==typeof e.then}class C{constructor(e){this.global=e,this.flags={},this.flagRegistry={},this.urlFlags={},this.populateURLFlags()}setPlatform(e,t){null!=this.platform&&console.warn(`Platform ${this.platformName} has already been set. Overwriting the platform with ${t}.`),this.platformName=e,this.platform=t}registerFlag(e,t,n){if(this.flagRegistry[e]={evaluationFn:t,setHook:n},null!=this.urlFlags[e]){const t=this.urlFlags[e];console.warn(`Setting feature override from URL ${e}: ${t}.`),this.set(e,t)}}async getAsync(e){return e in this.flags||(this.flags[e]=await this.evaluateFlag(e)),this.flags[e]}get(e){if(e in this.flags)return this.flags[e];const t=this.evaluateFlag(e);if(R(t))throw new Error(`Flag ${e} cannot be synchronously evaluated. Please use getAsync() instead.`);return this.flags[e]=t,this.flags[e]}getNumber(e){return this.get(e)}getBool(e){return this.get(e)}getFlags(){return this.flags}get features(){return this.flags}set(e,t){if(null==this.flagRegistry[e])throw new Error(`Cannot set flag ${e} as it has not been registered.`);this.flags[e]=t,null!=this.flagRegistry[e].setHook&&this.flagRegistry[e].setHook(t)}evaluateFlag(e){if(null==this.flagRegistry[e])throw new Error(`Cannot evaluate flag '${e}': no evaluation function found.`);return this.flagRegistry[e].evaluationFn()}setFlags(e){this.flags=Object.assign({},e)}reset(){this.flags={},this.urlFlags={},this.populateURLFlags()}populateURLFlags(){if(void 0===this.global||void 0===this.global.location||void 0===this.global.location.search)return;const e=function(e){const t={};return e.replace(/[?&]([^=?&]+)(?:=([^&]*))?/g,(e,...n)=>(function(e,t,n){e[decodeURIComponent(t)]=decodeURIComponent(n||"")}(t,n[0],n[1]),n.join("="))),t}(this.global.location.search);if("tfjsflags"in e){e.tfjsflags.split(",").forEach(e=>{const[t,n]=e.split(":");this.urlFlags[t]=function(e,t){if("true"===(t=t.toLowerCase())||"false"===t)return"true"===t;if(""+ +t===t)return+t;throw new Error(`Could not parse value flag value ${t} for flag ${e}.`)}(t,n)})}}}function F(){return e.ENV}let B;function P(){if(null==B){let e;if("undefined"!=typeof window)e=window;else if("undefined"!=typeof global)e=global;else if("undefined"!=typeof process)e=process;else{if("undefined"==typeof self)throw new Error("Could not find a global object");e=self}B=e}return B}function z(e,t){const n=function(){const e=P();return null==e._tfGlobals&&(e._tfGlobals=new Map),e._tfGlobals}();if(n.has(e))return n.get(e);{const r=t();return n.set(e,r),n.get(e)}}e.ENV=null;const L=z("kernelRegistry",()=>new Map),O=z("gradRegistry",()=>new Map);function K(e,t){const n=G(e,t);return L.get(n)}function W(e){return O.get(e)}function q(e){const t=L.entries(),n=[];for(;;){const{done:r,value:s}=t.next();if(r)break;const[o,a]=s,[i]=o.split("_");i===e&&n.push(a)}return n}function U(e){const{kernelName:t,backendName:n}=e,r=G(t,n);L.has(r)&&console.warn(`The kernel '${t}' for backend '${n}' is already registered`),L.set(r,e)}function G(e,t){return`${t}_${e}`}function V(e,t){if("string"===t)throw new Error("Cannot convert a string[] to a TypedArray");if(Array.isArray(e)&&(e=l(e)),F().getBool("DEBUG")&&b(e,t),function(e,t){return e instanceof Float32Array&&"float32"===t||e instanceof Int32Array&&"int32"===t||e instanceof Uint8Array&&"bool"===t}(e,t))return e;if(null==t||"float32"===t||"complex64"===t)return new Float32Array(e);if("int32"===t)return new Int32Array(e);if("bool"===t){const t=new Uint8Array(e.length);for(let n=0;n<t.length;++n)0!==Math.round(e[n])&&(t[n]=1);return t}throw new Error("Unknown data type "+t)}function H(){return F().platform.now()}function j(e,t="utf-8"){return t=t||"utf-8",F().platform.encode(e,t)}function J(e,t="utf-8"){return t=t||"utf-8",F().platform.decode(e,t)}var Y=Object.freeze({__proto__:null,createScalarValue:function(e,t){return"string"===t?j(e):V([e],t)},toTypedArray:V,now:H,fetch:function(e,t){return F().platform.fetch(e,t)},encodeString:j,decodeString:J,shuffle:r,shuffleCombo:function(e,t){if(e.length!==t.length)throw new Error("Array sizes must match to be shuffled together First array length was "+e.length+"Second array length was "+t.length);let n,r,s=e.length,o=0;for(;s>0;)o=Math.random()*s|0,s--,n=e[s],r=t[s],e[s]=e[o],t[s]=t[o],e[o]=n,t[o]=r},clamp:s,nearestLargerEven:function(e){return e%2==0?e:e+1},sum:function(e){let t=0;for(let n=0;n<e.length;n++)t+=e[n];return t},randUniform:function(e,t){const n=Math.random();return t*n+(1-n)*e},distSquared:function(e,t){let n=0;for(let r=0;r<e.length;r++){const s=Number(e[r])-Number(t[r]);n+=s*s}return n},assert:o,assertShapesMatch:a,assertNonNull:i,flatten:l,sizeFromShape:u,isScalarShape:function(e){return 0===e.length},arraysEqual:c,isInt:h,tanh:function(e){if(null!=Math.tanh)return Math.tanh(e);if(e===1/0)return 1;if(e===-1/0)return-1;{const t=Math.exp(2*e);return(t-1)/(t+1)}},sizeToSquarishShape:function(e){const t=Math.ceil(Math.sqrt(e));return[t,Math.ceil(e/t)]},createShuffledIndices:function(e){const t=new Uint32Array(e);for(let n=0;n<e;++n)t[n]=n;return r(t),t},rightPad:d,repeatedTry:function(e,t=(e=>0),n){return new Promise((r,s)=>{let o=0;const a=()=>{if(e())return void r();o++;const i=t(o);null!=n&&o>=n?s():setTimeout(a,i)};a()})},inferFromImplicitShape:function(e,t){let n=1,r=-1;for(let t=0;t<e.length;++t)if(e[t]>=0)n*=e[t];else if(-1===e[t]){if(-1!==r)throw Error(`Shapes can only have 1 implicit size. Found -1 at dim ${r} and dim ${t}`);r=t}else if(e[t]<0)throw Error(`Shapes can not be < 0. Found ${e[t]} at dim ${t}`);if(-1===r){if(t>0&&t!==n)throw Error(`Size(${t}) must match the product of shape ${e}`);return e}if(0===n)throw Error(`Cannot infer the missing size in [${e}] when there are 0 elements`);if(t%n!=0)throw Error(`The implicit shape can't be a fractional number. Got ${t} / ${n}`);const s=e.slice();return s[r]=t/n,s},parseAxisParam:p,squeezeShape:f,getTypedArrayFromDType:m,getArrayFromDType:g,checkConversionForErrors:b,isValidDtype:y,hasEncodingLoss:function(e,t){return"complex64"!==t&&(("float32"!==t||"complex64"===e)&&(("int32"!==t||"float32"===e||"complex64"===e)&&("bool"!==t||"bool"!==e)))},isTypedArray:w,bytesPerElement:k,bytesFromStringArray:v,isString:x,isBoolean:E,isNumber:S,inferDtype:A,isFunction:M,nearestDivisor:N,computeStrides:I,toNestedArray:_,makeOnesTypedArray:$,makeZerosTypedArray:T,makeZerosNestedTypedArray:function(e,t){const n=e.reduce((e,t)=>e*t,1);if(null==t||"float32"===t)return _(e,new Float32Array(n));if("int32"===t)return _(e,new Int32Array(n));if("bool"===t)return _(e,new Uint8Array(n));throw new Error("Unknown data type "+t)},assertNonNegativeIntegerDimensions:D,locToIndex:function(e,t,n){if(0===t)return 0;if(1===t)return e[0];let r=e[e.length-1];for(let t=0;t<e.length-1;++t)r+=n[t]*e[t];return r},indexToLoc:function(e,t,n){if(0===t)return[];if(1===t)return[e];const r=new Array(t);for(let t=0;t<r.length-1;++t)r[t]=Math.floor(e/n[t]),e-=r[t]*n[t];return r[r.length-1]=e,r},isPromise:R});class Z{constructor(e,t){this.backendTimer=e,this.logger=t,null==t&&(this.logger=new Q)}profileKernel(e,t,n){let r;const s=()=>{r=n()};let o;const a=H();if(this.backendTimer.timerAvailable())o=this.backendTimer.time(s);else{s();for(const e of r)e.dataSync();o=Promise.resolve({kernelMs:H()-a})}if(F().getBool("CHECK_COMPUTATION_FOR_ERRORS"))for(let t=0;t<r.length;t++){const n=r[t];n.data().then(t=>{X(t,n.dtype,e)})}return{kernelName:e,outputs:r,inputs:t,timeMs:o.then(e=>e.kernelMs),extraInfo:o.then(e=>null!=e.getExtraProfileInfo?e.getExtraProfileInfo():"")}}logKernelProfile(e){const{kernelName:t,outputs:n,timeMs:r,inputs:s,extraInfo:o}=e;n.forEach(e=>{Promise.all([e.data(),r,o]).then(n=>{this.logger.logKernelProfile(t,e,n[0],n[1],s,n[2])})})}}function X(e,t,n){if("float32"!==t)return!1;for(let t=0;t<e.length;t++){const r=e[t];if(isNaN(r)||!isFinite(r))return console.warn(`Found ${r} in the result of '${n}'`),!0}return!1}class Q{logKernelProfile(e,t,n,r,s,o){const a="number"==typeof r?d(r+"ms",9):r.error,i=d(e,25),l=t.rank,u=t.size,c=d(t.shape.toString(),14);let h="";for(const e in s){const n=s[e];if(null!=n){const r=n.shape||t.shape,s=r.length;h+=`${e}: ${s}D ${s>0?r:""} `}}console.log(`%c${i}\t%c${a}\t%c${l}D ${c}\t%c${u}\t%c${h}\t%c${o}`,"font-weight:bold","color:red","color:blue","color: orange","color: green","color: steelblue")}}function ee(e,t,n,r){const s=I(t),o=function(e,t,n,r){const s=u(t),o=r[r.length-1],a=new Array(o).fill(0),i=t.length,l="complex64"===n?re(e):e;if(i>1)for(let e=0;e<s/o;e++){const t=e*o;for(let e=0;e<o;e++)a[e]=Math.max(a[e],te(l[t+e],0,n).length)}return a}(e,t,n,s),a=t.length,i=function e(t,n,r,s,o,a=!0){const i="complex64"===r?2:1,l=n[0],u=n.length;if(0===u){if("complex64"===r){return[te(re(t)[0],0,r)]}return"bool"===r?[ne(t[0])]:[t[0].toString()]}if(1===u){if(l>20){const e=3*i;let n=Array.from(t.slice(0,e)),s=Array.from(t.slice((l-3)*i,l*i));return"complex64"===r&&(n=re(n),s=re(s)),["["+n.map((e,t)=>te(e,o[t],r)).join(", ")+", ..., "+s.map((e,t)=>te(e,o[l-3+t],r)).join(", ")+"]"]}return["["+("complex64"===r?re(t):Array.from(t)).map((e,t)=>te(e,o[t],r)).join(", ")+"]"]}const c=n.slice(1),h=s.slice(1),d=s[0]*i,p=[];if(l>20){for(let n=0;n<3;n++){const s=n*d,a=s+d;p.push(...e(t.slice(s,a),c,r,h,o,!1))}p.push("...");for(let n=l-3;n<l;n++){const s=n*d,a=s+d;p.push(...e(t.slice(s,a),c,r,h,o,n===l-1))}}else for(let n=0;n<l;n++){const s=n*d,a=s+d;p.push(...e(t.slice(s,a),c,r,h,o,n===l-1))}const f=2===u?",":"";p[0]="["+p[0]+f;for(let e=1;e<p.length-1;e++)p[e]=" "+p[e]+f;let m=",\n";for(let e=2;e<u;e++)m+="\n";return p[p.length-1]=" "+p[p.length-1]+"]"+(a?"":m),p}(e,t,n,s,o),l=["Tensor"];return r&&(l.push(" dtype: "+n),l.push(" rank: "+a),l.push(` shape: [${t}]`),l.push(" values:")),l.push(i.map(e=>" "+e).join("\n")),l.join("\n")}function te(e,t,n){let r;return r=Array.isArray(e)?parseFloat(e[0].toFixed(7))+" + "+parseFloat(e[1].toFixed(7))+"j":x(e)?`'${e}'`:"bool"===n?ne(e):parseFloat(e.toFixed(7)).toString(),d(r,t)}function ne(e){return 0===e?"false":"true"}function re(e){const t=[];for(let n=0;n<e.length;n+=2)t.push([e[n],e[n+1]]);return t}class se{constructor(e,t,n){if(this.dtype=t,this.shape=e.slice(),this.size=u(e),null!=n){const e=n.length;o(e===this.size,()=>`Length of values '${e}' does not match the size inferred by the shape '${this.size}'.`)}if("complex64"===t)throw new Error("complex64 dtype TensorBuffers are not supported. Please create a TensorBuffer for the real and imaginary parts separately and call tf.complex(real, imag).");this.values=n||g(t,this.size),this.strides=I(e)}set(e,...t){0===t.length&&(t=[0]),o(t.length===this.rank,()=>`The number of provided coordinates (${t.length}) must match the rank (${this.rank})`);const n=this.locToIndex(t);this.values[n]=e}get(...e){0===e.length&&(e=[0]);let t=0;for(const n of e){if(n<0||n>=this.shape[t]){const t=`Requested out of range element at ${e}. Buffer shape=`+this.shape;throw new Error(t)}t++}let n=e[e.length-1];for(let t=0;t<e.length-1;++t)n+=this.strides[t]*e[t];return this.values[n]}locToIndex(e){if(0===this.rank)return 0;if(1===this.rank)return e[0];let t=e[e.length-1];for(let n=0;n<e.length-1;++n)t+=this.strides[n]*e[n];return t}indexToLoc(e){if(0===this.rank)return[];if(1===this.rank)return[e];const t=new Array(this.shape.length);for(let n=0;n<t.length-1;++n)t[n]=Math.floor(e/this.strides[n]),e-=t[n]*this.strides[n];return t[t.length-1]=e,t}get rank(){return this.shape.length}toTensor(){return oe().makeTensor(this.values,this.shape,this.dtype)}}let oe=null,ae=null;class ie{constructor(e,t,n,r){this.kept=!1,this.isDisposedInternal=!1,this.shape=e.slice(),this.dtype=t||"float32",this.size=u(e),this.strides=I(e),this.dataId=n,this.id=r,this.rankType=this.rank<5?this.rank.toString():"higher"}get rank(){return this.shape.length}async buffer(){const e=await this.data();return ae.buffer(this.shape,this.dtype,e)}bufferSync(){return ae.buffer(this.shape,this.dtype,this.dataSync())}async array(){const e=await this.data();return _(this.shape,e)}arraySync(){return _(this.shape,this.dataSync())}async data(){this.throwIfDisposed();const e=oe().read(this.dataId);if("string"===this.dtype){const t=await e;try{return t.map(e=>J(e))}catch(e){throw new Error("Failed to decode the string bytes into utf-8. To get the original bytes, call tensor.bytes().")}}return e}dataSync(){this.throwIfDisposed();const e=oe().readSync(this.dataId);if("string"===this.dtype)try{return e.map(e=>J(e))}catch(e){throw new Error("Failed to decode the string bytes into utf-8. To get the original bytes, call tensor.bytes().")}return e}async bytes(){this.throwIfDisposed();const e=await oe().read(this.dataId);return"string"===this.dtype?e:new Uint8Array(e.buffer)}dispose(){this.isDisposed||(oe().disposeTensor(this),this.isDisposedInternal=!0)}get isDisposed(){return this.isDisposedInternal}throwIfDisposed(){if(this.isDisposed)throw new Error("Tensor is disposed.")}print(e=!1){return ae.print(this,e)}clone(){return this.throwIfDisposed(),ae.clone(this)}toString(e=!1){return ee(this.dataSync(),this.shape,this.dtype,e)}cast(e){return this.throwIfDisposed(),ae.cast(this,e)}variable(e=!0,t,n){return this.throwIfDisposed(),oe().makeVariable(this,e,t,n)}}Object.defineProperty(ie,Symbol.hasInstance,{value:e=>!!e&&null!=e.data&&null!=e.dataSync&&null!=e.throwIfDisposed}),z("Tensor",()=>ie);class le extends ie{constructor(e,t,n,r){super(e.shape,e.dtype,e.dataId,r),this.trainable=t,this.name=n}assign(e){if(e.dtype!==this.dtype)throw new Error(`dtype of the new value (${e.dtype}) and previous value (${this.dtype}) must match`);if(!c(e.shape,this.shape))throw new Error(`shape of the new value (${e.shape}) and previous value (${this.shape}) must match`);oe().disposeTensor(this),this.dataId=e.dataId,oe().incRef(this,null)}dispose(){oe().disposeVariable(this),this.isDisposedInternal=!0}}var ue,ce,he,de,pe;Object.defineProperty(le,Symbol.hasInstance,{value:e=>e instanceof ie&&null!=e.assign&&e.assign instanceof Function}),(ue=e.Rank||(e.Rank={})).R0="R0",ue.R1="R1",ue.R2="R2",ue.R3="R3",ue.R4="R4",ue.R5="R5",ue.R6="R6",function(e){e.float32="float32",e.int32="int32",e.bool="int32",e.complex64="complex64"}(ce||(ce={})),function(e){e.float32="float32",e.int32="int32",e.bool="bool",e.complex64="complex64"}(he||(he={})),function(e){e.float32="float32",e.int32="float32",e.bool="float32",e.complex64="complex64"}(de||(de={})),function(e){e.float32="complex64",e.int32="complex64",e.bool="complex64",e.complex64="complex64"}(pe||(pe={}));const fe={float32:de,int32:ce,bool:he,complex64:pe};function me(e,t){if("string"===e||"string"===t){if("string"===e&&"string"===t)return"string";throw new Error(`Can not upcast ${e} with ${t}`)}return fe[e][t]}function ge(e,t){if(e.dtype===t.dtype)return[e,t];const n=me(e.dtype,t.dtype);return[e.cast(n),t.cast(n)]}function be(e,t){o(e.dtype===t.dtype,()=>`The dtypes of the first(${e.dtype}) and second(${t.dtype}) input must match`)}function ye(e){const t=[];return function e(t,n,r){if(null==t)return;if(t instanceof ie)return void n.push(t);if(s=t,!Array.isArray(s)&&"object"!=typeof s)return;var s;const o=t;for(const t in o){const s=o[t];r.has(s)||(r.add(s),e(s,n,r))}}(e,t,new Set),t}var we=Object.freeze({__proto__:null,makeTypesMatch:ge,assertTypesMatch:be,isTensorInList:function(e,t){return t.some(t=>t.id===e.id)},getTensorsInContainer:ye});function ke(e){return null!=e.kernelName}class ve{constructor(){this.registeredVariables={},this.nextTapeNodeId=0,this.numBytes=0,this.numTensors=0,this.numStringTensors=0,this.numDataBuffers=0,this.gradientDepth=0,this.kernelDepth=0,this.scopeStack=[],this.numDataMovesStack=[],this.nextScopeId=0,this.tensorInfo=new WeakMap,this.profiling=!1,this.activeProfile={newBytes:0,newTensors:0,peakBytes:0,kernels:[],result:null,get kernelNames(){return Array.from(new Set(this.kernels.map(e=>e.name)))}}}dispose(){for(const e in this.registeredVariables)this.registeredVariables[e].dispose()}}class xe{constructor(e){this.ENV=e,this.registry={},this.registryFactory={},this.pendingBackendInitId=0,this.state=new ve}async ready(){if(null!=this.pendingBackendInit)return this.pendingBackendInit.then(()=>{});if(null!=this.backendInstance)return;const e=this.getSortedBackends();for(let t=0;t<e.length;t++){const n=e[t];if(await this.initializeBackend(n).success)return void await this.setBackend(n)}throw new Error("Could not initialize any backends, all backend initializations failed.")}get backend(){if(null!=this.pendingBackendInit)throw new Error(`Backend '${this.backendName}' has not yet been initialized. Make sure to await tf.ready() or await tf.setBackend() before calling other methods`);if(null==this.backendInstance){const{name:e,asyncInit:t}=this.initializeBackendsAndReturnBest();if(t)throw new Error(`The highest priority backend '${e}' has not yet been initialized. Make sure to await tf.ready() or await tf.setBackend() before calling other methods`);this.setBackend(e)}return this.backendInstance}backendNames(){return Object.keys(this.registryFactory)}findBackend(e){if(!(e in this.registry)){if(!(e in this.registryFactory))return null;{const{asyncInit:t}=this.initializeBackend(e);if(t)return null}}return this.registry[e]}findBackendFactory(e){return e in this.registryFactory?this.registryFactory[e].factory:null}registerBackend(e,t,n=1){return e in this.registryFactory?(console.warn(e+" backend was already registered. Reusing existing backend factory."),!1):(this.registryFactory[e]={factory:t,priority:n},!0)}async setBackend(e){if(null==this.registryFactory[e])throw new Error(`Backend name '${e}' not found in registry`);if(this.backendName=e,null==this.registry[e]){this.backendInstance=null;const{success:t,asyncInit:n}=this.initializeBackend(e);if(!(n?await t:t))return!1}return this.backendInstance=this.registry[e],this.setupRegisteredKernels(),this.profiler=new Z(this.backendInstance),!0}setupRegisteredKernels(){q(this.backendName).forEach(e=>{null!=e.setupFunc&&e.setupFunc(this.backendInstance)})}disposeRegisteredKernels(e){q(e).forEach(t=>{null!=t.disposeFunc&&t.disposeFunc(this.registry[e])})}initializeBackend(e){const n=this.registryFactory[e];if(null==n)throw new Error(`Cannot initialize backend ${e}, no registration found.`);try{const r=n.factory();if(!r||r instanceof t||"function"!=typeof r.then)return this.registry[e]=r,{success:!0,asyncInit:!1};{const t=++this.pendingBackendInitId,n=r.then(n=>!(t<this.pendingBackendInitId)&&(this.registry[e]=n,this.pendingBackendInit=null,!0)).catch(n=>(t<this.pendingBackendInitId||(this.pendingBackendInit=null,console.warn(`Initialization of backend ${e} failed`),console.warn(n.stack||n.message)),!1));return this.pendingBackendInit=n,{success:n,asyncInit:!0}}}catch(t){return console.warn(`Initialization of backend ${e} failed`),console.warn(t.stack||t.message),{success:!1,asyncInit:!1}}}removeBackend(e){if(!(e in this.registryFactory))throw new Error(e+" backend not found in registry");this.backendName===e&&null!=this.pendingBackendInit&&this.pendingBackendInitId++,e in this.registry&&(this.disposeRegisteredKernels(e),this.registry[e].dispose(),delete this.registry[e]),delete this.registryFactory[e],this.backendName===e&&(this.pendingBackendInit=null,this.backendName=null,this.backendInstance=null)}getSortedBackends(){if(0===Object.keys(this.registryFactory).length)throw new Error("No backend found in registry.");return Object.keys(this.registryFactory).sort((e,t)=>this.registryFactory[t].priority-this.registryFactory[e].priority)}initializeBackendsAndReturnBest(){const e=this.getSortedBackends();for(let t=0;t<e.length;t++){const n=e[t],{success:r,asyncInit:s}=this.initializeBackend(n);if(s||r)return{name:n,asyncInit:s}}throw new Error("Could not initialize any backends, all backend initializations failed.")}moveData(e,t){const n=this.state.tensorInfo.get(t),r=n.backend,s=this.readSync(t),o=r.refCount(t);r.disposeData(t,!0),n.backend=e,e.move(t,s,n.shape,n.dtype,o),this.shouldCheckForMemLeaks()&&this.state.numDataMovesStack[this.state.numDataMovesStack.length-1]++}tidy(e,t){let n,r=null;if(null==t){if("function"!=typeof e)throw new Error("Please provide a function to tidy()");t=e}else{if("string"!=typeof e&&!(e instanceof String))throw new Error("When calling with two arguments, the first argument to tidy() must be a string");if("function"!=typeof t)throw new Error("When calling with two arguments, the 2nd argument to tidy() must be a function");r=e}return this.scopedRun(()=>this.startScope(r),()=>this.endScope(n),()=>(n=t(),n instanceof Promise&&console.error("Cannot return a Promise inside of tidy."),n))}scopedRun(e,t,n){e();try{const e=n();return t(),e}catch(e){throw t(),e}}nextTensorId(){return xe.nextTensorId++}nextVariableId(){return xe.nextVariableId++}clone(e){const t=Se.runKernel("Identity",{x:e}),n={x:e};return this.addTapeNode(this.state.activeScope.name,n,[t],e=>({x:()=>{const t={x:e},n={dtype:"float32"};return Se.runKernel("Cast",t,n)}}),[],{}),t}runKernel(e,t,n){if(!(null!=K(e,this.backendName)))throw new Error(`Kernel '${e}' not registered for backend '${this.backendName}'`);return this.runKernelFunc({kernelName:e,inputs:t,attrs:n})}shouldCheckForMemLeaks(){return this.ENV.getBool("IS_TEST")}checkKernelForMemLeak(e,t,n){const r=this.backend.numDataIds();let s=0;n.forEach(e=>{s+="complex64"===e.dtype?3:1});const o=this.state.numDataMovesStack[this.state.numDataMovesStack.length-1],a=r-t-s-o;if(a>0)throw new Error(`Backend '${this.backendName}' has an internal memory leak (${a} data ids) after running '${e}'`)}runKernelFunc(e){let t,n=[];const r=this.isTapeOn(),s=this.state.numBytes,a=this.state.numTensors;let i,l;this.shouldCheckForMemLeaks()&&this.state.numDataMovesStack.push(0),null==this.backendName&&this.backend;const u=ke(e)?e.kernelName:null!=this.state.activeScope?this.state.activeScope.name:"";if(ke(e)){const{kernelName:t,inputs:s,attrs:a}=e;null==this.backendName&&this.backend;const u=K(t,this.backendName);o(null!=u,()=>`Cannot find registered kernel '${t}' for backend '${this.backendName}'`),i=()=>{const e=this.backend.numDataIds();l=u.kernelFunc({inputs:s,attrs:a,backend:this.backend});const o=Array.isArray(l)?l:[l];this.shouldCheckForMemLeaks()&&this.checkKernelForMemLeak(t,e,o);const i=o.map(e=>{if(null!=e.rank)return e;const{dataId:t,shape:n,dtype:r}=e;return this.makeTensorFromDataId(t,n,r)});if(r){const e=this.getTensorsForGradient(t,s,i);n=this.saveTensorsForBackwardMode(e)}return i}}else{const{forwardFunc:t}=e,s=e=>{r&&(n=e.map(e=>this.keep(this.clone(e))))};i=()=>{const e=this.backend.numDataIds();l=this.tidy(()=>t(this.backend,s));const n=Array.isArray(l)?l:[l];return this.shouldCheckForMemLeaks()&&this.checkKernelForMemLeak(u,e,n),n}}const{inputs:c,attrs:h}=e,d=ke(e)?null:e.backwardsFunc;let p;return this.scopedRun(()=>this.state.kernelDepth++,()=>this.state.kernelDepth--,()=>{this.ENV.getBool("DEBUG")||this.state.profiling?(p=this.profiler.profileKernel(u,c,()=>i()),this.ENV.getBool("DEBUG")&&this.profiler.logKernelProfile(p),t=p.outputs):t=i()}),r&&this.addTapeNode(u,c,t,d,n,h),this.state.profiling&&this.state.activeProfile.kernels.push({name:u,bytesAdded:this.state.numBytes-s,totalBytesSnapshot:this.state.numBytes,tensorsAdded:this.state.numTensors-a,totalTensorsSnapshot:this.state.numTensors,inputShapes:Object.keys(c).map(e=>null!=c[e]?c[e].shape:null),outputShapes:t.map(e=>e.shape),kernelTimeMs:p.timeMs,extraInfo:p.extraInfo}),Array.isArray(l)?t:t[0]}saveTensorsForBackwardMode(e){return e.map(e=>this.keep(this.clone(e)))}getTensorsForGradient(e,t,n){const r=W(e);if(null!=r){const e=r.inputsToSave||[],s=r.outputsToSave||[];let a;r.saveAllInputs?(o(Array.isArray(t),()=>"saveAllInputs is true, expected inputs to be an array."),a=Object.keys(t).map(e=>t[e])):a=e.map(e=>t[e]);const i=n.filter((e,t)=>s[t]);return a.concat(i)}return[]}makeTensor(e,t,n,r){if(null==e)throw new Error("Values passed to engine.makeTensor() are null");n=n||"float32",r=r||this.backend;let s=e;"string"===n&&x(e[0])&&(s=e.map(e=>j(e)));const o=r.write(s,t,n),a=new ie(t,n,o,this.nextTensorId());if(this.trackTensor(a,r),"string"===n){const e=this.state.tensorInfo.get(o),t=v(s);this.state.numBytes+=t-e.bytes,e.bytes=t}return a}makeTensorFromDataId(e,t,n,r){const s=new ie(t,n=n||"float32",e,this.nextTensorId());return this.trackTensor(s,r),s}makeVariable(e,t=!0,n,r){n=n||this.nextVariableId().toString(),null!=r&&r!==e.dtype&&(e=e.cast(r));const s=new le(e,t,n,this.nextTensorId());if(null!=this.state.registeredVariables[s.name])throw new Error(`Variable with name ${s.name} was already registered`);return this.state.registeredVariables[s.name]=s,this.incRef(s,this.backend),s}trackTensor(e,t){this.state.numTensors++,"string"===e.dtype&&this.state.numStringTensors++;let n=0;"complex64"!==e.dtype&&"string"!==e.dtype&&(n=e.size*k(e.dtype)),this.state.numBytes+=n,this.state.tensorInfo.has(e.dataId)||(this.state.numDataBuffers++,this.state.tensorInfo.set(e.dataId,{backend:t||this.backend,dtype:e.dtype,shape:e.shape,bytes:n})),e instanceof le||this.track(e)}incRef(e,t){this.trackTensor(e,t),this.backend.incRef(e.dataId)}removeDataId(e,t){this.state.tensorInfo.has(e)&&this.state.tensorInfo.get(e).backend===t&&(this.state.tensorInfo.delete(e),this.state.numDataBuffers--)}disposeTensor(e){if(!this.state.tensorInfo.has(e.dataId))return;const t=this.state.tensorInfo.get(e.dataId);if(this.state.numTensors--,"string"===e.dtype&&(this.state.numStringTensors--,this.state.numBytes-=t.bytes),"complex64"!==e.dtype&&"string"!==e.dtype){const t=e.size*k(e.dtype);this.state.numBytes-=t}t.backend.disposeData(e.dataId)&&this.removeDataId(e.dataId,t.backend)}disposeVariables(){for(const e in this.state.registeredVariables){const t=this.state.registeredVariables[e];this.disposeVariable(t)}}disposeVariable(e){this.disposeTensor(e),null!=this.state.registeredVariables[e.name]&&delete this.state.registeredVariables[e.name]}memory(){const e=this.backend.memory();return e.numTensors=this.state.numTensors,e.numDataBuffers=this.state.numDataBuffers,e.numBytes=this.state.numBytes,this.state.numStringTensors>0&&(e.unreliable=!0,null==e.reasons&&(e.reasons=[]),e.reasons.push("Memory usage by string tensors is approximate (2 bytes per character)")),e}async profile(e){this.state.profiling=!0;const t=this.state.numBytes,n=this.state.numTensors;this.state.activeProfile.kernels=[],this.state.activeProfile.result=await e(),this.state.profiling=!1,this.state.activeProfile.peakBytes=Math.max(...this.state.activeProfile.kernels.map(e=>e.totalBytesSnapshot)),this.state.activeProfile.newBytes=this.state.numBytes-t,this.state.activeProfile.newTensors=this.state.numTensors-n;for(const e of this.state.activeProfile.kernels)e.kernelTimeMs=await e.kernelTimeMs,e.extraInfo=await e.extraInfo;return this.state.activeProfile}isTapeOn(){return this.state.gradientDepth>0&&0===this.state.kernelDepth}addTapeNode(e,t,n,r,s,o){const a={id:this.state.nextTapeNodeId++,kernelName:e,inputs:t,outputs:n,saved:s},i=W(e);null!=i&&(r=i.gradFunc),null!=r&&(a.gradient=e=>(e=e.map((e,t)=>{if(null==e){const e=n[t],r=T(e.size,e.dtype);return this.makeTensor(r,e.shape,e.dtype)}return e}),r(e.length>1?e:e[0],s,o))),this.state.activeTape.push(a)}keep(e){return e.kept=!0,e}startTape(){0===this.state.gradientDepth&&(this.state.activeTape=[]),this.state.gradientDepth++}endTape(){this.state.gradientDepth--}startScope(e){const t={track:[],name:"unnamed scope",id:this.state.nextScopeId++};e&&(t.name=e),this.state.scopeStack.push(t),this.state.activeScope=t}endScope(e){const t=ye(e),n=new Set(t.map(e=>e.id));for(let e=0;e<this.state.activeScope.track.length;e++){const t=this.state.activeScope.track[e];t.kept||n.has(t.id)||t.dispose()}const r=this.state.scopeStack.pop();this.state.activeScope=0===this.state.scopeStack.length?null:this.state.scopeStack[this.state.scopeStack.length-1],t.forEach(e=>{e.kept||e.scopeId!==r.id||this.track(e)})}gradients(e,t,n,r=!1){if(o(t.length>0,()=>"gradients() received an empty list of xs."),null!=n&&"float32"!==n.dtype)throw new Error(`dy must have 'float32' dtype, but has '${n.dtype}'`);const s=this.scopedRun(()=>this.startTape(),()=>this.endTape(),()=>this.tidy("forward",e));o(s instanceof ie,()=>"The result y returned by f() must be a tensor.");const a=function(e,t,n){const r={},s={};for(let e=0;e<t.length;e++)r[t[e].id]=!0;for(let n=0;n<e.length;n++){const o=e[n],a=o.inputs;for(const e in a){const n=a[e];let i=!1;for(let e=0;e<t.length;e++)if(r[n.id]){o.outputs.forEach(e=>r[e.id]=!0),i=!0,s[o.id]=!0;break}if(i)break}}const o={};o[n.id]=!0;const a={};for(let t=e.length-1;t>=0;t--){const n=e[t],r=n.inputs;for(let e=0;e<n.outputs.length;e++)if(o[n.outputs[e].id]){for(const e in r)o[r[e].id]=!0,a[n.id]=!0;break}}const i=[];for(let t=0;t<e.length;t++){const n=e[t];if(s[n.id]&&a[n.id]){const e={};for(const t in n.inputs){const s=n.inputs[t];r[s.id]&&(e[t]=s)}const t=Object.assign({},n);t.inputs=e,t.outputs=n.outputs,i.push(t)}}return i}(this.state.activeTape,t,s);if(!r&&0===a.length&&t.length>0)throw new Error("Cannot compute gradient of y=f(x) with respect to x. Make sure that the f you passed encloses all operations that lead from x to y.");return this.tidy("backward",()=>{const e={};e[s.id]=null==n?function(e){const t=$(u(e),"float32");return Se.makeTensor(t,e,"float32")}(s.shape):n,function(e,t,n,r){for(let s=t.length-1;s>=0;s--){const o=t[s],a=[];if(o.outputs.forEach(t=>{const n=e[t.id];null!=n?a.push(n):a.push(null)}),null==o.gradient)throw new Error(`Cannot compute gradient: gradient function not found for ${o.kernelName}.`);const i=o.gradient(a);for(const t in o.inputs){if(!(t in i))throw new Error(`Cannot backprop through input ${t}. Available gradients found: ${Object.keys(i)}.`);const s=n(()=>i[t]());if("float32"!==s.dtype)throw new Error(`Error in gradient for op ${o.kernelName}. The gradient of input ${t} must have 'float32' dtype, but has '${s.dtype}'`);const a=o.inputs[t];if(!c(s.shape,a.shape))throw new Error(`Error in gradient for op ${o.kernelName}. The gradient of input '${t}' has shape '${s.shape}', which does not match the shape of the input '${a.shape}'`);if(null==e[a.id])e[a.id]=s;else{const t=e[a.id];e[a.id]=r(t,s),t.dispose()}}}}(e,a,e=>this.tidy(e),Ae);const r=t.map(t=>e[t.id]);return 0===this.state.gradientDepth&&(this.state.activeTape.forEach(e=>{for(const t of e.saved)t.dispose()}),this.state.activeTape=null),{value:s,grads:r}})}customGrad(e){return o(M(e),()=>"The f passed in customGrad(f) must be a function."),(...t)=>{let n;o(t.every(e=>e instanceof ie),()=>"The args passed in customGrad(f)(x1, x2,...) must all be tensors");const r={};t.forEach((e,t)=>{r[t]=e});return this.runKernelFunc({forwardFunc:(r,s)=>(n=e(...t,s),o(n.value instanceof ie,()=>"The function f passed in customGrad(f) must return an object where `obj.value` is a tensor"),o(M(n.gradFunc),()=>"The function f passed in customGrad(f) must return an object where `obj.gradFunc` is a function."),n.value),backwardsFunc:(e,r)=>{const s=n.gradFunc(e,r),a=Array.isArray(s)?s:[s];o(a.length===t.length,()=>"The function f passed in customGrad(f) must return an object where `obj.gradFunc` is a function that returns the same number of tensors as inputs passed to f(...)."),o(a.every(e=>e instanceof ie),()=>"The function f passed in customGrad(f) must return an object where `obj.gradFunc` is a function that returns a list of only tensors.");const i={};return a.forEach((e,t)=>{i[t]=()=>e}),i},inputs:r})}}readSync(e){return this.state.tensorInfo.get(e).backend.readSync(e)}read(e){return this.state.tensorInfo.get(e).backend.read(e)}async time(e){const t=H(),n=await this.backend.time(e);return n.wallMs=H()-t,n}track(e){return null!=this.state.activeScope&&(e.scopeId=this.state.activeScope.id,this.state.activeScope.track.push(e)),e}get registeredVariables(){return this.state.registeredVariables}reset(){this.pendingBackendInitId++,this.state.dispose(),this.ENV.reset(),this.state=new ve;for(const e in this.registry)this.disposeRegisteredKernels(e),this.registry[e].dispose(),delete this.registry[e];this.backendName=null,this.backendInstance=null,this.pendingBackendInit=null}}function Ee(){const t=P();if(null==t._tfengine){const e=new C(t);t._tfengine=new xe(e)}var n;return n=t._tfengine.ENV,e.ENV=n,oe=()=>t._tfengine,t._tfengine}xe.nextTensorId=0,xe.nextVariableId=0;const Se=Ee();function Ae(e,t){const n={a:e,b:t};return Se.runKernel("Add",n)}function Me(){return"undefined"!=typeof window&&null!=window.document||"undefined"!=typeof WorkerGlobalScope}var Ne=Object.freeze({__proto__:null,isMobile:function(){if("undefined"!=typeof navigator&&null!=navigator){const e=navigator.userAgent||navigator.vendor||window.opera;return/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(e)||/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(e.substr(0,4))}return!1},isBrowser:Me});const Ie=F();function _e(e,t){let n=e;if(w(e))return"string"===t?[]:[e.length];if(!Array.isArray(e))return[];const r=[];for(;Array.isArray(n)||w(n)&&"string"!==t;)r.push(n.length),n=n[0];return Array.isArray(e)&&F().getBool("TENSORLIKE_CHECK_SHAPE_CONSISTENCY")&&function e(t,n,r){if(r=r||[],!Array.isArray(t)&&!w(t))return void o(0===n.length,()=>`Element arr[${r.join("][")}] is a primitive, but should be an array/TypedArray of ${n[0]} elements`);o(n.length>0,()=>`Element arr[${r.join("][")}] should be a primitive, but is an array of ${t.length} elements`),o(t.length===n[0],()=>`Element arr[${r.join("][")}] should have ${n[0]} elements, but has ${t.length} elements`);const s=n.slice(1);for(let n=0;n<t.length;++n)e(t[n],s,r.concat(n))}(e,r,[]),r}function $e(e,t,n,r){if("string_or_numeric"!==e){if(null==e)throw new Error("Expected dtype cannot be null.");if("numeric"!==e&&e!==t||"numeric"===e&&"string"===t)throw new Error(`Argument '${n}' passed to '${r}' must be ${e} tensor, but got ${t} tensor`)}}function Te(e,t,n,r="numeric"){if(e instanceof ie)return $e(r,e.dtype,t,n),e;let s=A(e);if("string"!==s&&["bool","int32","float32"].indexOf(r)>=0&&(s=r),$e(r,s,t,n),null==e||!w(e)&&!Array.isArray(e)&&"number"!=typeof e&&"boolean"!=typeof e&&"string"!=typeof e){const r=null==e?"null":e.constructor.name;throw new Error(`Argument '${t}' passed to '${n}' must be a Tensor or TensorLike, but got '${r}'`)}const o=_e(e,s);w(e)||Array.isArray(e)||(e=[e]);const a="string"!==s?V(e,s):l(e,[],!0);return Se.makeTensor(a,o,s)}function De(e,t,n,r="numeric"){if(!Array.isArray(e))throw new Error(`Argument ${t} passed to ${n} must be a \`Tensor[]\` or \`TensorLike[]\``);return e.map((e,s)=>Te(e,`${t}[${s}]`,n,r))}Ie.registerFlag("DEBUG",()=>!1,e=>{e&&console.warn("Debugging mode is ON. The output of every math call will be downloaded to CPU and checked for NaNs. This significantly impacts performance.")}),Ie.registerFlag("IS_BROWSER",()=>Me()),Ie.registerFlag("IS_NODE",()=>"undefined"!=typeof process&&void 0!==process.versions&&void 0!==process.versions.node),Ie.registerFlag("IS_CHROME",()=>"undefined"!=typeof navigator&&null!=navigator&&null!=navigator.userAgent&&/Chrome/.test(navigator.userAgent)&&/Google Inc/.test(navigator.vendor)),Ie.registerFlag("PROD",()=>!1),Ie.registerFlag("TENSORLIKE_CHECK_SHAPE_CONSISTENCY",()=>Ie.getBool("DEBUG")),Ie.registerFlag("DEPRECATION_WARNINGS_ENABLED",()=>!0),Ie.registerFlag("IS_TEST",()=>!1),Ie.registerFlag("CHECK_COMPUTATION_FOR_ERRORS",()=>!0),Ie.registerFlag("WRAP_TO_IMAGEBITMAP",()=>!1);function Re(e){const t=Object.keys(e);if(1!==t.length)throw new Error("Please provide an object with a single key (operation name) mapping to a function. Got an object with "+t.length+" keys.");let n=t[0];const r=e[n];n.endsWith("_")&&(n=n.substring(0,n.length-1)),n+="__op";const s=(...e)=>{Se.startScope(n);try{const t=r(...e);return R(t)&&console.error("Cannot return a Promise inside of tidy."),Se.endScope(t),t}catch(e){throw Se.endScope(null),e}};return Object.defineProperty(s,"name",{value:n,configurable:!0}),s}const Ce=Re({complex_:function(e,t){const n=Te(e,"real","complex"),r=Te(t,"imag","complex");a(n.shape,r.shape,`real and imag shapes, ${n.shape} and ${r.shape}, must match in call to tf.complex().`);const s={real:n,imag:r};return Se.runKernel("Complex",s)}});function Fe(e,t,n,r){if(null==r&&(r=A(e)),"complex64"===r)throw new Error("Cannot construct a complex64 tensor directly. Please use tf.complex(real, imag).");if(!w(e)&&!Array.isArray(e)&&"number"!=typeof e&&"boolean"!=typeof e&&"string"!=typeof e)throw new Error("values passed to tensor(values) must be a number/boolean/string or an array of numbers/booleans/strings, or a TypedArray");if(null!=t){D(t);const e=u(t),r=u(n);o(e===r,()=>`Based on the provided shape, [${t}], the tensor should have ${e} values but has ${r}`);for(let e=0;e<n.length;++e){const r=n[e],s=e!==n.length-1||r!==u(t.slice(e));o(n[e]===t[e]||!s,()=>`Error creating a new Tensor. Inferred shape (${n}) does not match the provided shape (${t}). `)}}return w(e)||Array.isArray(e)||(e=[e]),t=t||n,e="string"!==r?V(e,r):l(e,[],!0),Se.makeTensor(e,t,r)}function Be(e,t,n){return Fe(e,t,_e(e,n),n)}const Pe={float32:4,float16:2,int32:4,uint16:2,uint8:1,bool:1,complex64:8};function ze(e,t){const n={};let r,s=0;for(const o of t){const t=o.name,a=o.dtype,i=o.shape,l=u(i);let c;if("quantization"in o){const n=o.quantization;if("uint8"===n.dtype||"uint16"===n.dtype){if(!("min"in n)||!("scale"in n))throw new Error(`Weight ${o.name} with quantization ${n.dtype} doesn't have corresponding metadata min and scale.`)}else{if("float16"!==n.dtype)throw new Error(`Weight ${o.name} has unknown quantization dtype ${n.dtype}. Supported quantization dtypes are: 'uint8', 'uint16', and 'float16'.`);if("float32"!==a)throw new Error(`Weight ${o.name} is quantized with ${n.dtype} which only supports weights of type float32 not ${a}.`)}const i=Pe[n.dtype],u=e.slice(s,s+l*i),h="uint8"===n.dtype?new Uint8Array(u):new Uint16Array(u);if("float32"===a)if("uint8"===n.dtype||"uint16"===n.dtype){c=new Float32Array(h.length);for(let e=0;e<h.length;e++){const t=h[e];c[e]=t*n.scale+n.min}}else{if("float16"!==n.dtype)throw new Error(`Unsupported quantization type ${n.dtype} for weight type float32.`);void 0===r&&(r=Ge()),c=r(h)}else{if("int32"!==a)throw new Error(`Unsupported dtype in weight '${t}': ${a}`);if("uint8"!==n.dtype&&"uint16"!==n.dtype)throw new Error(`Unsupported quantization type ${n.dtype} for weight type int32.`);c=new Int32Array(h.length);for(let e=0;e<h.length;e++){const t=h[e];c[e]=Math.round(t*n.scale+n.min)}}s+=l*i}else if("string"===a){const t=u(o.shape);c=[];for(let n=0;n<t;n++){const t=new Uint32Array(e.slice(s,s+4))[0];s+=4;const n=new Uint8Array(e.slice(s,s+t));c.push(n),s+=t}}else{const r=Pe[a],o=e.slice(s,s+l*r);if("float32"===a)c=new Float32Array(o);else if("int32"===a)c=new Int32Array(o);else if("bool"===a)c=new Uint8Array(o);else{if("complex64"!==a)throw new Error(`Unsupported dtype in weight '${t}': ${a}`);{c=new Float32Array(o);const e=new Float32Array(c.length/2),r=new Float32Array(c.length/2);for(let t=0;t<e.length;t++)e[t]=c[2*t],r[t]=c[2*t+1];const s=Be(e,i,"float32"),a=Be(r,i,"float32");n[t]=Ce(s,a),s.dispose(),a.dispose()}}s+=l*r}"complex64"!==a&&(n[t]=Be(c,i,a))}return n}function Le(e){if(null===e)throw new Error("Invalid input value: "+JSON.stringify(e));let t=0;const n=[];e.forEach(e=>{if(t+=e.byteLength,n.push(e.byteLength===e.buffer.byteLength?e:new e.constructor(e)),!(e instanceof Float32Array||e instanceof Int32Array||e instanceof Uint8Array))throw new Error("Unsupported TypedArray subtype: "+e.constructor.name)});const r=new Uint8Array(t);let s=0;return n.forEach(e=>{r.set(new Uint8Array(e.buffer),s),s+=e.byteLength}),r.buffer}const Oe="undefined"!=typeof Buffer&&("undefined"==typeof Blob||"undefined"==typeof atob||"undefined"==typeof btoa);function Ke(e){return Oe?Buffer.byteLength(e):new Blob([e]).size}function We(e){if(1===e.length)return e[0];let t=0;e.forEach(e=>{t+=e.byteLength});const n=new Uint8Array(t);let r=0;return e.forEach(e=>{n.set(new Uint8Array(e),r),r+=e.byteLength}),n.buffer}function qe(e){for(e=e.trim();e.endsWith("/");)e=e.slice(0,e.length-1);const t=e.split("/");return t[t.length-1]}function Ue(e){if(e.modelTopology instanceof ArrayBuffer)throw new Error("Expected JSON model topology, received ArrayBuffer.");return{dateSaved:new Date,modelTopologyType:"JSON",modelTopologyBytes:null==e.modelTopology?0:Ke(JSON.stringify(e.modelTopology)),weightSpecsBytes:null==e.weightSpecs?0:Ke(JSON.stringify(e.weightSpecs)),weightDataBytes:null==e.weightData?0:e.weightData.byteLength}}function Ge(){const e=function(){const e=e=>{let t=e<<13,n=0;for(;0==(8388608&t);)n-=8388608,t<<=1;return t&=-8388609,n+=947912704,t|n},t=new Uint32Array(2048);t[0]=0;for(let n=1;n<1024;n++)t[n]=e(n);for(let e=1024;e<2048;e++)t[e]=939524096+(e-1024<<13);return t}(),t=function(){const e=new Uint32Array(64);e[0]=0,e[31]=1199570944,e[32]=2147483648,e[63]=3347054592;for(let t=1;t<31;t++)e[t]=t<<23;for(let t=33;t<63;t++)e[t]=2147483648+(t-32<<23);return e}(),n=function(){const e=new Uint32Array(64);for(let t=0;t<64;t++)e[t]=1024;return e[0]=e[32]=0,e}();return r=>{const s=new ArrayBuffer(4*r.length),o=new Uint32Array(s);for(let s=0;s<r.length;s++){const a=r[s],i=e[n[a>>10]+(1023&a)]+t[a>>10];o[s]=i}return new Float32Array(s)}}class Ve{constructor(){this.saveRouters=[],this.loadRouters=[]}static getInstance(){return null==Ve.instance&&(Ve.instance=new Ve),Ve.instance}static registerSaveRouter(e){Ve.getInstance().saveRouters.push(e)}static registerLoadRouter(e){Ve.getInstance().loadRouters.push(e)}static getSaveHandlers(e){return Ve.getHandlers(e,"save")}static getLoadHandlers(e,t){return Ve.getHandlers(e,"load",t)}static getHandlers(e,t,n){const r=[];return("load"===t?Ve.getInstance().loadRouters:Ve.getInstance().saveRouters).forEach(t=>{const s=t(e,n);null!==s&&r.push(s)}),r}}function He(){if(!F().getBool("IS_BROWSER"))throw new Error("Failed to obtain IndexedDB factory because the current environmentis not a web browser.");const e="undefined"==typeof window?self:window,t=e.indexedDB||e.mozIndexedDB||e.webkitIndexedDB||e.msIndexedDB||e.shimIndexedDB;if(null==t)throw new Error("The current browser does not appear to support IndexedDB.");return t}function je(e){const t=e.result;t.createObjectStore("models_store",{keyPath:"modelPath"}),t.createObjectStore("model_info_store",{keyPath:"modelPath"})}class Je{constructor(e){if(this.indexedDB=He(),null==e||!e)throw new Error("For IndexedDB, modelPath must not be null, undefined or empty.");this.modelPath=e}async save(e){if(e.modelTopology instanceof ArrayBuffer)throw new Error("BrowserLocalStorage.save() does not support saving model topology in binary formats yet.");return this.databaseAction(this.modelPath,e)}async load(){return this.databaseAction(this.modelPath)}databaseAction(e,t){return new Promi