From 7971c8e6d5edff32660d56bfaaf7ee7fc006f08f Mon Sep 17 00:00:00 2001 From: Saksham Goyal Date: Thu, 15 Aug 2024 01:48:42 -0400 Subject: [PATCH 1/5] update types --- .github/workflows/ci.yml | 4 +- build.js | 2 +- gif.js.map | 1 - gif.worker.js.map | 1 - js/eval.js | 55 +- js/filters.js | 436 ++++++------- js/grecha.js | 77 ++- js/index.js | 126 ++-- package-lock.json | 1311 +++++++++++++++++++++++++++++++++++++- package.json | 7 +- serviceworker.js | 35 +- ts/eval.ts | 56 +- ts/filters.ts | 426 ++++++------- ts/grecha.ts | 103 ++- ts/index.ts | 221 +++---- tsconfig.json | 108 ++++ 16 files changed, 2150 insertions(+), 819 deletions(-) delete mode 100644 gif.js.map delete mode 100644 gif.worker.js.map create mode 100644 tsconfig.json diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be7b194..d01d0ea 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -2,13 +2,13 @@ name: CI on: [push, pull_request] jobs: - node-20-typescript: + node-22-typescript: runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: - node-version: '20' + node-version: '22' - run: npm install - run: npm run build - run: git diff --exit-code diff --git a/build.js b/build.js index 716ff5c..c14fdf9 100644 --- a/build.js +++ b/build.js @@ -2,7 +2,7 @@ import { spawn } from 'child_process'; function cmd(program, args) { console.log('CMD:', program, args); - const p = spawn(program, args.flat()); // NOTE: flattening the args array enables you to group related arguments for better self-documentation of the running command + const p = spawn(program, args.flat(), {shell: process.platform == 'win32'}); // NOTE: flattening the args array enables you to group related arguments for better self-documentation of the running command p.stdout.on('data', (data) => process.stdout.write(data)); p.stderr.on('data', (data) => process.stderr.write(data)); p.on('close', (code) => { diff --git a/gif.js.map b/gif.js.map deleted file mode 100644 index e146d8c..0000000 --- a/gif.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","node_modules/events/events.js","src/browser.coffee","src/gif.coffee"],"names":["f","exports","module","define","amd","g","window","global","self","this","GIF","r","e","n","t","o","i","c","require","u","a","Error","code","p","call","length","1","EventEmitter","_events","_maxListeners","undefined","prototype","defaultMaxListeners","setMaxListeners","isNumber","isNaN","TypeError","emit","type","er","handler","len","args","listeners","error","isObject","arguments","err","context","isUndefined","isFunction","Array","slice","apply","addListener","listener","m","newListener","push","warned","console","trace","on","once","fired","removeListener","list","position","splice","removeAllListeners","key","ret","listenerCount","evlistener","emitter","arg","UA","browser","mode","platform","ua","navigator","userAgent","toLowerCase","match","document","documentMode","name","version","parseFloat","parseInt","extend","child","parent","hasProp","ctor","constructor","__super__","superClass","defaults","frameDefaults","workerScript","workers","repeat","background","quality","width","height","transparent","debug","dither","delay","copy","dispose","options","base","value","running","frames","freeWorkers","activeWorkers","setOptions","setOption","_canvas","results","addFrame","image","frame","ImageData","data","CanvasRenderingContext2D","WebGLRenderingContext","getContextData","childNodes","getImageData","render","j","numWorkers","ref","nextFrame","finishedFrames","imageParts","spawnWorkers","globalPalette","renderNextFrame","abort","worker","shift","log","terminate","Math","min","forEach","_this","Worker","onmessage","event","indexOf","frameFinished","index","finishRendering","k","l","len1","len2","len3","offset","page","ref1","ref2","pageSize","cursor","round","Uint8Array","set","Blob","task","getTask","postMessage","ctx","createElement","getContext","fillStyle","fillRect","drawImage","last","canTransfer"],"mappings":"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","sourceRoot":"","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i 0 && this._events[type].length > m) {\n this._events[type].warned = true;\n console.error('(node) warning: possible EventEmitter memory ' +\n 'leak detected. %d listeners added. ' +\n 'Use emitter.setMaxListeners() to increase limit.',\n this._events[type].length);\n if (typeof console.trace === 'function') {\n // not supported in IE 10\n console.trace();\n }\n }\n }\n\n return this;\n};\n\nEventEmitter.prototype.on = EventEmitter.prototype.addListener;\n\nEventEmitter.prototype.once = function(type, listener) {\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n var fired = false;\n\n function g() {\n this.removeListener(type, g);\n\n if (!fired) {\n fired = true;\n listener.apply(this, arguments);\n }\n }\n\n g.listener = listener;\n this.on(type, g);\n\n return this;\n};\n\n// emits a 'removeListener' event iff the listener was removed\nEventEmitter.prototype.removeListener = function(type, listener) {\n var list, position, length, i;\n\n if (!isFunction(listener))\n throw TypeError('listener must be a function');\n\n if (!this._events || !this._events[type])\n return this;\n\n list = this._events[type];\n length = list.length;\n position = -1;\n\n if (list === listener ||\n (isFunction(list.listener) && list.listener === listener)) {\n delete this._events[type];\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n\n } else if (isObject(list)) {\n for (i = length; i-- > 0;) {\n if (list[i] === listener ||\n (list[i].listener && list[i].listener === listener)) {\n position = i;\n break;\n }\n }\n\n if (position < 0)\n return this;\n\n if (list.length === 1) {\n list.length = 0;\n delete this._events[type];\n } else {\n list.splice(position, 1);\n }\n\n if (this._events.removeListener)\n this.emit('removeListener', type, listener);\n }\n\n return this;\n};\n\nEventEmitter.prototype.removeAllListeners = function(type) {\n var key, listeners;\n\n if (!this._events)\n return this;\n\n // not listening for removeListener, no need to emit\n if (!this._events.removeListener) {\n if (arguments.length === 0)\n this._events = {};\n else if (this._events[type])\n delete this._events[type];\n return this;\n }\n\n // emit removeListener for all listeners on all events\n if (arguments.length === 0) {\n for (key in this._events) {\n if (key === 'removeListener') continue;\n this.removeAllListeners(key);\n }\n this.removeAllListeners('removeListener');\n this._events = {};\n return this;\n }\n\n listeners = this._events[type];\n\n if (isFunction(listeners)) {\n this.removeListener(type, listeners);\n } else if (listeners) {\n // LIFO order\n while (listeners.length)\n this.removeListener(type, listeners[listeners.length - 1]);\n }\n delete this._events[type];\n\n return this;\n};\n\nEventEmitter.prototype.listeners = function(type) {\n var ret;\n if (!this._events || !this._events[type])\n ret = [];\n else if (isFunction(this._events[type]))\n ret = [this._events[type]];\n else\n ret = this._events[type].slice();\n return ret;\n};\n\nEventEmitter.prototype.listenerCount = function(type) {\n if (this._events) {\n var evlistener = this._events[type];\n\n if (isFunction(evlistener))\n return 1;\n else if (evlistener)\n return evlistener.length;\n }\n return 0;\n};\n\nEventEmitter.listenerCount = function(emitter, type) {\n return emitter.listenerCount(type);\n};\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\n","### CoffeeScript version of the browser detection from MooTools ###\n\nua = navigator.userAgent.toLowerCase()\nplatform = navigator.platform.toLowerCase()\nUA = ua.match(/(opera|ie|firefox|chrome|version)[\\s\\/:]([\\w\\d\\.]+)?.*?(safari|version[\\s\\/:]([\\w\\d\\.]+)|$)/) or [null, 'unknown', 0]\nmode = UA[1] == 'ie' && document.documentMode\n\nbrowser =\n name: if UA[1] is 'version' then UA[3] else UA[1]\n version: mode or parseFloat(if UA[1] is 'opera' && UA[4] then UA[4] else UA[2])\n\n platform:\n name: if ua.match(/ip(?:ad|od|hone)/) then 'ios' else (ua.match(/(?:webos|android)/) or platform.match(/mac|win|linux/) or ['other'])[0]\n\nbrowser[browser.name] = true\nbrowser[browser.name + parseInt(browser.version, 10)] = true\nbrowser.platform[browser.platform.name] = true\n\nmodule.exports = browser\n","{EventEmitter} = require 'events'\nbrowser = require './browser.coffee'\n\nclass GIF extends EventEmitter\n\n defaults =\n workerScript: 'gif.worker.js'\n workers: 2\n repeat: 0 # repeat forever, -1 = repeat once\n background: '#fff'\n quality: 10 # pixel sample interval, lower is better\n width: null # size derermined from first frame if possible\n height: null\n transparent: null\n debug: false\n dither: false # see GIFEncoder.js for dithering options\n\n frameDefaults =\n delay: 500 # ms\n copy: false\n dispose: -1\n\n constructor: (options) ->\n @running = false\n\n @options = {}\n @frames = []\n\n @freeWorkers = []\n @activeWorkers = []\n\n @setOptions options\n for key, value of defaults\n @options[key] ?= value\n\n setOption: (key, value) ->\n @options[key] = value\n if @_canvas? and key in ['width', 'height']\n @_canvas[key] = value\n\n setOptions: (options) ->\n @setOption key, value for own key, value of options\n\n addFrame: (image, options={}) ->\n frame = {}\n frame.transparent = @options.transparent\n for key of frameDefaults\n frame[key] = options[key] or frameDefaults[key]\n\n # use the images width and height for options unless already set\n @setOption 'width', image.width unless @options.width?\n @setOption 'height', image.height unless @options.height?\n\n if ImageData? and image instanceof ImageData\n frame.data = image.data\n else if (CanvasRenderingContext2D? and image instanceof CanvasRenderingContext2D) or (WebGLRenderingContext? and image instanceof WebGLRenderingContext)\n if options.copy\n frame.data = @getContextData image\n else\n frame.context = image\n else if image.childNodes?\n if options.copy\n frame.data = @getImageData image\n else\n frame.image = image\n else\n throw new Error 'Invalid image'\n\n @frames.push frame\n\n render: ->\n throw new Error 'Already running' if @running\n\n if not @options.width? or not @options.height?\n throw new Error 'Width and height must be set prior to rendering'\n\n @running = true\n @nextFrame = 0\n @finishedFrames = 0\n\n @imageParts = (null for i in [0...@frames.length])\n numWorkers = @spawnWorkers()\n # we need to wait for the palette\n if @options.globalPalette == true\n @renderNextFrame()\n else\n @renderNextFrame() for i in [0...numWorkers]\n\n @emit 'start'\n @emit 'progress', 0\n\n abort: ->\n loop\n worker = @activeWorkers.shift()\n break unless worker?\n @log 'killing active worker'\n worker.terminate()\n @running = false\n @emit 'abort'\n\n # private\n\n spawnWorkers: ->\n numWorkers = Math.min(@options.workers, @frames.length)\n [@freeWorkers.length...numWorkers].forEach (i) =>\n @log \"spawning worker #{ i }\"\n worker = new Worker @options.workerScript\n worker.onmessage = (event) =>\n @activeWorkers.splice @activeWorkers.indexOf(worker), 1\n @freeWorkers.push worker\n @frameFinished event.data\n @freeWorkers.push worker\n return numWorkers\n\n frameFinished: (frame) ->\n @log \"frame #{ frame.index } finished - #{ @activeWorkers.length } active\"\n @finishedFrames++\n @emit 'progress', @finishedFrames / @frames.length\n @imageParts[frame.index] = frame\n # remember calculated palette, spawn the rest of the workers\n if @options.globalPalette == true\n @options.globalPalette = frame.globalPalette\n @log 'global palette analyzed'\n @renderNextFrame() for i in [1...@freeWorkers.length] if @frames.length > 2\n if null in @imageParts\n @renderNextFrame()\n else\n @finishRendering()\n\n finishRendering: ->\n len = 0\n for frame in @imageParts\n len += (frame.data.length - 1) * frame.pageSize + frame.cursor\n len += frame.pageSize - frame.cursor\n @log \"rendering finished - filesize #{ Math.round(len / 1000) }kb\"\n data = new Uint8Array len\n offset = 0\n for frame in @imageParts\n for page, i in frame.data\n data.set page, offset\n if i is frame.data.length - 1\n offset += frame.cursor\n else\n offset += frame.pageSize\n\n image = new Blob [data],\n type: 'image/gif'\n\n @emit 'finished', image, data\n\n renderNextFrame: ->\n throw new Error 'No free workers' if @freeWorkers.length is 0\n return if @nextFrame >= @frames.length # no new frame to render\n\n frame = @frames[@nextFrame++]\n worker = @freeWorkers.shift()\n task = @getTask frame\n\n @log \"starting frame #{ task.index + 1 } of #{ @frames.length }\"\n @activeWorkers.push worker\n worker.postMessage task#, [task.data.buffer]\n\n getContextData: (ctx) ->\n return ctx.getImageData(0, 0, @options.width, @options.height).data\n\n getImageData: (image) ->\n if not @_canvas?\n @_canvas = document.createElement 'canvas'\n @_canvas.width = @options.width\n @_canvas.height = @options.height\n\n ctx = @_canvas.getContext '2d'\n ctx.fillStyle = @options.background\n ctx.fillRect 0, 0, @options.width, @options.height\n ctx.drawImage image, 0, 0\n\n return @getContextData ctx\n\n getTask: (frame) ->\n index = @frames.indexOf frame\n task =\n index: index\n last: index is (@frames.length - 1)\n delay: frame.delay\n dispose: frame.dispose\n transparent: frame.transparent\n width: @options.width\n height: @options.height\n quality: @options.quality\n dither: @options.dither\n globalPalette: @options.globalPalette\n repeat: @options.repeat\n canTransfer: (browser.name is 'chrome')\n\n if frame.data?\n task.data = frame.data\n else if frame.context?\n task.data = @getContextData frame.context\n else if frame.image?\n task.data = @getImageData frame.image\n else\n throw new Error 'Invalid frame'\n\n return task\n\n log: (args...) ->\n return unless @options.debug\n console.log args...\n\n\nmodule.exports = GIF\n"]} \ No newline at end of file diff --git a/gif.worker.js.map b/gif.worker.js.map deleted file mode 100644 index 52b5c65..0000000 --- a/gif.worker.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["node_modules/browser-pack/_prelude.js","src/GIFEncoder.js","src/LZWEncoder.js","src/TypedNeuQuant.js","src/gif.worker.coffee"],"names":["r","e","n","t","o","i","f","c","require","u","a","Error","code","p","exports","call","length","1","module","NeuQuant","LZWEncoder","ByteArray","this","page","pages","newPage","pageSize","charMap","String","fromCharCode","prototype","Uint8Array","cursor","getData","rv","writeByte","val","writeUTFBytes","string","l","charCodeAt","writeBytes","array","offset","GIFEncoder","width","height","transparent","transIndex","repeat","delay","image","pixels","indexedPixels","colorDepth","colorTab","neuQuant","usedEntry","Array","palSize","dispose","firstFrame","sample","dither","globalPalette","out","setDelay","milliseconds","Math","round","setFrameRate","fps","setDispose","disposalCode","setRepeat","setTransparent","color","addFrame","imageData","slice","getImagePixels","analyzePixels","writeLSD","writePalette","writeNetscapeExt","writeGraphicCtrlExt","writeImageDesc","writePixels","finish","setQuality","quality","setDither","setGlobalPalette","palette","getGlobalPalette","writeHeader","buildColormap","getColormap","ditherPixels","replace","match","indexPixels","findClosest","imgq","nPix","k","j","index","findClosestRGB","kernel","serpentine","kernels","FalseFloydSteinberg","FloydSteinberg","Stucki","Atkinson","ds","data","direction","y","x","xend","idx","r1","g1","b1","r2","g2","b2","er","eg","eb","end","x1","y1","d","max","min","used","g","b","lookupRGB","minpos","dmin","len","dr","dg","db","w","h","srcPos","count","transp","disp","writeShort","pValue","enc","encode","stream","EOF","BITS","HSIZE","masks","initCodeSize","accum","htab","Int32Array","codetab","cur_accum","cur_bits","a_count","free_ent","maxcode","clear_flg","g_init_bits","ClearCode","EOFCode","char_out","outs","flush_char","cl_block","cl_hash","output","hsize","compress","init_bits","fcode","ent","hsize_reg","hshift","n_bits","MAXCODE","nextPixel","outer_loop","remaining","curPixel","pix","ncycles","netsize","maxnetpos","netbiasshift","intbiasshift","intbias","gammashift","gamma","betashift","beta","betagamma","initrad","radiusbiasshift","radiusbias","initradius","radiusdec","alphabiasshift","initalpha","alphadec","radbiasshift","radbias","alpharadbshift","alpharadbias","prime1","prime2","prime3","prime4","minpicturebytes","samplefac","network","netindex","bias","freq","radpower","init","v","Float64Array","unbiasnet","altersingle","alpha","alterneigh","radius","lo","abs","hi","m","contest","bestd","bestbiasd","bestpos","bestbiaspos","dist","biasdist","betafreq","inxbuild","q","smallpos","smallval","previouscol","startpos","inxsearch","best","learn","lengthcount","samplepixels","delta","rad","step","map","renderFrame","frame","encoder","transfer","last","constructor","canTransfer","ref","results","buffer","self","postMessage","onmessage","event"],"mappings":"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","sourceRoot":"","sourcesContent":["(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c=\"function\"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error(\"Cannot find module '\"+i+\"'\");throw a.code=\"MODULE_NOT_FOUND\",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u=\"function\"==typeof require&&require,i=0;i= ByteArray.pageSize) this.newPage();\n this.pages[this.page][this.cursor++] = val;\n};\n\nByteArray.prototype.writeUTFBytes = function(string) {\n for (var l = string.length, i = 0; i < l; i++)\n this.writeByte(string.charCodeAt(i));\n};\n\nByteArray.prototype.writeBytes = function(array, offset, length) {\n for (var l = length || array.length, i = offset || 0; i < l; i++)\n this.writeByte(array[i]);\n};\n\nfunction GIFEncoder(width, height) {\n // image size\n this.width = ~~width;\n this.height = ~~height;\n\n // transparent color if given\n this.transparent = null;\n\n // transparent index in color table\n this.transIndex = 0;\n\n // -1 = no repeat, 0 = forever. anything else is repeat count\n this.repeat = -1;\n\n // frame delay (hundredths)\n this.delay = 0;\n\n this.image = null; // current frame\n this.pixels = null; // BGR byte array from frame\n this.indexedPixels = null; // converted frame indexed to palette\n this.colorDepth = null; // number of bit planes\n this.colorTab = null; // RGB palette\n this.neuQuant = null; // NeuQuant instance that was used to generate this.colorTab.\n this.usedEntry = new Array(); // active palette entries\n this.palSize = 7; // color table size (bits-1)\n this.dispose = -1; // disposal code (-1 = use default)\n this.firstFrame = true;\n this.sample = 10; // default sample interval for quantizer\n this.dither = false; // default dithering\n this.globalPalette = false;\n\n this.out = new ByteArray();\n}\n\n/*\n Sets the delay time between each frame, or changes it for subsequent frames\n (applies to last frame added)\n*/\nGIFEncoder.prototype.setDelay = function(milliseconds) {\n this.delay = Math.round(milliseconds / 10);\n};\n\n/*\n Sets frame rate in frames per second.\n*/\nGIFEncoder.prototype.setFrameRate = function(fps) {\n this.delay = Math.round(100 / fps);\n};\n\n/*\n Sets the GIF frame disposal code for the last added frame and any\n subsequent frames.\n\n Default is 0 if no transparent color has been set, otherwise 2.\n*/\nGIFEncoder.prototype.setDispose = function(disposalCode) {\n if (disposalCode >= 0) this.dispose = disposalCode;\n};\n\n/*\n Sets the number of times the set of GIF frames should be played.\n\n -1 = play once\n 0 = repeat indefinitely\n\n Default is -1\n\n Must be invoked before the first image is added\n*/\n\nGIFEncoder.prototype.setRepeat = function(repeat) {\n this.repeat = repeat;\n};\n\n/*\n Sets the transparent color for the last added frame and any subsequent\n frames. Since all colors are subject to modification in the quantization\n process, the color in the final palette for each frame closest to the given\n color becomes the transparent color for that frame. May be set to null to\n indicate no transparent color.\n*/\nGIFEncoder.prototype.setTransparent = function(color) {\n this.transparent = color;\n};\n\n/*\n Adds next GIF frame. The frame is not written immediately, but is\n actually deferred until the next frame is received so that timing\n data can be inserted. Invoking finish() flushes all frames.\n*/\nGIFEncoder.prototype.addFrame = function(imageData) {\n this.image = imageData;\n\n this.colorTab = this.globalPalette && this.globalPalette.slice ? this.globalPalette : null;\n\n this.getImagePixels(); // convert to correct format if necessary\n this.analyzePixels(); // build color table & map pixels\n\n if (this.globalPalette === true) this.globalPalette = this.colorTab;\n\n if (this.firstFrame) {\n this.writeLSD(); // logical screen descriptior\n this.writePalette(); // global color table\n if (this.repeat >= 0) {\n // use NS app extension to indicate reps\n this.writeNetscapeExt();\n }\n }\n\n this.writeGraphicCtrlExt(); // write graphic control extension\n this.writeImageDesc(); // image descriptor\n if (!this.firstFrame && !this.globalPalette) this.writePalette(); // local color table\n this.writePixels(); // encode and write pixel data\n\n this.firstFrame = false;\n};\n\n/*\n Adds final trailer to the GIF stream, if you don't call the finish method\n the GIF stream will not be valid.\n*/\nGIFEncoder.prototype.finish = function() {\n this.out.writeByte(0x3b); // gif trailer\n};\n\n/*\n Sets quality of color quantization (conversion of images to the maximum 256\n colors allowed by the GIF specification). Lower values (minimum = 1)\n produce better colors, but slow processing significantly. 10 is the\n default, and produces good color mapping at reasonable speeds. Values\n greater than 20 do not yield significant improvements in speed.\n*/\nGIFEncoder.prototype.setQuality = function(quality) {\n if (quality < 1) quality = 1;\n this.sample = quality;\n};\n\n/*\n Sets dithering method. Available are:\n - FALSE no dithering\n - TRUE or FloydSteinberg\n - FalseFloydSteinberg\n - Stucki\n - Atkinson\n You can add '-serpentine' to use serpentine scanning\n*/\nGIFEncoder.prototype.setDither = function(dither) {\n if (dither === true) dither = 'FloydSteinberg';\n this.dither = dither;\n};\n\n/*\n Sets global palette for all frames.\n You can provide TRUE to create global palette from first picture.\n Or an array of r,g,b,r,g,b,...\n*/\nGIFEncoder.prototype.setGlobalPalette = function(palette) {\n this.globalPalette = palette;\n};\n\n/*\n Returns global palette used for all frames.\n If setGlobalPalette(true) was used, then this function will return\n calculated palette after the first frame is added.\n*/\nGIFEncoder.prototype.getGlobalPalette = function() {\n return (this.globalPalette && this.globalPalette.slice && this.globalPalette.slice(0)) || this.globalPalette;\n};\n\n/*\n Writes GIF file header\n*/\nGIFEncoder.prototype.writeHeader = function() {\n this.out.writeUTFBytes(\"GIF89a\");\n};\n\n/*\n Analyzes current frame colors and creates color map.\n*/\nGIFEncoder.prototype.analyzePixels = function() {\n if (!this.colorTab) {\n this.neuQuant = new NeuQuant(this.pixels, this.sample);\n this.neuQuant.buildColormap(); // create reduced palette\n this.colorTab = this.neuQuant.getColormap();\n }\n\n // map image pixels to new palette\n if (this.dither) {\n this.ditherPixels(this.dither.replace('-serpentine', ''), this.dither.match(/-serpentine/) !== null);\n } else {\n this.indexPixels();\n }\n\n this.pixels = null;\n this.colorDepth = 8;\n this.palSize = 7;\n\n // get closest match to transparent color if specified\n if (this.transparent !== null) {\n this.transIndex = this.findClosest(this.transparent, true);\n }\n};\n\n/*\n Index pixels, without dithering\n*/\nGIFEncoder.prototype.indexPixels = function(imgq) {\n var nPix = this.pixels.length / 3;\n this.indexedPixels = new Uint8Array(nPix);\n var k = 0;\n for (var j = 0; j < nPix; j++) {\n var index = this.findClosestRGB(\n this.pixels[k++] & 0xff,\n this.pixels[k++] & 0xff,\n this.pixels[k++] & 0xff\n );\n this.usedEntry[index] = true;\n this.indexedPixels[j] = index;\n }\n};\n\n/*\n Taken from http://jsbin.com/iXofIji/2/edit by PAEz\n*/\nGIFEncoder.prototype.ditherPixels = function(kernel, serpentine) {\n var kernels = {\n FalseFloydSteinberg: [\n [3 / 8, 1, 0],\n [3 / 8, 0, 1],\n [2 / 8, 1, 1]\n ],\n FloydSteinberg: [\n [7 / 16, 1, 0],\n [3 / 16, -1, 1],\n [5 / 16, 0, 1],\n [1 / 16, 1, 1]\n ],\n Stucki: [\n [8 / 42, 1, 0],\n [4 / 42, 2, 0],\n [2 / 42, -2, 1],\n [4 / 42, -1, 1],\n [8 / 42, 0, 1],\n [4 / 42, 1, 1],\n [2 / 42, 2, 1],\n [1 / 42, -2, 2],\n [2 / 42, -1, 2],\n [4 / 42, 0, 2],\n [2 / 42, 1, 2],\n [1 / 42, 2, 2]\n ],\n Atkinson: [\n [1 / 8, 1, 0],\n [1 / 8, 2, 0],\n [1 / 8, -1, 1],\n [1 / 8, 0, 1],\n [1 / 8, 1, 1],\n [1 / 8, 0, 2]\n ]\n };\n\n if (!kernel || !kernels[kernel]) {\n throw 'Unknown dithering kernel: ' + kernel;\n }\n\n var ds = kernels[kernel];\n var index = 0,\n height = this.height,\n width = this.width,\n data = this.pixels;\n var direction = serpentine ? -1 : 1;\n\n this.indexedPixels = new Uint8Array(this.pixels.length / 3);\n\n for (var y = 0; y < height; y++) {\n\n if (serpentine) direction = direction * -1;\n\n for (var x = (direction == 1 ? 0 : width - 1), xend = (direction == 1 ? width : 0); x !== xend; x += direction) {\n\n index = (y * width) + x;\n // Get original colour\n var idx = index * 3;\n var r1 = data[idx];\n var g1 = data[idx + 1];\n var b1 = data[idx + 2];\n\n // Get converted colour\n idx = this.findClosestRGB(r1, g1, b1);\n this.usedEntry[idx] = true;\n this.indexedPixels[index] = idx;\n idx *= 3;\n var r2 = this.colorTab[idx];\n var g2 = this.colorTab[idx + 1];\n var b2 = this.colorTab[idx + 2];\n\n var er = r1 - r2;\n var eg = g1 - g2;\n var eb = b1 - b2;\n\n for (var i = (direction == 1 ? 0: ds.length - 1), end = (direction == 1 ? ds.length : 0); i !== end; i += direction) {\n var x1 = ds[i][1]; // *direction; // Should this by timesd by direction?..to make the kernel go in the opposite direction....got no idea....\n var y1 = ds[i][2];\n if (x1 + x >= 0 && x1 + x < width && y1 + y >= 0 && y1 + y < height) {\n var d = ds[i][0];\n idx = index + x1 + (y1 * width);\n idx *= 3;\n\n data[idx] = Math.max(0, Math.min(255, data[idx] + er * d));\n data[idx + 1] = Math.max(0, Math.min(255, data[idx + 1] + eg * d));\n data[idx + 2] = Math.max(0, Math.min(255, data[idx + 2] + eb * d));\n }\n }\n }\n }\n};\n\n/*\n Returns index of palette color closest to c\n*/\nGIFEncoder.prototype.findClosest = function(c, used) {\n return this.findClosestRGB((c & 0xFF0000) >> 16, (c & 0x00FF00) >> 8, (c & 0x0000FF), used);\n};\n\nGIFEncoder.prototype.findClosestRGB = function(r, g, b, used) {\n if (this.colorTab === null) return -1;\n\n if (this.neuQuant && !used) {\n return this.neuQuant.lookupRGB(r, g, b);\n }\n\n var c = b | (g << 8) | (r << 16);\n\n var minpos = 0;\n var dmin = 256 * 256 * 256;\n var len = this.colorTab.length;\n\n for (var i = 0, index = 0; i < len; index++) {\n var dr = r - (this.colorTab[i++] & 0xff);\n var dg = g - (this.colorTab[i++] & 0xff);\n var db = b - (this.colorTab[i++] & 0xff);\n var d = dr * dr + dg * dg + db * db;\n if ((!used || this.usedEntry[index]) && (d < dmin)) {\n dmin = d;\n minpos = index;\n }\n }\n\n return minpos;\n};\n\n/*\n Extracts image pixels into byte array pixels\n (removes alphachannel from canvas imagedata)\n*/\nGIFEncoder.prototype.getImagePixels = function() {\n var w = this.width;\n var h = this.height;\n this.pixels = new Uint8Array(w * h * 3);\n\n var data = this.image;\n var srcPos = 0;\n var count = 0;\n\n for (var i = 0; i < h; i++) {\n for (var j = 0; j < w; j++) {\n this.pixels[count++] = data[srcPos++];\n this.pixels[count++] = data[srcPos++];\n this.pixels[count++] = data[srcPos++];\n srcPos++;\n }\n }\n};\n\n/*\n Writes Graphic Control Extension\n*/\nGIFEncoder.prototype.writeGraphicCtrlExt = function() {\n this.out.writeByte(0x21); // extension introducer\n this.out.writeByte(0xf9); // GCE label\n this.out.writeByte(4); // data block size\n\n var transp, disp;\n if (this.transparent === null) {\n transp = 0;\n disp = 0; // dispose = no action\n } else {\n transp = 1;\n disp = 2; // force clear if using transparent color\n }\n\n if (this.dispose >= 0) {\n disp = this.dispose & 7; // user override\n }\n disp <<= 2;\n\n // packed fields\n this.out.writeByte(\n 0 | // 1:3 reserved\n disp | // 4:6 disposal\n 0 | // 7 user input - 0 = none\n transp // 8 transparency flag\n );\n\n this.writeShort(this.delay); // delay x 1/100 sec\n this.out.writeByte(this.transIndex); // transparent color index\n this.out.writeByte(0); // block terminator\n};\n\n/*\n Writes Image Descriptor\n*/\nGIFEncoder.prototype.writeImageDesc = function() {\n this.out.writeByte(0x2c); // image separator\n this.writeShort(0); // image position x,y = 0,0\n this.writeShort(0);\n this.writeShort(this.width); // image size\n this.writeShort(this.height);\n\n // packed fields\n if (this.firstFrame || this.globalPalette) {\n // no LCT - GCT is used for first (or only) frame\n this.out.writeByte(0);\n } else {\n // specify normal LCT\n this.out.writeByte(\n 0x80 | // 1 local color table 1=yes\n 0 | // 2 interlace - 0=no\n 0 | // 3 sorted - 0=no\n 0 | // 4-5 reserved\n this.palSize // 6-8 size of color table\n );\n }\n};\n\n/*\n Writes Logical Screen Descriptor\n*/\nGIFEncoder.prototype.writeLSD = function() {\n // logical screen size\n this.writeShort(this.width);\n this.writeShort(this.height);\n\n // packed fields\n this.out.writeByte(\n 0x80 | // 1 : global color table flag = 1 (gct used)\n 0x70 | // 2-4 : color resolution = 7\n 0x00 | // 5 : gct sort flag = 0\n this.palSize // 6-8 : gct size\n );\n\n this.out.writeByte(0); // background color index\n this.out.writeByte(0); // pixel aspect ratio - assume 1:1\n};\n\n/*\n Writes Netscape application extension to define repeat count.\n*/\nGIFEncoder.prototype.writeNetscapeExt = function() {\n this.out.writeByte(0x21); // extension introducer\n this.out.writeByte(0xff); // app extension label\n this.out.writeByte(11); // block size\n this.out.writeUTFBytes('NETSCAPE2.0'); // app id + auth code\n this.out.writeByte(3); // sub-block size\n this.out.writeByte(1); // loop sub-block id\n this.writeShort(this.repeat); // loop count (extra iterations, 0=repeat forever)\n this.out.writeByte(0); // block terminator\n};\n\n/*\n Writes color table\n*/\nGIFEncoder.prototype.writePalette = function() {\n this.out.writeBytes(this.colorTab);\n var n = (3 * 256) - this.colorTab.length;\n for (var i = 0; i < n; i++)\n this.out.writeByte(0);\n};\n\nGIFEncoder.prototype.writeShort = function(pValue) {\n this.out.writeByte(pValue & 0xFF);\n this.out.writeByte((pValue >> 8) & 0xFF);\n};\n\n/*\n Encodes and writes pixel data\n*/\nGIFEncoder.prototype.writePixels = function() {\n var enc = new LZWEncoder(this.width, this.height, this.indexedPixels, this.colorDepth);\n enc.encode(this.out);\n};\n\n/*\n Retrieves the GIF stream\n*/\nGIFEncoder.prototype.stream = function() {\n return this.out;\n};\n\nmodule.exports = GIFEncoder;\n","/*\n LZWEncoder.js\n\n Authors\n Kevin Weiner (original Java version - kweiner@fmsware.com)\n Thibault Imbert (AS3 version - bytearray.org)\n Johan Nordberg (JS version - code@johan-nordberg.com)\n\n Acknowledgements\n GIFCOMPR.C - GIF Image compression routines\n Lempel-Ziv compression based on 'compress'. GIF modifications by\n David Rowley (mgardi@watdcsu.waterloo.edu)\n GIF Image compression - modified 'compress'\n Based on: compress.c - File compression ala IEEE Computer, June 1984.\n By Authors: Spencer W. Thomas (decvax!harpo!utah-cs!utah-gr!thomas)\n Jim McKie (decvax!mcvax!jim)\n Steve Davies (decvax!vax135!petsd!peora!srd)\n Ken Turkowski (decvax!decwrl!turtlevax!ken)\n James A. Woods (decvax!ihnp4!ames!jaw)\n Joe Orost (decvax!vax135!petsd!joe)\n*/\n\nvar EOF = -1;\nvar BITS = 12;\nvar HSIZE = 5003; // 80% occupancy\nvar masks = [0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F,\n 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF,\n 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF];\n\nfunction LZWEncoder(width, height, pixels, colorDepth) {\n var initCodeSize = Math.max(2, colorDepth);\n\n var accum = new Uint8Array(256);\n var htab = new Int32Array(HSIZE);\n var codetab = new Int32Array(HSIZE);\n\n var cur_accum, cur_bits = 0;\n var a_count;\n var free_ent = 0; // first unused entry\n var maxcode;\n\n // block compression parameters -- after all codes are used up,\n // and compression rate changes, start over.\n var clear_flg = false;\n\n // Algorithm: use open addressing double hashing (no chaining) on the\n // prefix code / next character combination. We do a variant of Knuth's\n // algorithm D (vol. 3, sec. 6.4) along with G. Knott's relatively-prime\n // secondary probe. Here, the modular division first probe is gives way\n // to a faster exclusive-or manipulation. Also do block compression with\n // an adaptive reset, whereby the code table is cleared when the compression\n // ratio decreases, but after the table fills. The variable-length output\n // codes are re-sized at this point, and a special CLEAR code is generated\n // for the decompressor. Late addition: construct the table according to\n // file size for noticeable speed improvement on small files. Please direct\n // questions about this implementation to ames!jaw.\n var g_init_bits, ClearCode, EOFCode;\n\n // Add a character to the end of the current packet, and if it is 254\n // characters, flush the packet to disk.\n function char_out(c, outs) {\n accum[a_count++] = c;\n if (a_count >= 254) flush_char(outs);\n }\n\n // Clear out the hash table\n // table clear for block compress\n function cl_block(outs) {\n cl_hash(HSIZE);\n free_ent = ClearCode + 2;\n clear_flg = true;\n output(ClearCode, outs);\n }\n\n // Reset code table\n function cl_hash(hsize) {\n for (var i = 0; i < hsize; ++i) htab[i] = -1;\n }\n\n function compress(init_bits, outs) {\n var fcode, c, i, ent, disp, hsize_reg, hshift;\n\n // Set up the globals: g_init_bits - initial number of bits\n g_init_bits = init_bits;\n\n // Set up the necessary values\n clear_flg = false;\n n_bits = g_init_bits;\n maxcode = MAXCODE(n_bits);\n\n ClearCode = 1 << (init_bits - 1);\n EOFCode = ClearCode + 1;\n free_ent = ClearCode + 2;\n\n a_count = 0; // clear packet\n\n ent = nextPixel();\n\n hshift = 0;\n for (fcode = HSIZE; fcode < 65536; fcode *= 2) ++hshift;\n hshift = 8 - hshift; // set hash code range bound\n hsize_reg = HSIZE;\n cl_hash(hsize_reg); // clear hash table\n\n output(ClearCode, outs);\n\n outer_loop: while ((c = nextPixel()) != EOF) {\n fcode = (c << BITS) + ent;\n i = (c << hshift) ^ ent; // xor hashing\n if (htab[i] === fcode) {\n ent = codetab[i];\n continue;\n } else if (htab[i] >= 0) { // non-empty slot\n disp = hsize_reg - i; // secondary hash (after G. Knott)\n if (i === 0) disp = 1;\n do {\n if ((i -= disp) < 0) i += hsize_reg;\n if (htab[i] === fcode) {\n ent = codetab[i];\n continue outer_loop;\n }\n } while (htab[i] >= 0);\n }\n output(ent, outs);\n ent = c;\n if (free_ent < 1 << BITS) {\n codetab[i] = free_ent++; // code -> hashtable\n htab[i] = fcode;\n } else {\n cl_block(outs);\n }\n }\n\n // Put out the final code.\n output(ent, outs);\n output(EOFCode, outs);\n }\n\n function encode(outs) {\n outs.writeByte(initCodeSize); // write \"initial code size\" byte\n remaining = width * height; // reset navigation variables\n curPixel = 0;\n compress(initCodeSize + 1, outs); // compress and write the pixel data\n outs.writeByte(0); // write block terminator\n }\n\n // Flush the packet to disk, and reset the accumulator\n function flush_char(outs) {\n if (a_count > 0) {\n outs.writeByte(a_count);\n outs.writeBytes(accum, 0, a_count);\n a_count = 0;\n }\n }\n\n function MAXCODE(n_bits) {\n return (1 << n_bits) - 1;\n }\n\n // Return the next pixel from the image\n function nextPixel() {\n if (remaining === 0) return EOF;\n --remaining;\n var pix = pixels[curPixel++];\n return pix & 0xff;\n }\n\n function output(code, outs) {\n cur_accum &= masks[cur_bits];\n\n if (cur_bits > 0) cur_accum |= (code << cur_bits);\n else cur_accum = code;\n\n cur_bits += n_bits;\n\n while (cur_bits >= 8) {\n char_out((cur_accum & 0xff), outs);\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n\n // If the next entry is going to be too big for the code size,\n // then increase it, if possible.\n if (free_ent > maxcode || clear_flg) {\n if (clear_flg) {\n maxcode = MAXCODE(n_bits = g_init_bits);\n clear_flg = false;\n } else {\n ++n_bits;\n if (n_bits == BITS) maxcode = 1 << BITS;\n else maxcode = MAXCODE(n_bits);\n }\n }\n\n if (code == EOFCode) {\n // At EOF, write the rest of the buffer.\n while (cur_bits > 0) {\n char_out((cur_accum & 0xff), outs);\n cur_accum >>= 8;\n cur_bits -= 8;\n }\n flush_char(outs);\n }\n }\n\n this.encode = encode;\n}\n\nmodule.exports = LZWEncoder;\n","/* NeuQuant Neural-Net Quantization Algorithm\n * ------------------------------------------\n *\n * Copyright (c) 1994 Anthony Dekker\n *\n * NEUQUANT Neural-Net quantization algorithm by Anthony Dekker, 1994.\n * See \"Kohonen neural networks for optimal colour quantization\"\n * in \"Network: Computation in Neural Systems\" Vol. 5 (1994) pp 351-367.\n * for a discussion of the algorithm.\n * See also http://members.ozemail.com.au/~dekker/NEUQUANT.HTML\n *\n * Any party obtaining a copy of these files from the author, directly or\n * indirectly, is granted, free of charge, a full and unrestricted irrevocable,\n * world-wide, paid up, royalty-free, nonexclusive right and license to deal\n * in this software and documentation files (the \"Software\"), including without\n * limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,\n * and/or sell copies of the Software, and to permit persons who receive\n * copies from any such party to do so, with the only requirement being\n * that this copyright notice remain intact.\n *\n * (JavaScript port 2012 by Johan Nordberg)\n */\n\nvar ncycles = 100; // number of learning cycles\nvar netsize = 256; // number of colors used\nvar maxnetpos = netsize - 1;\n\n// defs for freq and bias\nvar netbiasshift = 4; // bias for colour values\nvar intbiasshift = 16; // bias for fractions\nvar intbias = (1 << intbiasshift);\nvar gammashift = 10;\nvar gamma = (1 << gammashift);\nvar betashift = 10;\nvar beta = (intbias >> betashift); /* beta = 1/1024 */\nvar betagamma = (intbias << (gammashift - betashift));\n\n// defs for decreasing radius factor\nvar initrad = (netsize >> 3); // for 256 cols, radius starts\nvar radiusbiasshift = 6; // at 32.0 biased by 6 bits\nvar radiusbias = (1 << radiusbiasshift);\nvar initradius = (initrad * radiusbias); //and decreases by a\nvar radiusdec = 30; // factor of 1/30 each cycle\n\n// defs for decreasing alpha factor\nvar alphabiasshift = 10; // alpha starts at 1.0\nvar initalpha = (1 << alphabiasshift);\nvar alphadec; // biased by 10 bits\n\n/* radbias and alpharadbias used for radpower calculation */\nvar radbiasshift = 8;\nvar radbias = (1 << radbiasshift);\nvar alpharadbshift = (alphabiasshift + radbiasshift);\nvar alpharadbias = (1 << alpharadbshift);\n\n// four primes near 500 - assume no image has a length so large that it is\n// divisible by all four primes\nvar prime1 = 499;\nvar prime2 = 491;\nvar prime3 = 487;\nvar prime4 = 503;\nvar minpicturebytes = (3 * prime4);\n\n/*\n Constructor: NeuQuant\n\n Arguments:\n\n pixels - array of pixels in RGB format\n samplefac - sampling factor 1 to 30 where lower is better quality\n\n >\n > pixels = [r, g, b, r, g, b, r, g, b, ..]\n >\n*/\nfunction NeuQuant(pixels, samplefac) {\n var network; // int[netsize][4]\n var netindex; // for network lookup - really 256\n\n // bias and freq arrays for learning\n var bias;\n var freq;\n var radpower;\n\n /*\n Private Method: init\n\n sets up arrays\n */\n function init() {\n network = [];\n netindex = new Int32Array(256);\n bias = new Int32Array(netsize);\n freq = new Int32Array(netsize);\n radpower = new Int32Array(netsize >> 3);\n\n var i, v;\n for (i = 0; i < netsize; i++) {\n v = (i << (netbiasshift + 8)) / netsize;\n network[i] = new Float64Array([v, v, v, 0]);\n //network[i] = [v, v, v, 0]\n freq[i] = intbias / netsize;\n bias[i] = 0;\n }\n }\n\n /*\n Private Method: unbiasnet\n\n unbiases network to give byte values 0..255 and record position i to prepare for sort\n */\n function unbiasnet() {\n for (var i = 0; i < netsize; i++) {\n network[i][0] >>= netbiasshift;\n network[i][1] >>= netbiasshift;\n network[i][2] >>= netbiasshift;\n network[i][3] = i; // record color number\n }\n }\n\n /*\n Private Method: altersingle\n\n moves neuron *i* towards biased (b,g,r) by factor *alpha*\n */\n function altersingle(alpha, i, b, g, r) {\n network[i][0] -= (alpha * (network[i][0] - b)) / initalpha;\n network[i][1] -= (alpha * (network[i][1] - g)) / initalpha;\n network[i][2] -= (alpha * (network[i][2] - r)) / initalpha;\n }\n\n /*\n Private Method: alterneigh\n\n moves neurons in *radius* around index *i* towards biased (b,g,r) by factor *alpha*\n */\n function alterneigh(radius, i, b, g, r) {\n var lo = Math.abs(i - radius);\n var hi = Math.min(i + radius, netsize);\n\n var j = i + 1;\n var k = i - 1;\n var m = 1;\n\n var p, a;\n while ((j < hi) || (k > lo)) {\n a = radpower[m++];\n\n if (j < hi) {\n p = network[j++];\n p[0] -= (a * (p[0] - b)) / alpharadbias;\n p[1] -= (a * (p[1] - g)) / alpharadbias;\n p[2] -= (a * (p[2] - r)) / alpharadbias;\n }\n\n if (k > lo) {\n p = network[k--];\n p[0] -= (a * (p[0] - b)) / alpharadbias;\n p[1] -= (a * (p[1] - g)) / alpharadbias;\n p[2] -= (a * (p[2] - r)) / alpharadbias;\n }\n }\n }\n\n /*\n Private Method: contest\n\n searches for biased BGR values\n */\n function contest(b, g, r) {\n /*\n finds closest neuron (min dist) and updates freq\n finds best neuron (min dist-bias) and returns position\n for frequently chosen neurons, freq[i] is high and bias[i] is negative\n bias[i] = gamma * ((1 / netsize) - freq[i])\n */\n\n var bestd = ~(1 << 31);\n var bestbiasd = bestd;\n var bestpos = -1;\n var bestbiaspos = bestpos;\n\n var i, n, dist, biasdist, betafreq;\n for (i = 0; i < netsize; i++) {\n n = network[i];\n\n dist = Math.abs(n[0] - b) + Math.abs(n[1] - g) + Math.abs(n[2] - r);\n if (dist < bestd) {\n bestd = dist;\n bestpos = i;\n }\n\n biasdist = dist - ((bias[i]) >> (intbiasshift - netbiasshift));\n if (biasdist < bestbiasd) {\n bestbiasd = biasdist;\n bestbiaspos = i;\n }\n\n betafreq = (freq[i] >> betashift);\n freq[i] -= betafreq;\n bias[i] += (betafreq << gammashift);\n }\n\n freq[bestpos] += beta;\n bias[bestpos] -= betagamma;\n\n return bestbiaspos;\n }\n\n /*\n Private Method: inxbuild\n\n sorts network and builds netindex[0..255]\n */\n function inxbuild() {\n var i, j, p, q, smallpos, smallval, previouscol = 0, startpos = 0;\n for (i = 0; i < netsize; i++) {\n p = network[i];\n smallpos = i;\n smallval = p[1]; // index on g\n // find smallest in i..netsize-1\n for (j = i + 1; j < netsize; j++) {\n q = network[j];\n if (q[1] < smallval) { // index on g\n smallpos = j;\n smallval = q[1]; // index on g\n }\n }\n q = network[smallpos];\n // swap p (i) and q (smallpos) entries\n if (i != smallpos) {\n j = q[0]; q[0] = p[0]; p[0] = j;\n j = q[1]; q[1] = p[1]; p[1] = j;\n j = q[2]; q[2] = p[2]; p[2] = j;\n j = q[3]; q[3] = p[3]; p[3] = j;\n }\n // smallval entry is now in position i\n\n if (smallval != previouscol) {\n netindex[previouscol] = (startpos + i) >> 1;\n for (j = previouscol + 1; j < smallval; j++)\n netindex[j] = i;\n previouscol = smallval;\n startpos = i;\n }\n }\n netindex[previouscol] = (startpos + maxnetpos) >> 1;\n for (j = previouscol + 1; j < 256; j++)\n netindex[j] = maxnetpos; // really 256\n }\n\n /*\n Private Method: inxsearch\n\n searches for BGR values 0..255 and returns a color index\n */\n function inxsearch(b, g, r) {\n var a, p, dist;\n\n var bestd = 1000; // biggest possible dist is 256*3\n var best = -1;\n\n var i = netindex[g]; // index on g\n var j = i - 1; // start at netindex[g] and work outwards\n\n while ((i < netsize) || (j >= 0)) {\n if (i < netsize) {\n p = network[i];\n dist = p[1] - g; // inx key\n if (dist >= bestd) i = netsize; // stop iter\n else {\n i++;\n if (dist < 0) dist = -dist;\n a = p[0] - b; if (a < 0) a = -a;\n dist += a;\n if (dist < bestd) {\n a = p[2] - r; if (a < 0) a = -a;\n dist += a;\n if (dist < bestd) {\n bestd = dist;\n best = p[3];\n }\n }\n }\n }\n if (j >= 0) {\n p = network[j];\n dist = g - p[1]; // inx key - reverse dif\n if (dist >= bestd) j = -1; // stop iter\n else {\n j--;\n if (dist < 0) dist = -dist;\n a = p[0] - b; if (a < 0) a = -a;\n dist += a;\n if (dist < bestd) {\n a = p[2] - r; if (a < 0) a = -a;\n dist += a;\n if (dist < bestd) {\n bestd = dist;\n best = p[3];\n }\n }\n }\n }\n }\n\n return best;\n }\n\n /*\n Private Method: learn\n\n \"Main Learning Loop\"\n */\n function learn() {\n var i;\n\n var lengthcount = pixels.length;\n var alphadec = 30 + ((samplefac - 1) / 3);\n var samplepixels = lengthcount / (3 * samplefac);\n var delta = ~~(samplepixels / ncycles);\n var alpha = initalpha;\n var radius = initradius;\n\n var rad = radius >> radiusbiasshift;\n\n if (rad <= 1) rad = 0;\n for (i = 0; i < rad; i++)\n radpower[i] = alpha * (((rad * rad - i * i) * radbias) / (rad * rad));\n\n var step;\n if (lengthcount < minpicturebytes) {\n samplefac = 1;\n step = 3;\n } else if ((lengthcount % prime1) !== 0) {\n step = 3 * prime1;\n } else if ((lengthcount % prime2) !== 0) {\n step = 3 * prime2;\n } else if ((lengthcount % prime3) !== 0) {\n step = 3 * prime3;\n } else {\n step = 3 * prime4;\n }\n\n var b, g, r, j;\n var pix = 0; // current pixel\n\n i = 0;\n while (i < samplepixels) {\n b = (pixels[pix] & 0xff) << netbiasshift;\n g = (pixels[pix + 1] & 0xff) << netbiasshift;\n r = (pixels[pix + 2] & 0xff) << netbiasshift;\n\n j = contest(b, g, r);\n\n altersingle(alpha, j, b, g, r);\n if (rad !== 0) alterneigh(rad, j, b, g, r); // alter neighbours\n\n pix += step;\n if (pix >= lengthcount) pix -= lengthcount;\n\n i++;\n\n if (delta === 0) delta = 1;\n if (i % delta === 0) {\n alpha -= alpha / alphadec;\n radius -= radius / radiusdec;\n rad = radius >> radiusbiasshift;\n\n if (rad <= 1) rad = 0;\n for (j = 0; j < rad; j++)\n radpower[j] = alpha * (((rad * rad - j * j) * radbias) / (rad * rad));\n }\n }\n }\n\n /*\n Method: buildColormap\n\n 1. initializes network\n 2. trains it\n 3. removes misconceptions\n 4. builds colorindex\n */\n function buildColormap() {\n init();\n learn();\n unbiasnet();\n inxbuild();\n }\n this.buildColormap = buildColormap;\n\n /*\n Method: getColormap\n\n builds colormap from the index\n\n returns array in the format:\n\n >\n > [r, g, b, r, g, b, r, g, b, ..]\n >\n */\n function getColormap() {\n var map = [];\n var index = [];\n\n for (var i = 0; i < netsize; i++)\n index[network[i][3]] = i;\n\n var k = 0;\n for (var l = 0; l < netsize; l++) {\n var j = index[l];\n map[k++] = (network[j][0]);\n map[k++] = (network[j][1]);\n map[k++] = (network[j][2]);\n }\n return map;\n }\n this.getColormap = getColormap;\n\n /*\n Method: lookupRGB\n\n looks for the closest *r*, *g*, *b* color in the map and\n returns its index\n */\n this.lookupRGB = inxsearch;\n}\n\nmodule.exports = NeuQuant;\n","GIFEncoder = require './GIFEncoder.js'\n\nrenderFrame = (frame) ->\n encoder = new GIFEncoder frame.width, frame.height\n\n if frame.index is 0\n encoder.writeHeader()\n else\n encoder.firstFrame = false\n\n encoder.setTransparent frame.transparent\n encoder.setDispose frame.dispose\n encoder.setRepeat frame.repeat\n encoder.setDelay frame.delay\n encoder.setQuality frame.quality\n encoder.setDither frame.dither\n encoder.setGlobalPalette frame.globalPalette\n encoder.addFrame frame.data\n encoder.finish() if frame.last\n if frame.globalPalette == true\n frame.globalPalette = encoder.getGlobalPalette()\n\n stream = encoder.stream()\n frame.data = stream.pages\n frame.cursor = stream.cursor\n frame.pageSize = stream.constructor.pageSize\n\n if frame.canTransfer\n transfer = (page.buffer for page in frame.data)\n self.postMessage frame, transfer\n else\n self.postMessage frame\n\nself.onmessage = (event) -> renderFrame event.data\n"]} \ No newline at end of file diff --git a/js/eval.js b/js/eval.js index 44c0700..37c7f29 100644 --- a/js/eval.js +++ b/js/eval.js @@ -5,6 +5,7 @@ var BinaryPrec; BinaryPrec[BinaryPrec["PREC1"] = 1] = "PREC1"; BinaryPrec[BinaryPrec["COUNT_PRECS"] = 2] = "COUNT_PRECS"; })(BinaryPrec || (BinaryPrec = {})); +; var BINARY_OPS = { '+': { func: function (lhs, rhs) { return lhs + rhs; }, @@ -28,7 +29,7 @@ var BINARY_OPS = { } }; var UNARY_OPS = { - '-': function (arg) { return -arg; } + '-': function (arg) { return -arg; }, }; var Lexer = (function () { function Lexer(src) { @@ -73,15 +74,15 @@ function parse_primary(lexer) { "kind": "unary_op", "payload": { "op": token, - "operand": operand - } + "operand": operand, + }, }; } else if (token === '(') { var expr = parse_expr(lexer); token = lexer.next(); if (token !== ')') { - throw new Error("Expected ')' but got '" + token + "'"); + throw new Error("Expected ')' but got '".concat(token, "'")); } return expr; } @@ -95,10 +96,10 @@ function parse_primary(lexer) { next_token = lexer.next(); if (next_token === ')') { return { - "kind": "funcall", - "payload": { - "name": token, - "args": args + kind: "funcall", + payload: { + name: token, + args: args, } }; } @@ -113,13 +114,13 @@ function parse_primary(lexer) { next_token = lexer.next(); } if (next_token !== ')') { - throw Error("Expected ')' but got '" + next_token + "'"); + throw Error("Expected ')' but got '".concat(next_token, "'")); } return { - "kind": "funcall", - "payload": { - "name": token, - "args": args + kind: "funcall", + payload: { + name: token, + args: args, } }; } @@ -128,9 +129,9 @@ function parse_primary(lexer) { lexer.unnext(next_token); } return { - "kind": "symbol", - "payload": { - "value": token + kind: "symbol", + payload: { + value: token } }; } @@ -151,11 +152,11 @@ function parse_expr(lexer, prec) { if (op_token in BINARY_OPS && BINARY_OPS[op_token].prec == prec) { var rhs = parse_expr(lexer, prec); return { - "kind": "binary_op", - "payload": { - "op": op_token, - "lhs": lhs, - "rhs": rhs + kind: "binary_op", + payload: { + op: op_token, + lhs: lhs, + rhs: rhs, } }; } @@ -172,7 +173,7 @@ function compile_expr(src) { if (token !== null) { console.log(typeof (token)); console.log(token); - throw new Error("Unexpected token '" + token + "'"); + throw new Error("Unexpected token '".concat(token, "'")); } return result; } @@ -189,7 +190,7 @@ function run_expr(expr, user_context) { if (user_context.vars && value in user_context.vars) { return user_context.vars[value]; } - throw new Error("Unknown variable '" + value + "'"); + throw new Error("Unknown variable '".concat(value, "'")); } else { return number; @@ -200,24 +201,24 @@ function run_expr(expr, user_context) { if (unary_op.op in UNARY_OPS) { return UNARY_OPS[unary_op.op](run_expr(unary_op.operand, user_context)); } - throw new Error("Unknown unary operator '" + unary_op.op + "'"); + throw new Error("Unknown unary operator '".concat(unary_op.op, "'")); } case 'binary_op': { var binary_op = expr.payload; if (binary_op.op in BINARY_OPS) { return BINARY_OPS[binary_op.op].func(run_expr(binary_op.lhs, user_context), run_expr(binary_op.rhs, user_context)); } - throw new Error("Unknown binary operator '" + binary_op.op + "'"); + throw new Error("Unknown binary operator '".concat(binary_op.op, "'")); } case 'funcall': { var funcall = expr.payload; if (user_context.funcs && funcall.name in user_context.funcs) { return (_a = user_context.funcs)[funcall.name].apply(_a, funcall.args.map(function (arg) { return run_expr(arg, user_context); })); } - throw new Error("Unknown function '" + funcall.name + "'"); + throw new Error("Unknown function '".concat(funcall.name, "'")); } default: { - throw new Error("Unexpected AST node '" + expr.kind + "'"); + throw new Error("Unexpected AST node '".concat(expr.kind, "'")); } } } diff --git a/js/filters.js b/js/filters.js index d634ca5..c3b5df5 100644 --- a/js/filters.js +++ b/js/filters.js @@ -1,241 +1,241 @@ "use strict"; var filters = { - "Hop": { - "transparent": 0x00FF00 + "", - "duration": "interval * 2", - "params": { - "interval": { - "label": "Interval", - "type": "float", - "init": 0.85, - "min": 0.01, - "max": 2.00, - "step": 0.01 + Hop: { + transparent: String(0x00FF00), + duration: "interval * 2", + params: { + interval: { + label: "Interval", + type: "float", + init: 0.85, + min: 0.01, + max: 2.00, + step: 0.01, }, - "ground": { - "label": "Ground", - "type": "float", - "init": 0.5, - "min": -1.0, - "max": 1.0, - "step": 0.01 + ground: { + label: "Ground", + type: "float", + init: 0.5, + min: -1.0, + max: 1.0, + step: 0.01, }, - "scale": { - "label": "Scale", - "type": "float", - "init": 0.40, - "min": 0.0, - "max": 1.0, - "step": 0.01 + scale: { + label: "Scale", + type: "float", + init: 0.40, + min: 0.0, + max: 1.0, + step: 0.01, }, - "jump_height": { - "label": "Jump Height", - "type": "float", - "init": 4.0, - "min": 1.0, - "max": 10.0, - "step": 0.01 + jump_height: { + label: "Jump Height", + type: "float", + init: 4.0, + min: 1.0, + max: 10.0, + step: 0.01, }, - "hops": { - "label": "Hops Count", - "type": "float", - "init": 2.0, - "min": 1.0, - "max": 5.0, - "step": 1.0 + hops: { + label: "Hops Count", + type: "float", + init: 2.0, + min: 1.0, + max: 5.0, + step: 1.0, } }, - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\nuniform vec2 emoteSize;\n\nuniform float interval;\nuniform float ground;\nuniform float scale;\nuniform float jump_height;\nuniform float hops;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float x_time_interval = interval;\n float y_time_interval = x_time_interval / (2.0 * hops);\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n ((sliding_from_left_to_right(y_time_interval) * flipping_directions(y_time_interval) + 1.0) / jump_height) - ground);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", - "fragment": "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Hopper": { - "transparent": 0x00FF00 + "", - "duration": "0.85", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float scale = 0.40;\n float hops = 2.0;\n float x_time_interval = 0.85 / 2.0;\n float y_time_interval = x_time_interval / (2.0 * hops);\n float height = 0.5;\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n ((sliding_from_left_to_right(y_time_interval) * flipping_directions(y_time_interval) + 1.0) / 4.0) - height);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", - "fragment": "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Overheat": { - "transparent": 0x00FF00 + "", - "duration": "0.85 / 8.0 * 2.0", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float scale = 0.40;\n float hops = 2.0;\n float x_time_interval = 0.85 / 8.0;\n float y_time_interval = x_time_interval / (2.0 * hops);\n float height = 0.5;\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n ((sliding_from_left_to_right(y_time_interval) * flipping_directions(y_time_interval) + 1.0) / 4.0) - height);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", - "fragment": "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y)) * vec4(1.0, 0.0, 0.0, 1.0);\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Bounce": { - "transparent": 0x00FF00 + "", - "duration": "Math.PI / period", - "params": { - "period": { - "type": "float", - "init": 5.0, - "min": 1.0, - "max": 10.0, - "step": 0.1 + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\nuniform vec2 emoteSize;\n\nuniform float interval;\nuniform float ground;\nuniform float scale;\nuniform float jump_height;\nuniform float hops;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float x_time_interval = interval;\n float y_time_interval = x_time_interval / (2.0 * hops);\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n ((sliding_from_left_to_right(y_time_interval) * flipping_directions(y_time_interval) + 1.0) / jump_height) - ground);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", + fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" + }, + Hopper: { + transparent: String(0x00FF00), + duration: "0.85", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float scale = 0.40;\n float hops = 2.0;\n float x_time_interval = 0.85 / 2.0;\n float y_time_interval = x_time_interval / (2.0 * hops);\n float height = 0.5;\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n ((sliding_from_left_to_right(y_time_interval) * flipping_directions(y_time_interval) + 1.0) / 4.0) - height);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", + fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" + }, + Overheat: { + transparent: String(0x00FF00), + duration: "0.85 / 8.0 * 2.0", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float scale = 0.40;\n float hops = 2.0;\n float x_time_interval = 0.85 / 8.0;\n float y_time_interval = x_time_interval / (2.0 * hops);\n float height = 0.5;\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n ((sliding_from_left_to_right(y_time_interval) * flipping_directions(y_time_interval) + 1.0) / 4.0) - height);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", + fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y)) * vec4(1.0, 0.0, 0.0, 1.0);\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" + }, + Bounce: { + transparent: String(0x00FF00), + duration: "Math.PI / period", + params: { + period: { + type: "float", + init: 5.0, + min: 1.0, + max: 10.0, + step: 0.1, }, - "scale": { - "type": "float", - "init": 0.30, - "min": 0.0, - "max": 1.0, - "step": 0.01 + scale: { + type: "float", + init: 0.30, + min: 0.0, + max: 1.0, + step: 0.01, } }, - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform float period;\nuniform float scale;\n\nvarying vec2 uv;\n\nvoid main() {\n vec2 offset = vec2(0.0, (2.0 * abs(sin(time * period)) - 1.0) * (1.0 - scale));\n gl_Position = vec4(meshPosition * scale + offset, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Circle": { - "transparent": 0x00FF00 + "", - "duration": "Math.PI / 4.0", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvec2 rotate(vec2 v, float a) {\n\tfloat s = sin(a);\n\tfloat c = cos(a);\n\tmat2 m = mat2(c, -s, s, c);\n\treturn m * v;\n}\n\nvoid main() {\n float scale = 0.30;\n float period_interval = 8.0;\n float pi = 3.141592653589793238;\n vec2 outer_circle = vec2(cos(period_interval * time), sin(period_interval * time)) * (1.0 - scale);\n vec2 inner_circle = rotate(meshPosition * scale, (-period_interval * time) + pi / 2.0);\n gl_Position = vec4(\n inner_circle + outer_circle,\n 0.0,\n 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n float speed = 1.0;\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Slide": { - "transparent": 0x00FF00 + "", - "duration": "0.85 * 2", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float scale = 0.40;\n float hops = 2.0;\n float x_time_interval = 0.85;\n float y_time_interval = x_time_interval / (2.0 * hops);\n float height = 0.5;\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n - height);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", - "fragment": "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Laughing": { - "transparent": 0x00FF00 + "", - "duration": "Math.PI / 12.0", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n float a = 0.3;\n float t = (sin(24.0 * time) * a + a) / 2.0;\n\n gl_Position = vec4(\n meshPosition - vec2(0.0, t),\n 0.0,\n 1.0);\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n}\n", - "fragment": "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Blob": { - "transparent": 0x00FF00 + "", - "duration": "Math.PI / 3", - "vertex": "#version 100\n\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n float stretch = sin(6.0 * time) * 0.5 + 1.0;\n\n vec2 offset = vec2(0.0, 1.0 - stretch);\n gl_Position = vec4(\n meshPosition * vec2(stretch, 2.0 - stretch) + offset,\n 0.0,\n 1.0);\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n}\n", - "fragment": "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Go": { - "transparent": 0x00FF00 + "", - "duration": "1 / 4", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nfloat slide(float speed, float value) {\n return mod(value - speed * time, 1.0);\n}\n\nvoid main() {\n float speed = 4.0;\n gl_FragColor = texture2D(emote, vec2(slide(speed, uv.x), 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Elevator": { - "transparent": 0x00FF00 + "", - "duration": "1 / 4", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nfloat slide(float speed, float value) {\n return mod(value - speed * time, 1.0);\n}\n\nvoid main() {\n float speed = 4.0;\n gl_FragColor = texture2D(\n emote,\n vec2(uv.x, slide(speed, 1.0 - uv.y)));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Rain": { - "transparent": 0x00FF00 + "", - "duration": "1", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nfloat slide(float speed, float value) {\n return mod(value - speed * time, 1.0);\n}\n\nvoid main() {\n float speed = 1.0;\n gl_FragColor = texture2D(\n emote,\n vec2(mod(4.0 * slide(speed, uv.x), 1.0),\n mod(4.0 * slide(speed, 1.0 - uv.y), 1.0)));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Pride": { - "transparent": null, - "duration": "2.0", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvec3 hsl2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0);\n return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));\n}\n\nvoid main() {\n float speed = 1.0;\n\n vec4 pixel = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n pixel.w = floor(pixel.w + 0.5);\n pixel = vec4(mix(vec3(1.0), pixel.xyz, pixel.w), 1.0);\n vec4 rainbow = vec4(hsl2rgb(vec3((time - uv.x - uv.y) * 0.5, 1.0, 0.80)), 1.0);\n gl_FragColor = pixel * rainbow;\n}\n" - }, - "Hard": { - "transparent": 0x00FF00 + "", - "duration": "2.0 * Math.PI / intensity", - "params": { - "zoom": { - "type": "float", - "init": 1.4, - "min": 0.0, - "max": 6.9, - "step": 0.1 + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform float period;\nuniform float scale;\n\nvarying vec2 uv;\n\nvoid main() {\n vec2 offset = vec2(0.0, (2.0 * abs(sin(time * period)) - 1.0) * (1.0 - scale));\n gl_Position = vec4(meshPosition * scale + offset, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", + }, + Circle: { + transparent: String(0x00FF00), + duration: "Math.PI / 4.0", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvec2 rotate(vec2 v, float a) {\n\tfloat s = sin(a);\n\tfloat c = cos(a);\n\tmat2 m = mat2(c, -s, s, c);\n\treturn m * v;\n}\n\nvoid main() {\n float scale = 0.30;\n float period_interval = 8.0;\n float pi = 3.141592653589793238;\n vec2 outer_circle = vec2(cos(period_interval * time), sin(period_interval * time)) * (1.0 - scale);\n vec2 inner_circle = rotate(meshPosition * scale, (-period_interval * time) + pi / 2.0);\n gl_Position = vec4(\n inner_circle + outer_circle,\n 0.0,\n 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n float speed = 1.0;\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", + }, + Slide: { + transparent: String(0x00FF00), + duration: "0.85 * 2", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float scale = 0.40;\n float hops = 2.0;\n float x_time_interval = 0.85;\n float y_time_interval = x_time_interval / (2.0 * hops);\n float height = 0.5;\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n - height);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", + fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" + }, + Laughing: { + transparent: String(0x00FF00), + duration: "Math.PI / 12.0", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n float a = 0.3;\n float t = (sin(24.0 * time) * a + a) / 2.0;\n\n gl_Position = vec4(\n meshPosition - vec2(0.0, t),\n 0.0,\n 1.0);\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n}\n", + fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" + }, + Blob: { + transparent: String(0x00FF00), + duration: "Math.PI / 3", + vertex: "#version 100\n\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n float stretch = sin(6.0 * time) * 0.5 + 1.0;\n\n vec2 offset = vec2(0.0, 1.0 - stretch);\n gl_Position = vec4(\n meshPosition * vec2(stretch, 2.0 - stretch) + offset,\n 0.0,\n 1.0);\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n}\n", + fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" + }, + Go: { + transparent: String(0x00FF00), + duration: "1 / 4", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nfloat slide(float speed, float value) {\n return mod(value - speed * time, 1.0);\n}\n\nvoid main() {\n float speed = 4.0;\n gl_FragColor = texture2D(emote, vec2(slide(speed, uv.x), 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", + }, + Elevator: { + transparent: String(0x00FF00), + duration: "1 / 4", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nfloat slide(float speed, float value) {\n return mod(value - speed * time, 1.0);\n}\n\nvoid main() {\n float speed = 4.0;\n gl_FragColor = texture2D(\n emote,\n vec2(uv.x, slide(speed, 1.0 - uv.y)));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", + }, + Rain: { + transparent: String(0x00FF00), + duration: "1", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nfloat slide(float speed, float value) {\n return mod(value - speed * time, 1.0);\n}\n\nvoid main() {\n float speed = 1.0;\n gl_FragColor = texture2D(\n emote,\n vec2(mod(4.0 * slide(speed, uv.x), 1.0),\n mod(4.0 * slide(speed, 1.0 - uv.y), 1.0)));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", + }, + Pride: { + transparent: null, + duration: "2.0", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvec3 hsl2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0);\n return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));\n}\n\nvoid main() {\n float speed = 1.0;\n\n vec4 pixel = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n pixel.w = floor(pixel.w + 0.5);\n pixel = vec4(mix(vec3(1.0), pixel.xyz, pixel.w), 1.0);\n vec4 rainbow = vec4(hsl2rgb(vec3((time - uv.x - uv.y) * 0.5, 1.0, 0.80)), 1.0);\n gl_FragColor = pixel * rainbow;\n}\n", + }, + Hard: { + transparent: String(0x00FF00), + duration: "2.0 * Math.PI / intensity", + params: { + zoom: { + type: "float", + init: 1.4, + min: 0.0, + max: 6.9, + step: 0.1, }, - "intensity": { - "type": "float", - "init": 32.0, - "min": 1.0, - "max": 42.0, - "step": 1.0 + intensity: { + type: "float", + init: 32.0, + min: 1.0, + max: 42.0, + step: 1.0, + }, + amplitude: { + type: "float", + init: 1.0 / 8.0, + min: 0.0, + max: 1.0 / 2.0, + step: 0.001, }, - "amplitude": { - "type": "float", - "init": 1.0 / 8.0, - "min": 0.0, - "max": 1.0 / 2.0, - "step": 0.001 - } }, - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform float zoom;\nuniform float intensity;\nuniform float amplitude;\n\nvarying vec2 uv;\n\nvoid main() {\n vec2 shaking = vec2(cos(intensity * time), sin(intensity * time)) * amplitude;\n gl_Position = vec4(meshPosition * zoom + shaking, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Peek": { - "transparent": 0x00FF00 + "", - "duration": "2.0 * Math.PI", - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n float time_clipped= mod(time * 2.0, (4.0 * 3.14));\n\n float s1 = float(time_clipped < (2.0 * 3.14));\n float s2 = 1.0 - s1;\n\n float hold1 = float(time_clipped > (0.5 * 3.14) && time_clipped < (2.0 * 3.14));\n float hold2 = 1.0 - float(time_clipped > (2.5 * 3.14) && time_clipped < (4.0 * 3.14));\n\n float cycle_1 = 1.0 - ((s1 * sin(time_clipped) * (1.0 - hold1)) + hold1);\n float cycle_2 = s2 * hold2 * (sin(time_clipped) - 1.0); \n\n gl_Position = vec4(meshPosition.x + 1.0 + cycle_1 + cycle_2 , meshPosition.y, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - "Matrix": { - "transparent": null, - "duration": "3.0", - "vertex": "\n #version 100\n precision mediump float;\n\n attribute vec2 meshPosition;\n\n uniform vec2 resolution;\n uniform float time;\n\n varying vec2 _uv;\n\n void main()\n {\n _uv = (meshPosition + 1.0) / 2.0;\n gl_Position = vec4(meshPosition.x, meshPosition.y, 0.0, 1.0);\n }\n ", - "fragment": "\n #version 100\n precision mediump float;\n\n uniform vec2 resolution;\n uniform float time;\n uniform sampler2D emote;\n\n varying vec2 _uv;\n\n float clamp01(float value)\n {\n return clamp(value, 0.0, 1.0);\n }\n\n float sdf_zero(vec2 uv)\n {\n float inside = step(0.15, abs(uv.x)) + step(0.3, abs(uv.y));\n float outside = step(0.35, abs(uv.x)) + step(0.4, abs(uv.y));\n return clamp01(inside) - clamp01(outside);\n }\n\n float sdf_one(vec2 uv)\n {\n float top = step(0.25, -uv.y) * step(0.0, uv.x);\n float inside = (step(0.2, uv.x) + top);\n float outside = step(0.35, abs(uv.x)) + step(0.4, abs(uv.y));\n return clamp01(clamp01(inside) - clamp01(outside));\n }\n\n // Random float. No precomputed gradients mean this works for any number of grid coordinates\n float random01(vec2 n)\n {\n float random = 2920.0 * sin(n.x * 21942.0 + n.y * 171324.0 + 8912.0) *\n cos(n.x * 23157.0 * n.y * 217832.0 + 9758.0);\n \n return (sin(random) + 1.0) / 2.0;\n }\n\n float loop_time(float time_frame)\n {\n float times = floor(time / time_frame);\n return time - (times * time_frame);\n }\n\n void main()\n {\n vec2 uv = _uv;\n uv.y = 1.0 - _uv.y;\n \n float number_of_numbers = 8.0;\n float number_change_rate = 2.0;\n float amount_of_numbers = 0.6; // from 0 - 1\n \n vec4 texture_color = texture2D(emote, uv);\n vec4 number_color = vec4(0, 0.7, 0, 1);\n\n float looped_time = loop_time(3.0); \n\n vec2 translation = vec2(0, looped_time * -8.0);\n\n vec2 pos_idx = floor(uv * number_of_numbers + translation);\n float rnd_number = step(0.5, random01(pos_idx + floor(looped_time * number_change_rate)));\n float rnd_show = step(1.0 - amount_of_numbers, random01(pos_idx + vec2(99,99)));\n\n vec2 nuv = uv * number_of_numbers + translation;\n nuv = fract(nuv);\n\n float one = sdf_one(nuv - 0.5) * rnd_number;\n float zero = sdf_zero(nuv - 0.5) * (1.0 - rnd_number);\n float number = (one + zero) * rnd_show;\n\n float is_texture = 1.0 - number;\n float is_number = number;\n\n vec4 col = (texture_color * is_texture) + (number_color * is_number);\n\n gl_FragColor = col;\n gl_FragColor.w = 1.0;\n }\n " - }, - "Flag": { - "transparent": 0x00FF00 + "", - "duration": "Math.PI", - "vertex": "\n #version 100\n precision mediump float;\n\n attribute vec2 meshPosition;\n\n uniform vec2 resolution;\n uniform float time;\n\n varying vec2 _uv;\n\n void main()\n {\n _uv = (meshPosition + 1.0) / 2.0;\n _uv.y = 1.0 - _uv.y;\n gl_Position = vec4(meshPosition.x, meshPosition.y, 0.0, 1.0);\n }\n ", - "fragment": "\n #version 100\n precision mediump float;\n\n varying vec2 _uv;\n uniform sampler2D emote;\n uniform float time;\n\n float sin01(float value)\n {\n return (sin(value) + 1.0) / 2.0;\n }\n\n //pos is left bottom point.\n float sdf_rect(vec2 pos, vec2 size, vec2 uv)\n {\n float left = pos.x;\n float right = pos.x + size.x;\n float bottom = pos.y;\n float top = pos.y + size.y;\n return (step(bottom, uv.y) - step(top, uv.y)) * (step(left, uv.x) - step(right, uv.x)); \n }\n\n void main() {\n float stick_width = 0.1;\n float flag_height = 0.75;\n float wave_size = 0.08;\n vec4 stick_color = vec4(107.0 / 256.0, 59.0 / 256.0, 9.0 / 256.0,1);\n \n vec2 flag_uv = _uv;\n flag_uv.x = (1.0 / (1.0 - stick_width)) * (flag_uv.x - stick_width);\n flag_uv.y *= 1.0 / flag_height;\n\n float flag_close_to_stick = smoothstep(0.0, 0.5, flag_uv.x);\n flag_uv.y += sin((-time * 2.0) + (flag_uv.x * 8.0)) * flag_close_to_stick * wave_size;\n\n float is_flag = sdf_rect(vec2(0,0), vec2(1.0, 1.0), flag_uv);\n float is_flag_stick = sdf_rect(vec2(0.0, 0.0), vec2(stick_width, 1), _uv);\n\n vec4 emote_color = texture2D(emote, flag_uv);\n vec4 texture_color = (emote_color * is_flag) + (stick_color * is_flag_stick);\n\n gl_FragColor = texture_color;\n }\n " - }, - "Thanosed": { - "transparent": 0x00FF00 + "", - "duration": "duration", - "params": { - "duration": { - "type": "float", - "init": 6.0, - "min": 1.0, - "max": 16.0, - "step": 1.0 + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform float zoom;\nuniform float intensity;\nuniform float amplitude;\n\nvarying vec2 uv;\n\nvoid main() {\n vec2 shaking = vec2(cos(intensity * time), sin(intensity * time)) * amplitude;\n gl_Position = vec4(meshPosition * zoom + shaking, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", + }, + Peek: { + transparent: String(0x00FF00), + duration: "2.0 * Math.PI", + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n float time_clipped= mod(time * 2.0, (4.0 * 3.14));\n\n float s1 = float(time_clipped < (2.0 * 3.14));\n float s2 = 1.0 - s1;\n\n float hold1 = float(time_clipped > (0.5 * 3.14) && time_clipped < (2.0 * 3.14));\n float hold2 = 1.0 - float(time_clipped > (2.5 * 3.14) && time_clipped < (4.0 * 3.14));\n\n float cycle_1 = 1.0 - ((s1 * sin(time_clipped) * (1.0 - hold1)) + hold1);\n float cycle_2 = s2 * hold2 * (sin(time_clipped) - 1.0);\n\n gl_Position = vec4(meshPosition.x + 1.0 + cycle_1 + cycle_2 , meshPosition.y, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", + }, + Matrix: { + transparent: null, + duration: "3.0", + vertex: "\n #version 100\n precision mediump float;\n\n attribute vec2 meshPosition;\n\n uniform vec2 resolution;\n uniform float time;\n\n varying vec2 _uv;\n\n void main()\n {\n _uv = (meshPosition + 1.0) / 2.0;\n gl_Position = vec4(meshPosition.x, meshPosition.y, 0.0, 1.0);\n }\n ", + fragment: "\n #version 100\n precision mediump float;\n\n uniform vec2 resolution;\n uniform float time;\n uniform sampler2D emote;\n\n varying vec2 _uv;\n\n float clamp01(float value)\n {\n return clamp(value, 0.0, 1.0);\n }\n\n float sdf_zero(vec2 uv)\n {\n float inside = step(0.15, abs(uv.x)) + step(0.3, abs(uv.y));\n float outside = step(0.35, abs(uv.x)) + step(0.4, abs(uv.y));\n return clamp01(inside) - clamp01(outside);\n }\n\n float sdf_one(vec2 uv)\n {\n float top = step(0.25, -uv.y) * step(0.0, uv.x);\n float inside = (step(0.2, uv.x) + top);\n float outside = step(0.35, abs(uv.x)) + step(0.4, abs(uv.y));\n return clamp01(clamp01(inside) - clamp01(outside));\n }\n\n // Random float. No precomputed gradients mean this works for any number of grid coordinates\n float random01(vec2 n)\n {\n float random = 2920.0 * sin(n.x * 21942.0 + n.y * 171324.0 + 8912.0) *\n cos(n.x * 23157.0 * n.y * 217832.0 + 9758.0);\n\n return (sin(random) + 1.0) / 2.0;\n }\n\n float loop_time(float time_frame)\n {\n float times = floor(time / time_frame);\n return time - (times * time_frame);\n }\n\n void main()\n {\n vec2 uv = _uv;\n uv.y = 1.0 - _uv.y;\n\n float number_of_numbers = 8.0;\n float number_change_rate = 2.0;\n float amount_of_numbers = 0.6; // from 0 - 1\n\n vec4 texture_color = texture2D(emote, uv);\n vec4 number_color = vec4(0, 0.7, 0, 1);\n\n float looped_time = loop_time(3.0);\n\n vec2 translation = vec2(0, looped_time * -8.0);\n\n vec2 pos_idx = floor(uv * number_of_numbers + translation);\n float rnd_number = step(0.5, random01(pos_idx + floor(looped_time * number_change_rate)));\n float rnd_show = step(1.0 - amount_of_numbers, random01(pos_idx + vec2(99,99)));\n\n vec2 nuv = uv * number_of_numbers + translation;\n nuv = fract(nuv);\n\n float one = sdf_one(nuv - 0.5) * rnd_number;\n float zero = sdf_zero(nuv - 0.5) * (1.0 - rnd_number);\n float number = (one + zero) * rnd_show;\n\n float is_texture = 1.0 - number;\n float is_number = number;\n\n vec4 col = (texture_color * is_texture) + (number_color * is_number);\n\n gl_FragColor = col;\n gl_FragColor.w = 1.0;\n }\n " + }, + Flag: { + transparent: String(0x00FF00), + duration: "Math.PI", + vertex: "\n #version 100\n precision mediump float;\n\n attribute vec2 meshPosition;\n\n uniform vec2 resolution;\n uniform float time;\n\n varying vec2 _uv;\n\n void main()\n {\n _uv = (meshPosition + 1.0) / 2.0;\n _uv.y = 1.0 - _uv.y;\n gl_Position = vec4(meshPosition.x, meshPosition.y, 0.0, 1.0);\n }\n ", + fragment: "\n #version 100\n precision mediump float;\n\n varying vec2 _uv;\n uniform sampler2D emote;\n uniform float time;\n\n float sin01(float value)\n {\n return (sin(value) + 1.0) / 2.0;\n }\n\n //pos is left bottom point.\n float sdf_rect(vec2 pos, vec2 size, vec2 uv)\n {\n float left = pos.x;\n float right = pos.x + size.x;\n float bottom = pos.y;\n float top = pos.y + size.y;\n return (step(bottom, uv.y) - step(top, uv.y)) * (step(left, uv.x) - step(right, uv.x));\n }\n\n void main() {\n float stick_width = 0.1;\n float flag_height = 0.75;\n float wave_size = 0.08;\n vec4 stick_color = vec4(107.0 / 256.0, 59.0 / 256.0, 9.0 / 256.0,1);\n\n vec2 flag_uv = _uv;\n flag_uv.x = (1.0 / (1.0 - stick_width)) * (flag_uv.x - stick_width);\n flag_uv.y *= 1.0 / flag_height;\n\n float flag_close_to_stick = smoothstep(0.0, 0.5, flag_uv.x);\n flag_uv.y += sin((-time * 2.0) + (flag_uv.x * 8.0)) * flag_close_to_stick * wave_size;\n\n float is_flag = sdf_rect(vec2(0,0), vec2(1.0, 1.0), flag_uv);\n float is_flag_stick = sdf_rect(vec2(0.0, 0.0), vec2(stick_width, 1), _uv);\n\n vec4 emote_color = texture2D(emote, flag_uv);\n vec4 texture_color = (emote_color * is_flag) + (stick_color * is_flag_stick);\n\n gl_FragColor = texture_color;\n }\n " + }, + Thanosed: { + transparent: String(0x00FF00), + duration: "duration", + params: { + duration: { + type: "float", + init: 6.0, + min: 1.0, + max: 16.0, + step: 1.0, }, - "delay": { - "type": "float", - "init": 0.2, - "min": 0.0, - "max": 1.0, - "step": 0.1 + delay: { + type: "float", + init: 0.2, + min: 0.0, + max: 1.0, + step: 0.1, + }, + pixelization: { + type: "float", + init: 1.0, + min: 1.0, + max: 3.0, + step: 1.0, }, - "pixelization": { - "type": "float", - "init": 1.0, - "min": 1.0, - "max": 3.0, - "step": 1.0 - } }, - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\nuniform float duration;\nuniform float delay;\nuniform float pixelization;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\n// https://www.aussiedwarf.com/2017/05/09/Random10Bit.html\nfloat rand(vec2 co){\n vec3 product = vec3( sin( dot(co, vec2(0.129898,0.78233))),\n sin( dot(co, vec2(0.689898,0.23233))),\n sin( dot(co, vec2(0.434198,0.51833))) );\n vec3 weighting = vec3(4.37585453723, 2.465973, 3.18438);\n return fract(dot(weighting, product));\n}\n\nvoid main() {\n float pixelated_resolution = 112.0 / pixelization;\n vec2 pixelated_uv = floor(uv * pixelated_resolution);\n float noise = (rand(pixelated_uv) + 1.0) / 2.0;\n float slope = (0.2 + noise * 0.8) * (1.0 - (0.0 + uv.x * 0.5));\n float time_interval = 1.1 + delay * 2.0;\n float progress = 0.2 + delay + slope - mod(time_interval * time / duration, time_interval);\n float mask = progress > 0.1 ? 1.0 : 0.0;\n vec4 pixel = texture2D(emote, vec2(uv.x * (progress > 0.5 ? 1.0 : progress * 2.0), 1.0 - uv.y));\n pixel.w = floor(pixel.w + 0.5);\n gl_FragColor = pixel * vec4(vec3(1.0), mask);\n}\n" - }, - "Ripple": { - "transparent": 0x00FF00 + "", - "duration": "2 * Math.PI / b", - "params": { - "a": { - "label": "Wave Length", - "type": "float", - "init": 12.0, - "min": 0.01, - "max": 24.0, - "step": 0.01 + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\nuniform float duration;\nuniform float delay;\nuniform float pixelization;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\n// https://www.aussiedwarf.com/2017/05/09/Random10Bit.html\nfloat rand(vec2 co){\n vec3 product = vec3( sin( dot(co, vec2(0.129898,0.78233))),\n sin( dot(co, vec2(0.689898,0.23233))),\n sin( dot(co, vec2(0.434198,0.51833))) );\n vec3 weighting = vec3(4.37585453723, 2.465973, 3.18438);\n return fract(dot(weighting, product));\n}\n\nvoid main() {\n float pixelated_resolution = 112.0 / pixelization;\n vec2 pixelated_uv = floor(uv * pixelated_resolution);\n float noise = (rand(pixelated_uv) + 1.0) / 2.0;\n float slope = (0.2 + noise * 0.8) * (1.0 - (0.0 + uv.x * 0.5));\n float time_interval = 1.1 + delay * 2.0;\n float progress = 0.2 + delay + slope - mod(time_interval * time / duration, time_interval);\n float mask = progress > 0.1 ? 1.0 : 0.0;\n vec4 pixel = texture2D(emote, vec2(uv.x * (progress > 0.5 ? 1.0 : progress * 2.0), 1.0 - uv.y));\n pixel.w = floor(pixel.w + 0.5);\n gl_FragColor = pixel * vec4(vec3(1.0), mask);\n}\n", + }, + Ripple: { + transparent: String(0x00FF00), + duration: "2 * Math.PI / b", + params: { + a: { + label: "Wave Length", + type: "float", + init: 12.0, + min: 0.01, + max: 24.0, + step: 0.01, }, - "b": { - "label": "Time Freq", - "type": "float", - "init": 4.0, - "min": 0.01, - "max": 8.0, - "step": 0.01 + b: { + label: "Time Freq", + type: "float", + init: 4.0, + min: 0.01, + max: 8.0, + step: 0.01, }, - "c": { - "label": "Amplitude", - "type": "float", - "init": 0.03, - "min": 0.01, - "max": 0.06, - "step": 0.01 + c: { + label: "Amplitude", + type: "float", + init: 0.03, + min: 0.01, + max: 0.06, + step: 0.01, } }, - "vertex": "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - "fragment": "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nuniform float a;\nuniform float b;\nuniform float c;\n\nvarying vec2 uv;\n\nvoid main() {\n vec2 pos = vec2(uv.x, 1.0 - uv.y);\n vec2 center = vec2(0.5);\n vec2 dir = pos - center;\n float x = length(dir);\n float y = sin(x + time);\n vec4 pixel = texture2D(emote, pos + cos(x*a - time*b)*c*(dir/x));\n gl_FragColor = pixel;\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" + vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", + fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nuniform float a;\nuniform float b;\nuniform float c;\n\nvarying vec2 uv;\n\nvoid main() {\n vec2 pos = vec2(uv.x, 1.0 - uv.y);\n vec2 center = vec2(0.5);\n vec2 dir = pos - center;\n float x = length(dir);\n float y = sin(x + time);\n vec4 pixel = texture2D(emote, pos + cos(x*a - time*b)*c*(dir/x));\n gl_FragColor = pixel;\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", } }; diff --git a/js/grecha.js b/js/grecha.js index 879ca3c..e7a983c 100644 --- a/js/grecha.js +++ b/js/grecha.js @@ -1,10 +1,13 @@ "use strict"; -var __spreadArray = (this && this.__spreadArray) || function (to, from) { - for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) - to[j] = from[i]; - return to; +var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { + if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { + if (ar || !(i in from)) { + if (!ar) ar = Array.prototype.slice.call(from, 0, i); + ar[i] = from[i]; + } + } + return to.concat(ar || Array.prototype.slice.call(from)); }; -var LOREM = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; function tag(name) { var children = []; for (var _i = 1; _i < arguments.length; _i++) { @@ -13,7 +16,7 @@ function tag(name) { var result = document.createElement(name); for (var _a = 0, children_1 = children; _a < children_1.length; _a++) { var child = children_1[_a]; - if (typeof (child) === 'string') { + if (typeof child === 'string') { result.appendChild(document.createTextNode(child)); } else { @@ -30,75 +33,71 @@ function tag(name) { }; return result; } -function canvas() { +var canvas = function () { var children = []; for (var _i = 0; _i < arguments.length; _i++) { children[_i] = arguments[_i]; } - return tag.apply(void 0, __spreadArray(["canvas"], children)); -} -function h1() { + return tag.apply(void 0, __spreadArray(["canvas"], children, false)); +}; +var h1 = function () { var children = []; for (var _i = 0; _i < arguments.length; _i++) { children[_i] = arguments[_i]; } - return tag.apply(void 0, __spreadArray(["h1"], children)); -} -function h2() { + return tag.apply(void 0, __spreadArray(["h1"], children, false)); +}; +var h2 = function () { var children = []; for (var _i = 0; _i < arguments.length; _i++) { children[_i] = arguments[_i]; } - return tag.apply(void 0, __spreadArray(["h2"], children)); -} -function h3() { + return tag.apply(void 0, __spreadArray(["h2"], children, false)); +}; +var h3 = function () { var children = []; for (var _i = 0; _i < arguments.length; _i++) { children[_i] = arguments[_i]; } - return tag.apply(void 0, __spreadArray(["h3"], children)); -} -function p() { + return tag.apply(void 0, __spreadArray(["h3"], children, false)); +}; +var p = function () { var children = []; for (var _i = 0; _i < arguments.length; _i++) { children[_i] = arguments[_i]; } - return tag.apply(void 0, __spreadArray(["p"], children)); -} -function a() { + return tag.apply(void 0, __spreadArray(["p"], children, false)); +}; +var a = function () { var children = []; for (var _i = 0; _i < arguments.length; _i++) { children[_i] = arguments[_i]; } - return tag.apply(void 0, __spreadArray(["a"], children)); -} -function div() { + return tag.apply(void 0, __spreadArray(["a"], children, false)); +}; +var div = function () { var children = []; for (var _i = 0; _i < arguments.length; _i++) { children[_i] = arguments[_i]; } - return tag.apply(void 0, __spreadArray(["div"], children)); -} -function span() { + return tag.apply(void 0, __spreadArray(["div"], children, false)); +}; +var span = function () { var children = []; for (var _i = 0; _i < arguments.length; _i++) { children[_i] = arguments[_i]; } - return tag.apply(void 0, __spreadArray(["span"], children)); -} -function select() { + return tag.apply(void 0, __spreadArray(["span"], children, false)); +}; +var select = function () { var children = []; for (var _i = 0; _i < arguments.length; _i++) { children[_i] = arguments[_i]; } - return tag.apply(void 0, __spreadArray(["select"], children)); -} -function img(src) { - return tag("img").att$("src", src); -} -function input(type) { - return tag("input").att$("type", type); -} + return tag.apply(void 0, __spreadArray(["select"], children, false)); +}; +var img = function (src) { return tag("img").att$("src", src); }; +var input = function (type) { return tag("input").att$("type", type); }; function router(routes) { var result = div(); function syncHash() { diff --git a/js/index.js b/js/index.js index 5d46558..f248be5 100644 --- a/js/index.js +++ b/js/index.js @@ -25,7 +25,7 @@ function compileShaderSource(gl, source, shaderType) { gl.shaderSource(shader, source); gl.compileShader(shader); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - throw new Error("Could not compile " + shaderTypeToString() + " shader: " + gl.getShaderInfoLog(shader)); + throw new Error("Could not compile ".concat(shaderTypeToString(), " shader: ").concat(gl.getShaderInfoLog(shader))); } return shader; } @@ -38,12 +38,13 @@ function linkShaderProgram(gl, shaders, vertexAttribs) { var shader = shaders_1[_i]; gl.attachShader(program, shader); } - for (var vertexName in vertexAttribs) { - gl.bindAttribLocation(program, vertexAttribs[vertexName], vertexName); + for (var _a = 0, _b = Object.entries(vertexAttribs); _a < _b.length; _a++) { + var _c = _b[_a], vertexName = _c[0], vertexVal = _c[1]; + gl.bindAttribLocation(program, vertexVal, vertexName); } gl.linkProgram(program); if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - throw new Error("Could not link shader program: " + gl.getProgramInfoLog(program)); + throw new Error("Could not link shader program: ".concat(gl.getProgramInfoLog(program))); } return program; } @@ -69,74 +70,77 @@ function loadFilterProgram(gl, filter, vertexAttribs) { gl.deleteShader(fragmentShader); gl.useProgram(id); var uniforms = { - "resolution": gl.getUniformLocation(id, 'resolution'), - "time": gl.getUniformLocation(id, 'time'), - "emoteSize": gl.getUniformLocation(id, 'emoteSize') + resolution: gl.getUniformLocation(id, 'resolution'), + time: gl.getUniformLocation(id, 'time'), + emoteSize: gl.getUniformLocation(id, 'emoteSize'), }; var paramsPanel = div().att$("class", "widget-element"); var paramsInputs = {}; - var _loop_1 = function (paramName) { + if (!filter.params) + throw new Error("unknown error"); + var _loop_1 = function (paramName, paramVal) { if (paramName in uniforms) { - throw new Error("Redefinition of existing uniform parameter " + paramName); + throw new Error("Redefinition of existing uniform parameter ".concat(paramName)); } - switch (filter.params[paramName].type) { + switch (paramVal.type) { case "float": { - var valuePreview_1 = span(filter.params[paramName].init.toString()); + var valuePreview_1 = span(paramVal.init.toString()); var valueInput = input("range"); - if (filter.params[paramName].min !== undefined) { - valueInput.att$("min", filter.params[paramName].min); + if (paramVal.min !== undefined) { + valueInput.att$("min", String(paramVal.min)); } - if (filter.params[paramName].max !== undefined) { - valueInput.att$("max", filter.params[paramName].max); + if (paramVal.max !== undefined) { + valueInput.att$("max", String(paramVal.max)); } - if (filter.params[paramName].step !== undefined) { - valueInput.att$("step", filter.params[paramName].step); + if (paramVal.step !== undefined) { + valueInput.att$("step", String(paramVal.step)); } - if (filter.params[paramName].init !== undefined) { - valueInput.att$("value", filter.params[paramName].init); + if (paramVal.init !== undefined) { + valueInput.att$("value", String(paramVal.init)); } paramsInputs[paramName] = valueInput; valueInput.oninput = function () { valuePreview_1.innerText = this.value; paramsPanel.dispatchEvent(new CustomEvent("paramsChanged")); }; - var label = (_a = filter.params[paramName].label) !== null && _a !== void 0 ? _a : paramName; - paramsPanel.appendChild(div(span(label + ": "), valuePreview_1, div(valueInput))); + var label = (_a = paramVal.label) !== null && _a !== void 0 ? _a : paramName; + paramsPanel.appendChild(div(span("".concat(label, ": ")), valuePreview_1, div(valueInput))); } break; default: { - throw new Error("Filter parameters do not support type " + filter.params[paramName].type); + throw new Error("Filter parameters do not support type ".concat(paramVal.type)); } } uniforms[paramName] = gl.getUniformLocation(id, paramName); }; - for (var paramName in filter.params) { - _loop_1(paramName); + for (var _i = 0, _b = Object.entries(filter.params); _i < _b.length; _i++) { + var _c = _b[_i], paramName = _c[0], paramVal = _c[1]; + _loop_1(paramName, paramVal); } paramsPanel.paramsSnapshot$ = function () { var snapshot = {}; for (var paramName in paramsInputs) { snapshot[paramName] = { - "uniform": uniforms[paramName], - "value": Number(paramsInputs[paramName].value) + uniform: uniforms[paramName], + value: Number(paramsInputs[paramName].value) }; } return snapshot; }; return { - "id": id, - "uniforms": uniforms, - "duration": compile_expr(filter.duration), - "transparent": filter.transparent, - "paramsPanel": paramsPanel + id: id, + uniforms: uniforms, + duration: compile_expr(filter.duration), + transparent: filter.transparent, + paramsPanel: paramsPanel, }; } function ImageSelector() { var imageInput = input("file"); var imagePreview = img("img/tsodinClown.png") .att$("class", "widget-element") - .att$("width", CANVAS_WIDTH); + .att$("width", String(CANVAS_WIDTH)); var root = div(div(imageInput).att$("class", "widget-element"), imagePreview).att$("class", "widget"); root.selectedImage$ = function () { return imagePreview; @@ -154,8 +158,9 @@ function ImageSelector() { return file ? removeFileNameExt(file.name) : 'result'; }; root.updateFiles$ = function (files) { + var _a; imageInput.files = files; - imageInput.onchange(); + (_a = imageInput.onchange) === null || _a === void 0 ? void 0 : _a.call(imageInput); }; imagePreview.addEventListener('load', function () { root.dispatchEvent(new CustomEvent("imageSelected", { @@ -189,6 +194,7 @@ function FilterList() { })); }; root.addEventListener('wheel', function (e) { + var _a; e.preventDefault(); if (e.deltaY < 0) { root.selectedIndex = Math.max(root.selectedIndex - 1, 0); @@ -196,42 +202,40 @@ function FilterList() { if (e.deltaY > 0) { root.selectedIndex = Math.min(root.selectedIndex + 1, root.length - 1); } - root.onchange(); + (_a = root.onchange) === null || _a === void 0 ? void 0 : _a.call(root); }); return root; } function FilterSelector() { var filterList_ = FilterList(); var filterPreview = canvas() - .att$("width", CANVAS_WIDTH) - .att$("height", CANVAS_HEIGHT); + .att$("width", String(CANVAS_WIDTH)) + .att$("height", String(CANVAS_HEIGHT)); var root = div(div("Filter: ", filterList_) .att$("class", "widget-element"), filterPreview.att$("class", "widget-element")).att$("class", "widget"); var gl = filterPreview.getContext("webgl", { antialias: false, alpha: false }); if (!gl) { throw new Error("Could not initialize WebGL context"); } + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); { - gl.enable(gl.BLEND); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); - { - var meshPositionBufferData = new Float32Array(TRIANGLE_PAIR * TRIANGLE_VERTICIES * VEC2_COUNT); - for (var triangle = 0; triangle < TRIANGLE_PAIR; ++triangle) { - for (var vertex = 0; vertex < TRIANGLE_VERTICIES; ++vertex) { - var quad = triangle + vertex; - var index = triangle * TRIANGLE_VERTICIES * VEC2_COUNT + - vertex * VEC2_COUNT; - meshPositionBufferData[index + VEC2_X] = (2 * (quad & 1) - 1); - meshPositionBufferData[index + VEC2_Y] = (2 * ((quad >> 1) & 1) - 1); - } + var meshPositionBufferData = new Float32Array(TRIANGLE_PAIR * TRIANGLE_VERTICIES * VEC2_COUNT); + for (var triangle = 0; triangle < TRIANGLE_PAIR; ++triangle) { + for (var vertex = 0; vertex < TRIANGLE_VERTICIES; ++vertex) { + var quad = triangle + vertex; + var index = triangle * TRIANGLE_VERTICIES * VEC2_COUNT + + vertex * VEC2_COUNT; + meshPositionBufferData[index + VEC2_X] = (2 * (quad & 1) - 1); + meshPositionBufferData[index + VEC2_Y] = (2 * ((quad >> 1) & 1) - 1); } - var meshPositionBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, meshPositionBuffer); - gl.bufferData(gl.ARRAY_BUFFER, meshPositionBufferData, gl.STATIC_DRAW); - var meshPositionAttrib = vertexAttribs['meshPosition']; - gl.vertexAttribPointer(meshPositionAttrib, VEC2_COUNT, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(meshPositionAttrib); } + var meshPositionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, meshPositionBuffer); + gl.bufferData(gl.ARRAY_BUFFER, meshPositionBufferData, gl.STATIC_DRAW); + var meshPositionAttrib = vertexAttribs['meshPosition']; + gl.vertexAttribPointer(meshPositionAttrib, VEC2_COUNT, gl.FLOAT, false, 0, 0); + gl.enableVertexAttribArray(meshPositionAttrib); } var emoteImage = undefined; var emoteTexture = undefined; @@ -286,10 +290,10 @@ function FilterSelector() { quality: 10, width: CANVAS_WIDTH, height: CANVAS_HEIGHT, - transparent: program.transparent + transparent: program.transparent, }); var context = { - "vars": { + vars: { "Math.PI": Math.PI } }; @@ -346,9 +350,9 @@ function FilterSelector() { } gif.addFrame(new ImageData(pixels, CANVAS_WIDTH, CANVAS_HEIGHT), { delay: dt * 1000, - dispose: 2 + dispose: 2, }); - renderProgress.style.width = (t / duration) * 50 + "%"; + renderProgress.style.width = "".concat((t / duration) * 50, "%"); t += dt; } gif.on('finished', function (blob) { @@ -360,7 +364,7 @@ function FilterSelector() { renderSpinner.style.display = "none"; }); gif.on('progress', function (p) { - renderProgress.style.width = 50 + p * 50 + "%"; + renderProgress.style.width = "".concat(50 + p * 50, "%"); }); gif.render(); return gif; @@ -422,10 +426,10 @@ window.onload = function () { throw new Error('Could not find "render"'); } renderButton.onclick = function () { - if (gif && gif.running) { + if (gif === null || gif === void 0 ? void 0 : gif.running) { gif.abort(); } var fileName = imageSelector.selectedFileName$(); - gif = filterSelector.render$(fileName + ".gif"); + gif = filterSelector.render$("".concat(fileName, ".gif")); }; }; diff --git a/package-lock.json b/package-lock.json index 6de1ed3..b6ac677 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,73 +9,1318 @@ "version": "1.0.0", "license": "MIT", "devDependencies": { - "@types/gif.js": "^0.2.1", - "@types/node": "^20.9.3", - "typescript": "^4.3.2" + "@types/gif.js": "^0.2.5", + "@types/node": "^22", + "typescript": "^5.5", + "vite": "^5.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=12" + } + }, + "node_modules/@rollup/rollup-android-arm-eabi": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz", + "integrity": "sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-android-arm64": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.20.0.tgz", + "integrity": "sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ] + }, + "node_modules/@rollup/rollup-darwin-arm64": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.20.0.tgz", + "integrity": "sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-darwin-x64": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.20.0.tgz", + "integrity": "sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.20.0.tgz", + "integrity": "sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm-musleabihf": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.20.0.tgz", + "integrity": "sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.20.0.tgz", + "integrity": "sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-arm64-musl": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.20.0.tgz", + "integrity": "sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.20.0.tgz", + "integrity": "sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-riscv64-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.20.0.tgz", + "integrity": "sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-s390x-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.20.0.tgz", + "integrity": "sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.20.0.tgz", + "integrity": "sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-x64-musl": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.20.0.tgz", + "integrity": "sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-win32-arm64-msvc": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.20.0.tgz", + "integrity": "sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-ia32-msvc": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.20.0.tgz", + "integrity": "sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@rollup/rollup-win32-x64-msvc": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.20.0.tgz", + "integrity": "sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/events": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.3.tgz", + "integrity": "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/gif.js": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@types/gif.js/-/gif.js-0.2.1.tgz", - "integrity": "sha512-oZAPX8pgueiAngu3HfynjdtsDNt4EiD1fs5An//LtBKvOdnc4Wq8/S7GkAKpP80+29WyVwGEGVEUXPyFhbQ2+g==", - "dev": true + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@types/gif.js/-/gif.js-0.2.5.tgz", + "integrity": "sha512-OdDQYh9v7td9ztjaooBSqjUBAyAuui2xwDDmQcyRLd6c9T0iWgkebAoCBEdEEBoZG3ekJE/6UnH63Dzq0S3bvw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/events": "*" + } }, "node_modules/@types/node": { - "version": "20.9.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.3.tgz", - "integrity": "sha512-nk5wXLAXGBKfrhLB0cyHGbSqopS+nz0BUgZkUQqSHSSgdee0kssp1IAqlQOu333bW+gMNs2QREx7iynm19Abxw==", + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", "dev": true, + "license": "MIT", "dependencies": { - "undici-types": "~5.26.4" + "undici-types": "~6.18.2" + } + }, + "node_modules/esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true, + "license": "ISC" + }, + "node_modules/postcss": { + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/rollup": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.20.0.tgz", + "integrity": "sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "1.0.5" + }, + "bin": { + "rollup": "dist/bin/rollup" + }, + "engines": { + "node": ">=18.0.0", + "npm": ">=8.0.0" + }, + "optionalDependencies": { + "@rollup/rollup-android-arm-eabi": "4.20.0", + "@rollup/rollup-android-arm64": "4.20.0", + "@rollup/rollup-darwin-arm64": "4.20.0", + "@rollup/rollup-darwin-x64": "4.20.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.20.0", + "@rollup/rollup-linux-arm-musleabihf": "4.20.0", + "@rollup/rollup-linux-arm64-gnu": "4.20.0", + "@rollup/rollup-linux-arm64-musl": "4.20.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.20.0", + "@rollup/rollup-linux-riscv64-gnu": "4.20.0", + "@rollup/rollup-linux-s390x-gnu": "4.20.0", + "@rollup/rollup-linux-x64-gnu": "4.20.0", + "@rollup/rollup-linux-x64-musl": "4.20.0", + "@rollup/rollup-win32-arm64-msvc": "4.20.0", + "@rollup/rollup-win32-ia32-msvc": "4.20.0", + "@rollup/rollup-win32-x64-msvc": "4.20.0", + "fsevents": "~2.3.2" + } + }, + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.10.0" } }, "node_modules/typescript": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", - "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true, + "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" }, "engines": { - "node": ">=4.2.0" + "node": ">=14.17" } }, "node_modules/undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", - "dev": true + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/vite": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", + "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "^0.21.3", + "postcss": "^8.4.40", + "rollup": "^4.13.0" + }, + "bin": { + "vite": "bin/vite.js" + }, + "engines": { + "node": "^18.0.0 || >=20.0.0" + }, + "funding": { + "url": "https://github.com/vitejs/vite?sponsor=1" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + }, + "peerDependencies": { + "@types/node": "^18.0.0 || >=20.0.0", + "less": "*", + "lightningcss": "^1.21.0", + "sass": "*", + "sass-embedded": "*", + "stylus": "*", + "sugarss": "*", + "terser": "^5.4.0" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + }, + "less": { + "optional": true + }, + "lightningcss": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + }, + "stylus": { + "optional": true + }, + "sugarss": { + "optional": true + }, + "terser": { + "optional": true + } + } } }, "dependencies": { - "@types/gif.js": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/@types/gif.js/-/gif.js-0.2.1.tgz", - "integrity": "sha512-oZAPX8pgueiAngu3HfynjdtsDNt4EiD1fs5An//LtBKvOdnc4Wq8/S7GkAKpP80+29WyVwGEGVEUXPyFhbQ2+g==", + "@esbuild/aix-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", + "integrity": "sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.21.5.tgz", + "integrity": "sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==", + "dev": true, + "optional": true + }, + "@esbuild/android-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.21.5.tgz", + "integrity": "sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==", + "dev": true, + "optional": true + }, + "@esbuild/android-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.21.5.tgz", + "integrity": "sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.21.5.tgz", + "integrity": "sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==", + "dev": true, + "optional": true + }, + "@esbuild/darwin-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.21.5.tgz", + "integrity": "sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.21.5.tgz", + "integrity": "sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==", + "dev": true, + "optional": true + }, + "@esbuild/freebsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.21.5.tgz", + "integrity": "sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.21.5.tgz", + "integrity": "sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.21.5.tgz", + "integrity": "sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.21.5.tgz", + "integrity": "sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-loong64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.21.5.tgz", + "integrity": "sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-mips64el": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.21.5.tgz", + "integrity": "sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==", + "dev": true, + "optional": true + }, + "@esbuild/linux-ppc64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.21.5.tgz", + "integrity": "sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==", + "dev": true, + "optional": true + }, + "@esbuild/linux-riscv64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.21.5.tgz", + "integrity": "sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==", + "dev": true, + "optional": true + }, + "@esbuild/linux-s390x": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.21.5.tgz", + "integrity": "sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==", + "dev": true, + "optional": true + }, + "@esbuild/linux-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.21.5.tgz", + "integrity": "sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==", + "dev": true, + "optional": true + }, + "@esbuild/netbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.21.5.tgz", + "integrity": "sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==", + "dev": true, + "optional": true + }, + "@esbuild/openbsd-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.21.5.tgz", + "integrity": "sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==", + "dev": true, + "optional": true + }, + "@esbuild/sunos-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.21.5.tgz", + "integrity": "sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==", + "dev": true, + "optional": true + }, + "@esbuild/win32-arm64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.21.5.tgz", + "integrity": "sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==", + "dev": true, + "optional": true + }, + "@esbuild/win32-ia32": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.21.5.tgz", + "integrity": "sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==", + "dev": true, + "optional": true + }, + "@esbuild/win32-x64": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.21.5.tgz", + "integrity": "sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm-eabi": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.20.0.tgz", + "integrity": "sha512-TSpWzflCc4VGAUJZlPpgAJE1+V60MePDQnBd7PPkpuEmOy8i87aL6tinFGKBFKuEDikYpig72QzdT3QPYIi+oA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-android-arm64": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.20.0.tgz", + "integrity": "sha512-u00Ro/nok7oGzVuh/FMYfNoGqxU5CPWz1mxV85S2w9LxHR8OoMQBuSk+3BKVIDYgkpeOET5yXkx90OYFc+ytpQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-arm64": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.20.0.tgz", + "integrity": "sha512-uFVfvzvsdGtlSLuL0ZlvPJvl6ZmrH4CBwLGEFPe7hUmf7htGAN+aXo43R/V6LATyxlKVC/m6UsLb7jbG+LG39Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-darwin-x64": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.20.0.tgz", + "integrity": "sha512-xbrMDdlev53vNXexEa6l0LffojxhqDTBeL+VUxuuIXys4x6xyvbKq5XqTXBCEUA8ty8iEJblHvFaWRJTk/icAQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-gnueabihf": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.20.0.tgz", + "integrity": "sha512-jMYvxZwGmoHFBTbr12Xc6wOdc2xA5tF5F2q6t7Rcfab68TT0n+r7dgawD4qhPEvasDsVpQi+MgDzj2faOLsZjA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm-musleabihf": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.20.0.tgz", + "integrity": "sha512-1asSTl4HKuIHIB1GcdFHNNZhxAYEdqML/MW4QmPS4G0ivbEcBr1JKlFLKsIRqjSwOBkdItn3/ZDlyvZ/N6KPlw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.20.0.tgz", + "integrity": "sha512-COBb8Bkx56KldOYJfMf6wKeYJrtJ9vEgBRAOkfw6Ens0tnmzPqvlpjZiLgkhg6cA3DGzCmLmmd319pmHvKWWlQ==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-arm64-musl": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.20.0.tgz", + "integrity": "sha512-+it+mBSyMslVQa8wSPvBx53fYuZK/oLTu5RJoXogjk6x7Q7sz1GNRsXWjn6SwyJm8E/oMjNVwPhmNdIjwP135Q==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-powerpc64le-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.20.0.tgz", + "integrity": "sha512-yAMvqhPfGKsAxHN8I4+jE0CpLWD8cv4z7CK7BMmhjDuz606Q2tFKkWRY8bHR9JQXYcoLfopo5TTqzxgPUjUMfw==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-riscv64-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.20.0.tgz", + "integrity": "sha512-qmuxFpfmi/2SUkAw95TtNq/w/I7Gpjurx609OOOV7U4vhvUhBcftcmXwl3rqAek+ADBwSjIC4IVNLiszoj3dPA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-s390x-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.20.0.tgz", + "integrity": "sha512-I0BtGXddHSHjV1mqTNkgUZLnS3WtsqebAXv11D5BZE/gfw5KoyXSAXVqyJximQXNvNzUo4GKlCK/dIwXlz+jlg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-gnu": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.20.0.tgz", + "integrity": "sha512-y+eoL2I3iphUg9tN9GB6ku1FA8kOfmF4oUEWhztDJ4KXJy1agk/9+pejOuZkNFhRwHAOxMsBPLbXPd6mJiCwew==", + "dev": true, + "optional": true + }, + "@rollup/rollup-linux-x64-musl": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.20.0.tgz", + "integrity": "sha512-hM3nhW40kBNYUkZb/r9k2FKK+/MnKglX7UYd4ZUy5DJs8/sMsIbqWK2piZtVGE3kcXVNj3B2IrUYROJMMCikNg==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-arm64-msvc": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.20.0.tgz", + "integrity": "sha512-psegMvP+Ik/Bg7QRJbv8w8PAytPA7Uo8fpFjXyCRHWm6Nt42L+JtoqH8eDQ5hRP7/XW2UiIriy1Z46jf0Oa1kA==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-ia32-msvc": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.20.0.tgz", + "integrity": "sha512-GabekH3w4lgAJpVxkk7hUzUf2hICSQO0a/BLFA11/RMxQT92MabKAqyubzDZmMOC/hcJNlc+rrypzNzYl4Dx7A==", + "dev": true, + "optional": true + }, + "@rollup/rollup-win32-x64-msvc": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.20.0.tgz", + "integrity": "sha512-aJ1EJSuTdGnM6qbVC4B5DSmozPTqIag9fSzXRNNo+humQLG89XpPgdt16Ia56ORD7s+H8Pmyx44uczDQ0yDzpg==", + "dev": true, + "optional": true + }, + "@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, + "@types/events": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.3.tgz", + "integrity": "sha512-trOc4AAUThEz9hapPtSd7wf5tiQKvTtu5b371UxXdTuqzIh0ArcRspRP0i0Viu+LXstIQ1z96t1nsPxT9ol01g==", + "dev": true + }, + "@types/gif.js": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/@types/gif.js/-/gif.js-0.2.5.tgz", + "integrity": "sha512-OdDQYh9v7td9ztjaooBSqjUBAyAuui2xwDDmQcyRLd6c9T0iWgkebAoCBEdEEBoZG3ekJE/6UnH63Dzq0S3bvw==", + "dev": true, + "requires": { + "@types/events": "*" + } + }, "@types/node": { - "version": "20.9.3", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.3.tgz", - "integrity": "sha512-nk5wXLAXGBKfrhLB0cyHGbSqopS+nz0BUgZkUQqSHSSgdee0kssp1IAqlQOu333bW+gMNs2QREx7iynm19Abxw==", + "version": "22.3.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-22.3.0.tgz", + "integrity": "sha512-nrWpWVaDZuaVc5X84xJ0vNrLvomM205oQyLsRt7OHNZbSHslcWsvgFR7O7hire2ZonjLrWBbedmotmIlJDVd6g==", + "dev": true, + "requires": { + "undici-types": "~6.18.2" + } + }, + "esbuild": { + "version": "0.21.5", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", + "integrity": "sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==", + "dev": true, + "requires": { + "@esbuild/aix-ppc64": "0.21.5", + "@esbuild/android-arm": "0.21.5", + "@esbuild/android-arm64": "0.21.5", + "@esbuild/android-x64": "0.21.5", + "@esbuild/darwin-arm64": "0.21.5", + "@esbuild/darwin-x64": "0.21.5", + "@esbuild/freebsd-arm64": "0.21.5", + "@esbuild/freebsd-x64": "0.21.5", + "@esbuild/linux-arm": "0.21.5", + "@esbuild/linux-arm64": "0.21.5", + "@esbuild/linux-ia32": "0.21.5", + "@esbuild/linux-loong64": "0.21.5", + "@esbuild/linux-mips64el": "0.21.5", + "@esbuild/linux-ppc64": "0.21.5", + "@esbuild/linux-riscv64": "0.21.5", + "@esbuild/linux-s390x": "0.21.5", + "@esbuild/linux-x64": "0.21.5", + "@esbuild/netbsd-x64": "0.21.5", + "@esbuild/openbsd-x64": "0.21.5", + "@esbuild/sunos-x64": "0.21.5", + "@esbuild/win32-arm64": "0.21.5", + "@esbuild/win32-ia32": "0.21.5", + "@esbuild/win32-x64": "0.21.5" + } + }, + "fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "optional": true + }, + "nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true + }, + "picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true + }, + "postcss": { + "version": "8.4.41", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.41.tgz", + "integrity": "sha512-TesUflQ0WKZqAvg52PWL6kHgLKP6xB6heTOdoYM0Wt2UHyxNa4K25EZZMgKns3BH1RLVbZCREPpLY0rhnNoHVQ==", "dev": true, "requires": { - "undici-types": "~5.26.4" + "nanoid": "^3.3.7", + "picocolors": "^1.0.1", + "source-map-js": "^1.2.0" } }, + "rollup": { + "version": "4.20.0", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.20.0.tgz", + "integrity": "sha512-6rbWBChcnSGzIlXeIdNIZTopKYad8ZG8ajhl78lGRLsI2rX8IkaotQhVas2Ma+GPxJav19wrSzvRvuiv0YKzWw==", + "dev": true, + "requires": { + "@rollup/rollup-android-arm-eabi": "4.20.0", + "@rollup/rollup-android-arm64": "4.20.0", + "@rollup/rollup-darwin-arm64": "4.20.0", + "@rollup/rollup-darwin-x64": "4.20.0", + "@rollup/rollup-linux-arm-gnueabihf": "4.20.0", + "@rollup/rollup-linux-arm-musleabihf": "4.20.0", + "@rollup/rollup-linux-arm64-gnu": "4.20.0", + "@rollup/rollup-linux-arm64-musl": "4.20.0", + "@rollup/rollup-linux-powerpc64le-gnu": "4.20.0", + "@rollup/rollup-linux-riscv64-gnu": "4.20.0", + "@rollup/rollup-linux-s390x-gnu": "4.20.0", + "@rollup/rollup-linux-x64-gnu": "4.20.0", + "@rollup/rollup-linux-x64-musl": "4.20.0", + "@rollup/rollup-win32-arm64-msvc": "4.20.0", + "@rollup/rollup-win32-ia32-msvc": "4.20.0", + "@rollup/rollup-win32-x64-msvc": "4.20.0", + "@types/estree": "1.0.5", + "fsevents": "~2.3.2" + } + }, + "source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", + "dev": true + }, "typescript": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.3.2.tgz", - "integrity": "sha512-zZ4hShnmnoVnAHpVHWpTcxdv7dWP60S2FsydQLV8V5PbS3FifjWFFRiHSWpDJahly88PRyV5teTSLoq4eG7mKw==", + "version": "5.5.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.5.4.tgz", + "integrity": "sha512-Mtq29sKDAEYP7aljRgtPOpTvOfbwRWlS6dPRzwjdE+C0R4brX/GUyhHSecbHMFLNBLcJIPt9nl9yG5TZ1weH+Q==", "dev": true }, "undici-types": { - "version": "5.26.5", - "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", - "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "version": "6.18.2", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.18.2.tgz", + "integrity": "sha512-5ruQbENj95yDYJNS3TvcaxPMshV7aizdv/hWYjGIKoANWKjhWNBsr2YEuYZKodQulB1b8l7ILOuDQep3afowQQ==", "dev": true + }, + "vite": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/vite/-/vite-5.4.0.tgz", + "integrity": "sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==", + "dev": true, + "requires": { + "esbuild": "^0.21.3", + "fsevents": "~2.3.3", + "postcss": "^8.4.40", + "rollup": "^4.13.0" + } } } } diff --git a/package.json b/package.json index a56e15a..ed25420 100644 --- a/package.json +++ b/package.json @@ -30,8 +30,9 @@ }, "homepage": "https://github.com/tsoding/emoteJAM#readme", "devDependencies": { - "@types/gif.js": "^0.2.1", - "@types/node": "^20.9.3", - "typescript": "^4.3.2" + "@types/gif.js": "^0.2.5", + "@types/node": "^22", + "typescript": "^5.5", + "vite": "^5.4.0" } } diff --git a/serviceworker.js b/serviceworker.js index 2360621..cf49771 100644 --- a/serviceworker.js +++ b/serviceworker.js @@ -14,7 +14,7 @@ var __generator = (this && this.__generator) || function (thisArg, body) { function verb(n) { return function (v) { return step([n, v]); }; } function step(op) { if (f) throw new TypeError("Generator is already executing."); - while (_) try { + while (g && (g = 0, op[0] && (_ = 0)), _) try { if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; if (y = 0, t) op = [op[0] & 2, t.value]; switch (op[0]) { @@ -71,27 +71,30 @@ self.addEventListener("activate", function (e) { console.log("[Service Worker] Activate"); var event = e; event.waitUntil((function () { return __awaiter(void 0, void 0, void 0, function () { - var keys, _a, _b, _i, key; - return __generator(this, function (_c) { - switch (_c.label) { + var keys, _a, _b, _c, _i, key; + return __generator(this, function (_d) { + switch (_d.label) { case 0: console.log("[Service Worker] Cleaning up all caches"); return [4, caches.keys()]; case 1: - keys = _c.sent(); - _a = []; - for (_b in keys) - _a.push(_b); + keys = _d.sent(); + _a = keys; + _b = []; + for (_c in _a) + _b.push(_c); _i = 0; - _c.label = 2; + _d.label = 2; case 2: - if (!(_i < _a.length)) return [3, 5]; - key = _a[_i]; + if (!(_i < _b.length)) return [3, 5]; + _c = _b[_i]; + if (!(_c in _a)) return [3, 4]; + key = _c; if (!(key !== cacheName)) return [3, 4]; - return [4, caches["delete"](key)]; + return [4, caches.delete(key)]; case 3: - _c.sent(); - _c.label = 4; + _d.sent(); + _d.label = 4; case 4: _i++; return [3, 2]; @@ -107,7 +110,7 @@ self.addEventListener("fetch", function (e) { return __generator(this, function (_a) { switch (_a.label) { case 0: - console.log("[Service Worker] Fetch " + event.request.url); + console.log("[Service Worker] Fetch ".concat(event.request.url)); return [4, caches.open(cacheName)]; case 1: cache = _a.sent(); @@ -115,7 +118,7 @@ self.addEventListener("fetch", function (e) { case 2: response = _a.sent(); if (!(response === undefined)) return [3, 4]; - console.log("[Service Worker] Response for " + event.request.url + " is not available in cache. Making an actual request..."); + console.log("[Service Worker] Response for ".concat(event.request.url, " is not available in cache. Making an actual request...")); return [4, fetch(event.request.url)]; case 3: response = _a.sent(); diff --git a/ts/eval.ts b/ts/eval.ts index 5ccc100..c134761 100644 --- a/ts/eval.ts +++ b/ts/eval.ts @@ -5,14 +5,14 @@ enum BinaryPrec { PREC0 = 0, PREC1, COUNT_PRECS -} +}; interface BinaryOpDef { func: BinaryOpFunc, prec: BinaryPrec } -const BINARY_OPS: {[op in BinaryOp]: BinaryOpDef} = { +const BINARY_OPS: Record = { '+': { func: (lhs, rhs) => lhs + rhs, prec: BinaryPrec.PREC0 @@ -38,7 +38,7 @@ const BINARY_OPS: {[op in BinaryOp]: BinaryOpDef} = { type UnaryOp = '-'; type UnaryOpFunc = (arg: number) => number; -const UNARY_OPS: {[op in UnaryOp]: UnaryOpFunc} = { +const UNARY_OPS: Record = { '-': (arg: number) => -arg, }; @@ -65,14 +65,14 @@ class Lexer { return c in BINARY_OPS || c in UNARY_OPS || syntax.includes(c); } - if (is_token_break(this.src[0])) { - const token = this.src[0]; + if (is_token_break(this.src[0]!)) { + const token = this.src[0]!; this.src = this.src.slice(1); return token; } for (let i = 0; i < this.src.length; ++i) { - if (is_token_break(this.src[i]) || this.src[i] == ' ') { + if (is_token_break(this.src[i]!) || this.src[i] == ' ') { const token = this.src.slice(0, i); this.src = this.src.slice(i); return token; @@ -100,7 +100,7 @@ interface BinaryOpExpr { interface FuncallExpr { name: string, - args: Array, + args: Expr[], } interface SymbolExpr { @@ -136,15 +136,15 @@ function parse_primary(lexer: Lexer): Expr { } else { let next_token = lexer.next(); if (next_token === '(') { - const args: Array = []; + const args: Expr[] = []; next_token = lexer.next(); if (next_token === ')') { return { - "kind": "funcall", - "payload": { - "name": token, - "args": args, + kind: "funcall", + payload: { + name: token, + args: args, } }; } @@ -167,10 +167,10 @@ function parse_primary(lexer: Lexer): Expr { } return { - "kind": "funcall", - "payload": { - "name": token, - "args": args, + kind: "funcall", + payload: { + name: token, + args: args, } }; } else { @@ -178,9 +178,9 @@ function parse_primary(lexer: Lexer): Expr { lexer.unnext(next_token); } return { - "kind": "symbol", - "payload": { - "value": token + kind: "symbol", + payload: { + value: token } }; } @@ -202,11 +202,11 @@ function parse_expr(lexer: Lexer, prec: BinaryPrec = BinaryPrec.PREC0): Expr { if (op_token in BINARY_OPS && BINARY_OPS[op_token as BinaryOp].prec == prec) { let rhs = parse_expr(lexer, prec); return { - "kind": "binary_op", - "payload": { - "op": op_token as BinaryOp, - "lhs": lhs, - "rhs": rhs, + kind: "binary_op", + payload: { + op: op_token as BinaryOp, + lhs, + rhs, } }; } else { @@ -230,8 +230,8 @@ function compile_expr(src: string): Expr { } interface UserContext { - vars?: {[name: string]: number}, - funcs?: {[name: string]: (...xs: number[]) => number}, + vars?: Record, + funcs?: Record number>, } function run_expr(expr: Expr, user_context: UserContext = {}): number { @@ -244,7 +244,7 @@ function run_expr(expr: Expr, user_context: UserContext = {}): number { const number = Number(value); if (isNaN(number)) { if (user_context.vars && value in user_context.vars) { - return user_context.vars[value]; + return user_context.vars[value]!; } throw new Error(`Unknown variable '${value}'`); @@ -279,7 +279,7 @@ function run_expr(expr: Expr, user_context: UserContext = {}): number { const funcall = expr.payload as FuncallExpr; if (user_context.funcs && funcall.name in user_context.funcs) { - return user_context.funcs[funcall.name](...funcall.args.map((arg) => run_expr(arg, user_context))); + return user_context.funcs[funcall.name]!(...funcall.args.map((arg) => run_expr(arg, user_context))); } throw new Error(`Unknown function '${funcall.name}'`); diff --git a/ts/filters.ts b/ts/filters.ts index 0351601..4d51526 100644 --- a/ts/filters.ts +++ b/ts/filters.ts @@ -1,4 +1,4 @@ -interface Param { +type Param = { label?: string, type: string, init: number, @@ -7,69 +7,69 @@ interface Param { step?: number, } -interface Filter { +type Filter = { transparent: string | null, duration: string, - params?: { - [name: string]: Param - }, + params?: Record, vertex: string, fragment: string } +type FilterType = "Hop" | "Hopper" | "Overheat" | "Bounce" | "Circle" | "Slide" | "Laughing" | "Blob" | "Go" | "Elevator" | "Rain" | "Pride" | "Hard" | "Peek" | "Matrix" | "Flag" | "Thanosed" | "Ripple"; + // TODO(#58): add params to all of the filters // TODO(#61): human readable titles for the filter params -const filters: {[name: string]: Filter} = { - "Hop": { - "transparent": 0x00FF00 + "", - "duration": "interval * 2", +const filters: Record = { + Hop: { + transparent: String(0x00FF00), + duration: "interval * 2", // TODO(#62): when you have too many params the UI gets really cluttered - "params": { + params: { // TODO(#65): filter params should have help tooltips associated with them - "interval": { - "label": "Interval", - "type": "float", - "init": 0.85, - "min": 0.01, - "max": 2.00, - "step": 0.01, + interval: { + label: "Interval", + type: "float", + init: 0.85, + min: 0.01, + max: 2.00, + step: 0.01, }, - "ground": { - "label": "Ground", - "type": "float", - "init": 0.5, - "min": -1.0, - "max": 1.0, - "step": 0.01, + ground: { + label: "Ground", + type: "float", + init: 0.5, + min: -1.0, + max: 1.0, + step: 0.01, }, - "scale": { - "label": "Scale", - "type": "float", - "init": 0.40, - "min": 0.0, - "max": 1.0, - "step": 0.01, + scale: { + label: "Scale", + type: "float", + init: 0.40, + min: 0.0, + max: 1.0, + step: 0.01, }, // TODO(#63): jump_height in the "Hop" filter does not make any sense // If it's bigger the emote should jump higher. Right now it is the other way around. - "jump_height": { - "label": "Jump Height", - "type": "float", - "init": 4.0, - "min": 1.0, - "max": 10.0, - "step": 0.01, + jump_height: { + label: "Jump Height", + type: "float", + init: 4.0, + min: 1.0, + max: 10.0, + step: 0.01, }, - "hops": { - "label": "Hops Count", - "type": "float", - "init": 2.0, - "min": 1.0, - "max": 5.0, - "step": 1.0, + hops: { + label: "Hops Count", + type: "float", + init: 2.0, + min: 1.0, + max: 5.0, + step: 1.0, } }, - "vertex": `#version 100 + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -109,7 +109,7 @@ void main() { uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval); } `, - "fragment": `#version 100 + fragment: `#version 100 precision mediump float; @@ -126,10 +126,10 @@ void main() { } ` }, - "Hopper": { - "transparent": 0x00FF00 + "", - "duration": "0.85", - "vertex": `#version 100 + Hopper: { + transparent: String(0x00FF00), + duration: "0.85", + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -165,7 +165,7 @@ void main() { uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval); } `, - "fragment": `#version 100 + fragment: `#version 100 precision mediump float; @@ -182,10 +182,10 @@ void main() { } ` }, - "Overheat": { - "transparent": 0x00FF00 + "", - "duration": "0.85 / 8.0 * 2.0", - "vertex": `#version 100 + Overheat: { + transparent: String(0x00FF00), + duration: "0.85 / 8.0 * 2.0", + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -221,7 +221,7 @@ void main() { uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval); } `, - "fragment": `#version 100 + fragment: `#version 100 precision mediump float; @@ -238,26 +238,26 @@ void main() { } ` }, - "Bounce": { - "transparent": 0x00FF00 + "", - "duration": "Math.PI / period", - "params": { - "period": { - "type": "float", - "init": 5.0, - "min": 1.0, - "max": 10.0, - "step": 0.1, + Bounce: { + transparent: String(0x00FF00), + duration: "Math.PI / period", + params: { + period: { + type: "float", + init: 5.0, + min: 1.0, + max: 10.0, + step: 0.1, }, - "scale": { - "type": "float", - "init": 0.30, - "min": 0.0, - "max": 1.0, - "step": 0.01, + scale: { + type: "float", + init: 0.30, + min: 0.0, + max: 1.0, + step: 0.01, } }, - "vertex": `#version 100 + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -276,7 +276,7 @@ void main() { uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -294,10 +294,10 @@ void main() { } `, }, - "Circle": { - "transparent": 0x00FF00 + "", - "duration": "Math.PI / 4.0", - "vertex": `#version 100 + Circle: { + transparent: String(0x00FF00), + duration: "Math.PI / 4.0", + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -327,7 +327,7 @@ void main() { uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -346,10 +346,10 @@ void main() { } `, }, - "Slide": { - "transparent": 0x00FF00 + "", - "duration": "0.85 * 2", - "vertex": `#version 100 + Slide: { + transparent: String(0x00FF00), + duration: "0.85 * 2", + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -385,7 +385,7 @@ void main() { uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval); } `, - "fragment": `#version 100 + fragment: `#version 100 precision mediump float; @@ -402,10 +402,10 @@ void main() { } ` }, - "Laughing": { - "transparent": 0x00FF00 + "", - "duration": "Math.PI / 12.0", - "vertex": `#version 100 + Laughing: { + transparent: String(0x00FF00), + duration: "Math.PI / 12.0", + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -424,7 +424,7 @@ void main() { uv = (meshPosition + vec2(1.0, 1.0)) / 2.0; } `, - "fragment": `#version 100 + fragment: `#version 100 precision mediump float; @@ -441,10 +441,10 @@ void main() { } ` }, - "Blob": { - "transparent": 0x00FF00 + "", - "duration": "Math.PI / 3", - "vertex": `#version 100 + Blob: { + transparent: String(0x00FF00), + duration: "Math.PI / 3", + vertex: `#version 100 precision mediump float; @@ -466,7 +466,7 @@ void main() { uv = (meshPosition + vec2(1.0, 1.0)) / 2.0; } `, - "fragment": `#version 100 + fragment: `#version 100 precision mediump float; @@ -483,10 +483,10 @@ void main() { } ` }, - "Go": { - "transparent": 0x00FF00 + "", - "duration": "1 / 4", - "vertex": `#version 100 + Go: { + transparent: String(0x00FF00), + duration: "1 / 4", + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -501,7 +501,7 @@ void main() { uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -524,10 +524,10 @@ void main() { } `, }, - "Elevator": { - "transparent": 0x00FF00 + "", - "duration": "1 / 4", - "vertex": `#version 100 + Elevator: { + transparent: String(0x00FF00), + duration: "1 / 4", + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -542,7 +542,7 @@ void main() { uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -567,10 +567,10 @@ void main() { } `, }, - "Rain": { - "transparent": 0x00FF00 + "", - "duration": "1", - "vertex": `#version 100 + Rain: { + transparent: String(0x00FF00), + duration: "1", + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -585,7 +585,7 @@ void main() { uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -611,10 +611,10 @@ void main() { } `, }, - "Pride": { - "transparent": null, - "duration": "2.0", - "vertex": `#version 100 + Pride: { + transparent: null, + duration: "2.0", + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -629,7 +629,7 @@ void main() { uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -657,33 +657,33 @@ void main() { } `, }, - "Hard": { - "transparent": 0x00FF00 + "", - "duration": "2.0 * Math.PI / intensity", - "params": { - "zoom": { - "type": "float", - "init": 1.4, - "min": 0.0, - "max": 6.9, - "step": 0.1, + Hard: { + transparent: String(0x00FF00), + duration: "2.0 * Math.PI / intensity", + params: { + zoom: { + type: "float", + init: 1.4, + min: 0.0, + max: 6.9, + step: 0.1, }, - "intensity": { - "type": "float", - "init": 32.0, - "min": 1.0, - "max": 42.0, - "step": 1.0, + intensity: { + type: "float", + init: 32.0, + min: 1.0, + max: 42.0, + step: 1.0, }, - "amplitude": { - "type": "float", - "init": 1.0 / 8.0, - "min": 0.0, - "max": 1.0 / 2.0, - "step": 0.001, + amplitude: { + type: "float", + init: 1.0 / 8.0, + min: 0.0, + max: 1.0 / 2.0, + step: 0.001, }, }, - "vertex": `#version 100 + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -703,7 +703,7 @@ void main() { uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -721,10 +721,10 @@ void main() { } `, }, - "Peek":{ - "transparent": 0x00FF00 + "", - "duration": "2.0 * Math.PI" , - "vertex": `#version 100 + Peek:{ + transparent: String(0x00FF00), + duration: "2.0 * Math.PI" , + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -744,13 +744,13 @@ void main() { float hold2 = 1.0 - float(time_clipped > (2.5 * 3.14) && time_clipped < (4.0 * 3.14)); float cycle_1 = 1.0 - ((s1 * sin(time_clipped) * (1.0 - hold1)) + hold1); - float cycle_2 = s2 * hold2 * (sin(time_clipped) - 1.0); + float cycle_2 = s2 * hold2 * (sin(time_clipped) - 1.0); gl_Position = vec4(meshPosition.x + 1.0 + cycle_1 + cycle_2 , meshPosition.y, 0.0, 1.0); uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -766,12 +766,12 @@ void main() { gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y)); gl_FragColor.w = floor(gl_FragColor.w + 0.5); } -`, +`, }, - "Matrix": { - "transparent": null, - "duration": "3.0", - "vertex":` + Matrix: { + transparent: null, + duration: "3.0", + vertex:` #version 100 precision mediump float; @@ -788,7 +788,7 @@ void main() { gl_Position = vec4(meshPosition.x, meshPosition.y, 0.0, 1.0); } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -823,7 +823,7 @@ void main() { { float random = 2920.0 * sin(n.x * 21942.0 + n.y * 171324.0 + 8912.0) * cos(n.x * 23157.0 * n.y * 217832.0 + 9758.0); - + return (sin(random) + 1.0) / 2.0; } @@ -837,15 +837,15 @@ void main() { { vec2 uv = _uv; uv.y = 1.0 - _uv.y; - + float number_of_numbers = 8.0; float number_change_rate = 2.0; float amount_of_numbers = 0.6; // from 0 - 1 - + vec4 texture_color = texture2D(emote, uv); vec4 number_color = vec4(0, 0.7, 0, 1); - float looped_time = loop_time(3.0); + float looped_time = loop_time(3.0); vec2 translation = vec2(0, looped_time * -8.0); @@ -870,10 +870,10 @@ void main() { } ` }, - "Flag":{ - "transparent": 0x00FF00 + "", - "duration": "Math.PI", - "vertex":` + Flag: { + transparent: String(0x00FF00), + duration: "Math.PI", + vertex:` #version 100 precision mediump float; @@ -891,7 +891,7 @@ void main() { gl_Position = vec4(meshPosition.x, meshPosition.y, 0.0, 1.0); } `, - "fragment" :` + fragment :` #version 100 precision mediump float; @@ -911,7 +911,7 @@ void main() { float right = pos.x + size.x; float bottom = pos.y; float top = pos.y + size.y; - return (step(bottom, uv.y) - step(top, uv.y)) * (step(left, uv.x) - step(right, uv.x)); + return (step(bottom, uv.y) - step(top, uv.y)) * (step(left, uv.x) - step(right, uv.x)); } void main() { @@ -919,7 +919,7 @@ void main() { float flag_height = 0.75; float wave_size = 0.08; vec4 stick_color = vec4(107.0 / 256.0, 59.0 / 256.0, 9.0 / 256.0,1); - + vec2 flag_uv = _uv; flag_uv.x = (1.0 / (1.0 - stick_width)) * (flag_uv.x - stick_width); flag_uv.y *= 1.0 / flag_height; @@ -937,33 +937,33 @@ void main() { } ` }, - "Thanosed": { - "transparent": 0x00FF00 + "", - "duration": "duration", - "params": { - "duration": { - "type": "float", - "init": 6.0, - "min": 1.0, - "max": 16.0, - "step": 1.0, + Thanosed: { + transparent: String(0x00FF00), + duration: "duration", + params: { + duration: { + type: "float", + init: 6.0, + min: 1.0, + max: 16.0, + step: 1.0, }, - "delay": { - "type": "float", - "init": 0.2, - "min": 0.0, - "max": 1.0, - "step": 0.1, + delay: { + type: "float", + init: 0.2, + min: 0.0, + max: 1.0, + step: 0.1, }, - "pixelization": { - "type": "float", - "init": 1.0, - "min": 1.0, - "max": 3.0, - "step": 1.0, + pixelization: { + type: "float", + init: 1.0, + min: 1.0, + max: 3.0, + step: 1.0, }, }, - "vertex": `#version 100 + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -978,7 +978,7 @@ void main() { uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": ` + fragment: ` #version 100 precision mediump float; @@ -1016,36 +1016,36 @@ void main() { } `, }, - "Ripple": { - "transparent": 0x00FF00 + "", - "duration": "2 * Math.PI / b", - "params": { - "a": { - "label": "Wave Length", - "type": "float", - "init": 12.0, - "min": 0.01, - "max": 24.0, - "step": 0.01, + Ripple: { + transparent: String(0x00FF00), + duration: "2 * Math.PI / b", + params: { + a: { + label: "Wave Length", + type: "float", + init: 12.0, + min: 0.01, + max: 24.0, + step: 0.01, }, - "b": { - "label": "Time Freq", - "type": "float", - "init": 4.0, - "min": 0.01, - "max": 8.0, - "step": 0.01, + b: { + label: "Time Freq", + type: "float", + init: 4.0, + min: 0.01, + max: 8.0, + step: 0.01, }, - "c": { - "label": "Amplitude", - "type": "float", - "init": 0.03, - "min": 0.01, - "max": 0.06, - "step": 0.01, + c: { + label: "Amplitude", + type: "float", + init: 0.03, + min: 0.01, + max: 0.06, + step: 0.01, } }, - "vertex": `#version 100 + vertex: `#version 100 precision mediump float; attribute vec2 meshPosition; @@ -1060,7 +1060,7 @@ void main() { uv = (meshPosition + 1.0) / 2.0; } `, - "fragment": `#version 100 + fragment: `#version 100 precision mediump float; diff --git a/ts/grecha.ts b/ts/grecha.ts index dcef8d2..f7c028e 100644 --- a/ts/grecha.ts +++ b/ts/grecha.ts @@ -1,27 +1,44 @@ -const LOREM: string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."; - type Child = string | HTMLElement; -// TODO(#73): make tag more typesafe -// Essentially get rid of the `any` -type Tag = any; -function tag(name: string, ...children: Child[]): Tag { - const result: Tag = document.createElement(name); +/** + * Used to patch typescript conflict between class and className. + * Typscript merges interfaces so this works without modifying the library version of the interface. + * See the Notes section here. + * https://developer.mozilla.org/en-US/docs/Web/API/Element/className#notes + */ +interface HTMLElement { class : string } + +type Tag = T & { + att$ : (name: string, value: string) => Tag; + onclick$ : (callback: (this: GlobalEventHandlers, ev: MouseEvent) => Tag) => Tag; + paramsSnapshot$ : () => Snapshot; + selectedImage$ : () => Tag; + selectedFileName$ : () => string; + updateFiles$ : (files: FileList) => void; + selectedFilter$ : () => Filter; + render$ : (filename: string) => GIF | undefined; + updateImage$ : Function; // TODO: change this to the actual function type + + files : FileList; +}; + +function tag(name: string, ...children: Child[]): Tag { + const result = document.createElement(name) as Tag; for (const child of children) { - if (typeof(child) === 'string') { + if (typeof child === 'string') { result.appendChild(document.createTextNode(child)); } else { result.appendChild(child); } } - result.att$ = function(name: string, value: string) { + result.att$ = function (this, name : string, value) { this.setAttribute(name, value); return this; }; - result.onclick$ = function(callback: (this: GlobalEventHandlers, ev: MouseEvent) => Tag) { + result.onclick$ = function(this, callback) { this.onclick = callback; return this; }; @@ -29,57 +46,21 @@ function tag(name: string, ...children: Child[]): Tag { return result; } -function canvas(...children: Child[]): Tag { - return tag("canvas", ...children); -} - -function h1(...children: Child[]): Tag { - return tag("h1", ...children); -} - -function h2(...children: Child[]): Tag { - return tag("h2", ...children); -} - -function h3(...children: Child[]): Tag { - return tag("h3", ...children); -} - -function p(...children: Child[]): Tag { - return tag("p", ...children); -} - -function a(...children: Child[]): Tag { - return tag("a", ...children); -} - -function div(...children: Child[]): Tag { - return tag("div", ...children); -} - -function span(...children: Child[]): Tag { - return tag("span", ...children); -} - -function select(...children: Child[]): Tag { - return tag("select", ...children); -} - - -function img(src: string): Tag { - return tag("img").att$("src", src); -} - -function input(type: string): Tag { - return tag("input").att$("type", type); -} +const canvas = (...children: Child[]) => tag("canvas", ...children); +const h1 = (...children: Child[]) => tag("h1", ...children); +const h2 = (...children: Child[]) => tag("h2", ...children); +const h3 = (...children: Child[]) => tag("h3", ...children); +const p = (...children: Child[]) => tag("p", ...children); +const a = (...children: Child[]) => tag("a", ...children); +const div = (...children: Child[]) => tag("div", ...children); +const span = (...children: Child[]) => tag("span", ...children); +const select = (...children: Child[]) => tag("select", ...children); -interface Routes { - [route: string]: Tag -} +const img = (src: string) => tag("img").att$("src", src); +const input = (type: string) => tag("input").att$("type", type); -function router(routes: Routes): Tag { - let result = div(); +function router(routes: Record) { + const result = div(); function syncHash() { let hashLocation = document.location.hash.split('#')[1]; @@ -94,9 +75,9 @@ function router(routes: Routes): Tag { } while (result.firstChild) { - result.removeChild(result.lastChild); + result.removeChild(result.lastChild!); } - result.appendChild(routes[hashLocation]); + result.appendChild(routes[hashLocation]!); return result; }; diff --git a/ts/index.ts b/ts/index.ts index f45e7ab..7af979f 100644 --- a/ts/index.ts +++ b/ts/index.ts @@ -1,8 +1,6 @@ -let feature_params = false; +let feature_params = false; -interface VertexAttribs { - [name: string]: number -} +type VertexAttribs = Record; const vertexAttribs: VertexAttribs = { "meshPosition": 0 @@ -43,12 +41,12 @@ function linkShaderProgram(gl: WebGLRenderingContext, shaders: WebGLShader[], ve throw new Error('Could not create a new shader program'); } - for (let shader of shaders) { + for (const shader of shaders) { gl.attachShader(program, shader); } - for (let vertexName in vertexAttribs) { - gl.bindAttribLocation(program, vertexAttribs[vertexName], vertexName); + for (const [vertexName, vertexVal] of Object.entries(vertexAttribs)) { + gl.bindAttribLocation(program, vertexVal, vertexName); } gl.linkProgram(program); @@ -59,7 +57,7 @@ function linkShaderProgram(gl: WebGLRenderingContext, shaders: WebGLShader[], ve } function createTextureFromImage(gl: WebGLRenderingContext, image: TexImageSource): WebGLTexture { - let textureId = gl.createTexture(); + const textureId = gl.createTexture(); if (textureId === null) { throw new Error('Could not create a new WebGL texture'); } @@ -82,78 +80,76 @@ function createTextureFromImage(gl: WebGLRenderingContext, image: TexImageSource return textureId; } -interface Uniforms { - [name: string]: WebGLUniformLocation | null -} +type Uniforms = Record; -interface CompiledFilter { +interface CompiledFilter { id: WebGLProgram, uniforms: Uniforms, duration: Expr, transparent: string | null, - paramsPanel: Tag + paramsPanel: Tag } -interface Snapshot { - [name: string]: { - uniform: WebGLUniformLocation | null, - value: number | null - } -} +type Snapshot = Record // TODO(#54): pre-load all of the filters and just switch between them without loading/unloading them constantly function loadFilterProgram(gl: WebGLRenderingContext, filter: Filter, vertexAttribs: VertexAttribs): CompiledFilter { - let vertexShader = compileShaderSource(gl, filter.vertex, gl.VERTEX_SHADER); - let fragmentShader = compileShaderSource(gl, filter.fragment, gl.FRAGMENT_SHADER); - let id = linkShaderProgram(gl, [vertexShader, fragmentShader], vertexAttribs); + const vertexShader = compileShaderSource(gl, filter.vertex, gl.VERTEX_SHADER); + const fragmentShader = compileShaderSource(gl, filter.fragment, gl.FRAGMENT_SHADER); + const id = linkShaderProgram(gl, [vertexShader, fragmentShader], vertexAttribs); gl.deleteShader(vertexShader); gl.deleteShader(fragmentShader); gl.useProgram(id); - let uniforms: Uniforms = { - "resolution": gl.getUniformLocation(id, 'resolution'), - "time": gl.getUniformLocation(id, 'time'), - "emoteSize": gl.getUniformLocation(id, 'emoteSize'), + const uniforms: Uniforms = { + resolution: gl.getUniformLocation(id, 'resolution'), + time: gl.getUniformLocation(id, 'time'), + emoteSize: gl.getUniformLocation(id, 'emoteSize'), }; // TODO(#55): there no "reset to default" button in the params panel of a filter - let paramsPanel = div().att$("class", "widget-element"); - let paramsInputs: {[name: string]: Tag} = {}; + const paramsPanel = div().att$("class", "widget-element"); + const paramsInputs: Record = {}; - for (let paramName in filter.params) { + if (!filter.params) throw new Error("unknown error"); + + for (const [paramName, paramVal] of Object.entries(filter.params)) { if (paramName in uniforms) { throw new Error(`Redefinition of existing uniform parameter ${paramName}`); } - - switch (filter.params[paramName].type) { + + switch (paramVal.type) { case "float": { - const valuePreview = span(filter.params[paramName].init.toString()); + const valuePreview = span(paramVal.init.toString()); const valueInput = input("range"); - if (filter.params[paramName].min !== undefined) { - valueInput.att$("min", filter.params[paramName].min); + if (paramVal.min !== undefined) { + valueInput.att$("min", String(paramVal.min)); } - if (filter.params[paramName].max !== undefined) { - valueInput.att$("max", filter.params[paramName].max); + if (paramVal.max !== undefined) { + valueInput.att$("max", String(paramVal.max)); } - if (filter.params[paramName].step !== undefined) { - valueInput.att$("step", filter.params[paramName].step); + if (paramVal.step !== undefined) { + valueInput.att$("step", String(paramVal.step)); } - if (filter.params[paramName].init !== undefined) { - valueInput.att$("value", filter.params[paramName].init); + if (paramVal.init !== undefined) { + valueInput.att$("value", String(paramVal.init)); } paramsInputs[paramName] = valueInput; - valueInput.oninput = function () { + valueInput.oninput = function(this) { valuePreview.innerText = this.value; paramsPanel.dispatchEvent(new CustomEvent("paramsChanged")); }; - const label: string = filter.params[paramName].label ?? paramName; + const label = paramVal.label ?? paramName; paramsPanel.appendChild(div( span(`${label}: `), valuePreview, @@ -162,7 +158,7 @@ function loadFilterProgram(gl: WebGLRenderingContext, filter: Filter, vertexAttr } break; default: { - throw new Error(`Filter parameters do not support type ${filter.params[paramName].type}`) + throw new Error(`Filter parameters do not support type ${paramVal.type}`) } } @@ -170,23 +166,23 @@ function loadFilterProgram(gl: WebGLRenderingContext, filter: Filter, vertexAttr } - paramsPanel.paramsSnapshot$ = function() { + paramsPanel.paramsSnapshot$ = () => { let snapshot: Snapshot = {}; - for (let paramName in paramsInputs) { + for (const paramName in paramsInputs) { snapshot[paramName] = { - "uniform": uniforms[paramName], - "value": Number(paramsInputs[paramName].value) + uniform: uniforms[paramName], + value: Number(paramsInputs[paramName].value) }; } return snapshot; }; return { - "id": id, - "uniforms": uniforms, - "duration": compile_expr(filter.duration), - "transparent": filter.transparent, - "paramsPanel": paramsPanel, + id, + uniforms, + duration: compile_expr(filter.duration), + transparent: filter.transparent, + paramsPanel: paramsPanel, }; } @@ -194,17 +190,17 @@ function ImageSelector() { const imageInput = input("file"); const imagePreview = img("img/tsodinClown.png") .att$("class", "widget-element") - .att$("width", CANVAS_WIDTH); + .att$("width", String(CANVAS_WIDTH)); const root = div( div(imageInput).att$("class", "widget-element"), imagePreview ).att$("class", "widget"); - root.selectedImage$ = function() { + root.selectedImage$ = () => { return imagePreview; }; - root.selectedFileName$ = function() { + root.selectedFileName$ = () => { function removeFileNameExt(fileName: string): string { if (fileName.includes('.')) { return fileName.split('.').slice(0, -1).join('.'); @@ -217,12 +213,12 @@ function ImageSelector() { return file ? removeFileNameExt(file.name) : 'result'; }; - root.updateFiles$ = function(files: FileList) { + root.updateFiles$ = (files) => { imageInput.files = files; - imageInput.onchange(); + imageInput.onchange?.(); } - imagePreview.addEventListener('load', function(this: HTMLImageElement) { + imagePreview.addEventListener('load', function(this) { root.dispatchEvent(new CustomEvent("imageSelected", { detail: { imageData: this @@ -230,12 +226,12 @@ function ImageSelector() { })); }); - imagePreview.addEventListener('error', function(this: HTMLImageElement) { + imagePreview.addEventListener('error', function(this) { imageInput.value = ''; this.src = 'img/error.png'; }); - imageInput.onchange = function() { + imageInput.onchange = function(this) { imagePreview.src = URL.createObjectURL(this.files[0]); }; @@ -246,15 +242,15 @@ function FilterList() { const root = select(); // Populating the FilterList - for (let name in filters) { + for (const name in filters) { root.add(new Option(name)); } - root.selectedFilter$ = function() { + root.selectedFilter$ = () => { return filters[root.selectedOptions[0].value]; }; - root.onchange = function() { + root.onchange = () => { root.dispatchEvent(new CustomEvent('filterChanged', { detail: { filter: root.selectedFilter$() @@ -262,7 +258,7 @@ function FilterList() { })); }; - root.addEventListener('wheel', function(e: WheelEvent) { + root.addEventListener('wheel', (e: WheelEvent) => { e.preventDefault(); if (e.deltaY < 0) { root.selectedIndex = Math.max(root.selectedIndex - 1, 0); @@ -270,7 +266,7 @@ function FilterList() { if (e.deltaY > 0) { root.selectedIndex = Math.min(root.selectedIndex + 1, root.length - 1); } - root.onchange(); + root.onchange?.(); }); return root; @@ -279,8 +275,8 @@ function FilterList() { function FilterSelector() { const filterList_ = FilterList(); const filterPreview = canvas() - .att$("width", CANVAS_WIDTH) - .att$("height", CANVAS_HEIGHT); + .att$("width", String(CANVAS_WIDTH)) + .att$("height", String(CANVAS_HEIGHT)); const root = div( div("Filter: ", filterList_) .att$("class", "widget-element"), @@ -293,38 +289,33 @@ function FilterSelector() { } // Initialize GL + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + // Mesh Position { - gl.enable(gl.BLEND); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); - - // Mesh Position - { - let meshPositionBufferData = new Float32Array(TRIANGLE_PAIR * TRIANGLE_VERTICIES * VEC2_COUNT); - for (let triangle = 0; triangle < TRIANGLE_PAIR; ++triangle) { - for (let vertex = 0; vertex < TRIANGLE_VERTICIES; ++vertex) { - const quad = triangle + vertex; - const index = - triangle * TRIANGLE_VERTICIES * VEC2_COUNT + - vertex * VEC2_COUNT; - meshPositionBufferData[index + VEC2_X] = (2 * (quad & 1) - 1); - meshPositionBufferData[index + VEC2_Y] = (2 * ((quad >> 1) & 1) - 1); - } + const meshPositionBufferData = new Float32Array(TRIANGLE_PAIR * TRIANGLE_VERTICIES * VEC2_COUNT); + for (let triangle = 0; triangle < TRIANGLE_PAIR; ++triangle) { + for (let vertex = 0; vertex < TRIANGLE_VERTICIES; ++vertex) { + const quad = triangle + vertex; + const index = + triangle * TRIANGLE_VERTICIES * VEC2_COUNT + + vertex * VEC2_COUNT; + meshPositionBufferData[index + VEC2_X] = (2 * (quad & 1) - 1); + meshPositionBufferData[index + VEC2_Y] = (2 * ((quad >> 1) & 1) - 1); } - - let meshPositionBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, meshPositionBuffer); - gl.bufferData(gl.ARRAY_BUFFER, meshPositionBufferData, gl.STATIC_DRAW); - - const meshPositionAttrib = vertexAttribs['meshPosition']; - gl.vertexAttribPointer( - meshPositionAttrib, - VEC2_COUNT, - gl.FLOAT, - false, - 0, - 0); - gl.enableVertexAttribArray(meshPositionAttrib); } + const meshPositionBuffer = gl.createBuffer(); + gl.bindBuffer(gl.ARRAY_BUFFER, meshPositionBuffer); + gl.bufferData(gl.ARRAY_BUFFER, meshPositionBufferData, gl.STATIC_DRAW); + const meshPositionAttrib = vertexAttribs['meshPosition']; + gl.vertexAttribPointer( + meshPositionAttrib, + VEC2_COUNT, + gl.FLOAT, + false, + 0, + 0); + gl.enableVertexAttribArray(meshPositionAttrib); } // TODO(#49): FilterSelector does not handle loadFilterProgram() failures @@ -336,8 +327,8 @@ function FilterSelector() { function syncParams() { if (program) { const snapshot = program.paramsPanel.paramsSnapshot$(); - for (let paramName in snapshot) { - gl.uniform1f(snapshot[paramName].uniform, snapshot[paramName].value); + for (const paramName in snapshot) { + gl!.uniform1f(snapshot[paramName]!.uniform, snapshot[paramName]!.value!); } } } @@ -349,7 +340,7 @@ function FilterSelector() { } syncParams(); - root.updateImage$ = function(newEmoteImage: HTMLImageElement) { + root.updateImage$ = (newEmoteImage: HTMLImageElement) => { emoteImage = newEmoteImage; if (emoteTexture) { gl.deleteTexture(emoteTexture); @@ -374,7 +365,7 @@ function FilterSelector() { syncParams(); }); - root.render$ = function (filename: string): any | undefined { + root.render$ = (filename) => { if (program === undefined) { console.warn('Could not rendering anything because the filter was not selected'); return undefined; @@ -395,13 +386,13 @@ function FilterSelector() { }); const context: UserContext = { - "vars": { + vars: { "Math.PI": Math.PI } }; if (context.vars !== undefined) { const snapshot = program.paramsPanel.paramsSnapshot$(); - for (let paramName in snapshot) { + for (const paramName in snapshot) { context.vars[paramName] = snapshot[paramName].value; } } @@ -441,7 +432,7 @@ function FilterSelector() { gl.clear(gl.COLOR_BUFFER_BIT); gl.drawArrays(gl.TRIANGLES, 0, TRIANGLE_PAIR * TRIANGLE_VERTICIES); - let pixels = new Uint8ClampedArray(4 * CANVAS_WIDTH * CANVAS_HEIGHT); + const pixels = new Uint8ClampedArray(4 * CANVAS_WIDTH * CANVAS_HEIGHT); gl.readPixels(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, gl.RGBA, gl.UNSIGNED_BYTE, pixels); // Flip the image vertically { @@ -453,8 +444,8 @@ function FilterSelector() { const bi = (CANVAS_HEIGHT - y - 1) * 4 * CANVAS_WIDTH + x; const a = pixels[ai]; const b = pixels[bi]; - pixels[ai] = b; - pixels[bi] = a; + pixels[ai] = b!; + pixels[bi] = a!; } } } @@ -490,14 +481,14 @@ function FilterSelector() { // Rendering Loop { - const step = function(timestamp: number) { + const step = (timestamp: number) => { gl.clearColor(0.0, 1.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT); if (program && emoteImage) { - gl.uniform1f(program.uniforms.time, timestamp * 0.001); - gl.uniform2f(program.uniforms.resolution, filterPreview.width, filterPreview.height); - gl.uniform2f(program.uniforms.emoteSize, emoteImage.width, emoteImage.height); + gl.uniform1f(program.uniforms.time!, timestamp * 0.001); + gl.uniform2f(program.uniforms.resolution!, filterPreview.width, filterPreview.height); + gl.uniform2f(program.uniforms.emoteSize!, emoteImage.width, emoteImage.height); gl.drawArrays(gl.TRIANGLES, 0, TRIANGLE_PAIR * TRIANGLE_VERTICIES); } @@ -538,19 +529,19 @@ window.onload = () => { const imageSelector = ImageSelector(); const filterSelector = FilterSelector(); - imageSelector.addEventListener('imageSelected', function(e: CustomEvent) { + imageSelector.addEventListener('imageSelected', (e: CustomEvent) => { filterSelector.updateImage$(e.detail.imageData); }); filterSelectorEntry.appendChild(filterSelector); imageSelectorEntry.appendChild(imageSelector); // drag file from anywhere - document.ondrop = function(event: DragEvent) { + document.ondrop = (event: DragEvent) => { event.preventDefault(); - imageSelector.updateFiles$(event.dataTransfer?.files); + imageSelector.updateFiles$(event.dataTransfer?.files!); } - document.ondragover = function(event) { + document.ondragover = (event) => { event.preventDefault(); } @@ -561,8 +552,8 @@ window.onload = () => { if (renderButton === null) { throw new Error('Could not find "render"'); } - renderButton.onclick = function() { - if (gif && gif.running) { + renderButton.onclick = () => { + if (gif?.running) { gif.abort(); } const fileName = imageSelector.selectedFileName$(); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..8bb6097 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,108 @@ +{ + "compilerOptions": { + /* Visit https://aka.ms/tsconfig to read more about this file */ + + /* Projects */ + // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ + // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ + // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ + // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ + // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ + // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ + + /* Language and Environment */ + "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ + // "jsx": "preserve", /* Specify what JSX code is generated. */ + // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ + // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ + // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ + // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ + // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ + // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ + // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ + // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ + + /* Modules */ + "module": "commonjs", /* Specify what module code is generated. */ + // "rootDir": "./", /* Specify the root folder within your source files. */ + // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ + // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ + // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ + // "types": [], /* Specify type package names to be included without being referenced in a source file. */ + // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ + // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ + // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ + // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ + // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ + // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ + // "resolveJsonModule": true, /* Enable importing .json files. */ + // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ + // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ + + /* JavaScript Support */ + // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ + // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + + /* Emit */ + // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ + // "declarationMap": true, /* Create sourcemaps for d.ts files. */ + // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ + // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ + // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ + // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ + // "outDir": "./", /* Specify an output folder for all emitted files. */ + // "removeComments": true, /* Disable emitting comments. */ + // "noEmit": true, /* Disable emitting files from a compilation. */ + // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ + // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ + // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ + // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ + // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ + // "newLine": "crlf", /* Set the newline character for emitting files. */ + // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ + // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ + // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ + // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ + // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + + /* Interop Constraints */ + // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ + // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ + // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ + // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ + "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ + + /* Type Checking */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ + // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ + // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ + // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ + // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ + + /* Completeness */ + // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ + "skipLibCheck": true /* Skip type checking all .d.ts files. */ + } +} From 162ffdcaea1db1d3f250159bca7ab40a3ac423f9 Mon Sep 17 00:00:00 2001 From: Saksham Goyal Date: Thu, 15 Aug 2024 02:44:46 -0400 Subject: [PATCH 2/5] vite --- .gitignore | 3 +- build.js | 99 ------- gif.js | 3 - gif.worker.js | 3 - index.html | 10 +- js/eval.js | 224 -------------- js/filters.js | 241 --------------- js/grecha.js | 123 -------- js/index.js | 435 ---------------------------- package-lock.json | 119 ++++++++ package.json | 10 +- {img => public/img}/error.png | Bin {img => public/img}/error.svg | 0 {img => public/img}/tsodinClown.png | Bin serviceworker.js | 131 --------- serviceworker.ts | 53 ---- {ts => src}/eval.ts | 14 +- {ts => src}/filters.ts | 4 +- {ts => src}/grecha.ts | 36 ++- {ts => src}/index.ts | 51 ++-- tsconfig.json | 115 +++----- 21 files changed, 219 insertions(+), 1455 deletions(-) delete mode 100644 build.js delete mode 100644 gif.js delete mode 100644 gif.worker.js delete mode 100644 js/eval.js delete mode 100644 js/filters.js delete mode 100644 js/grecha.js delete mode 100644 js/index.js rename {img => public/img}/error.png (100%) rename {img => public/img}/error.svg (100%) rename {img => public/img}/tsodinClown.png (100%) delete mode 100644 serviceworker.js delete mode 100644 serviceworker.ts rename {ts => src}/eval.ts (95%) rename {ts => src}/filters.ts (99%) rename {ts => src}/grecha.ts (58%) rename {ts => src}/index.ts (93%) diff --git a/.gitignore b/.gitignore index 40b878d..b947077 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -node_modules/ \ No newline at end of file +node_modules/ +dist/ diff --git a/build.js b/build.js deleted file mode 100644 index c14fdf9..0000000 --- a/build.js +++ /dev/null @@ -1,99 +0,0 @@ -import { spawn } from 'child_process'; - -function cmd(program, args) { - console.log('CMD:', program, args); - const p = spawn(program, args.flat(), {shell: process.platform == 'win32'}); // NOTE: flattening the args array enables you to group related arguments for better self-documentation of the running command - p.stdout.on('data', (data) => process.stdout.write(data)); - p.stderr.on('data', (data) => process.stderr.write(data)); - p.on('close', (code) => { - if (code !== 0) { - console.error(program, args, 'exited with', code); - } - }); - return p; -} - -const commonTscFlags = [ - '--strict', - '--removeComments', - '--skipLibCheck', -]; - -const mainTs = [ - 'ts/eval.ts', - 'ts/filters.ts', - 'ts/grecha.ts', - 'ts/index.ts' -]; - -function tscMain(...extraParams) { - cmd('tsc', [ - ...commonTscFlags, - ['--outDir', 'js'], - ...extraParams, - mainTs, - ]); -} - -function tscServiceWorker(...extraParams) { - cmd('tsc', [ - ...commonTscFlags, - ['--lib', 'webworker'], - ['--outFile', 'serviceworker.js'], - ...extraParams, - 'serviceworker.ts' - ]); -} - -function build(part, ...args) { - switch (part) { - case undefined: - tscServiceWorker(); - tscMain(); - break; - case 'main': - tscMain(); - break; - case 'serviceworker': - tscServiceWorker(); - break; - default: - throw new Error(`Unknown build part ${part}. Available parts: main, serviceworker.`); - } -} - -function watch(part, ...args) { - switch (part) { - case undefined: - tscMain('-w', '--preserveWatchOutput'); - tscServiceWorker('-w', '--preserveWatchOutput'); - break; - case 'main': - tscMain('-w', '--preserveWatchOutput'); - break; - case 'serviceworker': - tscServiceWorker('-w', '--preserveWatchOutput'); - break; - default: - throw new Error(`Unknown watch part ${part}. Available parts: main, serviceworker.`); - } -} - -const [nodePath, scriptPath, command, ...args] = process.argv; -switch (command) { -case undefined: -case 'build': - build(...args); - break; -case 'watch': - watch(...args); - break; -case 'serve': - // TODO: maybe replace Python with something from Node itself? - // Python is a pretty unreasonable dependency. - cmd('python3', [['-m', 'http.server'], '6969']); - watch(); - break; -default: - throw new Error(`Unknown command ${command}. Available commands: build, watch.`); -} diff --git a/gif.js b/gif.js deleted file mode 100644 index f066142..0000000 --- a/gif.js +++ /dev/null @@ -1,3 +0,0 @@ -// gif.js 0.2.0 - https://github.com/jnordberg/gif.js -(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.GIF=f()}})(function(){var define,module,exports;return function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i0&&this._events[type].length>m){this._events[type].warned=true;console.error("(node) warning: possible EventEmitter memory "+"leak detected. %d listeners added. "+"Use emitter.setMaxListeners() to increase limit.",this._events[type].length);if(typeof console.trace==="function"){console.trace()}}}return this};EventEmitter.prototype.on=EventEmitter.prototype.addListener;EventEmitter.prototype.once=function(type,listener){if(!isFunction(listener))throw TypeError("listener must be a function");var fired=false;function g(){this.removeListener(type,g);if(!fired){fired=true;listener.apply(this,arguments)}}g.listener=listener;this.on(type,g);return this};EventEmitter.prototype.removeListener=function(type,listener){var list,position,length,i;if(!isFunction(listener))throw TypeError("listener must be a function");if(!this._events||!this._events[type])return this;list=this._events[type];length=list.length;position=-1;if(list===listener||isFunction(list.listener)&&list.listener===listener){delete this._events[type];if(this._events.removeListener)this.emit("removeListener",type,listener)}else if(isObject(list)){for(i=length;i-- >0;){if(list[i]===listener||list[i].listener&&list[i].listener===listener){position=i;break}}if(position<0)return this;if(list.length===1){list.length=0;delete this._events[type]}else{list.splice(position,1)}if(this._events.removeListener)this.emit("removeListener",type,listener)}return this};EventEmitter.prototype.removeAllListeners=function(type){var key,listeners;if(!this._events)return this;if(!this._events.removeListener){if(arguments.length===0)this._events={};else if(this._events[type])delete this._events[type];return this}if(arguments.length===0){for(key in this._events){if(key==="removeListener")continue;this.removeAllListeners(key)}this.removeAllListeners("removeListener");this._events={};return this}listeners=this._events[type];if(isFunction(listeners)){this.removeListener(type,listeners)}else if(listeners){while(listeners.length)this.removeListener(type,listeners[listeners.length-1])}delete this._events[type];return this};EventEmitter.prototype.listeners=function(type){var ret;if(!this._events||!this._events[type])ret=[];else if(isFunction(this._events[type]))ret=[this._events[type]];else ret=this._events[type].slice();return ret};EventEmitter.prototype.listenerCount=function(type){if(this._events){var evlistener=this._events[type];if(isFunction(evlistener))return 1;else if(evlistener)return evlistener.length}return 0};EventEmitter.listenerCount=function(emitter,type){return emitter.listenerCount(type)};function isFunction(arg){return typeof arg==="function"}function isNumber(arg){return typeof arg==="number"}function isObject(arg){return typeof arg==="object"&&arg!==null}function isUndefined(arg){return arg===void 0}},{}],2:[function(require,module,exports){var UA,browser,mode,platform,ua;ua=navigator.userAgent.toLowerCase();platform=navigator.platform.toLowerCase();UA=ua.match(/(opera|ie|firefox|chrome|version)[\s\/:]([\w\d\.]+)?.*?(safari|version[\s\/:]([\w\d\.]+)|$)/)||[null,"unknown",0];mode=UA[1]==="ie"&&document.documentMode;browser={name:UA[1]==="version"?UA[3]:UA[1],version:mode||parseFloat(UA[1]==="opera"&&UA[4]?UA[4]:UA[2]),platform:{name:ua.match(/ip(?:ad|od|hone)/)?"ios":(ua.match(/(?:webos|android)/)||platform.match(/mac|win|linux/)||["other"])[0]}};browser[browser.name]=true;browser[browser.name+parseInt(browser.version,10)]=true;browser.platform[browser.platform.name]=true;module.exports=browser},{}],3:[function(require,module,exports){var EventEmitter,GIF,browser,extend=function(child,parent){for(var key in parent){if(hasProp.call(parent,key))child[key]=parent[key]}function ctor(){this.constructor=child}ctor.prototype=parent.prototype;child.prototype=new ctor;child.__super__=parent.prototype;return child},hasProp={}.hasOwnProperty,indexOf=[].indexOf||function(item){for(var i=0,l=this.length;iref;i=0<=ref?++j:--j){results.push(null)}return results}.call(this);numWorkers=this.spawnWorkers();if(this.options.globalPalette===true){this.renderNextFrame()}else{for(i=j=0,ref=numWorkers;0<=ref?jref;i=0<=ref?++j:--j){this.renderNextFrame()}}this.emit("start");return this.emit("progress",0)};GIF.prototype.abort=function(){var worker;while(true){worker=this.activeWorkers.shift();if(worker==null){break}this.log("killing active worker");worker.terminate()}this.running=false;return this.emit("abort")};GIF.prototype.spawnWorkers=function(){var j,numWorkers,ref,results;numWorkers=Math.min(this.options.workers,this.frames.length);(function(){results=[];for(var j=ref=this.freeWorkers.length;ref<=numWorkers?jnumWorkers;ref<=numWorkers?j++:j--){results.push(j)}return results}).apply(this).forEach(function(_this){return function(i){var worker;_this.log("spawning worker "+i);worker=new Worker(_this.options.workerScript);worker.onmessage=function(event){_this.activeWorkers.splice(_this.activeWorkers.indexOf(worker),1);_this.freeWorkers.push(worker);return _this.frameFinished(event.data)};return _this.freeWorkers.push(worker)}}(this));return numWorkers};GIF.prototype.frameFinished=function(frame){var i,j,ref;this.log("frame "+frame.index+" finished - "+this.activeWorkers.length+" active");this.finishedFrames++;this.emit("progress",this.finishedFrames/this.frames.length);this.imageParts[frame.index]=frame;if(this.options.globalPalette===true){this.options.globalPalette=frame.globalPalette;this.log("global palette analyzed");if(this.frames.length>2){for(i=j=1,ref=this.freeWorkers.length;1<=ref?jref;i=1<=ref?++j:--j){this.renderNextFrame()}}}if(indexOf.call(this.imageParts,null)>=0){return this.renderNextFrame()}else{return this.finishRendering()}};GIF.prototype.finishRendering=function(){var data,frame,i,image,j,k,l,len,len1,len2,len3,offset,page,ref,ref1,ref2;len=0;ref=this.imageParts;for(j=0,len1=ref.length;j=this.frames.length){return}frame=this.frames[this.nextFrame++];worker=this.freeWorkers.shift();task=this.getTask(frame);this.log("starting frame "+(task.index+1)+" of "+this.frames.length);this.activeWorkers.push(worker);return worker.postMessage(task)};GIF.prototype.getContextData=function(ctx){return ctx.getImageData(0,0,this.options.width,this.options.height).data};GIF.prototype.getImageData=function(image){var ctx;if(this._canvas==null){this._canvas=document.createElement("canvas");this._canvas.width=this.options.width;this._canvas.height=this.options.height}ctx=this._canvas.getContext("2d");ctx.fillStyle=this.options.background;ctx.fillRect(0,0,this.options.width,this.options.height);ctx.drawImage(image,0,0);return this.getContextData(ctx)};GIF.prototype.getTask=function(frame){var index,task;index=this.frames.indexOf(frame);task={index:index,last:index===this.frames.length-1,delay:frame.delay,dispose:frame.dispose,transparent:frame.transparent,width:this.options.width,height:this.options.height,quality:this.options.quality,dither:this.options.dither,globalPalette:this.options.globalPalette,repeat:this.options.repeat,canTransfer:browser.name==="chrome"};if(frame.data!=null){task.data=frame.data}else if(frame.context!=null){task.data=this.getContextData(frame.context)}else if(frame.image!=null){task.data=this.getImageData(frame.image)}else{throw new Error("Invalid frame")}return task};GIF.prototype.log=function(){var args;args=1<=arguments.length?slice.call(arguments,0):[];if(!this.options.debug){return}return console.log.apply(console,args)};return GIF}(EventEmitter);module.exports=GIF},{"./browser.coffee":2,events:1}]},{},[3])(3)}); -//# sourceMappingURL=gif.js.map diff --git a/gif.worker.js b/gif.worker.js deleted file mode 100644 index 845c684..0000000 --- a/gif.worker.js +++ /dev/null @@ -1,3 +0,0 @@ -// gif.worker.js 0.2.0 - https://github.com/jnordberg/gif.js -(function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i=ByteArray.pageSize)this.newPage();this.pages[this.page][this.cursor++]=val};ByteArray.prototype.writeUTFBytes=function(string){for(var l=string.length,i=0;i=0)this.dispose=disposalCode};GIFEncoder.prototype.setRepeat=function(repeat){this.repeat=repeat};GIFEncoder.prototype.setTransparent=function(color){this.transparent=color};GIFEncoder.prototype.addFrame=function(imageData){this.image=imageData;this.colorTab=this.globalPalette&&this.globalPalette.slice?this.globalPalette:null;this.getImagePixels();this.analyzePixels();if(this.globalPalette===true)this.globalPalette=this.colorTab;if(this.firstFrame){this.writeLSD();this.writePalette();if(this.repeat>=0){this.writeNetscapeExt()}}this.writeGraphicCtrlExt();this.writeImageDesc();if(!this.firstFrame&&!this.globalPalette)this.writePalette();this.writePixels();this.firstFrame=false};GIFEncoder.prototype.finish=function(){this.out.writeByte(59)};GIFEncoder.prototype.setQuality=function(quality){if(quality<1)quality=1;this.sample=quality};GIFEncoder.prototype.setDither=function(dither){if(dither===true)dither="FloydSteinberg";this.dither=dither};GIFEncoder.prototype.setGlobalPalette=function(palette){this.globalPalette=palette};GIFEncoder.prototype.getGlobalPalette=function(){return this.globalPalette&&this.globalPalette.slice&&this.globalPalette.slice(0)||this.globalPalette};GIFEncoder.prototype.writeHeader=function(){this.out.writeUTFBytes("GIF89a")};GIFEncoder.prototype.analyzePixels=function(){if(!this.colorTab){this.neuQuant=new NeuQuant(this.pixels,this.sample);this.neuQuant.buildColormap();this.colorTab=this.neuQuant.getColormap()}if(this.dither){this.ditherPixels(this.dither.replace("-serpentine",""),this.dither.match(/-serpentine/)!==null)}else{this.indexPixels()}this.pixels=null;this.colorDepth=8;this.palSize=7;if(this.transparent!==null){this.transIndex=this.findClosest(this.transparent,true)}};GIFEncoder.prototype.indexPixels=function(imgq){var nPix=this.pixels.length/3;this.indexedPixels=new Uint8Array(nPix);var k=0;for(var j=0;j=0&&x1+x=0&&y1+y>16,(c&65280)>>8,c&255,used)};GIFEncoder.prototype.findClosestRGB=function(r,g,b,used){if(this.colorTab===null)return-1;if(this.neuQuant&&!used){return this.neuQuant.lookupRGB(r,g,b)}var c=b|g<<8|r<<16;var minpos=0;var dmin=256*256*256;var len=this.colorTab.length;for(var i=0,index=0;i=0){disp=this.dispose&7}disp<<=2;this.out.writeByte(0|disp|0|transp);this.writeShort(this.delay);this.out.writeByte(this.transIndex);this.out.writeByte(0)};GIFEncoder.prototype.writeImageDesc=function(){this.out.writeByte(44);this.writeShort(0);this.writeShort(0);this.writeShort(this.width);this.writeShort(this.height);if(this.firstFrame||this.globalPalette){this.out.writeByte(0)}else{this.out.writeByte(128|0|0|0|this.palSize)}};GIFEncoder.prototype.writeLSD=function(){this.writeShort(this.width);this.writeShort(this.height);this.out.writeByte(128|112|0|this.palSize);this.out.writeByte(0);this.out.writeByte(0)};GIFEncoder.prototype.writeNetscapeExt=function(){this.out.writeByte(33);this.out.writeByte(255);this.out.writeByte(11);this.out.writeUTFBytes("NETSCAPE2.0");this.out.writeByte(3);this.out.writeByte(1);this.writeShort(this.repeat);this.out.writeByte(0)};GIFEncoder.prototype.writePalette=function(){this.out.writeBytes(this.colorTab);var n=3*256-this.colorTab.length;for(var i=0;i>8&255)};GIFEncoder.prototype.writePixels=function(){var enc=new LZWEncoder(this.width,this.height,this.indexedPixels,this.colorDepth);enc.encode(this.out)};GIFEncoder.prototype.stream=function(){return this.out};module.exports=GIFEncoder},{"./LZWEncoder.js":2,"./TypedNeuQuant.js":3}],2:[function(require,module,exports){var EOF=-1;var BITS=12;var HSIZE=5003;var masks=[0,1,3,7,15,31,63,127,255,511,1023,2047,4095,8191,16383,32767,65535];function LZWEncoder(width,height,pixels,colorDepth){var initCodeSize=Math.max(2,colorDepth);var accum=new Uint8Array(256);var htab=new Int32Array(HSIZE);var codetab=new Int32Array(HSIZE);var cur_accum,cur_bits=0;var a_count;var free_ent=0;var maxcode;var clear_flg=false;var g_init_bits,ClearCode,EOFCode;function char_out(c,outs){accum[a_count++]=c;if(a_count>=254)flush_char(outs)}function cl_block(outs){cl_hash(HSIZE);free_ent=ClearCode+2;clear_flg=true;output(ClearCode,outs)}function cl_hash(hsize){for(var i=0;i=0){disp=hsize_reg-i;if(i===0)disp=1;do{if((i-=disp)<0)i+=hsize_reg;if(htab[i]===fcode){ent=codetab[i];continue outer_loop}}while(htab[i]>=0)}output(ent,outs);ent=c;if(free_ent<1<0){outs.writeByte(a_count);outs.writeBytes(accum,0,a_count);a_count=0}}function MAXCODE(n_bits){return(1<0)cur_accum|=code<=8){char_out(cur_accum&255,outs);cur_accum>>=8;cur_bits-=8}if(free_ent>maxcode||clear_flg){if(clear_flg){maxcode=MAXCODE(n_bits=g_init_bits);clear_flg=false}else{++n_bits;if(n_bits==BITS)maxcode=1<0){char_out(cur_accum&255,outs);cur_accum>>=8;cur_bits-=8}flush_char(outs)}}this.encode=encode}module.exports=LZWEncoder},{}],3:[function(require,module,exports){var ncycles=100;var netsize=256;var maxnetpos=netsize-1;var netbiasshift=4;var intbiasshift=16;var intbias=1<>betashift;var betagamma=intbias<>3;var radiusbiasshift=6;var radiusbias=1<>3);var i,v;for(i=0;i>=netbiasshift;network[i][1]>>=netbiasshift;network[i][2]>>=netbiasshift;network[i][3]=i}}function altersingle(alpha,i,b,g,r){network[i][0]-=alpha*(network[i][0]-b)/initalpha;network[i][1]-=alpha*(network[i][1]-g)/initalpha;network[i][2]-=alpha*(network[i][2]-r)/initalpha}function alterneigh(radius,i,b,g,r){var lo=Math.abs(i-radius);var hi=Math.min(i+radius,netsize);var j=i+1;var k=i-1;var m=1;var p,a;while(jlo){a=radpower[m++];if(jlo){p=network[k--];p[0]-=a*(p[0]-b)/alpharadbias;p[1]-=a*(p[1]-g)/alpharadbias;p[2]-=a*(p[2]-r)/alpharadbias}}}function contest(b,g,r){var bestd=~(1<<31);var bestbiasd=bestd;var bestpos=-1;var bestbiaspos=bestpos;var i,n,dist,biasdist,betafreq;for(i=0;i>intbiasshift-netbiasshift);if(biasdist>betashift;freq[i]-=betafreq;bias[i]+=betafreq<>1;for(j=previouscol+1;j>1;for(j=previouscol+1;j<256;j++)netindex[j]=maxnetpos}function inxsearch(b,g,r){var a,p,dist;var bestd=1e3;var best=-1;var i=netindex[g];var j=i-1;while(i=0){if(i=bestd)i=netsize;else{i++;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist=0){p=network[j];dist=g-p[1];if(dist>=bestd)j=-1;else{j--;if(dist<0)dist=-dist;a=p[0]-b;if(a<0)a=-a;dist+=a;if(dist>radiusbiasshift;if(rad<=1)rad=0;for(i=0;i=lengthcount)pix-=lengthcount;i++;if(delta===0)delta=1;if(i%delta===0){alpha-=alpha/alphadec;radius-=radius/radiusdec;rad=radius>>radiusbiasshift;if(rad<=1)rad=0;for(j=0;j3. Render the GIF - - - - - + + + + + diff --git a/js/eval.js b/js/eval.js deleted file mode 100644 index 37c7f29..0000000 --- a/js/eval.js +++ /dev/null @@ -1,224 +0,0 @@ -"use strict"; -var BinaryPrec; -(function (BinaryPrec) { - BinaryPrec[BinaryPrec["PREC0"] = 0] = "PREC0"; - BinaryPrec[BinaryPrec["PREC1"] = 1] = "PREC1"; - BinaryPrec[BinaryPrec["COUNT_PRECS"] = 2] = "COUNT_PRECS"; -})(BinaryPrec || (BinaryPrec = {})); -; -var BINARY_OPS = { - '+': { - func: function (lhs, rhs) { return lhs + rhs; }, - prec: BinaryPrec.PREC0 - }, - '-': { - func: function (lhs, rhs) { return lhs - rhs; }, - prec: BinaryPrec.PREC0 - }, - '*': { - func: function (lhs, rhs) { return lhs * rhs; }, - prec: BinaryPrec.PREC1 - }, - '/': { - func: function (lhs, rhs) { return lhs / rhs; }, - prec: BinaryPrec.PREC1 - }, - '%': { - func: function (lhs, rhs) { return lhs % rhs; }, - prec: BinaryPrec.PREC1 - } -}; -var UNARY_OPS = { - '-': function (arg) { return -arg; }, -}; -var Lexer = (function () { - function Lexer(src) { - this.src = src; - } - Lexer.prototype.unnext = function (token) { - this.src = token + this.src; - }; - Lexer.prototype.next = function () { - this.src = this.src.trimStart(); - if (this.src.length == 0) { - return null; - } - function is_token_break(c) { - var syntax = '(),'; - return c in BINARY_OPS || c in UNARY_OPS || syntax.includes(c); - } - if (is_token_break(this.src[0])) { - var token_1 = this.src[0]; - this.src = this.src.slice(1); - return token_1; - } - for (var i = 0; i < this.src.length; ++i) { - if (is_token_break(this.src[i]) || this.src[i] == ' ') { - var token_2 = this.src.slice(0, i); - this.src = this.src.slice(i); - return token_2; - } - } - var token = this.src; - this.src = ''; - return token; - }; - return Lexer; -}()); -function parse_primary(lexer) { - var token = lexer.next(); - if (token !== null) { - if (token in UNARY_OPS) { - var operand = parse_expr(lexer); - return { - "kind": "unary_op", - "payload": { - "op": token, - "operand": operand, - }, - }; - } - else if (token === '(') { - var expr = parse_expr(lexer); - token = lexer.next(); - if (token !== ')') { - throw new Error("Expected ')' but got '".concat(token, "'")); - } - return expr; - } - else if (token === ')') { - throw new Error("No primary expression starts with ')'"); - } - else { - var next_token = lexer.next(); - if (next_token === '(') { - var args = []; - next_token = lexer.next(); - if (next_token === ')') { - return { - kind: "funcall", - payload: { - name: token, - args: args, - } - }; - } - if (next_token === null) { - throw Error("Unexpected end of input"); - } - lexer.unnext(next_token); - args.push(parse_expr(lexer)); - next_token = lexer.next(); - while (next_token == ',') { - args.push(parse_expr(lexer)); - next_token = lexer.next(); - } - if (next_token !== ')') { - throw Error("Expected ')' but got '".concat(next_token, "'")); - } - return { - kind: "funcall", - payload: { - name: token, - args: args, - } - }; - } - else { - if (next_token !== null) { - lexer.unnext(next_token); - } - return { - kind: "symbol", - payload: { - value: token - } - }; - } - } - } - else { - throw new Error('Expected primary expression but reached the end of the input'); - } -} -function parse_expr(lexer, prec) { - if (prec === void 0) { prec = BinaryPrec.PREC0; } - if (prec >= BinaryPrec.COUNT_PRECS) { - return parse_primary(lexer); - } - var lhs = parse_expr(lexer, prec + 1); - var op_token = lexer.next(); - if (op_token !== null) { - if (op_token in BINARY_OPS && BINARY_OPS[op_token].prec == prec) { - var rhs = parse_expr(lexer, prec); - return { - kind: "binary_op", - payload: { - op: op_token, - lhs: lhs, - rhs: rhs, - } - }; - } - else { - lexer.unnext(op_token); - } - } - return lhs; -} -function compile_expr(src) { - var lexer = new Lexer(src); - var result = parse_expr(lexer); - var token = lexer.next(); - if (token !== null) { - console.log(typeof (token)); - console.log(token); - throw new Error("Unexpected token '".concat(token, "'")); - } - return result; -} -function run_expr(expr, user_context) { - var _a; - if (user_context === void 0) { user_context = {}; } - console.assert(typeof (expr) === 'object'); - switch (expr.kind) { - case 'symbol': { - var symbol = expr.payload; - var value = symbol.value; - var number = Number(value); - if (isNaN(number)) { - if (user_context.vars && value in user_context.vars) { - return user_context.vars[value]; - } - throw new Error("Unknown variable '".concat(value, "'")); - } - else { - return number; - } - } - case 'unary_op': { - var unary_op = expr.payload; - if (unary_op.op in UNARY_OPS) { - return UNARY_OPS[unary_op.op](run_expr(unary_op.operand, user_context)); - } - throw new Error("Unknown unary operator '".concat(unary_op.op, "'")); - } - case 'binary_op': { - var binary_op = expr.payload; - if (binary_op.op in BINARY_OPS) { - return BINARY_OPS[binary_op.op].func(run_expr(binary_op.lhs, user_context), run_expr(binary_op.rhs, user_context)); - } - throw new Error("Unknown binary operator '".concat(binary_op.op, "'")); - } - case 'funcall': { - var funcall = expr.payload; - if (user_context.funcs && funcall.name in user_context.funcs) { - return (_a = user_context.funcs)[funcall.name].apply(_a, funcall.args.map(function (arg) { return run_expr(arg, user_context); })); - } - throw new Error("Unknown function '".concat(funcall.name, "'")); - } - default: { - throw new Error("Unexpected AST node '".concat(expr.kind, "'")); - } - } -} diff --git a/js/filters.js b/js/filters.js deleted file mode 100644 index c3b5df5..0000000 --- a/js/filters.js +++ /dev/null @@ -1,241 +0,0 @@ -"use strict"; -var filters = { - Hop: { - transparent: String(0x00FF00), - duration: "interval * 2", - params: { - interval: { - label: "Interval", - type: "float", - init: 0.85, - min: 0.01, - max: 2.00, - step: 0.01, - }, - ground: { - label: "Ground", - type: "float", - init: 0.5, - min: -1.0, - max: 1.0, - step: 0.01, - }, - scale: { - label: "Scale", - type: "float", - init: 0.40, - min: 0.0, - max: 1.0, - step: 0.01, - }, - jump_height: { - label: "Jump Height", - type: "float", - init: 4.0, - min: 1.0, - max: 10.0, - step: 0.01, - }, - hops: { - label: "Hops Count", - type: "float", - init: 2.0, - min: 1.0, - max: 5.0, - step: 1.0, - } - }, - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\nuniform vec2 emoteSize;\n\nuniform float interval;\nuniform float ground;\nuniform float scale;\nuniform float jump_height;\nuniform float hops;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float x_time_interval = interval;\n float y_time_interval = x_time_interval / (2.0 * hops);\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n ((sliding_from_left_to_right(y_time_interval) * flipping_directions(y_time_interval) + 1.0) / jump_height) - ground);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", - fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - Hopper: { - transparent: String(0x00FF00), - duration: "0.85", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float scale = 0.40;\n float hops = 2.0;\n float x_time_interval = 0.85 / 2.0;\n float y_time_interval = x_time_interval / (2.0 * hops);\n float height = 0.5;\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n ((sliding_from_left_to_right(y_time_interval) * flipping_directions(y_time_interval) + 1.0) / 4.0) - height);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", - fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - Overheat: { - transparent: String(0x00FF00), - duration: "0.85 / 8.0 * 2.0", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float scale = 0.40;\n float hops = 2.0;\n float x_time_interval = 0.85 / 8.0;\n float y_time_interval = x_time_interval / (2.0 * hops);\n float height = 0.5;\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n ((sliding_from_left_to_right(y_time_interval) * flipping_directions(y_time_interval) + 1.0) / 4.0) - height);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", - fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y)) * vec4(1.0, 0.0, 0.0, 1.0);\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - Bounce: { - transparent: String(0x00FF00), - duration: "Math.PI / period", - params: { - period: { - type: "float", - init: 5.0, - min: 1.0, - max: 10.0, - step: 0.1, - }, - scale: { - type: "float", - init: 0.30, - min: 0.0, - max: 1.0, - step: 0.01, - } - }, - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform float period;\nuniform float scale;\n\nvarying vec2 uv;\n\nvoid main() {\n vec2 offset = vec2(0.0, (2.0 * abs(sin(time * period)) - 1.0) * (1.0 - scale));\n gl_Position = vec4(meshPosition * scale + offset, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", - }, - Circle: { - transparent: String(0x00FF00), - duration: "Math.PI / 4.0", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvec2 rotate(vec2 v, float a) {\n\tfloat s = sin(a);\n\tfloat c = cos(a);\n\tmat2 m = mat2(c, -s, s, c);\n\treturn m * v;\n}\n\nvoid main() {\n float scale = 0.30;\n float period_interval = 8.0;\n float pi = 3.141592653589793238;\n vec2 outer_circle = vec2(cos(period_interval * time), sin(period_interval * time)) * (1.0 - scale);\n vec2 inner_circle = rotate(meshPosition * scale, (-period_interval * time) + pi / 2.0);\n gl_Position = vec4(\n inner_circle + outer_circle,\n 0.0,\n 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n float speed = 1.0;\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", - }, - Slide: { - transparent: String(0x00FF00), - duration: "0.85 * 2", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nfloat sliding_from_left_to_right(float time_interval) {\n return (mod(time, time_interval) - time_interval * 0.5) / (time_interval * 0.5);\n}\n\nfloat flipping_directions(float time_interval) {\n return 1.0 - 2.0 * mod(floor(time / time_interval), 2.0);\n}\n\nvoid main() {\n float scale = 0.40;\n float hops = 2.0;\n float x_time_interval = 0.85;\n float y_time_interval = x_time_interval / (2.0 * hops);\n float height = 0.5;\n vec2 offset = vec2(\n sliding_from_left_to_right(x_time_interval) * flipping_directions(x_time_interval) * (1.0 - scale),\n - height);\n\n gl_Position = vec4(\n meshPosition * scale + offset,\n 0.0,\n 1.0);\n\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n\n uv.x = (flipping_directions(x_time_interval) + 1.0) / 2.0 - uv.x * flipping_directions(x_time_interval);\n}\n", - fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - Laughing: { - transparent: String(0x00FF00), - duration: "Math.PI / 12.0", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n float a = 0.3;\n float t = (sin(24.0 * time) * a + a) / 2.0;\n\n gl_Position = vec4(\n meshPosition - vec2(0.0, t),\n 0.0,\n 1.0);\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n}\n", - fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - Blob: { - transparent: String(0x00FF00), - duration: "Math.PI / 3", - vertex: "#version 100\n\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n float stretch = sin(6.0 * time) * 0.5 + 1.0;\n\n vec2 offset = vec2(0.0, 1.0 - stretch);\n gl_Position = vec4(\n meshPosition * vec2(stretch, 2.0 - stretch) + offset,\n 0.0,\n 1.0);\n uv = (meshPosition + vec2(1.0, 1.0)) / 2.0;\n}\n", - fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n" - }, - Go: { - transparent: String(0x00FF00), - duration: "1 / 4", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nfloat slide(float speed, float value) {\n return mod(value - speed * time, 1.0);\n}\n\nvoid main() {\n float speed = 4.0;\n gl_FragColor = texture2D(emote, vec2(slide(speed, uv.x), 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", - }, - Elevator: { - transparent: String(0x00FF00), - duration: "1 / 4", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nfloat slide(float speed, float value) {\n return mod(value - speed * time, 1.0);\n}\n\nvoid main() {\n float speed = 4.0;\n gl_FragColor = texture2D(\n emote,\n vec2(uv.x, slide(speed, 1.0 - uv.y)));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", - }, - Rain: { - transparent: String(0x00FF00), - duration: "1", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nfloat slide(float speed, float value) {\n return mod(value - speed * time, 1.0);\n}\n\nvoid main() {\n float speed = 1.0;\n gl_FragColor = texture2D(\n emote,\n vec2(mod(4.0 * slide(speed, uv.x), 1.0),\n mod(4.0 * slide(speed, 1.0 - uv.y), 1.0)));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", - }, - Pride: { - transparent: null, - duration: "2.0", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvec3 hsl2rgb(vec3 c) {\n vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0);\n return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));\n}\n\nvoid main() {\n float speed = 1.0;\n\n vec4 pixel = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n pixel.w = floor(pixel.w + 0.5);\n pixel = vec4(mix(vec3(1.0), pixel.xyz, pixel.w), 1.0);\n vec4 rainbow = vec4(hsl2rgb(vec3((time - uv.x - uv.y) * 0.5, 1.0, 0.80)), 1.0);\n gl_FragColor = pixel * rainbow;\n}\n", - }, - Hard: { - transparent: String(0x00FF00), - duration: "2.0 * Math.PI / intensity", - params: { - zoom: { - type: "float", - init: 1.4, - min: 0.0, - max: 6.9, - step: 0.1, - }, - intensity: { - type: "float", - init: 32.0, - min: 1.0, - max: 42.0, - step: 1.0, - }, - amplitude: { - type: "float", - init: 1.0 / 8.0, - min: 0.0, - max: 1.0 / 2.0, - step: 0.001, - }, - }, - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform float zoom;\nuniform float intensity;\nuniform float amplitude;\n\nvarying vec2 uv;\n\nvoid main() {\n vec2 shaking = vec2(cos(intensity * time), sin(intensity * time)) * amplitude;\n gl_Position = vec4(meshPosition * zoom + shaking, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", - }, - Peek: { - transparent: String(0x00FF00), - duration: "2.0 * Math.PI", - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n float time_clipped= mod(time * 2.0, (4.0 * 3.14));\n\n float s1 = float(time_clipped < (2.0 * 3.14));\n float s2 = 1.0 - s1;\n\n float hold1 = float(time_clipped > (0.5 * 3.14) && time_clipped < (2.0 * 3.14));\n float hold2 = 1.0 - float(time_clipped > (2.5 * 3.14) && time_clipped < (4.0 * 3.14));\n\n float cycle_1 = 1.0 - ((s1 * sin(time_clipped) * (1.0 - hold1)) + hold1);\n float cycle_2 = s2 * hold2 * (sin(time_clipped) - 1.0);\n\n gl_Position = vec4(meshPosition.x + 1.0 + cycle_1 + cycle_2 , meshPosition.y, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_FragColor = texture2D(emote, vec2(uv.x, 1.0 - uv.y));\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", - }, - Matrix: { - transparent: null, - duration: "3.0", - vertex: "\n #version 100\n precision mediump float;\n\n attribute vec2 meshPosition;\n\n uniform vec2 resolution;\n uniform float time;\n\n varying vec2 _uv;\n\n void main()\n {\n _uv = (meshPosition + 1.0) / 2.0;\n gl_Position = vec4(meshPosition.x, meshPosition.y, 0.0, 1.0);\n }\n ", - fragment: "\n #version 100\n precision mediump float;\n\n uniform vec2 resolution;\n uniform float time;\n uniform sampler2D emote;\n\n varying vec2 _uv;\n\n float clamp01(float value)\n {\n return clamp(value, 0.0, 1.0);\n }\n\n float sdf_zero(vec2 uv)\n {\n float inside = step(0.15, abs(uv.x)) + step(0.3, abs(uv.y));\n float outside = step(0.35, abs(uv.x)) + step(0.4, abs(uv.y));\n return clamp01(inside) - clamp01(outside);\n }\n\n float sdf_one(vec2 uv)\n {\n float top = step(0.25, -uv.y) * step(0.0, uv.x);\n float inside = (step(0.2, uv.x) + top);\n float outside = step(0.35, abs(uv.x)) + step(0.4, abs(uv.y));\n return clamp01(clamp01(inside) - clamp01(outside));\n }\n\n // Random float. No precomputed gradients mean this works for any number of grid coordinates\n float random01(vec2 n)\n {\n float random = 2920.0 * sin(n.x * 21942.0 + n.y * 171324.0 + 8912.0) *\n cos(n.x * 23157.0 * n.y * 217832.0 + 9758.0);\n\n return (sin(random) + 1.0) / 2.0;\n }\n\n float loop_time(float time_frame)\n {\n float times = floor(time / time_frame);\n return time - (times * time_frame);\n }\n\n void main()\n {\n vec2 uv = _uv;\n uv.y = 1.0 - _uv.y;\n\n float number_of_numbers = 8.0;\n float number_change_rate = 2.0;\n float amount_of_numbers = 0.6; // from 0 - 1\n\n vec4 texture_color = texture2D(emote, uv);\n vec4 number_color = vec4(0, 0.7, 0, 1);\n\n float looped_time = loop_time(3.0);\n\n vec2 translation = vec2(0, looped_time * -8.0);\n\n vec2 pos_idx = floor(uv * number_of_numbers + translation);\n float rnd_number = step(0.5, random01(pos_idx + floor(looped_time * number_change_rate)));\n float rnd_show = step(1.0 - amount_of_numbers, random01(pos_idx + vec2(99,99)));\n\n vec2 nuv = uv * number_of_numbers + translation;\n nuv = fract(nuv);\n\n float one = sdf_one(nuv - 0.5) * rnd_number;\n float zero = sdf_zero(nuv - 0.5) * (1.0 - rnd_number);\n float number = (one + zero) * rnd_show;\n\n float is_texture = 1.0 - number;\n float is_number = number;\n\n vec4 col = (texture_color * is_texture) + (number_color * is_number);\n\n gl_FragColor = col;\n gl_FragColor.w = 1.0;\n }\n " - }, - Flag: { - transparent: String(0x00FF00), - duration: "Math.PI", - vertex: "\n #version 100\n precision mediump float;\n\n attribute vec2 meshPosition;\n\n uniform vec2 resolution;\n uniform float time;\n\n varying vec2 _uv;\n\n void main()\n {\n _uv = (meshPosition + 1.0) / 2.0;\n _uv.y = 1.0 - _uv.y;\n gl_Position = vec4(meshPosition.x, meshPosition.y, 0.0, 1.0);\n }\n ", - fragment: "\n #version 100\n precision mediump float;\n\n varying vec2 _uv;\n uniform sampler2D emote;\n uniform float time;\n\n float sin01(float value)\n {\n return (sin(value) + 1.0) / 2.0;\n }\n\n //pos is left bottom point.\n float sdf_rect(vec2 pos, vec2 size, vec2 uv)\n {\n float left = pos.x;\n float right = pos.x + size.x;\n float bottom = pos.y;\n float top = pos.y + size.y;\n return (step(bottom, uv.y) - step(top, uv.y)) * (step(left, uv.x) - step(right, uv.x));\n }\n\n void main() {\n float stick_width = 0.1;\n float flag_height = 0.75;\n float wave_size = 0.08;\n vec4 stick_color = vec4(107.0 / 256.0, 59.0 / 256.0, 9.0 / 256.0,1);\n\n vec2 flag_uv = _uv;\n flag_uv.x = (1.0 / (1.0 - stick_width)) * (flag_uv.x - stick_width);\n flag_uv.y *= 1.0 / flag_height;\n\n float flag_close_to_stick = smoothstep(0.0, 0.5, flag_uv.x);\n flag_uv.y += sin((-time * 2.0) + (flag_uv.x * 8.0)) * flag_close_to_stick * wave_size;\n\n float is_flag = sdf_rect(vec2(0,0), vec2(1.0, 1.0), flag_uv);\n float is_flag_stick = sdf_rect(vec2(0.0, 0.0), vec2(stick_width, 1), _uv);\n\n vec4 emote_color = texture2D(emote, flag_uv);\n vec4 texture_color = (emote_color * is_flag) + (stick_color * is_flag_stick);\n\n gl_FragColor = texture_color;\n }\n " - }, - Thanosed: { - transparent: String(0x00FF00), - duration: "duration", - params: { - duration: { - type: "float", - init: 6.0, - min: 1.0, - max: 16.0, - step: 1.0, - }, - delay: { - type: "float", - init: 0.2, - min: 0.0, - max: 1.0, - step: 0.1, - }, - pixelization: { - type: "float", - init: 1.0, - min: 1.0, - max: 3.0, - step: 1.0, - }, - }, - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "\n#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\nuniform float duration;\nuniform float delay;\nuniform float pixelization;\n\nuniform sampler2D emote;\n\nvarying vec2 uv;\n\n// https://www.aussiedwarf.com/2017/05/09/Random10Bit.html\nfloat rand(vec2 co){\n vec3 product = vec3( sin( dot(co, vec2(0.129898,0.78233))),\n sin( dot(co, vec2(0.689898,0.23233))),\n sin( dot(co, vec2(0.434198,0.51833))) );\n vec3 weighting = vec3(4.37585453723, 2.465973, 3.18438);\n return fract(dot(weighting, product));\n}\n\nvoid main() {\n float pixelated_resolution = 112.0 / pixelization;\n vec2 pixelated_uv = floor(uv * pixelated_resolution);\n float noise = (rand(pixelated_uv) + 1.0) / 2.0;\n float slope = (0.2 + noise * 0.8) * (1.0 - (0.0 + uv.x * 0.5));\n float time_interval = 1.1 + delay * 2.0;\n float progress = 0.2 + delay + slope - mod(time_interval * time / duration, time_interval);\n float mask = progress > 0.1 ? 1.0 : 0.0;\n vec4 pixel = texture2D(emote, vec2(uv.x * (progress > 0.5 ? 1.0 : progress * 2.0), 1.0 - uv.y));\n pixel.w = floor(pixel.w + 0.5);\n gl_FragColor = pixel * vec4(vec3(1.0), mask);\n}\n", - }, - Ripple: { - transparent: String(0x00FF00), - duration: "2 * Math.PI / b", - params: { - a: { - label: "Wave Length", - type: "float", - init: 12.0, - min: 0.01, - max: 24.0, - step: 0.01, - }, - b: { - label: "Time Freq", - type: "float", - init: 4.0, - min: 0.01, - max: 8.0, - step: 0.01, - }, - c: { - label: "Amplitude", - type: "float", - init: 0.03, - min: 0.01, - max: 0.06, - step: 0.01, - } - }, - vertex: "#version 100\nprecision mediump float;\n\nattribute vec2 meshPosition;\n\nuniform vec2 resolution;\nuniform float time;\n\nvarying vec2 uv;\n\nvoid main() {\n gl_Position = vec4(meshPosition, 0.0, 1.0);\n uv = (meshPosition + 1.0) / 2.0;\n}\n", - fragment: "#version 100\n\nprecision mediump float;\n\nuniform vec2 resolution;\nuniform float time;\n\nuniform sampler2D emote;\n\nuniform float a;\nuniform float b;\nuniform float c;\n\nvarying vec2 uv;\n\nvoid main() {\n vec2 pos = vec2(uv.x, 1.0 - uv.y);\n vec2 center = vec2(0.5);\n vec2 dir = pos - center;\n float x = length(dir);\n float y = sin(x + time);\n vec4 pixel = texture2D(emote, pos + cos(x*a - time*b)*c*(dir/x));\n gl_FragColor = pixel;\n gl_FragColor.w = floor(gl_FragColor.w + 0.5);\n}\n", - } -}; diff --git a/js/grecha.js b/js/grecha.js deleted file mode 100644 index e7a983c..0000000 --- a/js/grecha.js +++ /dev/null @@ -1,123 +0,0 @@ -"use strict"; -var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { - if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { - if (ar || !(i in from)) { - if (!ar) ar = Array.prototype.slice.call(from, 0, i); - ar[i] = from[i]; - } - } - return to.concat(ar || Array.prototype.slice.call(from)); -}; -function tag(name) { - var children = []; - for (var _i = 1; _i < arguments.length; _i++) { - children[_i - 1] = arguments[_i]; - } - var result = document.createElement(name); - for (var _a = 0, children_1 = children; _a < children_1.length; _a++) { - var child = children_1[_a]; - if (typeof child === 'string') { - result.appendChild(document.createTextNode(child)); - } - else { - result.appendChild(child); - } - } - result.att$ = function (name, value) { - this.setAttribute(name, value); - return this; - }; - result.onclick$ = function (callback) { - this.onclick = callback; - return this; - }; - return result; -} -var canvas = function () { - var children = []; - for (var _i = 0; _i < arguments.length; _i++) { - children[_i] = arguments[_i]; - } - return tag.apply(void 0, __spreadArray(["canvas"], children, false)); -}; -var h1 = function () { - var children = []; - for (var _i = 0; _i < arguments.length; _i++) { - children[_i] = arguments[_i]; - } - return tag.apply(void 0, __spreadArray(["h1"], children, false)); -}; -var h2 = function () { - var children = []; - for (var _i = 0; _i < arguments.length; _i++) { - children[_i] = arguments[_i]; - } - return tag.apply(void 0, __spreadArray(["h2"], children, false)); -}; -var h3 = function () { - var children = []; - for (var _i = 0; _i < arguments.length; _i++) { - children[_i] = arguments[_i]; - } - return tag.apply(void 0, __spreadArray(["h3"], children, false)); -}; -var p = function () { - var children = []; - for (var _i = 0; _i < arguments.length; _i++) { - children[_i] = arguments[_i]; - } - return tag.apply(void 0, __spreadArray(["p"], children, false)); -}; -var a = function () { - var children = []; - for (var _i = 0; _i < arguments.length; _i++) { - children[_i] = arguments[_i]; - } - return tag.apply(void 0, __spreadArray(["a"], children, false)); -}; -var div = function () { - var children = []; - for (var _i = 0; _i < arguments.length; _i++) { - children[_i] = arguments[_i]; - } - return tag.apply(void 0, __spreadArray(["div"], children, false)); -}; -var span = function () { - var children = []; - for (var _i = 0; _i < arguments.length; _i++) { - children[_i] = arguments[_i]; - } - return tag.apply(void 0, __spreadArray(["span"], children, false)); -}; -var select = function () { - var children = []; - for (var _i = 0; _i < arguments.length; _i++) { - children[_i] = arguments[_i]; - } - return tag.apply(void 0, __spreadArray(["select"], children, false)); -}; -var img = function (src) { return tag("img").att$("src", src); }; -var input = function (type) { return tag("input").att$("type", type); }; -function router(routes) { - var result = div(); - function syncHash() { - var hashLocation = document.location.hash.split('#')[1]; - if (!hashLocation) { - hashLocation = '/'; - } - if (!(hashLocation in routes)) { - var route404 = '/404'; - console.assert(route404 in routes); - hashLocation = route404; - } - while (result.firstChild) { - result.removeChild(result.lastChild); - } - result.appendChild(routes[hashLocation]); - return result; - } - ; - syncHash(); - window.addEventListener("hashchange", syncHash); - return result; -} diff --git a/js/index.js b/js/index.js deleted file mode 100644 index f248be5..0000000 --- a/js/index.js +++ /dev/null @@ -1,435 +0,0 @@ -"use strict"; -var feature_params = false; -var vertexAttribs = { - "meshPosition": 0 -}; -var TRIANGLE_PAIR = 2; -var TRIANGLE_VERTICIES = 3; -var VEC2_COUNT = 2; -var VEC2_X = 0; -var VEC2_Y = 1; -var CANVAS_WIDTH = 112; -var CANVAS_HEIGHT = 112; -function compileShaderSource(gl, source, shaderType) { - function shaderTypeToString() { - switch (shaderType) { - case gl.VERTEX_SHADER: return 'Vertex'; - case gl.FRAGMENT_SHADER: return 'Fragment'; - default: return shaderType; - } - } - var shader = gl.createShader(shaderType); - if (shader === null) { - throw new Error("Could not create a new shader"); - } - gl.shaderSource(shader, source); - gl.compileShader(shader); - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - throw new Error("Could not compile ".concat(shaderTypeToString(), " shader: ").concat(gl.getShaderInfoLog(shader))); - } - return shader; -} -function linkShaderProgram(gl, shaders, vertexAttribs) { - var program = gl.createProgram(); - if (program === null) { - throw new Error('Could not create a new shader program'); - } - for (var _i = 0, shaders_1 = shaders; _i < shaders_1.length; _i++) { - var shader = shaders_1[_i]; - gl.attachShader(program, shader); - } - for (var _a = 0, _b = Object.entries(vertexAttribs); _a < _b.length; _a++) { - var _c = _b[_a], vertexName = _c[0], vertexVal = _c[1]; - gl.bindAttribLocation(program, vertexVal, vertexName); - } - gl.linkProgram(program); - if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { - throw new Error("Could not link shader program: ".concat(gl.getProgramInfoLog(program))); - } - return program; -} -function createTextureFromImage(gl, image) { - var textureId = gl.createTexture(); - if (textureId === null) { - throw new Error('Could not create a new WebGL texture'); - } - gl.bindTexture(gl.TEXTURE_2D, textureId); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, image); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - return textureId; -} -function loadFilterProgram(gl, filter, vertexAttribs) { - var _a; - var vertexShader = compileShaderSource(gl, filter.vertex, gl.VERTEX_SHADER); - var fragmentShader = compileShaderSource(gl, filter.fragment, gl.FRAGMENT_SHADER); - var id = linkShaderProgram(gl, [vertexShader, fragmentShader], vertexAttribs); - gl.deleteShader(vertexShader); - gl.deleteShader(fragmentShader); - gl.useProgram(id); - var uniforms = { - resolution: gl.getUniformLocation(id, 'resolution'), - time: gl.getUniformLocation(id, 'time'), - emoteSize: gl.getUniformLocation(id, 'emoteSize'), - }; - var paramsPanel = div().att$("class", "widget-element"); - var paramsInputs = {}; - if (!filter.params) - throw new Error("unknown error"); - var _loop_1 = function (paramName, paramVal) { - if (paramName in uniforms) { - throw new Error("Redefinition of existing uniform parameter ".concat(paramName)); - } - switch (paramVal.type) { - case "float": - { - var valuePreview_1 = span(paramVal.init.toString()); - var valueInput = input("range"); - if (paramVal.min !== undefined) { - valueInput.att$("min", String(paramVal.min)); - } - if (paramVal.max !== undefined) { - valueInput.att$("max", String(paramVal.max)); - } - if (paramVal.step !== undefined) { - valueInput.att$("step", String(paramVal.step)); - } - if (paramVal.init !== undefined) { - valueInput.att$("value", String(paramVal.init)); - } - paramsInputs[paramName] = valueInput; - valueInput.oninput = function () { - valuePreview_1.innerText = this.value; - paramsPanel.dispatchEvent(new CustomEvent("paramsChanged")); - }; - var label = (_a = paramVal.label) !== null && _a !== void 0 ? _a : paramName; - paramsPanel.appendChild(div(span("".concat(label, ": ")), valuePreview_1, div(valueInput))); - } - break; - default: { - throw new Error("Filter parameters do not support type ".concat(paramVal.type)); - } - } - uniforms[paramName] = gl.getUniformLocation(id, paramName); - }; - for (var _i = 0, _b = Object.entries(filter.params); _i < _b.length; _i++) { - var _c = _b[_i], paramName = _c[0], paramVal = _c[1]; - _loop_1(paramName, paramVal); - } - paramsPanel.paramsSnapshot$ = function () { - var snapshot = {}; - for (var paramName in paramsInputs) { - snapshot[paramName] = { - uniform: uniforms[paramName], - value: Number(paramsInputs[paramName].value) - }; - } - return snapshot; - }; - return { - id: id, - uniforms: uniforms, - duration: compile_expr(filter.duration), - transparent: filter.transparent, - paramsPanel: paramsPanel, - }; -} -function ImageSelector() { - var imageInput = input("file"); - var imagePreview = img("img/tsodinClown.png") - .att$("class", "widget-element") - .att$("width", String(CANVAS_WIDTH)); - var root = div(div(imageInput).att$("class", "widget-element"), imagePreview).att$("class", "widget"); - root.selectedImage$ = function () { - return imagePreview; - }; - root.selectedFileName$ = function () { - function removeFileNameExt(fileName) { - if (fileName.includes('.')) { - return fileName.split('.').slice(0, -1).join('.'); - } - else { - return fileName; - } - } - var file = imageInput.files[0]; - return file ? removeFileNameExt(file.name) : 'result'; - }; - root.updateFiles$ = function (files) { - var _a; - imageInput.files = files; - (_a = imageInput.onchange) === null || _a === void 0 ? void 0 : _a.call(imageInput); - }; - imagePreview.addEventListener('load', function () { - root.dispatchEvent(new CustomEvent("imageSelected", { - detail: { - imageData: this - } - })); - }); - imagePreview.addEventListener('error', function () { - imageInput.value = ''; - this.src = 'img/error.png'; - }); - imageInput.onchange = function () { - imagePreview.src = URL.createObjectURL(this.files[0]); - }; - return root; -} -function FilterList() { - var root = select(); - for (var name_1 in filters) { - root.add(new Option(name_1)); - } - root.selectedFilter$ = function () { - return filters[root.selectedOptions[0].value]; - }; - root.onchange = function () { - root.dispatchEvent(new CustomEvent('filterChanged', { - detail: { - filter: root.selectedFilter$() - } - })); - }; - root.addEventListener('wheel', function (e) { - var _a; - e.preventDefault(); - if (e.deltaY < 0) { - root.selectedIndex = Math.max(root.selectedIndex - 1, 0); - } - if (e.deltaY > 0) { - root.selectedIndex = Math.min(root.selectedIndex + 1, root.length - 1); - } - (_a = root.onchange) === null || _a === void 0 ? void 0 : _a.call(root); - }); - return root; -} -function FilterSelector() { - var filterList_ = FilterList(); - var filterPreview = canvas() - .att$("width", String(CANVAS_WIDTH)) - .att$("height", String(CANVAS_HEIGHT)); - var root = div(div("Filter: ", filterList_) - .att$("class", "widget-element"), filterPreview.att$("class", "widget-element")).att$("class", "widget"); - var gl = filterPreview.getContext("webgl", { antialias: false, alpha: false }); - if (!gl) { - throw new Error("Could not initialize WebGL context"); - } - gl.enable(gl.BLEND); - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); - { - var meshPositionBufferData = new Float32Array(TRIANGLE_PAIR * TRIANGLE_VERTICIES * VEC2_COUNT); - for (var triangle = 0; triangle < TRIANGLE_PAIR; ++triangle) { - for (var vertex = 0; vertex < TRIANGLE_VERTICIES; ++vertex) { - var quad = triangle + vertex; - var index = triangle * TRIANGLE_VERTICIES * VEC2_COUNT + - vertex * VEC2_COUNT; - meshPositionBufferData[index + VEC2_X] = (2 * (quad & 1) - 1); - meshPositionBufferData[index + VEC2_Y] = (2 * ((quad >> 1) & 1) - 1); - } - } - var meshPositionBuffer = gl.createBuffer(); - gl.bindBuffer(gl.ARRAY_BUFFER, meshPositionBuffer); - gl.bufferData(gl.ARRAY_BUFFER, meshPositionBufferData, gl.STATIC_DRAW); - var meshPositionAttrib = vertexAttribs['meshPosition']; - gl.vertexAttribPointer(meshPositionAttrib, VEC2_COUNT, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(meshPositionAttrib); - } - var emoteImage = undefined; - var emoteTexture = undefined; - var program = undefined; - function syncParams() { - if (program) { - var snapshot = program.paramsPanel.paramsSnapshot$(); - for (var paramName in snapshot) { - gl.uniform1f(snapshot[paramName].uniform, snapshot[paramName].value); - } - } - } - program = loadFilterProgram(gl, filterList_.selectedFilter$(), vertexAttribs); - program.paramsPanel.addEventListener('paramsChanged', syncParams); - if (feature_params) { - root.appendChild(program.paramsPanel); - } - syncParams(); - root.updateImage$ = function (newEmoteImage) { - emoteImage = newEmoteImage; - if (emoteTexture) { - gl.deleteTexture(emoteTexture); - } - emoteTexture = createTextureFromImage(gl, emoteImage); - }; - filterList_.addEventListener('filterChanged', function (e) { - if (program) { - gl.deleteProgram(program.id); - program.paramsPanel.removeEventListener('paramsChanged', syncParams); - if (feature_params) { - root.removeChild(program.paramsPanel); - } - } - program = loadFilterProgram(gl, e.detail.filter, vertexAttribs); - program.paramsPanel.addEventListener('paramsChanged', syncParams); - if (feature_params) { - root.appendChild(program.paramsPanel); - } - syncParams(); - }); - root.render$ = function (filename) { - if (program === undefined) { - console.warn('Could not rendering anything because the filter was not selected'); - return undefined; - } - if (emoteImage == undefined) { - console.warn('Could not rendering anything because the image was not selected'); - return undefined; - } - var gif = new GIF({ - workers: 5, - quality: 10, - width: CANVAS_WIDTH, - height: CANVAS_HEIGHT, - transparent: program.transparent, - }); - var context = { - vars: { - "Math.PI": Math.PI - } - }; - if (context.vars !== undefined) { - var snapshot = program.paramsPanel.paramsSnapshot$(); - for (var paramName in snapshot) { - context.vars[paramName] = snapshot[paramName].value; - } - } - var fps = 30; - var dt = 1.0 / fps; - var duration = Math.min(run_expr(program.duration, context), 60); - var renderProgress = document.getElementById("render-progress"); - if (renderProgress === null) { - throw new Error('Could not find "render-progress"'); - } - var renderSpinner = document.getElementById("render-spinner"); - if (renderSpinner === null) { - throw new Error('Could not find "render-spinner"'); - } - var renderPreview = document.getElementById("render-preview"); - if (renderPreview === null) { - throw new Error('Could not find "render-preview"'); - } - var renderDownload = document.getElementById("render-download"); - if (renderDownload === null) { - throw new Error('Could not find "render-download"'); - } - renderPreview.style.display = "none"; - renderSpinner.style.display = "block"; - var t = 0.0; - while (t <= duration) { - gl.uniform1f(program.uniforms.time, t); - gl.uniform2f(program.uniforms.resolution, CANVAS_WIDTH, CANVAS_HEIGHT); - gl.uniform2f(program.uniforms.emoteSize, emoteImage.width, emoteImage.height); - gl.clearColor(0.0, 1.0, 0.0, 1.0); - gl.clear(gl.COLOR_BUFFER_BIT); - gl.drawArrays(gl.TRIANGLES, 0, TRIANGLE_PAIR * TRIANGLE_VERTICIES); - var pixels = new Uint8ClampedArray(4 * CANVAS_WIDTH * CANVAS_HEIGHT); - gl.readPixels(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT, gl.RGBA, gl.UNSIGNED_BYTE, pixels); - { - var center = Math.floor(CANVAS_HEIGHT / 2); - for (var y = 0; y < center; ++y) { - var row = 4 * CANVAS_WIDTH; - for (var x = 0; x < row; ++x) { - var ai = y * 4 * CANVAS_WIDTH + x; - var bi = (CANVAS_HEIGHT - y - 1) * 4 * CANVAS_WIDTH + x; - var a_1 = pixels[ai]; - var b = pixels[bi]; - pixels[ai] = b; - pixels[bi] = a_1; - } - } - } - gif.addFrame(new ImageData(pixels, CANVAS_WIDTH, CANVAS_HEIGHT), { - delay: dt * 1000, - dispose: 2, - }); - renderProgress.style.width = "".concat((t / duration) * 50, "%"); - t += dt; - } - gif.on('finished', function (blob) { - renderPreview.src = URL.createObjectURL(blob); - renderPreview.style.display = "block"; - renderDownload.href = renderPreview.src; - renderDownload.download = filename; - renderDownload.style.display = "block"; - renderSpinner.style.display = "none"; - }); - gif.on('progress', function (p) { - renderProgress.style.width = "".concat(50 + p * 50, "%"); - }); - gif.render(); - return gif; - }; - { - var step_1 = function (timestamp) { - gl.clearColor(0.0, 1.0, 0.0, 1.0); - gl.clear(gl.COLOR_BUFFER_BIT); - if (program && emoteImage) { - gl.uniform1f(program.uniforms.time, timestamp * 0.001); - gl.uniform2f(program.uniforms.resolution, filterPreview.width, filterPreview.height); - gl.uniform2f(program.uniforms.emoteSize, emoteImage.width, emoteImage.height); - gl.drawArrays(gl.TRIANGLES, 0, TRIANGLE_PAIR * TRIANGLE_VERTICIES); - } - window.requestAnimationFrame(step_1); - }; - window.requestAnimationFrame(step_1); - } - return root; -} -window.onload = function () { - if ("serviceWorker" in navigator) { - navigator.serviceWorker.register('serviceworker.js').then(function (registration) { - console.log("Registered a Service Worker ", registration); - }, function (error) { - console.error("Could not register a Service Worker ", error); - }); - } - else { - console.error("Service Workers are not supported in this browser."); - } - feature_params = new URLSearchParams(document.location.search).has("feature-params"); - var filterSelectorEntry = document.getElementById('filter-selector-entry'); - if (filterSelectorEntry === null) { - throw new Error('Could not find "filter-selector-entry"'); - } - var imageSelectorEntry = document.getElementById('image-selector-entry'); - if (imageSelectorEntry === null) { - throw new Error('Could not find "image-selector-entry"'); - } - var imageSelector = ImageSelector(); - var filterSelector = FilterSelector(); - imageSelector.addEventListener('imageSelected', function (e) { - filterSelector.updateImage$(e.detail.imageData); - }); - filterSelectorEntry.appendChild(filterSelector); - imageSelectorEntry.appendChild(imageSelector); - document.ondrop = function (event) { - var _a; - event.preventDefault(); - imageSelector.updateFiles$((_a = event.dataTransfer) === null || _a === void 0 ? void 0 : _a.files); - }; - document.ondragover = function (event) { - event.preventDefault(); - }; - var gif = undefined; - var renderButton = document.getElementById("render"); - if (renderButton === null) { - throw new Error('Could not find "render"'); - } - renderButton.onclick = function () { - if (gif === null || gif === void 0 ? void 0 : gif.running) { - gif.abort(); - } - var fileName = imageSelector.selectedFileName$(); - gif = filterSelector.render$("".concat(fileName, ".gif")); - }; -}; diff --git a/package-lock.json b/package-lock.json index b6ac677..c54c2ac 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,9 @@ "name": "emotejam", "version": "1.0.0", "license": "MIT", + "dependencies": { + "@dhdbstjr98/gif.js": "^1.0.2" + }, "devDependencies": { "@types/gif.js": "^0.2.5", "@types/node": "^22", @@ -15,6 +18,16 @@ "vite": "^5.4.0" } }, + "node_modules/@dhdbstjr98/gif.js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@dhdbstjr98/gif.js/-/gif.js-1.0.2.tgz", + "integrity": "sha512-0XZTm2r9z5HLANwRnBOmHZOdFrLRzm7Sh0x5PIQGfEPa21bD1eb2VSOoAcyCMe1gXaBeekd7/l0JCgm0C6o3YA==", + "license": "MIT", + "dependencies": { + "buffer": "^6.0.3", + "events": "^3.3.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -664,6 +677,50 @@ "undici-types": "~6.18.2" } }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "node_modules/esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -703,6 +760,15 @@ "@esbuild/win32-x64": "0.21.5" } }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "license": "MIT", + "engines": { + "node": ">=0.8.x" + } + }, "node_modules/fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -718,6 +784,26 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", @@ -902,6 +988,15 @@ } }, "dependencies": { + "@dhdbstjr98/gif.js": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@dhdbstjr98/gif.js/-/gif.js-1.0.2.tgz", + "integrity": "sha512-0XZTm2r9z5HLANwRnBOmHZOdFrLRzm7Sh0x5PIQGfEPa21bD1eb2VSOoAcyCMe1gXaBeekd7/l0JCgm0C6o3YA==", + "requires": { + "buffer": "^6.0.3", + "events": "^3.3.0" + } + }, "@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -1205,6 +1300,20 @@ "undici-types": "~6.18.2" } }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==" + }, + "buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, "esbuild": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.21.5.tgz", @@ -1236,6 +1345,11 @@ "@esbuild/win32-x64": "0.21.5" } }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==" + }, "fsevents": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", @@ -1243,6 +1357,11 @@ "dev": true, "optional": true }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + }, "nanoid": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", diff --git a/package.json b/package.json index ed25420..ee782fe 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,10 @@ "main": "index.js", "type": "module", "scripts": { - "build": "node build.js build", - "watch": "node build.js watch", - "serve": "node build.js serve", + "build": "vite build", + "dev": "vite ", + "serve": "vite preview", + "lint" : "tsc --noEmit", "test": "echo \"Error: no test specified\" && exit 1" }, "repository": { @@ -34,5 +35,8 @@ "@types/node": "^22", "typescript": "^5.5", "vite": "^5.4.0" + }, + "dependencies": { + "@dhdbstjr98/gif.js": "^1.0.2" } } diff --git a/img/error.png b/public/img/error.png similarity index 100% rename from img/error.png rename to public/img/error.png diff --git a/img/error.svg b/public/img/error.svg similarity index 100% rename from img/error.svg rename to public/img/error.svg diff --git a/img/tsodinClown.png b/public/img/tsodinClown.png similarity index 100% rename from img/tsodinClown.png rename to public/img/tsodinClown.png diff --git a/serviceworker.js b/serviceworker.js deleted file mode 100644 index cf49771..0000000 --- a/serviceworker.js +++ /dev/null @@ -1,131 +0,0 @@ -"use strict"; -var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { - function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } - return new (P || (P = Promise))(function (resolve, reject) { - function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } - function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } - function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } - step((generator = generator.apply(thisArg, _arguments || [])).next()); - }); -}; -var __generator = (this && this.__generator) || function (thisArg, body) { - var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; - return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; - function verb(n) { return function (v) { return step([n, v]); }; } - function step(op) { - if (f) throw new TypeError("Generator is already executing."); - while (g && (g = 0, op[0] && (_ = 0)), _) try { - if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; - if (y = 0, t) op = [op[0] & 2, t.value]; - switch (op[0]) { - case 0: case 1: t = op; break; - case 4: _.label++; return { value: op[1], done: false }; - case 5: _.label++; y = op[1]; op = [0]; continue; - case 7: op = _.ops.pop(); _.trys.pop(); continue; - default: - if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } - if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } - if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } - if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } - if (t[2]) _.ops.pop(); - _.trys.pop(); continue; - } - op = body.call(thisArg, _); - } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } - if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; - } -}; -var cacheName = "emoteJAM-v1"; -var assets = [ - 'index.html', - 'css/bright.css', - 'css/main.css', - 'css/reset.css', - 'gif.js', - 'gif.worker.js', - 'img/tsodinClown.png', - 'js/eval.js', - 'js/filters.js', - 'js/grecha.js', - 'js/index.js', -]; -self.addEventListener("install", function (e) { - console.log("[Service Worker] Install"); - var event = e; - event.waitUntil((function () { return __awaiter(void 0, void 0, void 0, function () { - var cache; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - console.log("[Service Worker] Caching all the assets"); - return [4, caches.open(cacheName)]; - case 1: - cache = _a.sent(); - cache.addAll(assets); - return [2]; - } - }); - }); })()); -}); -self.addEventListener("activate", function (e) { - console.log("[Service Worker] Activate"); - var event = e; - event.waitUntil((function () { return __awaiter(void 0, void 0, void 0, function () { - var keys, _a, _b, _c, _i, key; - return __generator(this, function (_d) { - switch (_d.label) { - case 0: - console.log("[Service Worker] Cleaning up all caches"); - return [4, caches.keys()]; - case 1: - keys = _d.sent(); - _a = keys; - _b = []; - for (_c in _a) - _b.push(_c); - _i = 0; - _d.label = 2; - case 2: - if (!(_i < _b.length)) return [3, 5]; - _c = _b[_i]; - if (!(_c in _a)) return [3, 4]; - key = _c; - if (!(key !== cacheName)) return [3, 4]; - return [4, caches.delete(key)]; - case 3: - _d.sent(); - _d.label = 4; - case 4: - _i++; - return [3, 2]; - case 5: return [2]; - } - }); - }); })()); -}); -self.addEventListener("fetch", function (e) { - var event = e; - event.respondWith((function () { return __awaiter(void 0, void 0, void 0, function () { - var cache, response; - return __generator(this, function (_a) { - switch (_a.label) { - case 0: - console.log("[Service Worker] Fetch ".concat(event.request.url)); - return [4, caches.open(cacheName)]; - case 1: - cache = _a.sent(); - return [4, cache.match(event.request.url)]; - case 2: - response = _a.sent(); - if (!(response === undefined)) return [3, 4]; - console.log("[Service Worker] Response for ".concat(event.request.url, " is not available in cache. Making an actual request...")); - return [4, fetch(event.request.url)]; - case 3: - response = _a.sent(); - cache.put(event.request.url, response.clone()); - _a.label = 4; - case 4: return [2, response]; - } - }); - }); })()); -}); diff --git a/serviceworker.ts b/serviceworker.ts deleted file mode 100644 index 58be3a4..0000000 --- a/serviceworker.ts +++ /dev/null @@ -1,53 +0,0 @@ -const cacheName = "emoteJAM-v1"; -const assets = [ - 'index.html', - 'css/bright.css', - 'css/main.css', - 'css/reset.css', - 'gif.js', - 'gif.worker.js', - 'img/tsodinClown.png', - 'js/eval.js', - 'js/filters.js', - 'js/grecha.js', - 'js/index.js', -]; - -self.addEventListener("install", e => { - console.log("[Service Worker] Install"); - const event = e as ExtendableEvent; - event.waitUntil((async () => { - console.log("[Service Worker] Caching all the assets"); - const cache = await caches.open(cacheName); - cache.addAll(assets); - })()); -}); - -self.addEventListener("activate", e => { - console.log("[Service Worker] Activate"); - const event = e as ExtendableEvent; - event.waitUntil((async() => { - console.log("[Service Worker] Cleaning up all caches"); - const keys = await caches.keys(); - for (let key in keys) { - if (key !== cacheName) { - await caches.delete(key); - } - } - })()); -}); - -self.addEventListener("fetch", (e) => { - const event = e as FetchEvent; - event.respondWith((async () => { - console.log(`[Service Worker] Fetch ${event.request.url}`); - const cache = await caches.open(cacheName); - let response = await cache.match(event.request.url); - if (response === undefined) { - console.log(`[Service Worker] Response for ${event.request.url} is not available in cache. Making an actual request...`); - response = await fetch(event.request.url); - cache.put(event.request.url, response.clone()); - } - return response; - })()); -}); diff --git a/ts/eval.ts b/src/eval.ts similarity index 95% rename from ts/eval.ts rename to src/eval.ts index c134761..921280f 100644 --- a/ts/eval.ts +++ b/src/eval.ts @@ -1,5 +1,5 @@ -type BinaryOp = '+' | '-' | '*' | '/' | '%'; -type BinaryOpFunc = (lhs: number, rhs: number) => number; +export type BinaryOp = '+' | '-' | '*' | '/' | '%'; +export type BinaryOpFunc = (lhs: number, rhs: number) => number; enum BinaryPrec { PREC0 = 0, @@ -42,7 +42,7 @@ const UNARY_OPS: Record = { '-': (arg: number) => -arg, }; -class Lexer { +export class Lexer { src: string constructor(src: string) { @@ -107,7 +107,7 @@ interface SymbolExpr { value: string } -interface Expr { +export interface Expr { kind: ExprKind, payload: UnaryOpExpr | BinaryOpExpr | FuncallExpr | SymbolExpr } @@ -217,7 +217,7 @@ function parse_expr(lexer: Lexer, prec: BinaryPrec = BinaryPrec.PREC0): Expr { return lhs; } -function compile_expr(src: string): Expr { +export function compile_expr(src: string): Expr { const lexer = new Lexer(src); const result = parse_expr(lexer); const token = lexer.next(); @@ -229,12 +229,12 @@ function compile_expr(src: string): Expr { return result; } -interface UserContext { +export interface UserContext { vars?: Record, funcs?: Record number>, } -function run_expr(expr: Expr, user_context: UserContext = {}): number { +export function run_expr(expr: Expr, user_context: UserContext = {}): number { console.assert(typeof(expr) === 'object'); switch (expr.kind) { diff --git a/ts/filters.ts b/src/filters.ts similarity index 99% rename from ts/filters.ts rename to src/filters.ts index 4d51526..3763156 100644 --- a/ts/filters.ts +++ b/src/filters.ts @@ -7,7 +7,7 @@ type Param = { step?: number, } -type Filter = { +export type Filter = { transparent: string | null, duration: string, params?: Record, @@ -19,7 +19,7 @@ type FilterType = "Hop" | "Hopper" | "Overheat" | "Bounce" | "Circle" | "Slide" // TODO(#58): add params to all of the filters // TODO(#61): human readable titles for the filter params -const filters: Record = { +export const filters: Record = { Hop: { transparent: String(0x00FF00), duration: "interval * 2", diff --git a/ts/grecha.ts b/src/grecha.ts similarity index 58% rename from ts/grecha.ts rename to src/grecha.ts index f7c028e..00c16b1 100644 --- a/ts/grecha.ts +++ b/src/grecha.ts @@ -1,4 +1,7 @@ -type Child = string | HTMLElement; +import type { Filter } from "./filters"; +import type { Snapshot } from "./index"; + +type Child = string | HTMLElement | Tag; /** * Used to patch typescript conflict between class and className. @@ -6,9 +9,9 @@ type Child = string | HTMLElement; * See the Notes section here. * https://developer.mozilla.org/en-US/docs/Web/API/Element/className#notes */ -interface HTMLElement { class : string } +// interface HTMLElement { class : string } -type Tag = T & { +export type Tag = T & { att$ : (name: string, value: string) => Tag; onclick$ : (callback: (this: GlobalEventHandlers, ev: MouseEvent) => Tag) => Tag; paramsSnapshot$ : () => Snapshot; @@ -20,9 +23,10 @@ type Tag = T & { updateImage$ : Function; // TODO: change this to the actual function type files : FileList; + value : any; }; -function tag(name: string, ...children: Child[]): Tag { +export function tag(name: string, ...children: Child[]): Tag { const result = document.createElement(name) as Tag; for (const child of children) { if (typeof child === 'string') { @@ -46,20 +50,20 @@ function tag(name: string, ...children: Chi return result; } -const canvas = (...children: Child[]) => tag("canvas", ...children); -const h1 = (...children: Child[]) => tag("h1", ...children); -const h2 = (...children: Child[]) => tag("h2", ...children); -const h3 = (...children: Child[]) => tag("h3", ...children); -const p = (...children: Child[]) => tag("p", ...children); -const a = (...children: Child[]) => tag("a", ...children); -const div = (...children: Child[]) => tag("div", ...children); -const span = (...children: Child[]) => tag("span", ...children); -const select = (...children: Child[]) => tag("select", ...children); +export const canvas = (...children: Child[]) => tag("canvas", ...children); +export const h1 = (...children: Child[]) => tag("h1", ...children); +export const h2 = (...children: Child[]) => tag("h2", ...children); +export const h3 = (...children: Child[]) => tag("h3", ...children); +export const p = (...children: Child[]) => tag("p", ...children); +export const a = (...children: Child[]) => tag("a", ...children); +export const div = (...children: Child[]) => tag("div", ...children); +export const span = (...children: Child[]) => tag("span", ...children); +export const select = (...children: Child[]) => tag("select", ...children); -const img = (src: string) => tag("img").att$("src", src); -const input = (type: string) => tag("input").att$("type", type); +export const img = (src: string) => tag("img").att$("src", src); +export const input = (type: string) => tag("input").att$("type", type); -function router(routes: Record) { +export function router(routes: Record) { const result = div(); function syncHash() { diff --git a/ts/index.ts b/src/index.ts similarity index 93% rename from ts/index.ts rename to src/index.ts index 7af979f..0093eed 100644 --- a/ts/index.ts +++ b/src/index.ts @@ -1,3 +1,8 @@ +import GIF from '@dhdbstjr98/gif.js'; +import { compile_expr, run_expr, type Expr, type UserContext } from "./eval"; +import { type Filter, filters } from "./filters"; +import { canvas, div, img, input, select, span, type Tag } from "./grecha"; + let feature_params = false; type VertexAttribs = Record; @@ -82,15 +87,15 @@ function createTextureFromImage(gl: WebGLRenderingContext, image: TexImageSource type Uniforms = Record; -interface CompiledFilter { +interface CompiledFilter { id: WebGLProgram, uniforms: Uniforms, duration: Expr, transparent: string | null, - paramsPanel: Tag + paramsPanel: Tag } -type Snapshot = Record @@ -112,11 +117,11 @@ function loadFilterProgram(gl: WebGLRenderingContext, filter: Filter, vertexAttr // TODO(#55): there no "reset to default" button in the params panel of a filter const paramsPanel = div().att$("class", "widget-element"); - const paramsInputs: Record = {}; + const paramsInputs: Record> = {}; - if (!filter.params) throw new Error("unknown error"); + // if (!filter.params) throw new Error("unknown error"); - for (const [paramName, paramVal] of Object.entries(filter.params)) { + for (const [paramName, paramVal] of Object.entries(filter.params ?? [])) { if (paramName in uniforms) { throw new Error(`Redefinition of existing uniform parameter ${paramName}`); } @@ -170,8 +175,8 @@ function loadFilterProgram(gl: WebGLRenderingContext, filter: Filter, vertexAttr let snapshot: Snapshot = {}; for (const paramName in paramsInputs) { snapshot[paramName] = { - uniform: uniforms[paramName], - value: Number(paramsInputs[paramName].value) + uniform: uniforms[paramName]!, + value: Number(paramsInputs[paramName]!.value) }; } return snapshot; @@ -309,13 +314,13 @@ function FilterSelector() { gl.bufferData(gl.ARRAY_BUFFER, meshPositionBufferData, gl.STATIC_DRAW); const meshPositionAttrib = vertexAttribs['meshPosition']; gl.vertexAttribPointer( - meshPositionAttrib, + meshPositionAttrib!, VEC2_COUNT, gl.FLOAT, false, 0, 0); - gl.enableVertexAttribArray(meshPositionAttrib); + gl.enableVertexAttribArray(meshPositionAttrib!); } // TODO(#49): FilterSelector does not handle loadFilterProgram() failures @@ -393,7 +398,7 @@ function FilterSelector() { if (context.vars !== undefined) { const snapshot = program.paramsPanel.paramsSnapshot$(); for (const paramName in snapshot) { - context.vars[paramName] = snapshot[paramName].value; + context.vars[paramName] = snapshot[paramName]!.value!; } } @@ -424,9 +429,9 @@ function FilterSelector() { let t = 0.0; while (t <= duration) { - gl.uniform1f(program.uniforms.time, t); - gl.uniform2f(program.uniforms.resolution, CANVAS_WIDTH, CANVAS_HEIGHT); - gl.uniform2f(program.uniforms.emoteSize, emoteImage.width, emoteImage.height); + gl.uniform1f(program.uniforms.time!, t); + gl.uniform2f(program.uniforms.resolution!, CANVAS_WIDTH, CANVAS_HEIGHT); + gl.uniform2f(program.uniforms.emoteSize!, emoteImage.width, emoteImage.height); gl.clearColor(0.0, 1.0, 0.0, 1.0); gl.clear(gl.COLOR_BUFFER_BIT); @@ -503,19 +508,6 @@ function FilterSelector() { } window.onload = () => { - if ("serviceWorker" in navigator) { - navigator.serviceWorker.register('serviceworker.js').then( - (registration) => { - console.log("Registered a Service Worker ", registration); - }, - (error) => { - console.error("Could not register a Service Worker ", error); - }, - ); - } else { - console.error("Service Workers are not supported in this browser."); - } - feature_params = new URLSearchParams(document.location.search).has("feature-params"); const filterSelectorEntry = document.getElementById('filter-selector-entry'); @@ -529,9 +521,9 @@ window.onload = () => { const imageSelector = ImageSelector(); const filterSelector = FilterSelector(); - imageSelector.addEventListener('imageSelected', (e: CustomEvent) => { + imageSelector.addEventListener('imageSelected', ((e: CustomEvent) => { filterSelector.updateImage$(e.detail.imageData); - }); + }) as EventListener); filterSelectorEntry.appendChild(filterSelector); imageSelectorEntry.appendChild(imageSelector); @@ -560,4 +552,3 @@ window.onload = () => { gif = filterSelector.render$(`${fileName}.gif`); }; } -// TODO(#75): run typescript compiler on CI diff --git a/tsconfig.json b/tsconfig.json index 8bb6097..8c95007 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,108 +1,65 @@ { "compilerOptions": { - /* Visit https://aka.ms/tsconfig to read more about this file */ - - /* Projects */ - // "incremental": true, /* Save .tsbuildinfo files to allow for incremental compilation of projects. */ - // "composite": true, /* Enable constraints that allow a TypeScript project to be used with project references. */ - // "tsBuildInfoFile": "./.tsbuildinfo", /* Specify the path to .tsbuildinfo incremental compilation file. */ - // "disableSourceOfProjectReferenceRedirect": true, /* Disable preferring source files instead of declaration files when referencing composite projects. */ - // "disableSolutionSearching": true, /* Opt a project out of multi-project reference checking when editing. */ - // "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */ - - /* Language and Environment */ - "target": "es2016", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ - // "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ - // "jsx": "preserve", /* Specify what JSX code is generated. */ - // "experimentalDecorators": true, /* Enable experimental support for legacy experimental decorators. */ - // "emitDecoratorMetadata": true, /* Emit design-type metadata for decorated declarations in source files. */ - // "jsxFactory": "", /* Specify the JSX factory function used when targeting React JSX emit, e.g. 'React.createElement' or 'h'. */ - // "jsxFragmentFactory": "", /* Specify the JSX Fragment reference used for fragments when targeting React JSX emit e.g. 'React.Fragment' or 'Fragment'. */ - // "jsxImportSource": "", /* Specify module specifier used to import the JSX factory functions when using 'jsx: react-jsx*'. */ - // "reactNamespace": "", /* Specify the object invoked for 'createElement'. This only applies when targeting 'react' JSX emit. */ - // "noLib": true, /* Disable including any library files, including the default lib.d.ts. */ - // "useDefineForClassFields": true, /* Emit ECMAScript-standard-compliant class fields. */ + "target": "ES5", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */ + "lib": ["DOM", "DOM.Iterable", "ES5"], /* Specify a set of bundled library declaration files that describe the target runtime environment. */ // "moduleDetection": "auto", /* Control what method is used to detect module-format JS files. */ /* Modules */ - "module": "commonjs", /* Specify what module code is generated. */ - // "rootDir": "./", /* Specify the root folder within your source files. */ - // "moduleResolution": "node10", /* Specify how TypeScript looks up a file from a given module specifier. */ + "module": "ESNext", /* Specify what module code is generated. */ + // "rootDir": "./ts", /* Specify the root folder within your source files. */ + "moduleResolution": "Bundler", /* Specify how TypeScript looks up a file from a given module specifier. */ // "baseUrl": "./", /* Specify the base directory to resolve non-relative module names. */ // "paths": {}, /* Specify a set of entries that re-map imports to additional lookup locations. */ + "paths": { + "@dhdbstjr98/gif.js": ["./node_modules/@types/gif.js"] + }, // "rootDirs": [], /* Allow multiple folders to be treated as one when resolving modules. */ // "typeRoots": [], /* Specify multiple folders that act like './node_modules/@types'. */ - // "types": [], /* Specify type package names to be included without being referenced in a source file. */ // "allowUmdGlobalAccess": true, /* Allow accessing UMD globals from modules. */ // "moduleSuffixes": [], /* List of file name suffixes to search when resolving a module. */ - // "allowImportingTsExtensions": true, /* Allow imports to include TypeScript file extensions. Requires '--moduleResolution bundler' and either '--noEmit' or '--emitDeclarationOnly' to be set. */ - // "resolvePackageJsonExports": true, /* Use the package.json 'exports' field when resolving package imports. */ - // "resolvePackageJsonImports": true, /* Use the package.json 'imports' field when resolving imports. */ - // "customConditions": [], /* Conditions to set in addition to the resolver-specific defaults when resolving imports. */ - // "resolveJsonModule": true, /* Enable importing .json files. */ - // "allowArbitraryExtensions": true, /* Enable importing files with any extension, provided a declaration file is present. */ // "noResolve": true, /* Disallow 'import's, 'require's or ''s from expanding the number of files TypeScript should add to a project. */ /* JavaScript Support */ - // "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ - // "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ - // "maxNodeModuleJsDepth": 1, /* Specify the maximum folder depth used for checking JavaScript files from 'node_modules'. Only applicable with 'allowJs'. */ + "allowJs": true, /* Allow JavaScript files to be a part of your program. Use the 'checkJS' option to get errors from these files. */ + "checkJs": true, /* Enable error reporting in type-checked JavaScript files. */ /* Emit */ - // "declaration": true, /* Generate .d.ts files from TypeScript and JavaScript files in your project. */ - // "declarationMap": true, /* Create sourcemaps for d.ts files. */ - // "emitDeclarationOnly": true, /* Only output d.ts files and not JavaScript files. */ - // "sourceMap": true, /* Create source map files for emitted JavaScript files. */ - // "inlineSourceMap": true, /* Include sourcemap files inside the emitted JavaScript. */ // "outFile": "./", /* Specify a file that bundles all outputs into one JavaScript file. If 'declaration' is true, also designates a file that bundles all .d.ts output. */ - // "outDir": "./", /* Specify an output folder for all emitted files. */ - // "removeComments": true, /* Disable emitting comments. */ - // "noEmit": true, /* Disable emitting files from a compilation. */ - // "importHelpers": true, /* Allow importing helper functions from tslib once per project, instead of including them per-file. */ - // "downlevelIteration": true, /* Emit more compliant, but verbose and less performant JavaScript for iteration. */ - // "sourceRoot": "", /* Specify the root path for debuggers to find the reference source code. */ - // "mapRoot": "", /* Specify the location where debugger should locate map files instead of generated locations. */ - // "inlineSources": true, /* Include source code in the sourcemaps inside the emitted JavaScript. */ - // "emitBOM": true, /* Emit a UTF-8 Byte Order Mark (BOM) in the beginning of output files. */ - // "newLine": "crlf", /* Set the newline character for emitting files. */ - // "stripInternal": true, /* Disable emitting declarations that have '@internal' in their JSDoc comments. */ - // "noEmitHelpers": true, /* Disable generating custom helper functions like '__extends' in compiled output. */ - // "noEmitOnError": true, /* Disable emitting files if any type checking errors are reported. */ - // "preserveConstEnums": true, /* Disable erasing 'const enum' declarations in generated code. */ - // "declarationDir": "./", /* Specify the output directory for generated declaration files. */ + // "outDir": "./js", /* Specify an output folder for all emitted files. */ + "removeComments": true, /* Disable emitting comments. */ /* Interop Constraints */ - // "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ - // "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ - // "isolatedDeclarations": true, /* Require sufficient annotation on exports so other tools can trivially generate declaration files. */ - // "allowSyntheticDefaultImports": true, /* Allow 'import x from y' when a module doesn't have a default export. */ + "isolatedModules": true, /* Ensure that each file can be safely transpiled without relying on other imports. */ + "verbatimModuleSyntax": true, /* Do not transform or elide any imports or exports not marked as type-only, ensuring they are written in the output file's format based on the 'module' setting. */ "esModuleInterop": true, /* Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility. */ - // "preserveSymlinks": true, /* Disable resolving symlinks to their realpath. This correlates to the same flag in node. */ "forceConsistentCasingInFileNames": true, /* Ensure that casing is correct in imports. */ /* Type Checking */ - "strict": true, /* Enable all strict type-checking options. */ - // "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ - // "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ - // "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ - // "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ - // "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ - // "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ - // "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ - // "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ - // "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ - // "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ + "strict": true, /* Enable all strict type-checking options. */ + "noImplicitAny": true, /* Enable error reporting for expressions and declarations with an implied 'any' type. */ + "strictNullChecks": true, /* When type checking, take into account 'null' and 'undefined'. */ + "strictFunctionTypes": true, /* When assigning functions, check to ensure parameters and the return values are subtype-compatible. */ + "strictBindCallApply": true, /* Check that the arguments for 'bind', 'call', and 'apply' methods match the original function. */ + "strictPropertyInitialization": true, /* Check for class properties that are declared but not set in the constructor. */ + "noImplicitThis": true, /* Enable error reporting when 'this' is given the type 'any'. */ + "useUnknownInCatchVariables": true, /* Default catch clause variables as 'unknown' instead of 'any'. */ + "alwaysStrict": true, /* Ensure 'use strict' is always emitted. */ + "noUnusedLocals": true, /* Enable error reporting when local variables aren't read. */ + "noUnusedParameters": true, /* Raise an error when a function parameter isn't read. */ // "exactOptionalPropertyTypes": true, /* Interpret optional property types as written, rather than adding 'undefined'. */ - // "noImplicitReturns": true, /* Enable error reporting for codepaths that do not explicitly return in a function. */ - // "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ - // "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ - // "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ + "noFallthroughCasesInSwitch": true, /* Enable error reporting for fallthrough cases in switch statements. */ + "noUncheckedIndexedAccess": true, /* Add 'undefined' to a type when accessed using an index. */ + "noImplicitOverride": true, /* Ensure overriding members in derived classes are marked with an override modifier. */ // "noPropertyAccessFromIndexSignature": true, /* Enforces using indexed accessors for keys declared using an indexed type. */ - // "allowUnusedLabels": true, /* Disable error reporting for unused labels. */ - // "allowUnreachableCode": true, /* Disable error reporting for unreachable code. */ /* Completeness */ - // "skipDefaultLibCheck": true, /* Skip type checking .d.ts files that are included with TypeScript. */ "skipLibCheck": true /* Skip type checking all .d.ts files. */ - } + }, + "exclude" : [ + "src/gif.js", + "src/gif.worker.js", + "build.js", + "js/**", + "dist/**" + ] } From 5349f9476b4cab6a3aacc845afc2e9d4508846ac Mon Sep 17 00:00:00 2001 From: Saksham Goyal Date: Thu, 15 Aug 2024 03:03:06 -0400 Subject: [PATCH 3/5] avoid enums --- src/eval.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/eval.ts b/src/eval.ts index 921280f..847dd67 100644 --- a/src/eval.ts +++ b/src/eval.ts @@ -1,11 +1,13 @@ export type BinaryOp = '+' | '-' | '*' | '/' | '%'; export type BinaryOpFunc = (lhs: number, rhs: number) => number; -enum BinaryPrec { - PREC0 = 0, - PREC1, - COUNT_PRECS -}; +const BinaryPrec = { // avoid dangerous enum in TS + PREC0: 0, + PREC1 : 1, + COUNT_PRECS : 2 +} as const; + +type BinaryPrec = typeof BinaryPrec[keyof typeof BinaryPrec]; interface BinaryOpDef { func: BinaryOpFunc, @@ -195,7 +197,7 @@ function parse_expr(lexer: Lexer, prec: BinaryPrec = BinaryPrec.PREC0): Expr { return parse_primary(lexer); } - let lhs = parse_expr(lexer, prec + 1); + let lhs = parse_expr(lexer, (prec + 1) as BinaryPrec); let op_token = lexer.next(); if (op_token !== null) { From c0991d554468fd0fd173d90d1cc4f502a8eaa1e4 Mon Sep 17 00:00:00 2001 From: Saksham Goyal Date: Thu, 15 Aug 2024 03:05:02 -0400 Subject: [PATCH 4/5] remove unused svg --- public/img/error.svg | 79 -------------------------------------------- 1 file changed, 79 deletions(-) delete mode 100644 public/img/error.svg diff --git a/public/img/error.svg b/public/img/error.svg deleted file mode 100644 index 3d5944e..0000000 --- a/public/img/error.svg +++ /dev/null @@ -1,79 +0,0 @@ - - - - - - - - - - image/svg+xml - - - - - - - - - - - From f25ab1ca5874e4edbd8d397113a4ad8d083d3c4a Mon Sep 17 00:00:00 2001 From: Saksham Goyal Date: Fri, 16 Aug 2024 12:58:28 -0400 Subject: [PATCH 5/5] remove unnessesary comment --- src/grecha.ts | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/grecha.ts b/src/grecha.ts index 00c16b1..59a1dc1 100644 --- a/src/grecha.ts +++ b/src/grecha.ts @@ -3,14 +3,6 @@ import type { Snapshot } from "./index"; type Child = string | HTMLElement | Tag; -/** - * Used to patch typescript conflict between class and className. - * Typscript merges interfaces so this works without modifying the library version of the interface. - * See the Notes section here. - * https://developer.mozilla.org/en-US/docs/Web/API/Element/className#notes - */ -// interface HTMLElement { class : string } - export type Tag = T & { att$ : (name: string, value: string) => Tag; onclick$ : (callback: (this: GlobalEventHandlers, ev: MouseEvent) => Tag) => Tag;