Files
keras-js/lib/weblas.map.json

1 line
186 KiB
JSON

{"version":3,"sources":["../../../../../usr/lib/node_modules/browserify/node_modules/browser-pack/_prelude.js","index.js","lib/globals.js","lib/test.js","lib/pipeline.js","lib/saxpycalculator.js","lib/sscalcalculator.js","lib/sdwnscalculator.js","lib/sgemmcalculator.js","lib/sclmpcalculator.js","lib/tensor.js","node_modules/floader/lib/xhr-loader.js","node_modules/async/lib/async.js","lib/webgl.js","../../../../../usr/lib/node_modules/browserify/node_modules/process/browser.js"],"names":["sgemm","M","N","K","alpha","A","B","beta","C","length","Error","texels1","texels0","texels2","transpose","texture0","gl","createDataTexture","texture1","texture2","texture3","createOutputTexture","sgemmcalculator","calculate","rawBuffer","readData","context","deleteTexture","Float32Array","saxpy","a","X","Y","isFloat32Array","fill","saxpycalculator","obj","Object","prototype","toString","call","sscal","b","sscalcalculator","sstd","mu","sigma","sdwns","channels","factor","stride","N_out","Math","floor","M_out","sdwnscalculator","sclmp","Number","MIN_VALUE","MAX_VALUE","sclmpcalculator","isNumeric","parseFloat","fromArray","array","type","tranpose","data","c","shape","ii","jj","r","typedArray","result","constructor","i","j","globals","require","pipeline","SGEMMCalculator","SAXPYCalculator","SSCALCalculator","SDWNSCalculator","SCLMPCalculator","test","module","exports","gpu","bind","encode","util","String","format","args","arguments","this","replace","match","number","WebGL","async","loader","allclose","RTOL","ATOL","console","log","index","abs","randomArray","row","random","sqrt","push","padData","pad","padded","set","subarray","load","testDirectory","matrixFiles","callback","testFiles","map","item","err","results","matrices","JSON","parse","assert","t","msg","ok","actual","expected","_assert","message","operator","extra","t0","tOut","Tensor","texture","t1","t2","webgl","standalone","s","program","createProgram","p","TEXTURE_UNIFORM_NAME_0","TEXTURE_UNIFORM_NAME_1","LENGTH_UNIFORM_NAME","COEFFICIENT_UNIFORM_NAME","out","selectProgram","bindInputTexture","TEXTURE0","TEXTURE1","getPad","bindUniforms","bindOutputTexture","drawElements","TRIANGLES","UNSIGNED_SHORT","unbindInputTexture","textureUnit","name","activeTexture","bindTexture","TEXTURE_2D","sampler","getUniformLocation","uniform1i","N_gl","a_gl","uniform1f","ADD_UNIFORM_NAME","MUL_UNIFORM_NAME","mod","COMPONENTS_PER_TEXEL","b_gl","pad_gl","DownsampleCalculator","INPUT_ROW_COUNT_UNIFORM_NAME","INPUT_COLUMN_COUNT_UNIFORM_NAME","OUTPUT_ROW_COUNT_UNIFORM_NAME","OUTPUT_COLUMN_COUNT_UNIFORM_NAME","FACTOR_UNIFORM_NAME","STRIDE_UNIFORM_NAME","CHANNEL_COUNT_UNIFORM_NAME","M_gl","M_out_gl","N_out_gl","factor_gl","stride_gl","channel_count_gl","s_c","p_c","program_","program_c","TEXTURE_UNIFORM_NAME_2","SHARED_LENGTH_UNIFORM_NAME","COLUMN_COUNT_UNIFORM_NAME","PAD_UNIFORM_NAME","ALPHA_UNIFORM_NAME","BETA_UNIFORM_NAME","TEXTURE2","kPad","nPad","K_gl","alpha_gl","beta_gl","LOWER_UNIFORM_NAME","UPPER_UNIFORM_NAME","transfer","keep","reshape","tT","url","xhr","XMLHttpRequest","onreadystatechange","readyState","status","responseText","errno","open","send","noop","identity","v","toBool","notId","only_once","fn","apply","_once","_isArrayLike","arr","_isArray","_arrayEach","iterator","_map","Array","_range","count","_reduce","memo","x","_forEachOf","object","_keys","key","_indexOf","_keyIterator","coll","len","keys","_restParam","func","startIndex","max","rest","_withoutIndex","value","_eachOfLimit","limit","nextKey","done","running","errored","replenish","doParallel","eachOf","doParallelLimit","doSeries","eachOfSeries","_asyncMap","eachfn","_filter","sort","_reject","cb","_createTester","check","getResult","iteratee","_","_findGetResult","_parallel","tasks","task","_concat","y","concat","_queue","worker","concurrency","payload","_insert","q","pos","started","idle","setImmediate","drain","unshift","saturated","process","_next","workers","removed","workersList","splice","empty","paused","kill","pause","resume","resumeCount","min","w","_console_fn","error","_times","mapper","_applyEach","fns","go","that","pop","ensureAsync","innerArgs","sync","previous_async","root","self","global","noConflict","_toString","isArray","_isObject","k","hasOwnProperty","_setImmediate","_delay","setTimeout","nextTick","forEach","each","forEachSeries","eachSeries","forEachLimit","eachLimit","forEachOf","completed","iter","forEachOfSeries","iterate","forEachOfLimit","eachOfLimit","mapSeries","mapLimit","inject","foldl","reduce","foldr","reduceRight","reversed","reverse","transform","select","filter","selectLimit","filterLimit","selectSeries","filterSeries","reject","rejectLimit","rejectSeries","any","some","someLimit","all","every","everyLimit","detect","detectSeries","detectLimit","sortBy","comparator","left","right","criteria","auto","addListener","listeners","removeListener","idx","taskComplete","remainingTasks","slice","runningTasks","ready","requires","listener","taskCallback","dep","safeResults","val","rkey","retry","times","parseTimes","acc","parseInt","DEFAULT_TIMES","interval","DEFAULT_INTERVAL","wrappedTask","wrappedCallback","wrappedResults","retryAttempt","finalAttempt","seriesCallback","retryInterval","opts","attempts","series","waterfall","wrapIterator","next","parallel","parallelLimit","makeCallback","callArgs","concatSeries","whilst","doWhilst","calls","until","doUntil","during","truth","doDuring","queue","items","priorityQueue","_compareTasks","priority","_binarySearch","sequence","compare","beg","end","mid","cargo","dir","memoize","hasher","queues","memoized","l","unmemoized","unmemoize","timesSeries","timesLimit","seq","newargs","nextargs","compose","applyEach","applyEachSeries","forever","constant","values","wrapSync","asyncify","e","then","define","amd","options","glOptions","ext","canvas","document","createElement","premultipliedAlpha","preserveDrawingBuffer","getContext","getExtension","hasFloat","highp","getShaderPrecisionFormat","FRAGMENT_SHADER","HIGH_FLOAT","hasHighPrecision","precision","passThrough","vertexShader","createShader","VERTEX_SHADER","shaderSource","compileShader","encode_program","transpose_program","reshape_program","POSITION_UNIFORM_NAME","TEXTURE_UNIFORM_NAME","npad","mpad","npad_gl","mpad_gl","pad_out","M_in_gl","N_in_gl","pad_in_gl","fragmentShaderSource","fragmentShader","getShaderParameter","COMPILE_STATUS","getShaderInfoLog","attachShader","linkProgram","useProgram","bindVertices","renderer","position","getAttribLocation","vertexBuffer","createBuffer","bindBuffer","ARRAY_BUFFER","vertices","bufferData","STATIC_DRAW","vertexAttribPointer","FLOAT","enableVertexAttribArray","texCoords","textureCoords","indices","ELEMENT_ARRAY_BUFFER","vertexIndices","Uint16Array","h","texels","PAD_TEMPLATE","rem","createTexture","texImage2D","RGBA","remainder","full_texel_row_len","full_row_texture_width","row_start","last_texel","full_texel_row_end","buffer","BYTES_PER_ELEMENT","texSubImage2D","texParameteri","TEXTURE_WRAP_S","CLAMP_TO_EDGE","TEXTURE_WRAP_T","TEXTURE_MAG_FILTER","NEAREST","TEXTURE_MIN_FILTER","destTexture","UNSIGNED_BYTE","height","width","viewport","framebuffer","createFramebuffer","bindFramebuffer","FRAMEBUFFER","framebufferTexture2D","COLOR_ATTACHMENT0","checkFramebufferStatus","FRAMEBUFFER_COMPLETE","rawbuffer","ArrayBuffer","prod","Uint8Array","readPixels","cleanUpNextTick","draining","currentQueue","queueIndex","drainQueue","timeout","run","clearTimeout","Item","fun","title","browser","env","argv","version","versions","on","once","off","removeAllListeners","emit","binding","cwd","chdir","umask"],"mappings":"AAAA;ACiDA,QAASA,OAAMC,EAAGC,EAAGC,EAAGC,EAAOC,EAAGC,EAAGC,EAAMC,GAE1C,GAAQ,MAALA,GAAaA,EAAEC,QAAUP,EAC3B,KAAM,IAAIQ,OAAM,uEAIjB,IACCC,GADGC,EAAUP,EAEbQ,EAAUL,CAGXG,GAAUG,UAAUX,EAAGD,EAAGI,EAG1B,IAAIS,GAAWC,GAAGC,kBAAkBhB,EAAGE,EAAGS,GACtCM,EAAWF,GAAGC,kBAAkBf,EAAGC,EAAGQ,GACtCQ,EAAW,IACD,OAAXN,IACFM,EAAWH,GAAGC,kBAAkB,EAAGf,EAAGW,GAGvC,IAAIO,GAAWJ,GAAGK,oBAAoBpB,EAAGC,EAgBzC,OAdAoB,iBAAgBC,UAAUtB,EAAGC,EAAGC,EAAGC,EAAOW,EAAUG,EAAUX,EAAMY,EAAUC,GAG9EI,UAAYR,GAAGS,SAASxB,EAAGC,GAG3Bc,GAAGU,QAAQC,cAAcZ,GACzBC,GAAGU,QAAQC,cAAcT,GACV,MAAZC,GACFH,GAAGU,QAAQC,cAAcR,GAE1BH,GAAGU,QAAQC,cAAcP,GAGlB,GAAIQ,cAAaJ,WAIzB,QAASK,OAAM3B,EAAG4B,EAAGC,EAAGC,GAEvB,GAAIR,GAIHb,EADGC,EAAUmB,CAIXE,gBAAeD,GACjBrB,EAAUqB,GAEVrB,EAAU,GAAIiB,cAAa1B,GAC3BS,EAAQuB,KAAKF,GAId,IAAIjB,GAAWC,GAAGC,kBAAkB,EAAGf,EAAGU,GACtCM,EAAWF,GAAGC,kBAAkB,EAAGf,EAAGS,GAEtCS,EAAWJ,GAAGK,oBAAoB,EAAGnB,EAazC,OAXAiC,iBAAgBZ,UAAUrB,EAAG4B,EAAGf,EAAUG,EAAUE,GAGpDI,EAAYR,GAAGS,SAAS,EAAGvB,GAG3Bc,GAAGU,QAAQC,cAAcZ,GACzBC,GAAGU,QAAQC,cAAcT,GACzBF,GAAGU,QAAQC,cAAcP,GAGlB,GAAIQ,cAAaJ,GAIzB,QAASS,gBAAeG,GACvB,MAA+C,0BAAxCC,OAAOC,UAAUC,SAASC,KAAKJ,GAevC,QAASK,OAAMxC,EAAGC,EAAG4B,EAAGY,EAAGX,GAE1B,GAAIP,GAEAZ,EAAUmB,EACVhB,EAAWC,GAAGC,kBAAkBhB,EAAGC,EAAGU,GAEtCQ,EAAWJ,GAAGK,oBAAoBpB,EAAGC,EAYzC,OAVAyC,iBAAgBpB,UAAUtB,EAAGC,EAAG4B,EAAGY,EAAG3B,EAAUK,GAGhDI,EAAYR,GAAGS,SAASxB,EAAGC,GAG3Bc,GAAGU,QAAQC,cAAcZ,GACzBC,GAAGU,QAAQC,cAAcP,GAGlB,GAAIQ,cAAaJ,GAMzB,QAASoB,MAAK3C,EAAGC,EAAG2C,EAAIC,EAAOf,GAE9B,GAAIP,GAEAZ,EAAUmB,EACVhB,EAAWC,GAAGC,kBAAkBhB,EAAGC,EAAGU,GAEtCQ,EAAWJ,GAAGK,oBAAoBpB,EAAGC,EAazC,OAVAyC,iBAAgBpB,UAAUtB,EAAGC,EAAG,EAAI4C,EAAO,GAAOD,EAAGC,EAAO/B,EAAUK,GAGtEI,EAAYR,GAAGS,SAASxB,EAAGC,GAG3Bc,GAAGU,QAAQC,cAAcZ,GACzBC,GAAGU,QAAQC,cAAcP,GAGlB,GAAIQ,cAAaJ,GAYzB,QAASuB,OAAM9C,EAAGC,EAAG8C,EAAUC,EAAQC,EAAQnB,GAG9C,GAEIhB,GAAWC,GAAGC,kBAAkBhB,EAAGC,EAAI8C,EAAUjB,GAEjDoB,EAAQC,KAAKC,OAAOnD,EAAI+C,GAAUC,GAAU,EAC5CI,EAAQF,KAAKC,OAAOpD,EAAIgD,GAAUC,GAAU,EAE5C9B,EAAWJ,GAAGK,oBAAoBiC,EAAOH,EAAQH,EAYrD,OAVAO,iBAAgBhC,UAAUtB,EAAGC,EAAG8C,EAAUC,EAAQC,EAAQnC,EAAUK,GAGpEI,UAAYR,GAAGS,SAAS6B,EAAOH,EAAQH,GAGvChC,GAAGU,QAAQC,cAAcZ,GACzBC,GAAGU,QAAQC,cAAcP,GAGlB,GAAIQ,cAAaJ,WAmBzB,QAASgC,OAAMvD,EAAGC,EAAG4B,EAAGY,EAAGX,GAE1BD,EAAU,MAALA,EAAaA,EAAI2B,OAAOC,UAC7BhB,EAAU,MAALA,EAAaA,EAAIe,OAAOE,SAE7B,IAAInC,GAEAZ,EAAUmB,EACVhB,EAAWC,GAAGC,kBAAkBhB,EAAGC,EAAGU,GAEtCQ,EAAWJ,GAAGK,oBAAoBpB,EAAGC,EAYzC,OAVA0D,iBAAgBrC,UAAUtB,EAAGC,EAAG4B,EAAGY,EAAG3B,EAAUK,GAGhDI,EAAYR,GAAGS,SAASxB,EAAGC,GAG3Bc,GAAGU,QAAQC,cAAcZ,GACzBC,GAAGU,QAAQC,cAAcP,GAGlB,GAAIQ,cAAaJ,GAwCzB,QAASqC,WAAWzB,GAAQ,MAAQA,GAAM0B,WAAY1B,GAAQ,GAAM,EAGpE,QAAS2B,WAAUC,EAAOC,EAAMC,GAC/B,GACEC,GACAC,EAFEC,IAIAH,IAIHG,EAAM,GAAKL,EAAMvD,OACjB4D,EAAM,GAAKL,EAAM,GAAGvD,SAJpB4D,EAAM,GAAKL,EAAMvD,OACjB4D,EAAM,GAAKL,EAAM,GAAGvD,QAKrB2D,EAAIC,EAAM,GAEVJ,EAAOA,GAAQrC,aAEfuC,EAAO,GAAIF,GAAKI,EAAM,GAAGA,EAAM,GAE/B,KAAK,GAAIC,GAAK,EAAGA,EAAKD,EAAM,KAAMC,EACjC,IAAK,GAAIC,GAAK,EAAGA,EAAKF,EAAM,KAAME,EAC9BL,EAGHC,EAAKG,EAAGF,EAAIG,GAAMP,EAAMO,GAAID,GAF5BH,EAAKG,EAAGF,EAAIG,GAAMP,EAAMM,GAAIC,EAI9B,OAAOJ,GAKR,QAASrD,WAAU0D,EAAGJ,EAAGK,GAGxB,IAAI,GAFAC,GAAS,GAAID,GAAWE,YAAYH,EAAEJ,GAElCQ,EAAI,EAAOJ,EAAJI,EAAOA,IACrB,IAAI,GAAIC,GAAI,EAAOT,EAAJS,EAAOA,IACrBH,EAAOG,EAAIL,EAAII,GAAKH,EAAWG,EAAIR,EAAIS,EAIzC,OAAOH,GA1VR,GAAII,SAAUC,QAAQ,iBACrBC,SAAWD,QAAQ,kBACnBE,gBAAkBF,QAAQ,yBAC1BG,gBAAkBH,QAAQ,yBAC1BI,gBAAkBJ,QAAQ,yBAC1BK,gBAAkBL,QAAQ,yBAC1BM,gBAAkBN,QAAQ,yBAC1BO,KAAOP,QAAQ,cAEZ/D,GAAK8D,QAAQ9D,GAChBM,gBAAkB,GAAI2D,iBAAgBjE,IACtCmB,gBAAkB,GAAI+C,iBAAgBlE,IACtC2B,gBAAkB,GAAIwC,iBAAgBnE,IACtCuC,gBAAkB,GAAI6B,iBAAgBpE,IACtC4C,gBAAkB,GAAIyB,iBAAgBrE,GAEvCuE,QAAOC,SAEN3D,MAAUA,MACVY,MAAUA,MAGVzC,MAAUA,MAEV4C,KAASA,KACTG,MAASA,MACTS,MAASA,MAETwB,SAAaA,SAEbS,KAAUzE,GAAMA,GACZhB,MAASgF,SAAS1D,gBAAgBC,UAAUmE,KAAKV,SAAS1D,iBAC3DmB,MAAUuC,SAASrC,gBAAgBpB,UAAUmE,KAAKV,SAASrC,iBAC3Da,MAAUwB,SAASpB,gBAAgBrC,UAAUmE,KAAKV,SAASpB,iBAC3Db,MAAUiC,SAASzB,gBAAgBhC,UAAUmE,KAAKV,SAASzB,iBAC3DoC,OAAW3E,GAAG2E,OAAOD,KAAK1E,KAE7B4E,MAAW7B,UAAcA,UAAWjD,UAAcA,WAClDwE,KAASA,MA8PLO,OAAOvD,UAAUwD,SACpBD,OAAOvD,UAAUwD,OAAS,WAC3B,GAAIC,GAAOC,SACX,OAAOC,MAAKC,QAAQ,WAAY,SAASC,EAAOC,GAC9C,MAA8B,mBAAhBL,GAAKK,GAClBL,EAAKK,GACLD;;AC1SJ,GAAIE,OAAQtB,QAAQ,WAEhB/D,GAAK,GAAIqF,MAEbd,QAAOC,SACNxE,GAAOA;;AE2BR,QAASyB,OAAMX,EAAGY,EAAGqG,GAEpB,GAAI9I,GAAI8I,EAAG1E,MAAM,GAChBnE,EAAI6I,EAAG1E,MAAM,GAGV2E,EAAO,GAAIC,SAAQhJ,EAAGC,GAAI,KAI9B,OAFAyC,iBAAgBpB,UAAUtB,EAAGC,EAAG4B,EAAGY,EAAGqG,EAAGG,QAASF,EAAKE,SAEhDF,EAKR,QAAShJ,OAAMI,EAAO2I,EAAII,EAAI5I,EAAM6I,GAEnC,GAAGD,EAAG9E,MAAM,KAAO0E,EAAG1E,MAAM,GAC3B,KAAM,IAAI3D,OAAM,yFAEjB,IAIIS,GAJAlB,EAAI8I,EAAG1E,MAAM,GAChBnE,EAAIiJ,EAAG9E,MAAM,GACblE,EAAI4I,EAAG1E,MAAM,EAKblD,GADEiI,EACSA,EAAGF,QAEH,IAIZ,IAAIF,GAAO,GAAIC,SAAQhJ,EAAGC,GAAI,KAI9B,OAFAoB,iBAAgBC,UAAUtB,EAAGC,EAAGC,EAAGC,EAAO2I,EAAGG,QAASC,EAAGD,QAAS3I,EAAMY,EAAU6H,EAAKE,SAEhFF,EAGR,QAASjG,OAAMC,EAAUC,EAAQC,EAAQ6F,GAExC,GAAGA,EAAG1E,MAAM,GAAKrB,IAAa,EAC7B,KAAM,IAAItC,OAAM,4DAEjB,IAAIT,GAAI8I,EAAG1E,MAAM,GAChBnE,EAAI6I,EAAG1E,MAAM,GAAKrB,EAEfM,EAAQF,KAAKC,OAAOpD,EAAIgD,GAAUC,GAAU,EAC5CC,EAAQC,KAAKC,OAAOnD,EAAI+C,GAAUC,GAAU,EAG5C8F,EAAO,GAAIC,SAAQ3F,EAAOH,EAAQH,GAAW,KAIjD,OAFAO,iBAAgBhC,UAAUtB,EAAGC,EAAG8C,EAAUC,EAAQC,EAAQ6F,EAAGG,QAASF,EAAKE,SAEpEF,EAGR,QAASxF,OAAM1B,EAAGY,EAAGqG,GAEpBjH,EAAU,MAALA,EAAaA,EAAI2B,OAAOC,UAC7BhB,EAAU,MAALA,EAAaA,EAAIe,OAAOE,SAE7B,IAAI1D,GAAI8I,EAAG1E,MAAM,GAChBnE,EAAI6I,EAAG1E,MAAM,GAGV2E,EAAO,GAAIC,SAAQhJ,EAAGC,GAAI,KAI9B,OAFA0D,iBAAgBrC,UAAUtB,EAAGC,EAAG4B,EAAGY,EAAGqG,EAAGG,QAASF,EAAKE,SAEhDF,EAxGR,GAAIlE,SAAUC,QAAQ,aACrBE,gBAAkBF,QAAQ,qBAC1BG,gBAAkBH,QAAQ,qBAC1BI,gBAAkBJ,QAAQ,qBAC1BK,gBAAkBL,QAAQ,qBAC1BM,gBAAkBN,QAAQ,qBAC1BkE,OAASlE,QAAQ,YAGd/D,GAAK8D,QAAQ9D,GAChBM,gBAAkB,GAAI2D,iBAAgBjE,IAAI,GAC1CmB,gBAAkB,GAAI+C,iBAAgBlE,IAAI,GAC1C2B,gBAAkB,GAAIwC,iBAAgBnE,IAAI,GAC1CuC,gBAAkB,GAAI6B,iBAAgBpE,IAAI,GAC1C4C,gBAAkB,GAAIyB,iBAAgBrE,IAAI,EAE3CuE,QAAOC,SACNyD,OAAWA,OACXxG,MAAUA,MACVzC,MAAUA,MACV+C,MAAUA,MACVS,MAAUA,MAEVlC,gBAAoBA,gBACpBa,gBAAoBA,gBACpBQ,gBAAoBA,gBACpBY,gBAAoBA,gBACpBK,gBAAoBA;;ACRrB,QAASsB,iBAAgBmE,EAAOC,GAC/BrD,KAAKoD,MAAQA,EACbpD,KAAKqD,WAAaA,IAAc,CAGhC,IAAIC,GAAI,63EAMLtD,MAAKqD,WACPrD,KAAKuD,QAAUvD,KAAKoD,MAAMI,cAAcF,GAExCtD,KAAKuD,QAAUvD,KAAKoD,MAAMI,cAAcC,GAjC1C,GAAIrD,OAAQtB,QAAQ,UAqCpBQ,QAAOC,QAAUN,gBAKjBA,gBAAgByE,uBAAyB,IACzCzE,gBAAgB0E,uBAAyB,IACzC1E,gBAAgB2E,oBAAsB,IACtC3E,gBAAgB4E,yBAA2B,IAoB3C5E,gBAAgB5C,UAAUf,UAAY,SAASrB,EAAG4B,EAAGC,EAAGC,EAAG+H,GAE1D,GAAI/I,GAAKiF,KAAKoD,MAAM3H,OAOpBuE,MAAKoD,MAAMW,cAAc/D,KAAKuD,SAG9BvD,KAAKgE,iBAAiBlI,EAAGf,EAAGkJ,SAAUhF,gBAAgByE,wBACtD1D,KAAKgE,iBAAiBjI,EAAGhB,EAAGmJ,SAAUjF,gBAAgB0E,uBAGtD,IAAIvC,GAAMpB,KAAKoD,MAAMe,OAAOlK,EAE5B+F,MAAKoE,aAAanK,EAAImH,EAAKvF,GAG3BmE,KAAKoD,MAAMiB,kBAAkB,EAAGpK,EAAImH,EAAK0C,GAIzC/I,EAAGuJ,aAAavJ,EAAGwJ,UAAwB,EAAGxJ,EAAGyJ,eAAgB,GAEjExE,KAAKoD,MAAMqB,mBAAmB1J,EAAGkJ,UACjCjE,KAAKoD,MAAMqB,mBAAmB1J,EAAGmJ,WAclCjF,gBAAgB5C,UAAU2H,iBAAmB,SAASf,EAASyB,EAAaC,GAC3E,GAAI5J,GAAKiF,KAAKoD,MAAM3H,QACnB8H,EAAUvD,KAAKuD,OAEhBxI,GAAG6J,cAAcF,GACjB3J,EAAG8J,YAAe9J,EAAG+J,WAAY7B,EAEjC,IAAI8B,GAAUhK,EAAGiK,mBAAmBzB,EAASoB,EAC7C5J,GAAGkK,UAAUF,EAASL,EAAc3J,EAAGkJ,WAOxChF,gBAAgB5C,UAAU+H,aAAe,SAASnK,EAAG4B,GACpD,GAAId,GAAKiF,KAAKoD,MAAM3H,QAGhByJ,EAAOnK,EAAGiK,mBAAmBhF,KAAKuD,QAAStE,gBAAgB2E,qBAC9DuB,EAAOpK,EAAGiK,mBAAmBhF,KAAKuD,QAAStE,gBAAgB4E,yBAG5D9I,GAAGkK,UAAUC,EAAMjL,GACnBc,EAAGqK,UAAUD,EAAMtJ;;AI7GpB,QAASuD,iBAAgBgE,EAAOC,GAC/BrD,KAAKoD,MAAQA,EACbpD,KAAKqD,WAA4B,MAAdA,EAAsBA,GAAa,CAEtD,IAAIC,GAAI,qlFACPG,EAAI,4wCAKFzD,MAAKqD,WACPrD,KAAKuD,QAAUvD,KAAKoD,MAAMI,cAAcF,GAExCtD,KAAKuD,QAAUvD,KAAKoD,MAAMI,cAAcC,GAnC1C,GAAIrD,OAAQtB,QAAQ,UAuCpBQ,QAAOC,QAAUH,gBAKjBA,gBAAgBsE,uBAAyB,IACzCtE,gBAAgBwE,oBAAsB,IACtCxE,gBAAgBqI,mBAAqB,IACrCrI,gBAAgBsI,mBAAqB,IAqBrCtI,gBAAgB/C,UAAUf,UAAY,SAAStB,EAAGC,EAAG4B,EAAGY,EAAGX,EAAGgI,GAE7DjI,EAAU,MAALA,EAAaA,EAAI2B,OAAOC,UAC7BhB,EAAU,MAALA,EAAaA,EAAIe,OAAOE,SAE7B,IAAI3C,GAAKiF,KAAKoD,MAAM3H,OAEpBuE,MAAKoD,MAAMW,cAAc/D,KAAKuD,SAG9BvD,KAAKgE,iBAAiBlI,EAAGf,EAAGkJ,SAAU7E,gBAAgBsE,uBAEtD,IAAI2D,GAAOrH,KAAKoD,MAAMe,OAAOlK,EAE7B+F,MAAKoE,aAAanK,EAAGoN,EAAMxL,EAAGY,GAG3BuD,KAAKqD,WACPrD,KAAKoD,MAAMiB,kBAAkBrK,EAAGC,EAAIoN,EAAMvD,GAE1C9D,KAAKoD,MAAMiB,kBAAkBrK,GAAIC,EAAIoN,GAAO,EAAGvD,GAIhD/I,EAAGuJ,aAAavJ,EAAGwJ,UAAwB,EAAGxJ,EAAGyJ,eAAgB,GAEjExE,KAAKoD,MAAMqB,mBAAmB1J,EAAGkJ,WAclC7E,gBAAgB/C,UAAU2H,iBAAmB,SAASf,EAASyB,EAAaC,GAC3E,GAAI5J,GAAKiF,KAAKoD,MAAM3H,QACnB8H,EAAUvD,KAAKuD,OAEhBxI,GAAG6J,cAAcF,GACjB3J,EAAG8J,YAAe9J,EAAG+J,WAAY7B,EAEjC,IAAI8B,GAAUhK,EAAGiK,mBAAmBzB,EAASoB,EAC7C5J,GAAGkK,UAAUF,EAASL,EAAc3J,EAAGkJ,WAOxC7E,gBAAgB/C,UAAU+H,aAAe,SAASnK,EAAGmH,EAAKvF,EAAGY,GAC5D,GAAI1B,GAAKiF,KAAKoD,MAAM3H,QAGhByJ,EAAOnK,EAAGiK,mBAAmBhF,KAAKuD,QAASnE,gBAAgBwE,qBAC9D6B,EAAO1K,EAAGiK,mBAAmBhF,KAAKuD,QAASnE,gBAAgBsI,oBAC3DvC,EAAOpK,EAAGiK,mBAAmBhF,KAAKuD,QAASnE,gBAAgBqI,oBAC3D/B,EAAS3K,EAAGiK,mBAAmBhF,KAAKuD,QAAS,MAG9CxI,GAAGkK,UAAUC,EAAMjL,GACnBc,EAAGkK,UAAUS,EAAQtE,GACrBrG,EAAGqK,UAAUD,EAAMtJ,GACnBd,EAAGqK,UAAUK,EAAMhJ;;AF1HpB,QAASkJ,sBAAqBvC,EAAOC,GACpCrD,KAAKoD,MAAQA,EACbpD,KAAKqD,WAA4B,MAAdA,EAAsBA,GAAa,CAEtD,IAAIC,GAAI,qpGACPG,GAAI,+nDAKFzD,KAAKqD,WACPrD,KAAKuD,QAAUvD,KAAKoD,MAAMI,cAAcF,GAExCtD,KAAKuD,QAAUvD,KAAKoD,MAAMI,cAAcC,GA3B1C,GAAIrD,OAAQtB,QAAQ,UA+BpBQ,QAAOC,QAAUoG,qBAKjBA,qBAAqBjC,uBAAyB,IAC9CiC,qBAAqBC,6BAA+B,IACpDD,qBAAqBE,gCAAkC,IACvDF,qBAAqBG,8BAAgC,QACrDH,qBAAqBI,iCAAmC,QACxDJ,qBAAqBK,oBAAsB,SAC3CL,qBAAqBM,oBAAsB,SAC3CN,qBAAqBO,2BAA6B,IAsBlDP,qBAAqBtJ,UAAUf,UAAY,SAAStB,EAAGC,EAAG8C,EAAUC,EAAQC,EAAQnB,EAAGgI,GAEtF,GAAG/G,EAAWqD,MAAMoF,sBAAwB,EAC3C,KAAM,IAAI/K,OAAM,uCAAyC2F,MAAMoF,qBAEhE,IAAIzK,GAAKiF,KAAKoD,MAAM3H,QAEbyB,GAASC,KAAKC,OAAOnD,EAAI+C,GAAUC,GAAU,GAAKF,EAClDM,EAAQF,KAAKC,OAAOpD,EAAIgD,GAAUC,GAAU,CAEnD+C,MAAKoD,MAAMW,cAAc/D,KAAKuD,SAG9BvD,KAAKgE,iBAAiBlI,EAAGf,EAAGkJ,SAAU0B,qBAAqBjC,wBAI3D1D,KAAKoE,aAAapK,EAAGC,EAAI8C,EAAUM,EAAOH,EAAOF,EAAQC,EAAQF,GAG9DiD,KAAKqD,WACPrD,KAAKoD,MAAMiB,kBAAkBhH,EAAOH,EAAO4G,GAE3C9D,KAAKoD,MAAMiB,kBAAkBhH,EAAOH,EAAMkD,MAAMoF,qBAAsB1B,GAKvE/I,EAAGuJ,aAAavJ,EAAGwJ,UAAwB,EAAGxJ,EAAGyJ,eAAgB,GAEjExE,KAAKoD,MAAMqB,mBAAmB1J,EAAGkJ,WAYlC0B,qBAAqBtJ,UAAU2H,iBAAmB,SAASf,EAASyB,EAAaC,GAChF,GAAI5J,GAAKiF,KAAKoD,MAAM3H,QACnB8H,EAAUvD,KAAKuD,OAEhBxI,GAAG6J,cAAcF,GACjB3J,EAAG8J,YAAe9J,EAAG+J,WAAY7B,EAEjC,IAAI8B,GAAUhK,EAAGiK,mBAAmBzB,EAASoB,EAC7C5J,GAAGkK,UAAUF,EAASL,EAAc3J,EAAGkJ,WAOxC0B,qBAAqBtJ,UAAU+H,aAAe,SAASpK,EAAGC,EAAGoD,EAAOH,EAAOF,EAAQC,EAAQkB,GAC1F,GAAIpD,GAAKiF,KAAKoD,MAAM3H,QAGhB0K,EAAOpL,EAAGiK,mBAAmBhF,KAAKuD,QAASoC,qBAAqBC,8BACnEV,EAAOnK,EAAGiK,mBAAmBhF,KAAKuD,QAASoC,qBAAqBE,iCAChEO,EAAWrL,EAAGiK,mBAAmBhF,KAAKuD,QAASoC,qBAAqBG,+BACpEO,EAAWtL,EAAGiK,mBAAmBhF,KAAKuD,QAASoC,qBAAqBI,kCACpEO,EAAYvL,EAAGiK,mBAAmBhF,KAAKuD,QAASoC,qBAAqBK,qBACrEO,EAAYxL,EAAGiK,mBAAmBhF,KAAKuD,QAASoC,qBAAqBM,qBACrEO,EAAmBzL,EAAGiK,mBAAmBhF,KAAKuD,QAASoC,qBAAqBO,2BAG7EnL,GAAGqK,UAAUe,EAAMnM,GACnBe,EAAGqK,UAAUF,EAAMjL,GACnBc,EAAGqK,UAAUgB,EAAU/I,GACvBtC,EAAGqK,UAAUiB,EAAUnJ,GACvBnC,EAAGkK,UAAUqB,EAAWtJ,GACxBjC,EAAGqK,UAAUmB,EAAWtJ,GACxBlC,EAAGqK,UAAUoB,EAAkBrI;;AC1HhC,QAASa,iBAAgBoE,EAAOC,GAC/BrD,KAAKoD,MAAQA,EACbpD,KAAKqD,WAA4B,MAAdA,EAAsBA,GAAa,CAGtD,IAAIC,GAAI,2/GACPmD,EAAM,owIACNhD,EAAI,qgGACJiD,EAAM,mnGAKJ1G,MAAKqD,YACPrD,KAAK2G,SAAW3G,KAAKoD,MAAMI,cAAcF,GACzCtD,KAAK4G,UAAY5G,KAAKoD,MAAMI,cAAciD,KAE1CzG,KAAK2G,SAAW3G,KAAKoD,MAAMI,cAAcC,GACzCzD,KAAK4G,UAAY5G,KAAKoD,MAAMI,cAAckD,IArC5C,GAAItG,OAAQtB,QAAQ,UA0CpBQ,QAAOC,QAAUP,gBAKjBA,gBAAgB0E,uBAAyB,IACzC1E,gBAAgB2E,uBAAyB,MACzC3E,gBAAgB6H,uBAAyB,IACzC7H,gBAAgB8H,2BAA6B,IAC7C9H,gBAAgB+H,0BAA4B,IAC5C/H,gBAAgBgI,iBAAmB,MACnChI,gBAAgBiI,mBAAqB,QACrCjI,gBAAgBkI,kBAAoB,OA0BpClI,gBAAgB3C,UAAUf,UAAY,SAAStB,EAAGC,EAAGC,EAAGC,EAAOC,EAAGC,EAAGC,EAAMC,EAAGuJ,GAE7E,GAAI/I,GAAKiF,KAAKoD,MAAM3H,OAQZ,OAALlB,EACFyF,KAAKuD,QAAUvD,KAAK4G,WAEpBtM,EAAO,KACP0F,KAAKuD,QAAUvD,KAAK2G,UAGrB3G,KAAKoD,MAAMW,cAAc/D,KAAKuD,SAG9BvD,KAAKgE,iBAAiB5J,EAAGW,EAAGkJ,SAAUjF,gBAAgB0E,wBACtD1D,KAAKgE,iBAAiB3J,EAAGU,EAAGmJ,SAAUlF,gBAAgB2E,wBAC9C,MAALpJ,GACFyF,KAAKgE,iBAAiBzJ,EAAGQ,EAAGoM,SAAUnI,gBAAgB6H,uBAGvD,IAAIO,GAAOpH,KAAKoD,MAAMe,OAAOjK,GAC5BmN,EAAOrH,KAAKoD,MAAMe,OAAOlK,EAG1B+F,MAAKoE,aAAanK,EAAGC,EAAIkN,EAAMC,EAAMlN,EAAOG,GAGzC0F,KAAKqD,WACPrD,KAAKoD,MAAMiB,kBAAkBrK,EAAGC,EAAIoN,EAAMvD,GAE1C9D,KAAKoD,MAAMiB,kBAAkBrK,GAAIC,EAAIoN,GAAO,EAAGvD,GAIhD/I,EAAGuJ,aAAavJ,EAAGwJ,UAAwB,EAAGxJ,EAAGyJ,eAAgB,GAEjExE,KAAKoD,MAAMqB,mBAAmB1J,EAAGkJ,UACjCjE,KAAKoD,MAAMqB,mBAAmB1J,EAAGmJ,UACjClE,KAAKoD,MAAMqB,mBAAmB1J,EAAGoM,WAiBlCnI,gBAAgB3C,UAAU2H,iBAAmB,SAASf,EAASyB,EAAaC,GAC3E,GAAI5J,GAAKiF,KAAKoD,MAAM3H,QACnB8H,EAAUvD,KAAKuD,OAEhBxI,GAAG6J,cAAcF,GACjB3J,EAAG8J,YAAe9J,EAAG+J,WAAY7B,EAEjC,IAAI8B,GAAUhK,EAAGiK,mBAAmBzB,EAASoB,EAC7C5J,GAAGkK,UAAUF,EAASL,EAAc3J,EAAGkJ,WASxCjF,gBAAgB3C,UAAU+H,aAAe,SAASnK,EAAGC,EAAGkH,EAAKjH,EAAOG,GACnE,GAAIS,GAAKiF,KAAKoD,MAAM3H,QAGhB6L,EAAQvM,EAAGiK,mBAAmBhF,KAAKuD,QAASvE,gBAAgB8H,4BAC/DS,EAAWxM,EAAGiK,mBAAmBhF,KAAKuD,QAASvE,gBAAgBiI,oBAC/DO,EAAUzM,EAAGiK,mBAAmBhF,KAAKuD,QAASvE,gBAAgBkI,mBAC9DhC,EAAOnK,EAAGiK,mBAAmBhF,KAAKuD,QAASvE,gBAAgB+H,2BAC3DrB,EAASA,EAAS3K,EAAGiK,mBAAmBhF,KAAKuD,QAASvE,gBAAgBgI,iBAEvEjM,GAAGqK,UAAUoC,EAASlN,GACtBS,EAAGkK,UAAUC,EAAMjL,GACnBc,EAAGkK,UAAUS,EAAQtE,GAGrBrG,EAAGkK,UAAUqC,EAAMpN,GAEnBa,EAAGqK,UAAUmC,EAAUpN;;AF3JxB,QAAS+E,iBAAgBkE,EAAOC,GAC/BrD,KAAKoD,MAAQA,EACbpD,KAAKqD,WAA4B,MAAdA,EAAsBA,GAAa,CAEtD,IAAIC,GAAI,m5EACPG,EAAI,qtCAKFzD,MAAKqD,WACPrD,KAAKuD,QAAUvD,KAAKoD,MAAMI,cAAcF,GAExCtD,KAAKuD,QAAUvD,KAAKoD,MAAMI,cAAcC,GAjC1C,GAAIrD,OAAQtB,QAAQ,UAqCpBQ,QAAOC,QAAUL,gBAKjBA,gBAAgBwE,uBAAyB,IACzCxE,gBAAgB0E,oBAAsB,IACtC1E,gBAAgBmG,iBAAmB,IACnCnG,gBAAgBoG,iBAAmB,IAoBnCpG,gBAAgB7C,UAAUf,UAAY,SAAStB,EAAGC,EAAG4B,EAAGY,EAAGX,EAAGgI,GAE7D,GAAI/I,GAAKiF,KAAKoD,MAAM3H,QAEhB8J,EAAOtL,EAAImG,MAAMoF,qBACpBpE,EAAa,GAAPmE,EAAW,EAAInF,MAAMoF,qBAAuBD,CAEnDvF,MAAKoD,MAAMW,cAAc/D,KAAKuD,SAG9BvD,KAAKgE,iBAAiBlI,EAAGf,EAAGkJ,SAAU/E,gBAAgBwE,wBAGtD1D,KAAKoE,aAAanK,EAAGmH,EAAKvF,EAAGY,GAG1BuD,KAAKqD,WACPrD,KAAKoD,MAAMiB,kBAAkBrK,EAAGC,EAAImH,EAAK0C,GAEzC9D,KAAKoD,MAAMiB,kBAAkBrK,GAAIC,EAAImH,GAAM,EAAG0C,GAK/C/I,EAAGuJ,aAAavJ,EAAGwJ,UAAwB,EAAGxJ,EAAGyJ,eAAgB,GAEjExE,KAAKoD,MAAMqB,mBAAmB1J,EAAGkJ,WAYlC/E,gBAAgB7C,UAAU2H,iBAAmB,SAASf,EAASyB,EAAaC,GAC3E,GAAI5J,GAAKiF,KAAKoD,MAAM3H,QACnB8H,EAAUvD,KAAKuD,OAEhBxI,GAAG6J,cAAcF,GACjB3J,EAAG8J,YAAe9J,EAAG+J,WAAY7B,EAEjC,IAAI8B,GAAUhK,EAAGiK,mBAAmBzB,EAASoB,EAC7C5J,GAAGkK,UAAUF,EAASL,EAAc3J,EAAGkJ,WAOxC/E,gBAAgB7C,UAAU+H,aAAe,SAASnK,EAAGmH,EAAKvF,EAAGY,GAC5D,GAAI1B,GAAKiF,KAAKoD,MAAM3H,QAGhByJ,EAAOnK,EAAGiK,mBAAmBhF,KAAKuD,QAASrE,gBAAgB0E,qBAC9D6B,EAAO1K,EAAGiK,mBAAmBhF,KAAKuD,QAASrE,gBAAgBmG,kBAC3DF,EAAOpK,EAAGiK,mBAAmBhF,KAAKuD,QAASrE,gBAAgBoG,kBAC3DI,EAAS3K,EAAGiK,mBAAmBhF,KAAKuD,QAAS,MAG9CxI,GAAGkK,UAAUC,EAAMjL,GACnBc,EAAGkK,UAAUS,EAAQtE,GACrBrG,EAAGqK,UAAUD,EAAMtJ,GACnBd,EAAGqK,UAAUK,EAAMhJ;;AI/HpB,QAASuG,QAAO5E,EAAOF,GACtB,GAAmB,GAAhBE,EAAM5D,OACR,KAAM,IAAIC,OAAM,4DAEjB,IAAIT,GAAIoE,EAAM,GACbnE,EAAImE,EAAM,EAEX4B,MAAKiD,QAAUlI,GAAGC,kBAAkBhB,EAAGC,EAAGiE,GAE1C8B,KAAK5B,OAASpE,EAAGC,GAblB,GAAI4E,SAAUC,QAAQ,aAElB/D,GAAK8D,QAAQ9D,EAcjBuE,QAAOC,QAAUyD,OAEjBA,OAAO3G,UAAP2G,UAA0B,WACzBjI,GAAGU,QAAQC,cAAcsE,KAAKiD,SAC9BjD,KAAKiD,QAAU,KACfjD,KAAK5B,MAAQ,MAGd4E,OAAO3G,UAAUsL,SAAW,SAASC,GAEpC,GAEC9D,GACArF,EAHGzE,EAAIgG,KAAK5B,MAAM,GAClBnE,EAAI+F,KAAK5B,MAAM,EAmBhB,OAdA0F,GAAM/I,GAAGK,oBAAoBpB,EAAGC,GAGhCc,GAAG2E,OAAO1F,EAAGC,EAAG+F,KAAKiD,QAASa,GAE9BrF,EAAS,GAAI9C,cAAaZ,GAAGS,SAASxB,EAAGC,IAGzCc,GAAGU,QAAQC,cAAcoI,GAErB8D,GACH5H,KAAAA,YAGMvB,GAGRuE,OAAO3G,UAAUwL,QAAU,SAASzJ,EAAOwJ,GAE1C,GAAI5N,GAAIgG,KAAK5B,MAAM,GAClBnE,EAAI+F,KAAK5B,MAAM,GACff,EAAQe,EAAM,GACdlB,EAAQkB,EAAM,GAGX0E,EAAK,GAAIE,QAAO5E,EAAO,KAS3B,OANArD,IAAG8M,QAAQ7N,EAAGC,EAAGoD,EAAOH,EAAO8C,KAAKiD,QAASH,EAAGG,SAE5C2E,GACH5H,KAAAA,YAGM8C,GAGRE,OAAO3G,UAAUxB,UAAY,SAAS+M,GAErC,GAAI5N,GAAIgG,KAAK5B,MAAM,GAClBnE,EAAI+F,KAAK5B,MAAM,GAGZ0J,EAAK,GAAI9E,SAAQ/I,EAAGD,GAAI,KAS5B,OANAe,IAAGF,UAAUb,EAAGC,EAAG+F,KAAKiD,QAAS6E,EAAG7E,SAEhC2E,GACH5H,KAAAA,YAGM8H;;APpFR,GAAIzH,OAAQvB,QAAQ,SACnBwB,OAASxB,QAAQ,UAIlBO,SAUAA,KAAKkB,SAAW,SAAS1E,EAAGY,EAAG+D,EAAMC,GAIpC,GAHAD,EAAMA,GAAQ,KACdC,EAAMA,GAAQ,KAEX5E,EAAErB,QAAUiC,EAAEjC,OAEhB,MADAkG,SAAQC,IAAI,sBAAwB9E,EAAErB,OAAS,KAAOiC,EAAEjC,SAChDiE,QAAW,EAAOmC,MAAS,KAIpC,KAAI,GADAnC,GACIE,EAAI,EAAGA,EAAI9C,EAAErB,OAAQmE,IAI5B,GAFAF,EAAStB,KAAK0D,IAAIhF,EAAE8C,GAAKlC,EAAEkC,KAAO8B,EAAOD,EAAOrD,KAAK0D,IAAIpE,EAAEkC,KAEvDF,EACH,OAAQA,QAAU,EAAOmC,MAASjC,EAIpC,QAAQF,QAAU,EAAMmC,MAASjC,IAGlCU,KAAKyB,YAAc,SAAS7G,EAAGD,GAI9B,IAAI,GAFAkE,MAEIS,EAAI,EAAO1E,EAAJ0E,EAAOA,IAAI,CAEzB,IAAI,GADAoC,MACInC,EAAI,EAAO5E,EAAJ4E,EAAOA,IACrBmC,EAAInC,GAAKzB,KAAK6D,SAAW7D,KAAK8D,KAAKhH,EAEpCiE,GAAKgD,KAAKH,GAGX,MAAO7C,IAGRmB,KAAK8B,QAAU,SAASnH,EAAGC,EAAGmH,EAAKlD,GAGlC,IAAI,GADAmD,GAAS,GAAI1F,cAAa3B,GAAKC,EAAImH,IAC/BzC,EAAI,EAAO3E,EAAJ2E,EAAOA,IACrB0C,EAAOC,IAAIpD,EAAKqD,SAAS5C,EAAI1E,GAAI0E,EAAI,GAAK1E,GAAI0E,GAAK1E,EAAImH,GAExD,OAAOC,IASRhC,KAAKmC,KAAO,SAASC,EAAeC,EAAaC,GAGhD,GAAIC,GAAYF,EAAYG,IAAI,SAASC,GAAO,MAAOL,GAAgBK,GAGvEzB,OAAMwB,IAAID,EAAWtB,OAAOkB,KAC3B,SAASO,EAAKC,GAEb,GAAGD,EAAK,MAAOJ,GAASI,EAKxB,IAAIE,GAAWD,EAAQH,IAAIK,KAAKC,MAEhCR,GAASI,EAAKE,MAKjB5C,KAAK+C,UAGL/C,KAAK+C,OAAO7B,SAAW,SAAS8B,EAAGxG,EAAGY,EAAG6F,EAAK9B,EAAMC,GAEnD,GAAI8B,GAAKlD,KAAKkB,SAAS1E,EAAGY,EAAG+D,EAAMC,GAClC+B,EAAS,IACTC,EAAW,GAEZ,KAAIF,EAAG9D,OAAO,CAEV8D,EAAG3B,MAAQ,IACb4B,GAAU,QACVC,GAAY,SAEVF,EAAG3B,MAAQ,IACb4B,GAAU3G,EAAE0G,EAAG3B,MAAQ,GAAK,KAC5B6B,GAAYhG,EAAE8F,EAAG3B,MAAQ,GAAK,MAE/B4B,GAAU,MACVC,GAAY,KAEZ,KAAI,GAAI9D,GAAI4D,EAAG3B,MAAOjC,EAAI4D,EAAG3B,MAAQ,GAAKjC,EAAI9C,EAAErB,OAAQmE,IACvD6D,GAAU3G,EAAE8C,GAAK,KACjB8D,GAAYhG,EAAEkC,GAAK,IAEjBA,GAAI9C,EAAErB,QACRgI,GAAU,OACVC,GAAY,SAEZD,GAAU,IACVC,GAAY,KAEbH,EAAMA,GAAO,yBAA2BC,EAAG3B,MAGzCyB,EAAEK,QAAQH,EAAG9D,QACTkE,QAAUL,GAAO,qBACjBM,SAAW,WACXJ,OAASA,EACTC,SAAWA,EACXI,MAAQ,QAIhBvD,OAAOC,QAAUF;;AU/GjB,QAASe,OAAMmY,GAEd,GAAIC,GACHC,CAcD,IAZAF,EAAUA,MAGmB,mBAAnBA,GAAQG,OACjB1Y,KAAK0Y,OAASC,SAASC,cAAc,UAErC5Y,KAAK0Y,OAASH,EAAQG,OAGvBF,GAAcK,oBAAoB,EAAOC,uBAAuB,GAChE9Y,KAAKvE,QAAUuE,KAAK0Y,OAAOK,WAAW,qBAAsBP,GAEhC,mBAAjBxY,MAAKvE,QACf,KAAM,IAAIhB,OAAM,wBAGjB,KACCge,EAAMzY,KAAKvE,QAAQud,aAAa,qBAC/B,MAAMb,IAGFM,EAILzY,KAAKiZ,UAAW,GAHhBvY,QAAQC,IAAI,+CACZX,KAAKiZ,UAAW,EAKjB,IAAIC,GAAQlZ,KAAKvE,QAAQ0d,yBAAyBnZ,KAAKvE,QAAQ2d,gBAAiBpZ,KAAKvE,QAAQ4d,WAC7FrZ,MAAKsZ,iBAAsC,GAAnBJ,EAAMK,UAC3BvZ,KAAKsZ,mBAAkBtZ,KAAKkZ,MAAQA,EAGvC,IAAIM,GAAc,4UAClBxZ,MAAKyZ,aAAezZ,KAAKvE,QAAQie,aAAa1Z,KAAKvE,QAAQke,eAC3D3Z,KAAKvE,QAAQme,aAAa5Z,KAAKyZ,aAAcD,GAC7CxZ,KAAKvE,QAAQoe,cAAc7Z,KAAKyZ,aAEhC,IAAI/Z,GAAS,otEACZ7E,EAAY,+qEACZgN,EAAU,qyGAEX7H,MAAK8Z,eAAiB9Z,KAAKwD,cAAc9D,GACzCM,KAAK+Z,kBAAoB/Z,KAAKwD,cAAc3I,GAC5CmF,KAAKga,gBAAkBha,KAAKwD,cAAcqE,GAG3CvI,OAAOC,QAAUa,MAGjBA,MAAMoF,qBAAuB,EAE7BpF,MAAM6Z,sBAAwB,MAC9B7Z,MAAM8Z,qBAAuB,MAG7B9Z,MAAM/D,UAAUqD,OAAS,SAAS1F,EAAGC,EAAGa,EAAUgJ,GAEjD9D,KAAKuD,QAAUvD,KAAK8Z,eACpB9Z,KAAK+D,cAAc/D,KAAKuD,QAExB,IAAInC,GAAMpB,KAAKmE,OAAOlK,GAElBiL,EAAOlF,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,KACxDmC,EAAS1F,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,MAExDvD,MAAKvE,QAAQwJ,UAAUC,EAAMjL,GAC7B+F,KAAKvE,QAAQwJ,UAAUS,EAAQtE,GAE/BpB,KAAKgE,iBAAiBlJ,EAAUkF,KAAKvE,QAAQwI,SAAU,KAEvDjE,KAAKqE,kBAAkBrK,EAAGC,EAAG6J,GAE7B9D,KAAKvE,QAAQ6I,aAAatE,KAAKvE,QAAQ8I,UAAwB,EAAGvE,KAAKvE,QAAQ+I,eAAgB,GAE/FxE,KAAKyE,mBAAmBzE,KAAKvE,QAAQwI,WAKtC7D,MAAM/D,UAAUxB,UAAY,SAASb,EAAGC,EAAGa,EAAUgJ,GAEpD9D,KAAKuD,QAAUvD,KAAK+Z,kBACpB/Z,KAAK+D,cAAc/D,KAAKuD,QAExB,IAAI4W,GAAOna,KAAKmE,OAAOlK,GACtBmgB,EAAOpa,KAAKmE,OAAOnK,GAGhBkL,EAAOlF,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,KACxD8W,EAAUra,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,QACxD4C,EAAOnG,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,KACrD+W,EAAUta,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,OAEzDvD,MAAKvE,QAAQwJ,UAAUC,EAAMlL,GAC7BgG,KAAKvE,QAAQwJ,UAAUoV,EAASD,GAChCpa,KAAKvE,QAAQwJ,UAAUkB,EAAMlM,GAC7B+F,KAAKvE,QAAQwJ,UAAUqV,EAASH,GAEhCna,KAAKgE,iBAAiBlJ,EAAUkF,KAAKvE,QAAQwI,SAAU,KAEvDjE,KAAKqE,kBAAkBpK,GAAID,EAAIogB,GAAM,EAAGtW,GAExC9D,KAAKvE,QAAQ6I,aAAatE,KAAKvE,QAAQ8I,UAAwB,EAAGvE,KAAKvE,QAAQ+I,eAAgB,GAE/FxE,KAAKyE,mBAAmBzE,KAAKvE,QAAQwI,WAKtC7D,MAAM/D,UAAUwL,QAAU,SAAS7N,EAAGC,EAAGoD,EAAOH,EAAOpC,EAAUgJ,GAEhE9D,KAAKuD,QAAUvD,KAAKga,gBACpBha,KAAK+D,cAAc/D,KAAKuD,QAExB,IAAInC,GAAMpB,KAAKmE,OAAOlK,GACrBsgB,EAAUva,KAAKmE,OAAOjH,GAGnBiJ,EAAOnG,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,KACxD2B,EAAOlF,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,KACrDmC,EAAS1F,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,OACvDiX,EAAUxa,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,QACxDkX,EAAUza,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,QACxDmX,EAAY1a,KAAKvE,QAAQuJ,mBAAmBhF,KAAKuD,QAAS,SAE3DvD,MAAKvE,QAAQ2J,UAAUe,EAAM9I,GAC7B2C,KAAKvE,QAAQ2J,UAAUF,EAAMhI,GAC7B8C,KAAKvE,QAAQ2J,UAAUM,EAAQ6U,GAC/Bva,KAAKvE,QAAQ2J,UAAUoV,EAASxgB,GAChCgG,KAAKvE,QAAQ2J,UAAUqV,EAASxgB,GAChC+F,KAAKvE,QAAQ2J,UAAUsV,EAAWtZ,GAElCpB,KAAKgE,iBAAiBlJ,EAAUkF,KAAKvE,QAAQwI,SAAU,KAEvDjE,KAAKqE,kBAAkBhH,GAAQH,EAAQqd,GAAS,EAAGzW,GAEnD9D,KAAKvE,QAAQ6I,aAAatE,KAAKvE,QAAQ8I,UAAwB,EAAGvE,KAAKvE,QAAQ+I,eAAgB,GAE/FxE,KAAKyE,mBAAmBzE,KAAKvE,QAAQwI,WAGtC7D,MAAM/D,UAAU2H,iBAAmB,SAASf,EAASyB,EAAaC,GACjE,GAAI5J,GAAKiF,KAAKvE,QACb8H,EAAUvD,KAAKuD,OAEhBxI,GAAG6J,cAAcF,GACjB3J,EAAG8J,YAAe9J,EAAG+J,WAAY7B,EAEjC,IAAI8B,GAAUhK,EAAGiK,mBAAmBzB,EAASoB,EAC7C5J,GAAGkK,UAAUF,EAASL,EAAc3J,EAAGkJ,WAWxC7D,MAAM/D,UAAUmH,cAAgB,SAASmX,GACxC,GACCC,GADG7f,EAAKiF,KAAKvE,OASd,IALAmf,EAAiB7f,EAAG2e,aAAa3e,EAAGqe,iBACpCre,EAAG6e,aAAagB,EAAgBD,GAChC5f,EAAG8e,cAAce,GAG+C,GAA5D7f,EAAG8f,mBAAmBD,EAAgB7f,EAAG+f,gBAC5C,KAAM,IAAIrgB,OAAMM,EAAGggB,iBAAiBH,GAIrC,IAAIrX,GAAUxI,EAAGyI,eAKjB,OAJAzI,GAAGigB,aAAazX,EAASvD,KAAKyZ,cAC9B1e,EAAGigB,aAAazX,EAASqX,GACzB7f,EAAGkgB,YAAY1X,GAERA,GAGRnD,MAAM/D,UAAU0H,cAAgB,SAASR,GAExC,GAAIxI,GAAKiF,KAAKvE,OAGdV,GAAGmgB,WAAW3X,GAEdvD,KAAKmb,aAAa5X,IAMnBnD,MAAM/D,UAAU8e,aAAe,SAAS5X,GACvC,GAAIxI,GAAKiF,KAAKvE,QACb2f,EAAW7X,EAGR8X,EAAWtgB,EAAGugB,kBAAkBF,EAAUhb,MAAM6Z,uBAChDsB,EAAexgB,EAAGygB,cACtBzgB,GAAG0gB,WAAW1gB,EAAG2gB,aAAcH,EAG/B,IAAII,IAAY,GAAM,GAAM,EACvB,EAAK,GAAM,EACX,EAAM,EAAK,EACZ,GAAO,EAAK,EAChB5gB,GAAG6gB,WAAW7gB,EAAG2gB,aAAc,GAAI/f,cAAaggB,GAAW5gB,EAAG8gB,aAC9D9gB,EAAG+gB,oBAAoBT,EAAuB,EAAGtgB,EAAGghB,OAAO,EAAO,EAAG,GACrEhhB,EAAGihB,wBAAwBX,EAG3B,IAAIpY,GAAUlI,EAAGugB,kBAAkBF,EAAUhb,MAAM8Z,sBAC/C+B,EAAYlhB,EAAGygB,cACnBzgB,GAAG0gB,WAAW1gB,EAAG2gB,aAAcO,EAC/B,IAAIC,IAAiB,EAAK,EACpB,EAAK,EACL,EAAK,EACL,EAAK,EACXnhB,GAAG6gB,WAAW7gB,EAAG2gB,aAAc,GAAI/f,cAAaugB,GAAgBnhB,EAAG8gB,aACnE9gB,EAAG+gB,oBAAoB7Y,EAAsB,EAAGlI,EAAGghB,OAAO,EAAO,EAAG,GACpEhhB,EAAGihB,wBAAwB/Y,EAG3B,IAAIkZ,GAAUphB,EAAGygB,cACjBzgB,GAAG0gB,WAAW1gB,EAAGqhB,qBAAsBD,EAGvC,IAAIE,IAAiB,EAAG,EAAG,EACrB,EAAG,EAAG,EACZthB,GAAG6gB,WAAW7gB,EAAGqhB,qBAAsB,GAAIE,aAAYD,GAAgBthB,EAAG8gB,cAW3Ezb,MAAM/D,UAAUrB,kBAAoB,SAASuhB,EAAGjO,EAAGkO,GAElD,GAAIzhB,GAAKiF,KAAKvE,QAEVghB,GAAgB,EAAK,EAAK,EAAK,GAE/BC,EAAOpO,EAAIlO,MAAMoF,qBACpBpE,EAAa,GAAPsb,EAAW,EAAItc,MAAMoF,qBAAuBkX,EAG/CzZ,EAAUlI,EAAG4hB,eAUjB,IARA5hB,EAAG8J,YAAe9J,EAAG+J,WAAY7B,GAQvB,GAAP7B,GAAsB,MAAVob,GAAoC,mBAAXA,GAEvCzhB,EAAG6hB,WAAc7hB,EAAG+J,WAAY,EAAG/J,EAAG8hB,MAAOvO,EAAIlN,GAAOhB,MAAMoF,qBAAsB+W,EAAG,EACjFxhB,EAAG8hB,KAAM9hB,EAAGghB,MAAOS,OAEnB,CAINzhB,EAAG6hB,WAAc7hB,EAAG+J,WAAY,EAAG/J,EAAG8hB,MAAOvO,EAAIlN,GAAOhB,MAAMoF,qBAAsB+W,EAAG,EACjFxhB,EAAG8hB,KAAM9hB,EAAGghB,MAAO,KAWzB,KAAI,GAJAhb,GAAK+b,EALLC,EAAqBzO,EAAIoO,EAC5BM,EAAyBD,EAAqB3c,MAAMoF,qBAEjDyX,EAAY,EACZC,EAAa,GAAIvhB,cAAa8gB,GAK1B9d,EAAI,EAAO4d,EAAJ5d,EAAOA,IACrBse,EAAYte,EAAI2P,EAChB6O,mBAAqBF,EAAYF,EACjChc,EAAM,GAAIpF,cAAa6gB,EAAOY,OAAQH,EAAYT,EAAOa,kBAAmBN,GACzEA,EAAqB,GAEvBhiB,EAAGuiB,cAAcviB,EAAG+J,WAClB,EACA,EACAnG,EACAqe,EACA,EACAjiB,EAAG8hB,KACH9hB,EAAGghB,MACHhb,GAIH+b,EAAY,GAAInhB,cAAa6gB,EAAOY,OAAQD,mBAAqBX,EAAOa,kBAAmBX,GAC3FQ,EAAW5b,IAAIwb,GAEf/hB,EAAGuiB,cAAcviB,EAAG+J,WAClB,EACAkY,EACAre,EACA,EACA,EACA5D,EAAG8hB,KACH9hB,EAAGghB,MACHmB,GAgBJ,MAVAniB,GAAGwiB,cAAcxiB,EAAG+J,WAAY/J,EAAGyiB,eAAgBziB,EAAG0iB,eACtD1iB,EAAGwiB,cAAcxiB,EAAG+J,WAAY/J,EAAG2iB,eAAgB3iB,EAAG0iB,eAGtD1iB,EAAGwiB,cAAexiB,EAAG+J,WAAY/J,EAAG4iB,mBAAoB5iB,EAAG6iB,SAC3D7iB,EAAGwiB,cAAexiB,EAAG+J,WAAY/J,EAAG8iB,mBAAoB9iB,EAAG6iB,SAG3D7iB,EAAG8J,YAAY9J,EAAG+J,WAAY,MAEvB7B,GAUR7C,MAAM/D,UAAUjB,oBAAsB,SAASmhB,EAAGjO,GACjD,GAAIvT,GAAKiF,KAAKvE,QAEV2F,EAAMpB,KAAKmE,OAAOmK,GAGlBwP,EAAc/iB,EAAG4hB,eAerB,OAbA5hB,GAAG8J,YAAY9J,EAAG+J,WAAYgZ,GAC9B/iB,EAAG6hB,WAAW7hB,EAAG+J,WAAoB,EAAG/J,EAAG8hB,KAAMvO,EAAIlN,EAAKmb,EAAG,EAAGxhB,EAAG8hB,KAAM9hB,EAAGgjB,cAAe,MAG3FhjB,EAAGwiB,cAAcxiB,EAAG+J,WAAY/J,EAAGyiB,eAAgBziB,EAAG0iB,eACtD1iB,EAAGwiB,cAAcxiB,EAAG+J,WAAY/J,EAAG2iB,eAAgB3iB,EAAG0iB,eAEtD1iB,EAAGwiB,cAAexiB,EAAG+J,WAAY/J,EAAG4iB,mBAAoB5iB,EAAG6iB,SAC3D7iB,EAAGwiB,cAAexiB,EAAG+J,WAAY/J,EAAG8iB,mBAAoB9iB,EAAG6iB,SAG3D7iB,EAAG8J,YAAY9J,EAAG+J,WAAY,MAEvBgZ,GASR1d,MAAM/D,UAAUgI,kBAAoB,SAASrK,EAAGC,EAAGgJ,GAClD,GAAIlI,GAAKiF,KAAKvE,OAed,IAZAuE,KAAK0Y,OAAOsF,OAAShkB,EACrBgG,KAAK0Y,OAAOuF,MAAQhkB,EACpBc,EAAGmjB,SAAS,EAAG,EAAGjkB,EAAGD,GAGrBgG,KAAKme,YAAcne,KAAKme,aAAepjB,EAAGqjB,oBAE1CrjB,EAAGsjB,gBAAgBtjB,EAAGujB,YAAate,KAAKme,aAExCpjB,EAAGwjB,qBAAqBxjB,EAAGujB,YAAavjB,EAAGyjB,kBAAmBzjB,EAAG+J,WAAY7B,EAAkB,GAG3FlI,EAAG0jB,uBAAuB1jB,EAAGujB,cAAgBvjB,EAAG2jB,qBACnD,KAAM,IAAIjkB,OAAM,qCAEjB,OAAOuF,MAAKme,aAGb/d,MAAM/D,UAAUoI,mBAAqB,SAASC,GAC7C,GAAI3J,GAAKiF,KAAKvE,OAEdV,GAAG6J,cAAcF,GACjB3J,EAAG8J,YAAY9J,EAAG+J,WAAY,OAI/B1E,MAAM/D,UAAUb,SAAW,SAASxB,EAAGC,GACtC,GAAIc,GAAKiF,KAAKvE,OAUd,OAPAkjB,WAAY,GAAIC,aAAY5kB,EAAEC,EAAE0B,aAAa0hB,mBAG7CwB,KAAO,GAAIC,YAAWH,WACtB5jB,EAAGgkB,WAAW,EAAG,EAAG9kB,EAAGD,EAAGe,EAAG8hB,KAAM9hB,EAAGgjB,cAAec,MAG9CF,WAIRve,MAAM/D,UAAU8H,OAAS,SAASlK,GAEjC,GAAIyiB,GAAOziB,EAAImG,MAAMoF,qBACpBpE,EAAa,GAAPsb,EAAW,EAAItc,MAAMoF,qBAAuBkX,CAEnD,OAAOtb;;;CDzbP,WAGG,QAASqH,MACT,QAASC,GAASC,GACd,MAAOA,GAEX,QAASC,GAAOD,GACZ,QAASA,EAEb,QAASE,GAAMF,GACX,OAAQA,EAsBZ,QAASG,GAAUC,GACf,MAAO,YACH,GAAW,OAAPA,EAAa,KAAM,IAAItO,OAAM,+BACjCsO,GAAGC,MAAMhJ,KAAMD,WACfgJ,EAAK,MAIb,QAASE,GAAMF,GACX,MAAO,YACQ,OAAPA,IACJA,EAAGC,MAAMhJ,KAAMD,WACfgJ,EAAK,OAkBb,QAASG,GAAaC,GAClB,MAAOC,GAASD,IAEU,gBAAfA,GAAI3O,QACX2O,EAAI3O,QAAU,GACd2O,EAAI3O,OAAS,IAAM,EAI3B,QAAS6O,GAAWF,EAAKG,GAIrB,IAHA,GAAI1I,GAAQ,GACRpG,EAAS2O,EAAI3O,SAERoG,EAAQpG,GACb8O,EAASH,EAAIvI,GAAQA,EAAOuI,GAIpC,QAASI,GAAKJ,EAAKG,GAKf,IAJA,GAAI1I,GAAQ,GACRpG,EAAS2O,EAAI3O,OACbiE,EAAS+K,MAAMhP,KAEVoG,EAAQpG,GACbiE,EAAOmC,GAAS0I,EAASH,EAAIvI,GAAQA,EAAOuI,EAEhD,OAAO1K,GAGX,QAASgL,GAAOC,GACZ,MAAOH,GAAKC,MAAME,GAAQ,SAAUf,EAAGhK,GAAK,MAAOA,KAGvD,QAASgL,GAAQR,EAAKG,EAAUM,GAI5B,MAHAP,GAAWF,EAAK,SAAUU,EAAGlL,EAAG9C,GAC5B+N,EAAON,EAASM,EAAMC,EAAGlL,EAAG9C,KAEzB+N,EAGX,QAASE,GAAWC,EAAQT,GACxBD,EAAWW,EAAMD,GAAS,SAAUE,GAChCX,EAASS,EAAOE,GAAMA,KAI9B,QAASC,GAASf,EAAKrH,GACnB,IAAK,GAAInD,GAAI,EAAGA,EAAIwK,EAAI3O,OAAQmE,IAC5B,GAAIwK,EAAIxK,KAAOmD,EAAM,MAAOnD,EAEhC,OAAO,GAaX,QAASwL,GAAaC,GAClB,GACIC,GACAC,EAFA3L,EAAI,EAGR,OAAIuK,GAAakB,IACbC,EAAMD,EAAK5P,OACJ,WAEH,MADAmE,KACW0L,EAAJ1L,EAAUA,EAAI,QAGzB2L,EAAON,EAAMI,GACbC,EAAMC,EAAK9P,OACJ,WAEH,MADAmE,KACW0L,EAAJ1L,EAAU2L,EAAK3L,GAAK,OAQvC,QAAS4L,GAAWC,EAAMC,GAEtB,MADAA,GAA2B,MAAdA,EAAqBD,EAAKhQ,OAAS,GAAKiQ,EAC9C,WAGH,IAAK,GAFDjQ,GAAS2C,KAAKuN,IAAI3K,UAAUvF,OAASiQ,EAAY,GACjDE,EAAOnB,MAAMhP,GACRoG,EAAQ,EAAWpG,EAARoG,EAAgBA,IAChC+J,EAAK/J,GAASb,UAAUa,EAAQ6J,EAEpC,QAAQA,GACJ,IAAK,GAAG,MAAOD,GAAKjO,KAAKyD,KAAM2K,EAC/B,KAAK,GAAG,MAAOH,GAAKjO,KAAKyD,KAAMD,UAAU,GAAI4K,KAYzD,QAASC,GAActB,GACnB,MAAO,UAAUuB,EAAOjK,EAAOe,GAC3B,MAAO2H,GAASuB,EAAOlJ,IA8G/B,QAASmJ,GAAaC,GAElB,MAAO,UAAU5O,EAAKmN,EAAU3H,GAC5BA,EAAWsH,EAAMtH,GAAY8G,GAC7BtM,EAAMA,KACN,IAAI6O,GAAUb,EAAahO,EAC3B,IAAa,GAAT4O,EACA,MAAOpJ,GAAS,KAEpB,IAAIsJ,IAAO,EACPC,EAAU,EACVC,GAAU,GAEd,QAAUC,KACN,GAAIH,GAAmB,GAAXC,EACR,MAAOvJ,GAAS,KAGpB,MAAiBoJ,EAAVG,IAAoBC,GAAS,CAChC,GAAIlB,GAAMe,GACV,IAAY,OAARf,EAKA,MAJAgB,IAAO,OACQ,GAAXC,GACAvJ,EAAS,MAIjBuJ,IAAW,EACX5B,EAASnN,EAAI8N,GAAMA,EAAKnB,EAAU,SAAU/G,GACxCmJ,GAAW,EACPnJ,GACAJ,EAASI,GACToJ,GAAU,GAGVC,YASxB,QAASC,GAAWtC,GAChB,MAAO,UAAU5M,EAAKmN,EAAU3H,GAC5B,MAAOoH,GAAG1I,EAAMiL,OAAQnP,EAAKmN,EAAU3H,IAG/C,QAAS4J,GAAgBxC,GACrB,MAAO,UAAU5M,EAAK4O,EAAOzB,EAAU3H,GACnC,MAAOoH,GAAG+B,EAAaC,GAAQ5O,EAAKmN,EAAU3H,IAGtD,QAAS6J,GAASzC,GACd,MAAO,UAAU5M,EAAKmN,EAAU3H,GAC5B,MAAOoH,GAAG1I,EAAMoL,aAActP,EAAKmN,EAAU3H,IAIrD,QAAS+J,GAAUC,EAAQxC,EAAKG,EAAU3H,GACtCA,EAAWsH,EAAMtH,GAAY8G,GAC7BU,EAAMA,KACN,IAAInH,GAAUkH,EAAaC,QAC3BwC,GAAOxC,EAAK,SAAU0B,EAAOjK,EAAOe,GAChC2H,EAASuB,EAAO,SAAU9I,EAAK4G,GAC3B3G,EAAQpB,GAAS+H,EACjBhH,EAASI,MAEd,SAAUA,GACTJ,EAASI,EAAKC,KA2CtB,QAAS4J,GAAQD,EAAQxC,EAAKG,EAAU3H,GACpC,GAAIK,KACJ2J,GAAOxC,EAAK,SAAUU,EAAGjJ,EAAOe,GAC5B2H,EAASO,EAAG,SAAUlB,GACdA,GACA3G,EAAQd,MAAMN,MAAOA,EAAOiK,MAAOhB,IAEvClI,OAEL,WACCA,EAAS4H,EAAKvH,EAAQ6J,KAAK,SAAUhQ,EAAGY,GACpC,MAAOZ,GAAE+E,MAAQnE,EAAEmE,QACnB,SAAUiJ,GACV,MAAOA,GAAEgB,WAcrB,QAASiB,GAAQH,EAAQxC,EAAKG,EAAU3H,GACpCiK,EAAQD,EAAQxC,EAAK,SAAS0B,EAAOkB,GACjCzC,EAASuB,EAAO,SAASlC,GACrBoD,GAAIpD,MAEThH,GAMP,QAASqK,GAAcL,EAAQM,EAAOC,GAClC,MAAO,UAAS/C,EAAK4B,EAAOzB,EAAUyC,GAClC,QAASd,KACDc,GAAIA,EAAGG,GAAU,EAAO,SAEhC,QAASC,GAAStC,EAAGuC,EAAGzK,GACpB,MAAKoK,OACLzC,GAASO,EAAG,SAAUlB,GACdoD,GAAME,EAAMtD,KACZoD,EAAGG,GAAU,EAAMrC,IACnBkC,EAAKzC,GAAW,GAEpB3H,MANYA,IAShB5B,UAAUvF,OAAS,EACnBmR,EAAOxC,EAAK4B,EAAOoB,EAAUlB,IAE7Bc,EAAKzC,EACLA,EAAWyB,EACXY,EAAOxC,EAAKgD,EAAUlB,KAelC,QAASoB,GAAe1D,EAAGkB,GACvB,MAAOA,GAsOX,QAASyC,GAAUX,EAAQY,EAAO5K,GAC9BA,EAAWA,GAAY8G,CACvB,IAAIzG,GAAUkH,EAAaqD,QAE3BZ,GAAOY,EAAO,SAAUC,EAAMvC,EAAKtI,GAC/B6K,EAAKjC,EAAW,SAAUxI,EAAKjC,GACvBA,EAAKtF,QAAU,IACfsF,EAAOA,EAAK,IAEhBkC,EAAQiI,GAAOnK,EACf6B,EAASI,OAEd,SAAUA,GACTJ,EAASI,EAAKC,KAwCtB,QAASyK,GAAQd,EAAQxC,EAAKJ,EAAIpH,GAC9B,GAAIlD,KACJkN,GAAOxC,EAAK,SAAUU,EAAGjJ,EAAOmL,GAC5BhD,EAAGc,EAAG,SAAU9H,EAAK2K,GACjBjO,EAASA,EAAOkO,OAAOD,OACvBX,EAAGhK,MAER,SAAUA,GACTJ,EAASI,EAAKtD,KA+EtB,QAASmO,GAAOC,EAAQC,EAAaC,GAOjC,QAASC,GAAQC,EAAG/O,EAAMgP,EAAKvL,GAC3B,GAAgB,MAAZA,GAAwC,kBAAbA,GAC3B,KAAM,IAAIlH,OAAM,mCAMpB,OAJAwS,GAAEE,SAAU,EACP/D,EAASlL,KACVA,GAAQA,IAEO,IAAhBA,EAAK1D,QAAgByS,EAAEG,OAEf/M,EAAMgN,aAAa,WACtBJ,EAAEK,WAGVjE,EAAWnL,EAAM,SAASsO,GACtB,GAAI1K,IACA5D,KAAMsO,EACN7K,SAAUA,GAAY8G,EAGtByE,GACAD,EAAEV,MAAMgB,QAAQzL,GAEhBmL,EAAEV,MAAMrL,KAAKY,GAGbmL,EAAEV,MAAM/R,SAAWyS,EAAEH,aACrBG,EAAEO,kBAGVnN,GAAMgN,aAAaJ,EAAEQ,UAEzB,QAASC,GAAMT,EAAGV,GACd,MAAO,YACHoB,GAAW,CAEX,IAAIC,IAAU,EACV9N,EAAOC,SACXsJ,GAAWkD,EAAO,SAAUC,GACxBnD,EAAWwE,EAAa,SAAUhB,EAAQjM,GAClCiM,IAAWL,GAASoB,IACpBC,EAAYC,OAAOlN,EAAO,GAC1BgN,GAAU,KAIlBpB,EAAK7K,SAASqH,MAAMwD,EAAM1M,KAE1BmN,EAAEV,MAAM/R,OAASmT,IAAY,GAC7BV,EAAEK,QAENL,EAAEQ,WAzDV,GAAmB,MAAfX,EACAA,EAAc,MAEb,IAAmB,IAAhBA,EACJ,KAAM,IAAIrS,OAAM,+BAyDpB,IAAIkT,GAAU,EACVE,KACAZ,GACAV,SACAO,YAAaA,EACbC,QAASA,EACTS,UAAW/E,EACXsF,MAAOtF,EACP6E,MAAO7E,EACP0E,SAAS,EACTa,QAAQ,EACR9M,KAAM,SAAUhD,EAAMyD,GAClBqL,EAAQC,EAAG/O,GAAM,EAAOyD,IAE5BsM,KAAM,WACFhB,EAAEK,MAAQ7E,EACVwE,EAAEV,UAENgB,QAAS,SAAUrP,EAAMyD,GACrBqL,EAAQC,EAAG/O,GAAM,EAAMyD,IAE3B8L,QAAS,WACL,IAAKR,EAAEe,QAAUL,EAAUV,EAAEH,aAAeG,EAAEV,MAAM/R,OAChD,KAAMmT,EAAUV,EAAEH,aAAeG,EAAEV,MAAM/R,QAAO,CAC5C,GAAI+R,GAAQU,EAAEF,QACVE,EAAEV,MAAMuB,OAAO,EAAGb,EAAEF,SACpBE,EAAEV,MAAMuB,OAAO,EAAGb,EAAEV,MAAM/R,QAE1B0D,EAAOqL,EAAKgD,EAAO,SAAUC,GAC7B,MAAOA,GAAKtO,MAGO,KAAnB+O,EAAEV,MAAM/R,QACRyS,EAAEc,QAENJ,GAAW,EACXE,EAAY3M,KAAKqL,EAAM,GACvB,IAAIR,GAAKjD,EAAU4E,EAAMT,EAAGV,GAC5BM,GAAO3O,EAAM6N,KAIzBvR,OAAQ,WACJ,MAAOyS,GAAEV,MAAM/R,QAEnB0Q,QAAS,WACL,MAAOyC,IAEXE,YAAa,WACT,MAAOA,IAEXT,KAAM,WACF,MAAOH,GAAEV,MAAM/R,OAASmT,IAAY,GAExCO,MAAO,WACHjB,EAAEe,QAAS,GAEfG,OAAQ,WACJ,GAAIlB,EAAEe,UAAW,EAAjB,CACAf,EAAEe,QAAS,CAIX,KAAK,GAHDI,GAAcjR,KAAKkR,IAAIpB,EAAEH,YAAaG,EAAEV,MAAM/R,QAGzC8T,EAAI,EAAQF,GAALE,EAAkBA,IAC9BjO,EAAMgN,aAAaJ,EAAEQ,WAIjC,OAAOR,GA+EX,QAASsB,GAAY5J,GACjB,MAAO4F,GAAW,SAAUxB,EAAIjJ,GAC5BiJ,EAAGC,MAAM,KAAMlJ,EAAK6M,QAAQpC,EAAW,SAAUxI,EAAKjC,GAC3B,gBAAZY,WACHqB,EACIrB,QAAQ8N,OACR9N,QAAQ8N,MAAMzM,GAGbrB,QAAQiE,IACb0E,EAAWvJ,EAAM,SAAU+J,GACvBnJ,QAAQiE,GAAMkF,aAmDtC,QAAS4E,GAAOC,GACZ,MAAO,UAAUhF,EAAOJ,EAAU3H,GAC9B+M,EAAOjF,EAAOC,GAAQJ,EAAU3H,IAsCxC,QAASgN,GAAWhD,GAChB,MAAOpB,GAAW,SAASqE,EAAK9O,GAC5B,GAAI+O,GAAKtE,EAAW,SAASzK,GACzB,GAAIgP,GAAO9O,KACP2B,EAAW7B,EAAKiP,KACpB,OAAOpD,GAAOiD,EAAK,SAAU7F,EAAIqD,EAAGL,GAChChD,EAAGC,MAAM8F,EAAMhP,EAAK6M,QAAQZ,MAEhCpK,IAEJ,OAAI7B,GAAKtF,OACEqU,EAAG7F,MAAMhJ,KAAMF,GAGf+O,IAqBnB,QAASG,GAAYjG,GACjB,MAAOwB,GAAW,SAAUzK,GACxB,GAAI6B,GAAW7B,EAAKiP,KACpBjP,GAAKoB,KAAK,WACN,GAAI+N,GAAYlP,SACZmP,GACA7O,EAAMgN,aAAa,WACf1L,EAASqH,MAAM,KAAMiG,KAGzBtN,EAASqH,MAAM,KAAMiG,IAG7B,IAAIC,IAAO,CACXnG,GAAGC,MAAMhJ,KAAMF,GACfoP,GAAO,IA/qCf,GAaIC,GAbA9O,KAkBA+O,EAAuB,gBAATC,OAAqBA,KAAKA,OAASA,MAAQA,MACnC,gBAAXC,SAAuBA,OAAOA,SAAWA,QAAUA,QAC1DtP,IAEI,OAARoP,IACAD,EAAiBC,EAAK/O,OAG1BA,EAAMkP,WAAa,WAEf,MADAH,GAAK/O,MAAQ8O,EACN9O,EAqBX,IAAImP,GAAYpT,OAAOC,UAAUC,SAE7B8M,EAAWI,MAAMiG,SAAW,SAAUtT,GACtC,MAA+B,mBAAxBqT,EAAUjT,KAAKJ,IAItBuT,EAAY,SAASvT,GACrB,GAAI6B,SAAc7B,EAClB,OAAgB,aAAT6B,GAAgC,WAATA,KAAuB7B,GAwDrD6N,EAAQ5N,OAAOkO,MAAQ,SAAUnO,GACjC,GAAImO,KACJ,KAAK,GAAIqF,KAAKxT,GACNA,EAAIyT,eAAeD,IACnBrF,EAAKpJ,KAAKyO,EAGlB,OAAOrF,IA2DPuF,EAAwC,kBAAjBxC,eAA+BA,aAEtDyC,EAASD,EAAgB,SAAS9G,GAElC8G,EAAc9G,IACd,SAASA,GACTgH,WAAWhH,EAAI,GAGI,iBAAZ0E,UAAoD,kBAArBA,SAAQuC,SAC9C3P,EAAM2P,SAAWvC,QAAQuC,SAEzB3P,EAAM2P,SAAWF,EAErBzP,EAAMgN,aAAewC,EAAgBC,EAASzP,EAAM2P,SAGpD3P,EAAM4P,QACN5P,EAAM6P,KAAO,SAAU/G,EAAKG,EAAU3H,GAClC,MAAOtB,GAAMiL,OAAOnC,EAAKyB,EAActB,GAAW3H,IAGtDtB,EAAM8P,cACN9P,EAAM+P,WAAa,SAAUjH,EAAKG,EAAU3H,GACxC,MAAOtB,GAAMoL,aAAatC,EAAKyB,EAActB,GAAW3H,IAI5DtB,EAAMgQ,aACNhQ,EAAMiQ,UAAY,SAAUnH,EAAK4B,EAAOzB,EAAU3H,GAC9C,MAAOmJ,GAAaC,GAAO5B,EAAKyB,EAActB,GAAW3H,IAG7DtB,EAAMkQ,UACNlQ,EAAMiL,OAAS,SAAUvB,EAAQT,EAAU3H,GAcvC,QAASsJ,GAAKlJ,GACVyO,IACIzO,EACAJ,EAASI,GAII,OAARkI,GAA6B,GAAbuG,GACrB7O,EAAS,MArBjBA,EAAWsH,EAAMtH,GAAY8G,GAC7BsB,EAASA,KAKT,KAHA,GACIE,GADAwG,EAAOtG,EAAaJ,GACfyG,EAAY,EAEI,OAAjBvG,EAAMwG,MACVD,GAAa,EACblH,EAASS,EAAOE,GAAMA,EAAKnB,EAAUmC,GAGvB,KAAduF,GAAiB7O,EAAS,OAelCtB,EAAMqQ,gBACNrQ,EAAMoL,aAAe,SAAUtP,EAAKmN,EAAU3H,GAK1C,QAASgP,KACL,GAAIzB,IAAO,CACX,OAAY,QAARjF,EACOtI,EAAS,OAEpB2H,EAASnN,EAAI8N,GAAMA,EAAKnB,EAAU,SAAU/G,GACxC,GAAIA,EACAJ,EAASI,OAER,CAED,GADAkI,EAAMe,IACM,OAARf,EACA,MAAOtI,GAAS,KAEZuN,GACA7O,EAAMgN,aAAasD,GAEnBA,aAKhBzB,GAAO,IA1BXvN,EAAWsH,EAAMtH,GAAY8G,GAC7BtM,EAAMA,KACN,IAAI6O,GAAUb,EAAahO,GACvB8N,EAAMe,GAyBV2F,MAKJtQ,EAAMuQ,eACNvQ,EAAMwQ,YAAc,SAAU1U,EAAK4O,EAAOzB,EAAU3H,GAChDmJ,EAAaC,GAAO5O,EAAKmN,EAAU3H,IA6EvCtB,EAAMwB,IAAMwJ,EAAWK,GACvBrL,EAAMyQ,UAAYtF,EAASE,GAC3BrL,EAAM0Q,SAAWxF,EAAgBG,GAIjCrL,EAAM2Q,OACN3Q,EAAM4Q,MACN5Q,EAAM6Q,OAAS,SAAU/H,EAAKS,EAAMN,EAAU3H,GAC1CtB,EAAMoL,aAAatC,EAAK,SAAUU,EAAGlL,EAAGgD,GACpC2H,EAASM,EAAMC,EAAG,SAAU9H,EAAK4G,GAC7BiB,EAAOjB,EACPhH,EAASI,MAEd,SAAUA,GACTJ,EAASI,EAAK6H,MAItBvJ,EAAM8Q,MACN9Q,EAAM+Q,YAAc,SAAUjI,EAAKS,EAAMN,EAAU3H,GAC/C,GAAI0P,GAAW9H,EAAKJ,EAAKT,GAAU4I,SACnCjR,GAAM6Q,OAAOG,EAAUzH,EAAMN,EAAU3H,IAG3CtB,EAAMkR,UAAY,SAAUpI,EAAKS,EAAMN,EAAU3H,GACpB,IAArB5B,UAAUvF,SACVmH,EAAW2H,EACXA,EAAWM,EACXA,EAAOR,EAASD,UAGpB9I,EAAMiL,OAAOnC,EAAK,SAASR,EAAGgH,EAAG5D,GAC7BzC,EAASM,EAAMjB,EAAGgH,EAAG5D,IACtB,SAAShK,GACRJ,EAASI,EAAK6H,MAsBtBvJ,EAAMmR,OACNnR,EAAMoR,OAASpG,EAAWO,GAE1BvL,EAAMqR,YACNrR,EAAMsR,YAAcpG,EAAgBK,GAEpCvL,EAAMuR,aACNvR,EAAMwR,aAAerG,EAASI,GAS9BvL,EAAMyR,OAASzG,EAAWS,GAC1BzL,EAAM0R,YAAcxG,EAAgBO,GACpCzL,EAAM2R,aAAexG,EAASM,GA2B9BzL,EAAM4R,IACN5R,EAAM6R,KAAOlG,EAAc3L,EAAMiL,OAAQ1C,EAAQF,GAEjDrI,EAAM8R,UAAYnG,EAAc3L,EAAMwQ,YAAajI,EAAQF,GAE3DrI,EAAM+R,IACN/R,EAAMgS,MAAQrG,EAAc3L,EAAMiL,OAAQzC,EAAOA,GAEjDxI,EAAMiS,WAAatG,EAAc3L,EAAMwQ,YAAahI,EAAOA,GAK3DxI,EAAMkS,OAASvG,EAAc3L,EAAMiL,OAAQ5C,EAAU2D,GACrDhM,EAAMmS,aAAexG,EAAc3L,EAAMoL,aAAc/C,EAAU2D,GACjEhM,EAAMoS,YAAczG,EAAc3L,EAAMwQ,YAAanI,EAAU2D,GAE/DhM,EAAMqS,OAAS,SAAUvJ,EAAKG,EAAU3H,GAsBpC,QAASgR,GAAWC,EAAMC,GACtB,GAAIhX,GAAI+W,EAAKE,SAAUrW,EAAIoW,EAAMC,QACjC,OAAWrW,GAAJZ,EAAQ,GAAKA,EAAIY,EAAI,EAAI,EAvBpC4D,EAAMwB,IAAIsH,EAAK,SAAUU,EAAGlI,GACxB2H,EAASO,EAAG,SAAU9H,EAAK+Q,GACnB/Q,EACAJ,EAASI,GAGTJ,EAAS,MAAOkJ,MAAOhB,EAAGiJ,SAAUA,OAG7C,SAAU/Q,EAAKC,GACd,MAAID,GACOJ,EAASI,OAGhBJ,GAAS,KAAM4H,EAAKvH,EAAQ6J,KAAK8G,GAAa,SAAU9I,GACpD,MAAOA,GAAEgB,YAYzBxK,EAAM0S,KAAO,SAAUxG,EAAOO,EAAanL,GAoBvC,QAASqR,GAAYjK,GACjBkK,EAAU1F,QAAQxE,GAEtB,QAASmK,GAAenK,GACpB,GAAIoK,GAAMjJ,EAAS+I,EAAWlK,EAC1BoK,IAAO,GAAGF,EAAUnF,OAAOqF,EAAK,GAExC,QAASC,KACLC,IACAhK,EAAW4J,EAAUK,MAAM,GAAI,SAAUvK,GACrCA,MA7BHpH,IAEDA,EAAWmL,EACXA,EAAc,MAElBnL,EAAWsH,EAAMtH,GAAY8G,EAC7B,IAAI6B,GAAON,EAAMuC,GACb8G,EAAiB/I,EAAK9P,MAC1B,KAAK6Y,EACD,MAAO1R,GAAS,KAEfmL,KACDA,EAAcuG,EAGlB,IAAIrR,MACAuR,EAAe,EAEfN,IAeJD,GAAY,WACHK,GACD1R,EAAS,KAAMK,KAIvBqH,EAAWiB,EAAM,SAAUqF,GAgCvB,QAAS6D,KACL,MAAsB1G,GAAfyG,GAA8B5J,EAAQ8J,EAAU,SAAU5X,EAAGgO,GAChE,MAAQhO,IAAKmG,EAAQ4N,eAAe/F,KACrC,KAAU7H,EAAQ4N,eAAeD,GASxC,QAAS+D,KACDF,MACAD,IACAL,EAAeQ,GACflH,EAAKA,EAAKhS,OAAS,GAAGmZ,EAAc3R,IAxB5C,IAvBA,GAsBI4R,GAtBApH,EAAOpD,EAASmD,EAAMoD,IAAMpD,EAAMoD,IAAKpD,EAAMoD,IAC7CgE,EAAepJ,EAAW,SAASxI,EAAKjC,GAKxC,GAJAyT,IACIzT,EAAKtF,QAAU,IACfsF,EAAOA,EAAK,IAEZiC,EAAK,CACL,GAAI8R,KACJ/J,GAAW9H,EAAS,SAAS8R,EAAKC,GAC9BF,EAAYE,GAAQD,IAExBD,EAAYlE,GAAK7P,EACjB6B,EAASI,EAAK8R,OAGd7R,GAAQ2N,GAAK7P,EACbO,EAAMgN,aAAa+F,KAGvBK,EAAWjH,EAAK8G,MAAM,EAAG9G,EAAKhS,OAAS,GAEvC6P,EAAMoJ,EAASjZ,OAEZ6P,KAAO,CACV,KAAMuJ,EAAMrH,EAAMkH,EAASpJ,KACvB,KAAM,IAAI5P,OAAM,4BAEpB,IAAI2O,EAASwK,IAAQ1J,EAAS0J,EAAKjE,IAAM,EACrC,KAAM,IAAIlV,OAAM,2BAQpB+Y,KACAD,IACA/G,EAAKA,EAAKhS,OAAS,GAAGmZ,EAAc3R,IAGpCgR,EAAYU,MAcxBrT,EAAM2T,MAAQ,SAASC,EAAOzH,EAAM7K,GAWhC,QAASuS,GAAWC,EAAK9R,GACrB,GAAgB,gBAANA,GACN8R,EAAIF,MAAQG,SAAS/R,EAAG,KAAOgS,MAC5B,CAAA,GAAgB,gBAANhS,GAIb,KAAM,IAAI5H,OAAM,gDAAqD4H,GAHrE8R,GAAIF,MAAQG,SAAS/R,EAAE4R,MAAO,KAAOI,EACrCF,EAAIG,SAAWF,SAAS/R,EAAEiS,SAAU,KAAOC,GAmBnD,QAASC,GAAYC,EAAiBC,GAClC,QAASC,GAAanI,EAAMoI,GACxB,MAAO,UAASC,GACZrI,EAAK,SAASzK,EAAKtD,GACfoW,GAAgB9S,GAAO6S,GAAe7S,IAAKA,EAAKtD,OAAQA,KACzDiW,IAIX,QAASI,GAAcR,GACnB,MAAO,UAASO,GACZ9E,WAAW,WACP8E,EAAe,OAChBP,IAIX,KAAOS,EAAKd,OAAO,CAEf,GAAIW,KAAiBG,EAAKd,OAAO,EACjCe,GAAS9T,KAAKyT,EAAaI,EAAKvI,KAAMoI,KAClCA,GAAgBG,EAAKT,SAAW,GAChCU,EAAS9T,KAAK4T,EAAcC,EAAKT,WAIzCjU,EAAM4U,OAAOD,EAAU,SAAS/J,EAAM/M,GAClCA,EAAOA,EAAKA,EAAK1D,OAAS,IACzBia,GAAmBM,EAAKpT,UAAUzD,EAAK6D,IAAK7D,EAAKO,UA9D1D,GAAI4V,GAAgB,EAChBE,EAAmB,EAEnBS,KAEAD,GACAd,MAAOI,EACPC,SAAUC,GAcV/Z,EAASuF,UAAUvF,MACvB,IAAa,EAATA,GAAcA,EAAS,EACvB,KAAM,IAAIC,OAAM,wGA4CpB,OA3CqB,IAAVD,GAAgC,kBAAVyZ,KAC7BtS,EAAW6K,EACXA,EAAOyH,GAEU,kBAAVA,IACPC,EAAWa,EAAMd,GAErBc,EAAKpT,SAAWA,EAChBoT,EAAKvI,KAAOA,EAmCLuI,EAAKpT,SAAW6S,IAAgBA,GAG3CnU,EAAM6U,UAAY,SAAU3I,EAAO5K,GAS/B,QAASwT,GAAa7L,GAClB,MAAOiB,GAAW,SAAUxI,EAAKjC,GAC7B,GAAIiC,EACAJ,EAASqH,MAAM,MAAOjH,GAAK4K,OAAO7M,QAEjC,CACD,GAAIsV,GAAO9L,EAAS8L,MAChBA,GACAtV,EAAKoB,KAAKiU,EAAaC,IAGvBtV,EAAKoB,KAAKS,GAEdqN,EAAY1F,GAAUN,MAAM,KAAMlJ,MApB9C,GADA6B,EAAWsH,EAAMtH,GAAY8G,IACxBW,EAASmD,GAAQ,CAClB,GAAIxK,GAAM,GAAItH,OAAM,4DACpB,OAAOkH,GAASI,GAEpB,MAAKwK,GAAM/R,WAoBX2a,GAAa9U,EAAMiJ,SAASiD,MAnBjB5K,KAuCftB,EAAMgV,SAAW,SAAU9I,EAAO5K,GAC9B2K,EAAUjM,EAAMiL,OAAQiB,EAAO5K,IAGnCtB,EAAMiV,cAAgB,SAAS/I,EAAOxB,EAAOpJ,GACzC2K,EAAUxB,EAAaC,GAAQwB,EAAO5K,IAG1CtB,EAAM4U,OAAS,SAAS1I,EAAO5K,GAC3B2K,EAAUjM,EAAMoL,aAAcc,EAAO5K,IAGzCtB,EAAMiJ,SAAW,SAAUiD,GACvB,QAASgJ,GAAa3U,GAClB,QAASmI,KAIL,MAHIwD,GAAM/R,QACN+R,EAAM3L,GAAOoI,MAAM,KAAMjJ,WAEtBgJ,EAAGqM,OAKd,MAHArM,GAAGqM,KAAO,WACN,MAAQxU,GAAQ2L,EAAM/R,OAAS,EAAK+a,EAAa3U,EAAQ,GAAI,MAE1DmI,EAEX,MAAOwM,GAAa,IAGxBlV,EAAM2I,MAAQuB,EAAW,SAAUxB,EAAIjJ,GACnC,MAAOyK,GAAW,SAAUiL,GACxB,MAAOzM,GAAGC,MACN,KAAMlJ,EAAK6M,OAAO6I,QAgB9BnV,EAAMsM,OAAStB,EAAWoB,GAC1BpM,EAAMoV,aAAejK,EAASiB,GAE9BpM,EAAMqV,OAAS,SAAUrW,EAAMiK,EAAU3H,GAErC,GADAA,EAAWA,GAAY8G,EACnBpJ,IAAQ,CACR,GAAI+V,GAAO7K,EAAW,SAASxI,EAAKjC,GAC5BiC,EACAJ,EAASI,GACF1C,EAAK2J,MAAMhJ,KAAMF,GACxBwJ,EAAS8L,GAETzT,EAAS,OAGjB2H,GAAS8L,OAETzT,GAAS,OAIjBtB,EAAMsV,SAAW,SAAUrM,EAAUjK,EAAMsC,GACvC,GAAIiU,GAAQ,CACZ,OAAOvV,GAAMqV,OAAO,WAChB,QAASE,GAAS,GAAKvW,EAAK2J,MAAMhJ,KAAMD,YACzCuJ,EAAU3H,IAGjBtB,EAAMwV,MAAQ,SAAUxW,EAAMiK,EAAU3H,GACpC,MAAOtB,GAAMqV,OAAO,WAChB,OAAQrW,EAAK2J,MAAMhJ,KAAMD,YAC1BuJ,EAAU3H,IAGjBtB,EAAMyV,QAAU,SAAUxM,EAAUjK,EAAMsC,GACtC,MAAOtB,GAAMsV,SAASrM,EAAU,WAC5B,OAAQjK,EAAK2J,MAAMhJ,KAAMD,YAC1B4B,IAGPtB,EAAM0V,OAAS,SAAU1W,EAAMiK,EAAU3H,GACrCA,EAAWA,GAAY8G,CAEvB,IAAI2M,GAAO7K,EAAW,SAASxI,EAAKjC,GAC5BiC,EACAJ,EAASI,IAETjC,EAAKoB,KAAK+K,GACV5M,EAAK2J,MAAMhJ,KAAMF,MAIrBmM,EAAQ,SAASlK,EAAKiU,GAClBjU,EACAJ,EAASI,GACFiU,EACP1M,EAAS8L,GAETzT,EAAS,MAIjBtC,GAAK4M,IAGT5L,EAAM4V,SAAW,SAAU3M,EAAUjK,EAAMsC,GACvC,GAAIiU,GAAQ,CACZvV,GAAM0V,OAAO,SAASX,GACdQ,IAAU,EACVR,EAAK,MAAM,GAEX/V,EAAK2J,MAAMhJ,KAAMD,YAEtBuJ,EAAU3H,IAwIjBtB,EAAM6V,MAAQ,SAAUrJ,EAAQC,GAC5B,GAAIG,GAAIL,EAAO,SAAUuJ,EAAOpK,GAC5Bc,EAAOsJ,EAAM,GAAIpK,IAClBe,EAAa,EAEhB,OAAOG,IAGX5M,EAAM+V,cAAgB,SAAUvJ,EAAQC,GAEpC,QAASuJ,GAAcxa,EAAGY,GACtB,MAAOZ,GAAEya,SAAW7Z,EAAE6Z,SAG1B,QAASC,GAAcC,EAAU1U,EAAM2U,GAGnC,IAFA,GAAIC,GAAM,GACNC,EAAMH,EAAShc,OAAS,EACfmc,EAAND,GAAW,CACd,GAAIE,GAAMF,GAAQC,EAAMD,EAAM,IAAO,EACjCD,GAAQ3U,EAAM0U,EAASI,KAAS,EAChCF,EAAME,EAEND,EAAMC,EAAM,EAGpB,MAAOF,GAGX,QAAS1J,GAAQC,EAAG/O,EAAMoY,EAAU3U,GAChC,GAAgB,MAAZA,GAAwC,kBAAbA,GAC3B,KAAM,IAAIlH,OAAM,mCAMpB,OAJAwS,GAAEE,SAAU,EACP/D,EAASlL,KACVA,GAAQA,IAEO,IAAhBA,EAAK1D,OAEG6F,EAAMgN,aAAa,WACtBJ,EAAEK,cAGVjE,GAAWnL,EAAM,SAASsO,GACtB,GAAI1K,IACA5D,KAAMsO,EACN8J,SAAUA,EACV3U,SAA8B,kBAAbA,GAA0BA,EAAW8G,EAG1DwE,GAAEV,MAAMuB,OAAOyI,EAActJ,EAAEV,MAAOzK,EAAMuU,GAAiB,EAAG,EAAGvU,GAE/DmL,EAAEV,MAAM/R,SAAWyS,EAAEH,aACrBG,EAAEO,YAENnN,EAAMgN,aAAaJ,EAAEQ,WAK7B,GAAIR,GAAI5M,EAAM6V,MAAMrJ,EAAQC,EAU5B,OAPAG,GAAE/L,KAAO,SAAUhD,EAAMoY,EAAU3U,GAC/BqL,EAAQC,EAAG/O,EAAMoY,EAAU3U,UAIxBsL,GAAEM,QAEFN,GAGX5M,EAAMwW,MAAQ,SAAUhK,EAAQE,GAC5B,MAAOH,GAAOC,EAAQ,EAAGE,IAqB7B1M,EAAMM,IAAM4N,EAAY,OACxBlO,EAAMyW,IAAMvI,EAAY,OAKxBlO,EAAM0W,QAAU,SAAUhO,EAAIiO,GAC1B,GAAIpN,MACAqN,IACJD,GAASA,GAAUtO,CACnB,IAAIwO,GAAW3M,EAAW,SAAkBzK,GACxC,GAAI6B,GAAW7B,EAAKiP,MAChB9E,EAAM+M,EAAOhO,MAAM,KAAMlJ,EACzBmK,KAAOL,GACPvJ,EAAMgN,aAAa,WACf1L,EAASqH,MAAM,KAAMY,EAAKK,MAGzBA,IAAOgN,GACZA,EAAOhN,GAAK/I,KAAKS,IAGjBsV,EAAOhN,IAAQtI,GACfoH,EAAGC,MAAM,KAAMlJ,EAAK6M,QAAQpC,EAAW,SAAUzK,GAC7C8J,EAAKK,GAAOnK,CACZ,IAAImN,GAAIgK,EAAOhN,SACRgN,GAAOhN,EACd,KAAK,GAAItL,GAAI,EAAGwY,EAAIlK,EAAEzS,OAAY2c,EAAJxY,EAAOA,IACjCsO,EAAEtO,GAAGqK,MAAM,KAAMlJ,UAOjC,OAFAoX,GAAStN,KAAOA,EAChBsN,EAASE,WAAarO,EACfmO,GAGX7W,EAAMgX,UAAY,SAAUtO,GACxB,MAAO,YACH,OAAQA,EAAGqO,YAAcrO,GAAIC,MAAM,KAAMjJ,aAUjDM,EAAM4T,MAAQxF,EAAOpO,EAAMwB,KAC3BxB,EAAMiX,YAAc7I,EAAOpO,EAAMyQ,WACjCzQ,EAAMkX,WAAa,SAAU7N,EAAOqB,EAAOzB,EAAU3H,GACjD,MAAOtB,GAAM0Q,SAAStH,EAAOC,GAAQqB,EAAOzB,EAAU3H,IAG1DtB,EAAMmX,IAAM,WACR,GAAI5I,GAAM7O,SACV,OAAOwK,GAAW,SAAUzK,GACxB,GAAIgP,GAAO9O,KAEP2B,EAAW7B,EAAKA,EAAKtF,OAAS,EACX,mBAAZmH,GACP7B,EAAKiP,MAELpN,EAAW8G,EAGfpI,EAAM6Q,OAAOtC,EAAK9O,EAAM,SAAU2X,EAAS1O,EAAIgD,GAC3ChD,EAAGC,MAAM8F,EAAM2I,EAAQ9K,QAAQpC,EAAW,SAAUxI,EAAK2V,GACrD3L,EAAGhK,EAAK2V,SAGhB,SAAU3V,EAAKC,GACXL,EAASqH,MAAM8F,GAAO/M,GAAK4K,OAAO3K,SAK9C3B,EAAMsX,QAAU,WACZ,MAAOtX,GAAMmX,IAAIxO,MAAM,KAAMQ,MAAMnN,UAAUiV,QAAQ/U,KAAKwD,aAuB9DM,EAAMuX,UAAYjJ,EAAWtO,EAAMiL,QACnCjL,EAAMwX,gBAAkBlJ,EAAWtO,EAAMoL,cAGzCpL,EAAMyX,QAAU,SAAU/O,EAAIpH,GAG1B,QAASyT,GAAKrT,GACV,MAAIA,GACOkJ,EAAKlJ,OAEhByK,GAAK4I,GANT,GAAInK,GAAOnC,EAAUnH,GAAY8G,GAC7B+D,EAAOwC,EAAYjG,EAOvBqM,MAsBJ/U,EAAM2O,YAAcA,EAEpB3O,EAAM0X,SAAWxN,EAAW,SAASyN,GACjC,GAAIlY,IAAQ,MAAM6M,OAAOqL,EACzB,OAAO,UAAUrW,GACb,MAAOA,GAASqH,MAAMhJ,KAAMF,MAIpCO,EAAM4X,SACN5X,EAAM6X,SAAW,SAAkB1N,GAC/B,MAAOD,GAAW,SAAUzK,GACxB,GACIrB,GADAkD,EAAW7B,EAAKiP,KAEpB,KACItQ,EAAS+L,EAAKxB,MAAMhJ,KAAMF,GAC5B,MAAOqY,GACL,MAAOxW,GAASwW,GAGhBzI,EAAUjR,IAAkC,kBAAhBA,GAAO2Z,KACnC3Z,EAAO2Z,KAAK,SAASvN,GACjBlJ,EAAS,KAAMkJ,KAChB,SAAS,SAAS9I,GACjBJ,EAASI,EAAIY,QAAUZ,EAAM,GAAItH,OAAMsH,MAG3CJ,EAAS,KAAMlD,MAML,gBAAXa,SAAuBA,OAAOC,QACrCD,OAAOC,QAAUc,EAGM,kBAAXgY,SAAyBA,OAAOC,IAC5CD,UAAW,WACP,MAAOhY,KAKX+O,EAAK/O,MAAQA;;;;ADxuCrBd,QAAQiC,KAAO,SAASuG,EAAKpG,GAC5B,GAAIqG,GAAM,GAAIC,eAEdD,GAAIE,mBAAqB,WACxB,GAAuB,IAAnBF,EAAIG,WAIR,GAAIH,EAAII,QAAU,KAAOJ,EAAII,OAAS,IACrCzG,EAAS,KAAMqG,EAAIK,kBACb,CACN,GAAItG,GAAM,GAAItH,OAAM,2BAA6BsN,EAAM,IAEvDhG,GAAIuG,MAAQ,GACZ3G,EAASI,IAIX,KACCiG,EAAIO,KAAK,MAAOR,GAAK,GACrBC,EAAIQ,KAAK,MACR,MAAOzG,GACRJ,EAASI;;AGdX,QAASid,mBACLC,UAAW,EACPC,aAAa1kB,OACb0b,MAAQgJ,aAAavS,OAAOuJ,OAE5BiJ,WAAa,GAEbjJ,MAAM1b,QACN4kB,aAIR,QAASA,cACL,IAAIH,SAAJ,CAGA,GAAII,GAAUtP,WAAWiP,gBACzBC,WAAW,CAGX,KADA,GAAI5U,GAAM6L,MAAM1b,OACV6P,GAAK,CAGP,IAFA6U,aAAehJ,MACfA,WACSiJ,WAAa9U,GACd6U,cACAA,aAAaC,YAAYG,KAGjCH,YAAa,GACb9U,EAAM6L,MAAM1b,OAEhB0kB,aAAe,KACfD,UAAW,EACXM,aAAaF,IAiBjB,QAASG,MAAKC,EAAK1hB,GACfiC,KAAKyf,IAAMA,EACXzf,KAAKjC,MAAQA,EAYjB,QAAS0K,SAtET,GAAIgF,SAAUnO,OAAOC,WACjB2W,SACA+I,UAAW,EACXC,aACAC,WAAa,EAsCjB1R,SAAQuC,SAAW,SAAUyP,GACzB,GAAI3f,GAAO,GAAI0J,OAAMzJ,UAAUvF,OAAS,EACxC,IAAIuF,UAAUvF,OAAS,EACnB,IAAK,GAAImE,GAAI,EAAGA,EAAIoB,UAAUvF,OAAQmE,IAClCmB,EAAKnB,EAAI,GAAKoB,UAAUpB,EAGhCuX,OAAMhV,KAAK,GAAIse,MAAKC,EAAK3f,IACJ,IAAjBoW,MAAM1b,QAAiBykB,UACvBlP,WAAWqP,WAAY,IAS/BI,KAAKnjB,UAAUijB,IAAM,WACjBtf,KAAKyf,IAAIzW,MAAM,KAAMhJ,KAAKjC,QAE9B0P,QAAQiS,MAAQ,UAChBjS,QAAQkS,SAAU,EAClBlS,QAAQmS,OACRnS,QAAQoS,QACRpS,QAAQqS,QAAU,GAClBrS,QAAQsS,YAIRtS,QAAQuS,GAAKvX,KACbgF,QAAQuF,YAAcvK,KACtBgF,QAAQwS,KAAOxX,KACfgF,QAAQyS,IAAMzX,KACdgF,QAAQyF,eAAiBzK,KACzBgF,QAAQ0S,mBAAqB1X,KAC7BgF,QAAQ2S,KAAO3X,KAEfgF,QAAQ4S,QAAU,SAAU1b,GACxB,KAAM,IAAIlK,OAAM,qCAGpBgT,QAAQ6S,IAAM,WAAc,MAAO,KACnC7S,QAAQ8S,MAAQ,SAAUzJ,GACtB,KAAM,IAAIrc,OAAM,mCAEpBgT,QAAQ+S,MAAQ,WAAa,MAAO","file":"bundle.js","sourcesContent":["(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})","var globals = require('./lib/globals'),\n\tpipeline = require(\"./lib/pipeline\"),\n\tSGEMMCalculator = require(\"./lib/sgemmcalculator\"),\n\tSAXPYCalculator = require(\"./lib/saxpycalculator\"),\n\tSSCALCalculator = require(\"./lib/sscalcalculator\"),\n\tSDWNSCalculator = require(\"./lib/sdwnscalculator\"),\n\tSCLMPCalculator = require(\"./lib/sclmpcalculator\"),\n\ttest = require(\"./lib/test\");\n\nvar gl = globals.gl,\n\tsgemmcalculator = new SGEMMCalculator(gl),\n\tsaxpycalculator = new SAXPYCalculator(gl),\n\tsscalcalculator = new SSCALCalculator(gl),\n\tsdwnscalculator = new SDWNSCalculator(gl),\n\tsclmpcalculator = new SCLMPCalculator(gl);\n\nmodule.exports = {\n\t// level one\n\t\"saxpy\" : saxpy,\n\t\"sscal\" : sscal, // single precision matrix scale\n\t// level two\n\t// level three\n\t\"sgemm\" : sgemm, // single precision generalized matrix multiply\n\t// extra\n\t\"sstd\" : sstd, // single precision Standard Score normalization\n\t\"sdwns\": sdwns,\n\t\"sclmp\": sclmp,\n\t// pipeline\n\t\"pipeline\" : pipeline,\n\t// internals\n\t\"gpu\" : {\t\"gl\": gl,\n\t \t\t\t\"sgemm\": pipeline.sgemmcalculator.calculate.bind(pipeline.sgemmcalculator),\n\t\t\t\t\"sscal\" : pipeline.sscalcalculator.calculate.bind(pipeline.sscalcalculator),\n\t\t\t\t\"sclmp\" : pipeline.sclmpcalculator.calculate.bind(pipeline.sclmpcalculator),\n\t\t\t\t\"sdwns\" : pipeline.sdwnscalculator.calculate.bind(pipeline.sdwnscalculator),\n\t\t\t\t\"encode\" : gl.encode.bind(gl)\n\t\t\t},\n\t\"util\" : { \"fromArray\" : fromArray, \"transpose\" : transpose},\n\t\"test\" : test\n};\n\n\n/* Wrap the GL calculation object in a (relatively) user friendly function that\n\taccepts TypedArrays\n\n\t* convert the data to (padded) textures in GPU memory\n\t* execute calculation\n\t* read result into an array, and return\n */\nfunction sgemm(M, N, K, alpha, A, B, beta, C){\n\n\tif(C != null && C.length != N){\n\t\tthrow new Error(\"Only vector C with length matching rows in A is currently supported.\");\n\t}\n\n\t// pack each matrix into a single RGBA texel array, with the second transposed\n\tvar texels0 = A,\n\t\ttexels1,\n\t\ttexels2 = C;\n\n\n\ttexels1 = transpose(K, N, B);\n\n\t// create input textures from data\n\tvar texture0 = gl.createDataTexture(M, K, texels0);\n\tvar texture1 = gl.createDataTexture(N, K, texels1);\n\tvar texture2 = null;\n\tif(texels2 != null){\n\t\ttexture2 = gl.createDataTexture(1, N, texels2);\n\t}\n\n\tvar texture3 = gl.createOutputTexture(M, N);\n\n\tsgemmcalculator.calculate(M, N, K, alpha, texture0, texture1, beta, texture2, texture3);\n\n\t// retrieve data\n\trawBuffer = gl.readData(M, N);\n\n\t// clean up\n\tgl.context.deleteTexture(texture0);\n\tgl.context.deleteTexture(texture1);\n\tif(texture2 != null){\n\t\tgl.context.deleteTexture(texture2);\n\t}\n\tgl.context.deleteTexture(texture3);\n\n\t// return result\n\treturn new Float32Array(rawBuffer);\n\n}\n\nfunction saxpy(N, a, X, Y){\n\n\tvar rawBuffer;\n\n\n\tvar texels0 = X,\n\t\ttexels1;\n\n\t// TODO: special shader for constant Y\n\tif(isFloat32Array(Y)){\n\t\ttexels1 = Y;\n\t} else {\n\t\ttexels1 = new Float32Array(N);\n\t\ttexels1.fill(Y);\n\t}\n\n\t// create input textures from data\n\tvar texture0 = gl.createDataTexture(1, N, texels0);\n\tvar texture1 = gl.createDataTexture(1, N, texels1);\n\n\tvar texture3 = gl.createOutputTexture(1, N);\n\n\tsaxpycalculator.calculate(N, a, texture0, texture1, texture3);\n\n\t// retrieve data\n\trawBuffer = gl.readData(1, N);\n\n\t// clean up\n\tgl.context.deleteTexture(texture0);\n\tgl.context.deleteTexture(texture1);\n\tgl.context.deleteTexture(texture3);\n\n\t// return result\n\treturn new Float32Array(rawBuffer);\n\n}\n\nfunction isFloat32Array(obj){\n\treturn Object.prototype.toString.call(obj) === \"[object Float32Array]\";\n}\n/* a more general version of the BLAS Level 1 scale, that works on matrices\n and includes an elementwise scalar addition\n\n a * X + b\n\n a - multiplicative scalar\n b - additive scalar\n X - matrix (M x N)\n\n to get the standard BLAS scal set M = 1 and b = 0\n\n this function is generally only cost effective to use in a pipeline\n*/\nfunction sscal(M, N, a, b, X){\n\n\tvar rawBuffer;\n\n\tvar texels0 = X;\n\tvar texture0 = gl.createDataTexture(M, N, texels0);\n\n\tvar texture3 = gl.createOutputTexture(M, N);\n\n\tsscalcalculator.calculate(M, N, a, b, texture0, texture3);\n\n\t// retrieve data\n\trawBuffer = gl.readData(M, N);\n\n\t// clean up\n\tgl.context.deleteTexture(texture0);\n\tgl.context.deleteTexture(texture3);\n\n\t// return result\n\treturn new Float32Array(rawBuffer);\n}\n\n/* Calculate the Standard Score normalization (subtract mean\n ,divide by standard deviation).\n */\nfunction sstd(M, N, mu, sigma, X){\n\n\tvar rawBuffer;\n\n\tvar texels0 = X;\n\tvar texture0 = gl.createDataTexture(M, N, texels0);\n\n\tvar texture3 = gl.createOutputTexture(M, N);\n\n\t// adjust the parameters (for inverse) and call the standard score normalization\n\tsscalcalculator.calculate(M, N, 1.0/sigma, -1.0 * mu/sigma, texture0, texture3);\n\n\t// retrieve data\n\trawBuffer = gl.readData(M, N);\n\n\t// clean up\n\tgl.context.deleteTexture(texture0);\n\tgl.context.deleteTexture(texture3);\n\n\t// return result\n\treturn new Float32Array(rawBuffer);\n}\n\n/* downsample an image (taking the max) for Pooling\n\n\tM - rows in input\n\tN - columns in input\n\tc - channels in input\n\tfactor - the downsample factor (width of patch to sample)\n\tstride - width between pooling regions\n\tX - input image\n */\nfunction sdwns(M, N, channels, factor, stride, X){\n\n\n\tvar texels0 = X;\n\n\tvar texture0 = gl.createDataTexture(M, N * channels, X);\n\n\tvar N_out = Math.floor((N - factor) / stride) + 1;\n\tvar M_out = Math.floor((M - factor) / stride) + 1;\n\n\tvar texture3 = gl.createOutputTexture(M_out, N_out * channels);\n\n\tsdwnscalculator.calculate(M, N, channels, factor, stride, texture0, texture3);\n\n\t// retrieve data\n\trawBuffer = gl.readData(M_out, N_out * channels);\n\n\t// clean up\n\tgl.context.deleteTexture(texture0);\n\tgl.context.deleteTexture(texture3);\n\n\t// return result\n\treturn new Float32Array(rawBuffer);\n}\n/* Elementwise clamp function for matrices on the interval [a, b]. Can also be\n\tused for min or max, by passing Number.MIN_VALUE for the first parameter and\n\tNumber.MAX_VALUE for the second parameter, respectively.\n\n\tPassing `null` for either of these parameters will default to it's\n\trespective min or max value.\n\n\tM - number of rows in X\n\tN - number of columns in X\n\ta - lower bound (inclusize)\n\tb - upper bound (inclusive)\n\tX - matrix\n\n to get the standard BLAS scal set M = 1 and b = 0\n\n this function is generally only cost effective to use in a pipeline\n*/\nfunction sclmp(M, N, a, b, X){\n\n\ta = (a != null) ? a : Number.MIN_VALUE;\n\tb = (b != null) ? b : Number.MAX_VALUE;\n\n\tvar rawBuffer;\n\n\tvar texels0 = X;\n\tvar texture0 = gl.createDataTexture(M, N, texels0);\n\n\tvar texture3 = gl.createOutputTexture(M, N);\n\n\tsclmpcalculator.calculate(M, N, a, b, texture0, texture3);\n\n\t// retrieve data\n\trawBuffer = gl.readData(M, N);\n\n\t// clean up\n\tgl.context.deleteTexture(texture0);\n\tgl.context.deleteTexture(texture3);\n\n\t// return result\n\treturn new Float32Array(rawBuffer);\n}\n/*\nfunction saxpy(n, a, x, y){\n\tvar i = 0,\n\t\tresult = new Float32Array(n);\n\n\t// assert n = x.length\n\t// assert a is scalar\n\t// assert x is Float32Array\n\n\tif(isNumeric(y)){\n\t\t// shortcut for scalar y\n\t\tfor(; i < n; i++){\n\t\t\tresult[i] = a * x[i] + y;\n\t\t}\n\t} else {\n\n\t\tfor(; i < n; i++){\n\t\t\tresult[i] = a * x[i] + y[i];\n\t\t}\n\t}\n\n\treturn result;\n\n}*/\n\n// add a String.format method, if none exists\nif (!String.prototype.format) {\n String.prototype.format = function() {\n\tvar args = arguments;\n\treturn this.replace(/{(\\d+)}/g, function(match, number) {\n\t return typeof args[number] != 'undefined'\n\t\t? args[number]\n\t\t: match\n\t ;\n\t});\n };\n}\n\nfunction isNumeric( obj ) { return (obj - parseFloat( obj ) + 1) >= 0; }\n\n/* create a typed array from a 2D javascript array */\nfunction fromArray(array, type, tranpose) {\n\tvar shape = [],\n\t\t\tdata,\n\t\t\tc; // number of columns\n\n\tif(!tranpose){\n\t\tshape[0] = array.length;\n\t\tshape[1] = array[0].length;\n\t} else {\n\t\tshape[1] = array.length;\n\t\tshape[0] = array[0].length;\n\t}\n\tc = shape[1];\n\n\ttype = type || Float32Array;\n\n\tdata = new type(shape[0]*shape[1]);\n\n\tfor (var ii = 0; ii < shape[0]; ++ii)\n\t\tfor (var jj = 0; jj < shape[1]; ++jj)\n\t\tif(!tranpose)\n\t\t\tdata[ii*c + jj] = array[ii][jj];\n\t\telse\n\t\t\tdata[ii*c + jj] = array[jj][ii];\n\n\treturn data;\n};\n\n// tranpose a typed array in row major order, with the given row and column\n// numers\nfunction transpose(r, c, typedArray){\n\tvar result = new typedArray.constructor(r*c);\n\n\tfor(var i = 0; i < r; i++){\n\t\tfor(var j = 0; j < c; j++){\n\t\t\tresult[j * r + i] = typedArray[i * c + j];\n\t\t}\n\t}\n\n\treturn result;\n}\n","var WebGL = require(\"./webgl\");\n\nvar gl = new WebGL();\n\nmodule.exports = {\n\t\"gl\" : gl\n}\n","var async = require('async'),\n\tloader = require('floader'); // browserify aware file loader (xhr in browser)\n\n/* Collection of helper methods for testing numerical computation\n */\ntest = {};\n\n/* Check all entries in two TypedArrays of identical length for approximate\n\tequality.\n\tIf the following equation is element-wise true, returns true\n\n\tabsolute(a - b) <= (atol + rtol * absolute(b))\n\n\tfrom numpy.allclose\n */\ntest.allclose = function(a, b, RTOL, ATOL){\n\tRTOL= RTOL || 1e-05; // for 32 bit precision: 1e-06\n\tATOL= ATOL || 1e-08;\n\n\tif(a.length != b.length){\n\t\tconsole.log(\"lengths not equal: \" + a.length + \", \" + b.length);\n\t\treturn {\"result\" : false, \"index\": null};\n\t}\n\n\tvar result;\n\tfor(var i = 0; i < a.length; i++){\n\n\t\tresult = Math.abs(a[i] - b[i]) <= ATOL + RTOL * Math.abs(b[i]);\n\n\t\tif(!result) {\n\t\t\treturn {\"result\": false, \"index\": i};\n\t\t}\n\t}\n\n\treturn {\"result\": true, \"index\": i};\n};\n\ntest.randomArray = function(N, M){\n\n\tvar data = [];\n\n\tfor(var i = 0; i < N; i++){\n\t\tvar row = [];\n\t\tfor(var j = 0; j < M; j++){\n\t\t\trow[j] = Math.random() / Math.sqrt(N);\n\t\t}\n\t\tdata.push(row);\n\t}\n\n\treturn data;\n};\n// pad rows with zeros\ntest.padData = function(M, N, pad, data){\n\n\tvar padded = new Float32Array(M * (N + pad)); // new array of specified length filled with zeros\n\tfor(var i = 0; i < M; i++){\n\t\tpadded.set(data.subarray(i * N, (i + 1) * N), i * (N + pad));\n\t}\n\treturn padded;\n}\n\n\n/* Load test matrices from JSON data, works in a browser (with XHR)\n\tassumes three files 'a.json', 'b.json' and 'c.json' in nested Array format.\n\n callback = function(err, a, b, c)\n */\ntest.load = function(testDirectory, matrixFiles, callback){\n\n\t// array of paths to matrix data files for current test\n\tvar testFiles = matrixFiles.map(function(item){ return testDirectory + item;});\n\n\t//console.log(testFiles);\n\tasync.map(testFiles, loader.load,\n\t\tfunction(err, results){\n\n\t\t\tif(err) return callback(err);\n\n\t\t\t// results contains three strings.\n\t\t\t// each string contains the contents of a file\n\t\t\t// files contain JSON describing a matrix (2D array)\n\t\t\tvar matrices = results.map(JSON.parse);\n\n\t\t\tcallback(err, matrices);\n\t\t}\n\t);\n};\n\ntest.assert = {};\n\n/* create a tape compatible assert */\ntest.assert.allclose = function(t, a, b, msg, RTOL, ATOL) {\n\n\tvar ok = test.allclose(a, b, RTOL, ATOL),\n\t\tactual = \"[\",\n\t\texpected = \"[\";\n\n\tif(!ok.result){\n\n\t\tif(ok.index > 1){\n\t\t\tactual += \"..., \";\n\t\t\texpected += \"..., \";\n\t\t}\n\t\tif(ok.index > 0){\n\t\t\tactual += a[ok.index - 1] + \", \";\n\t\t\texpected += b[ok.index - 1] + \", \";\n\t\t}\n\t\tactual += \"-->\";\n\t\texpected += \"-->\";\n\n\t\tfor(var i = ok.index; i < ok.index + 4 && i < a.length; i++ ){\n\t\t\tactual += a[i] + \", \";\n\t\t\texpected += b[i] + \", \";\n\t\t}\n\t\tif(i < a.length){\n\t\t\tactual += \"...]\";\n\t\t\texpected += \"...]\";\n\t\t} else {\n\t\t\tactual += \"]\";\n\t\t\texpected += \"]\";\n\t\t}\n\t\tmsg = msg || 'should be allclose at ' + ok.index;\n\t}\n\n t._assert(ok.result, {\n message : msg || 'should be allclose',\n operator : 'allclose',\n actual : actual,\n expected : expected,\n extra : null\n });\n}\n\nmodule.exports = test;\n","var globals = require('./globals'),\n\tSGEMMCalculator = require(\"./sgemmcalculator\"),\n\tSAXPYCalculator = require(\"./saxpycalculator\"),\n\tSSCALCalculator = require(\"./sscalcalculator\"),\n\tSDWNSCalculator = require(\"./sdwnscalculator\"),\n\tSCLMPCalculator = require(\"./sclmpcalculator\"),\n\tTensor = require('./tensor');\n\n\nvar gl = globals.gl,\n\tsgemmcalculator = new SGEMMCalculator(gl, false),\n\tsaxpycalculator = new SAXPYCalculator(gl, false),\n\tsscalcalculator = new SSCALCalculator(gl, false),\n\tsdwnscalculator = new SDWNSCalculator(gl, false),\n\tsclmpcalculator = new SCLMPCalculator(gl, false);\n\nmodule.exports = {\n\t\"Tensor\" : Tensor,\n\t\"sscal\" : sscal,\n\t\"sgemm\" : sgemm,\n\t\"sdwns\" : sdwns,\n\t\"sclmp\" : sclmp,\n\n\t\"sgemmcalculator\" : sgemmcalculator,\n\t\"saxpycalculator\" : saxpycalculator,\n\t\"sscalcalculator\" : sscalcalculator,\n\t\"sdwnscalculator\" : sdwnscalculator,\n\t\"sclmpcalculator\" : sclmpcalculator\n}\n\n/* scale (and optionally offset) a Tensor, elementwise\n */\nfunction sscal(a, b, t0){\n\n\tvar M = t0.shape[0],\n\t\tN = t0.shape[1];\n\n\t// create an empty output Tensor\n\tvar tOut = new Tensor([M, N], null);\n\n\tsscalcalculator.calculate(M, N, a, b, t0.texture, tOut.texture);\n\n\treturn tOut;\n}\n\n/* matrix multiply on t0 and t1 with additive t2. t1 must be transposed\n */\nfunction sgemm(alpha, t0, t1, beta, t2){\n\n\tif(t1.shape[1] !== t0.shape[1])\n\t\tthrow new Error(\"Second dimension must be of same size for input Tensors (second Tensor is transposed).\");\n\n\tvar M = t0.shape[0],\n\t\tN = t1.shape[0],\n\t\tK = t0.shape[1];\n\n\tvar texture2;\n\n\tif(t2){\n\t\ttexture2 = t2.texture;\n\t} else {\n\t\ttexture2 = null;\n\t}\n\n\t// create an empty output Tensor\n\tvar tOut = new Tensor([M, N], null);\n\n\tsgemmcalculator.calculate(M, N, K, alpha, t0.texture, t1.texture, beta, texture2, tOut.texture);\n\n\treturn tOut;\n}\n\nfunction sdwns(channels, factor, stride, t0){\n\n\tif(t0.shape[1] % channels !== 0)\n\t\tthrow new Error(\"Second dimension of tensor must be a multiple of channels\");\n\n\tvar M = t0.shape[0],\n\t\tN = t0.shape[1] / channels;\n\n\tvar M_out = Math.floor((M - factor) / stride) + 1;\n\tvar N_out = Math.floor((N - factor) / stride) + 1;\n\n\t// create an empty output Tensor\n\tvar tOut = new Tensor([M_out, N_out * channels], null);\n\n\tsdwnscalculator.calculate(M, N, channels, factor, stride, t0.texture, tOut.texture);\n\n\treturn tOut;\n}\n\nfunction sclmp(a, b, t0){\n\n\ta = (a != null) ? a : Number.MIN_VALUE;\n\tb = (b != null) ? b : Number.MAX_VALUE;\n\n\tvar M = t0.shape[0],\n\t\tN = t0.shape[1];\n\n\t// create an empty output Tensor\n\tvar tOut = new Tensor([M, N], null);\n\n\tsclmpcalculator.calculate(M, N, a, b, t0.texture, tOut.texture);\n\n\treturn tOut;\n}\n","var WebGL = require('./webgl');\n\n/* A calculator object for the Float texture based AXPY\n\n\ta times X plus Y (AXPY):\n\n\tY = a * X + Y\n\n\twhere X + Y is elementwise matrix addition\n\n\n\twebgl - a weblas.WebGL object\n\tstandalone - whether or not to automatically run the floating point encode\n\t\tstep for rendering to an UNSIGNED_BYTE texture (this is required for\n\t\tmobile, circa 2015) but can't be used as part of a pipeline.\n\n\t* uploads and downloads data\n\t* executes calculation\n */\nfunction SAXPYCalculator(webgl, standalone){\n\tthis.webgl = webgl,\n\tthis.standalone = standalone || true; // default to standalone mode\n\n\n\tvar s = \"#define GLSLIFY 1\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D X;\\t\\t// texture with data from padded A\\nuniform sampler2D Y;\\t\\t// texture with data from padded transpose of B\\nuniform int N;\\nuniform float a; \\t\\t// coefficient to multiplication\\n\\n// Render float to bytes according to IEEE 754 Floating Point\\nvec4 encode_float_1540259130(float val) {\\n\\n\\t// TODO: correctly handle denormal numbers\\n\\t// http://www.2ality.com/2012/04/number-encoding.html\\n\\tfloat a = abs(val); // encode absolute value + sign\\n\\tfloat exp = floor(log2(a)); // number of powers of 2\\n\\tfloat mant = pow(2.,log2(a)-exp) * pow(2.,23.); // multiply to fill 24 bits (implied leading 1)\\n\\tfloat mant1 = floor(mant / 256. / 256.); // first 8 bits of mantissa\\n\\tfloat mant2 = mod(floor(mant / 256.),256.); // second 8 bits\\n\\tfloat mant3 = mod(mant,256.); // third 8 bits\\n\\n\\thighp float sign = 128.-128.*(a/val);\\t\\t\\t// sign bit is 256 or 0\\n\\thighp float e = (sign+exp+127.)/510.;\\t\\t// exponent and sign\\n\\thighp float m1 = (mant1-(128.*(1.-mod(exp+127.,2.))))/255.; // handle leading bit\\n\\thighp float m2 = (mant2)/255.;\\t\\t\\t\\t// middle part\\n\\thighp float m3 = (mant3+.5)/255.;\\t\\t\\t// scale to 0 - 255\\n\\n\\treturn vec4(m3,m2,m1,e);\\n}\\n\\n// select an element from a vector based on index\\nfloat select_index_1604150559(vec4 v, int index){\\n\\tfloat val;\\n\\tif (index == 0) {\\n\\t\\tval = v.r;\\n\\t} else if(index == 1) {\\n\\t\\tval = v.g;\\n\\t} else if(index == 2) {\\n\\t\\tval = v.b;\\n\\t} else if(index == 3){\\n\\t\\tval = v.a;\\n\\t} else {\\n\\t\\t// should never be here\\n\\t\\tval = 0.0;\\n\\t}\\n\\n\\treturn val;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n \\tfloat row = outTex.y;\\n\\tfloat col = outTex.x;\\n\\n\\t// direct usage of col requires output be padded exactly like input\\n\\tvec4 x = texture2D( X, vec2(col, row));\\n\\tvec4 y = texture2D( Y, vec2(col, row));\\n\\tvec4 sum_v = (a * x) + y;\\n\\tint channel = int(mod(col * float(N), 4.0 ));\\n\\tfloat sum = select_index_1604150559(sum_v, channel);\\n\\n\\tif (sum == 0.) {\\n\\t\\tgl_FragColor = vec4(0.,0.,0.,0.);\\n\\t\\treturn;\\n\\t}\\n\\n \\t// output vec4 with bytes for an IEEE754 32-bit floating point number\\n\\tgl_FragColor = encode_float_1540259130(sum);\\n}\\n\";\n\t//\tp = glslify('./glsl/saxpy/pipeline.glsl');\n\n\t// create the webgl shader program for this calculation\n\t// based on the specific fragment shader for this calculation\n\t// and the generic pass through shader\n\tif(this.standalone){\n\t\tthis.program = this.webgl.createProgram(s);\n\t} else {\n\t\tthis.program = this.webgl.createProgram(p);\n\t}\n}\n\nmodule.exports = SAXPYCalculator;\n\n/* Names of the uniforms (variables) used in the shader program passed in on\n each calculation.\n */\nSAXPYCalculator.TEXTURE_UNIFORM_NAME_0 = \"X\";\nSAXPYCalculator.TEXTURE_UNIFORM_NAME_1 = \"Y\";\nSAXPYCalculator.LENGTH_UNIFORM_NAME = \"N\";\nSAXPYCalculator.COEFFICIENT_UNIFORM_NAME = \"a\";\n\n\n/* Calculate the AXPY, with the given data.\n\n\tN - number of elements in X and Y\n\ta - scalar coefficient to X\n\tX - left hand vector (texture)\n\tY - right hand vector (texture)\n\tout - output (texture)\n\n How this works:\n\n 1. Activate our shader program\n 2. Bind input textures\n 3. Set shader program parameters\n 4. Bind output texture\n 5. Activate calculation with `drawElements`\n\n */\nSAXPYCalculator.prototype.calculate = function(N, a, X, Y, out){\n\n\tvar gl = this.webgl.context;\n\n\t/*\n\tvar h1 = M, w1 = K,\n\t\th2 = K, w2 = N;\n\t*/\n\n\tthis.webgl.selectProgram(this.program);\n\n\t// create and bind our input texture using matrix data\n\tthis.bindInputTexture(X, gl.TEXTURE0, SAXPYCalculator.TEXTURE_UNIFORM_NAME_0);\n\tthis.bindInputTexture(Y, gl.TEXTURE1, SAXPYCalculator.TEXTURE_UNIFORM_NAME_1);\n\n\n\tvar pad = this.webgl.getPad(N);\n\t// set the data specific variables in our shader program\n\tthis.bindUniforms(N + pad, a);\n\n\t// create our destination texture\n\tthis.webgl.bindOutputTexture(1, N + pad, out);\n\n\n\t// initiate calculation\n\tgl.drawElements(gl.TRIANGLES, /*num items*/6, gl.UNSIGNED_SHORT, 0);\n\n\tthis.webgl.unbindInputTexture(gl.TEXTURE0);\n\tthis.webgl.unbindInputTexture(gl.TEXTURE1);\n\n};\n\n/* Create a texture from the given texel data and bind it to our shader program.\n\n\th - number of rows in input matrix\n\tw - number of cols in input matrix\n\ttexels - packed data\n\ttextureUnit - the texture unit to bind to (gl.TEXTURE0, gl.TEXTURE1, etc)\n\tname - the uniform name to associate with (must match shader program)\n\n\tmust compile program (with createProgram) first\n*/\nSAXPYCalculator.prototype.bindInputTexture = function(texture, textureUnit, name){\n\tvar gl = this.webgl.context,\n\t\tprogram = this.program;\n\n\tgl.activeTexture(textureUnit); // gl.TEXTURE0, gl.TEXTURE1, etc\n\tgl.bindTexture(\t gl.TEXTURE_2D, texture);\n\n\tvar sampler = gl.getUniformLocation(program, name);\n\tgl.uniform1i(sampler, textureUnit - gl.TEXTURE0);\n\n};\n\n/* Set up inputs for the texture shader\n\n */\nSAXPYCalculator.prototype.bindUniforms = function(N, a) {\n\tvar gl = this.webgl.context;\n\n\t// get var locations\n\tvar N_gl = gl.getUniformLocation(this.program, SAXPYCalculator.LENGTH_UNIFORM_NAME),\n\t\ta_gl = gl.getUniformLocation(this.program, SAXPYCalculator.COEFFICIENT_UNIFORM_NAME);\n\n\t// bind length of shared dimension\n\tgl.uniform1i(N_gl, N);\n\tgl.uniform1f(a_gl, a);\n\n};\n","var WebGL = require('./webgl');\n\n/* a more general version of the BLAS Level 1 scale that works on matrices\n and includes an elementwise scalar addition\n\n a * X + b\n\n\twhere X is a matrix, a and b are scalars and operations are elementwise\n\n to get the standard BLAS scal set M = 1 and b = 0\n\n\n\twebgl - a weblas.WebGL object\n\tstandalone - whether or not to automatically run the floating point encode\n\t\tstep for rendering to an UNSIGNED_BYTE texture (this is required for\n\t\tmobile, circa 2015) but can't be used as part of a pipeline.\n\n\t* uploads and downloads data\n\t* executes calculation\n */\nfunction SSCALCalculator(webgl, standalone){\n\tthis.webgl = webgl,\n\tthis.standalone = (standalone != null) ? standalone : true; // default to standalone mode\n\n\tvar s = \"#define GLSLIFY 1\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D X;\\t\\t// texture with data from padded X\\nuniform int N;\\t\\t// number of columns\\nuniform int pad;\\t\\t// additional columns to nearest multiple of four\\nuniform float b; \\t\\t// additive term\\nuniform float a; \\t\\t// multiplicative term\\n\\n// Render float to bytes according to IEEE 754 Floating Point\\nvec4 encode_float_1540259130(float val) {\\n\\n\\t// TODO: correctly handle denormal numbers\\n\\t// http://www.2ality.com/2012/04/number-encoding.html\\n\\tfloat a = abs(val); // encode absolute value + sign\\n\\tfloat exp = floor(log2(a)); // number of powers of 2\\n\\tfloat mant = pow(2.,log2(a)-exp) * pow(2.,23.); // multiply to fill 24 bits (implied leading 1)\\n\\tfloat mant1 = floor(mant / 256. / 256.); // first 8 bits of mantissa\\n\\tfloat mant2 = mod(floor(mant / 256.),256.); // second 8 bits\\n\\tfloat mant3 = mod(mant,256.); // third 8 bits\\n\\n\\thighp float sign = 128.-128.*(a/val);\\t\\t\\t// sign bit is 256 or 0\\n\\thighp float e = (sign+exp+127.)/510.;\\t\\t// exponent and sign\\n\\thighp float m1 = (mant1-(128.*(1.-mod(exp+127.,2.))))/255.; // handle leading bit\\n\\thighp float m2 = (mant2)/255.;\\t\\t\\t\\t// middle part\\n\\thighp float m3 = (mant3+.5)/255.;\\t\\t\\t// scale to 0 - 255\\n\\n\\treturn vec4(m3,m2,m1,e);\\n}\\n\\n// select an element from a vector based on index\\nfloat select_index_1604150559(vec4 v, int index){\\n\\tfloat val;\\n\\tif (index == 0) {\\n\\t\\tval = v.r;\\n\\t} else if(index == 1) {\\n\\t\\tval = v.g;\\n\\t} else if(index == 2) {\\n\\t\\tval = v.b;\\n\\t} else if(index == 3){\\n\\t\\tval = v.a;\\n\\t} else {\\n\\t\\t// should never be here\\n\\t\\tval = 0.0;\\n\\t}\\n\\n\\treturn val;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n \\tfloat row = outTex.y;\\n\\tfloat col = outTex.x;\\n\\n\\t// direct usage of col requires output be padded exactly like input\\n\\tvec4 x = texture2D( X, vec2(col, row));\\n\\tvec4 sum_v = (a * x) + b;\\n\\tint channel = int(mod(col * float(N + pad), 4.0 ));\\n\\tfloat sum = select_index_1604150559(sum_v, channel);\\n\\n\\tif (sum == 0.) {\\n\\t\\tgl_FragColor = vec4(0.,0.,0.,0.);\\n\\t\\treturn;\\n\\t}\\n\\n \\t// output vec4 with bytes for an IEEE754 32-bit floating point number\\n\\tgl_FragColor = encode_float_1540259130(sum);\\n}\\n\",\n\t\tp = \"#define GLSLIFY 1\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D X;\\t\\t// texture with data from padded X\\nuniform int N;\\t\\t// number of columns\\nuniform int pad;\\t\\t// additional columns to nearest multiple of four\\nuniform float b; \\t\\t// additive term\\nuniform float a; \\t\\t// multiplicative term\\n\\n// set pad values to 0.0, if in padded region of output texture\\nvoid fix_pad_1540259130(inout vec4 v, int pad){\\n\\tv.a = 0.0;\\n\\tif(pad == 2){\\n\\t\\tv.b = 0.0;\\n\\t} else if(pad == 3){\\n\\t\\tv.b = 0.0;\\n\\t\\tv.g = 0.0;\\n\\t}\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row_t = outTex.y;\\n\\tfloat col_t = outTex.x;\\n\\tfloat col = (col_t * float(N + pad) - 2.0); // index of first element in pixel (matrix space)\\n\\n\\t// direct usage of col requires output be padded exactly like input\\n\\tvec4 x = texture2D( X, vec2(col_t, row_t));\\n\\tvec4 sum_v = (a * x) + b;\\n\\n\\t// fix padded region\\n\\tif(pad > 0 && col + 4.0 > float(N) ) {\\n\\t\\tfix_pad_1540259130(sum_v, pad);\\n\\t}\\n\\n\\tgl_FragColor = sum_v;\\n}\\n\";\n\n\t// create the webgl shader program for this calculation\n\t// based on the specific fragment shader for this calculation\n\t// and the generic pass through shader\n\tif(this.standalone){\n\t\tthis.program = this.webgl.createProgram(s);\n\t} else {\n\t\tthis.program = this.webgl.createProgram(p);\n\t}\n}\n\nmodule.exports = SSCALCalculator;\n\n/* Names of the uniforms (variables) used in the shader program passed in on\n each calculation.\n */\nSSCALCalculator.TEXTURE_UNIFORM_NAME_0 = \"X\";\nSSCALCalculator.LENGTH_UNIFORM_NAME = \"N\";\nSSCALCalculator.ADD_UNIFORM_NAME = \"b\";\nSSCALCalculator.MUL_UNIFORM_NAME = \"a\";\n\n/* Elementwise scale and offset a matrix\n\n\tM - number of rows in X\n\tN - number of columns in X\n\ta - scalar coefficient to X\n\tb - scalar offset of X\n\tX - matrix (texture)\n\tout - output (texture)\n\n How this works:\n\n 1. Activate our shader program\n 2. Bind input textures\n 3. Set shader program parameters\n 4. Bind output texture\n 5. Activate calculation with `drawElements`\n\n */\nSSCALCalculator.prototype.calculate = function(M, N, a, b, X, out){\n\n\tvar gl = this.webgl.context;\n\n\tvar mod = (N % WebGL.COMPONENTS_PER_TEXEL),\n\t\tpad = mod == 0 ? 0 : WebGL.COMPONENTS_PER_TEXEL - mod;\n\n\tthis.webgl.selectProgram(this.program);\n\n\t// create and bind our input texture using matrix data\n\tthis.bindInputTexture(X, gl.TEXTURE0, SSCALCalculator.TEXTURE_UNIFORM_NAME_0);\n\n\t// set the data specific variables in our shader program\n\tthis.bindUniforms(N, pad, a, b);\n\n\t// create our destination texture\n\tif(this.standalone){\n\t\tthis.webgl.bindOutputTexture(M, N + pad, out);\n\t} else {\n\t\tthis.webgl.bindOutputTexture(M, (N + pad)/ 4, out);\n\t}\n\n\n\t// initiate calculation\n\tgl.drawElements(gl.TRIANGLES, /*num items*/6, gl.UNSIGNED_SHORT, 0);\n\n\tthis.webgl.unbindInputTexture(gl.TEXTURE0);\n\n};\n\n/* Create a texture from the given texel data and bind it to our shader program.\n\n\ttexture - texture containing the data\n\ttextureUnit - the texture unit to bind to (gl.TEXTURE0, gl.TEXTURE1, etc)\n\tname - the uniform name to associate with (must match shader program)\n\n\tmust compile program (with createProgram) first\n*/\nSSCALCalculator.prototype.bindInputTexture = function(texture, textureUnit, name){\n\tvar gl = this.webgl.context,\n\t\tprogram = this.program;\n\n\tgl.activeTexture(textureUnit); // gl.TEXTURE0, gl.TEXTURE1, etc\n\tgl.bindTexture(\t gl.TEXTURE_2D, texture);\n\n\tvar sampler = gl.getUniformLocation(program, name);\n\tgl.uniform1i(sampler, textureUnit - gl.TEXTURE0);\n\n};\n\n/* Set up inputs for the texture shader\n\n */\nSSCALCalculator.prototype.bindUniforms = function(N, pad, a, b) {\n\tvar gl = this.webgl.context;\n\n\t// get var locations\n\tvar N_gl = gl.getUniformLocation(this.program, SSCALCalculator.LENGTH_UNIFORM_NAME),\n\t\tb_gl = gl.getUniformLocation(this.program, SSCALCalculator.ADD_UNIFORM_NAME),\n\t\ta_gl = gl.getUniformLocation(this.program, SSCALCalculator.MUL_UNIFORM_NAME),\n\t\tpad_gl = gl.getUniformLocation(this.program, \"pad\");\n\n\t// bind length of shared dimension\n\tgl.uniform1i(N_gl, N);\n\tgl.uniform1i(pad_gl, pad);\n\tgl.uniform1f(a_gl, a);\n\tgl.uniform1f(b_gl, b);\n\n};\n","var WebGL = require('./webgl');\n\n/* Downsample an image (useful in pooling layers).\n\n\n\n\twebgl - a weblas.WebGL object\n\tstandalone - whether or not to automatically run the floating point encode\n\t\tstep for rendering to an UNSIGNED_BYTE texture (this is required for\n\t\tmobile, circa 2015) but can't be used as part of a pipeline.\n\n\t* uploads and downloads data\n\t* executes calculation\n */\nfunction DownsampleCalculator(webgl, standalone){\n\tthis.webgl = webgl,\n\tthis.standalone = (standalone != null) ? standalone : true; // default to standalone mode\n\n\tvar s = \"#define GLSLIFY 1\\n// TODO: unroll loop for stride == factor and small values (2, 3)\\nprecision highp float;\\n\\nvarying vec2 outTex; // texture coords of row/column to calculate\\nuniform sampler2D X; // texture with data from padded A\\nuniform int factor; // width of image patch\\nuniform float stride; // width between image patches\\nuniform float C; // number of channels\\nuniform float M;\\nuniform float N;\\nuniform float N_out;\\nuniform float M_out;\\n\\n// Render float to bytes according to IEEE 754 Floating Point\\nvec4 encode_float_1540259130(float val) {\\n\\n\\t// TODO: correctly handle denormal numbers\\n\\t// http://www.2ality.com/2012/04/number-encoding.html\\n\\tfloat a = abs(val); // encode absolute value + sign\\n\\tfloat exp = floor(log2(a)); // number of powers of 2\\n\\tfloat mant = pow(2.,log2(a)-exp) * pow(2.,23.); // multiply to fill 24 bits (implied leading 1)\\n\\tfloat mant1 = floor(mant / 256. / 256.); // first 8 bits of mantissa\\n\\tfloat mant2 = mod(floor(mant / 256.),256.); // second 8 bits\\n\\tfloat mant3 = mod(mant,256.); // third 8 bits\\n\\n\\thighp float sign = 128.-128.*(a/val);\\t\\t\\t// sign bit is 256 or 0\\n\\thighp float e = (sign+exp+127.)/510.;\\t\\t// exponent and sign\\n\\thighp float m1 = (mant1-(128.*(1.-mod(exp+127.,2.))))/255.; // handle leading bit\\n\\thighp float m2 = (mant2)/255.;\\t\\t\\t\\t// middle part\\n\\thighp float m3 = (mant3+.5)/255.;\\t\\t\\t// scale to 0 - 255\\n\\n\\treturn vec4(m3,m2,m1,e);\\n}\\n\\n// select an element from a vector based on index\\nfloat select_index_1604150559(vec4 v, int index){\\n\\tfloat val;\\n\\tif (index == 0) {\\n\\t\\tval = v.r;\\n\\t} else if(index == 1) {\\n\\t\\tval = v.g;\\n\\t} else if(index == 2) {\\n\\t\\tval = v.b;\\n\\t} else if(index == 3){\\n\\t\\tval = v.a;\\n\\t} else {\\n\\t\\t// should never be here\\n\\t\\tval = 0.0;\\n\\t}\\n\\n\\treturn val;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate and translate to output pixel space.\\n\\tfloat row = floor(outTex.y * M_out); // row on output texture (matrix space)\\n\\tfloat col = floor(outTex.x * N_out); // column on output texture (matrix space)\\n\\tfloat vcol = floor(col / C); // virtual column on output texture (matrix space)\\n\\tfloat vchannel = floor(mod(col, C)); // virtual channel on output texture\\n\\n\\tconst float min = -1.0e+08;\\n\\tvec4 currentMax = vec4(min, min, min, min);\\n\\n\\tfloat deltaY = 1.0/M;\\n\\tfloat deltaX = 1.0/N;\\n\\tfloat y = ((row * stride) + 0.5)*deltaY; // texture position of input row\\n\\tfloat x;\\n\\tfloat z = vchannel * deltaX;\\n\\tfor (int i = 0; i < 100; i += 1) {\\n\\t\\tif (i >= factor) {\\n\\t\\t\\tbreak;\\n\\t\\t}\\n\\t\\tx = ((vcol * stride * C) + 0.5) * deltaX; // texture position of input column\\n\\n\\t\\tfor (int j = 0; j < 100; j += 1) {\\n\\t\\t\\tif (j >= factor) {\\n\\t\\t\\t\\tbreak;\\n\\t\\t\\t}\\n\\n\\t\\t\\tvec2 coords = vec2(x + z, y);\\n\\t\\t\\tvec4 x_v = texture2D(X, coords);\\n\\t\\t\\tcurrentMax = max(currentMax, x_v);\\n\\n\\t\\t\\tx += (deltaX * C);\\n\\t\\t}\\n\\t\\ty += deltaY;\\n\\t}\\n\\tint chan = int(mod(outTex.x * N_out, 4.0 ));\\n\\tfloat val = select_index_1604150559(currentMax, int(chan));\\n\\tif (val == 0.) {\\n\\t\\tgl_FragColor = vec4(0.,0.,0.,0.);\\n\\t\\treturn;\\n\\t}\\n\\n\\tgl_FragColor = encode_float_1540259130(val);\\n}\\n\";\n\t\tp = \"#define GLSLIFY 1\\n// TODO: unroll loop for stride == factor and small values (2, 3)\\nprecision highp float;\\n\\nvarying vec2 outTex; // texture coords of row/column to calculate\\nuniform sampler2D X; // texture with data from padded A\\nuniform int factor; // width of image patch\\nuniform float stride; // width between image patches\\nuniform float C; // number of channels\\nuniform float M;\\nuniform float N;\\nuniform float N_out;\\nuniform float M_out;\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate and translate to output pixel space.\\n\\tfloat row = floor(outTex.y * M_out); // row on output texture (pixel space)\\n\\tfloat col = floor(outTex.x * N_out); // column on output texture (matrix space)\\n\\tfloat vcol = floor(col / C); // virtual column on output texture (matrix space)\\n\\tfloat vchannel = floor(mod(col, C)); // virtual channel on output texture\\n\\n\\tconst float min = -1.0e+08;\\n\\tvec4 currentMax = vec4(min, min, min, min);\\n\\n\\tfloat deltaY = 1.0/M;\\n\\tfloat deltaX = 1.0/N;\\n\\tfloat y = ((row * stride) + 0.5)*deltaY; // texture position of input row\\n\\tfloat x;\\n\\tfloat z = vchannel * deltaX;\\n\\tfor (int i = 0; i < 100; i += 1) {\\n\\t\\tif (i >= factor) {\\n\\t\\t\\tbreak;\\n\\t\\t}\\n\\t\\tx = ((vcol * stride * C) + 0.5) * deltaX; // texture position of input column\\n\\n\\t\\tfor (int j = 0; j < 100; j += 1) {\\n\\t\\t\\tif (j >= factor) {\\n\\t\\t\\t\\tbreak;\\n\\t\\t\\t}\\n\\n\\t\\t\\tvec2 coords = vec2(x + z, y);\\n\\t\\t\\tvec4 x_v = texture2D(X, coords);\\n\\t\\t\\tcurrentMax = max(currentMax, x_v);\\n\\n\\t\\t\\tx += (deltaX * C);\\n\\t\\t}\\n\\t\\ty += deltaY;\\n\\t}\\n\\n\\tgl_FragColor = currentMax;\\n}\\n\";\n\n\t// create the webgl shader program for this calculation\n\t// based on the specific fragment shader for this calculation\n\t// and the generic pass through shader\n\tif(this.standalone){\n\t\tthis.program = this.webgl.createProgram(s);\n\t} else {\n\t\tthis.program = this.webgl.createProgram(p);\n\t}\n}\n\nmodule.exports = DownsampleCalculator;\n\n/* Names of the uniforms (variables) used in the shader program passed in on\n each calculation.\n */\nDownsampleCalculator.TEXTURE_UNIFORM_NAME_0 = \"X\";\nDownsampleCalculator.INPUT_ROW_COUNT_UNIFORM_NAME = \"M\";\nDownsampleCalculator.INPUT_COLUMN_COUNT_UNIFORM_NAME = \"N\";\nDownsampleCalculator.OUTPUT_ROW_COUNT_UNIFORM_NAME = \"M_out\";\nDownsampleCalculator.OUTPUT_COLUMN_COUNT_UNIFORM_NAME = \"N_out\";\nDownsampleCalculator.FACTOR_UNIFORM_NAME = \"factor\";\nDownsampleCalculator.STRIDE_UNIFORM_NAME = \"stride\";\nDownsampleCalculator.CHANNEL_COUNT_UNIFORM_NAME = \"C\";\n\n\n/* Downsample (pool) the input using the maximum for each channel.\n\n\tM - rows in X\n\tN - columns in X\n\tc - (channels / 4) in X\n\tfactor - the number of pixels (width and height) to combine\n\tstride - amount between groups of pixels\n\tX - input matrix (texture)\n\tout - output (texture)\n\n How this works:\n\n 1. Activate our shader program\n 2. Bind input textures\n 3. Set shader program parameters\n 4. Bind output texture\n 5. Activate calculation with `drawElements`\n\n */\nDownsampleCalculator.prototype.calculate = function(M, N, channels, factor, stride, X, out){\n\n\tif(channels % WebGL.COMPONENTS_PER_TEXEL != 0){\n\t\tthrow new Error(\"Channel count must be a multiple of \" + WebGL.COMPONENTS_PER_TEXEL);\n\t}\n\tvar gl = this.webgl.context;\n\n var N_out = (Math.floor((N - factor) / stride) + 1) * channels;\n var M_out = Math.floor((M - factor) / stride) + 1;\n\n\tthis.webgl.selectProgram(this.program);\n\n\t// create and bind our input texture using matrix data\n\tthis.bindInputTexture(X, gl.TEXTURE0, DownsampleCalculator.TEXTURE_UNIFORM_NAME_0);\n\n\n\t// set the data specific variables in our shader program\n\tthis.bindUniforms(M, N * channels, M_out, N_out, factor, stride, channels);\n\n\t// create our destination texture\n\tif(this.standalone){\n\t\tthis.webgl.bindOutputTexture(M_out, N_out, out);\n\t} else {\n\t\tthis.webgl.bindOutputTexture(M_out, N_out/WebGL.COMPONENTS_PER_TEXEL, out);\n\t}\n\n\n\t// initiate calculation\n\tgl.drawElements(gl.TRIANGLES, /*num items*/6, gl.UNSIGNED_SHORT, 0);\n\n\tthis.webgl.unbindInputTexture(gl.TEXTURE0);\n\n};\n\n/* Create a texture from the given texel data and bind it to our shader program.\n\n\ttexture - texture containing input values to bind\n\ttextureUnit - the texture unit to bind to (gl.TEXTURE0, gl.TEXTURE1, etc)\n\tname - the uniform name to associate with (must match shader program)\n\n\tmust compile program (with createProgram) first\n*/\nDownsampleCalculator.prototype.bindInputTexture = function(texture, textureUnit, name){\n\tvar gl = this.webgl.context,\n\t\tprogram = this.program;\n\n\tgl.activeTexture(textureUnit); // gl.TEXTURE0, gl.TEXTURE1, etc\n\tgl.bindTexture(\t gl.TEXTURE_2D, texture);\n\n\tvar sampler = gl.getUniformLocation(program, name);\n\tgl.uniform1i(sampler, textureUnit - gl.TEXTURE0);\n\n};\n\n/* Set up inputs for the texture shader\n\n */\nDownsampleCalculator.prototype.bindUniforms = function(M, N, M_out, N_out, factor, stride, c) {\n\tvar gl = this.webgl.context;\n\n\t// get var locations\n\tvar M_gl = gl.getUniformLocation(this.program, DownsampleCalculator.INPUT_ROW_COUNT_UNIFORM_NAME),\n\t\tN_gl = gl.getUniformLocation(this.program, DownsampleCalculator.INPUT_COLUMN_COUNT_UNIFORM_NAME),\n\t\tM_out_gl = gl.getUniformLocation(this.program, DownsampleCalculator.OUTPUT_ROW_COUNT_UNIFORM_NAME),\n\t\tN_out_gl = gl.getUniformLocation(this.program, DownsampleCalculator.OUTPUT_COLUMN_COUNT_UNIFORM_NAME),\n\t\tfactor_gl = gl.getUniformLocation(this.program, DownsampleCalculator.FACTOR_UNIFORM_NAME),\n\t\tstride_gl = gl.getUniformLocation(this.program, DownsampleCalculator.STRIDE_UNIFORM_NAME),\n\t\tchannel_count_gl = gl.getUniformLocation(this.program, DownsampleCalculator.CHANNEL_COUNT_UNIFORM_NAME);\n\n\t// bind length of shared dimension\n\tgl.uniform1f(M_gl, M);\n\tgl.uniform1f(N_gl, N);\n\tgl.uniform1f(M_out_gl, M_out);\n\tgl.uniform1f(N_out_gl, N_out);\n\tgl.uniform1i(factor_gl, factor);\n\tgl.uniform1f(stride_gl, stride);\n\tgl.uniform1f(channel_count_gl, c);\n\n};\n","var WebGL = require('./webgl');\n\n/* A calculator object for the Float texture based GEMM\n\n\tGeneralized Matrix Multiply (GEMM):\n\n\tC = alpha * A * B + beta * C\n\n\twhere A * B is matrix multiplication\n\n\n\twebgl - a weblas.WebGL object\n\tstandalone - whether or not to automatically run the floating point encode\n\t\tstep for rendering to an UNSIGNED_BYTE texture (this is required for\n\t\tmobile, circa 2015) but can't be used as part of a pipeline.\n\n\t* uploads and downloads data\n\t* executes calculation\n */\nfunction SGEMMCalculator(webgl, standalone){\n\tthis.webgl = webgl,\n\tthis.standalone = (standalone != null) ? standalone : true; // default to standalone mode\n\n\t// read GLSL files\n\tvar s = \"#define GLSLIFY 1\\n// fragment shader that calculates the matrix product and renders each\\n// element to the bytes representing a 32-bit IEEE754 floating point in\\n// the output RGBA canvas.\\n// readPixel is used to read the bytes.\\n\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D A;\\t\\t// texture with data from padded A\\nuniform sampler2D B_t;\\t\\t// texture with data from padded transpose of B\\nuniform int K;\\t\\t// number of elements in shared dimension\\nuniform int N;\\t\\t// number of columns in output\\nuniform int pad;\\t\\t//\\nuniform float alpha; \\t// coefficient to multiplication\\n\\n// sum of products between elements in row i (from A) x col j (from B)\\n\\n// Calculate the dot product between the row (from A) and column (from B)\\n// identified by the passed indeces (output texture coordinate space).\\n// We loop over elements in the row and column and sum the product\\n// using the glsl `dot` function to process four elements at a time.\\n// This four element optimization requires that the matrix B be\\n// transposed before texel packing and that both matrices be padded\\n// (with zeros) to a multiple of four (4) in their shared dimension.\\nfloat dot_rowcol_1540259130(float y, float x, sampler2D A, sampler2D B_t, int K) {\\n\\tfloat delta_t = 1./float(K);// space (on texture) between elements\\n\\tfloat sum = 0.;\\t\\t\\t// sum for this row/column pair\\n\\tfloat z = 0.5 * (4.0 * delta_t);// position for shared dimension on source textures\\n\\n\\tfor (int l=0 ; l<4096 ; ++l) {\\n\\t\\tif(l >= K / 4) break; // stop when we finish the row/column\\n\\t\\t// l is in pixel space, so we divide by four\\n\\n\\t\\t// retrieve next four elements from each texture\\n\\t\\tvec4 a_ik = texture2D( A, vec2(z, y));\\n\\t\\tvec4 b_kj = texture2D(B_t, vec2(z, x));\\n\\n\\t// use `dot` to process four elements at a time\\n\\t\\tsum += dot(a_ik, b_kj);\\n\\t\\tz += (4.0 * delta_t); // (z + 0.5)*delta\\n\\t}\\n\\treturn sum;\\n}\\n\\n// Render float to bytes according to IEEE 754 Floating Point\\nvec4 encode_float_1604150559(float val) {\\n\\n\\t// TODO: correctly handle denormal numbers\\n\\t// http://www.2ality.com/2012/04/number-encoding.html\\n\\tfloat a = abs(val); // encode absolute value + sign\\n\\tfloat exp = floor(log2(a)); // number of powers of 2\\n\\tfloat mant = pow(2.,log2(a)-exp) * pow(2.,23.); // multiply to fill 24 bits (implied leading 1)\\n\\tfloat mant1 = floor(mant / 256. / 256.); // first 8 bits of mantissa\\n\\tfloat mant2 = mod(floor(mant / 256.),256.); // second 8 bits\\n\\tfloat mant3 = mod(mant,256.); // third 8 bits\\n\\n\\thighp float sign = 128.-128.*(a/val);\\t\\t\\t// sign bit is 256 or 0\\n\\thighp float e = (sign+exp+127.)/510.;\\t\\t// exponent and sign\\n\\thighp float m1 = (mant1-(128.*(1.-mod(exp+127.,2.))))/255.; // handle leading bit\\n\\thighp float m2 = (mant2)/255.;\\t\\t\\t\\t// middle part\\n\\thighp float m3 = (mant3+.5)/255.;\\t\\t\\t// scale to 0 - 255\\n\\n\\treturn vec4(m3,m2,m1,e);\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row_t = outTex.y;\\n\\tfloat col_t = outTex.x;\\n\\n\\t// sum row x col for the passed pixel\\n\\tfloat sum = alpha * dot_rowcol_1540259130(row_t, col_t * float(N + pad)/float(N), A, B_t, K);\\n\\n\\tif (sum == 0.) {\\n\\t\\tgl_FragColor = vec4(0.,0.,0.,0.);\\n\\t\\treturn;\\n\\t}\\n\\n\\t// output vec4 with bytes for an IEEE754 32-bit floating point number\\n\\tgl_FragColor = encode_float_1604150559(sum);\\n}\\n\",\n\t\ts_c = \"#define GLSLIFY 1\\n// fragment shader that calculates the matrix product (with additive 'C' term)\\n// and renders each element to the bytes representing a 32-bit IEEE754 floating\\n// point in the output RGBA canvas.\\n// readPixel is used to read the bytes.\\n\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D A;\\t\\t// texture with data from padded A\\nuniform sampler2D B_t;\\t\\t// texture with data from padded transpose of B\\nuniform sampler2D C;\\t\\t// texture with data from C\\nuniform int K;\\t\\t// number of elements in shared dimension\\nuniform int N;\\t\\t// number of columns in output\\nuniform int pad;\\t\\t//\\nuniform float alpha; \\t// coefficient to multiplication\\nuniform float beta; \\t// coefficient to additive term\\n\\n// sum of products between elements in row i (from A) x col j (from B)\\n\\n// Calculate the dot product between the row (from A) and column (from B)\\n// identified by the passed indeces (output texture coordinate space).\\n// We loop over elements in the row and column and sum the product\\n// using the glsl `dot` function to process four elements at a time.\\n// This four element optimization requires that the matrix B be\\n// transposed before texel packing and that both matrices be padded\\n// (with zeros) to a multiple of four (4) in their shared dimension.\\nfloat dot_rowcol_1540259130(float y, float x, sampler2D A, sampler2D B_t, int K) {\\n\\tfloat delta_t = 1./float(K);// space (on texture) between elements\\n\\tfloat sum = 0.;\\t\\t\\t// sum for this row/column pair\\n\\tfloat z = 0.5 * (4.0 * delta_t);// position for shared dimension on source textures\\n\\n\\tfor (int l=0 ; l<4096 ; ++l) {\\n\\t\\tif(l >= K / 4) break; // stop when we finish the row/column\\n\\t\\t// l is in pixel space, so we divide by four\\n\\n\\t\\t// retrieve next four elements from each texture\\n\\t\\tvec4 a_ik = texture2D( A, vec2(z, y));\\n\\t\\tvec4 b_kj = texture2D(B_t, vec2(z, x));\\n\\n\\t// use `dot` to process four elements at a time\\n\\t\\tsum += dot(a_ik, b_kj);\\n\\t\\tz += (4.0 * delta_t); // (z + 0.5)*delta\\n\\t}\\n\\treturn sum;\\n}\\n\\n// Render float to bytes according to IEEE 754 Floating Point\\nvec4 encode_float_1604150559(float val) {\\n\\n\\t// TODO: correctly handle denormal numbers\\n\\t// http://www.2ality.com/2012/04/number-encoding.html\\n\\tfloat a = abs(val); // encode absolute value + sign\\n\\tfloat exp = floor(log2(a)); // number of powers of 2\\n\\tfloat mant = pow(2.,log2(a)-exp) * pow(2.,23.); // multiply to fill 24 bits (implied leading 1)\\n\\tfloat mant1 = floor(mant / 256. / 256.); // first 8 bits of mantissa\\n\\tfloat mant2 = mod(floor(mant / 256.),256.); // second 8 bits\\n\\tfloat mant3 = mod(mant,256.); // third 8 bits\\n\\n\\thighp float sign = 128.-128.*(a/val);\\t\\t\\t// sign bit is 256 or 0\\n\\thighp float e = (sign+exp+127.)/510.;\\t\\t// exponent and sign\\n\\thighp float m1 = (mant1-(128.*(1.-mod(exp+127.,2.))))/255.; // handle leading bit\\n\\thighp float m2 = (mant2)/255.;\\t\\t\\t\\t// middle part\\n\\thighp float m3 = (mant3+.5)/255.;\\t\\t\\t// scale to 0 - 255\\n\\n\\treturn vec4(m3,m2,m1,e);\\n}\\n\\n// select an element from a vector based on index\\nfloat select_index_1117569599(vec4 v, int index){\\n\\tfloat val;\\n\\tif (index == 0) {\\n\\t\\tval = v.r;\\n\\t} else if(index == 1) {\\n\\t\\tval = v.g;\\n\\t} else if(index == 2) {\\n\\t\\tval = v.b;\\n\\t} else if(index == 3){\\n\\t\\tval = v.a;\\n\\t} else {\\n\\t\\t// should never be here\\n\\t\\tval = 0.0;\\n\\t}\\n\\n\\treturn val;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row_t = outTex.y;\\n\\tfloat col_t = outTex.x;\\n\\tvec4 c_vec = texture2D(C, vec2(col_t, 0.5));\\n\\n\\t// should be -0.5, but that subtly breaks at zero\\n\\tfloat col = col_t * float(N + pad); // index of first element in pixel (matrix space)\\n\\tint channel = int(mod(col, 4.0 ));\\n\\tfloat c = select_index_1117569599(c_vec, channel);\\n\\n\\t// sum row x col for the passed pixel\\n\\tfloat sum = alpha * dot_rowcol_1540259130(row_t, col_t * float(N + pad)/float(N), A, B_t, K);\\n\\tsum += beta * c;\\n\\n\\tif (sum == 0.) {\\n\\t\\tgl_FragColor = vec4(0.,0.,0.,0.);\\n\\t\\treturn;\\n\\t}\\n\\n\\t// output vec4 with bytes for an IEEE754 32-bit floating point number\\n\\tgl_FragColor = encode_float_1604150559(sum);\\n}\\n\",\n\t\tp = \"#define GLSLIFY 1\\n// fragment shader that calculates the matrix product and writes each\\n// element to a pixel component in a floating point texture.\\n// the output RGBA canvas.\\n// readPixel is used to read the bytes.\\n\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D A;\\t\\t// texture with data from padded A\\nuniform sampler2D B_t;\\t\\t// texture with data from padded transpose of B\\nuniform int K;\\t\\t// number of elements in shared dimension\\nuniform int N;\\t\\t// number of columns in output\\nuniform int pad;\\t\\t//\\nuniform float alpha; \\t// coefficient to multiplication\\n\\n// sum of products between elements in row i (from A) x col j (from B)\\n\\n// Calculate the dot product between the row (from A) and column (from B)\\n// identified by the passed indeces (output texture coordinate space).\\n// We loop over elements in the row and column and sum the product\\n// using the glsl `dot` function to process four elements at a time.\\n// This four element optimization requires that the matrix B be\\n// transposed before texel packing and that both matrices be padded\\n// (with zeros) to a multiple of four (4) in their shared dimension.\\nfloat dot_rowcol_1540259130(float y, float x, sampler2D A, sampler2D B_t, int K) {\\n\\tfloat delta_t = 1./float(K);// space (on texture) between elements\\n\\tfloat sum = 0.;\\t\\t\\t// sum for this row/column pair\\n\\tfloat z = 0.5 * (4.0 * delta_t);// position for shared dimension on source textures\\n\\n\\tfor (int l=0 ; l<4096 ; ++l) {\\n\\t\\tif(l >= K / 4) break; // stop when we finish the row/column\\n\\t\\t// l is in pixel space, so we divide by four\\n\\n\\t\\t// retrieve next four elements from each texture\\n\\t\\tvec4 a_ik = texture2D( A, vec2(z, y));\\n\\t\\tvec4 b_kj = texture2D(B_t, vec2(z, x));\\n\\n\\t// use `dot` to process four elements at a time\\n\\t\\tsum += dot(a_ik, b_kj);\\n\\t\\tz += (4.0 * delta_t); // (z + 0.5)*delta\\n\\t}\\n\\treturn sum;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row_t = outTex.y;\\n\\tfloat col_t = outTex.x;\\n\\n\\tvec4 sum_v = vec4(0.0, 0.0, 0.0, 0.0);\\n\\tfloat col = (col_t * float(N + pad) - 2.0); // index of first element in pixel (matrix space)\\n\\tsum_v.r = alpha * dot_rowcol_1540259130(row_t, (col + 0.5)/float(N), A, B_t, K);\\n\\t// is last element in pixel past row length?\\n\\tif(pad > 0 && (col + 4.0) > float(N) ) {\\n\\t\\t// compute elements in padded region\\n\\t\\tif(pad < 3){\\n\\t\\t\\tsum_v.g = alpha * dot_rowcol_1540259130(row_t, (col + 1.5)/float(N), A, B_t, K);\\n\\t\\t}\\n\\t\\tif(pad < 2){\\n\\t\\t\\tsum_v.b = alpha * dot_rowcol_1540259130(row_t, (col + 2.5)/float(N), A, B_t, K);\\n\\t\\t}\\n\\t} else {\\n\\t\\tsum_v.g = alpha * dot_rowcol_1540259130(row_t, (col + 1.5)/float(N), A, B_t, K);\\n\\t\\tsum_v.b = alpha * dot_rowcol_1540259130(row_t, (col + 2.5)/float(N), A, B_t, K);\\n\\t\\tsum_v.a = alpha * dot_rowcol_1540259130(row_t, (col + 3.5)/float(N), A, B_t, K);\\n\\t}\\n\\n\\tgl_FragColor = sum_v;\\n}\\n\",\n\t\tp_c = \"#define GLSLIFY 1\\n// fragment shader that calculates the matrix product and writes each\\n// element to a pixel component in a floating point texture.\\n// the output RGBA canvas.\\n// readPixel is used to read the bytes.\\n\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D A;\\t\\t// texture with data from padded A\\nuniform sampler2D B_t;\\t\\t// texture with data from padded transpose of B\\nuniform sampler2D C;\\t\\t// texture with data from C\\nuniform int K;\\t\\t// number of elements in shared dimension\\nuniform int N;\\t\\t// number of columns in output\\nuniform int pad;\\t\\t//\\nuniform float alpha; \\t// coefficient to multiplication\\nuniform float beta; \\t// coefficient to addition\\n\\n// sum of products between elements in row i (from A) x col j (from B)\\n\\n// Calculate the dot product between the row (from A) and column (from B)\\n// identified by the passed indeces (output texture coordinate space).\\n// We loop over elements in the row and column and sum the product\\n// using the glsl `dot` function to process four elements at a time.\\n// This four element optimization requires that the matrix B be\\n// transposed before texel packing and that both matrices be padded\\n// (with zeros) to a multiple of four (4) in their shared dimension.\\nfloat dot_rowcol_1540259130(float y, float x, sampler2D A, sampler2D B_t, int K) {\\n\\tfloat delta_t = 1./float(K);// space (on texture) between elements\\n\\tfloat sum = 0.;\\t\\t\\t// sum for this row/column pair\\n\\tfloat z = 0.5 * (4.0 * delta_t);// position for shared dimension on source textures\\n\\n\\tfor (int l=0 ; l<4096 ; ++l) {\\n\\t\\tif(l >= K / 4) break; // stop when we finish the row/column\\n\\t\\t// l is in pixel space, so we divide by four\\n\\n\\t\\t// retrieve next four elements from each texture\\n\\t\\tvec4 a_ik = texture2D( A, vec2(z, y));\\n\\t\\tvec4 b_kj = texture2D(B_t, vec2(z, x));\\n\\n\\t// use `dot` to process four elements at a time\\n\\t\\tsum += dot(a_ik, b_kj);\\n\\t\\tz += (4.0 * delta_t); // (z + 0.5)*delta\\n\\t}\\n\\treturn sum;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row_t = outTex.y;\\n\\tfloat col_t = outTex.x;\\n\\tvec4 c_v = texture2D(C, vec2(col_t, 0.5));\\n\\n\\tvec4 sum_v = vec4(0.0, 0.0, 0.0, 0.0);\\n\\tfloat col = (col_t * float(N + pad) - 2.0); // index of first element in pixel (matrix space)\\n\\tsum_v.r = alpha * dot_rowcol_1540259130(row_t, (col + 0.5)/float(N), A, B_t, K);\\n\\t// in the padding region?\\n\\tif(pad > 0 && (col + 4.0) > float(N) ) {\\n\\t\\t// pad\\n\\t\\tif(pad < 3){\\n\\t\\t\\tsum_v.g = alpha * dot_rowcol_1540259130(row_t, (col + 1.5)/float(N), A, B_t, K);\\n\\t\\t}\\n\\t\\tif(pad < 2){\\n\\t\\t\\tsum_v.b = alpha * dot_rowcol_1540259130(row_t, (col + 2.5)/float(N), A, B_t, K);\\n\\t\\t}\\n\\t} else {\\n\\t\\tsum_v.g = alpha * dot_rowcol_1540259130(row_t, (col + 1.5)/float(N), A, B_t, K);\\n\\t\\tsum_v.b = alpha * dot_rowcol_1540259130(row_t, (col + 2.5)/float(N), A, B_t, K);\\n\\t\\tsum_v.a = alpha * dot_rowcol_1540259130(row_t, (col + 3.5)/float(N), A, B_t, K);\\n\\t}\\n\\n\\tgl_FragColor = sum_v + beta*c_v;\\n}\\n\";\n\n\t// create the webgl shader program for this calculation\n\t// based on the specific fragment shader for this calculation\n\t// and the generic pass through shader\n\tif(this.standalone){\n\t\tthis.program_ = this.webgl.createProgram(s);\n\t\tthis.program_c = this.webgl.createProgram(s_c);\n\t} else {\n\t\tthis.program_ = this.webgl.createProgram(p);\n\t\tthis.program_c = this.webgl.createProgram(p_c);\n\t}\n\n}\n\nmodule.exports = SGEMMCalculator;\n\n/* Names of the uniforms (variables) used in the shader program passed in on\n each calculation.\n */\nSGEMMCalculator.TEXTURE_UNIFORM_NAME_0 = \"A\";\nSGEMMCalculator.TEXTURE_UNIFORM_NAME_1 = \"B_t\";\nSGEMMCalculator.TEXTURE_UNIFORM_NAME_2 = \"C\";\nSGEMMCalculator.SHARED_LENGTH_UNIFORM_NAME = \"K\";\nSGEMMCalculator.COLUMN_COUNT_UNIFORM_NAME = \"N\";\nSGEMMCalculator.PAD_UNIFORM_NAME = \"pad\";\nSGEMMCalculator.ALPHA_UNIFORM_NAME = \"alpha\";\nSGEMMCalculator.BETA_UNIFORM_NAME = \"beta\";\n\n/* Calculate the GEMM, with the given data.\n\n\tM - number of rows in A\n\tN - number of columns in B\n\tK - number of elements in shared dimension (including padding)\n\talpha - scalar for A\n\tA - left hand matrix (as padded texture)\n\tB - transpose of right hand matrix (as padded texture)\n\tbeta - scalar for C\n\tC - additive matrix (texture)\n\tout - output (texture)\n\n How this works:\n\n 1. Activate our shader program\n 2. Bind input textures\n 3. Set shader program parameters\n 4. Bind output texture\n 5. Activate calculation with `drawElements`\n\n TODO: signature should look like this:\n ( TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC )\n http://www.math.utah.edu/software/lapack/lapack-blas/dgemm.html\n */\nSGEMMCalculator.prototype.calculate = function(M, N, K, alpha, A, B, beta, C, out){\n\n\tvar gl = this.webgl.context;\n\n\t/*\n\tvar h1 = M, w1 = K,\n\t\th2 = K, w2 = N;\n\t*/\n\n\t// set this calculator program as the active program\n\tif(C != null){\n\t\tthis.program = this.program_c;\n\t} else {\n\t\tbeta = null;\n\t\tthis.program = this.program_;\n\t\t//console.log(\"no C\");\n\t}\n\tthis.webgl.selectProgram(this.program);\n\n\t// bind our input textures containing matrix data\n\tthis.bindInputTexture(A, gl.TEXTURE0, SGEMMCalculator.TEXTURE_UNIFORM_NAME_0);\n\tthis.bindInputTexture(B, gl.TEXTURE1, SGEMMCalculator.TEXTURE_UNIFORM_NAME_1);\n\tif(C != null){\n\t\tthis.bindInputTexture(C, gl.TEXTURE2, SGEMMCalculator.TEXTURE_UNIFORM_NAME_2);\n\t}\n\n\tvar kPad = this.webgl.getPad(K),\n\t\tnPad = this.webgl.getPad(N);\n\n\t// set the data specific variables in our shader program\n\tthis.bindUniforms(N, K + kPad, nPad, alpha, beta);\n\n\t// create our destination texture\n\tif(this.standalone){\n\t\tthis.webgl.bindOutputTexture(M, N + nPad, out);\n\t} else {\n\t\tthis.webgl.bindOutputTexture(M, (N + nPad)/ 4, out);\n\t}\n\n\t// initiate calculation\n\tgl.drawElements(gl.TRIANGLES, /*num items*/6, gl.UNSIGNED_SHORT, 0);\n\n\tthis.webgl.unbindInputTexture(gl.TEXTURE0);\n\tthis.webgl.unbindInputTexture(gl.TEXTURE1);\n\tthis.webgl.unbindInputTexture(gl.TEXTURE2);\n\n\t// result can now be read with gl.readResult, or more operations can be\n\t// performed on destination texture (in pipeline mode)\n};\n\n\n/* Create a texture from the given texel data and bind it to our shader program.\n\n\th - number of rows in input matrix\n\tw - number of cols in input matrix\n\ttexels - packed data\n\ttextureUnit - the texture unit to bind to (gl.TEXTURE0, gl.TEXTURE1, etc)\n\tname - the uniform name to associate with (must match shader program)\n\n\tmust compile program (with createProgram) first\n*/\nSGEMMCalculator.prototype.bindInputTexture = function(texture, textureUnit, name){\n\tvar gl = this.webgl.context,\n\t\tprogram = this.program;\n\n\tgl.activeTexture(textureUnit); // gl.TEXTURE0, gl.TEXTURE1, etc\n\tgl.bindTexture(\t gl.TEXTURE_2D, texture);\n\n\tvar sampler = gl.getUniformLocation(program, name);\n\tgl.uniform1i(sampler, textureUnit - gl.TEXTURE0);\n\n};\n\n\n/* Set up inputs for the texture shader\n\n\tK - size of shared dimension for multiplied matrices\n */\nSGEMMCalculator.prototype.bindUniforms = function(N, K, pad, alpha, beta) {\n\tvar gl = this.webgl.context;\n\n\t// get var locations\n\tvar K_gl\t = gl.getUniformLocation(this.program, SGEMMCalculator.SHARED_LENGTH_UNIFORM_NAME),\n\t\talpha_gl = gl.getUniformLocation(this.program, SGEMMCalculator.ALPHA_UNIFORM_NAME),\n\t\tbeta_gl = gl.getUniformLocation(this.program, SGEMMCalculator.BETA_UNIFORM_NAME),\n\t\tN_gl = gl.getUniformLocation(this.program, SGEMMCalculator.COLUMN_COUNT_UNIFORM_NAME),\n\t\tpad_gl = pad_gl = gl.getUniformLocation(this.program, SGEMMCalculator.PAD_UNIFORM_NAME);\n\n\tgl.uniform1f(beta_gl, beta);\n\tgl.uniform1i(N_gl, N);\n\tgl.uniform1i(pad_gl, pad);\n\n\t// bind length of shared dimension\n\tgl.uniform1i(K_gl, K);\n\t// bind alpha\n\tgl.uniform1f(alpha_gl, alpha);\n\n};\n","var WebGL = require('./webgl');\n\n/* Elementwise clamp function for matrices on the interval [a, b]. Can also be\n\tused for min or max, by passing Number.MIN_VALUE for the first parameter and\n\tNumber.MAX_VALUE for the second parameter, respectively.\n\n\tPassing `null` for either of these parameters will default to it's\n\trespective min or max value.\n\n\tmax(a, min(b, x)) for each x in X\n\n\twhere X is a matrix, a and b are scalars\n\n\n\twebgl - a weblas.WebGL object\n\tstandalone - whether or not to automatically run the floating point encode\n\t\tstep for rendering to an UNSIGNED_BYTE texture (this is required for\n\t\tmobile, circa 2015) but can't be used as part of a pipeline.\n\n\t* uploads and downloads data\n\t* executes calculation\n */\nfunction SCLMPCalculator(webgl, standalone){\n\tthis.webgl = webgl,\n\tthis.standalone = (standalone != null) ? standalone : true; // default to standalone mode\n\n\tvar s = \"#define GLSLIFY 1\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D X;\\t\\t// texture with data from padded A\\nuniform int N;\\t\\t// number of columns\\nuniform int pad;\\t\\t// additional columns to nearest multiple of four\\nuniform float a; \\t\\t// lower bound\\nuniform float b; \\t\\t// upper bound\\n\\n// Render float to bytes according to IEEE 754 Floating Point\\nvec4 encode_float_1540259130(float val) {\\n\\n\\t// TODO: correctly handle denormal numbers\\n\\t// http://www.2ality.com/2012/04/number-encoding.html\\n\\tfloat a = abs(val); // encode absolute value + sign\\n\\tfloat exp = floor(log2(a)); // number of powers of 2\\n\\tfloat mant = pow(2.,log2(a)-exp) * pow(2.,23.); // multiply to fill 24 bits (implied leading 1)\\n\\tfloat mant1 = floor(mant / 256. / 256.); // first 8 bits of mantissa\\n\\tfloat mant2 = mod(floor(mant / 256.),256.); // second 8 bits\\n\\tfloat mant3 = mod(mant,256.); // third 8 bits\\n\\n\\thighp float sign = 128.-128.*(a/val);\\t\\t\\t// sign bit is 256 or 0\\n\\thighp float e = (sign+exp+127.)/510.;\\t\\t// exponent and sign\\n\\thighp float m1 = (mant1-(128.*(1.-mod(exp+127.,2.))))/255.; // handle leading bit\\n\\thighp float m2 = (mant2)/255.;\\t\\t\\t\\t// middle part\\n\\thighp float m3 = (mant3+.5)/255.;\\t\\t\\t// scale to 0 - 255\\n\\n\\treturn vec4(m3,m2,m1,e);\\n}\\n\\n// select an element from a vector based on index\\nfloat select_index_1604150559(vec4 v, int index){\\n\\tfloat val;\\n\\tif (index == 0) {\\n\\t\\tval = v.r;\\n\\t} else if(index == 1) {\\n\\t\\tval = v.g;\\n\\t} else if(index == 2) {\\n\\t\\tval = v.b;\\n\\t} else if(index == 3){\\n\\t\\tval = v.a;\\n\\t} else {\\n\\t\\t// should never be here\\n\\t\\tval = 0.0;\\n\\t}\\n\\n\\treturn val;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row = outTex.y;\\n\\tfloat col = outTex.x;\\n\\n\\t// return 0.0 if in padded region of output texture\\n\\tif(col * float(N + pad) > float(N) ) {\\n\\t\\tgl_FragColor = vec4(0.,0.,0.,0.);\\n\\t\\treturn;\\n\\t}\\n\\n\\t// direct usage of col requires output be padded exactly like input\\n\\tvec4 x = texture2D( X, vec2(col, row));\\n\\tvec4 val = clamp(x, a, b);\\n\\n\\t// select and output channel (standalone version only)\\n\\tint channel = int(mod(col * float(N + pad), 4.0));\\n\\tfloat sum = select_index_1604150559(val, channel);\\n\\n\\tif (sum == 0.) {\\n\\t\\tgl_FragColor = vec4(0.,0.,0.,0.);\\n\\t\\treturn;\\n\\t}\\n\\n\\t// output vec4 with bytes for an IEEE754 32-bit floating point number\\n\\tgl_FragColor = encode_float_1540259130(sum);\\n}\\n\",\n\t\tp = \"#define GLSLIFY 1\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D X;\\t\\t// texture with data from padded A\\nuniform int N;\\t\\t// number of columns\\nuniform int pad;\\t\\t// additional columns to nearest multiple of four\\nuniform float a; \\t\\t// lower bound\\nuniform float b; \\t\\t// upper bound\\n\\n// set pad values to 0.0, if in padded region of output texture\\nvoid fix_pad_1540259130(inout vec4 v, int pad){\\n\\tv.a = 0.0;\\n\\tif(pad == 2){\\n\\t\\tv.b = 0.0;\\n\\t} else if(pad == 3){\\n\\t\\tv.b = 0.0;\\n\\t\\tv.g = 0.0;\\n\\t}\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row_t = outTex.y;\\n\\tfloat col_t = outTex.x;\\n\\tfloat col = (col_t * float(N + pad) - 2.0); // index of first element in pixel (matrix space)\\n\\n\\t// direct usage of col requires output be padded exactly like input\\n\\tvec4 x = texture2D( X, vec2(col_t, row_t));\\n\\tvec4 val_v = clamp(x, a, b);\\n\\n\\t// is last element in pixel past row length?\\n\\tif(pad > 0 && (col + 4.0) > float(N) ) {\\n\\t\\t// fix elements in padded region\\n\\t\\tfix_pad_1540259130(val_v, pad);\\n\\t}\\n\\n\\tgl_FragColor = val_v;\\n}\\n\";\n\n\t// create the webgl shader program for this calculation\n\t// based on the specific fragment shader for this calculation\n\t// and the generic pass through shader\n\tif(this.standalone){\n\t\tthis.program = this.webgl.createProgram(s);\n\t} else {\n\t\tthis.program = this.webgl.createProgram(p);\n\t}\n}\n\nmodule.exports = SCLMPCalculator;\n\n/* Names of the uniforms (variables) used in the shader program passed in on\n each calculation.\n */\nSCLMPCalculator.TEXTURE_UNIFORM_NAME_0 = \"X\";\nSCLMPCalculator.LENGTH_UNIFORM_NAME = \"N\";\nSCLMPCalculator.LOWER_UNIFORM_NAME = \"a\";\nSCLMPCalculator.UPPER_UNIFORM_NAME = \"b\";\n\n\n/* Elementwise clamp a matrix to the interval [a, b]\n\n\tM - number of rows in X\n\tN - number of columns in X\n\ta - lower bound (inclusize)\n\tb - upper bound (inclusive)\n\tX - matrix (texture)\n\tout - output (texture)\n\n How this works:\n\n 1. Activate our shader program\n 2. Bind input textures\n 3. Set shader program parameters\n 4. Bind output texture\n 5. Activate calculation with `drawElements`\n\n */\nSCLMPCalculator.prototype.calculate = function(M, N, a, b, X, out){\n\n\ta = (a != null) ? a : Number.MIN_VALUE;\n\tb = (b != null) ? b : Number.MAX_VALUE;\n\n\tvar gl = this.webgl.context;\n\n\tthis.webgl.selectProgram(this.program);\n\n\t// create and bind our input texture using matrix data\n\tthis.bindInputTexture(X, gl.TEXTURE0, SCLMPCalculator.TEXTURE_UNIFORM_NAME_0);\n\n\tvar nPad = this.webgl.getPad(N);\n\t// set the data specific variables in our shader program\n\tthis.bindUniforms(N, nPad, a, b);\n\n\t// create our destination texture\n\tif(this.standalone){\n\t\tthis.webgl.bindOutputTexture(M, N + nPad, out);\n\t} else {\n\t\tthis.webgl.bindOutputTexture(M, (N + nPad)/ 4, out);\n\t}\n\n\t// initiate calculation\n\tgl.drawElements(gl.TRIANGLES, /*num items*/6, gl.UNSIGNED_SHORT, 0);\n\n\tthis.webgl.unbindInputTexture(gl.TEXTURE0);\n\n};\n\n/* Create a texture from the given texel data and bind it to our shader program.\n\n\th - number of rows in input matrix\n\tw - number of cols in input matrix\n\ttexels - packed data\n\ttextureUnit - the texture unit to bind to (gl.TEXTURE0, gl.TEXTURE1, etc)\n\tname - the uniform name to associate with (must match shader program)\n\n\tmust compile program (with createProgram) first\n*/\nSCLMPCalculator.prototype.bindInputTexture = function(texture, textureUnit, name){\n\tvar gl = this.webgl.context,\n\t\tprogram = this.program;\n\n\tgl.activeTexture(textureUnit); // gl.TEXTURE0, gl.TEXTURE1, etc\n\tgl.bindTexture(\t gl.TEXTURE_2D, texture);\n\n\tvar sampler = gl.getUniformLocation(program, name);\n\tgl.uniform1i(sampler, textureUnit - gl.TEXTURE0);\n\n};\n\n/* Set up inputs for the texture shader\n\n */\nSCLMPCalculator.prototype.bindUniforms = function(N, pad, a, b) {\n\tvar gl = this.webgl.context;\n\n\t// get var locations\n\tvar N_gl = gl.getUniformLocation(this.program, SCLMPCalculator.LENGTH_UNIFORM_NAME),\n\t\tb_gl = gl.getUniformLocation(this.program, SCLMPCalculator.UPPER_UNIFORM_NAME),\n\t\ta_gl = gl.getUniformLocation(this.program, SCLMPCalculator.LOWER_UNIFORM_NAME),\n\t\tpad_gl = gl.getUniformLocation(this.program, \"pad\");\n\n\t// bind length of shared dimension\n\tgl.uniform1i(N_gl, N);\n\tgl.uniform1i(pad_gl, pad);\n\tgl.uniform1f(a_gl, a);\n\tgl.uniform1f(b_gl, b);\n\n};\n","var globals = require(\"./globals\");\n\nvar gl = globals.gl;\n\nfunction Tensor(shape, data){\n\tif(shape.length != 2)\n\t\tthrow new Error(\"Only Tensor of order two (matrix) is supported right now.\");\n\n\tvar M = shape[0],\n\t\tN = shape[1];\n\n\tthis.texture = gl.createDataTexture(M, N, data);\n\n\tthis.shape = [M, N];\n}\n\nmodule.exports = Tensor;\n\nTensor.prototype.delete = function(){\n\tgl.context.deleteTexture(this.texture);\n\tthis.texture = null;\n\tthis.shape = null;\n};\n\nTensor.prototype.transfer = function(keep){\n\n\tvar M = this.shape[0],\n\t\tN = this.shape[1],\n\t\tout,\n\t\tresult;\n\n\t// create output texture\n\tout = gl.createOutputTexture(M, N);\n\n\t// float extraction\n\tgl.encode(M, N, this.texture, out);\n\n\tresult = new Float32Array(gl.readData(M, N));\n\n\t// clean up\n\tgl.context.deleteTexture(out);\n\n\tif(!keep){\n\t\tthis.delete();\n\t}\n\n\treturn result;\n};\n\nTensor.prototype.reshape = function(shape, keep){\n\n\tvar M = this.shape[0],\n\t\tN = this.shape[1],\n\t\tM_out = shape[0],\n\t\tN_out = shape[1];\n\n\t// create new texture to hold tranpose\n\tvar t0 = new Tensor(shape, null);\n\n\t// invoke shader\n\tgl.reshape(M, N, M_out, N_out, this.texture, t0.texture);\n\n\tif(!keep){\n\t\tthis.delete();\n\t}\n\n\treturn t0;\n};\n\nTensor.prototype.transpose = function(keep){\n\n\tvar M = this.shape[0],\n\t\tN = this.shape[1];\n\n\t// create new texture to hold tranpose\n\tvar tT = new Tensor([N, M], null);\n\n\t// invoke shader\n\tgl.transpose(M, N, this.texture, tT.texture);\n\n\tif(!keep){\n\t\tthis.delete();\n\t}\n\n\treturn tT;\n};\n","exports.load = function(url, callback) {\n\tvar xhr = new XMLHttpRequest();\n\n\txhr.onreadystatechange = function() {\n\t\tif (xhr.readyState !== 4) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (xhr.status >= 200 && xhr.status < 300) {\n\t\t\tcallback(null, xhr.responseText);\n\t\t} else {\n\t\t\tvar err = new Error(\"failed to request file '\" + url + \"'\");\n\t\t\t// follow Node.js error signature\n\t\t\terr.errno = 34;\n\t\t\tcallback(err);\n\t\t}\n\t};\n\n\ttry {\n\t\txhr.open('GET', url, true);\n\t\txhr.send(null);\n\t} catch (err) {\n\t\tcallback(err);\n\t}\n};","/*!\n * async\n * https://github.com/caolan/async\n *\n * Copyright 2010-2014 Caolan McMahon\n * Released under the MIT license\n */\n(function () {\n\n var async = {};\n function noop() {}\n function identity(v) {\n return v;\n }\n function toBool(v) {\n return !!v;\n }\n function notId(v) {\n return !v;\n }\n\n // global on the server, window in the browser\n var previous_async;\n\n // Establish the root object, `window` (`self`) in the browser, `global`\n // on the server, or `this` in some virtual machines. We use `self`\n // instead of `window` for `WebWorker` support.\n var root = typeof self === 'object' && self.self === self && self ||\n typeof global === 'object' && global.global === global && global ||\n this;\n\n if (root != null) {\n previous_async = root.async;\n }\n\n async.noConflict = function () {\n root.async = previous_async;\n return async;\n };\n\n function only_once(fn) {\n return function() {\n if (fn === null) throw new Error(\"Callback was already called.\");\n fn.apply(this, arguments);\n fn = null;\n };\n }\n\n function _once(fn) {\n return function() {\n if (fn === null) return;\n fn.apply(this, arguments);\n fn = null;\n };\n }\n\n //// cross-browser compatiblity functions ////\n\n var _toString = Object.prototype.toString;\n\n var _isArray = Array.isArray || function (obj) {\n return _toString.call(obj) === '[object Array]';\n };\n\n // Ported from underscore.js isObject\n var _isObject = function(obj) {\n var type = typeof obj;\n return type === 'function' || type === 'object' && !!obj;\n };\n\n function _isArrayLike(arr) {\n return _isArray(arr) || (\n // has a positive integer length property\n typeof arr.length === \"number\" &&\n arr.length >= 0 &&\n arr.length % 1 === 0\n );\n }\n\n function _arrayEach(arr, iterator) {\n var index = -1,\n length = arr.length;\n\n while (++index < length) {\n iterator(arr[index], index, arr);\n }\n }\n\n function _map(arr, iterator) {\n var index = -1,\n length = arr.length,\n result = Array(length);\n\n while (++index < length) {\n result[index] = iterator(arr[index], index, arr);\n }\n return result;\n }\n\n function _range(count) {\n return _map(Array(count), function (v, i) { return i; });\n }\n\n function _reduce(arr, iterator, memo) {\n _arrayEach(arr, function (x, i, a) {\n memo = iterator(memo, x, i, a);\n });\n return memo;\n }\n\n function _forEachOf(object, iterator) {\n _arrayEach(_keys(object), function (key) {\n iterator(object[key], key);\n });\n }\n\n function _indexOf(arr, item) {\n for (var i = 0; i < arr.length; i++) {\n if (arr[i] === item) return i;\n }\n return -1;\n }\n\n var _keys = Object.keys || function (obj) {\n var keys = [];\n for (var k in obj) {\n if (obj.hasOwnProperty(k)) {\n keys.push(k);\n }\n }\n return keys;\n };\n\n function _keyIterator(coll) {\n var i = -1;\n var len;\n var keys;\n if (_isArrayLike(coll)) {\n len = coll.length;\n return function next() {\n i++;\n return i < len ? i : null;\n };\n } else {\n keys = _keys(coll);\n len = keys.length;\n return function next() {\n i++;\n return i < len ? keys[i] : null;\n };\n }\n }\n\n // Similar to ES6's rest param (http://ariya.ofilabs.com/2013/03/es6-and-rest-parameter.html)\n // This accumulates the arguments passed into an array, after a given index.\n // From underscore.js (https://github.com/jashkenas/underscore/pull/2140).\n function _restParam(func, startIndex) {\n startIndex = startIndex == null ? func.length - 1 : +startIndex;\n return function() {\n var length = Math.max(arguments.length - startIndex, 0);\n var rest = Array(length);\n for (var index = 0; index < length; index++) {\n rest[index] = arguments[index + startIndex];\n }\n switch (startIndex) {\n case 0: return func.call(this, rest);\n case 1: return func.call(this, arguments[0], rest);\n }\n // Currently unused but handle cases outside of the switch statement:\n // var args = Array(startIndex + 1);\n // for (index = 0; index < startIndex; index++) {\n // args[index] = arguments[index];\n // }\n // args[startIndex] = rest;\n // return func.apply(this, args);\n };\n }\n\n function _withoutIndex(iterator) {\n return function (value, index, callback) {\n return iterator(value, callback);\n };\n }\n\n //// exported async module functions ////\n\n //// nextTick implementation with browser-compatible fallback ////\n\n // capture the global reference to guard against fakeTimer mocks\n var _setImmediate = typeof setImmediate === 'function' && setImmediate;\n\n var _delay = _setImmediate ? function(fn) {\n // not a direct alias for IE10 compatibility\n _setImmediate(fn);\n } : function(fn) {\n setTimeout(fn, 0);\n };\n\n if (typeof process === 'object' && typeof process.nextTick === 'function') {\n async.nextTick = process.nextTick;\n } else {\n async.nextTick = _delay;\n }\n async.setImmediate = _setImmediate ? _delay : async.nextTick;\n\n\n async.forEach =\n async.each = function (arr, iterator, callback) {\n return async.eachOf(arr, _withoutIndex(iterator), callback);\n };\n\n async.forEachSeries =\n async.eachSeries = function (arr, iterator, callback) {\n return async.eachOfSeries(arr, _withoutIndex(iterator), callback);\n };\n\n\n async.forEachLimit =\n async.eachLimit = function (arr, limit, iterator, callback) {\n return _eachOfLimit(limit)(arr, _withoutIndex(iterator), callback);\n };\n\n async.forEachOf =\n async.eachOf = function (object, iterator, callback) {\n callback = _once(callback || noop);\n object = object || [];\n\n var iter = _keyIterator(object);\n var key, completed = 0;\n\n while ((key = iter()) != null) {\n completed += 1;\n iterator(object[key], key, only_once(done));\n }\n\n if (completed === 0) callback(null);\n\n function done(err) {\n completed--;\n if (err) {\n callback(err);\n }\n // Check key is null in case iterator isn't exhausted\n // and done resolved synchronously.\n else if (key === null && completed <= 0) {\n callback(null);\n }\n }\n };\n\n async.forEachOfSeries =\n async.eachOfSeries = function (obj, iterator, callback) {\n callback = _once(callback || noop);\n obj = obj || [];\n var nextKey = _keyIterator(obj);\n var key = nextKey();\n function iterate() {\n var sync = true;\n if (key === null) {\n return callback(null);\n }\n iterator(obj[key], key, only_once(function (err) {\n if (err) {\n callback(err);\n }\n else {\n key = nextKey();\n if (key === null) {\n return callback(null);\n } else {\n if (sync) {\n async.setImmediate(iterate);\n } else {\n iterate();\n }\n }\n }\n }));\n sync = false;\n }\n iterate();\n };\n\n\n\n async.forEachOfLimit =\n async.eachOfLimit = function (obj, limit, iterator, callback) {\n _eachOfLimit(limit)(obj, iterator, callback);\n };\n\n function _eachOfLimit(limit) {\n\n return function (obj, iterator, callback) {\n callback = _once(callback || noop);\n obj = obj || [];\n var nextKey = _keyIterator(obj);\n if (limit <= 0) {\n return callback(null);\n }\n var done = false;\n var running = 0;\n var errored = false;\n\n (function replenish () {\n if (done && running <= 0) {\n return callback(null);\n }\n\n while (running < limit && !errored) {\n var key = nextKey();\n if (key === null) {\n done = true;\n if (running <= 0) {\n callback(null);\n }\n return;\n }\n running += 1;\n iterator(obj[key], key, only_once(function (err) {\n running -= 1;\n if (err) {\n callback(err);\n errored = true;\n }\n else {\n replenish();\n }\n }));\n }\n })();\n };\n }\n\n\n function doParallel(fn) {\n return function (obj, iterator, callback) {\n return fn(async.eachOf, obj, iterator, callback);\n };\n }\n function doParallelLimit(fn) {\n return function (obj, limit, iterator, callback) {\n return fn(_eachOfLimit(limit), obj, iterator, callback);\n };\n }\n function doSeries(fn) {\n return function (obj, iterator, callback) {\n return fn(async.eachOfSeries, obj, iterator, callback);\n };\n }\n\n function _asyncMap(eachfn, arr, iterator, callback) {\n callback = _once(callback || noop);\n arr = arr || [];\n var results = _isArrayLike(arr) ? [] : {};\n eachfn(arr, function (value, index, callback) {\n iterator(value, function (err, v) {\n results[index] = v;\n callback(err);\n });\n }, function (err) {\n callback(err, results);\n });\n }\n\n async.map = doParallel(_asyncMap);\n async.mapSeries = doSeries(_asyncMap);\n async.mapLimit = doParallelLimit(_asyncMap);\n\n // reduce only has a series version, as doing reduce in parallel won't\n // work in many situations.\n async.inject =\n async.foldl =\n async.reduce = function (arr, memo, iterator, callback) {\n async.eachOfSeries(arr, function (x, i, callback) {\n iterator(memo, x, function (err, v) {\n memo = v;\n callback(err);\n });\n }, function (err) {\n callback(err, memo);\n });\n };\n\n async.foldr =\n async.reduceRight = function (arr, memo, iterator, callback) {\n var reversed = _map(arr, identity).reverse();\n async.reduce(reversed, memo, iterator, callback);\n };\n\n async.transform = function (arr, memo, iterator, callback) {\n if (arguments.length === 3) {\n callback = iterator;\n iterator = memo;\n memo = _isArray(arr) ? [] : {};\n }\n\n async.eachOf(arr, function(v, k, cb) {\n iterator(memo, v, k, cb);\n }, function(err) {\n callback(err, memo);\n });\n };\n\n function _filter(eachfn, arr, iterator, callback) {\n var results = [];\n eachfn(arr, function (x, index, callback) {\n iterator(x, function (v) {\n if (v) {\n results.push({index: index, value: x});\n }\n callback();\n });\n }, function () {\n callback(_map(results.sort(function (a, b) {\n return a.index - b.index;\n }), function (x) {\n return x.value;\n }));\n });\n }\n\n async.select =\n async.filter = doParallel(_filter);\n\n async.selectLimit =\n async.filterLimit = doParallelLimit(_filter);\n\n async.selectSeries =\n async.filterSeries = doSeries(_filter);\n\n function _reject(eachfn, arr, iterator, callback) {\n _filter(eachfn, arr, function(value, cb) {\n iterator(value, function(v) {\n cb(!v);\n });\n }, callback);\n }\n async.reject = doParallel(_reject);\n async.rejectLimit = doParallelLimit(_reject);\n async.rejectSeries = doSeries(_reject);\n\n function _createTester(eachfn, check, getResult) {\n return function(arr, limit, iterator, cb) {\n function done() {\n if (cb) cb(getResult(false, void 0));\n }\n function iteratee(x, _, callback) {\n if (!cb) return callback();\n iterator(x, function (v) {\n if (cb && check(v)) {\n cb(getResult(true, x));\n cb = iterator = false;\n }\n callback();\n });\n }\n if (arguments.length > 3) {\n eachfn(arr, limit, iteratee, done);\n } else {\n cb = iterator;\n iterator = limit;\n eachfn(arr, iteratee, done);\n }\n };\n }\n\n async.any =\n async.some = _createTester(async.eachOf, toBool, identity);\n\n async.someLimit = _createTester(async.eachOfLimit, toBool, identity);\n\n async.all =\n async.every = _createTester(async.eachOf, notId, notId);\n\n async.everyLimit = _createTester(async.eachOfLimit, notId, notId);\n\n function _findGetResult(v, x) {\n return x;\n }\n async.detect = _createTester(async.eachOf, identity, _findGetResult);\n async.detectSeries = _createTester(async.eachOfSeries, identity, _findGetResult);\n async.detectLimit = _createTester(async.eachOfLimit, identity, _findGetResult);\n\n async.sortBy = function (arr, iterator, callback) {\n async.map(arr, function (x, callback) {\n iterator(x, function (err, criteria) {\n if (err) {\n callback(err);\n }\n else {\n callback(null, {value: x, criteria: criteria});\n }\n });\n }, function (err, results) {\n if (err) {\n return callback(err);\n }\n else {\n callback(null, _map(results.sort(comparator), function (x) {\n return x.value;\n }));\n }\n\n });\n\n function comparator(left, right) {\n var a = left.criteria, b = right.criteria;\n return a < b ? -1 : a > b ? 1 : 0;\n }\n };\n\n async.auto = function (tasks, concurrency, callback) {\n if (!callback) {\n // concurrency is optional, shift the args.\n callback = concurrency;\n concurrency = null;\n }\n callback = _once(callback || noop);\n var keys = _keys(tasks);\n var remainingTasks = keys.length;\n if (!remainingTasks) {\n return callback(null);\n }\n if (!concurrency) {\n concurrency = remainingTasks;\n }\n\n var results = {};\n var runningTasks = 0;\n\n var listeners = [];\n function addListener(fn) {\n listeners.unshift(fn);\n }\n function removeListener(fn) {\n var idx = _indexOf(listeners, fn);\n if (idx >= 0) listeners.splice(idx, 1);\n }\n function taskComplete() {\n remainingTasks--;\n _arrayEach(listeners.slice(0), function (fn) {\n fn();\n });\n }\n\n addListener(function () {\n if (!remainingTasks) {\n callback(null, results);\n }\n });\n\n _arrayEach(keys, function (k) {\n var task = _isArray(tasks[k]) ? tasks[k]: [tasks[k]];\n var taskCallback = _restParam(function(err, args) {\n runningTasks--;\n if (args.length <= 1) {\n args = args[0];\n }\n if (err) {\n var safeResults = {};\n _forEachOf(results, function(val, rkey) {\n safeResults[rkey] = val;\n });\n safeResults[k] = args;\n callback(err, safeResults);\n }\n else {\n results[k] = args;\n async.setImmediate(taskComplete);\n }\n });\n var requires = task.slice(0, task.length - 1);\n // prevent dead-locks\n var len = requires.length;\n var dep;\n while (len--) {\n if (!(dep = tasks[requires[len]])) {\n throw new Error('Has inexistant dependency');\n }\n if (_isArray(dep) && _indexOf(dep, k) >= 0) {\n throw new Error('Has cyclic dependencies');\n }\n }\n function ready() {\n return runningTasks < concurrency && _reduce(requires, function (a, x) {\n return (a && results.hasOwnProperty(x));\n }, true) && !results.hasOwnProperty(k);\n }\n if (ready()) {\n runningTasks++;\n task[task.length - 1](taskCallback, results);\n }\n else {\n addListener(listener);\n }\n function listener() {\n if (ready()) {\n runningTasks++;\n removeListener(listener);\n task[task.length - 1](taskCallback, results);\n }\n }\n });\n };\n\n\n\n async.retry = function(times, task, callback) {\n var DEFAULT_TIMES = 5;\n var DEFAULT_INTERVAL = 0;\n\n var attempts = [];\n\n var opts = {\n times: DEFAULT_TIMES,\n interval: DEFAULT_INTERVAL\n };\n\n function parseTimes(acc, t){\n if(typeof t === 'number'){\n acc.times = parseInt(t, 10) || DEFAULT_TIMES;\n } else if(typeof t === 'object'){\n acc.times = parseInt(t.times, 10) || DEFAULT_TIMES;\n acc.interval = parseInt(t.interval, 10) || DEFAULT_INTERVAL;\n } else {\n throw new Error('Unsupported argument type for \\'times\\': ' + typeof t);\n }\n }\n\n var length = arguments.length;\n if (length < 1 || length > 3) {\n throw new Error('Invalid arguments - must be either (task), (task, callback), (times, task) or (times, task, callback)');\n } else if (length <= 2 && typeof times === 'function') {\n callback = task;\n task = times;\n }\n if (typeof times !== 'function') {\n parseTimes(opts, times);\n }\n opts.callback = callback;\n opts.task = task;\n\n function wrappedTask(wrappedCallback, wrappedResults) {\n function retryAttempt(task, finalAttempt) {\n return function(seriesCallback) {\n task(function(err, result){\n seriesCallback(!err || finalAttempt, {err: err, result: result});\n }, wrappedResults);\n };\n }\n\n function retryInterval(interval){\n return function(seriesCallback){\n setTimeout(function(){\n seriesCallback(null);\n }, interval);\n };\n }\n\n while (opts.times) {\n\n var finalAttempt = !(opts.times-=1);\n attempts.push(retryAttempt(opts.task, finalAttempt));\n if(!finalAttempt && opts.interval > 0){\n attempts.push(retryInterval(opts.interval));\n }\n }\n\n async.series(attempts, function(done, data){\n data = data[data.length - 1];\n (wrappedCallback || opts.callback)(data.err, data.result);\n });\n }\n\n // If a callback is passed, run this as a controll flow\n return opts.callback ? wrappedTask() : wrappedTask;\n };\n\n async.waterfall = function (tasks, callback) {\n callback = _once(callback || noop);\n if (!_isArray(tasks)) {\n var err = new Error('First argument to waterfall must be an array of functions');\n return callback(err);\n }\n if (!tasks.length) {\n return callback();\n }\n function wrapIterator(iterator) {\n return _restParam(function (err, args) {\n if (err) {\n callback.apply(null, [err].concat(args));\n }\n else {\n var next = iterator.next();\n if (next) {\n args.push(wrapIterator(next));\n }\n else {\n args.push(callback);\n }\n ensureAsync(iterator).apply(null, args);\n }\n });\n }\n wrapIterator(async.iterator(tasks))();\n };\n\n function _parallel(eachfn, tasks, callback) {\n callback = callback || noop;\n var results = _isArrayLike(tasks) ? [] : {};\n\n eachfn(tasks, function (task, key, callback) {\n task(_restParam(function (err, args) {\n if (args.length <= 1) {\n args = args[0];\n }\n results[key] = args;\n callback(err);\n }));\n }, function (err) {\n callback(err, results);\n });\n }\n\n async.parallel = function (tasks, callback) {\n _parallel(async.eachOf, tasks, callback);\n };\n\n async.parallelLimit = function(tasks, limit, callback) {\n _parallel(_eachOfLimit(limit), tasks, callback);\n };\n\n async.series = function(tasks, callback) {\n _parallel(async.eachOfSeries, tasks, callback);\n };\n\n async.iterator = function (tasks) {\n function makeCallback(index) {\n function fn() {\n if (tasks.length) {\n tasks[index].apply(null, arguments);\n }\n return fn.next();\n }\n fn.next = function () {\n return (index < tasks.length - 1) ? makeCallback(index + 1): null;\n };\n return fn;\n }\n return makeCallback(0);\n };\n\n async.apply = _restParam(function (fn, args) {\n return _restParam(function (callArgs) {\n return fn.apply(\n null, args.concat(callArgs)\n );\n });\n });\n\n function _concat(eachfn, arr, fn, callback) {\n var result = [];\n eachfn(arr, function (x, index, cb) {\n fn(x, function (err, y) {\n result = result.concat(y || []);\n cb(err);\n });\n }, function (err) {\n callback(err, result);\n });\n }\n async.concat = doParallel(_concat);\n async.concatSeries = doSeries(_concat);\n\n async.whilst = function (test, iterator, callback) {\n callback = callback || noop;\n if (test()) {\n var next = _restParam(function(err, args) {\n if (err) {\n callback(err);\n } else if (test.apply(this, args)) {\n iterator(next);\n } else {\n callback(null);\n }\n });\n iterator(next);\n } else {\n callback(null);\n }\n };\n\n async.doWhilst = function (iterator, test, callback) {\n var calls = 0;\n return async.whilst(function() {\n return ++calls <= 1 || test.apply(this, arguments);\n }, iterator, callback);\n };\n\n async.until = function (test, iterator, callback) {\n return async.whilst(function() {\n return !test.apply(this, arguments);\n }, iterator, callback);\n };\n\n async.doUntil = function (iterator, test, callback) {\n return async.doWhilst(iterator, function() {\n return !test.apply(this, arguments);\n }, callback);\n };\n\n async.during = function (test, iterator, callback) {\n callback = callback || noop;\n\n var next = _restParam(function(err, args) {\n if (err) {\n callback(err);\n } else {\n args.push(check);\n test.apply(this, args);\n }\n });\n\n var check = function(err, truth) {\n if (err) {\n callback(err);\n } else if (truth) {\n iterator(next);\n } else {\n callback(null);\n }\n };\n\n test(check);\n };\n\n async.doDuring = function (iterator, test, callback) {\n var calls = 0;\n async.during(function(next) {\n if (calls++ < 1) {\n next(null, true);\n } else {\n test.apply(this, arguments);\n }\n }, iterator, callback);\n };\n\n function _queue(worker, concurrency, payload) {\n if (concurrency == null) {\n concurrency = 1;\n }\n else if(concurrency === 0) {\n throw new Error('Concurrency must not be zero');\n }\n function _insert(q, data, pos, callback) {\n if (callback != null && typeof callback !== \"function\") {\n throw new Error(\"task callback must be a function\");\n }\n q.started = true;\n if (!_isArray(data)) {\n data = [data];\n }\n if(data.length === 0 && q.idle()) {\n // call drain immediately if there are no tasks\n return async.setImmediate(function() {\n q.drain();\n });\n }\n _arrayEach(data, function(task) {\n var item = {\n data: task,\n callback: callback || noop\n };\n\n if (pos) {\n q.tasks.unshift(item);\n } else {\n q.tasks.push(item);\n }\n\n if (q.tasks.length === q.concurrency) {\n q.saturated();\n }\n });\n async.setImmediate(q.process);\n }\n function _next(q, tasks) {\n return function(){\n workers -= 1;\n\n var removed = false;\n var args = arguments;\n _arrayEach(tasks, function (task) {\n _arrayEach(workersList, function (worker, index) {\n if (worker === task && !removed) {\n workersList.splice(index, 1);\n removed = true;\n }\n });\n\n task.callback.apply(task, args);\n });\n if (q.tasks.length + workers === 0) {\n q.drain();\n }\n q.process();\n };\n }\n\n var workers = 0;\n var workersList = [];\n var q = {\n tasks: [],\n concurrency: concurrency,\n payload: payload,\n saturated: noop,\n empty: noop,\n drain: noop,\n started: false,\n paused: false,\n push: function (data, callback) {\n _insert(q, data, false, callback);\n },\n kill: function () {\n q.drain = noop;\n q.tasks = [];\n },\n unshift: function (data, callback) {\n _insert(q, data, true, callback);\n },\n process: function () {\n if (!q.paused && workers < q.concurrency && q.tasks.length) {\n while(workers < q.concurrency && q.tasks.length){\n var tasks = q.payload ?\n q.tasks.splice(0, q.payload) :\n q.tasks.splice(0, q.tasks.length);\n\n var data = _map(tasks, function (task) {\n return task.data;\n });\n\n if (q.tasks.length === 0) {\n q.empty();\n }\n workers += 1;\n workersList.push(tasks[0]);\n var cb = only_once(_next(q, tasks));\n worker(data, cb);\n }\n }\n },\n length: function () {\n return q.tasks.length;\n },\n running: function () {\n return workers;\n },\n workersList: function () {\n return workersList;\n },\n idle: function() {\n return q.tasks.length + workers === 0;\n },\n pause: function () {\n q.paused = true;\n },\n resume: function () {\n if (q.paused === false) { return; }\n q.paused = false;\n var resumeCount = Math.min(q.concurrency, q.tasks.length);\n // Need to call q.process once per concurrent\n // worker to preserve full concurrency after pause\n for (var w = 1; w <= resumeCount; w++) {\n async.setImmediate(q.process);\n }\n }\n };\n return q;\n }\n\n async.queue = function (worker, concurrency) {\n var q = _queue(function (items, cb) {\n worker(items[0], cb);\n }, concurrency, 1);\n\n return q;\n };\n\n async.priorityQueue = function (worker, concurrency) {\n\n function _compareTasks(a, b){\n return a.priority - b.priority;\n }\n\n function _binarySearch(sequence, item, compare) {\n var beg = -1,\n end = sequence.length - 1;\n while (beg < end) {\n var mid = beg + ((end - beg + 1) >>> 1);\n if (compare(item, sequence[mid]) >= 0) {\n beg = mid;\n } else {\n end = mid - 1;\n }\n }\n return beg;\n }\n\n function _insert(q, data, priority, callback) {\n if (callback != null && typeof callback !== \"function\") {\n throw new Error(\"task callback must be a function\");\n }\n q.started = true;\n if (!_isArray(data)) {\n data = [data];\n }\n if(data.length === 0) {\n // call drain immediately if there are no tasks\n return async.setImmediate(function() {\n q.drain();\n });\n }\n _arrayEach(data, function(task) {\n var item = {\n data: task,\n priority: priority,\n callback: typeof callback === 'function' ? callback : noop\n };\n\n q.tasks.splice(_binarySearch(q.tasks, item, _compareTasks) + 1, 0, item);\n\n if (q.tasks.length === q.concurrency) {\n q.saturated();\n }\n async.setImmediate(q.process);\n });\n }\n\n // Start with a normal queue\n var q = async.queue(worker, concurrency);\n\n // Override push to accept second parameter representing priority\n q.push = function (data, priority, callback) {\n _insert(q, data, priority, callback);\n };\n\n // Remove unshift function\n delete q.unshift;\n\n return q;\n };\n\n async.cargo = function (worker, payload) {\n return _queue(worker, 1, payload);\n };\n\n function _console_fn(name) {\n return _restParam(function (fn, args) {\n fn.apply(null, args.concat([_restParam(function (err, args) {\n if (typeof console === 'object') {\n if (err) {\n if (console.error) {\n console.error(err);\n }\n }\n else if (console[name]) {\n _arrayEach(args, function (x) {\n console[name](x);\n });\n }\n }\n })]));\n });\n }\n async.log = _console_fn('log');\n async.dir = _console_fn('dir');\n /*async.info = _console_fn('info');\n async.warn = _console_fn('warn');\n async.error = _console_fn('error');*/\n\n async.memoize = function (fn, hasher) {\n var memo = {};\n var queues = {};\n hasher = hasher || identity;\n var memoized = _restParam(function memoized(args) {\n var callback = args.pop();\n var key = hasher.apply(null, args);\n if (key in memo) {\n async.setImmediate(function () {\n callback.apply(null, memo[key]);\n });\n }\n else if (key in queues) {\n queues[key].push(callback);\n }\n else {\n queues[key] = [callback];\n fn.apply(null, args.concat([_restParam(function (args) {\n memo[key] = args;\n var q = queues[key];\n delete queues[key];\n for (var i = 0, l = q.length; i < l; i++) {\n q[i].apply(null, args);\n }\n })]));\n }\n });\n memoized.memo = memo;\n memoized.unmemoized = fn;\n return memoized;\n };\n\n async.unmemoize = function (fn) {\n return function () {\n return (fn.unmemoized || fn).apply(null, arguments);\n };\n };\n\n function _times(mapper) {\n return function (count, iterator, callback) {\n mapper(_range(count), iterator, callback);\n };\n }\n\n async.times = _times(async.map);\n async.timesSeries = _times(async.mapSeries);\n async.timesLimit = function (count, limit, iterator, callback) {\n return async.mapLimit(_range(count), limit, iterator, callback);\n };\n\n async.seq = function (/* functions... */) {\n var fns = arguments;\n return _restParam(function (args) {\n var that = this;\n\n var callback = args[args.length - 1];\n if (typeof callback == 'function') {\n args.pop();\n } else {\n callback = noop;\n }\n\n async.reduce(fns, args, function (newargs, fn, cb) {\n fn.apply(that, newargs.concat([_restParam(function (err, nextargs) {\n cb(err, nextargs);\n })]));\n },\n function (err, results) {\n callback.apply(that, [err].concat(results));\n });\n });\n };\n\n async.compose = function (/* functions... */) {\n return async.seq.apply(null, Array.prototype.reverse.call(arguments));\n };\n\n\n function _applyEach(eachfn) {\n return _restParam(function(fns, args) {\n var go = _restParam(function(args) {\n var that = this;\n var callback = args.pop();\n return eachfn(fns, function (fn, _, cb) {\n fn.apply(that, args.concat([cb]));\n },\n callback);\n });\n if (args.length) {\n return go.apply(this, args);\n }\n else {\n return go;\n }\n });\n }\n\n async.applyEach = _applyEach(async.eachOf);\n async.applyEachSeries = _applyEach(async.eachOfSeries);\n\n\n async.forever = function (fn, callback) {\n var done = only_once(callback || noop);\n var task = ensureAsync(fn);\n function next(err) {\n if (err) {\n return done(err);\n }\n task(next);\n }\n next();\n };\n\n function ensureAsync(fn) {\n return _restParam(function (args) {\n var callback = args.pop();\n args.push(function () {\n var innerArgs = arguments;\n if (sync) {\n async.setImmediate(function () {\n callback.apply(null, innerArgs);\n });\n } else {\n callback.apply(null, innerArgs);\n }\n });\n var sync = true;\n fn.apply(this, args);\n sync = false;\n });\n }\n\n async.ensureAsync = ensureAsync;\n\n async.constant = _restParam(function(values) {\n var args = [null].concat(values);\n return function (callback) {\n return callback.apply(this, args);\n };\n });\n\n async.wrapSync =\n async.asyncify = function asyncify(func) {\n return _restParam(function (args) {\n var callback = args.pop();\n var result;\n try {\n result = func.apply(this, args);\n } catch (e) {\n return callback(e);\n }\n // if result is Promise object\n if (_isObject(result) && typeof result.then === \"function\") {\n result.then(function(value) {\n callback(null, value);\n })[\"catch\"](function(err) {\n callback(err.message ? err : new Error(err));\n });\n } else {\n callback(null, result);\n }\n });\n };\n\n // Node.js\n if (typeof module === 'object' && module.exports) {\n module.exports = async;\n }\n // AMD / RequireJS\n else if (typeof define === 'function' && define.amd) {\n define([], function () {\n return async;\n });\n }\n // included directly via <script> tag\n else {\n root.async = async;\n }\n\n}());\n","\n/*\nCopyright (c) 2015 Waylon Flinn\n\nwebgl.js\n\nmultiply matrices up to 4096 x 4096 on GPUs that support OES_texture_float\nextension. input is encoded into the red and green channels of an input texture and\ncalculations are done using a custom fragment shader.\n\n*/\n\n\n/*\n\tA WebGL context associated with a specific canvas element.\n\n\t* creates a canvas\n\t* sets up webgl context\n\t* translates numbers into textures\n\t* compiles shader programs for executing math (when supplied with an\n\t\toperation specific fragment shader)\n */\nfunction WebGL(options) {\n\n\tvar glOptions,\n\t\text;\n\n\toptions = options || {};\n\n\t// canvas\n\tif(typeof options.canvas === 'undefined')\n\t\tthis.canvas = document.createElement('canvas');\n\telse\n\t\tthis.canvas = options.canvas;\n\n\t// context\n\tglOptions = { premultipliedAlpha: false, preserveDrawingBuffer: false };\n\tthis.context = this.canvas.getContext(\"experimental-webgl\", glOptions);\n\n\tif (typeof this.context === 'undefined')\n\t\tthrow new Error(\"No support for Webgl.\");\n\n\t// float texture extension\n\ttry {\n\t\text = this.context.getExtension('OES_texture_float');\n\t} catch(e) {\n\n\t}\n\tif ( !ext ) {\n\t\tconsole.log(\"No support for OES_texture_float extension.\");\n\t\tthis.hasFloat = false;\n\t} else {\n\t\tthis.hasFloat = true;\n\t}\n\n\tvar highp = this.context.getShaderPrecisionFormat(this.context.FRAGMENT_SHADER, this.context.HIGH_FLOAT);\n\tthis.hasHighPrecision = highp.precision != 0;\n\tif(this.hasHighPrecision) this.highp = highp;\n\n\t// create pass through vertex shader\n\tvar passThrough = \"#define GLSLIFY 1\\n// vertex shader for a single quad\\n// work is performed in the operation specific texture shader\\n\\nprecision highp float;\\n\\nattribute vec3 pos;\\nattribute vec2 tex;\\nvarying vec2 outTex;\\nvoid main(void)\\n{\\n\\t// just pass the position and texture coords\\n\\tgl_Position = vec4(pos, 1.0);\\n\\toutTex = tex;\\n}\\n\";\n\tthis.vertexShader = this.context.createShader(this.context.VERTEX_SHADER);\n\tthis.context.shaderSource(this.vertexShader, passThrough);\n\tthis.context.compileShader(this.vertexShader);\n\n\tvar encode = \"#define GLSLIFY 1\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D A;\\t\\t// texture with data from padded A\\nuniform int N;\\t\\t// number of columns in output\\nuniform int pad;\\t\\t//\\n\\n// Render float to bytes according to IEEE 754 Floating Point\\nvec4 encode_float_1540259130(float val) {\\n\\n\\t// TODO: correctly handle denormal numbers\\n\\t// http://www.2ality.com/2012/04/number-encoding.html\\n\\tfloat a = abs(val); // encode absolute value + sign\\n\\tfloat exp = floor(log2(a)); // number of powers of 2\\n\\tfloat mant = pow(2.,log2(a)-exp) * pow(2.,23.); // multiply to fill 24 bits (implied leading 1)\\n\\tfloat mant1 = floor(mant / 256. / 256.); // first 8 bits of mantissa\\n\\tfloat mant2 = mod(floor(mant / 256.),256.); // second 8 bits\\n\\tfloat mant3 = mod(mant,256.); // third 8 bits\\n\\n\\thighp float sign = 128.-128.*(a/val);\\t\\t\\t// sign bit is 256 or 0\\n\\thighp float e = (sign+exp+127.)/510.;\\t\\t// exponent and sign\\n\\thighp float m1 = (mant1-(128.*(1.-mod(exp+127.,2.))))/255.; // handle leading bit\\n\\thighp float m2 = (mant2)/255.;\\t\\t\\t\\t// middle part\\n\\thighp float m3 = (mant3+.5)/255.;\\t\\t\\t// scale to 0 - 255\\n\\n\\treturn vec4(m3,m2,m1,e);\\n}\\n\\n// select an element from a vector based on index\\nfloat select_index_1604150559(vec4 v, int index){\\n\\tfloat val;\\n\\tif (index == 0) {\\n\\t\\tval = v.r;\\n\\t} else if(index == 1) {\\n\\t\\tval = v.g;\\n\\t} else if(index == 2) {\\n\\t\\tval = v.b;\\n\\t} else if(index == 3){\\n\\t\\tval = v.a;\\n\\t} else {\\n\\t\\t// should never be here\\n\\t\\tval = 0.0;\\n\\t}\\n\\n\\treturn val;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row_t = outTex.y;\\n\\tfloat col_t = outTex.x;\\n\\n\\tvec4 val_v = texture2D(A, vec2(col_t * float(N)/float(N + pad), row_t));\\n\\tint channel = int(mod(col_t * float(N), 4.0 ));\\n\\tfloat val = select_index_1604150559(val_v, channel);\\n\\n\\tif (val == 0.) {\\n\\t\\tgl_FragColor = vec4(0.,0.,0.,0.);\\n\\t\\treturn;\\n\\t}\\n\\n \\t// output vec4 with bytes for an IEEE754 32-bit floating point number\\n\\tgl_FragColor = encode_float_1540259130(val);\\n}\\n\",\n\t\ttranspose = \"#define GLSLIFY 1\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D A;\\t\\t// texture with data from padded A\\nuniform int M;\\t\\t// number of rows in output\\nuniform int N;\\t\\t// number of columns in output\\nuniform int mpad;\\t\\t//\\nuniform int npad;\\t\\t//\\n\\n// select an element from a vector based on index\\nfloat select_index_1540259130(vec4 v, int index){\\n\\tfloat val;\\n\\tif (index == 0) {\\n\\t\\tval = v.r;\\n\\t} else if(index == 1) {\\n\\t\\tval = v.g;\\n\\t} else if(index == 2) {\\n\\t\\tval = v.b;\\n\\t} else if(index == 3){\\n\\t\\tval = v.a;\\n\\t} else {\\n\\t\\t// should never be here\\n\\t\\tval = 0.0;\\n\\t}\\n\\n\\treturn val;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row_t = outTex.y;\\n\\tfloat col_t = outTex.x;\\n\\tfloat col = (col_t * float(N + npad) - 2.0); // index of first element in pixel (matrix space)\\n\\n\\t// get rows in the input, each containing one element in the output\\n\\tvec4 row_1 = texture2D(A, vec2((row_t * float(M))/float(M + mpad), (col + 0.5)/float(N)));\\n\\tvec4 row_2 = texture2D(A, vec2((row_t * float(M))/float(M + mpad), (col + 1.5)/float(N)));\\n\\tvec4 row_3 = texture2D(A, vec2((row_t * float(M))/float(M + mpad), (col + 2.5)/float(N)));\\n\\tvec4 row_4 = texture2D(A, vec2((row_t * float(M))/float(M + mpad), (col + 3.5)/float(N)));\\n\\n\\t// package into output vector\\n\\tint channel = int(mod(row_t * float(M), 4.0 ));\\n\\n\\tvec4 col_v = vec4(0.0, 0.0, 0.0, 0.0); // vec4 representing four elements in a column in the input\\n\\n\\t// extract relevent element from each input row\\n\\tcol_v.r = select_index_1540259130(row_1, channel);\\n\\tif(npad > 0 && (col + 4.0) > float(N) ) {\\n\\t\\t// compute elements in padded region\\n\\t\\tif(npad < 3){\\n\\t\\t\\tcol_v.g = select_index_1540259130(row_2, channel);\\n\\t\\t}\\n\\t\\tif(npad < 2){\\n\\t\\t\\tcol_v.b = select_index_1540259130(row_3, channel);\\n\\t\\t}\\n\\t} else {\\n\\t\\tcol_v.g = select_index_1540259130(row_2, channel);\\n\\t\\tcol_v.b = select_index_1540259130(row_3, channel);\\n\\t\\tcol_v.a = select_index_1540259130(row_4, channel);\\n\\t}\\n\\n\\tgl_FragColor = col_v;\\n}\\n\",\n\t\treshape = \"#define GLSLIFY 1\\nprecision highp float;\\n\\nvarying vec2 outTex;\\t// texture coords of row/column to calculate\\nuniform sampler2D A;\\t\\t// texture with data from padded A\\nuniform float M;\\t\\t// number of rows in output\\nuniform float N;\\t\\t// number of columns in output\\nuniform float pad;\\t\\t// column padding in output\\nuniform float M_in;\\t\\t// number of rows in input\\nuniform float N_in;\\t\\t// number of columns in input\\nuniform float pad_in;\\t// column padding in input\\n\\n/* number of input pixels\\n origin index (channel) for each\\n termination index (channel) for each\\n destination origin index (channel) for each\\n */\\n// select an element from a vector based on index\\nfloat select_index_1604150559(vec4 v, int index){\\n\\tfloat val;\\n\\tif (index == 0) {\\n\\t\\tval = v.r;\\n\\t} else if(index == 1) {\\n\\t\\tval = v.g;\\n\\t} else if(index == 2) {\\n\\t\\tval = v.b;\\n\\t} else if(index == 3){\\n\\t\\tval = v.a;\\n\\t} else {\\n\\t\\t// should never be here\\n\\t\\tval = 0.0;\\n\\t}\\n\\n\\treturn val;\\n}\\n\\n// set pad values to 0.0, if in padded region of output texture\\nvoid fix_pad_1540259130(inout vec4 v, int pad){\\n\\tv.a = 0.0;\\n\\tif(pad == 2){\\n\\t\\tv.b = 0.0;\\n\\t} else if(pad == 3){\\n\\t\\tv.b = 0.0;\\n\\t\\tv.g = 0.0;\\n\\t}\\n}\\n\\n// translate a linear index into x, y coordinates for a matrix\\nvec2 linear_index_coords(float linear_index, float row_length){\\n\\tvec2 coords;\\n\\n\\tcoords.x = floor(mod(linear_index + 0.5, row_length)); // column\\n\\tcoords.y = floor((linear_index + 0.5) / row_length); // row\\n\\n\\treturn coords;\\n}\\n\\nvoid main(void) {\\n\\n\\t// get the implied row and column from .y and .x of passed (output)\\n\\t// texture coordinate. These map directly to input texture space when\\n\\t// the relevant dimensions are the same.\\n\\tfloat row_t = outTex.y;\\n\\tfloat col_t = outTex.x;\\n\\n\\tfloat row = floor(row_t * M);\\n\\tfloat col_0 = (col_t * (N + pad) - 2.0); // index of first element in pixel (matrix space)\\n\\t//float col_0 = floor(col_t * (N + pad)/4.0)*4.0; // index of first element in pixel (matrix space)\\n\\tfloat lin_index_0 = row * N + col_0; // linearized index of first element in pixel in output\\n\\n\\tvec4 pixel_in = vec4(0.0, 0.0, 0.0, 0.0);\\n\\tvec4 result = vec4(0.0, 0.0, 0.0, 0.0);\\n\\tvec2 coords = linear_index_coords(lin_index_0, N_in);\\n\\tvec2 ncoords;\\n\\tint current_pixel_index = int(mod(coords.x, 4.0));\\n\\n\\tpixel_in = texture2D(A, vec2((coords.x + 0.5)/(N_in + pad_in), (coords.y + 0.5)/M_in));\\n\\n\\t// go through channels for current output pixel\\n\\tfor(int i = 0; i < 4; i++){\\n\\n\\t\\t// are we on a new input pixel?\\n\\t\\tncoords = linear_index_coords(lin_index_0 + float(i), N_in);\\n\\t\\tif(floor(coords.x/4.0) != floor(ncoords.x/4.0) || coords.y != ncoords.y){\\n\\t\\t\\tcoords = ncoords;\\n\\t\\t\\tpixel_in = texture2D(A, vec2((coords.x + 0.5)/(N_in + pad_in), (coords.y + 0.5)/M_in));\\n\\t\\t\\tcurrent_pixel_index = 0;\\n\\t\\t}\\n\\n\\t\\tif(i == 0){\\n\\t\\t\\tresult.r = select_index_1604150559(pixel_in, current_pixel_index);\\n\\t\\t} else if(i == 1){\\n\\t\\t\\tresult.g = select_index_1604150559(pixel_in, current_pixel_index);\\n\\t\\t} else if(i == 2){\\n\\t\\t\\tresult.b = select_index_1604150559(pixel_in, current_pixel_index);\\n\\t\\t} else {\\n\\t\\t\\tresult.a = select_index_1604150559(pixel_in, current_pixel_index);\\n\\t\\t}\\n\\n\\t\\tcurrent_pixel_index++;\\n\\t}\\n\\n\\t// are we in the padded (output) region?\\n\\tif(pad > 0.0 && col_0 + 3.5 > N ) {\\n\\t\\tfix_pad_1540259130(result, int(pad));\\n\\t}\\n\\n\\tgl_FragColor = result;\\n}\\n\";\n\n\tthis.encode_program = this.createProgram(encode);\n\tthis.transpose_program = this.createProgram(transpose);\n\tthis.reshape_program = this.createProgram(reshape);\n};\n\nmodule.exports = WebGL;\n\n// RGBA is the standard input/ouput texture\nWebGL.COMPONENTS_PER_TEXEL = 4;\n\nWebGL.POSITION_UNIFORM_NAME = \"pos\";\nWebGL.TEXTURE_UNIFORM_NAME = \"tex\";\n\n\nWebGL.prototype.encode = function(M, N, texture0, out){\n\n\tthis.program = this.encode_program;\n\tthis.selectProgram(this.program);\n\n\tvar pad = this.getPad(N);\n\n\tvar N_gl = this.context.getUniformLocation(this.program, \"N\"),\n\t\tpad_gl = this.context.getUniformLocation(this.program, \"pad\");\n\n\tthis.context.uniform1i(N_gl, N);\n\tthis.context.uniform1i(pad_gl, pad);\n\n\tthis.bindInputTexture(texture0, this.context.TEXTURE0, \"A\");\n\n\tthis.bindOutputTexture(M, N, out);\n\n\tthis.context.drawElements(this.context.TRIANGLES, /*num items*/6, this.context.UNSIGNED_SHORT, 0);\n\n\tthis.unbindInputTexture(this.context.TEXTURE0);\n}\n\n/* tranpose a texture where input has M rows and N columns\n */\nWebGL.prototype.transpose = function(M, N, texture0, out){\n\n\tthis.program = this.transpose_program;\n\tthis.selectProgram(this.program);\n\n\tvar npad = this.getPad(N),\n\t\tmpad = this.getPad(M);\n\n\t// in the shader M and N describe rows and columns in the *output*, respectively\n\tvar N_gl = this.context.getUniformLocation(this.program, \"N\"),\n\t\tnpad_gl = this.context.getUniformLocation(this.program, \"npad\"),\n\t\tM_gl = this.context.getUniformLocation(this.program, \"M\"),\n\t\tmpad_gl = this.context.getUniformLocation(this.program, \"mpad\");\n\n\tthis.context.uniform1i(N_gl, M);\n\tthis.context.uniform1i(npad_gl, mpad);\n\tthis.context.uniform1i(M_gl, N);\n\tthis.context.uniform1i(mpad_gl, npad);\n\n\tthis.bindInputTexture(texture0, this.context.TEXTURE0, \"A\");\n\n\tthis.bindOutputTexture(N, (M + mpad)/4, out);\n\n\tthis.context.drawElements(this.context.TRIANGLES, /*num items*/6, this.context.UNSIGNED_SHORT, 0);\n\n\tthis.unbindInputTexture(this.context.TEXTURE0);\n};\n\n/* tranpose a texture where input has M rows and N columns\n */\nWebGL.prototype.reshape = function(M, N, M_out, N_out, texture0, out){\n\n\tthis.program = this.reshape_program;\n\tthis.selectProgram(this.program);\n\n\tvar pad = this.getPad(N),\n\t\tpad_out = this.getPad(N_out);\n\n\t// in the shader M and N describe rows and columns in the *output*, respectively\n\tvar M_gl = this.context.getUniformLocation(this.program, \"M\"),\n\t\tN_gl = this.context.getUniformLocation(this.program, \"N\"),\n\t\tpad_gl = this.context.getUniformLocation(this.program, \"pad\"),\n\t\tM_in_gl = this.context.getUniformLocation(this.program, \"M_in\"),\n\t\tN_in_gl = this.context.getUniformLocation(this.program, \"N_in\"),\n\t\tpad_in_gl = this.context.getUniformLocation(this.program, \"pad_in\");\n\n\tthis.context.uniform1f(M_gl, M_out);\n\tthis.context.uniform1f(N_gl, N_out);\n\tthis.context.uniform1f(pad_gl, pad_out);\n\tthis.context.uniform1f(M_in_gl, M);\n\tthis.context.uniform1f(N_in_gl, N);\n\tthis.context.uniform1f(pad_in_gl, pad);\n\n\tthis.bindInputTexture(texture0, this.context.TEXTURE0, \"A\");\n\n\tthis.bindOutputTexture(M_out, (N_out + pad_out)/4, out);\n\n\tthis.context.drawElements(this.context.TRIANGLES, /*num items*/6, this.context.UNSIGNED_SHORT, 0);\n\n\tthis.unbindInputTexture(this.context.TEXTURE0);\n};\n\nWebGL.prototype.bindInputTexture = function(texture, textureUnit, name){\n\tvar gl = this.context,\n\t\tprogram = this.program;\n\n\tgl.activeTexture(textureUnit); // gl.TEXTURE0, gl.TEXTURE1, etc\n\tgl.bindTexture(\t gl.TEXTURE_2D, texture);\n\n\tvar sampler = gl.getUniformLocation(program, name);\n\tgl.uniform1i(sampler, textureUnit - gl.TEXTURE0);\n\n};\n\n/* Create a shader program based on a pass through vertex shader and\n\tthe supplied operation specific fragment shader.\n\n\tfragmentShaderSource - string containing the fragment shader source code.\n\tshader will recieve `vec2 outTex` with texture coordinates from the pass\n\tthrough vertex shader.\n */\nWebGL.prototype.createProgram = function(fragmentShaderSource){\n\tvar gl = this.context,\n\t\tfragmentShader;\n\n\t// compile the provided fragment/texture shader\n\tfragmentShader = gl.createShader(gl.FRAGMENT_SHADER);\n\tgl.shaderSource(fragmentShader, fragmentShaderSource);\n\tgl.compileShader(fragmentShader);\n\n\t// did it compile correctly?\n\tif (gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS) == 0)\n\t\tthrow new Error(gl.getShaderInfoLog(fragmentShader));\n\n\t// link the program specific fragment shader and the generic pass through\n\t// shader into a program\n\tvar program = gl.createProgram();\n\tgl.attachShader(program, this.vertexShader);\n\tgl.attachShader(program, fragmentShader);\n\tgl.linkProgram(program);\n\n\treturn program;\n};\n\nWebGL.prototype.selectProgram = function(program){\n\n\tvar gl = this.context;\n\n\t// set calculator program to current shader program\n\tgl.useProgram(program);\n\n\tthis.bindVertices(program);\n};\n\n/* setup required to draw a square to our vertex shader and have\n fragment shader called for each pixel\n */\nWebGL.prototype.bindVertices = function(program) {\n\tvar gl = this.context,\n\t\trenderer = program;\n\n\t// bind vertices\n\tvar position = gl.getAttribLocation(renderer, WebGL.POSITION_UNIFORM_NAME);\n\tvar vertexBuffer = gl.createBuffer();\n\tgl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);\n\n\t// define a square that covers the screen\n\tvar vertices = [-1.0, -1.0, 0.0,\t// bottom left\n\t\t\t\t\t 1.0, -1.0, 0.0,\t// bottom right\n\t\t\t\t\t 1.0, 1.0, 0.0,\t// top right\n\t\t\t\t\t-1.0, 1.0, 0.0];\t// top left\n\tgl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);\n\tgl.vertexAttribPointer(position, /*item size*/3, gl.FLOAT, false, 0, 0);\n\tgl.enableVertexAttribArray(position);\n\n\t// bind texture cords\n\tvar texture = gl.getAttribLocation(renderer, WebGL.TEXTURE_UNIFORM_NAME);\n\tvar texCoords = gl.createBuffer();\n\tgl.bindBuffer(gl.ARRAY_BUFFER, texCoords);\n\tvar textureCoords = [0.0, 0.0,\n\t\t\t\t\t\t 1.0, 0.0,\n\t\t\t\t\t\t 1.0, 1.0,\n\t\t\t\t\t\t 0.0, 1.0];\n\tgl.bufferData(gl.ARRAY_BUFFER, new Float32Array(textureCoords), gl.STATIC_DRAW);\n\tgl.vertexAttribPointer(texture, /*item size*/2, gl.FLOAT, false, 0, 0);\n\tgl.enableVertexAttribArray(texture);\n\n\t// index to vertices\n\tvar indices = gl.createBuffer();\n\tgl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indices);\n\t// tesselate square into triangles\n\t// indeces into vertex array creating triangles, with counter-clockwise winding\n\tvar vertexIndices = [0, 1, 2,\t// bottom right triangle\n\t\t\t\t\t\t 0, 2, 3];\t// top left triangle\n\tgl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(vertexIndices), gl.STATIC_DRAW);\n};\n\n/* create RGBA texture of width w/4 from given texels\n padding the width of each row to a multiple of 4, where necessary.\n\n if texels is null, an empty texture is created.\n\n alternative to textures?\n http://stackoverflow.com/questions/17203508/webgl-hardware-skinning-with-a-bone-texture\n */\nWebGL.prototype.createDataTexture = function(h, w, texels){\n\n\tvar gl = this.context;\n\n\tvar PAD_TEMPLATE = [0.0, 0.0, 0.0, 0.0]; // value to pad remainder with\n\n\tvar rem = (w % WebGL.COMPONENTS_PER_TEXEL),\n\t\tpad = rem == 0 ? 0 : WebGL.COMPONENTS_PER_TEXEL - rem;\n\n\t// create the texture from our floats\n\tvar texture = gl.createTexture();\n\n\tgl.bindTexture(\t gl.TEXTURE_2D, texture);\n\t/*\n\t// https://www.opengl.org/wiki/GLAPI/glPixelStore\n gl.pixelStorei(gl.UNPACK_ROW_LENGTH, w/4);\n gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);\n\n\tsee also: https://www.opengl.org/wiki/Common_Mistakes#Creating_a_complete_texture\n\t*/\n\tif(pad == 0 || texels == null || typeof texels === 'undefined'){\n\t\t// no padding required, write directly from input array\n\t\tgl.texImage2D(\t gl.TEXTURE_2D, 0, gl.RGBA, (w + pad) / WebGL.COMPONENTS_PER_TEXEL, h, 0,\n\t\t\t\t\t\t gl.RGBA, gl.FLOAT, texels);\n\n\t} else {\n\t\t// must pad each row\n\n\t\t// create empty texture\n\t\tgl.texImage2D(\t gl.TEXTURE_2D, 0, gl.RGBA, (w + pad) / WebGL.COMPONENTS_PER_TEXEL, h, 0,\n\t\t\t\t\t\t gl.RGBA, gl.FLOAT, null);\n\n\t\tvar full_texel_row_len = w - rem,\n\t\t\tfull_row_texture_width = full_texel_row_len / WebGL.COMPONENTS_PER_TEXEL;\n\n\t\tvar row_start = 0;\n\t\tvar last_texel = new Float32Array(PAD_TEMPLATE);\n\t\tvar row, remainder;\n\n\t\t// set texture data, one row at a time, padding each row to a multiple\n\t\t// of the texel length\n\t\tfor(var i = 0; i < h; i++){\n\t\t\trow_start = i * w;\n\t\t\tfull_texel_row_end = row_start + full_texel_row_len;\n\t\t\trow = new Float32Array(texels.buffer, row_start * texels.BYTES_PER_ELEMENT, full_texel_row_len);\n\t\t\tif(full_texel_row_len > 0){\n\t\t\t\t// https://www.khronos.org/registry/webgl/specs/latest/1.0/index.html#TEXSUBIMAGE2D\n\t\t\t\tgl.texSubImage2D(gl.TEXTURE_2D,\n\t\t\t\t\t 0,\t\t\t\t\t// mip-map level\n\t\t\t\t\t 0,\t\t\t\t\t// x-offset\n\t\t\t\t\t i,\t\t\t\t\t// y-offset\n\t\t\t\t\t full_row_texture_width,\t// width\n\t\t\t\t\t 1,\t\t\t\t\t// height\n\t\t\t\t\t gl.RGBA,\t\t\t// format\n\t\t\t\t\t gl.FLOAT,\t\t\t// type\n\t\t\t\t\t row\t\t\t// data\n\t\t\t\t );\n\t\t\t}\n\n\t\t\tremainder = new Float32Array(texels.buffer, full_texel_row_end * texels.BYTES_PER_ELEMENT, rem);\n\t\t\tlast_texel.set(remainder); // copy remaining data\n\n\t\t\tgl.texSubImage2D(gl.TEXTURE_2D,\n\t\t\t\t 0,\t\t\t\t// mip-map level\n\t\t\t\t full_row_texture_width, // x-offset\n\t\t\t\t i,\t\t\t\t// y-offset\n\t\t\t\t 1,\t\t\t\t// width\n\t\t\t\t 1,\t\t\t\t// height\n\t\t\t\t gl.RGBA,\t\t// format\n\t\t\t\t gl.FLOAT,\t\t// type\n\t\t\t\t last_texel\t\t// data\n\t\t\t );\n\t\t}\n\t}\n\n\t// clamp to edge to support non-power of two textures\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\n\t// don't interpolate when getting data from texture\n\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n\n\t// we're done with setup, so unbind current texture\n\tgl.bindTexture(gl.TEXTURE_2D, null);\n\n\treturn texture;\n};\n\n/* Create a (padded) texture suitable for reading into an array with readPixels.\n\tUNSIGNED_BYTE\n Can be passed to bindDestinationTexture.\n\n Returns an unsigned byte RGBA texture (other formats are not yet supported\n\ton most platforms, see WEBGL_color_buffer_float extension)\n */\nWebGL.prototype.createOutputTexture = function(h, w) {\n\tvar gl = this.context;\n\n\tvar pad = this.getPad(w);\n\n\t// create and bind texture to render to\n\tvar destTexture = gl.createTexture();\n\t//gl.activeTexture(gl.TEXTURE2);\n\tgl.bindTexture(gl.TEXTURE_2D, destTexture);\n\tgl.texImage2D(gl.TEXTURE_2D,/*level*/0, gl.RGBA, w + pad, h, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);\n\n\t// clamp to edge to support non-power of two textures\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);\n\tgl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);\n\t// don't interpolate when getting data from texture\n\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n\tgl.texParameteri( gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n\n\t// we're done with setup, so unbind current texture\n\tgl.bindTexture(gl.TEXTURE_2D, null);\n\n\treturn destTexture;\n};\n\n/* Set up output\n\n\tM - number of rows in output\n\tN - number of columns in output\n\tdstTex - texture for holding the output\n */\nWebGL.prototype.bindOutputTexture = function(M, N, texture) {\n\tvar gl = this.context;\n\n\t// set canvas and viewport size\n\tthis.canvas.height = M;\n\tthis.canvas.width = N;\n\tgl.viewport(0, 0, N, M);\n\n\t// create and bind framebuffer\n\tthis.framebuffer = this.framebuffer || gl.createFramebuffer();\n\n\tgl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer);\n\n\tgl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, /*level*/0);\n\n\n\tif( gl.checkFramebufferStatus(gl.FRAMEBUFFER) != gl.FRAMEBUFFER_COMPLETE)\n\t\tthrow new Error(\"Bound framebuffer is not complete.\");\n\n\treturn this.framebuffer;\n};\n\nWebGL.prototype.unbindInputTexture = function(textureUnit){\n\tvar gl = this.context;\n\n\tgl.activeTexture(textureUnit);\n\tgl.bindTexture(gl.TEXTURE_2D, null);\n};\n\n/* Read data out as unsigned bytes */\nWebGL.prototype.readData = function(M, N){\n\tvar gl = this.context;\n\n\t// create destination buffer\n\trawbuffer = new ArrayBuffer(M*N*Float32Array.BYTES_PER_ELEMENT);\n\n\t// read the result into our buffer, as bytes\n\tprod = new Uint8Array(rawbuffer);\n\tgl.readPixels(0, 0, N, M, gl.RGBA, gl.UNSIGNED_BYTE, prod);\n\n\t// return raw result bytes\n\treturn rawbuffer; // M x N\n};\n\n// how many extra elements do we need to fill up a pixel?\nWebGL.prototype.getPad = function(N){\n\n\tvar rem = (N % WebGL.COMPONENTS_PER_TEXEL),\n\t\tpad = rem == 0 ? 0 : WebGL.COMPONENTS_PER_TEXEL - rem;\n\n\treturn pad;\n};\n","// shim for using process in browser\n\nvar process = module.exports = {};\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = setTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n clearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n setTimeout(drainQueue, 0);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n"]}