From e7fa005d96f0db60297193f6810037d387c62550 Mon Sep 17 00:00:00 2001 From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com> Date: Fri, 30 Jun 2023 04:52:24 +0100 Subject: [PATCH 01/32] codeGIO/ExtraUtilities: update clipboard blocks for consistency (#636) --- extensions/codeGIO/ExtraUtilities.js | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/extensions/codeGIO/ExtraUtilities.js b/extensions/codeGIO/ExtraUtilities.js index ff188064fe..3c7414dde4 100644 --- a/extensions/codeGIO/ExtraUtilities.js +++ b/extensions/codeGIO/ExtraUtilities.js @@ -326,12 +326,19 @@ } set_clipboard(args) { - navigator.clipboard.writeText(args.one); + if (navigator.clipboard && navigator.clipboard.writeText) { + navigator.clipboard.writeText(args.one); + } } get_clipboard() { if (navigator.clipboard && navigator.clipboard.readText) { - return navigator.clipboard.readText(); + return Scratch.canReadClipboard().then(allowed => { + if (allowed) { + return navigator.clipboard.readText(); + } + return ''; + }); } return ''; } From cc8f7f5df4177ca3c5fed95fab99ba783517ef3f Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Sat, 1 Jul 2023 00:26:59 -0500 Subject: [PATCH 02/32] Remove desktop app version number from the website (#663) --- website/index.ejs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/index.ejs b/website/index.ejs index 523fbc7434..a6b4b7b691 100644 --- a/website/index.ejs +++ b/website/index.ejs @@ -245,7 +245,7 @@ <% } else { %>
Some extensions may not work in TurboWarp Desktop.
For compatibility, security, and offline support, each TurboWarp Desktop update contains an offline copy of these extensions from its release date, so some extensions may be outdated or missing. - Use the latest update (v1.8.0) for best results. + Use the latest update for best results. <% } %> From a037d8644f5d0e71120de6b8bb1a4767edc7e890 Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Sat, 1 Jul 2023 19:34:23 -0500 Subject: [PATCH 03/32] sound: fix timeout error handling (#670) --- extensions/sound.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/sound.js b/extensions/sound.js index 0a34b84418..57228fc0b5 100644 --- a/extensions/sound.js +++ b/extensions/sound.js @@ -14,7 +14,7 @@ const xhr = new XMLHttpRequest(); let timeout = setTimeout(() => { xhr.abort(); - throw new Error('Timed out'); + reject(new Error('Timed out')); }, 5000); xhr.onload = () => { clearTimeout(timeout); From 98ab9d03e13b9fdecf431565d2badad90ad6601c Mon Sep 17 00:00:00 2001 From: godslayerakp <74981904+RedMan13@users.noreply.github.com> Date: Sun, 2 Jul 2023 19:05:32 -0700 Subject: [PATCH 04/32] Add godslayerakp/http extension (#458) --- extensions/godslayerakp/http.js | 672 ++++++++++++++++++++++++++++++++ images/godslayerakp/http.png | Bin 0 -> 27809 bytes website/index.ejs | 6 + 3 files changed, 678 insertions(+) create mode 100644 extensions/godslayerakp/http.js create mode 100644 images/godslayerakp/http.png diff --git a/extensions/godslayerakp/http.js b/extensions/godslayerakp/http.js new file mode 100644 index 0000000000..6d7e6c5b58 --- /dev/null +++ b/extensions/godslayerakp/http.js @@ -0,0 +1,672 @@ +(function(Scratch) { + 'use strict'; + if (!Scratch.extensions.unsandboxed) throw new Error('can not load out side unsandboxed mode'); + + const pathRegex = /[^.]+/g; + const setType = (value, type) => { + switch (type) { + case 'string': + switch (typeof value) { + case 'string': + case 'boolean': + case 'number': + case 'function': + return String(value); + case 'object': + try { + return JSON.stringify(value); + } catch { + return '{}'; + } + } + break; + case 'number': + switch (typeof value) { + case 'string': + return String(value); + case 'boolean': + return Boolean(value); + case 'number': + return value; + case 'function': + case 'object': + return NaN; + } + break; + case 'boolean': + switch (typeof value) { + case 'string': + case 'boolean': + case 'function': + case 'number': + return Boolean(value); + case 'object': + return false; + } + break; + case 'object': + switch (typeof value) { + case 'string': + try { + const parsed = JSON.parse(value); + if (typeof parsed === 'object') return parsed; + return {}; + } catch { + return {}; + } + case 'boolean': + case 'function': + case 'number': + return {}; + case 'object': + return value; + } + break; + } + }; + const parseType = text => { + // this isnt text and we just pass it down as what ever it is + if (typeof text !== 'string') return text; + if (!isNaN(Number(text))) { + return Number(text); + } else { + try { + const parsed = JSON.parse(text); + if (typeof parsed === 'object') return parsed; + if (typeof parsed === 'boolean') return parsed; + return text; + } catch { + return text; + } + } + }; + const getPathArray = path => { + const names = path.match(pathRegex); + for (let index = 0; index < names.length; index++) { + let name = names[index]; + name = name.replaceAll(/(? { + for (const name of path) { + object = object[name]; + if (typeof object !== 'object') return; + } + return object; + }; + const setValueAtPath = (object, path, value) => { + for (const name of path) { + object = object[name]; + if (typeof object !== 'object') return; + } + return object = value; + }; + + const {vm} = Scratch; + const {runtime} = vm; + + const extensionId = 'gsaHTTPRequests'; + + // the funny class to make event blocks look better + class Events { + constructor() { + this.events = {}; + this.blocks = {}; + } + + /** + * adds a event name listner for a block + * @param {string} name name of the event + * @param {string} [block] a block to run when trigered + */ + add(name, block) { + if (block) { + if (!this.blocks[name]) this.blocks[name] = []; + this.blocks[name].push(block); + } + } + + /** + * activate an event + * @param {string} name name of the event + */ + activate(name) { + this.events[name] = true; + if (this.blocks[name]) { + for (const block of this.blocks[name]) { + runtime.startHats(block); + } + } + } + } + const createBlockId = block => `${extensionId}_${block}`; + + /* ------- BLOCKS -------- */ + const {BlockType, Cast, ArgumentType} = Scratch; + + class WebRequests { + static get defaultRequest() { + const defaultRequest = { + events: new Events(), + get mimeType() { + return this.options.headers['Content-Type']; + }, + set mimeType(value) { + this.options.headers['Content-Type'] = value; + }, + set method(val) { + this.options.method = val; + // remove body on get requests + if (val === 'GET') { + delete this.options.body; + } + }, + get method() { + return this.options.method; + }, + options: { + headers: { + 'Content-Type': 'text/plain' + }, + method: 'GET' + }, + set body(val) { + if (this.method === 'GET') return; + this.options.body = val; + }, + get body() { + return this.options.body; + }, + end: false, + fail: false, + success: false + }; + + defaultRequest.events.add('reqSuccess', createBlockId('onResponse')); + defaultRequest.events.add('reqFail', createBlockId('onFail')); + + return defaultRequest; + } + static get defualtResponse() { + const defualtResponse = { + text: '', + status: '', + statusText: '', + headers: new Headers(), + error: '', + url: '' + }; + + return defualtResponse; + } + + /** + * no need to install runtime as it comes with Scratch var + */ + constructor() { + this.clearAll(); + this.showingExtra = false; + } + getInfo() { + return { + id: extensionId, + name: 'HTTP', + color1: '#307eff', + color2: '#2c5eb0', + blocks: [ + { + opcode: 'clearAll', + blockType: BlockType.COMMAND, + text: 'clear current data' + }, + { + blockType: Scratch.BlockType.LABEL, + text: 'Response' + }, + { + opcode: 'resData', + blockType: BlockType.REPORTER, + text: 'response' + }, + { + opcode: 'error', + blockType: BlockType.REPORTER, + text: 'error' + }, + { + opcode: 'status', + blockType: BlockType.REPORTER, + text: 'status' + }, + { + opcode: 'statusText', + blockType: BlockType.REPORTER, + text: 'status text' + }, + '---', + { + opcode: 'getHeaderJSON', + blockType: BlockType.REPORTER, + disableMonitor: true, + text: 'get headers as json' + }, + { + opcode: 'getHeaderValue', + blockType: BlockType.REPORTER, + arguments: { + name: { + type: ArgumentType.STRING + } + }, + text: 'get [name] from header' + }, + '---', + { + opcode: 'requestComplete', + blockType: BlockType.BOOLEAN, + text: 'site responded?' + }, + { + opcode: 'requestFail', + blockType: BlockType.BOOLEAN, + text: 'request failed?' + }, + { + opcode: 'requestSuccess', + blockType: BlockType.BOOLEAN, + text: 'request succeeded?' + }, + '---', + { + opcode: 'onResponse', + blockType: BlockType.HAT, + isEdgeActivated: false, + text: 'when a site responds' + }, + { + opcode: 'onFail', + blockType: BlockType.HAT, + isEdgeActivated: false, + text: 'when a request fails' + }, + { + blockType: Scratch.BlockType.LABEL, + text: 'Request' + }, + { + opcode: 'setMimeType', + blockType: BlockType.COMMAND, + arguments: { + type: { + type: ArgumentType.STRING, + menu: 'mimeType', + defaultValue: this.request.mimeType + } + }, + text: 'set content type to [type]' + }, + { + opcode: 'setRequestmethod', + blockType: BlockType.COMMAND, + arguments: { + method: { + type: ArgumentType.STRING, + menu: 'method', + defaultValue: this.request.method + } + }, + text: 'set request method to [method]' + }, + { + opcode: 'setHeaderData', + blockType: BlockType.COMMAND, + arguments: { + name: { + type: ArgumentType.STRING, + defaultValue: 'Content-Type' + }, + value: { + type: ArgumentType.STRING, + defaultValue: this.request.mimeType + } + }, + text: 'in header set [name] to [value]' + }, + { + opcode: 'setHeaderJSON', + blockType: BlockType.COMMAND, + arguments: { + json: { + type: ArgumentType.STRING, + defaultValue: `{"Content-Type": "${this.request.mimeType}"}` + } + }, + text: 'set headers to json [json]' + }, + { + opcode: 'setBody', + blockType: BlockType.COMMAND, + arguments: { + text: { + type: ArgumentType.STRING + } + }, + text: 'set request body to [text]' + }, + { + opcode: 'sendRequest', + blockType: BlockType.COMMAND, + arguments: { + url: { + type: ArgumentType.STRING, + defaultValue: 'https://extensions.turbowarp.org/hello.txt' + } + }, + text: 'send request to [url]' + }, + { + func: 'showExtra', + blockType: BlockType.BUTTON, + text: 'Show Extra', + hideFromPalette: this.showingExtra + }, + { + func: 'hideExtra', + blockType: BlockType.BUTTON, + text: 'Hide Extra', + hideFromPalette: !this.showingExtra + }, + { + opcode: 'setUnkownProperty', + blockType: BlockType.COMMAND, + arguments: { + path: { + type: ArgumentType.STRING, + defaultValue: 'path.to.item' + }, + value: { + type: ArgumentType.STRING, + defaultValue: 'data' + } + }, + text: 'set [path] to [value] in request options', + hideFromPalette: !this.showingExtra + }, + { + opcode: 'setUnkownPropertyType', + blockType: BlockType.COMMAND, + arguments: { + path: { + type: ArgumentType.STRING, + defaultValue: 'path.to.item' + }, + type: { + type: ArgumentType.STRING, + menu: 'jsTypes' + } + }, + text: 'set [path] to type [type] in request options', + hideFromPalette: !this.showingExtra + }, + { + opcode: 'getUnkownProperty', + blockType: BlockType.REPORTER, + arguments: { + path: { + type: ArgumentType.STRING, + defaultValue: 'path.to.item' + } + }, + text: 'get [path] in request options', + hideFromPalette: !this.showingExtra + }, + { + opcode: 'getUnkownPropertyType', + blockType: BlockType.REPORTER, + arguments: { + path: { + type: ArgumentType.STRING, + defaultValue: 'path.to.item' + } + }, + text: 'get type of [path] in request options', + hideFromPalette: !this.showingExtra + } + ], + menus: { + jsTypes: { + items: [ + 'string', + 'number', + 'boolean', + 'object' + ] + }, + method: { + items: [ + 'GET', + 'POST', + 'PUT', + 'PATCH', + 'DELETE', + 'HEAD', + 'OPTIONS' + ], + acceptReporters: true + }, + mimeType: { + items: [ + 'application/javascript', + 'application/ogg', + 'application/pdf', + 'application/json', + 'application/ld+json', + 'application/xml', + 'application/zip', + 'audio/mpeg', + 'image/gif', + 'image/jpeg', + 'image/png', + 'image/tiff', + 'image/x-icon', + 'image/svg+xml', + 'text/css', + 'text/csv', + 'text/html', + 'text/plain', + 'text/xml', + 'video/mpeg', + 'video/mp4', + 'video/x-ms-wmv', + 'video/x-msvideo', + 'video/x-flv', + 'video/webm' + ], + acceptReporters: true + } + } + }; + } + + /* ------ RESETING ------- */ + + clearAll() { + this.request = WebRequests.defaultRequest; + this.response = WebRequests.defualtResponse; + } + + /* ------- DATA READING -------- */ + + resData() { + return this.response.text; + } + + error() { + return this.response.error; + } + + status() { + return this.response.status; + } + + requestComplete() { + return this.request.end; + } + + requestFail() { + return this.request.fail; + } + + requestSuccess() { + return this.request.success; + } + + statusText() { + return this.response.statusText; + } + + getHeaderValue(args) { + const name = Cast.toString(args.name); + return this.response.get(name); + } + + getHeaderJSON() { + const object = {}; + for (const entry of this.response.headers.entries()) { + object[entry[0]] = entry[1]; + } + return JSON.stringify(object); + } + + /* -------- EVENTS -------- */ + + onResponse() { + // filer olo + return false; + } + + onFail() { + // filer olo + return false; + } + + /* -------- CONTROL --------- */ + + setMimeType(args) { + const type = Cast.toString(args.type); + this.request.mimeType = type; + } + + setRequestmethod(args) { + const method = Cast.toString(args.method); + this.request.method = method; + } + + setHeaderData(args) { + const key = Cast.toString(args.name); + const value = Cast.toString(args.value); + this.request.options.headers[key] = value; + } + + setHeaderJSON(args) { + const json = Cast.toString(args.json); + let object; + // ignore invalid data + try { + object = JSON.parse(json); + } catch { + return; + } + if (typeof object !== 'object') return; + this.request.options.headers = object; + } + + setBody(args) { + const body = Cast.toString(args.text); + this.request.body = body; + } + + // eslint-disable-next-line require-await + async sendRequest(args) { + const url = Cast.toString(args.url); + + this.clearAll(); + + this.response.url = url; + Scratch.fetch(url, this.request.options) + .then(res => { + // @ts-ignore + this.response.status = res.status; + this.response.headers = res.headers; + this.response.statusText = res.statusText; + if (res.ok) { + this.request.success = true; + this.request.events.activate('reqSuccess'); + } else { + this.request.fail = true; + this.request.events.activate('reqFail'); + } + this.request.end = true; + return res.text(); + }) + .then(body => this.response.text = body) + .catch(err => { + this.response.error = String(err); + console.warn('request failed with error', err); + this.request.fail = true; + this.request.end = true; + this.request.events.activate('reqFail'); + }); + } + + /* extra stuff for when its missing something */ + + showExtra() { + this.showingExtra = true; + vm.extensionManager.refreshBlocks(); + } + + hideExtra() { + this.showingExtra = false; + vm.extensionManager.refreshBlocks(); + } + + setUnkownProperty(args) { + const name = Cast.toString(args.name); + const text = Cast.toString(args.value); + + const path = getPathArray(name); + const value = parseType(text); + setValueAtPath(this.request.options, path, value); + } + + setUnkownPropertyType(args) { + const name = Cast.toString(args.name); + const type = Cast.toString(args.type); + const path = getPathArray(name); + + const oldValue = getValueAtPath(this.request.options, path); + const newValue = setType(oldValue, type); + setValueAtPath(this.request.options, path, newValue); + } + + getUnkownProperty(args) { + const name = Cast.toString(args.name); + const path = getPathArray(name); + + return getValueAtPath(this.request.options, path); + } + + getUnkownPropertyType(args) { + const name = Cast.toString(args.name); + const path = getPathArray(name); + const value = getValueAtPath(this.request.options, path); + + return typeof value; + } + } + + const instance = new WebRequests(); + Scratch.extensions.register(instance); +})(Scratch); diff --git a/images/godslayerakp/http.png b/images/godslayerakp/http.png new file mode 100644 index 0000000000000000000000000000000000000000..cc0d60026e8d9ec0856470dd863603c4b369ec9c GIT binary patch literal 27809 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 z zS7lR+k734oND)fW5x`KT)dcuh*YiHIwHAE8KUr?t<}@ELI$|EtV+!%ANDi61&Uj{@ zMkx`e{RO<$N6nViD0##LfE0D?NY!)QoZES=jzr1mPTGf*TNK%jwP$fr?|B9AH(qb_ z*No|TYKU%qv30Vn?M4}R?Ib<-oK*I@iW|dU)$J+}MJDs!JqqO_J3!>1OYu?O}OWS0H|;&PDno&3px?xN*ia z$^J{!i#Lsz`z{v_gS_SxjfvtR7b9EG_g-IHoJE5zI)aG?a%t(ZUElJnlDhY$OkMcw z7pQHFUK*yw&c(keZ8)1G=4Pwzc3>(Uc&B4OyjWe{MXQ!{&bf1oe(=zlH$u|Yok{R{ z%6^-#i16y=gQ1u$fmk%5Y2np(^sV%doL&c20ncr`E%1EhyL;uQROqou1^~0%^^5z@ zi>jf~jE&!qPE|iV+a1V6k|3_H>#mbzd-3kxuR5NM-ALw|4V&Jf8CFs47BY8xgsJJx9PT2JfmADlWHsi%CynyL_a+`6Y zDUh@xF8J7R5NW;<@Bf-!XRYD^=AHa*xpc~LE}D95?)ss=+ti1&k^L%v-{p#$cx&`p zxqD8(THm?1#mphawmfw&(}N3Bu2@x6)gWn6&HoGa#S=hfiiFw#-Z>2sP6PLqb*9C_ zPC-h+`Y!~Sfa}`zRmrc`qs?^a{Yr5afB$uSw_8VyLbZRR=uYW%eA(J4I_Cnn%sxhx z>=|3wu%zvEJLC|H7!AEkfYF*uT0}xMrJP19pn!0KEqBq)u>R~`QJ)7o&dcexjcXFO zM$NLn1tqol2_rL3CZg#WE2Ltq61`J=k3Who^euF}kRy=)dQA~AVUg9n1BU)xDz(eH z^<%c974e#WTQ;)3;%s>txW$^$D1K&TF{2w{5D>{)X~b`vpqEGfKd)jDoW7t1CgprM z$I22Qyg-FHsFhx~ptow-z-#XZjoJB^fdYKsdNJYmfGh0K>wHJS<>t5i#!OW9T44ek zc09u6ru;Uo&ESgtw89k-BWbq&*}wi>>@1UAmVzjE1%|oy_VH2DNUXA#weESTKz$0U z&+5#$XpEsT_x0ZX1tmOk%D2<*0Nu-^bVyF-7Tf0bIvtl-UEkY5kRn$V+jo&-YuSUM z>lpkxa+*z8Km{)az_Ext$wVZ?wSa`5kqE9NAo}ZO?^6;>)nfPhkhw2PDJoXm=IQkb z*OZu`F3*^0rG(tr?Uo!WJ+A8vxYZFWnQ3@!I47I=>=ix{q`(=!ntc*dBVTiM9K*Ho z$GbpdIPooP(yaj3&<^%?^DqrV4 zw9gm1;@A%-7-C~9-4dh*MbVRNcGKqUNw*MgDM4`oH*>cuuFnq-|B{oKvo??ytT>lv zQ}N7a5AipIu=*}s_iz5Ot0mlNY|*KSFKu8Q!r<35AZAh)U&@GA<$OX*1ZV!(0vyy3 z@K2Hz*_iLK46^5=)#U^zv0$r~rE4)tOZMJ8PVRb`brSHn{#nkFTPEjQ-c0qH`gXfE zRrT4Yjw_7b>Zk0!$m10H*_mxC#=c^jda!ztS zt5dxR%U$o$!I&CbJ z?dG;x=E;Thr=AlH%8+);M$8hbTy8_W)>7?( zHAv~E-4?nRT047#5KZ!*@n0Wtf80jv>UTTj`zo`bu|DvgZny9UT!Vf;boa~2p% zl*NR&uJ6&xV%x1TSiCqV1ih;3n&G#Ft`CeYPSxU}^jp{=Un+K-Yd{8%gHGh}OY`$GC^|`6DyiIr7^L_n; zLVPQx-+NrqeT4C&Wz+cxUty@IdQ)>~fi?@)1c>DY^9mL}gfnuz8mE}*tPeDYgx~%n8T$>z)g{p z82~Y;$T(4GoQnDpe?ZZhn_=>XQgdlznN{-dQLW1^loDL?bK=EW#$JJ%n4PGQUo^2I zvup3%#<6=2K9yJ!e>)VJux|U|IUT)H)q;-FP$*F_SGCGhWf~OCJDZ+P#u9w*9WZ8_ zf`&+?GrF}Kx9ObJb?7B8k0>N#d##`@W!hblkvV1Fu z-&%ET7ko)@!4*{uM9B5^R>E{X_1>h|#I@)2UWHLe9RC@wsE9tr2gy=*YlOOJw-pTnC$**QiNgK`T}7CQ)!nv;j3RUa!AhFJ6o;~-N;LxNZ!RZ$Gm8vF?4=h z|GQU)s7wzMvn6DLzfxNWhfWfT)Iz?>BF!XL<{Mwx%j^3&h68_o2U@=OCQ|m~{=fG~XXs%Uu8pz<^NPr1_=&K$W1i)dr?Biug1ip9z zfG>Q{+wIr9?>mVp+Q9uN;_8)Rbxpd;;Ilm1^y-6XZlowO-pF|1I$rfJZy0`}TdT7n z)ArPBti6)1Iqj&FMbBCeLD&0d#`-cWhc`a3f9rZmr1U?{s9-#wc_J+lTc}HWzN#=% z2YPGg-evlv4?RivrX-tIC*xA4=Qiu?lWwKQ>mipmQ6bg8NpeASY%0z2Ki8`~UM<)Q z__LSrP&Cil%$QQYBEpfxDs%nk3}FtZjg5KOcSIOUAF@X%5w-v6u%%C8nfHRacYMf^ zdb8myb;sA=(Ka*TxDI~<(8dfOc5m!9792m(EqyMF*A0ZD`q7RUffk9`N#7KSWA$fz zT9GToQ0kIImSFPqotK7Dkz(EAEfiXwwCX_2Zt!Xrq;LAe6uW_^w-Af-F3Y#$Eb`xk zh~Tbx&TBdK0{7QfHO`Me4re`DRhnu(gu3+7Qp)XqnKt_I&1IZ5!`bqtP<}2`Qq@Da z%r0s4j~*eyF-z{B`|yf1ZG$j1HJgzu`Q_G6Mf5uQ;;?2B45Gg(CQVpGEd+e4t$6*C zNm=4a5Vm!rLPz02FGoiEP9>71Ly}#sO?>6Ik6D;X7ZgLM?jVAd+-B@gU=mvza%XDU zeyT)CP9IG)W*iC!1yDkUJ;_Q-s)-D7A_iJ@I_my@ezTH~epEWGUe8oAX9>~#?2ryn zm5pJ;o|S4dNNS2JinR9^^H`e*BRWRWezVJ=;}DqO#(yMRD1SnRl5sEBZH^0GR+fYn zl9!nvxVLR3;m)bP?^>#3ch^m04afVPvJP4xys2arC~A|px@6mMV`jIkH~aU}*Rmnt zTJhNB`f|T=JrTl2vNJ>#PL>|7Hq99;ame36phj$Xdlh_oFm%S9>gjCBhRT1^uh0%c zFjBzr_#8lYo1pl9Aa#X-5dNq}e`_S*qfz~P@2}x}Ss-}ZZl$1Y@vPINsHo{hY}s5< zArZpzy(Z_6%lxj$)H${SN!Ek*xtoaDukA9uvb;+oUd-ODf^efTpjd&dw_SaFHltP1 zYP?uV4&?Sm*Vi%|UWr2k3#!2_wYXF49S-H`FX)6rJpZhg;#Y&9oOcFVn?+%YtC zlXP_I&sB2Yj!oxHYxTI^@jp0L#aQ&W?kQEUlRv=hJ+-V(3R0^Lm59I6wzwU%``eyR zx=RU5{Se(sNU7S5?mvS;nQCIU2BlqW$!Pl8U8}c;AgL>@q-;5$6&_?uUC_D zBvpj1@y#}kkk}IqOHr^WP`kP7zt_rFp7u@h zT#kgVMID1EC9e6Cd?&8cYz3z40s3ACcD;Wd>8(KLyAKP~rgr^!Yl5Eq3oH+MJuUjM z-u*a*EkrC-f*lCAqCWUPWK!ZVc|@&&%D+=>UveUJbVzW#B1C;%{r7VlKFc%=Wp>uq z`{aY^tNKxx(bw>cWpb`GYC5K&eDR?bbuxDN3H?n1tN%t&f31u8q}sSRjg}_60EEsM zOT(3_-0HHcjP%ATKSSpT0C>eko%l=%F#~8mX)d;stcE797fE6ZMm3iMuO4mjDMeql z^xeevUTyiN`LYPQ_|atxgWuGh{_AL2h1 z|M~w<2pV?FcbLlNC@!crJIQC9_PSj5Rn$IJ)NeXHT0fN>Ny$;Z{FKq04HDH4u8~Bm zBs|UlhA$N+&IBI85s+F^n^1A(?p#@PTXvL-y|U8M z@$o2*iHl3=%XZ{a$xKdmApO2OQ&RFp{%Y0D>oUkPt>%F6&g>Ut7cu0udj`A1F#phB-#{#b;6<*C8zPA`VoJ2;$Ak(qR0dTFf=13Vygy}U# z^=06qk`^oWoJVRr@*eopx@ELh>V_y*iKRGoDe->1h4P z+w|O9Vsu&8uKYaP1*=E*GAQ9mD?9XBsttb)(`+fVEevWFkHiz5*Bs)|QZNXfbRubM zE*2g>KW#-kK+HJJL0lZ)V95J^?v~QFZZ}>xxri>l8sIO*$MdYd_J`1Neg@QQ`1JhM zA$ck>KF$JOm$n)CK3{ouF|hGUKAUC!W#4OjE?~W!uG5x~DWn>Xoh!0SwS3k{R==~% zW~-2)W%y8`ywlX*cY@#uH?;RDX3jNS!{zVkD726g+?Dr#I#rd(yHI8~-Yf{mo3n$S zcb%`xpLV{)Ee3_00~T|)zP40mm&@~K`_@P#UNK((ElYT~HRGHxvVmk78=b7+K{#gA zxS?B<^4e@25tk$8J8}d>H0}=jLq$Gsxbz*|b7zC-6GIAxebvlk%XhcBidOq2xKuOk zSC2lyd~f>P(^u%&(rYb;wUGF35qz#s3V_e`#)a&D3(#xXS(k%$01k#o_nn1J3NbZTNf9z zui#-RneqzV)Z}9(y6oZ;{Mjq%CqJ^OUbsy1Tc`M8Aifm=fWfVhpCUR^E`IG!5W=WomjE(q&tMS_9j6!@>3)Z2ptGzhkKNwWx4T0OvORTwZPf ze(2lT-1j;ukNQ}f@<;rv|JiMpbCKV#h6^v%lnd=zw%rO=U-w7lrOb_2UKBgt&A;2v z+q?9;lcK^kx?1#^#h!3Sqd}Ghc*_L=(OqK86U0tM_Z=1eZVbQUTT1@3iu*A75_fUc zWpB~9R1}(oT%w%*`BL9IZrn+Ml=)_BYCVZEM}GDtzBIV;rM@AlY_tDB0T^z$DjzlV zr9#jD{EaUHx!m&o_D228s3W~Oi=IXK*1fqmbaSnYQu2Ier`WSxRm4R}$6wQ@dssiJ zLBT)quY(0!3?3)x{|z_s)nw^!`yrXZ_NFTQoTa<4BaL)}z;>h|P0x?S1o*EMUCdir zE86wB?CNc-Vb9xaON59^lKmZAr@bSscBw70Rp(~CTX#K3&FpPw=e~3s8}>;-qs|r4 z3td~Q^7uhUSO4T(LiS6$#>e{$4P;`D^aPrkU)A5^sCFDz|L*y_^Kn{F4#yb|oR3M! zMAb9+!HZu<8nV`j_^#>AIY ztIR6^+Sz%uBgWp{_Hl}3)gRUoMDZ_1f{Qzs_4YaD*1(#S?1 zhq@WcGwct@nZBn(+ej}UX-m1u`rKa6InU3(|H-RCt`Cxw^{4bic8U+y5Yj6D3#`AzpUxJT;6kekog%1blU<2j&VhzSp?;eEfq{rl`b_uO;OJ@?*oKIij{lss`&Z#9(s zgd-*1mRliq%me8cjtLm6AE$r2K<$M5K+&4Rrczk*PrB2U8;_##w%-wN2ioo5LNphN zYT+$$IET;9rbPN4t*p}GFX2E5=DIG&Ka)mRKnTNhcc1q_7LF|^mCaB!jd;<~vp{4XWE>qmW9{e{3wS(>xCZ&|Ch zP!`^XZqZI+bjd4=*Z#XP7OtPNJjO7YZ{MGvnb*8u%L{pssquEY1y#N?d z;W)-p!+GmVP|l!+oK*Rg4+!6fz60ETd`|g~K405;@M&61A521Z`qJA~*1{r7!t8SR^Uv2+!u#24Y#xOC zhX(Bn@{XZ*vO=ZK&j;}c&TxK558&V}_VoQG9=mCKaQ`n2b<)_Zy~ff+7&3 zw~tDf#23Bvg=7O-G9~r+!1T<_~`I}268DMd`1D_hQed7-{#GiIiKI;mYSQA9G~AOzH2)*@cGtw z#jq*ub~lNcjKJ)nqUUbNh|5zZmOLO+dtX~b{`N04&LaBH4w3okjNj9G`D2guvYh}t zSD2>AVPvq>O_v#$DH*4z=n~e2p0H~<{DB7yd5#?0Rin;6b3+@^=!3bhJ0lZxFV9$j zD59uR;H|=6tezo<7on4bl}_)iEVu*jEEc}qEP~#9@%zfMLK)Ja-K*T#lJ)txGA89% z_%)lYMYQfph@9-m2LOpC|0g_O<}XYlweI0M!n^btQ*7dQ*see%H;qP1CoKy#` zB!9kM#*Xv5Sn`1=`BH7m`aYE~f4&izV9~&#PQF7QTrB?fUchF|(OT2@J4OC?U(&G_ zbiZ6lH?-5cm{& zh&BWwQ2XSKj+$id)gwJ5%;e499B5N5GVIIN;4l7Jmq8XzSuV{dTXLqFWEIb!m(uOt z`qBFL;cM_?9>Wq6K~gBSF^>?|ekR(X(cHm|h&dy~4|alF)Q+&H8{E&lQyCT_0m$6} ztQf>>K;jc>`Ps&oNdtmG4b6$7<^>qhh;;mmY;7QHV1A1xxMDkz^oE!v7=+&Q z4(CFGO#lh|osWs?zKdXOOx030Omk$9gy?G0&-%m-1|qs<=_mF2KvO|zoK&NkZ3jIX zF~RYYZ=5sS{`AK4^QlsxY<}!zccTsp37`Ty+GJYLKnh$}5HfQ=WctgaEGD3ISh0mQ zD;~xN27r1V4gHb)EtFsRWJs_tkBbY2>xDt>)giGGcfK;}K@ow*?-^Jus&04@NC*hI zs(e3s_qvbrK6B$+Izcp_tpu^H5D;SVEiDOA13X&br3UfnjpXOt9nAVt>Sr>4ozWBX z(A$QWrp$SOYf(lS48l{^MBhQHgK=H2YhpLXiwb4J`KP0)O*F5jlVT_82@+h_7y$vr z6Ir7~fDjyd@`_{qD&O-iczeIfum{6rW2=O~3t$K@6@yk=++f8YtYVtTPimUbc~TVJ z(`HaiX9EA(yH0WfJ(gS;?^a22sVfksXqe~p(F=%Yc+3I$pP_o+a3*^o>Q|>C$R2M0 zwG3oibt&4FnmCE^+;FXMh3W=l0D6K(^kxVVlYGJYWDWMA+iJAg zIIlKqQ0Kcq>BX1{kwX~ubW*@<7S6s*70Wd6v+!Bf%OYSVYS~o7+%9JVC}O6g0+9D| zYFilMbk5mPaR6|?FRvs|8c+iS6c}PZb;Cfbq9ZOUS+e1bHcKwpvyWE5=k#505w74thv7)Ud?YG#GoVV1X=@9}|qY-)k#p zA4~;8Bh0KASkoT@wxg3J@$0)R)TZ26&4|0+S;{sjHTzHfLndi17ZHpN@j93G(D3}W zp9kgCRTKSinfxH}`PEl&MP^o8HlRWGWA!4_7Euhu)Q^88|Ka-U{g?N4TzQmK&ER=)^ac37DgPVP5eF2}3cE>Wl(49XvILBbDDg7AQYvTvxt_V4l?m z@Q^@{*aC>B$8zv98ne+)GHW3GW64L?4inf7mq7zndV%p8e?9omx8Haak2-CqrSlnD zwImU3P+R&P0sqnv{1&F&VE;uht}r8RgV5&BH2&&Gg>fS;*0U`v$|OpPy&MOtkBx z7ge38=07iY>>r>plabRti-?Q$znWiu%OssVo4jvE;TP`^TGVDUewtPtU)X)HF&RfSZaHjxxq37) z+XoHT1pxGy@ZdV8xEf2joToG8Nn7WJ`q(Cz<=wgp5wV2sn@vd7d=aybfvcv^4xJ|l zUPo@lb+ae2%4XbN{hJ)pYxGB`d-Xp_+6AEta|z@(cG%OrE!DF(T+%4yeCuUBvb3** zfs9xs8y|pk?W4aXd%>0HEcf*KTj!~Tip+4P>2Vsfr$r1Gjyta&|BIUcS1YT)VyjRa z65eFjsR(g9-@2eD!E9kiqY>Nz5_TWk?F)R%WdGvsz!E)06@$frnt%{_9}WWMV><8l zzwMC`y6|Muilv(16g{I5ymORaqckn?%)NtW1Lrd8EG=TzHk$)={rKK+$Ka#3?go`f zes4G-b(pjHe@6cXVvH~}QqezGvZ>5xF?8$GO;1vWD+<&L&V( z0IOp_QoZ{d*f0RYjHrg^!i-;~c6=P09hIjcr&NFO$=Pjn=u0@i@y(XMXP(B8H>5^; z4_uT1D{#f-N&jaBj1@@sM(3Yx^yG4j1m)#Gg71!^rJQsdll^Gv`{x@(Wf7u{3%)!T z+Gk*CCrI(%+UbTTGgbgNdIQNfISp#zOy82Yo0l31MNn->`K%=vTRvX?YewvNh_&y3 z5dCoz%q}7?@ZU)4Hq5l;kU5}xYFoqOo-fi=K>^X+r_bucks-> zoCBMDH0JvM2?2Pp>P$V!LB=OKs_x-Tq^6zDfDgIkb`ez#T(Q2>HQ0oX2_SrNsnD5G zCFgyB9x{wr|JSxq#vl*WGp1w(?4Ec5&_rq5U3IbCL?XFco+n0Cj#=q3P!IrOBn?y4u$t)}0Ui&+V)hAnD7P=1QfgiVMP*8yr5$ z)u`#9g?VN_Tf~MFh6v`hkpDCcFi4Fe{did%ohm(xem{N+a6%0|Agy(=(B~v4h`RtA z!ADWml%L8QaSHluJY@{id{w4$*zSuf7NcOHb8o5&XD)M3wj=-BttLD4LL9_1K)C)6c5UXX zv}1_2GUhq}h7E$ki;yE2VX*Pxw!TqiLlh1q(m*{2uPiiTZ>Jwa+&pM$C`;zm{$RJ4 zBWHzA*;YZKEjL&W|Lv22=Apz$i0>_fjE)3zx=WX7(mMKucA{GsN6L{UAYoXwX$eQ# zaM4&f>h~$5h>3<)riJq*xeZWk1DuG6sd@b|Wk5A)#3qN;awP6xC$$@f#a*lma$-+- z2dZr3E)HeOO?phLfVSq;nwkezX8;KY;O+Hfp{e0OTGISlT2^Ss)AH2Cay6}3hd>NL zUUI9D6oJGm99;)-{j=$_WP-f$??UWk)SyDU;%shOeHRx?w!l=eRxA4F#nk}ytu@1O=7IOVk=!hD{cdobLlTZ?_fc<|xofEX z!;3d3u_GjS?rH+n;|D;pB{OCwHZzCJ=wJ8tnSe~IgFBJuy2N|U7rzwzwqbZdM~&_f zMIv!O0ev>jM=hh*zs{z@YwWYcTq=O?s)1EJjJkt zLa+H!`xqO?*EI~E6?%HwdjE#JpLeg;o5<(yp<=G)igY1;}4ZL^pJ@VNj=Y)=Le$gLffM4e%iQ|ZI|<) zAVt)G!Dyr?3s54Vg2ds4HUjwXfdTEJ$=e17c%XLiQz`$HEe^l*>ebUkY10KapFgY27I>$ho8J!@w-rLXb9+>8c z-B)h;OR6Su?Idc<-p(dtq1|_49hy5L6V(0PmJdtW2TSOsKdDYgmwn4+M|ARh&QUgI zD*TlQ6m$X`@Y1)B>qgh?%M%R2V}#o=yFr4V<)9oHnRjX?c%o8V3%z&+$7jCNXl#uM zfz9@-WH%vcJDvmW2BS?A+dA6!NSL)hB#+kG9M%qrNT0T<;F^X(rf0cg@-`GtExq|h z*VVcJ%8IDpD!X+Fo96erO>s*aUS#FvbXkS)u)=|p#n5QhzQlA_lRj~NV$sa<3b{~( zrsaC{m=(!Ph+F$;|FPy@B_c$RKTFI|`x+Gn5fF9peODPT@sLAg1h=ec(Mzc}!;#68@I!YJx5$y+u64AeKT;jl)$byLd zeUL>3d+03y#j);^0s{%{@mQ>h8PW{jRuNFO~~qE`=*qZDXF2A;2cq6)LlC zPHp_!gbC7IfFwp>v!eMAcN8;8Ita06Emm5=?ok55wfufF@Q12WZpEJxto=>eW*lqk z_!JkXOoi@VZ%h7r;~7brU`%B0z&#LE?Yib{{mn_gqmOHJ<}hamjptyY_?M==pKIM% zTuTOkimJ{77bte`$xDryxkf4_V_t5GPrIlRZE!6s(R>3(g+8nKncd3u2FKmlm?ZLf z`H2vhS#pfl>cSH^Td`uTb0_ZDBJ;2}x9;-H))Dk5=cnJaZ3Kjx#((-CU=G|aAIn0H zRqw=P2unLnch;@^2w4H?YYe8{_5v7)lqlXTHNU!Z+*t@Rl1IM@@nr>&hjmCVCP|~c zh|fwWZzi(xPoQ!7f5iGcmR}8Wfib0@eUBqrMifa-aleH$VTRUv%LKV$d3df?c^zKELKA>gDgd zKk!^od1e-rV?-8$ELB(DXA3?5MUii$H(Sb+OmDmR_*fBXuE(PV76uJmHF53E1gfJ* z-zNr}JhYHSBe*GR&-RQDffzHE@(7FHBQt4UI^C~*4DEOkhS0|gg-wVb<=Be&!h-g~ zX75tudW9|}Or%EEo`$6rcP>(-JbCzIDRTP*t3?O^ztF--%3_tdHaZHv2B$V59I{nP z+g3y_RPLKEdV=tUTYS5Wqq+=)HyQA|MgXWmR(mWNrTELsEY6n>-st@|#KP_vYZ`XH z-kJB)J^Y~oK4`$H9B!JmOOmWU9JyF@*0EyV%#^V`E8Kr<5qwTc8D5fa9KpF|MuHh4 z&m2aL*V-L6CZiq-;~mldHkHk{w@Y>F*2ENuxNk~My(5pfW2n)gM>%nO3~0DN=U(RZ zeBLtYs2M|O1&Xr9=NE#89um^jtXCXf=J;`oQd&ZY8JaeRvK#IOJ4mdha+e? zfWk%EaX;~AzK(bD6$S22z(NjA@3$N?L&-=sx#!?B!z+f!MO zedj$aCRlHN=#9XLVgdS7Fy>srmApcOxNzotWyrQV!S=+p!Ny*@JGu8s0Y`Mw**{e~ zZO@pG2V^dCg}yq-i7xiO4jcuS8IAqAO*G&{b$|q9CmWds<=i5VL}B6Z(Z&)mg`%+q zRPZ|(N`NBXxUaT6R?{K_8{6EpX2n9w?_SFl9_Jj-WhZ~jAouXjaadd1th=(%YxpR+ z?FevEC+EQmm&~0GSOIAIp(=NT!q@EbgWoa{>50)y+IE5etjFSm^Z-f`uy7X}rU;y_QSe!2aAxhM&B2Fz z6i1E>_WV-FJ7wG4_n`GA`n-_~49u0LLo^8@QXs^G60qOUB>Z`X3`(<)Sp z_5LYjE#Yr-SFS@M3U{#L=YkGuZ=RwK*V1%n1ehnrAi%jGbA<^leHU$hhI;K%{gsxP z(Q*EsPMvv(s|l@VpjWV^@OG(P)^+JFy!ZGmn|evHAo5a&L9c3W#ly3W*MA5bBum`06B z9o}AWxRTplcT2>~@>eB^d0!=yf{WKX8A~zU$H_uctykz~dnkq_`)Pknr<8i-Mnm(^bLHiRSTQ`TI)k=GZXn^aMmk?G4`w@-sOrr^Fhq<6}JlY?u;mj zduroO{&5;(=B0nWQkyQQj%YeHk7@Mcx^y`#RfFxGe{#H0%2CMoC^>oNW2e^ZK7J=U zOuX+662SetPvfq6k0vyD^*hG>Mf_|`olqOYYcT>$PG)oMHn?WNMs!SW+uD4Ya?s~PaLU#~GS#3#K)8-~{%F{?M+ELmVMUoyxHoosT z!#uTV5zbP<{o|Q9x6^VUv%P^wLQoZ1wx*Ed@$))U6BtV6*8DbALS5u2+}(Hn2&JFv z70v`Tspq8TWDXh~RIt^jj=q~=QIGj3S3$qRTfKEZm$H8HfH^++o^vkBL9<}!jSs=t zGB%9PWz?arnxoXN(co!a^_I5z%kQG6=sQq2B_QhZYm?QUmED1FzqE&@E4-wil>qk< z@gU0=FTjmw5~k(RDcjo;^O5fEz3H+9yxWd5E2fFrjfD{H(!}P{O&*eUk*QHz{UN=+ z$i8*p3iin;JS9ocoDK@7!i4svGNeq>l8UsD1s?H`;59yB4HcugD;~3^UQ<(&C9hdI z@zSC&hfA1-AO|eM-HhKxlwD=1gH|@sM@yn8zhiAF94{(0sIA%ob|QmItL29 zMgH2apR=u3#6oc7h}RBPT?E{Xfz51(^L9VB3Rjrx)yT4bXpR4ZQX$BqL&9`KLeTQ3 zdzGA(uH;$>{D>`HcNGSKf64u!(j8Xm``p>#^oaYHg-jWa!6(-i>`k(C&mJ6w1r#3HVFN{gJ4Fj$wjESe*BRZ zFQh=Jy;WkqAuUB_y|qqjvkAawO9Duk1Y zc}M=&bhPeu!{Khevsg&}q-4k~N*(LkEBT>a{{-^z7e3f^cjL6WF&$D~%USMCBBG&E z#)C4aYexZ8c}kbm!r}au%_G+BozC`?%on+h!q>bl!4-p#3s3wxWTO_9#=R``=mP@7 zSSm_>^0vQ*>Lgj7wH&wnkY675A4|ybiqOJTn^rhntu0NydEc56Tmi6l(+Se%fk4{y zy-R#JNX7A)n6996&@_&^!}VdUNO$bhM(GI3QRqq#p^AP zOKq;)+GR>qHW~JtPsxOxOHBSlfmgJg}=$1Ty9vVcTczQO`(d{YUsf4n7huEWE zy2>@ryd*7c)5{Y%xyW)?Dj3TT)N+gcYsLm-z#{XRf3YmkxX_gyupf*ys^@j4==)Cge0qYu@7; zW1JqqFX<6@Ty9eCI$W-rzZ^z2RmVtbX{}K9;g-gU9%`P;wV7I^##HWf_o7v5VUAs= zQBR)(#;4aFCa%~*HX;A4v5fS3z98eS5U5?NiEjZp5J9jcr&HAMxJIw=QmtmcipzTH z+r-RGgwZEOX=bx>(@D}DcDr%P;8?# z5Rq5`@`~113ZJ@c_%l;?7%ZH!$*!l0)mNLfv_NN!vp=DQ*(yliEC{|zN@Q$Mji7)6 zbp^m3D~84+rjP_W0%WGNDlMk6t#kR!Ozk#ME((EV>?e(NzgzEyboBpzgulLm`yn&_ zb!tkn*!b(WJa$1n6KFoc_>%dbirV}IkgB?`(vN33uNfERN}CoJG=4CUu*}JHJ-bDq z3%`Y3c3NpdO~CrXWsE1~;w+*vSrDaVwGg5u>hY<>@hc$hw9MzRfuv~whlO&5ApnRn zNAkYCX>tE8t@nrhV8o6F$C6zC!;bvPej(5XYPpDmWSa=sDh=f}xhT$|3}RHxOtdT^ zP^U#eCYWdyQvL+WRo*^_RT)qCs$bE|eJH*LY~igbSNf3=Doo*rrFth{0@N9ISK8>4 zm)+k~-PH6{FJkCIlt74BoR3ZExCo}Q^!5g;HyunI>pMDQZcJm&yMv~na34U+*gBRiN6wWW}!|7Vly!;mtS z0IRAX4nmE&OmO^V4E#OEg&0-Klez~eU-I$k=346oa-~UW0qMBZR_%zFNRsZQNxx2B&i}XJ1lq*v zax}XUfc|aY(s16=1JZ>NFC4Vf=ecU_1te$;8FxvT4Wu(9y;tAHUnbgK$!MQaALa5h z#9Ol#0OQRlQ31Hp0kw4SWy+J@`S5a>ZFBFuYa*&>i0{-b;c{FKu)nqcr6HZ>SeK54 z!RYOisM`P*cTFw*%B4p8)bg^>m&34O|8y;yBWxLjeh_th)2xpD%0W*QmnxXyGBGHw zy;>l0nJ0d!+0_$qEZikPJp;sjH?P;)uuD*=0)JtX)UWq71mQQBeael`Uf5P&e#s;G zIbf*4KI-LqJQ`pS^O$-s69o|X&gGAsRhZ?K21tzZL6S|zcKH&62A7=L-O@&74Cf$! z>u#0spt>>eJ+map?L;E$%opcFpbyleAu4W9y-0o1MwUAwt4MW5Z2NlY_qZ2H&39cs zT=ZOY0X)FrcL4J{tyR090E;^orfIMt(zj4lMd|4y0p1!mMr=mucXJ|O`XKaEkO`Yl zce!4BB?v_2lD`P+Q=m}a7QRVF1>WY&p_0ZZL0R84uZwIjJsT*QWp9sD0F+)PC11d# z3Et%S;1v$(77EXf?tb_jUseb_F+H$2cB+aZ?g}Bv;T0f1dUP-td&~(iK#oe3e4!Pl zWt`i7tsZy7i>Q)|e9PFb+o>z`)UT8PH0`gkY9FVYvkYH#qK6$b(kf6c&qP!B^h!oR z9s?d?ZIq#|TQD5tkDwFOYlWO6k3_}nN&M)U@7`LCPy*&<^X0(Eb3VcIe&4G$-#ogxG&abv0-0(!O$( zqfW(I$g{{5gB)pPJ$h=CrQ$0lb3uL#lR)lV^(7z)F3=CLac$qqL^hB0*&gip`KO1? zlqsV#$4%X!1i(F@&Nz(n$@{`k@eg}=t{8$kwqx(JHoK$&wpdU!Fg#;)P1U-L*q)#t%TsT16{`6&xoJFiC`eaW5-7Y${OO%3rYFI zvTz;(hT8P6A`9=n&BX1mtcGs^+x692gEcUu<%7df^U#RAbTn8_44v)|Fs{vND_E>z zK3>Wg9O=5sWgtC%scjS^1uWo684+Id+;iOs6kcd}{~J>=$UquvjRbo$?vl3-JiK=7 zuQ7!kGS7e84frTH`a-Mr8RHed`%++fh2-oZ(|3v9F(qAP9--AWwFXY z!6}N&1zn!1``vKh%%j$*04@;#;YlTs>OZ!~Fw=i`%jLaCm^PTS%~l2(u>_b&s!OZ_ zJ>aagc+frh)rDG^lIX*TGG-*dd9XDPe}BSu-?F5i#J(R}ekQZ<&NK1V)QGZ%hGkt+ zr?qUMu+Iv9%2C;g*@A_@*hmvdSH`(vfO@Hm_)EkW548bc?rXcy+UP+ z1IO$KKE>6Dp?sdh3m_)JVQga$#;O)V1(Q(#iU}2(EPgGtABAe$Hl;Yz8?~%hrcVp9X4mT$5+pJHGo*U`dn(h`9W|A&w_~Eh#LTK$ z3AY6XPS#8wq$EjaS2PZY0!z>DlViy}2FAH(d!XEpTKMapAAXc z5Q0p9y>G&bp=`*ZGVA1I-8?U&$DE+>%86k&{TQ3E%cix{IbHjSezB`nK~CB`vs184E2o_>M|TD>n_9 ziK&oDoQbVKQH>FnU@b&$mNOb{G`qd$^O8&7o!yjrbPc@yQK0zH?fuNB&I+X5>+UMk z4g;Kyd8LnD5`I&5b8X8_g;|vqfSn)n4#@E}mo3YFIK5vXv@QO>xmkbxXP9Sc?st>Y zm4&Mkjo8VzqU%}jUxjdT>psQ@Z-}pbkQ1gmy2Q_s__u SH;#Nkz)w?MSFJ(?8~J}s7oy?- literal 0 HcmV?d00001 diff --git a/website/index.ejs b/website/index.ejs index a6b4b7b691..653cd4d146 100644 --- a/website/index.ejs +++ b/website/index.ejs @@ -686,6 +686,12 @@

Use the power of dictionaries in your project. Created by Vercte.

+
+ <%- banner('godslayerakp/http') %> +

http/https

+

Extension HTTP extension. Created by RedMan13.

+
+
<%- banner('Lily/CommentBlocks') %>

Comment Blocks

From e2366f0ce0dca84d9b13187a60b11348b79409fc Mon Sep 17 00:00:00 2001 From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com> Date: Mon, 3 Jul 2023 03:45:55 +0100 Subject: [PATCH 05/32] Update extension images (#656) Lily/ClonesPlus, Lily/LooksPlus, Lily/MoreTimers, Lily/TempVariables2 --- images/Lily/ClonesPlus.svg | 2 +- images/Lily/LooksPlus.svg | 2 +- images/Lily/MoreTimers.svg | 2 +- images/Lily/TempVariables2.svg | 2 +- images/README.md | 11 +++++++---- 5 files changed, 11 insertions(+), 8 deletions(-) diff --git a/images/Lily/ClonesPlus.svg b/images/Lily/ClonesPlus.svg index 88ed22e998..1720a0f1e1 100644 --- a/images/Lily/ClonesPlus.svg +++ b/images/Lily/ClonesPlus.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/Lily/LooksPlus.svg b/images/Lily/LooksPlus.svg index 0155880047..b518ffdbea 100644 --- a/images/Lily/LooksPlus.svg +++ b/images/Lily/LooksPlus.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/Lily/MoreTimers.svg b/images/Lily/MoreTimers.svg index 8c5397f33d..8bc4449149 100644 --- a/images/Lily/MoreTimers.svg +++ b/images/Lily/MoreTimers.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/Lily/TempVariables2.svg b/images/Lily/TempVariables2.svg index 2699e90a36..ce214bb6e8 100644 --- a/images/Lily/TempVariables2.svg +++ b/images/Lily/TempVariables2.svg @@ -1 +1 @@ - + \ No newline at end of file diff --git a/images/README.md b/images/README.md index 39f6bbd570..7d8c7cf157 100644 --- a/images/README.md +++ b/images/README.md @@ -169,11 +169,11 @@ All images in this folder are licensed under the [GNU General Public License ver - Created by [@True-Fantom](https://scratch.mit.edu/users/TrueFantom/) and [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/) in https://github.com/TurboWarp/extensions/pull/498. ## Lily/ClonesPlus.svg - - Created by [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/) in https://github.com/TurboWarp/extensions/pull/382. + - Created by [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/) in https://github.com/TurboWarp/extensions/pull/656. - Dango based on dango from [Twemoji](https://twemoji.twitter.com/) under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). -## Lily/TempVariables.svg - - Created by [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/) in https://github.com/TurboWarp/extensions/pull/410. +## Lily/TempVariables2.svg + - Created by [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/) in https://github.com/TurboWarp/extensions/pull/656. ## obviousAlexC/SensingPlus.svg - Created by [@David-Orangemoon](https://scratch.mit.edu/users/pinksheep2917/) in https://github.com/TurboWarp/extensions/pull/379. @@ -207,7 +207,7 @@ All images in this folder are licensed under the [GNU General Public License ver - Created by [@Juenjos](https://github.com/Juenjos) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1573040329 ## Lily/MoreTimers.svg -- Created by [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/). +- Created by [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/) in https://github.com/TurboWarp/extensions/pull/656. - Timer SVG based from https://www.svgrepo.com/svg/2045/stopwatch under CC0. ## rixxyx.svg @@ -231,3 +231,6 @@ All images in this folder are licensed under the [GNU General Public License ver ## ZXMushroom63/searchApi.svg - Created by [@CST1229](https://github.com/CST1229) and [@BlueDome77](https://github.com/BlueDome77) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1596177193 + +## Lily/LooksPlus.svg + - Created by [@LilyMakesThings](https://github.com/LilyMakesThings) in https://github.com/TurboWarp/extensions/pull/656 From ab6a7be37b3743d817369ecb2f94f0601bbb4cf9 Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Sun, 2 Jul 2023 22:16:42 -0500 Subject: [PATCH 06/32] Update images 11 (#682) * Update navigator image - https://github.com/TurboWarp/extensions/issues/90#issuecomment-1602552989 * Update -SIPC-/consoles image * Update -SIPC-/time image * Update 0832/rxFS2 image - https://github.com/TurboWarp/extensions/issues/90#issuecomment-1604175329 * Update ZXMushroom63/searchApi image - https://github.com/TurboWarp/extensions/issues/90#issuecomment-1596158611 --- images/-SIPC-/consoles.svg | 2 +- images/-SIPC-/time.svg | 2 +- images/0832/rxFS2.svg | 45 +------------------------------ images/README.md | 15 +++++------ images/ZXMushroom63/searchApi.svg | 2 +- images/navigator.svg | 2 +- 6 files changed, 12 insertions(+), 56 deletions(-) diff --git a/images/-SIPC-/consoles.svg b/images/-SIPC-/consoles.svg index f452db1034..216ae5c6ad 100644 --- a/images/-SIPC-/consoles.svg +++ b/images/-SIPC-/consoles.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/-SIPC-/time.svg b/images/-SIPC-/time.svg index 0ab7deea4e..c707c71ada 100644 --- a/images/-SIPC-/time.svg +++ b/images/-SIPC-/time.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/0832/rxFS2.svg b/images/0832/rxFS2.svg index cff9d561a7..f8737c299b 100644 --- a/images/0832/rxFS2.svg +++ b/images/0832/rxFS2.svg @@ -1,44 +1 @@ - - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/images/README.md b/images/README.md index 7d8c7cf157..9b629d4eb8 100644 --- a/images/README.md +++ b/images/README.md @@ -106,12 +106,12 @@ All images in this folder are licensed under the [GNU General Public License ver - Background based on https://bgjar.com/rect-light under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). ## -SIPC-/consoles.svg - - Created by @SIPC in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1431207669. - - Font is Noto Sans. + - Created by [@SharkPool](https://scratch.mit.edu/users/DemonX5/) + - Based on an image by [@SIPC](https://github.com/SIPC) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1431207669 ## -SIPC-/time.svg - - Created by @SIPC in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1431207669. - - Font is Noto Sans. + - Created by [@SharkPool](https://scratch.mit.edu/users/DemonX5/) + - Based on an image by [@SIPC](https://github.com/SIPC) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1431207669. ## Skyhigh173/json.svg - Created by @Skyhigh173 in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1457973080. @@ -123,8 +123,7 @@ All images in this folder are licensed under the [GNU General Public License ver - Created by [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/) in https://github.com/TurboWarp/extensions/pull/271#issuecomment-1475119545. ## 0832/rxFS2.svg - - Created by @0832k12 in https://github.com/TurboWarp/extensions/pull/291. - - Background from https://app.haikei.app/. + - Created by [@BlueDome77](https://github.com/BlueDome77) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1604175329. ## NOname-awa/math-and-string.svg - Created by @NOname in https://github.com/TurboWarp/extensions/pull/316. @@ -223,14 +222,14 @@ All images in this folder are licensed under the [GNU General Public License ver - Created by [@HamsterCreativity](https://github.com/HamsterCreativity) ## navigator.svg - - Created by [@HamsterCreativity](https://github.com/HamsterCreativity) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1593886519 + - Created by [@BlueDome77](https://github.com/BlueDome77) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1602552989 ## qxsck/var-and-list.svg - Created by [@CST1229](https://github.com/CST1229) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1595642879 - Based on icons: [list_icon.svg](https://github.com/ScratchAddons/ScratchAddons/blob/master/addons/block-palette-icons/icons/list_icon.svg) and [variables_icon.svg](https://github.com/ScratchAddons/ScratchAddons/blob/master/addons/block-palette-icons/icons/variables_icon.svg) ## ZXMushroom63/searchApi.svg - - Created by [@CST1229](https://github.com/CST1229) and [@BlueDome77](https://github.com/BlueDome77) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1596177193 + - Created by [@CST1229](https://github.com/CST1229) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1596158611 ## Lily/LooksPlus.svg - Created by [@LilyMakesThings](https://github.com/LilyMakesThings) in https://github.com/TurboWarp/extensions/pull/656 diff --git a/images/ZXMushroom63/searchApi.svg b/images/ZXMushroom63/searchApi.svg index 30ba849189..782aa62f35 100644 --- a/images/ZXMushroom63/searchApi.svg +++ b/images/ZXMushroom63/searchApi.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/navigator.svg b/images/navigator.svg index aae9f1d995..2f392d354e 100644 --- a/images/navigator.svg +++ b/images/navigator.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file From d3740410a2cb73d3d97003611681c8c9d412bf18 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Sun, 2 Jul 2023 22:17:24 -0500 Subject: [PATCH 07/32] build(deps-dev): bump eslint from 8.43.0 to 8.44.0 (#680) Bumps [eslint](https://github.com/eslint/eslint) from 8.43.0 to 8.44.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.43.0...v8.44.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 58 +++++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 30 insertions(+), 30 deletions(-) diff --git a/package-lock.json b/package-lock.json index 120c844694..8b42440fd5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4,6 +4,12 @@ "lockfileVersion": 1, "requires": true, "dependencies": { + "@aashutoshrathi/word-wrap": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz", + "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==", + "dev": true + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -20,14 +26,14 @@ "dev": true }, "@eslint/eslintrc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.0.3.tgz", - "integrity": "sha512-+5gy6OQfk+xx3q0d6jGZZC3f3KzAkXc/IanVxd1is/VIIziRqqt3ongQz0FiTUXqTk0c7aDB3OaFuKnuSoJicQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz", + "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==", "dev": true, "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.5.2", + "espree": "^9.6.0", "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", @@ -54,9 +60,9 @@ } }, "@eslint/js": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.43.0.tgz", - "integrity": "sha512-s2UHCoiXfxMvmfzqoN+vrQ84ahUSYde9qNO1MdxmoEhyHWsfmwOpFlwYV+ePJEVc7gFnATGUi376WowX1N7tFg==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz", + "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==", "dev": true }, "@humanwhocodes/config-array": { @@ -406,15 +412,15 @@ "dev": true }, "eslint": { - "version": "8.43.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.43.0.tgz", - "integrity": "sha512-aaCpf2JqqKesMFGgmRPessmVKjcGXqdlAYLLC3THM8t5nBRZRQ+st5WM/hoJXkdioEXLLbXgclUpM0TXo5HX5Q==", + "version": "8.44.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", + "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.3", - "@eslint/js": "8.43.0", + "@eslint/eslintrc": "^2.1.0", + "@eslint/js": "8.44.0", "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", @@ -426,7 +432,7 @@ "escape-string-regexp": "^4.0.0", "eslint-scope": "^7.2.0", "eslint-visitor-keys": "^3.4.1", - "espree": "^9.5.2", + "espree": "^9.6.0", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -446,7 +452,7 @@ "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" @@ -495,12 +501,12 @@ "dev": true }, "espree": { - "version": "9.5.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.2.tgz", - "integrity": "sha512-7OASN1Wma5fum5SrNhFMAMJxOUAbhyfQ8dQ//PJaJbNw0URTPWqIghHWt1MmAANKhHZIYOHruW4Kw4ruUWOdGw==", + "version": "9.6.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", + "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^3.4.1" } @@ -1022,17 +1028,17 @@ } }, "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "version": "0.9.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.3.tgz", + "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==", "dev": true, "requires": { + "@aashutoshrathi/word-wrap": "^1.2.3", "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "type-check": "^0.4.0" } }, "p-limit": { @@ -1366,12 +1372,6 @@ "isexe": "^2.0.0" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 562be34f1c..7124317889 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,7 @@ "express": "^4.18.2" }, "devDependencies": { - "eslint": "^8.43.0" + "eslint": "^8.44.0" }, "private": true } From 5b9aac169264e174f7081b1964ab88e5521d338f Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Mon, 3 Jul 2023 19:48:14 -0500 Subject: [PATCH 08/32] Automatic image validation (#688) * Validate that images are exactly 2:1 aspect ratio * Validate that SVGs do not contain * Update or remove images to pass validation: /images/clouddata-ping.svg: Error: Aspect ratio must be exactly 2, but found 2.0127 (159x79) /images/godslayerakp/http.png: Error: Aspect ratio must be exactly 2, but found 1.6129 (600x372) /images/utilities.svg: Error: Aspect ratio must be exactly 2, but found 2.0127 (159x79) * Update godslayerakp/http description --- development/builder.js | 62 +++++++++++++++++++++++++++++++---- development/colors.js | 9 +++++ development/validate.js | 19 ++++++++++- images/clouddata-ping.svg | 2 +- images/godslayerakp/http.png | Bin 27809 -> 0 bytes images/utilities.svg | 2 +- package-lock.json | 18 +++++++++- package.json | 3 +- website/index.ejs | 4 +-- 9 files changed, 106 insertions(+), 13 deletions(-) create mode 100644 development/colors.js delete mode 100644 images/godslayerakp/http.png diff --git a/development/builder.js b/development/builder.js index 757cf7e492..9a2f025994 100644 --- a/development/builder.js +++ b/development/builder.js @@ -1,5 +1,6 @@ const fs = require('fs'); const pathUtil = require('path'); +const sizeOfImage = require('image-size'); const renderTemplate = require('./render-template'); const compatibilityAliases = require('./compatibility-aliases'); @@ -7,8 +8,6 @@ const compatibilityAliases = require('./compatibility-aliases'); * @typedef {'development'|'production'|'desktop'} Mode */ -const IMAGE_EXTENSIONS = ['png', 'jpg', 'svg']; - /** * Recursively read a directory. * @param {string} directory @@ -52,6 +51,10 @@ class DiskFile { read () { return fs.readFileSync(this.path); } + + validate () { + // no-op + } } class ExtensionFile extends DiskFile { @@ -63,10 +66,12 @@ class ExtensionFile extends DiskFile { // TODO: we can add some code to eg. show a message when the extension was modified on disk? } -class HTMLFile { +class HTMLFile extends DiskFile { constructor (path, data) { - this.path = path; + super(path); this.data = data; + // force development server to use read() + this.getDiskPath = null; } getType () { @@ -78,6 +83,33 @@ class HTMLFile { } } +class ImageFile extends DiskFile { + validate () { + const contents = this.read(); + const {width, height} = sizeOfImage(contents); + const aspectRatio = width / height; + if (aspectRatio !== 2) { + throw new Error(`Aspect ratio must be exactly 2, but found ${aspectRatio.toFixed(4)} (${width}x${height})`); + } + } +} + +class SVGFile extends ImageFile { + validate () { + const contents = this.read(); + if (contents.includes(' elements -- please convert the text to a path. This ensures it will display correctly on all devices.'); + } + + super.validate(); + } +} + +const IMAGE_FORMATS = new Map(); +IMAGE_FORMATS.set('.png', ImageFile); +IMAGE_FORMATS.set('.jpg', ImageFile); +IMAGE_FORMATS.set('.svg', SVGFile); + class Build { constructor () { this.files = {}; @@ -134,14 +166,16 @@ class Builder { const images = {}; for (const [imageFilename, path] of readDirectory(this.imagesRoot)) { - if (!IMAGE_EXTENSIONS.some(extension => imageFilename.endsWith(`.${extension}`))) { + const extension = pathUtil.extname(imageFilename); + const ImageFileClass = IMAGE_FORMATS.get(extension); + if (!ImageFileClass) { continue; } const extensionId = imageFilename.split('.')[0]; if (extensionId !== 'unknown') { images[extensionId] = imageFilename; } - build.files[`/images/${imageFilename}`] = new DiskFile(path); + build.files[`/images/${imageFilename}`] = new ImageFileClass(path); } const extensionFiles = []; @@ -212,6 +246,22 @@ class Builder { callback(this.tryBuild()); }); } + + validate () { + const errors = []; + const build = this.build(); + for (const [fileName, file] of Object.entries(build.files)) { + try { + file.validate(); + } catch (e) { + errors.push({ + fileName, + error: e + }); + } + } + return errors; + } } module.exports = Builder; diff --git a/development/colors.js b/development/colors.js new file mode 100644 index 0000000000..6dc21194d1 --- /dev/null +++ b/development/colors.js @@ -0,0 +1,9 @@ +const enableColor = !process.env.NO_COLOR; +const color = (i) => enableColor ? i : ''; + +module.exports = { + RESET: color('\x1b[0m'), + BOLD: color('\x1b[1m'), + RED: color('\x1b[31m'), + GREEN: color('\x1b[32m') +}; diff --git a/development/validate.js b/development/validate.js index 79f37a5eee..e9386baebe 100644 --- a/development/validate.js +++ b/development/validate.js @@ -1 +1,18 @@ -require('./build-production'); +const Builder = require('./builder'); +const Colors = require('./colors'); + +const builder = new Builder('production'); +const errors = builder.validate(); + +if (errors.length === 0) { + console.log(`${Colors.GREEN}${Colors.BOLD}Validation checks passed.${Colors.RESET}`); + process.exit(0); +} else { + console.error(`${Colors.RED}${Colors.BOLD}${errors.length} ${errors.length === 1 ? 'file' : 'files'} failed validation.${Colors.RESET}`); + console.error(''); + for (const {fileName, error} of errors) { + console.error(`${Colors.BOLD}${fileName}${Colors.RESET}: ${error}`); + } + console.error(``); + process.exit(1); +} diff --git a/images/clouddata-ping.svg b/images/clouddata-ping.svg index 274b7585c3..6eae7df964 100644 --- a/images/clouddata-ping.svg +++ b/images/clouddata-ping.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/images/godslayerakp/http.png b/images/godslayerakp/http.png deleted file mode 100644 index cc0d60026e8d9ec0856470dd863603c4b369ec9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27809 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 z 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 SH;#Nkz)w?MSFJ(?8~J}s7oy?- diff --git a/images/utilities.svg b/images/utilities.svg index aeeda95117..ab0ce25a11 100644 --- a/images/utilities.svg +++ b/images/utilities.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 8b42440fd5..17d82f4ddc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -133,7 +133,7 @@ }, "@turbowarp/types": { "version": "git+https://github.com/TurboWarp/types-tw.git#59febbb5494a25898defda095ebe306a747974dd", - "from": "git+https://github.com/TurboWarp/types-tw.git#59febbb5494a25898defda095ebe306a747974dd" + "from": "git+https://github.com/TurboWarp/types-tw.git#tw" }, "accepts": { "version": "1.3.8", @@ -812,6 +812,14 @@ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "dev": true }, + "image-size": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.0.2.tgz", + "integrity": "sha512-xfOoWjceHntRb3qFCrh5ZFORYH8XCdYpASltMhZ/Q0KZiOwjdE/Yl2QCiWdwD+lygV5bMCvauzgu5PxBX/Yerg==", + "requires": { + "queue": "6.0.2" + } + }, "import-fresh": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", @@ -1130,6 +1138,14 @@ "side-channel": "^1.0.4" } }, + "queue": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/queue/-/queue-6.0.2.tgz", + "integrity": "sha512-iHZWu+q3IdFZFX36ro/lKBkSvfkztY5Y7HMiPlOUjhupPcG2JMfst2KKEpu5XndviX/3UhFbRngUPNKtgvtZiA==", + "requires": { + "inherits": "~2.0.3" + } + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", diff --git a/package.json b/package.json index 7124317889..57f22155ea 100644 --- a/package.json +++ b/package.json @@ -23,7 +23,8 @@ "@turbowarp/types": "git+https://github.com/TurboWarp/types-tw.git#tw", "chokidar": "^3.5.3", "ejs": "^3.1.9", - "express": "^4.18.2" + "express": "^4.18.2", + "image-size": "^1.0.2" }, "devDependencies": { "eslint": "^8.44.0" diff --git a/website/index.ejs b/website/index.ejs index 653cd4d146..1e620f2d0d 100644 --- a/website/index.ejs +++ b/website/index.ejs @@ -688,8 +688,8 @@
<%- banner('godslayerakp/http') %> -

http/https

-

Extension HTTP extension. Created by RedMan13.

+

HTTP

+

Comprehensive extension for interacting with external websites. Created by RedMan13.

From bfb68ac6a909ab23ac4c2715d29b8515089f5739 Mon Sep 17 00:00:00 2001 From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com> Date: Sat, 8 Jul 2023 01:56:23 +0100 Subject: [PATCH 09/32] Add Lily/Cast extension (#605) --- extensions/Lily/Cast.js | 73 +++++++++++++++++++++++++++++++++++++++++ images/Lily/Cast.svg | 1 + website/index.ejs | 6 ++++ 3 files changed, 80 insertions(+) create mode 100644 extensions/Lily/Cast.js create mode 100644 images/Lily/Cast.svg diff --git a/extensions/Lily/Cast.js b/extensions/Lily/Cast.js new file mode 100644 index 0000000000..5035acae5a --- /dev/null +++ b/extensions/Lily/Cast.js @@ -0,0 +1,73 @@ +(function (Scratch) { + 'use strict'; + + const Cast = Scratch.Cast; + + class CastUtil { + getInfo() { + return { + id: 'lmsCast', + name: 'Cast', + blocks: [ + { + opcode: 'toType', + blockType: Scratch.BlockType.REPORTER, + text: 'cast [INPUT] to [TYPE]', + allowDropAnywhere: true, + disableMonitor: true, + arguments: { + INPUT: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'apple' + }, + TYPE: { + type: Scratch.ArgumentType.STRING, + menu: 'type' + } + } + }, + { + opcode: 'typeOf', + blockType: Scratch.BlockType.REPORTER, + text: 'type of [INPUT]', + disableMonitor: true, + arguments: { + INPUT: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'apple' + } + } + } + ], + menus: { + type: { + acceptReporters: true, + items: ['number', 'string', 'boolean', 'default'] + } + } + }; + } + + toType(args) { + const input = args.INPUT; + switch (args.TYPE) { + case ('number'): return Cast.toNumber(input); + case ('string'): return Cast.toString(input); + case ('boolean'): return Cast.toBoolean(input); + default: return input; + } + } + + typeOf(args) { + const input = args.INPUT; + switch (typeof input) { + case ('number'): return 'number'; + case ('string'): return 'string'; + case ('boolean'): return 'boolean'; + default: return ''; + } + } + } + + Scratch.extensions.register(new CastUtil()); +})(Scratch); diff --git a/images/Lily/Cast.svg b/images/Lily/Cast.svg new file mode 100644 index 0000000000..c133d27df6 --- /dev/null +++ b/images/Lily/Cast.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/index.ejs b/website/index.ejs index 1e620f2d0d..f6dd5b3ab3 100644 --- a/website/index.ejs +++ b/website/index.ejs @@ -572,6 +572,12 @@

A few adapter blocks. Created by TrueFantom.

+
+ <%- banner('Lily/Cast') %> +

Cast

+

Convert values between types. Created by LilyMakesThings

+
+
<%- banner('-SIPC-/time') %>

Time

From f63699ae87dda2c3b89f4f83c04d5e6a4f2c6926 Mon Sep 17 00:00:00 2001 From: CST1229 <68464103+CST1229@users.noreply.github.com> Date: Sat, 8 Jul 2023 03:55:23 +0200 Subject: [PATCH 10/32] files: Add download URL block (#700) --- extensions/files.js | 71 +++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 65 insertions(+), 6 deletions(-) diff --git a/extensions/files.js b/extensions/files.js index 25842fd6b2..2d1cea7860 100644 --- a/extensions/files.js +++ b/extensions/files.js @@ -165,21 +165,58 @@ }); /** - * @param {string} text Text to download - * @param {string} file Name of the file + * @param {string} url a data:, blob:, or same-origin URL + * @param {string} file */ - const download = (text, file) => { - const blob = new Blob([text]); - const url = URL.createObjectURL(blob); + const downloadURL = (url, file) => { const link = document.createElement('a'); link.href = url; link.download = file; document.body.appendChild(link); link.click(); link.remove(); + }; + + /** + * @param {Blob} blob Data to download + * @param {string} file Name of the file + */ + const downloadBlob = (blob, file) => { + const url = URL.createObjectURL(blob); + downloadURL(url, file); URL.revokeObjectURL(url); }; + /** + * @param {string} url + * @returns {boolean} + */ + const isDataURL = (url) => { + try { + const parsed = new URL(url); + return parsed.protocol === 'data:'; + } catch (e) { + return false; + } + }; + + /** + * @param {string} url + * @param {string} file + */ + const downloadUntrustedURL = (url, file) => { + // Don't want to return a Promise here when not actually needed + if (isDataURL(url)) { + downloadURL(url, file); + } else { + return Scratch.fetch(url) + .then(res => res.blob()) + .then(blob => { + downloadBlob(blob, file); + }); + } + }; + class Files { getInfo () { return { @@ -253,6 +290,24 @@ } } }, + { + opcode: 'downloadURL', + blockType: Scratch.BlockType.COMMAND, + text: 'download URL [url] as [file]', + arguments: { + url: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'data:text/plain;base64,SGVsbG8sIHdvcmxkIQ==' + }, + file: { + type: Scratch.ArgumentType.STRING, + defaultValue: 'save.txt' + } + } + }, + + '---', + { opcode: 'setOpenMode', blockType: Scratch.BlockType.COMMAND, @@ -314,7 +369,11 @@ } download (args) { - download(args.text, args.file); + downloadBlob(new Blob([Scratch.Cast.toString(args.text)]), Scratch.Cast.toString(args.file)); + } + + downloadURL (args) { + return downloadUntrustedURL(Scratch.Cast.toString(args.url), Scratch.Cast.toString(args.file)); } setOpenMode (args) { From 60507385c91a4c79c07d59b1e4ac523ffcc2ac7d Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Fri, 7 Jul 2023 21:16:01 -0500 Subject: [PATCH 11/32] Fix some image pixelation issues (#689) * Convert cursor to PNG * Convert gamejolt to PNG * Convert pointerlock to PNG --- images/cursor.png | Bin 0 -> 8767 bytes images/cursor.svg | 1 - images/gamejolt.png | Bin 0 -> 1926 bytes images/gamejolt.svg | 1 - images/pointerlock.png | Bin 0 -> 28312 bytes images/pointerlock.svg | 1 - 6 files changed, 3 deletions(-) create mode 100644 images/cursor.png delete mode 100644 images/cursor.svg create mode 100644 images/gamejolt.png delete mode 100644 images/gamejolt.svg create mode 100644 images/pointerlock.png delete mode 100644 images/pointerlock.svg diff --git a/images/cursor.png b/images/cursor.png new file mode 100644 index 0000000000000000000000000000000000000000..b53b880cd6f65718e65c99f2f532256eab2b71dd GIT binary patch literal 8767 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 literal 0 HcmV?d00001 diff --git a/images/cursor.svg b/images/cursor.svg deleted file mode 100644 index 5a0ab87dbb..0000000000 --- a/images/cursor.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/images/gamejolt.png b/images/gamejolt.png new file mode 100644 index 0000000000000000000000000000000000000000..d72c1540549d5a3d19cff91b8626df86368c5777 GIT binary patch literal 1926 zcmah~c{E%39=|whElM$i8EdFSLakLXh9Q?@&{4Am_#5dai=_8+l6%EJf<{4~i0m*hu@N=hXr zL;|U)sVLHAa$-1<8i}GLM3=0hHJ~t(-sdj3K+akkx(2#%m>vSAZ(_J_NFxKtP^Vy! znVyQn8ylJ$8=4tYh;XCR@c3|eLIgZ90+ASrNRBeO;Dbb1ApN|NS4hY!vB>mTRA!v% zHOgtim#4EYS>y#4B}lH37E&B zm}VlTCDyei%uip7$xme!E!9XE$wQYt8AF(l)XDbl_-TXPw9iRF8r5X-p6G19 zrk$pCi%#e9T7al)LX%`W;iTngbWll6S`Gq~)F42|1OmQzsr~fVFx~GDLcH9HD-ff>2bN#~%`CG=+tlNLf$@JAM z4-UEeYM!0HkQQSnca*iJQ2Q&ntAQ_g85*oFEZ6?^NC+01yH*umiXw8%6Mk)idYP9e8?lz^nsZN(i&V9+thYO%@S~oY zvddAc>?d>=lQNNm^~tfb@=f~wa1%Y-7lnAdwFE@Vcf)PToTPv)f1D2ULE6v%#taJn zSfYa!u|zuI#3GD%L{zgpISJQK*D@jU85&@ld(l$#9hd=BHjkvo(WPt~wZ z>w3dh8I(AjZJ4{_!0-e`j9AyBb2`j%9&GJ~^^IwAdL~Y)rO;Ia=4mK4`?@6iB4a2~ z(zXz*swQ2q^SvaElb>}m_}zKj$xSm>1Oc}&y4#h-l>Khf=)Udu!%F@y!Q@Z|{h zSyTva<=C3y;?B~nUsBy0CUwM|S)YsDpwaEtAcByw)kMSwUwB8;MqBnpM^X^{cf!Pj=Iv}JPdAtx%LZdBM+UjlwXI`2=mBN6 zh@YuWZMI;sw#Z!T)$x~BE1%t(R`}Cr!|L+={)L>`Qm^#Tj$7fq9^6mocty#%+c;@* z$7bH6<-)}&^cjb(G|?tvT^d20$=^^iY+q=S5`$E zT`f*$Dh_V&Csk1#gN&k)8}>z@p6!P|YxVtmjU2yB?I#l(CZx#h8oH?jZ*Q>Of}PLj zmINeaY>(xGETI8wUXe)btzo1@`GWF-+*#N1Tdw84d0*#p8{RS}N$1Pf&QIP;@miFTBffkErdtKs^IinC-Ccfh7rcl-^9YUqsBhYR zDsZY5-V2!x{wPjf-3;QDmX>e4TjM$$w~hDFV?KSYl}SywDijRaYadEf{+|=uA>S@a zc`8EtwJ%zTVHJP*vdq2*8zoJcPGx_2_f9{DK6{wY3jP<^{-~A4TJMM|jX!CC^sJ^p zy>9G@h5Cl3KeIO+-4jWxa1IjMlDV6!F`e*)=)cGdt5 \ No newline at end of file diff --git a/images/pointerlock.png b/images/pointerlock.png new file mode 100644 index 0000000000000000000000000000000000000000..e653ce69e45e5c8ce89cf5af909b56b1e77db941 GIT binary patch literal 28312 zcmXtfWmFu#(>2~Ly12VL#ihvNQrz9$-EDD);_mM5P$&+?o#K=t#l6_O{k{L^1BY|6 zyUERDa_7z@iBeLKLO~=zgo1)Xk&zZxfr5h3f`Wo(0>D685)E|*Apbr(No%`8L7{&C z_Xj=dSYZZf#CMa>a#MA*aPu^FF^BT>^klJiuyr*xb~0yibg|4n|4aY{s!6oKm2Vzx@jLxEm&q>>#w!-*F^f^!4_KEyM4=L0E!?-$2kaJm49*Uu zD*a zoN4CkxhS@jx42!t@xhS}3=9)3)7Fj4tm6!LZ*nPU&yWy7*T$ zFyF`11PSwk{=aW`*m%VhOvj~q82JincHfnDoe9@&zh;ljyl?ppDfm5|_AS0#S%jEN zrNp;;dxi;%WfB(xwOZ2BD1*tw|4kbPG;H9el&SjbT4N!YSa5EOQgXYfOl@)bj$`J@vC&7^{uItKFFfjoON~haU2O2o`aSLPmga`!l^a;RAZP(Xd)b zQ_oV9NgpKgPM$0zSVGBp!@|k_KiCU^$CHxiFOnoevWA7Ads3pXeP*M}0V&%iv9+!! z>6>r9(f^^UgRz?}k$h==Qu-CTnh2O8vGwc!wVK0l7vlB}(QbnZZ?pgpjvV3_m8HD6F0jzDe1abM6{8(<;yX7{r7_5B+EVD1nym*83t!Ft$HQpH zXt&*#n*+LjBo)e_8y9_Y;aI-J18PvJ-9-HVF9YY-A;Z}tP$y+aHLawN??htw&UO~s z!gc*}+-i?_1nqwla;w~BPT5Qf(0G@5^WxxWH)}UPE_Nr$Ej%64L>kp?DIxRwdDFUK zl}!5Ae{N@i3qbfY%EcRbPTXmDv<*F-1c%JXzui7dBmE~rMBtz2F3c0l=HfyphSTHz*6j^yFxhVrX9-n=0<7%H12R_jWNL&M zc((jeN<*iI2)q5+xN*ZouT*levcV5gKhYjaKZ#Y_yBL8^WtRAD2vjeV^R!N8XFXVv zeLn#J?nOF0;K*dJ?~q-oxTv7ae)#MT&1V`n)i;~`s-2*&3cQt(2X%DQruhgs!66M? zB84IbqkmjJxWwt{gKXpy32d^z^=Xb>rQeZuImP1m4f}-PZf6?gYMX`2C?zVx@&` z+(hyOD$}KWw6-Ix%*KGSb9DUds!3TMf2udp9g3XlRKByb_$cSTF-{AuihYr^>sB7^ zz2@aRW;DLLwJ5mRSkSxa{HJ!~n;-1g?)RGKM)i-_AXmfEeM=+7_s5tql6xZ`< z2Zfyx$Piyxc?BydGZWJ`-vkU_3?kk7h=piQ)=Gc&o7qZGhR-u@oGQ>!NL2qIwr=cq zsIWfLwtsI_${`IO6!v697Bv8SH1vy4o$znV)^2NOx_i-fUc@l=&=jQTEh3ikoK~FH z+_Ew6u;3 zNF+>U!^XuQ764)pnmdD+%ytO`$%;c0XX^B-=5@}brz8~42I?jx%!N+zy6e$8^6#PS z!2^UH_yn^J5)gTq9r%ca)VS&Q*9+hbp5z_ZJ*)gGv?DzrtTUhgH$^YW4ZaD&i5%vL z9zMyQA1W!#MS}RdI?-bhU7YQg{H0Q?!IzG45p-vrqh9`iKJ1JgOdy7Vp+-Da3k2n zgQqK<0_v}nc0|afV6UtU{|cto9o*bHj1Y#17P_%U36J|`3h9hy{l;ZiYwCL4>tQfo zkLtxk9x&wb(_lU};XTvzr$6vC?x9N%@iH$6l1rTn%UlaYH*v6WpKl_tgR4xpHspJ5cqYiGCY%^Z<6D#J*BoKGa z+{m)S`jE68IUZJ#$<{wtt26FWhy9{eP#}55|{%QAZgNX-Y)mYRz3WyvU?(K)oVY>4;Ic>C?j-Q}w*}E%QM7g$LUw?F`#UFbX|*UJpBhLx2;~BZ2pUrk z(M_SN02a&*3Uq^0^~AQOo=N4o@DIgWQFebaq_^%>vwdpn<8kQ#7v&1#VRWc`f>&2` zb0&g2ONQ;Q+mN%sF5R{s%wJ6@yGpNf=oNWDm(!U}G~5nBF9C?ck@FNwrGgi(TYowf zykg0m3)gM033HV}17r+-2y>s!5ZdltkM#Cl9Tcca1R;Cm^PmeV|H@^fFzHQ#L@`#4 z=VbaNNyo+kl)AF}l(*h1Hn9?Ri6TLoObP&cD3Pfdo|cvM4}+0*^ey_-tIIEEIOn-A zGNS_WhCgx+eu|)`M=n4Fj`uU)iHiNI`JfwIiFd(#Zf4l0?}NVT&94~`mpY&6=^qXD z$s3sPg--WGNQMbF8Zqd>m**~TXJsK%O}xPA_$1@Ruv_S`>cSkFPsOB5XFCSBArzt} zWDlAszL5QwFvcsfmLlJx`fy$ADWyAmAOi3aKgtwXmi83T9~wAukHg!Pjr#Vu%fM1R z+W1N^JURe__>4;dsLq)|Hfu&DpM)v2iA4@Uczx_GgJZOj?!#XHC04N!@p#6D9=wCb zrej zotXBi&El$y|9Uh#aIGQz@1)Ta9_9z~vC3BhG3(if?D)Cx5OC-6Z{LSw6;vX@h5Xt9 zpNY0JjI+_D4h+TNF%87+KW0$S7Fx7}O-N*d0;{57K#qr5eQhbL;_!MrZ%7r?bi32C82ygo!pJ_|pE;s4Lq?h=S z%p`3g$0tkZe1cRFyiaO%YZd%!=}#i10&=eeBE&{`86V!m3P(CmPzEFl=-1N$qOS2t zg_`yCA|~sTAg$VYyF2H_=2qQ@JDRE`28C?YgZ%p;<&@aWHLRhgBpMXaLKXYw{KY>+ zM#xNc$!>wOetIZdYIe6LfCVov?6}sKs&my=AqD$j|Bp8?7B^&oA6yUv(qwBu2bEVI zj92+eIJ{f&xj3^WbncYb#ov!Zzn@F57jdw?bosF@&xC3wU*CF~L}=q9U+@r{o)M!9 zF!||ol_yHpFaDXg$dTVn(=ojT zg#6(9+o9k#cd5aA&2~e*t$^vm{q^6y9~&vvPjD0#{y;)38WGcr;i*g+ObLn=Agirp zBZ}G83mExcN!v{d2`oQO6caboHVGI4tBr+mryzXPLgaDjukc{myW(YK5Ec^v)#cFl&C-M0cSZqe&;>Wq9}}izLDz#gu3G!< z!4^-g#w)$R__`7E(Ssd``Y~s=4Ag$8wDH(~k;Q#{=CV&myDOtfSX`9t+8u{>myK{4 zC16E65Qqs0&~Nv22;)FP#ZGnlR5tQiWQ<`;U2vI6GMu`0aP>JicPqv7cXz9UM7C@ z;8{Ntvy6ELWQU1wH6<#jYRV%_9wifr&7ga&eNuw{MY!Nr2k{9Uo#4+-rEp5D6yr%c zYN<`6I6i+pB?z_z92-paxV^o}-gCo4m=Gv-fa$)FJrkK^tWbT)lViY7_nG1rZht(n zc;Qm&SE!f&^U^c^S6t)5pn+K$G*OlhhMWAE>Z`E5sifYba4avLBFIq6FT`zMcDiNTeHh=)$ip{Df9L| zrE|~8$>t>{FZ8#BuJz;*vi$%kob13qHgsqrY8N? ziVsSM_IcZGT`~LJQj~spBPy495OZhpd|7fKagcaox6)WI2o6{mBwI%J^+Mfoa~Xe* z?wCtE?^i5$pF#VBfVxnB>a0*?ep8;9I5gxnq8!Ou~I>pyq+p8O_prZFCH; zMi)LOx~luYpW?ys??UE<=Du0I*l6nq@rA8L(nb4p>s=vvg4#ESGaMT!s|yQEmm}!a zzpslu=2iq-ojzhY59qw!rce>05EPx*(}9kkU*sJL(jQgWD6l*I!=ZO2oq@+2Tbjph z4NqoAM)VI9p<=50eYrdr%JvfgCL+mhAZY9z4;RMg>fWhUm4+75SImeb;LhwcUaS*D9!j6jd)`p*Tq^RxH9Af z>U2-mom~g#m0T7!P0ju7X)FsxpX+=hs*i678UdDD8QZeVaKXpk2+=B-Ql zf%VHr_TY2@eR?y88P7JL)q^K20ZU81^EDnARAZFD;fE#1G~Bm0D~ zU;V5!SOVa9brD~}4c9GC32>?i|><0<@`DHR@37KB??kL$hsz@Qqux zo0oe*(39A2b>MSu<9AV(nI%XXC!8Ihs0gFTyBEDehUJT%OxDaqAsId}wp#N9Mmt1d zK;-vC;86Q^l!)59?Gnq9aZ_6cd$Q&HSfhT1ThUDRrEupYR9K>@{eGMc$DCl$wQ7xB z^!p6qx+vC2?V{#@B3qBpSv;m9s*Uh=6b(OLz!9s>L(cI`p3zM@q&o6IfR?l^6qGyi zh%Cy&u94HQYx<8BUbvp#SAqxH+A}3zoRr2wbZKa|Q$-}l^TS?}fSe^1Q zviUP?6X?Q9ON9fTwKFlp<1Dh!36q_8389#Qq|wNoXHb008&~dzRXXjynu^Ho83veRZ-KE3;Xl8M71|DZ1k+9kGfNH)2RJe7rnD@2v>*IM}%g)l3L$ zwAd_lwWhSc?G|pSg&!my?aE$vvw^WdRtlfkk-@Z)reWs+hU$nkaT*+tjsX(s8+AFJ z9rZlQwHvSde{&Bo@9|jqQ%w2cvcid6sU%wrm`(!XV9`EiMA>IY>O)KHKO%U-d~SFI zm%~^jXHsW;F`%}ZP0->PWW*o8Z5ex*7s*4o*&OftVzVG`Jk5UY`PSbx6EkA9;QK!3 zmEmVm!y7`zS&oO#+^znNvh1hcgHV$1RAi!uKw!hpoDHiD9K+sDs;-JSvZm9F>DD54 zncK92k`y1np)@Db2wcIkA#vxGN=H*^|dD$T4k(_fLUs>$YMJ1`jcVK zF4G~kkLp)-S#EN*!CS#U`#P^Y-mzScA?cyINp>E$PV9d z@9}h)Cl}%5eKELOMi_ySgOoJ|x{K(2*4iCR{_=OdFwB-d04uSXEYM3l6Aou(tE8<{ch#Qt}4!hX$*vpY{>_3R<$+2 zb_k?zs710UXMd#@w!p~MeRLuV1utwTq@a%;XMF3al(LEtGT+bmwR4RXn7-GH8JjSMWM6-r-`I=fCMRG2u+B+zp?60`^sHB9#B;2)zk5ls_FNN8U73FYYb7JWX zcRXe3w0FUiKa@H=jv+d>a3O1mstk8W!Vgj^HP23m3VpycIrK-f`jZ;wS_a+sZ zx6xhHp+=p$nZ|4ZzEGPvx?M{{`GTWbb~%3V9e;F+`iAH(t8@o8baa3n`o;*9{B$6_M6N){(%6}5#biV`Uq>-*);W!bTtvSiu1Gv+$s3`U;%{!bXB=)B zd2BVge;ul~I>>==+@Y8QarY=Sp10L7+wgcWR4gnQ5YquFMXZ2S9aMPW(6u_c?qC)^ z48S7GNw7&m+o^Q!{Dz|3MFOm;FxYMa=ydEph{wQ?vqFfaM5~MbSzcjpNHy*WaDj2L1vbE-@4+BLn%g$m)Us=-+9jgU*gy8;NtDX zUn*uhq)As~VPr0XP4AO1b_Qb_7RS7ajurK^?#P*8#~=EX8E(UcwJ5TgeSymSCLgmY zM8)<}etZNMF%5>)@E2aS18d&D%EhUk*CNsfaAlow-Wv}&%JjOf{(n#^?e z%eFC|&tE#PGhu8NKPkgv*Sg+5G<{G#JIOtpnNt@N_i9s>wDE8sX0j9dXyhwg}gJj{D21<)n2c`?=a8N=y!leB0DagsquQ+3EF0LMTL~ zHG520X4~J|Ar(m^e%ClSVm&&AeGC{fF^nY3*?!Zi2S+f#xhMf|uYtJS^;HUBNIMES zKIkft@>y6s(-q|93UDtla-KYv3iaf8P`owY;%+SV>T#Ff`1K(ZHV`YW?FUoV2!_bm z174<&CkFiQgVj+~wJL!zNU8sb<$^Ho*=2+Pe``aS>)zmo{KP0Kev%lrF2AGyPnWK| z#?Wl^1d`*i@=fP$T6ZzExUyq*N}`hwq3g+Ck>%n*|Bx_zl}ee7Uk0FrKR`0UC7F|_ zb^G!UO_{hIrTg}*)!aH+;{zh=nSIuDS1ZqF1;u3jATM1KRq@nNPsP$xNoS=~vv+$A z!IJiJFhb0hJ?|J;?8YfAOAzoxNJ)9$M@Y;ehl)Z#Lk2x_j@|jgOsZ$&WvO+5;*cQ1 zNsnMEutFyi$?}Ze z+lspHS$TP;#I>_J3XX<~bqKxOrDS~qJmFC;9E;V|Arh&f1DdLZg~_uyry3LqtDcOn zaH8vzEEUag$g96>bEd%InY^^yV??fUKmMRCG4VpmwXT?TJP{I@O5r-ise1Q&RBqWZ2Ep>Qld zmljXQ1z$#CZI_HC;ju;1iDiXn$ukviAfqR3?2XgU|EL*6GWOs6^3pIJxppePFL*Levamv{MSB+Nh_PtT7S?>0#C3)X|O3_ zFKwM@?^mxY&K)*@RU(d*X-Ax&i_~<^;YzMM0Ux5W(pO_-4d7O{n_e3nwJ^= z*NRSBUwkpycB~!0ELR3Ll6+8O{O^|RNn4Y8K<_#=zA-EL`LO>S{`s25(HZ+R%whTL{6is{ zopT-vu5eDo>J|^5Ef0~1Q*x&{%z#85H2A5p4}Fz$uDhD~nwEOQsvj8-9KBU!!K&5K z;=@i26||$00k+JT=Uns@1C^?*JJ<+kq|FaN*^xEkdcrE}ZyFx=72WBbNY^Uly+ep) z_{w$Lnio$ZEkto^OLrDTi`)fa6ke^Nd!CiN0?hZ@4B&#W_mi~ z0vkJ7lZ=jrldEasT6Cy&U)S8lX4x2`C@l>+5i+K2btKcK=v5Xjlm(~3eCa#xFY+NQ z-X;kMSS`H3uk2UPeo>sMPGo-NqDp%&7bvzN2V8C_B?Q#H+m+Yk0@CudoxtVT5ZwwMyjVEVUM!}tXR8!Ee7yGC zKBb0xis#7^J9s@euOSq*H;Knmns{vyqv8m7_%IvpT1E;hrXf8Gy3#nZ#gcEMM;e3D z1ecU>fp{B|lTqVPCd%92=40Q`?w&bqf5WwHLNWtcOI1J2$FG-Ok$M@mVqGfLD{3h6 zhdx6H8>7T|OUGC&Ox7U-IU=j(v7IspqNAw~5)m5dTn?gyq`K$41qsx8{qGk1Rj7_Pon{0#-M5>?DgIq4b#>%H7 zKnr%w@vnJ87P3T>F_oSBU$DRk?~Z+^fLt#EPRY$6imVQ zn!mD`n6oaigk1$n_G%Xvhn=a28zPg{p==93mMQU)ZW}9E)jwdxw>C^;iPXyz7n+sR zRk&l?f6DdooTzefd%}jCP9Ds2q!Pv@YXdAuT@R?BRFV#jxyhJ3IK`pAbm(!hz&R6E ziiwd~1V$mlww1Uj zvVw&L-Q>%t`Igm7spIm6Wd{9-*;mNPFN9N-(?gOT7rI>4f0h`9ketYyKh{8wgR9a` zH($8Lyb56#0puar;Vwy3ePH0BC#)Jc{7LOoCYT(%SqIoF3$&z`Zo@9AM>oUl@$SAx zYM4T{26)J$zG`h>hdPSc$#iS4!-d&UY7x3;uehrkP*4Ko(IOa@cLxuXk(0wr zpSjlU`=NbS%!?zcn7z7$W8A&ppvUj3fR~cn<6+T}c-dv{H-|0Sa!_jQ{xfHX!a_RAVl0c zVf9a$Cq`_?=oYiW$ExbgUd+54xPCop^*VWMB5SFwbPWh&I^;rGU?e$*zvBD+c@xS5%sdh3wVYeg8b(CtYD@i)I&2b3bE zyVzC{CTrB{K}`s$EUb{(vfmq9Ui2zEu7qjOzUq zcLs$4==Opam57b)1Fh~d)3s=p7RaxCJd__uyV~kMJXiKFCi7?|n`^VEQ4K*)<JBjlm)_gh3c|J#LCmbFD9^3AagaseqJU2r)yPIMMhFXNQ?t7YG+ z*kwwp{G+&FF2UBrMs=~)yy^Y5%#^>HL$fRR5)KANX2L)Us0^DOv_iI6(AJ8OY&RT! zj5nvqjxARIulwFkclY^UnpAS7M;@8bXXm1OW}5n(5LN`COt^TG0%% zda^Cfr?$A|%ra+2vwe>cm2s!Xx-r%evEj_Nap;XUxd$~Dh8Q1jGQ&xz{+c<2XgA+h zxEp;TGACkqcuPiz?4bF125S(a6oSEE!C zJR?QESNjV8>30fmrtV_jI6|0Bvel}^V5@GoKPOY^4-Vjj2QZY<2dDX*_6eg~wa3=4 zuqg?_Yhw+YxmR#_SnuW>V0vc&$xJnAwGAN!CJ{pq%gSp3vs8}q(|-|;}^1Jj2d+I+g2`^q`uZh1{pViF{s0gYf;3vy4&<;6&SLcbCpa`E(m9oh+HB7CF zP?R6J*W_I?44_y^g^y@ZD#+$U4{bTVA)z8X9~U1TX>{ls{_!`OV=>&QYSS%Ep)lm6 zzb|F4PumUUkMyD8E<=xWyg+NBf=n4cmJLE_*FY7wmRFLocSCL@7=NC#QD;fMYK(d( zCg|tgBK&F|rag2>LQJ{Zl1fTNXOd|OY$V=l?nC`V$W7Do!XB_pVZvb_AlhY(%d*a7 z@*~Q?zdELi=u5lV(OHiEV&81foh*lF5ehZa?!j~_?oq&CqT8Rs4lY^8aRWK0F8gGO z4oP_qx|EgDE`c5tA3>BAdk3>>RFw&};rc1WH4l?avF5e==JicY1Vqkn+SSYEJ)seDP6q0uN+g*=Eq;~j!yUci1Y1zw zq83d@Q)UWBh=5!);fo15q1v>F{SG=_&0D6^Axd-134no=(Nd?Gs?y7`881)+)_@Y; z*YyOZmDj&&Eml6!GJ5vfXzY0=b92Tix7S*coMz${+ljO1_}v>|;i!291ws~Qc zsYmb#>s9(8BmR=8JlDvDfFJ;5VnW|Bl2~X!_2_0a9sbtf?O*Xaatln;sr5$*REvue zc8uYpQiwfgCCwwyJnbd^I-t%~eyDV)kHrggP?3Wruf9HuiW4+6wWgeSnz763*dMF#ozOFO_gx)~HeXY2wPIa2vVz{D+HI`^(Muy^_3f<8w=Cf(oBX zBM$d_|3*ykWgV0n*{?(#&0UH0f^GWouImNYB2CqeuwR7d)9~gBDM{?YvUfEEh4Rh+EVEOP@)3F3yOIX)tCEvan&$QyaF=64DP6EC0IiW(qonQKhh5pjDv$ruGT zt_NCAuK5c_L3Sc!OZLvAE9JYjc=g<^i|igwU%qqYdv))AyEy5Gvc29SzJ$DqZ+1d)UZVBLC5*Ex&>zh`Quk(eVUe{%ZSpND5104glgsOlbHm2A^cW_t}N zI~n?|Ycc%C?fbGkvTwxt5#Jon&R%LT_*15MJDHxc|5tK(AX{fUS66m+uvZ=B{+pdt zDaTJea)1tlv|$VxmCp}YI|ruhA9*}YFuYr3C+Jrf%`jsvjLsM(Ysy`U#0=94Up~Rx z>)TC|^~bP$89C~7Cg7OY3lWtsQS)pUlCwTV4_$}~@{2s)vz|ee2%C2x4IfiszSBxw zfpD#LacdWhv0Wg%t$gc;CgPRlym}(@`jTXU#mmjlXw*OheI|f`X4aND&poRgT@HS!DK0YjOgIc5G_*3K#{cg@PLX1 zKJ|ZRZ`q8AL<#;divbpm)2rGTRWpfSl!hbPv?-y(lbfhf+7z;TP+{JvWqd6RF#PG1 zdQX;6bcf#V^WL&j!Y%ZGBzC&_uVJJy@k!NXpD?a+uV*k3LXm0hh%UTY0+TTS zpr|$+#6dFw&;i51Qy4gzbQ;0fs(fAkKrSK+pUz6x!$oTXz@p&$5`Licb<)IA0r3dxmQWv^m*-#XI#Cz>yRvkAD`rfDc7prMW$Wj^llyQ8= z0O2`DfSW}+Y7Qc4hW$r;>Cqq0;3BHe)|kR9%c(?UquXiMX3KsTGm(QOYgIOL!x>6z z`2gjU#?M*s?~nP~g&SA_1(Z9OG&R?8;-i;L>}df?4Se1rmoPS7dWu_nZ55WkDPvh0>8=H(G|IYr`ed8DoYlCjzV$?b8(XFjb3c@UYc+O6tc!m9 z&}(ny`%)Y5AOox3d;=(#SeMppQ5{!3*CVx*xAT#x@nc(0BbR&^KK4x&(aJZABFiZ( zAPU`%Hq;zkMg^Y-Wj_~dU$OU(|0Gz_AJpO4lyghf6Ot@6(;Zw3q7reYU)tQYFVd!4 z_|@R+|AQ#lB2l}rmkL@IpEZs|e3X}gh^1C&y0kJ(i@l-ikW)e#uL13-E^sLqY{M2j zK@aHSnb7&Hu(4j*Q+YUUBmlP?dyb@sv!P%1BisQZJTijru`Nxyy;{5Ot z(~6k5!QpjkJj${gYW;20+zE&77GX3BbHrcJ72O@glWehZSSt7jrv?wBwz`9Jn^U{< zJiZq!L_BJG$*&WD4mja|OV;r(3?7_8?imZG`MORoQ3FJ0DJ|1;X5wm01V%>Ol#9N7<)%>NQ-3_7KA?xP>NTM-OV{iy6U6@UGI?|o-mu}!BAyn*JEk*g>^zx2v zW%kC%np`=92we>ZOVs<%ub{_(j=%s3XY6({LZHVNCWKc`R)2%vlA`OBe1zFFKF1bQMM;OGN*WV+1LRW~9H}2qH!U4e zgwVVDTul-udupJ_iBd&(2Ui8tJ`OsvJE~Q>S|Nx+()Z5gmJ2H0BJ#*4ChgCF3p0&N zpGl>NO;X!&rWem&n#iiZ#}-3Y$N+2);{d5v zcyNR44>4Hah+BGJp-vPQ3J4243mzJsLL7weQhz9&VdVZQ?NP}X;f-pKcVS@Y84MrM z+=c*}(=R0m0>%diLvz3uDi~Fw08G0lx2Cp0x(+lS|LdgaXUWT0&1yjTZD+t&gDyYm zkAVpXb~SkRrn!ocdFP(i3niXOqYMh@h9JVn+yFyI;0wiRP>#oZ8GUJ)VN7cq{OAxt zk(t;BVGnrct1Vp~ z7nUn<5qo5`LpXF)ya1pIP2jy^Jc+%6p4#o*%{WVqfBG2c({Ma5UlA}AhZS?YX4V)h zb{SP=R@EDl_1P?PCQX!y`XCC^eRgt8;rbZL7#&XrxPu$4C~EoTZ77UqSx)kf1z>Xf zW{n<3CY~u`5oQq;#IKp1ZZnq&i4?p#K{oD$PP?rqR+0yMS3L$tO}OpQ{pJkXFS|0y485L+;!hS zfDQWB(sTCVk#GndS;2YnNRHYcaO!=EsOWTJ5(rG53-lH_IM@{JO&v=rcoD1m5x$`ByX%l{+%I}q{|1w1>Ji9LS?c||mm0G^{s zX_*LXvR|+hOtg7--d!2k>uIF_2%ZIy^;|cSfyLaA6$1bL#wimU5x0W-SA#rC#8O?$ z@@`Gdfa7pYGlLM$raHe6R}>j19AE&5tUto_1*=>b3lU@$ITa0wZydd-@+9J*vl@3d zcnM3lz?2`|+THC@U`$^I$x_U!8{XA;8NpOTuAy(X9xI{5R*~^14AumvAmB+;I_AGO zEV+-(O5psvt4>DSPi{_zfF4QaiW#=^YNr|U6k=kY^A zuE7b=pRJb@4HOA^0R#*!YcucAX6utDQ>TK_xpY6e#fdx+lRf%ERZ+T*P9D<*TPXUF zrNN1qk znefPtV$QF4It=QV;wX2380g&fGcr~j;kh1QPX4nL^z ze{h(LZGj-GM{p@*5C}l_!dlS(K0@sBhpWv4>u8#++uu`Vk&uNlSwg=1&wNY-p(d

N$J@zI$Ad%d2{wM9acet7gN|2J* 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 \ No newline at end of file From ff2580601f5c777e74ed8f969cf0c0a2fea041eb Mon Sep 17 00:00:00 2001 From: Alestore Inc <82514000+Alestore@users.noreply.github.com> Date: Sun, 9 Jul 2023 00:52:47 +0200 Subject: [PATCH 12/32] Add Alestore/nfcwarp extension (#628) --- extensions/Alestore/nfcwarp.js | 73 ++++++++++++++++++++++++++++++++++ website/index.ejs | 6 +++ 2 files changed, 79 insertions(+) create mode 100644 extensions/Alestore/nfcwarp.js diff --git a/extensions/Alestore/nfcwarp.js b/extensions/Alestore/nfcwarp.js new file mode 100644 index 0000000000..c731f04095 --- /dev/null +++ b/extensions/Alestore/nfcwarp.js @@ -0,0 +1,73 @@ +(function(Scratch) { + 'use strict'; + + /* globals NDEFReader */ + + const extIcon = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAACXBIWXMAAAsTAAALEwEAmpwYAAACN0lEQVR4nK2WzW7TQBDHDRIVHCr6CYV+PUG5hENvlpKdfyxX6q0SanmVqo+AkKqqPAG8CAVE1RJaKYn6cSiiIO70RBnYydi4ttcJjiPtIbsz/59nPZ4Zz9MfEz1nog8MXDHAhYvoGxPtMDAvvrXaHQZeJ2ysxnsGNiL9HgR4lRK6YOB8AOAPNmZJNJaX76lf2m73XyTZwwM2ZoGBswFgLfa8W6q16bBb9zTEDEgjnWei074wgMTemKeOh9nzHO9EQOIcBHNMdNInqheJ67vOOf/pOZxjkAjU67MMdAtAe4mkusyzKQTx6uooAxN6LY+ZqOMAXSYSq/v/oDBclMRoNCblf7P5iInaOaBrm+IKOiwLskKf2Pen9GoeMHCU8THmvoIOyoMGgdXrD6sBRd+MC2bMwvAg+y0RHcewIJjW1J+OsywMF6uIaF9Egc8Ka3MYzqjwfqWgRAStGGazsFKQvZ6b19XS/eO4Hg4F6hXWaO/IJoDs+/6UZGHSZ8iIZlJZ17EVQs5WVsYZ+FgNqCfGTpjvj8WwkqBDcVpbG2Hgdw6sbRNBbBqNSREvBSLqJIrkd5cNR5EBE7YAl4noawKU1xhZV9e2kNRY4ARlGx/RL/b9u+r4sgDE0hSDYK4QpI3vnUOkpineLARBS1Q0EeWD3tqDDYfzpjhubd2OS0/xOtPvLg/0LAp3N+fwi50BtBo8kdGqP+w8M3IR7aRnu3Xb+2+8M6I3cee0Qwqw7ZoJUutKtKJI/gr8AfOqgU5hKhA4AAAAAElFTkSuQmCC'; + const blocksIcon = 'data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMCIgd2lkdGg9IjE2MDAuMDAwMDAwcHQiIGhlaWdodD0iMTYwMC4wMDAwMDBwdCIgdmlld0JveD0iMCAwIDE2MDAuMDAwMDAwIDE2MDAuMDAwMDAwIiBwcmVzZXJ2ZUFzcGVjdFJhdGlvPSJ4TWlkWU1pZCBtZWV0Ij4KPG1ldGFkYXRhIGZpbGw9IiNmZmZmZmYiPgpDcmVhdGVkIGJ5IHBvdHJhY2UgMS4xNSwgd3JpdHRlbiBieSBQZXRlciBTZWxpbmdlciAyMDAxLTIwMTcKPC9tZXRhZGF0YT4KPGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUoMC4wMDAwMDAsMTYwMC4wMDAwMDApIHNjYWxlKDAuMTAwMDAwLC0wLjEwMDAwMCkiIGZpbGw9IiNmZmZmZmYiIHN0cm9rZT0ibm9uZSI+CjxwYXRoIGQ9Ik0yNjk3IDE1OTg5IGMtNTY1IC01MCAtMTEwOCAtMjY0IC0xNTY3IC02MTkgLTExNCAtODggLTM5MSAtMzYyIC00ODQgLTQ4MCAtMTY0IC0yMDYgLTM0MCAtNTA5IC00MzQgLTc0NSAtODQgLTIxMSAtMTQzIC00MzAgLTE4NCAtNjgwIGwtMjMgLTE0MCAtMyAtNTEwNSBjLTIgLTM3MDkgMCAtNTE0NSA4IC01MjUwIDcwIC05MDUgNTQ5IC0xNzI0IDEzMDQgLTIyMjkgMzU3IC0yMzkgNzc4IC00MDIgMTIwMyAtNDY2IDIwOSAtMzIgNDA0IC0zNiAxNDM4IC0zMyBsMTAzMCAzIC01MCAyOSBjLTQ3MyAyNzIgLTkwMCA5ODAgLTExMzUgMTg4MCAtMTM2IDUyMSAtMjAwIDk1MiAtMjYyIDE3NjYgLTkgMTE2IC0xMyAxNTYzIC0xNSA1NzE5IGwtMyA1NTY0IDU5IC01NCBjMzMgLTMwIDE0NTAgLTE0MzMgMzE1MCAtMzExOSBsMzA5MSAtMzA2NSAwIC05NjAgMCAtOTYwIC0xNjcgMTY2IGMtMjc2IDI3MiAtMzY2MiAzNjM3IC00Mjg4IDQyNjEgbC01ODAgNTc4IC0zIC0zMDI4IGMtMyAtMzA1NiAwIC0zMzg3IDM0IC0zOTU3IDc2IC0xMjg5IDI1NyAtMjI1MSA1NTggLTI5NjggNTggLTEzOCAxOTUgLTQwNCAyNzEgLTUyNyAxNTYgLTI1MSA0MzQgLTU2MCA2NDggLTcxOSAzNTcgLTI2NiA3NzkgLTQ0OSAxMzIwIC01NzEgbDE3NyAtNDEgMjYzMyA0IGMyODk0IDMgMjY2NyAtMiAyOTgzIDYyIDk2MSAxOTQgMTc4NyA4OTMgMjE0OCAxODE2IDg2IDIyMSAxNDAgNDMwIDE4MyA3MDkgMTYgMTA4IDE4IDQxMyAyMSA1MTg1IDIgMzQ1NCAwIDUxMTcgLTggNTIxNyAtMTkgMjc4IC02MSA0OTAgLTE0NCA3NDMgLTM3NCAxMTI2IC0xMzc3IDE5MTQgLTI1NjEgMjAxNSAtNzIgNiAtNTU1IDEwIC0xMjAwIDEwIGwtMTA4MCAwIDU4IC0zMyBjMTAwIC01NiAxNzkgLTExOSAyOTcgLTIzNyA0NjUgLTQ2MyA4MDggLTEyNzMgOTc5IC0yMzEwIDU0IC0zMjkgODkgLTY1NCAxMjMgLTExNDUgOCAtMTI1IDEyIC0xNjI3IDE1IC01NzA0IGw0IC01NTMzIC0zOSAzMyBjLTIyIDE5IC0xMDc0IDEwNjAgLTIzMzggMjMxNCAtMTI2NCAxMjU0IC0yNjY1IDI2NDIgLTMxMTEgMzA4NSBsLTgxMyA4MDUgMCA5NjQgMCA5NjMgMTg1MyAtMTg0MyBjMTAxOCAtMTAxNCAyMTUyIC0yMTQzIDI1MjAgLTI1MDggbDY2NyAtNjY1IDAgMzAyNSBjMCAxNzQ5IC00IDMxNTMgLTEwIDMzMjkgLTU3IDE3OTQgLTI3NCAyOTkyIC02OTUgMzgzOCAtMTUzIDMwOCAtMzExIDUzNiAtNTI1IDc1NiAtMjIxIDIyNyAtNDQxIDM4NiAtNzM1IDUzMSAtMjY2IDEzMSAtNTM2IDIyMyAtODgzIDMwMSBsLTE1NCAzNCAtMjU5NiAtMSBjLTE0MjkgLTEgLTI2MzYgLTUgLTI2ODUgLTEweiIgZmlsbD0iI2ZmZmZmZiIvPgo8L2c+Cjwvc3ZnPg=='; + + class NFCWarp { + getInfo() { + return { + id: 'alestorenfc', + name: 'NFCWarp', + color1: '#FF4646', + color2: '#FF0000', + color3: '#990033', + menuIconURI: extIcon, + blockIconURI: blocksIcon, + blocks: [ + { + blockType: Scratch.BlockType.LABEL, + text: 'Only works in Chrome on Android' + }, + { + opcode: 'supported', + blockType: Scratch.BlockType.BOOLEAN, + text: 'NFC supported?' + }, + { + opcode: 'nfcRead', + blockType: Scratch.BlockType.REPORTER, + text: 'read NFC tag', + disableMonitor: true + } + ] + }; + } + + supported () { + return typeof NDEFReader !== 'undefined'; + } + + nfcRead() { + if (!this.supported()) { + return 'NFC not supported'; + } + return new Promise((resolve, reject) => { + const ndef = new NDEFReader(); + ndef.scan() + .then(() => { + ndef.onreadingerror = event => { + console.log('Reading error', event); + resolve('Tag not supported'); + }; + ndef.onreading = evt => { + const decoder = new TextDecoder(); + const record = evt.message.records[0]; + console.log('Record type: ' + record.recordType); + console.log('Record encoding: ' + record.encoding); + console.log('Record data: ' + decoder.decode(record.data)); + resolve(decoder.decode(record.data)); + }; + }) + .catch(error => { + console.log('Scan error', error); + resolve(`Error: ${error}`); + }); + }); + } + } + + Scratch.extensions.register(new NFCWarp()); +})(Scratch); diff --git a/website/index.ejs b/website/index.ejs index f6dd5b3ab3..013f65559a 100644 --- a/website/index.ejs +++ b/website/index.ejs @@ -710,6 +710,12 @@

Allows you to use webhooks. Created by CubesterYT.

+
+ <%- banner('Alestore/nfcwarp') %> +

NFCWarp

+

Allows reading data from NFC (NDEF) devices. Only works in Chrome on Android. Created by Alestore Games.

+
+
<%- banner('itchio') %>

itch.io

From 13e9166ddee1129a6952a92f20cddaf46147d0c8 Mon Sep 17 00:00:00 2001 From: NexusKitten <127152751+NexusKitten@users.noreply.github.com> Date: Sat, 8 Jul 2023 21:28:37 -0400 Subject: [PATCH 13/32] Add clipboard extension (#667) --- extensions/clipboard.js | 118 ++++++++++++++++++++++++++++++++++++++++ images/README.md | 3 + images/clipboard.svg | 1 + website/index.ejs | 6 ++ 4 files changed, 128 insertions(+) create mode 100644 extensions/clipboard.js create mode 100644 images/clipboard.svg diff --git a/extensions/clipboard.js b/extensions/clipboard.js new file mode 100644 index 0000000000..7064a0194f --- /dev/null +++ b/extensions/clipboard.js @@ -0,0 +1,118 @@ +/*! + * Copyright 2023 tomyo-code + AdamMady + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +(function(Scratch) { + 'use strict'; + + if (!Scratch.extensions.unsandboxed) { + throw new Error('Clipboard must run unsandboxed'); + } + + const extensionicon = "data:image/svg+xml;base64,PHN2ZyB2ZXJzaW9uPSIxLjEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHdpZHRoPSI4MC40NTQ1NCIgaGVpZ2h0PSI4MC40NTQ1NCIgdmlld0JveD0iMCwwLDgwLjQ1NDU0LDgwLjQ1NDU0Ij48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgtMTk5Ljc3MjcyLC0xMzkuNzcyNzIpIj48ZyBkYXRhLXBhcGVyLWRhdGE9InsmcXVvdDtpc1BhaW50aW5nTGF5ZXImcXVvdDs6dHJ1ZX0iIGZpbGwtcnVsZT0ibm9uemVybyIgc3Ryb2tlPSJub25lIiBzdHJva2UtbGluZWNhcD0iYnV0dCIgc3Ryb2tlLWxpbmVqb2luPSJtaXRlciIgc3Ryb2tlLW1pdGVybGltaXQ9IjEwIiBzdHJva2UtZGFzaGFycmF5PSIiIHN0cm9rZS1kYXNob2Zmc2V0PSIwIiBzdHlsZT0ibWl4LWJsZW5kLW1vZGU6IG5vcm1hbCI+PHBhdGggZD0iTTE5OS43NzI3MywxODBjMCwtMjIuMjE2OSAxOC4wMTAzNywtNDAuMjI3MjcgNDAuMjI3MjcsLTQwLjIyNzI3YzIyLjIxNjksMCA0MC4yMjcyNywxOC4wMTAzNyA0MC4yMjcyNyw0MC4yMjcyN2MwLDIyLjIxNjkgLTE4LjAxMDM3LDQwLjIyNzI3IC00MC4yMjcyNyw0MC4yMjcyN2MtMjIuMjE2OSwwIC00MC4yMjcyNywtMTguMDEwMzcgLTQwLjIyNzI3LC00MC4yMjcyN3oiIGZpbGw9IiMwMDgwODAiIHN0cm9rZS13aWR0aD0iMCIvPjxpbWFnZSB4PSI0MzQiIHk9IjMwMCIgdHJhbnNmb3JtPSJzY2FsZSgwLjUsMC41KSIgd2lkdGg9Ijk0IiBoZWlnaHQ9IjExOCIgeGxpbms6aHJlZj0iZGF0YTppbWFnZS9wbmc7YmFzZTY0LGlWQk9SdzBLR2dvQUFBQU5TVWhFVWdBQUFGNEFBQUIyQ0FZQUFBQkJMU1ExQUFBQUFYTlNSMElBcnM0YzZRQUFCckpKUkVGVWVGN3RuVnZJYmtNWXgyZTJuTUlPeVNHbDVCQjJTWExNc1lRTFo5cHNaMEl1aEhKQmlkeTZJaUVrNTFPT0VYZkVqZHk0c0pPemN0Z1hLRGtrNStTdmI3Ny9zMzNmM3U5YTYxbnZtdlhNdk85KzNwdXA5VDd6UERPLythOVpzMmF0bVJWRDVUOEFlN0tJMXpNOWx1bTJUTDlqK2dyVGV4ZlNHT09mTlZjdDFseTRoYkk1ZU9NV0FuQXpROTdLZEN0bEVlUU1XRTNsdjYzTVoycFdyZUlkdktrT1V0ZHlHME5LT3EwNHBJOVAxNFFZNDd2R1ZXa05OMjJsUnF1RGd4OE43V1RIQVBibFB4OHczVHhURVQ2bm4vMm8vSDh6K1Iza3BockZiN0xnQVd6QkpyeUo2UWxNdHh6VXRQOW5mcHFLdTN1U1B3Q1A4dmlsSGZIKzR2OC9NZDJaNllxR2ZPRHhreG4vOVliNGovRzRuSGxEcXkzbGU0SnhuMW5xY0wzaUhUeHN3UVBZbmkwaFYvMjloeloxUS80MzJQSW5OaWp1TXg3ZnB5SC9iengrTVAwa2V3RFg4TGljU1UzZFovby94bmhkUS94ZmVIeTd6UFdYTSs0cHhyODRwUTUrRVRNQWMvRFM5NnpKM05JYnVudVZMWDU2ZytLKzVmRmRHOHFSenNnWTQyRU4rZi9nOGFZNzNPZVkvN3lHL0QvdytJNGpjemhWRk8vZ0Z4VnZEcjVMS2JrRWNCa1ZKeGV4Wlg0QnlCekxMZzBCcFp4SDBjOTc3Q0p1cFAzdFRKdjYrT2VaNzl3R3hiL0c0NmZrcW5DRG4zV2llQWUvcUhoejhITFY3V3JvZjJnZzQrZ3VlMm5RQjZpMFc5b3lBT2pxNHlXN2xFTXVoanQwS0YzeWRmWHhLMm1ZN0VJSVJ6TGRyS09pY29adHJTeEhNbHNZMVRqNFJjVlhCLzVIdHVReFREL3Bram9WM210T0JNRDM5THVUeHY4VU51a0pWWXp4ekQ1NUFUVGRFWXNiK2Y4U0huaVFhV3MramVJZGZIdExqUVkrRFRkampCZjBVWXJXRnNCcHRIMVpveFN0M3dsMklxQzlXSitmQi9ocXpLbzljeldLZC9BOVdpZ24rTWVwa0s1WlExWHhBSnhFdzZ1WW5zRTAxL3g3Vnpua1J1bGhHcVpaMFJqalIxMFpOZjhyN2tlU0c0M2lIYnlHT0cxeWduK1Npa2l6YW4xL0FPUk84SDdtM1oxcExROWg1TDVBWm1mUFlYM2x2cUpYbFIyOEh0ZDhnUWR3Tk92K3BuRWZya2MrMlRMTnBZUVFWbEg1di9aeFdGenhEajQwVGZhcEw2NVQ5ZkVBWkpTd2Z4L0ZWR1I3SnhWL1E1OHkxYUI0QjkvU1lwcmhaQy9GQXppQThkNW4yalc3MTBkUWxyYmZVUEV5Q2xQRkxxWjRCOS81UUdlY1BuN0pVLzk3VkJLcDEwaUdtWHYwR2RlWFZMeThidUhnQy9YeHZlYTlLeFMrUEVGN2lJcVhKMTZ0UlMycGVMbTRPbmhMeFZlb1hOTWlGVk84YVMwckRPYmdDeldLZzNmd2hRZ1VDdXVLbjNmd0FPVFo2ZVhHZGIyTDQrdG5qZVBXTVk1MzhNdmJ3YXlyQVpEZWV3OGhwUGUrRFgvcHJlTVlZM29MdVphZmd5L1VFcGJnWlUyUjlQVldWYjZEaW4vRUtxQW1qb1BYVUJyQnhnejhDR1dmYVpjT3ZsRHo1UVF2NnpNdktsU1htUXJyNEFzMWw0TjM4SVVJRkFwcnBuZ0FCN0tPRTFkY0Y2cC9qckN5dzlOTHZGLzRYZVBVd1dzb3RkdFVELzVGbHYvczRYV3R5b01zUTVYZFF0WnFTcWRkcjZ0NWhhOTFPQW5Bd1M5cEVVdndhZVYyQ01GNlBsNGp3Q0UyZnkrOWRtblhTRG40SWNnWDgxWVBYdmI0emIyejBYQjB3enpJeXZTMDRqekdxRnFwYnFsNEIxK2lqeDhtcXZuTGJhYjQrVU0zckVZT2ZoaS9xWE03K0tuUkRjdG9CbjdKUnFHeVUrdXdrbytYTzYzd0dQdExDZzUrNHdhY08vQ3l3K21WNDRrMWkrY1BxZmhEc25ocmNHS3BlQWRmWWh3UElNMVhoeERPR2xOSkdYeW5mUzFqakx0bDhOWG93bEx4RHI2UTRnOW4zT1BHVkZJRzMxOVE4UzlrOEZXRjRoMThDY1dQcVo1WjlHM1d4ODhpbkRITDdPREhwTnZpMjhIUEFmaFJOL3dzeEdlMHNEa1Y3K0I3TkpNWmVBQlhzMXhWclVWU3NQcUs0L3J6RmJacUV3ZmZqV3Jtd1pkYTlkZU50dDBpdmFJWFk1UXZIUXoxbC9KYkt0N0JqM1RuMm5weEJYQXQ0MTZSUlRKMlRyNms0clBPcWxvcTNzR1hVTHlkUUdjamtwbmlad09IWFNrZHZCM3JaWkVjdklNdlJLQlFXRmY4dklNSGNCRHJlRVNodWtyWVR6a3VmNnRrT2N3VTcrQ1hON01sK0ZvV24zMU14Y3NXdTBXRTcrQ0xZTGVkSkx1dmtybWFkNmo0NHdzeE41K2RkUEFsNW1vQXlGZmhaUkZhS2NISi9IcXY3emJsTHF4bEgrL2dTeWcrdDJKbTNaK1o0bWNkVk83eU8vamNSSlgrSEx3U1ZHNHpCNSticU5LZmcxZUN5bTJXRTN6YW56M0d1Q1ozSWVmUlg4NDl5Ung4RDRYa0JKLzJhd2toSEVybGY5MmpISnVNS1lEVnJHeDZEeW1FMFBwVlQ4MmVaQTVlSVo4eHdFdFkyU3BLdm9HbktFNVZKbkdrMG9qZmJlaC9oU2FPUnZFT3ZwM2sxT0JGd1RMWnBXa3d0NW1ld0xwMHJRVGc0S2VIT0UzTzllRFRON2xEQ0JkTzQ4WHpxQW5JenEzcDYwRUxpbmZ3YW5hREREY0N2NUx1MGpQTEVNS3FRZTQ5ODRZRUJMaDhDVGw5UFdoQjhRNStYTEZNQlA4ZjVqR04yQ3N0cTkwQUFBQUFTVVZPUks1Q1lJST0iIGZpbGw9Im5vbmUiIHN0cm9rZS13aWR0aD0iMC41Ii8+PC9nPjwvZz48L3N2Zz4="; + + let lastPastedText = ''; + + window.addEventListener('copy', (event) => { + Scratch.vm.runtime.startHats('clipboard_whenCopied') ; + }); + window.addEventListener('paste', (event) => { + Scratch.vm.runtime.startHats('clipboard_whenPasted'); + const clipboardData = event.clipboardData || window.clipboardData; + const pastedText = clipboardData.getData('Text'); + lastPastedText = pastedText; + }); + + class Clipboard { + getInfo() { + return { + id: 'clipboard', + name: 'Clipboard', + blockIconURI: extensionicon, + color1: '#008080', + color2: '#006666', + blocks: [ + { + opcode: 'whenCopied', + blockType: Scratch.BlockType.HAT, + text: 'when something is copied', + isEdgeActivated: false + }, + { + opcode: 'whenPasted', + blockType: Scratch.BlockType.HAT, + text: 'when something is pasted', + isEdgeActivated: false + }, + '---', + { + opcode: 'setClipboard', + blockType: Scratch.BlockType.COMMAND, + text: 'copy to clipboard: [TEXT]', + arguments: { + TEXT: { + type: Scratch.ArgumentType.STRING + } + } + }, + { + opcode: 'resetClipboard', + blockType: Scratch.BlockType.COMMAND, + text: 'reset clipboard' + }, + '---', + { + opcode: 'clipboard', + blockType: Scratch.BlockType.REPORTER, + text: 'clipboard', + disableMonitor: true + }, + { + opcode: 'getLastPastedText', + blockType: Scratch.BlockType.REPORTER, + text: 'last pasted text', + disableMonitor: true + } + ], + }; + } + + setClipboard(args) { + navigator.clipboard.writeText(args.TEXT); + } + + resetClipboard() { + navigator.clipboard.writeText(''); + } + + clipboard() { + if (navigator.clipboard && navigator.clipboard.readText) { + return Scratch.canReadClipboard().then(allowed => { + if (allowed) { + return navigator.clipboard.readText(); + } + return ''; + }); + } + return ''; + } + + getLastPastedText() { + return lastPastedText; + } + } + + Scratch.extensions.register(new Clipboard()); +})(Scratch); diff --git a/images/README.md b/images/README.md index 9b629d4eb8..76bd6f0da2 100644 --- a/images/README.md +++ b/images/README.md @@ -233,3 +233,6 @@ All images in this folder are licensed under the [GNU General Public License ver ## Lily/LooksPlus.svg - Created by [@LilyMakesThings](https://github.com/LilyMakesThings) in https://github.com/TurboWarp/extensions/pull/656 + +## clipboard.svg + - Created by [@AdamMady](https://github.com/AdamMady/) diff --git a/images/clipboard.svg b/images/clipboard.svg new file mode 100644 index 0000000000..f02be5a0ee --- /dev/null +++ b/images/clipboard.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/index.ejs b/website/index.ejs index 013f65559a..fd3812c909 100644 --- a/website/index.ejs +++ b/website/index.ejs @@ -476,6 +476,12 @@

Clipping outside of a specified rectangular area and additive color blending. Created by Vadik1.

+
+ <%- banner('clipboard') %> +

Clipboard

+

Read and write from the system clipboard.

+
+
<%- banner('penplus') %>

Pen Plus

From e19128c53e682f6768410b9b182f0a39a2b2ea7a Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Sat, 8 Jul 2023 21:11:10 -0500 Subject: [PATCH 14/32] Generate a sitemap (#712) --- development/builder.js | 37 ++++++++++++++++++++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/development/builder.js b/development/builder.js index 9a2f025994..38330bafb5 100644 --- a/development/builder.js +++ b/development/builder.js @@ -105,6 +105,39 @@ class SVGFile extends ImageFile { } } +class SitemapFile extends DiskFile { + constructor (build) { + super(null); + this.getDiskPath = null; + this.build = build; + } + + getType () { + return '.xml'; + } + + read () { + let xml = ''; + xml += '\n'; + xml += '\n'; + + xml += Object.keys(this.build.files) + .filter(file => file.endsWith('.html')) + .map(file => file.replace('index.html', '').replace('.html', '')) + .sort((a, b) => { + if (a.length < b.length) return -1; + if (a.length > b.length) return 1; + return a - b; + }) + .map(path => `https://extensions.turbowarp.org${path}`) + .map(absoluteURL => `${absoluteURL}`) + .join('\n'); + + xml += '\n'; + return xml; + } +} + const IMAGE_FORMATS = new Map(); IMAGE_FORMATS.set('.png', ImageFile); IMAGE_FORMATS.set('.jpg', ImageFile); @@ -116,7 +149,7 @@ class Build { } getFile (path) { - return this.files[path] || this.files[`${path}index.html`] || null; + return this.files[path] || this.files[`${path}.html`] || this.files[`${path}index.html`] || null; } export (root) { @@ -192,6 +225,8 @@ class Builder { build.files[oldPath] = build.files[newPath]; } + build.files['/sitemap.xml'] = new SitemapFile(build); + const mostRecentExtensions = extensionFiles .sort((a, b) => b.getLastModified() - a.getLastModified()) .slice(0, 5) From cd85f6332c65a732e937fb3b9351a9c50cc816ba Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Sat, 8 Jul 2023 21:19:15 -0500 Subject: [PATCH 15/32] Don't output sitemap in desktop builds (#713) --- development/builder.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/development/builder.js b/development/builder.js index 38330bafb5..3d755fd631 100644 --- a/development/builder.js +++ b/development/builder.js @@ -225,7 +225,9 @@ class Builder { build.files[oldPath] = build.files[newPath]; } - build.files['/sitemap.xml'] = new SitemapFile(build); + if (this.mode !== 'desktop') { + build.files['/sitemap.xml'] = new SitemapFile(build); + } const mostRecentExtensions = extensionFiles .sort((a, b) => b.getLastModified() - a.getLastModified()) From c0b8f2db73ab395164a2872cb5d42694cbc81937 Mon Sep 17 00:00:00 2001 From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com> Date: Mon, 10 Jul 2023 03:24:14 +0100 Subject: [PATCH 16/32] Lily/TempVariables2: remove console.log (#717) --- extensions/Lily/TempVariables2.js | 1 - 1 file changed, 1 deletion(-) diff --git a/extensions/Lily/TempVariables2.js b/extensions/Lily/TempVariables2.js index ad131fbc18..13912281f8 100644 --- a/extensions/Lily/TempVariables2.js +++ b/extensions/Lily/TempVariables2.js @@ -14,7 +14,6 @@ }); function resetRuntimeVariables() { - console.log('runtime variables cleared'); runtimeVariables = Object.create(null); } From 61353ff9e5e9c53a3e984147f415e353bfdcb8c1 Mon Sep 17 00:00:00 2001 From: godslayerakp <74981904+RedMan13@users.noreply.github.com> Date: Mon, 10 Jul 2023 21:05:40 -0700 Subject: [PATCH 17/32] godslayerakp/http: patched value handling order (#724) --- extensions/godslayerakp/http.js | 44 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/extensions/godslayerakp/http.js b/extensions/godslayerakp/http.js index 6d7e6c5b58..46321fa848 100644 --- a/extensions/godslayerakp/http.js +++ b/extensions/godslayerakp/http.js @@ -590,34 +590,34 @@ // eslint-disable-next-line require-await async sendRequest(args) { const url = Cast.toString(args.url); + const options = this.request.options; this.clearAll(); this.response.url = url; - Scratch.fetch(url, this.request.options) - .then(res => { - // @ts-ignore - this.response.status = res.status; - this.response.headers = res.headers; - this.response.statusText = res.statusText; - if (res.ok) { - this.request.success = true; - this.request.events.activate('reqSuccess'); - } else { - this.request.fail = true; - this.request.events.activate('reqFail'); - } - this.request.end = true; - return res.text(); - }) - .then(body => this.response.text = body) - .catch(err => { - this.response.error = String(err); - console.warn('request failed with error', err); + try { + const res = await Scratch.fetch(url, options); + // @ts-ignore + this.response.status = res.status; + this.response.headers = res.headers; + this.response.statusText = res.statusText; + if (res.ok) { + this.request.success = true; + this.request.events.activate('reqSuccess'); + } else { this.request.fail = true; - this.request.end = true; this.request.events.activate('reqFail'); - }); + } + this.request.end = true; + const body = await res.text(); + this.response.text = body; + } catch (err) { + this.response.error = String(err); + console.warn('request failed with error', err); + this.request.fail = true; + this.request.end = true; + this.request.events.activate('reqFail'); + } } /* extra stuff for when its missing something */ From f5b10848dd344a9d2d23c8363c88b266bc0aec53 Mon Sep 17 00:00:00 2001 From: TheShovel <68913917+TheShovel@users.noreply.github.com> Date: Thu, 13 Jul 2023 02:40:00 +0300 Subject: [PATCH 18/32] TheShovel/CanvasEffects: fix block name (#731) X and Y are usually used for position, not size. --- extensions/TheShovel/CanvasEffects.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/TheShovel/CanvasEffects.js b/extensions/TheShovel/CanvasEffects.js index 3018114acf..4d53b09cc2 100644 --- a/extensions/TheShovel/CanvasEffects.js +++ b/extensions/TheShovel/CanvasEffects.js @@ -69,7 +69,7 @@ { opcode: 'renderscale', blockType: Scratch.BlockType.COMMAND, - text: 'set canvas render size to x:[X] y:[Y]', + text: 'set canvas render size to width:[X] height:[Y]', arguments: { X: { type: Scratch.ArgumentType.NUMBER, From 0d8f1291f6edf0b4605488e7332408f3885109c0 Mon Sep 17 00:00:00 2001 From: NexusKitten <127152751+NexusKitten@users.noreply.github.com> Date: Sat, 15 Jul 2023 20:51:21 -0400 Subject: [PATCH 19/32] Update 2 images (#664) --- images/README.md | 7 +++++-- images/cs2627883/numericalencoding.svg | 2 +- images/mdwalters/notifications.png | Bin 93203 -> 0 bytes images/mdwalters/notifications.svg | 1 + 4 files changed, 7 insertions(+), 3 deletions(-) delete mode 100644 images/mdwalters/notifications.png create mode 100644 images/mdwalters/notifications.svg diff --git a/images/README.md b/images/README.md index 76bd6f0da2..0931e6dec6 100644 --- a/images/README.md +++ b/images/README.md @@ -144,7 +144,9 @@ All images in this folder are licensed under the [GNU General Public License ver - Created by @Pizzalover4783 in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1526886264. ## cs2627883/numericalencoding.svg - - Created by @Pizzalover4783 in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1534022176. + - Created by [@NexusKitten](https://scratch.mit.edu/users/namelesscat/). + - Silkscreen font used under [Open Font License](https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL) + - Dango based on dango from [Twemoji](https://twemoji.twitter.com/) under [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/). ## NOname-awa/graphics2d.svg - Created by @Pizzalover4783 in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1550426448. @@ -203,7 +205,8 @@ All images in this folder are licensed under the [GNU General Public License ver - Based on image created by [@Flappy25](https://github.com/Flappy25) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1575100933 ## mdwalters/notifications.svg - - Created by [@Juenjos](https://github.com/Juenjos) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1573040329 + - Created by [@NexusKitten](https://scratch.mit.edu/users/namelesscat/). + - Modified by [JeremyGamer13](https://scratch.mit.edu/users/JeremyGamer13/). ## Lily/MoreTimers.svg - Created by [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/) in https://github.com/TurboWarp/extensions/pull/656. diff --git a/images/cs2627883/numericalencoding.svg b/images/cs2627883/numericalencoding.svg index 0c88234196..8584491b8f 100644 --- a/images/cs2627883/numericalencoding.svg +++ b/images/cs2627883/numericalencoding.svg @@ -1 +1 @@ - \ No newline at end of file + diff --git a/images/mdwalters/notifications.png b/images/mdwalters/notifications.png deleted file mode 100644 index 0a84773c85099bd11463ff56268a93c591146436..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 93203 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

B0!z(Xe&ArEcc(pa4kvf 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 From 916ee3caffecb9d7b38b71aaaf0148d14ae5b12e Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Sun, 16 Jul 2023 09:25:36 -0500 Subject: [PATCH 20/32] Update images 12 (#748) * Update mdwalters/notifications image * Add godslayerakp/http image * Add Alestore/nfcwarp image * Update encoding image --- images/Alestore/nfcwarp.svg | 2 + images/README.md | 12 ++-- images/encoding.svg | 112 ++++++++++++++++++++++++++++- images/godslayerakp/http.svg | 2 + images/mdwalters/notifications.svg | 55 +++++++++++++- 5 files changed, 177 insertions(+), 6 deletions(-) create mode 100644 images/Alestore/nfcwarp.svg create mode 100644 images/godslayerakp/http.svg diff --git a/images/Alestore/nfcwarp.svg b/images/Alestore/nfcwarp.svg new file mode 100644 index 0000000000..01ba378a20 --- /dev/null +++ b/images/Alestore/nfcwarp.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/images/README.md b/images/README.md index 0931e6dec6..cbe7d3e4b9 100644 --- a/images/README.md +++ b/images/README.md @@ -64,8 +64,7 @@ All images in this folder are licensed under the [GNU General Public License ver - Created by [@softedco](https://scratch.mit.edu/users/softed/) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1369138404. ## encoding.svg - - Created by @SIPC in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1396819269. - - Font is Noto Sans. + - Created by [@BlueDome77](https://github.com/BlueDome77) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1632625905 ## true-fantom/network.svg - Created by [@True-Fantom](https://scratch.mit.edu/users/TrueFantom/) in https://github.com/TurboWarp/extensions/pull/122#issue-1524383752. @@ -205,8 +204,7 @@ All images in this folder are licensed under the [GNU General Public License ver - Based on image created by [@Flappy25](https://github.com/Flappy25) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1575100933 ## mdwalters/notifications.svg - - Created by [@NexusKitten](https://scratch.mit.edu/users/namelesscat/). - - Modified by [JeremyGamer13](https://scratch.mit.edu/users/JeremyGamer13/). + - Created by [@BlueDome77](https://github.com/BlueDome77) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1637077987 ## Lily/MoreTimers.svg - Created by [@LilyMakesThings](https://scratch.mit.edu/users/LilyMakesThings/) in https://github.com/TurboWarp/extensions/pull/656. @@ -239,3 +237,9 @@ All images in this folder are licensed under the [GNU General Public License ver ## clipboard.svg - Created by [@AdamMady](https://github.com/AdamMady/) + +## godslayerakp/http.svg + - Created by [@HamsterCreativity](https://github.com/HamsterCreativity) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1636912111 + +## Alestore/nfcwarp.svg + - Created by [@HamsterCreativity](https://github.com/HamsterCreativity) in https://github.com/TurboWarp/extensions/issues/90#issuecomment-1636726352 diff --git a/images/encoding.svg b/images/encoding.svg index cd6453f81c..ce113c7db9 100644 --- a/images/encoding.svg +++ b/images/encoding.svg @@ -1 +1,111 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/images/godslayerakp/http.svg b/images/godslayerakp/http.svg new file mode 100644 index 0000000000..61444571ed --- /dev/null +++ b/images/godslayerakp/http.svg @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/images/mdwalters/notifications.svg b/images/mdwalters/notifications.svg index 8f32153ef3..20afd6a097 100644 --- a/images/mdwalters/notifications.svg +++ b/images/mdwalters/notifications.svg @@ -1 +1,54 @@ - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From 179255c407ac985fd96782103c113b40e433ddb0 Mon Sep 17 00:00:00 2001 From: CST1229 <68464103+CST1229@users.noreply.github.com> Date: Sun, 16 Jul 2023 16:43:41 +0200 Subject: [PATCH 21/32] Add CST1229/zip extension (#705) --- extensions/CST1229/zip.js | 884 ++++++++++++++++++++ images/CST1229/zip.svg | 1 + website/CST1229/images/zip-close.svg | 14 + website/CST1229/images/zip-create-dir.svg | 14 + website/CST1229/images/zip-create-empty.svg | 14 + website/CST1229/images/zip-current-dir.svg | 14 + website/CST1229/images/zip-delete.svg | 14 + website/CST1229/images/zip-dir-contents.svg | 14 + website/CST1229/images/zip-exists.svg | 14 + website/CST1229/images/zip-file.svg | 14 + website/CST1229/images/zip-get-comment.svg | 14 + website/CST1229/images/zip-get-info.svg | 14 + website/CST1229/images/zip-goto-dir.svg | 14 + website/CST1229/images/zip-is-open.svg | 14 + website/CST1229/images/zip-open.svg | 14 + website/CST1229/images/zip-output.svg | 14 + website/CST1229/images/zip-path.svg | 14 + website/CST1229/images/zip-rename.svg | 14 + website/CST1229/images/zip-set-comment.svg | 14 + website/CST1229/images/zip-set-meta.svg | 14 + website/CST1229/images/zip-write.svg | 14 + website/CST1229/zip.html | 551 ++++++++++++ website/hello.zip | Bin 0 -> 3055 bytes website/index.ejs | 6 + 24 files changed, 1708 insertions(+) create mode 100644 extensions/CST1229/zip.js create mode 100644 images/CST1229/zip.svg create mode 100644 website/CST1229/images/zip-close.svg create mode 100644 website/CST1229/images/zip-create-dir.svg create mode 100644 website/CST1229/images/zip-create-empty.svg create mode 100644 website/CST1229/images/zip-current-dir.svg create mode 100644 website/CST1229/images/zip-delete.svg create mode 100644 website/CST1229/images/zip-dir-contents.svg create mode 100644 website/CST1229/images/zip-exists.svg create mode 100644 website/CST1229/images/zip-file.svg create mode 100644 website/CST1229/images/zip-get-comment.svg create mode 100644 website/CST1229/images/zip-get-info.svg create mode 100644 website/CST1229/images/zip-goto-dir.svg create mode 100644 website/CST1229/images/zip-is-open.svg create mode 100644 website/CST1229/images/zip-open.svg create mode 100644 website/CST1229/images/zip-output.svg create mode 100644 website/CST1229/images/zip-path.svg create mode 100644 website/CST1229/images/zip-rename.svg create mode 100644 website/CST1229/images/zip-set-comment.svg create mode 100644 website/CST1229/images/zip-set-meta.svg create mode 100644 website/CST1229/images/zip-write.svg create mode 100644 website/CST1229/zip.html create mode 100644 website/hello.zip diff --git a/extensions/CST1229/zip.js b/extensions/CST1229/zip.js new file mode 100644 index 0000000000..511931a0ee --- /dev/null +++ b/extensions/CST1229/zip.js @@ -0,0 +1,884 @@ +(function (Scratch) { + "use strict"; + + // Tricking JSZip into thinking it's running as a CommonJS module + // is probably better than letting it overwrite globals + const exports = {}; + const module = { exports: null }; + + // jszip source code: + // https://github.com/Stuk/jszip + // using it under the MIT license + + // minified code from: https://cdn.jsdelivr.net/npm/jszip@3/dist/jszip.min.js + // in a function for code folding + function jsZip() { + /*! + + JSZip v3.10.1 - A JavaScript class for generating and reading zip files + + + (c) 2009-2016 Stuart Knightley + Dual licenced under the MIT license or GPLv3. See https://raw.github.com/Stuk/jszip/main/LICENSE.markdown. + + JSZip uses the library pako released under the MIT license : + https://github.com/nodeca/pako/blob/main/LICENSE + */ + // eslint-disable-next-line + // @ts-ignore + !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h)}return o[r].exports}for(var l="function"==typeof require&&require,e=0;e>2,s=(3&t)<<4|r>>4,a=1>6:64,o=2>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l}},{"./support":30,"./utils":32}],2:[function(e,t,r){"use strict";var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){"use strict";var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){"use strict";var n=e("./utils");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t.charCodeAt(a))];return-1^e}(0|t,e,e.length,0):0}},{"./utils":32}],5:[function(e,t,r){"use strict";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){"use strict";var n=null;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){"use strict";var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function h(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={}}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1)},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},h.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta})}},r.compressWorker=function(e){return new h("Deflate",e)},r.uncompressWorker=function(){return new h("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){"use strict";function A(e,t){var r,n="";for(r=0;r>>=8;return n}function n(e,t,r,n,i,s){var a,o,h=e.file,u=e.compression,l=s!==O.utf8encode,f=I.transformTo("string",s(h.name)),c=I.transformTo("string",O.utf8encode(h.name)),d=h.comment,p=I.transformTo("string",s(d)),m=I.transformTo("string",O.utf8encode(d)),_=c.length!==h.name.length,g=m.length!==d.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),"UNIX"===i?(C=798,z|=function(e,t){var r=e;return e||(r=t?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(e){return 63&(e||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+c,b+="up"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+="uc"+A(y.length,2)+y);var E="";return E+="\n\0",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+"\0\0\0\0"+A(z,4)+A(n,4)+f+b+p}}var I=e("../utils"),i=e("../stream/GenericWorker"),O=e("../utf8"),B=e("../crc32"),R=e("../signature");function s(e,t,r,n){i.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}I.inherits(s,i),s.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,i.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}))},s.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=n(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},s.prototype.closedSource=function(e){this.accumulate=!1;var t=this.streamFiles&&!e.file.dir,r=n(e,t,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),t)this.push({data:function(e){return R.DATA_DESCRIPTOR+A(e.crc32,4)+A(e.compressedSize,4)+A(e.uncompressedSize,4)}(e),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},s.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i},{"../utils":32}],19:[function(e,t,r){"use strict";var n=e("./Uint8ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){"use strict";var n=e("./DataReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){"use strict";var n=e("./ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){"use strict";var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),h=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new h(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){"use strict";r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b"},{}],24:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta})},t.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e)},t.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0)}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length}i.prototype.processChunk.call(this,e)},t.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat()},function(e){t.error(e)})}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t)}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){"use strict";function n(e){this.name=e||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}n.prototype={push:function(e){this.emit("data",e)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(e){this.emit("error",e)}return!0},error:function(e){return!this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(e,t){if(this._listeners[e])for(var r=0;r "+e:e}},t.exports=n},{}],29:[function(e,t,r){"use strict";var h=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),u=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter")}catch(e){}function l(e,o){return new a.Promise(function(t,r){var n=[],i=e._internalType,s=e._outputType,a=e._mimeType;e.on("data",function(e,t){n.push(e),o&&o(t)}).on("error",function(e){n=[],r(e)}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return h.newBlob(h.transformTo("arraybuffer",t),r);case"base64":return u.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return h.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t>10&1023,a[r++]=56320|1023&n)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(h.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(h.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length)}else t=this.leftOver.concat(t);this.leftOver=null}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}(t),i=t;n!==t.length&&(h.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(l,n),l.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta})},s.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,a){"use strict";var o=e("./support"),h=e("./base64"),r=e("./nodejsUtils"),u=e("./external");function n(e){return e}function l(e,t){for(var r=0;r>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var e=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4))}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return l(e,e.length)},r.binstring2buf=function(e){for(var t=new h.Buf8(e.length),r=0,n=t.length;r>10&1023,o[n++]=56320|1023&i)}return l(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}},{"./common":41}],43:[function(e,t,r){"use strict";t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}},{}],46:[function(e,t,r){"use strict";var h,c=e("../utils/common"),u=e("./trees"),d=e("./adler32"),p=e("./crc32"),n=e("./messages"),l=0,f=4,m=0,_=-2,g=-1,b=4,i=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(e,t){return e.msg=n[t],t}function T(e){return(e<<1)-(4e.avail_out&&(r=e.avail_out),0!==r&&(c.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function N(e,t){u._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,F(e.strm)}function U(e,t){e.pending_buf[e.pending++]=t}function P(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function L(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,h=e.strstart>e.w_size-z?e.strstart-(e.w_size-z):0,u=e.window,l=e.w_mask,f=e.prev,c=e.strstart+S,d=u[s+a-1],p=u[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(u[(r=t)+a]===p&&u[r+a-1]===d&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&sh&&0!=--i);return a<=e.lookahead?a:e.lookahead}function j(e){var t,r,n,i,s,a,o,h,u,l,f=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=f+(f-z)){for(c.arraySet(e.window,e.window,f,f,0),e.match_start-=f,e.strstart-=f,e.block_start-=f,t=r=e.hash_size;n=e.head[--t],e.head[t]=f<=n?n-f:0,--r;);for(t=r=f;n=e.prev[--t],e.prev[t]=f<=n?n-f:0,--r;);i+=f}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,h=e.strstart+e.lookahead,u=i,l=void 0,l=a.avail_in,u=x)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x)if(n=u._tr_tally(e,e.strstart-e.match_start,e.match_length-x),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=x){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-x,n=u._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-x),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(j(e),0===e.lookahead&&t===l)return A;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,N(e,!1),0===e.strm.avail_out))return A;if(e.strstart-e.block_start>=e.w_size-z&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):(e.strstart>e.block_start&&(N(e,!1),e.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(e,t){return Y(e,t,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?_:(e.state.gzhead=t,m):_},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5>8&255),U(n,n.gzhead.time>>16&255),U(n,n.gzhead.time>>24&255),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(U(n,255&n.gzhead.extra.length),U(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(U(n,0),U(n,0),U(n,0),U(n,0),U(n,0),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,3),n.status=E);else{var a=v+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=E,P(n,a),0!==n.strstart&&(P(n,e.adler>>>16),P(n,65535&e.adler)),e.adler=1}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending!==n.pending_buf_size));)U(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&F(e),n.pending+2<=n.pending_buf_size&&(U(n,255&e.adler),U(n,e.adler>>8&255),e.adler=0,n.status=E)):n.status=E),0!==n.pending){if(F(e),0===e.avail_out)return n.last_flush=-1,m}else if(0===e.avail_in&&T(t)<=T(r)&&t!==f)return R(e,-5);if(666===n.status&&0!==e.avail_in)return R(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==l&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(j(e),0===e.lookahead)){if(t===l)return A;break}if(e.match_length=0,r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=S){if(j(e),e.lookahead<=S&&t===l)return A;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=x&&0e.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=x?(r=u._tr_tally(e,1,e.match_length-x),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):h[n.level].func(n,t);if(o!==O&&o!==B||(n.status=666),o===A||o===O)return 0===e.avail_out&&(n.last_flush=-1),m;if(o===I&&(1===t?u._tr_align(n):5!==t&&(u._tr_stored_block(n,0,0,!1),3===t&&(D(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),F(e),0===e.avail_out))return n.last_flush=-1,m}return t!==f?m:n.wrap<=0?1:(2===n.wrap?(U(n,255&e.adler),U(n,e.adler>>8&255),U(n,e.adler>>16&255),U(n,e.adler>>24&255),U(n,255&e.total_in),U(n,e.total_in>>8&255),U(n,e.total_in>>16&255),U(n,e.total_in>>24&255)):(P(n,e.adler>>>16),P(n,65535&e.adler)),F(e),0=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new c.Buf8(r.w_size),c.arraySet(u,t,l-r.w_size,r.w_size,0),t=u,l=r.w_size),a=e.avail_in,o=e.next_in,h=e.input,e.avail_in=l,e.next_in=0,e.input=t,j(r);r.lookahead>=x;){for(n=r.strstart,i=r.lookahead-(x-1);r.ins_h=(r.ins_h<>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else{if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(d&(1<>>=y,p-=y),p<15&&(d+=z[n++]<>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(d&(1<>>=y,p-=y,(y=s-a)>3,d&=(1<<(p-=w<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function h(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){e.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(d=r.length)&&(d=o),d&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,d,k)),512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,r.length-=d),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(d=0;k=n[s+d++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&d>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break e;o--,u+=n[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;u>>>=2,l-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break e;o--,u+=n[s++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(d=r.length){if(o>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l>>=_,l-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],d=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l>>=_)),u>>>=3,l-=3}else{for(z=_+7;l>>=_)),u>>>=7,l-=7}if(r.have+d>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;d--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=h){e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,R(e,c),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break e;if(d=c-h,r.offset>d){if((d=r.offset-d)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=d>r.wnext?(d-=r.wnext,r.wsize-d):r.wnext-d,d>r.length&&(d=r.length),m=r.window}else m=i,p=a-r.offset,d=r.length;for(hd?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=t[r+a[v]]}if(k>>7)]}function U(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function P(e,t,r){e.bi_valid>d-r?(e.bi_buf|=t<>d-e.bi_valid,e.bi_valid+=r-d):(e.bi_buf|=t<>>=1,r<<=1,0<--t;);return r>>>1}function Z(e,t,r){var n,i,s=new Array(g+1),a=0;for(n=1;n<=g;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=j(s[o]++,o))}}function W(e){var t;for(t=0;t>1;1<=r;r--)G(e,s,r);for(i=h;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],G(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,G(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,f=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=g;s++)e.bl_count[s]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<_;r++)p<(s=h[2*h[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),h[2*n+1]=s,u>=7;n>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return o;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return h;for(t=32;t>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?J(e,t,r,n):4===e.strategy||s===i?(P(e,2+(n?1:0),3),K(e,z,C)):(P(e,4+(n?1:0),3),function(e,t,r,n){var i;for(P(e,t-257,5),P(e,r-1,5),P(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(A[r]+u+1)]++,e.dyn_dtree[2*N(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){P(e,2,3),L(e,m,z),function(e){16===e.bi_valid?(U(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):8<=e.bi_valid&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}(e)}},{"../utils/common":41}],53:[function(e,t,r){"use strict";t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(e,t,r){(function(e){!function(r,n){"use strict";if(!r.setImmediate){var i,s,t,a,o=1,h={},u=!1,l=r.document,e=Object.getPrototypeOf&&Object.getPrototypeOf(r);e=e&&e.setTimeout?e:r,i="[object process]"==={}.toString.call(r.process)?function(e){process.nextTick(function(){c(e)})}:function(){if(r.postMessage&&!r.importScripts){var e=!0,t=r.onmessage;return r.onmessage=function(){e=!1},r.postMessage("","*"),r.onmessage=t,e}}()?(a="setImmediate$"+Math.random()+"$",r.addEventListener?r.addEventListener("message",d,!1):r.attachEvent("onmessage",d),function(e){r.postMessage(a+e,"*")}):r.MessageChannel?((t=new MessageChannel).port1.onmessage=function(e){c(e.data)},function(e){t.port2.postMessage(e)}):l&&"onreadystatechange"in l.createElement("script")?(s=l.documentElement,function(e){var t=l.createElement("script");t.onreadystatechange=function(){c(e),t.onreadystatechange=null,s.removeChild(t),t=null},s.appendChild(t)}):function(e){setTimeout(c,0,e)},e.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),r=0;r parseInt(o, 16))); + } break; + case "binary": { + if (!/^(?:[01]{8})*$/i.test(DATA)) return; + const dataArr = this.splitIntoParts(DATA, 8); + DATA = Uint8Array.from(dataArr.map(o => parseInt(o, 2))); + } break; + } + + this.zip = await JSZip.loadAsync(DATA, { createFolders: true }); + this.zipPath = "/"; + } catch (e) { + console.error("Zip extension: Could not open zip file.", e); + } + } + async getZip({ TYPE, COMPRESSION }) { + if (!this.zip) return ""; + try { + COMPRESSION = Scratch.Cast.toNumber(COMPRESSION); + COMPRESSION = Math.max(Math.min(Math.round(COMPRESSION), 9), 0); + + const compType = COMPRESSION === 0 ? "STORE" : "DEFLATE"; + const options = { compression: compType, compressionOptions: { level: COMPRESSION } }; + + switch (TYPE) { + case "text": + case "string": + return await this.zip.generateAsync({ + type: "binarystring", + ...options + }); + case "base64": + case "data: URL": { + let data = await this.zip.generateAsync({ + type: "base64", + ...options + }); + if (TYPE === "data: URL") + data = "data:application/zip;base64," + data; + return data; + } + case "hex": { + const data = await this.zip.generateAsync({ + type: "array", + ...options + }); + return data.map(data => data.toString(16).padStart(2, "0")).join(""); + } + case "binary": { + const data = await this.zip.generateAsync({ + type: "array", + ...options + }); + return data.map(data => data.toString(2).padStart(8, "0")).join(""); + } + default: return ""; + } + } catch (e) { + console.error(`Zip extension: Error creating zip with type ${TYPE} compression ${COMPRESSION}:`, e); + } + } + close() { + this.zip = null; + this.zipPath = null; + } + isOpen() { + return !!this.zip; + } + + exists({ OBJECT }) { + try { + return !!this.getObj(this.normalize(this.zipPath, Scratch.Cast.toString(OBJECT))); + } catch (e) { + return false; + } + } + async getFile({ FILE, TYPE }) { + if (!this.zip) return ""; + + FILE = Scratch.Cast.toString(FILE); + TYPE = Scratch.Cast.toString(TYPE); + try { + const path = this.normalize(this.zipPath, FILE); + if (path.endsWith("/")) return ""; + const obj = this.getObj(path); + if (!obj || obj.dir) return ""; + + switch (TYPE) { + case "text": + return await obj.async("string"); + case "base64": + case "data: URL": { + let data = await obj.async("base64"); + if (TYPE === "data: URL") + data = "data:application/octet-stream;base64," + data; + return data; + } + case "hex": { + const data = await obj.async("array"); + return data.map(data => data.toString(16).padStart(2, "0")).join(""); + } + case "binary": { + const data = await obj.async("array"); + return data.map(data => data.toString(2).padStart(8, "0")).join(""); + } + default: return ""; + } + } catch (e) { + console.error(`Zip extension: Error getting file ${FILE} with type ${TYPE}:`, e); + return ""; + } + } + async writeFile({ FILE, CONTENT, TYPE }) { + if (!this.zip) return; + + FILE = Scratch.Cast.toString(FILE); + CONTENT = Scratch.Cast.toString(CONTENT); + TYPE = Scratch.Cast.toString(TYPE); + try { + let path = this.normalize(this.zipPath, FILE); + if (path.endsWith("/")) return; + + const obj = this.getObj(path); + if (obj && obj.dir) return; + + if (path.startsWith("/")) path = path.substring(1); + + switch (TYPE) { + case "text": + this.zip.file(path, CONTENT, { + createFolders: true, + }); + break; + case "base64": + case "data: URL": { // compatibility + if (TYPE === "data: URL") + CONTENT = CONTENT.substring(CONTENT.indexOf(",")); + this.zip.file(path, CONTENT, { + base64: true, + createFolders: true, + }); + break; + } + case "URL": { + const resp = await Scratch.fetch(CONTENT); + this.zip.file(path, await resp.blob(), { + base64: true, + createFolders: true, + }); + } break; + case "hex": { + if (!/^(?:[0-9A-F]{2})*$/i.test(CONTENT)) return ""; + const dataArr = this.splitIntoParts(CONTENT, 2); + const data = Uint8Array.from(dataArr.map(o => parseInt(o, 16))); + this.zip.file(path, data, { + createFolders: true, + }); + } break; + case "binary": { + if (!/^(?:[01]{8})*$/i.test(CONTENT)) return ""; + const dataArr = this.splitIntoParts(CONTENT, 8); + const data = Uint8Array.from(dataArr.map(o => parseInt(o, 2))); + this.zip.file(path, data, { + createFolders: true, + }); + } break; + default: return ""; + } + } catch (e) { + console.error(`Zip extension: Error writing to file ${FILE} type ${TYPE}:`, e); + } + } + renameFile({ FROM, TO }) { + if (!this.zip) return; + + const renameOne = (from, to) => { + const obj = this.zip.files[from]; + this.zip.files[to] = obj; + obj.name = to; + delete this.zip.files[from]; + }; + + FROM = Scratch.Cast.toString(FROM); + TO = Scratch.Cast.toString(TO); + try { + let fromPath = this.normalize(this.zipPath, FROM); + let fromObj = this.getObj(fromPath); + if (!fromObj && !fromPath.endsWith("/")) { + fromPath += "/"; + fromObj = this.getObj(fromPath); + } + if (!fromObj) return; + let toPath = this.normalize(this.zipPath, TO); + const replacedTo = TO.replaceAll(/\\/g, "/"); + const slashes = replacedTo.split("/").length - 1; + if (slashes <= +fromObj.dir && (slashes === 0 || replacedTo.endsWith("/"))) { + // this is a name-only change + toPath = this.normalize(fromPath, "../" + replacedTo); + if (fromObj.dir) { + if (!fromPath.endsWith("/")) fromPath += "/"; + } else { + if (fromPath.endsWith("/")) return; + } + } + + if (fromPath.startsWith("/")) fromPath = fromPath.substring(1); + if (toPath.startsWith("/")) toPath = toPath.substring(1); + + // If this is a file, just renaming this one is enough + if (!fromObj.dir) { + renameOne(fromPath, toPath); + return; + } + + // Otherwise, we need to rename this object + // and everything else in it + if (!toPath.endsWith("/")) toPath += "/"; + + // Move current directory + if (this.zipPath.substring(1).startsWith(fromPath)) { + this.zipPath = + "/" + toPath + (this.zipPath.substring(1).substring(fromPath.length)); + } + + for (const path in this.zip.files) { + if (!path.startsWith(fromPath)) continue; + const extraPath = path.substring(fromPath.length); + renameOne(path, toPath + extraPath); + } + this.createFolders(toPath); + } catch (e) { + console.error(`Zip extension: Error renaming ${FROM} to ${TO}:`, e); + } + } + deleteFile({ FILE }) { + if (!this.zip) return; + + FILE = Scratch.Cast.toString(FILE); + try { + let path = this.normalize(this.zipPath, FILE); + if (!this.getObj(path)) return; + if (path === "/") return; + + const shouldGoBack = this.getObj(path).dir && this.zipPath.startsWith(path); + if (path.startsWith("/")) path = path.substring(1); + + + this.zip.remove(path); + + if (shouldGoBack) { + // Go back until we are in a directory that exists + const split = this.zipPath.split("/"); + this.zipPath = ""; + + let i = 0; + while (i < split.length) { + if (split[i] === "") { + i++; + continue; + } + const newPath = this.zipPath + split[i] + "/"; + if (!this.getObj(newPath)) break; + this.zipPath = newPath; + i++; + } + if (this.zipPath === "") this.zipPath = "/"; + } + } catch (e) { + console.error(`Zip extension: Error deleting file ${FILE}:`, e); + } + } + + setFileMeta({ META, FILE, VALUE }) { + if (!this.zip) return; + + META = Scratch.Cast.toString(META); + FILE = Scratch.Cast.toString(FILE); + VALUE = Scratch.Cast.toString(VALUE); + try { + const normalized = this.normalize(this.zipPath, FILE); + const obj = this.getObj(normalized); + if (!obj) return ""; + switch (META) { + case "modified days since 2000": { + const msPerDay = 24 * 60 * 60 * 1000; + const start = +(new Date(2000, 0, 1)); + obj.date = new Date(start + (Scratch.Cast.toNumber(VALUE) * msPerDay)); + } break; + case "unix modified timestamp": + obj.date = new Date(Scratch.Cast.toNumber(VALUE)); + break; + case "comment": + obj.comment = VALUE; + break; + default: return; + } + } catch (e) { + console.error(`Zip extension: Error getting ${META} of ${FILE}:`, e); + return ""; + } + } + getFileMeta({ META, FILE }) { + if (!this.zip) return ""; + + META = Scratch.Cast.toString(META); + FILE = Scratch.Cast.toString(FILE); + try { + const normalized = this.normalize(this.zipPath, FILE); + const obj = this.getObj(normalized); + if (!obj) return ""; + switch (META) { + case "name": { + const splitPath = obj.name.split("/"); + // Directories have an extra slash at the end + // (obj.dir is casted to 0 or 1) + return splitPath[splitPath.length - 1 - +obj.dir] || ""; + } + case "path": + return "/" + obj.name; + case "folder": { + /** @type {Array} */ + const splitPath = obj.name.split("/"); + const folders = (splitPath.slice( + 0, splitPath.length - 1 - +obj.dir + ).join("/")); + return "/" + folders + (folders === "" ? "" : "/"); + } + case "modification date": + return obj.date.toLocaleString(navigator.language); + case "long modification date": + return new Date().toLocaleString( + navigator.language, + { dateStyle: "full", timeStyle: "medium" } + ); + case "modified days since 2000": { + const msPerDay = 24 * 60 * 60 * 1000; + const start = +(new Date(2000, 0, 1)); + return (+obj.date - start) / msPerDay; + } + case "unix modified timestamp": + return +obj.date; + case "comment": + return obj.comment || ""; + default: return ""; + } + } catch (e) { + console.error(`Zip extension: Error getting ${META} of ${FILE}:`, e); + return ""; + } + } + + createDir({ DIR }) { + if (!this.zip) return; + DIR = Scratch.Cast.toString(DIR); + try { + let newPath = this.normalize(this.zipPath, DIR); + if (!newPath.endsWith("/")) newPath += "/"; + if (newPath.startsWith("/")) newPath = newPath.substring(1); + if (this.getObj(newPath)) return; + this.zip.folder(newPath); + } catch (e) { + console.error(`Error creating directory ${DIR}:`, e); + } + } + goToDir({ DIR }) { + if (!this.zip) return; + DIR = Scratch.Cast.toString(DIR); + try { + let newPath = this.normalize(this.zipPath, DIR); + if (!newPath.endsWith("/")) newPath += "/"; + if (!this.getObj(newPath)) return; + this.zipPath = newPath; + } catch (e) { + console.error(`Error going to directory ${DIR}:`, e); + } + } + getDir({ DIR }) { + if (!this.zip) return ""; + try { + DIR = Scratch.Cast.toString(DIR); + if (!DIR.endsWith("/")) DIR += "/"; + + const normalized = this.normalize(this.zipPath, DIR); + if (!this.getObj(normalized) && normalized !== "/") return ""; + const dir = normalized.substring(1); + const length = dir.length; + + return JSON.stringify(Object.values(this.zip.files).filter((obj) => { + // Above the current directory + if (!obj.name.startsWith(dir)) return false; + // Below the current directory + if (obj.name.substring(length).split("/").length > (obj.dir + 1)) return false; + // Is the current directory + if (obj.name === dir) return false; + return true; + }).map(obj => obj.name.substring(length))); + } catch (e) { + console.error(`Zip extension: Could not get directory ${DIR}:`, e); + return ""; + } + } + currentDir() { + return this.zipPath || ""; + } + + setComment({ COMMENT }) { + if (!this.zip) return; + this.zip.comment = Scratch.Cast.toString(COMMENT); + } + getComment({ COMMENT }) { + if (!this.zip) return ""; + return this.zip.comment || ""; + } + + normalizePath({ ORIGIN, PATH }) { + try { + return this.normalize( + Scratch.Cast.toString(ORIGIN), + Scratch.Cast.toString(PATH) + ); + } catch (e) { + return ""; + } + } + } + + // @ts-ignore + Scratch.extensions.register(new ZipExt()); +})(globalThis.Scratch); diff --git a/images/CST1229/zip.svg b/images/CST1229/zip.svg new file mode 100644 index 0000000000..60bb67ca79 --- /dev/null +++ b/images/CST1229/zip.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/website/CST1229/images/zip-close.svg b/website/CST1229/images/zip-close.svg new file mode 100644 index 0000000000..2f6a2c2513 --- /dev/null +++ b/website/CST1229/images/zip-close.svg @@ -0,0 +1,14 @@ +close archive \ No newline at end of file diff --git a/website/CST1229/images/zip-create-dir.svg b/website/CST1229/images/zip-create-dir.svg new file mode 100644 index 0000000000..874586f431 --- /dev/null +++ b/website/CST1229/images/zip-create-dir.svg @@ -0,0 +1,14 @@ +new foldercreate directory \ No newline at end of file diff --git a/website/CST1229/images/zip-create-empty.svg b/website/CST1229/images/zip-create-empty.svg new file mode 100644 index 0000000000..f7e8fe7a6b --- /dev/null +++ b/website/CST1229/images/zip-create-empty.svg @@ -0,0 +1,14 @@ +create empty archive \ No newline at end of file diff --git a/website/CST1229/images/zip-current-dir.svg b/website/CST1229/images/zip-current-dir.svg new file mode 100644 index 0000000000..d96fc8da98 --- /dev/null +++ b/website/CST1229/images/zip-current-dir.svg @@ -0,0 +1,14 @@ +current directory path \ No newline at end of file diff --git a/website/CST1229/images/zip-delete.svg b/website/CST1229/images/zip-delete.svg new file mode 100644 index 0000000000..43fd396b76 --- /dev/null +++ b/website/CST1229/images/zip-delete.svg @@ -0,0 +1,14 @@ +hello.txtdelete \ No newline at end of file diff --git a/website/CST1229/images/zip-dir-contents.svg b/website/CST1229/images/zip-dir-contents.svg new file mode 100644 index 0000000000..e9bc074c6f --- /dev/null +++ b/website/CST1229/images/zip-dir-contents.svg @@ -0,0 +1,14 @@ +.contents of directory \ No newline at end of file diff --git a/website/CST1229/images/zip-exists.svg b/website/CST1229/images/zip-exists.svg new file mode 100644 index 0000000000..bc351983e8 --- /dev/null +++ b/website/CST1229/images/zip-exists.svg @@ -0,0 +1,14 @@ +folder/exists? \ No newline at end of file diff --git a/website/CST1229/images/zip-file.svg b/website/CST1229/images/zip-file.svg new file mode 100644 index 0000000000..a996abcfed --- /dev/null +++ b/website/CST1229/images/zip-file.svg @@ -0,0 +1,14 @@ +hello.txttextfileas \ No newline at end of file diff --git a/website/CST1229/images/zip-get-comment.svg b/website/CST1229/images/zip-get-comment.svg new file mode 100644 index 0000000000..349a3f4462 --- /dev/null +++ b/website/CST1229/images/zip-get-comment.svg @@ -0,0 +1,14 @@ +archive comment \ No newline at end of file diff --git a/website/CST1229/images/zip-get-info.svg b/website/CST1229/images/zip-get-info.svg new file mode 100644 index 0000000000..a090926a6b --- /dev/null +++ b/website/CST1229/images/zip-get-info.svg @@ -0,0 +1,14 @@ +namefolder/dango.pngof \ No newline at end of file diff --git a/website/CST1229/images/zip-goto-dir.svg b/website/CST1229/images/zip-goto-dir.svg new file mode 100644 index 0000000000..03df84e034 --- /dev/null +++ b/website/CST1229/images/zip-goto-dir.svg @@ -0,0 +1,14 @@ +foldergo to directory \ No newline at end of file diff --git a/website/CST1229/images/zip-is-open.svg b/website/CST1229/images/zip-is-open.svg new file mode 100644 index 0000000000..12d39065d7 --- /dev/null +++ b/website/CST1229/images/zip-is-open.svg @@ -0,0 +1,14 @@ +archive is open? \ No newline at end of file diff --git a/website/CST1229/images/zip-open.svg b/website/CST1229/images/zip-open.svg new file mode 100644 index 0000000000..ce9e5b08df --- /dev/null +++ b/website/CST1229/images/zip-open.svg @@ -0,0 +1,14 @@ +URLhttps://extensions.turbowarp.org/hello.zipopen zip from \ No newline at end of file diff --git a/website/CST1229/images/zip-output.svg b/website/CST1229/images/zip-output.svg new file mode 100644 index 0000000000..738d44354a --- /dev/null +++ b/website/CST1229/images/zip-output.svg @@ -0,0 +1,14 @@ +data: URL6output zip typecompression level \ No newline at end of file diff --git a/website/CST1229/images/zip-path.svg b/website/CST1229/images/zip-path.svg new file mode 100644 index 0000000000..e3d64b99cb --- /dev/null +++ b/website/CST1229/images/zip-path.svg @@ -0,0 +1,14 @@ +../folder3//folder/folder2pathfrom \ No newline at end of file diff --git a/website/CST1229/images/zip-rename.svg b/website/CST1229/images/zip-rename.svg new file mode 100644 index 0000000000..01738cc4c7 --- /dev/null +++ b/website/CST1229/images/zip-rename.svg @@ -0,0 +1,14 @@ +hello.txthello renamed.txtrenameto \ No newline at end of file diff --git a/website/CST1229/images/zip-set-comment.svg b/website/CST1229/images/zip-set-comment.svg new file mode 100644 index 0000000000..6f159602a5 --- /dev/null +++ b/website/CST1229/images/zip-set-comment.svg @@ -0,0 +1,14 @@ +any textset archive comment to \ No newline at end of file diff --git a/website/CST1229/images/zip-set-meta.svg b/website/CST1229/images/zip-set-meta.svg new file mode 100644 index 0000000000..6973702608 --- /dev/null +++ b/website/CST1229/images/zip-set-meta.svg @@ -0,0 +1,14 @@ +modified days since 2000folder/dango.png0setofto \ No newline at end of file diff --git a/website/CST1229/images/zip-write.svg b/website/CST1229/images/zip-write.svg new file mode 100644 index 0000000000..2b08c5b107 --- /dev/null +++ b/website/CST1229/images/zip-write.svg @@ -0,0 +1,14 @@ +new file.txtHello, world?textwrite filecontenttype \ No newline at end of file diff --git a/website/CST1229/zip.html b/website/CST1229/zip.html new file mode 100644 index 0000000000..0c2b767646 --- /dev/null +++ b/website/CST1229/zip.html @@ -0,0 +1,551 @@ + + + + + + + Zip docs + + + + +

+

Zip extension documentation

+
+
+

+ The Zip extension allows you to read, create and edit .zip format files, + including Scratch project and sprite files + (.sb3, .sprite3). +

+ +

+ Paths + (link) +

+

Most blocks in this extension work with a path format:

+
    +
  • + The path is relative to the current directory by default +
  • +
  • + Directories (folders) and the filename are separated by slashes, like + folder1/folder2/file.txt +
  • +
  • + .. goes to the parent directory, like + ../file.txt +
  • +
  • + . goes to the current directory, like + ./file.txt +
  • +
  • + A / at the very start goes to the root directory, like + /file.txt +
  • +
  • + A / at the end denotes a directory, like + folder/ +
  • +
  • + + Multiple slashes in a row or trying to go above the root directory will + result in an error (usually the block doing nothing or returning the + empty value) +
  • +
+ +

+ + Archive management blocks + (link) +

+

+ Blocks for creating and saving the current archive. + Only one archive can be open at a time. +

+ +

+ create empty archive + (link) +

+

+ Creates and opens an empty archive with nothing in it. +

+ +

+ open zip from [URL] [https://extensions.turbowarp.org/hello.zip] + (link) +

+

+ Opens a .zip (or .sb3 or .sprite3...) file. +

+

+ The type can be one of the following: +

+
    +
  • + URL: A URL, which can be either a web URL or data: URL. Recommended. +
  • +
  • + base64: A base64 string without the data URL header. +
  • +
  • + hex: A sequence of hexadecimal bytes + (like 101A1B1C), + without a separator. +
  • +
  • + binary: A sequence of binary bytes + (like 000000010010101001101011), + without a separator. +
  • +
  • + string: Plain text. + Not recommended! + Text encoding behavior will likely break it, as it's a binary file. +
  • +
+

+ If the file is not of zip format (e.g RAR or 7z) or is password-protected, + it won't be opened. + Make sure to check if it loaded successfully with the + archive is open? block. +

+ +

+ output zip type [data: URL] compression level [6] + (link) +

+

+ Save the zip data into a string, which can be saved with e.g the Files extension. +

+

+ The type can be one of the following: +

+
    +
  • + data: URL: A base64-encoded data URL. Recommended. +
  • +
  • + base64: A base64 string without the data URL header. +
  • +
  • + hex: A sequence of hexadecimal bytes + (like 101A1B1C), + without a separator. +
  • +
  • + binary: A sequence of binary bytes + (like 000000010010101001101011), + without a separator. +
  • +
  • + string: Plain text. + Not recommended! + Text encoding behavior will likely break it, as it's a binary file. +
  • +
+

+ The compression level decides how much the zip is compressed. +
+ Lower compression levels will result in a bigger file, + but are faster to create. Usually, high compression levels + provide diminishing returns (lesser gains the higher you go) + with much slower speeds. +
+ A compression level of 0 (no compression) is the fastest, + but will often result in a very big file. +

+ +

+ close archive + (link) +

+

Closes the archive. Use after you're done working with it.

+ +

+ archive is open? + (link) +

+

Returns true if an archive is open.

+ + +

+ File blocks + (link) +

+

+ Blocks for working with files + (and blocks that are general to both files and folders/directories.) +

+ +

+ [folder/] exists? + (link) +

+

+ Returns if a file or directory exists or not. + The slash at the end matters! + If a directory named folder exists, + [folder] exists? will return false, + but [folder/] exists? will return true. +

+ +

+ write file [new file.txt] content [Hello, world?] type [text] + (link) +

+

+ Writes content to a file, creating the file if it doesn't exist + and replacing its existing data if it does. +

+

+ The type can be one of the following: +

+
    +
  • + text: Plain text. +
  • +
  • + URL: A URL, which can be either a web URL or data: URL. + Best for binary data (like other zip files). +
  • +
  • + base64: A base64 string without the data URL header. +
  • +
  • + hex: A sequence of hexadecimal bytes + (like 101A1B1C), + without a separator. +
  • +
  • + binary: A sequence of binary bytes + (like 000000010010101001101011), + without a separator. +
  • +
+ +

+ rename [hello.txt] to [hello renamed.txt] + (link) +

+

+ Renames a file or directory to another name. + If the target file already exists, it will be overwritten. + The current directory will also be updated. + This block can also be used to move files to a different directory. +

+ +

+ delete [hello.txt] + (link) +

+

+ Deletes a file or directory (including everything in it). +
+ If the current directory is in that directory, it will + be set to the closest existing parent directory. +

+ +

+ file [hello.txt] as [text] + (link) +

+

+ Get the contents of a file. +

+

+ The type can be one of the following: +

+
    +
  • + text: Plain text. +
  • +
  • + data: URL: A base64-encoded data URL. + Best for binary data (like other zip files). +
  • +
  • + base64: A base64 string without the data URL header. +
  • +
  • + hex: A sequence of hexadecimal bytes + (like 101A1B1C), + without a separator. +
  • +
  • + binary: A sequence of binary bytes + (like 000000010010101001101011), + without a separator. +
  • +
+ +

+ File info blocks + (link) +

+

Blocks for getting and setting additional information on a file.

+ +

+ set [unix modified timestamp] of [folder/dango.png] to [0] + (link) +

+

+ Set additional info on a file or directory. +

+

+ Available options: +

+
    +
  • + modified days since 2000: + The modification date of the file, as days since 2000. +
  • +
  • + unix modified timestamp: + The modification date of the file, as a Unix timestamp (milliseconds since 1970). + Useful when combined with e.g the Time extension. +
  • +
  • + comment: A comment on the file. Can be any text. + Some programs may show this as metadata. +
  • +
+ +

+ [name] of [folder/dango.png] + (link) +

+

+ Get additional info on a file or directory. +

+

+ Available options: +

+
    +
  • + name: + Just the name of this file (without the directories it's in). + For example, the name of /folder1/folder2/dango.png + would be dango.png. +
  • +
  • + path: The full absolute path of this file + (its name and any directories it's in). +
  • +
  • + folder: + Just the folders this file is in (without its filename). + For example, the folder of /folder1/folder2/dango.png + would be /folder1/folder2/. +
  • +
  • + modification date: + A human-readable version of the file's modification date. + The output of this depends on the browser's language and possibly other factors. +
  • +
  • + long modification date: + A longer human-readable version of the file's modification date. + The output of this depends on the browser's language and possibly other factors. +
  • +
  • + modified days since 2000: + The modification date of the file, as days since 2000. +
  • +
  • + unix modified timestamp: + The modification date of the file, as a Unix timestamp (milliseconds since 1970). + Useful when combined with e.g the Time extension. +
  • +
  • + comment: A comment on the file. Can be any text. + Some programs may show this as metadata. +
  • +
+ +

+ Directory blocks + (link) +

+

Blocks that deal with directories and the current directory.

+ + +

+ create directory [new folder] + (link) +

+

+ Creates a directory with a name. This can create multiple directories + at once (by having multiple directores in the path, like + /new folder1/new folder2/new folder3/). +

+ +

+ go to [folder] + (link) +

+

+ Moves the current directory (the default origin of most file operations) + to the speficied directory. If it doesn't exist, this block will do nothing. +

+ +

+ contents of directory [.] + (link) +

+

+ Returns a list of files in a directory, as JSON + (which you can parse with the JSON extension). +

+ +

+ current directory path + (link) +

+

+ Returns the absolute path to the current directory. +

+ +

+ Other blocks + (link) +

+

+ Miscellaneous stuff. +

+ +

+ set archive comment to [any text] + (link) +

+

+ Sets the archive's comment to some text. Just like file comments, + this is saved and may be displayed as metadata by some programs. +

+ +

+ archive comment + (link) +

+

+ Returns the archive's comment. +

+ +

+ path [../folder3/] from [/folder/folder2] + (link) +

+

+ Returns an absolute path from an origin path and a target path. + Does not depend on the archive, so it works without one open. + This is mostly a utility used internally, but it might + be useful for users too. +

+
+ + + \ No newline at end of file diff --git a/website/hello.zip b/website/hello.zip new file mode 100644 index 0000000000000000000000000000000000000000..18f132bee47d3cd3da686309053c891af1c16961 GIT binary patch literal 3055 zcmZ{m2{=@HAIHy(v5X;Rh-{f+s7sct-7BN9ja@2S+1F?op)56K$ePG9MNvuIAGKyG#LA9C;;q@+!aW?&WXucln66+3_FGQ4GZ@O@d3ia!&Ur)&WCz= z1pBDqL;P}Q^&~mQH)cjBPDk|5+$G?o{A5}T9h~?Psu*m%`nWKTYTrL!$ls7oGD9{f z7#Q>2>=T5D+!WsA%7MK8daQa;IOC(w^_W3QAWpFid*zaomVZ^*6!|w5izHgmR=2`a z+C=4}&Ob_SYDTZm>qSpkBxU6hR=ysm%_$OmMsBPK5%pK!Fotf4W$^>wLVVN+e)^QT z505ua$#3Eds3npdV-L&wH={CW)JW$ccC8ogmd=z*?i0_MO=KAHJo@KZ%`#3uRJ|R_9EH%)A=# z7k772(cL@(p7oZYm&$MJZP#a*iZH&@1R+t>SU!(=THV@#u<|Tq>)k50aVLqY}Eh z6%zhhW!yQXJm}gT*=PImsu0nSEOcQ5i?XIpf^dUL*F9_;O~18d>`5Z=NNCEyV!nx| zg81FZt}b@BB3i0)?^Y>-8TK5G2usN~i)vao&&Q|u)<+e#2@KR?pMnq+y})vp*}iFk zdUASn`X2X;J8dt7Ela8r-S)U#;@rw!`^s#J)xEL4Tpi>S#`WP2MZ`xbU{jxyrb#fmtiun`kb9cYDZ0m_tQ?IKU!A$UcOwL z6A#f_#bwN6&t>^yp#zAVg1}s%P;Y)`-GQ|EK0aK%;0UIaf1Dr|5zRf_u25NW6?dt@b zK_~CpVh(`rnG`g0>&~1Tzk0Y8O#m;nB;IEY*7c;5!RhHd*fayobmFTeorQJ2rgw7< zr#}Y*jXzVOuL8F{T9%jJ4%zOL0q83LC{VLJb6U~vitN&g)ggdj(FbL|^*cbsLHILT z&d1bU$?Vqim)L)m!h)yufx6Kz*1y~%q4|Y3QzDr==oI1b`7IUJPP{zP*&-X6`H*|Gem1`&-BR)wza=S}@bi1UWSZKmC`;JBrk5 zU)ti7m6+Y23+^R&iC-$V0XuK(gc-k;hNwCP#=z%aAT7aa}cDWimRi1 z$oSg`WbcYTCBTvdDum>0E&h^T0taQ5Sr-|qHlbdLhBr);!`_uw6UY08-J;|c=CIKN zJ!BXCPJ#`x@CqMZ!>x)tc)Kl`t}4vzf2_SP`NfI+LJ~f(dbpQ-z|Cl#U}N;@+EPjd za3TBDeYXS2@bRlBBcDba2%3iR_jtQ2qeaJ~MI(kzR?-eH3CMVN5-Or^+H zEWaLkW`ozi03o7zze*_U`L*w9Fr&{KoNGd+5}llsJEBk;rPbDG_$qDsx+7EjJE z5?lfruRPrq0IR%ZLnXFjz?I3VAMAUvOR zfi0W*^LXkJE5w5@BT~;}UejL{F?w5HY@3)0HN^=^cknj_j+8oEiIZk0*YlKswSrmM z#pec^s2~(Itb%*r^`Ab7Aq!ZcB0o39bwc_VefN(BYi`*sM0Z|<*&uMp3a+l}y^Tpd zh0$kfKuyyM&=wQ20dP&SeKzq3( zf+}@#*06-2=w?+ zlO%iF(_MN_uEg)exi0~0^D6T^Yd7=ym13hXu7TWY*F~qKc&DrENM`w!%3E3%!Z+(v zM5hjIu#c}FbbA4gM*9ys#Ma+|L|d70gJW{jJ-6RC3Z3oUDmNwtAm}ny6u;&I`ngSo z1x+iRTJDIGt`)$0tXhIi{q4(K>Z`T(m0;Cnvu4yFY8&*4=b>8ha6+Qi*j10;*7qOq3IdA){~vleR!&3y*?&i1TZ_L<|IEC9W$%KmHb>tH_;1rc zGw@#~BqyBxVfs$QKaTv%{lE47aMyB*`ChH91@|s30}#%|;KW7FCNJQH4-E7P3i}rz C4@Z^& literal 0 HcmV?d00001 diff --git a/website/index.ejs b/website/index.ejs index fd3812c909..c785b75872 100644 --- a/website/index.ejs +++ b/website/index.ejs @@ -644,6 +644,12 @@

Create disposable runtime or thread variables. Created by LilyMakesThings.

+
+ <%- banner('CST1229/zip') %> +

Zip

+

Create and edit .zip format files, including .sb3 files. Created by CST1229.

+
+
<%- banner('0832/rxFS2') %>

rxFS

From f13bb78d303610216effd6b85b3894bbf6b172e0 Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Sun, 16 Jul 2023 11:25:39 -0500 Subject: [PATCH 22/32] CST1229/zip: unbreak eslint (#749) --- extensions/CST1229/zip.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extensions/CST1229/zip.js b/extensions/CST1229/zip.js index 511931a0ee..9bbb0392ce 100644 --- a/extensions/CST1229/zip.js +++ b/extensions/CST1229/zip.js @@ -24,9 +24,10 @@ JSZip uses the library pako released under the MIT license : https://github.com/nodeca/pako/blob/main/LICENSE */ - // eslint-disable-next-line + /* eslint-disable */ // @ts-ignore !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).JSZip=e()}}(function(){return function s(a,o,h){function u(r,e){if(!o[r]){if(!a[r]){var t="function"==typeof require&&require;if(!e&&t)return t(r,!0);if(l)return l(r,!0);var n=new Error("Cannot find module '"+r+"'");throw n.code="MODULE_NOT_FOUND",n}var i=o[r]={exports:{}};a[r][0].call(i.exports,function(e){var t=a[r][1][e];return u(t||e)},i,i.exports,s,a,o,h)}return o[r].exports}for(var l="function"==typeof require&&require,e=0;e>2,s=(3&t)<<4|r>>4,a=1>6:64,o=2>4,r=(15&i)<<4|(s=p.indexOf(e.charAt(o++)))>>2,n=(3&s)<<6|(a=p.indexOf(e.charAt(o++))),l[h++]=t,64!==s&&(l[h++]=r),64!==a&&(l[h++]=n);return l}},{"./support":30,"./utils":32}],2:[function(e,t,r){"use strict";var n=e("./external"),i=e("./stream/DataWorker"),s=e("./stream/Crc32Probe"),a=e("./stream/DataLengthProbe");function o(e,t,r,n,i){this.compressedSize=e,this.uncompressedSize=t,this.crc32=r,this.compression=n,this.compressedContent=i}o.prototype={getContentWorker:function(){var e=new i(n.Promise.resolve(this.compressedContent)).pipe(this.compression.uncompressWorker()).pipe(new a("data_length")),t=this;return e.on("end",function(){if(this.streamInfo.data_length!==t.uncompressedSize)throw new Error("Bug : uncompressed data size mismatch")}),e},getCompressedWorker:function(){return new i(n.Promise.resolve(this.compressedContent)).withStreamInfo("compressedSize",this.compressedSize).withStreamInfo("uncompressedSize",this.uncompressedSize).withStreamInfo("crc32",this.crc32).withStreamInfo("compression",this.compression)}},o.createWorkerFrom=function(e,t,r){return e.pipe(new s).pipe(new a("uncompressedSize")).pipe(t.compressWorker(r)).pipe(new a("compressedSize")).withStreamInfo("compression",t)},t.exports=o},{"./external":6,"./stream/Crc32Probe":25,"./stream/DataLengthProbe":26,"./stream/DataWorker":27}],3:[function(e,t,r){"use strict";var n=e("./stream/GenericWorker");r.STORE={magic:"\0\0",compressWorker:function(){return new n("STORE compression")},uncompressWorker:function(){return new n("STORE decompression")}},r.DEFLATE=e("./flate")},{"./flate":7,"./stream/GenericWorker":28}],4:[function(e,t,r){"use strict";var n=e("./utils");var o=function(){for(var e,t=[],r=0;r<256;r++){e=r;for(var n=0;n<8;n++)e=1&e?3988292384^e>>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t){return void 0!==e&&e.length?"string"!==n.getTypeOf(e)?function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}(0|t,e,e.length,0):function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t.charCodeAt(a))];return-1^e}(0|t,e,e.length,0):0}},{"./utils":32}],5:[function(e,t,r){"use strict";r.base64=!1,r.binary=!1,r.dir=!1,r.createFolders=!0,r.date=null,r.compression=null,r.compressionOptions=null,r.comment=null,r.unixPermissions=null,r.dosPermissions=null},{}],6:[function(e,t,r){"use strict";var n=null;n="undefined"!=typeof Promise?Promise:e("lie"),t.exports={Promise:n}},{lie:37}],7:[function(e,t,r){"use strict";var n="undefined"!=typeof Uint8Array&&"undefined"!=typeof Uint16Array&&"undefined"!=typeof Uint32Array,i=e("pako"),s=e("./utils"),a=e("./stream/GenericWorker"),o=n?"uint8array":"array";function h(e,t){a.call(this,"FlateWorker/"+e),this._pako=null,this._pakoAction=e,this._pakoOptions=t,this.meta={}}r.magic="\b\0",s.inherits(h,a),h.prototype.processChunk=function(e){this.meta=e.meta,null===this._pako&&this._createPako(),this._pako.push(s.transformTo(o,e.data),!1)},h.prototype.flush=function(){a.prototype.flush.call(this),null===this._pako&&this._createPako(),this._pako.push([],!0)},h.prototype.cleanUp=function(){a.prototype.cleanUp.call(this),this._pako=null},h.prototype._createPako=function(){this._pako=new i[this._pakoAction]({raw:!0,level:this._pakoOptions.level||-1});var t=this;this._pako.onData=function(e){t.push({data:e,meta:t.meta})}},r.compressWorker=function(e){return new h("Deflate",e)},r.uncompressWorker=function(){return new h("Inflate",{})}},{"./stream/GenericWorker":28,"./utils":32,pako:38}],8:[function(e,t,r){"use strict";function A(e,t){var r,n="";for(r=0;r>>=8;return n}function n(e,t,r,n,i,s){var a,o,h=e.file,u=e.compression,l=s!==O.utf8encode,f=I.transformTo("string",s(h.name)),c=I.transformTo("string",O.utf8encode(h.name)),d=h.comment,p=I.transformTo("string",s(d)),m=I.transformTo("string",O.utf8encode(d)),_=c.length!==h.name.length,g=m.length!==d.length,b="",v="",y="",w=h.dir,k=h.date,x={crc32:0,compressedSize:0,uncompressedSize:0};t&&!r||(x.crc32=e.crc32,x.compressedSize=e.compressedSize,x.uncompressedSize=e.uncompressedSize);var S=0;t&&(S|=8),l||!_&&!g||(S|=2048);var z=0,C=0;w&&(z|=16),"UNIX"===i?(C=798,z|=function(e,t){var r=e;return e||(r=t?16893:33204),(65535&r)<<16}(h.unixPermissions,w)):(C=20,z|=function(e){return 63&(e||0)}(h.dosPermissions)),a=k.getUTCHours(),a<<=6,a|=k.getUTCMinutes(),a<<=5,a|=k.getUTCSeconds()/2,o=k.getUTCFullYear()-1980,o<<=4,o|=k.getUTCMonth()+1,o<<=5,o|=k.getUTCDate(),_&&(v=A(1,1)+A(B(f),4)+c,b+="up"+A(v.length,2)+v),g&&(y=A(1,1)+A(B(p),4)+m,b+="uc"+A(y.length,2)+y);var E="";return E+="\n\0",E+=A(S,2),E+=u.magic,E+=A(a,2),E+=A(o,2),E+=A(x.crc32,4),E+=A(x.compressedSize,4),E+=A(x.uncompressedSize,4),E+=A(f.length,2),E+=A(b.length,2),{fileRecord:R.LOCAL_FILE_HEADER+E+f+b,dirRecord:R.CENTRAL_FILE_HEADER+A(C,2)+E+A(p.length,2)+"\0\0\0\0"+A(z,4)+A(n,4)+f+b+p}}var I=e("../utils"),i=e("../stream/GenericWorker"),O=e("../utf8"),B=e("../crc32"),R=e("../signature");function s(e,t,r,n){i.call(this,"ZipFileWorker"),this.bytesWritten=0,this.zipComment=t,this.zipPlatform=r,this.encodeFileName=n,this.streamFiles=e,this.accumulate=!1,this.contentBuffer=[],this.dirRecords=[],this.currentSourceOffset=0,this.entriesCount=0,this.currentFile=null,this._sources=[]}I.inherits(s,i),s.prototype.push=function(e){var t=e.meta.percent||0,r=this.entriesCount,n=this._sources.length;this.accumulate?this.contentBuffer.push(e):(this.bytesWritten+=e.data.length,i.prototype.push.call(this,{data:e.data,meta:{currentFile:this.currentFile,percent:r?(t+100*(r-n-1))/r:100}}))},s.prototype.openedSource=function(e){this.currentSourceOffset=this.bytesWritten,this.currentFile=e.file.name;var t=this.streamFiles&&!e.file.dir;if(t){var r=n(e,t,!1,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);this.push({data:r.fileRecord,meta:{percent:0}})}else this.accumulate=!0},s.prototype.closedSource=function(e){this.accumulate=!1;var t=this.streamFiles&&!e.file.dir,r=n(e,t,!0,this.currentSourceOffset,this.zipPlatform,this.encodeFileName);if(this.dirRecords.push(r.dirRecord),t)this.push({data:function(e){return R.DATA_DESCRIPTOR+A(e.crc32,4)+A(e.compressedSize,4)+A(e.uncompressedSize,4)}(e),meta:{percent:100}});else for(this.push({data:r.fileRecord,meta:{percent:0}});this.contentBuffer.length;)this.push(this.contentBuffer.shift());this.currentFile=null},s.prototype.flush=function(){for(var e=this.bytesWritten,t=0;t=this.index;t--)r=(r<<8)+this.byteAt(t);return this.index+=e,r},readString:function(e){return n.transformTo("string",this.readData(e))},readData:function(){},lastIndexOfSignature:function(){},readAndCheckSignature:function(){},readDate:function(){var e=this.readInt(4);return new Date(Date.UTC(1980+(e>>25&127),(e>>21&15)-1,e>>16&31,e>>11&31,e>>5&63,(31&e)<<1))}},t.exports=i},{"../utils":32}],19:[function(e,t,r){"use strict";var n=e("./Uint8ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./Uint8ArrayReader":21}],20:[function(e,t,r){"use strict";var n=e("./DataReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.byteAt=function(e){return this.data.charCodeAt(this.zero+e)},i.prototype.lastIndexOfSignature=function(e){return this.data.lastIndexOf(e)-this.zero},i.prototype.readAndCheckSignature=function(e){return e===this.readData(4)},i.prototype.readData=function(e){this.checkOffset(e);var t=this.data.slice(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./DataReader":18}],21:[function(e,t,r){"use strict";var n=e("./ArrayReader");function i(e){n.call(this,e)}e("../utils").inherits(i,n),i.prototype.readData=function(e){if(this.checkOffset(e),0===e)return new Uint8Array(0);var t=this.data.subarray(this.zero+this.index,this.zero+this.index+e);return this.index+=e,t},t.exports=i},{"../utils":32,"./ArrayReader":17}],22:[function(e,t,r){"use strict";var n=e("../utils"),i=e("../support"),s=e("./ArrayReader"),a=e("./StringReader"),o=e("./NodeBufferReader"),h=e("./Uint8ArrayReader");t.exports=function(e){var t=n.getTypeOf(e);return n.checkSupport(t),"string"!==t||i.uint8array?"nodebuffer"===t?new o(e):i.uint8array?new h(n.transformTo("uint8array",e)):new s(n.transformTo("array",e)):new a(e)}},{"../support":30,"../utils":32,"./ArrayReader":17,"./NodeBufferReader":19,"./StringReader":20,"./Uint8ArrayReader":21}],23:[function(e,t,r){"use strict";r.LOCAL_FILE_HEADER="PK",r.CENTRAL_FILE_HEADER="PK",r.CENTRAL_DIRECTORY_END="PK",r.ZIP64_CENTRAL_DIRECTORY_LOCATOR="PK",r.ZIP64_CENTRAL_DIRECTORY_END="PK",r.DATA_DESCRIPTOR="PK\b"},{}],24:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../utils");function s(e){n.call(this,"ConvertWorker to "+e),this.destType=e}i.inherits(s,n),s.prototype.processChunk=function(e){this.push({data:i.transformTo(this.destType,e.data),meta:e.meta})},t.exports=s},{"../utils":32,"./GenericWorker":28}],25:[function(e,t,r){"use strict";var n=e("./GenericWorker"),i=e("../crc32");function s(){n.call(this,"Crc32Probe"),this.withStreamInfo("crc32",0)}e("../utils").inherits(s,n),s.prototype.processChunk=function(e){this.streamInfo.crc32=i(e.data,this.streamInfo.crc32||0),this.push(e)},t.exports=s},{"../crc32":4,"../utils":32,"./GenericWorker":28}],26:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataLengthProbe for "+e),this.propName=e,this.withStreamInfo(e,0)}n.inherits(s,i),s.prototype.processChunk=function(e){if(e){var t=this.streamInfo[this.propName]||0;this.streamInfo[this.propName]=t+e.data.length}i.prototype.processChunk.call(this,e)},t.exports=s},{"../utils":32,"./GenericWorker":28}],27:[function(e,t,r){"use strict";var n=e("../utils"),i=e("./GenericWorker");function s(e){i.call(this,"DataWorker");var t=this;this.dataIsReady=!1,this.index=0,this.max=0,this.data=null,this.type="",this._tickScheduled=!1,e.then(function(e){t.dataIsReady=!0,t.data=e,t.max=e&&e.length||0,t.type=n.getTypeOf(e),t.isPaused||t._tickAndRepeat()},function(e){t.error(e)})}n.inherits(s,i),s.prototype.cleanUp=function(){i.prototype.cleanUp.call(this),this.data=null},s.prototype.resume=function(){return!!i.prototype.resume.call(this)&&(!this._tickScheduled&&this.dataIsReady&&(this._tickScheduled=!0,n.delay(this._tickAndRepeat,[],this)),!0)},s.prototype._tickAndRepeat=function(){this._tickScheduled=!1,this.isPaused||this.isFinished||(this._tick(),this.isFinished||(n.delay(this._tickAndRepeat,[],this),this._tickScheduled=!0))},s.prototype._tick=function(){if(this.isPaused||this.isFinished)return!1;var e=null,t=Math.min(this.max,this.index+16384);if(this.index>=this.max)return this.end();switch(this.type){case"string":e=this.data.substring(this.index,t);break;case"uint8array":e=this.data.subarray(this.index,t);break;case"array":case"nodebuffer":e=this.data.slice(this.index,t)}return this.index=t,this.push({data:e,meta:{percent:this.max?this.index/this.max*100:0}})},t.exports=s},{"../utils":32,"./GenericWorker":28}],28:[function(e,t,r){"use strict";function n(e){this.name=e||"default",this.streamInfo={},this.generatedError=null,this.extraStreamInfo={},this.isPaused=!0,this.isFinished=!1,this.isLocked=!1,this._listeners={data:[],end:[],error:[]},this.previous=null}n.prototype={push:function(e){this.emit("data",e)},end:function(){if(this.isFinished)return!1;this.flush();try{this.emit("end"),this.cleanUp(),this.isFinished=!0}catch(e){this.emit("error",e)}return!0},error:function(e){return!this.isFinished&&(this.isPaused?this.generatedError=e:(this.isFinished=!0,this.emit("error",e),this.previous&&this.previous.error(e),this.cleanUp()),!0)},on:function(e,t){return this._listeners[e].push(t),this},cleanUp:function(){this.streamInfo=this.generatedError=this.extraStreamInfo=null,this._listeners=[]},emit:function(e,t){if(this._listeners[e])for(var r=0;r "+e:e}},t.exports=n},{}],29:[function(e,t,r){"use strict";var h=e("../utils"),i=e("./ConvertWorker"),s=e("./GenericWorker"),u=e("../base64"),n=e("../support"),a=e("../external"),o=null;if(n.nodestream)try{o=e("../nodejs/NodejsStreamOutputAdapter")}catch(e){}function l(e,o){return new a.Promise(function(t,r){var n=[],i=e._internalType,s=e._outputType,a=e._mimeType;e.on("data",function(e,t){n.push(e),o&&o(t)}).on("error",function(e){n=[],r(e)}).on("end",function(){try{var e=function(e,t,r){switch(e){case"blob":return h.newBlob(h.transformTo("arraybuffer",t),r);case"base64":return u.encode(t);default:return h.transformTo(e,t)}}(s,function(e,t){var r,n=0,i=null,s=0;for(r=0;r>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t}(e)},s.utf8decode=function(e){return h.nodebuffer?o.transformTo("nodebuffer",e).toString("utf-8"):function(e){var t,r,n,i,s=e.length,a=new Array(2*s);for(t=r=0;t>10&1023,a[r++]=56320|1023&n)}return a.length!==r&&(a.subarray?a=a.subarray(0,r):a.length=r),o.applyFromCharCode(a)}(e=o.transformTo(h.uint8array?"uint8array":"array",e))},o.inherits(a,n),a.prototype.processChunk=function(e){var t=o.transformTo(h.uint8array?"uint8array":"array",e.data);if(this.leftOver&&this.leftOver.length){if(h.uint8array){var r=t;(t=new Uint8Array(r.length+this.leftOver.length)).set(this.leftOver,0),t.set(r,this.leftOver.length)}else t=this.leftOver.concat(t);this.leftOver=null}var n=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}(t),i=t;n!==t.length&&(h.uint8array?(i=t.subarray(0,n),this.leftOver=t.subarray(n,t.length)):(i=t.slice(0,n),this.leftOver=t.slice(n,t.length))),this.push({data:s.utf8decode(i),meta:e.meta})},a.prototype.flush=function(){this.leftOver&&this.leftOver.length&&(this.push({data:s.utf8decode(this.leftOver),meta:{}}),this.leftOver=null)},s.Utf8DecodeWorker=a,o.inherits(l,n),l.prototype.processChunk=function(e){this.push({data:s.utf8encode(e.data),meta:e.meta})},s.Utf8EncodeWorker=l},{"./nodejsUtils":14,"./stream/GenericWorker":28,"./support":30,"./utils":32}],32:[function(e,t,a){"use strict";var o=e("./support"),h=e("./base64"),r=e("./nodejsUtils"),u=e("./external");function n(e){return e}function l(e,t){for(var r=0;r>8;this.dir=!!(16&this.externalFileAttributes),0==e&&(this.dosPermissions=63&this.externalFileAttributes),3==e&&(this.unixPermissions=this.externalFileAttributes>>16&65535),this.dir||"/"!==this.fileNameStr.slice(-1)||(this.dir=!0)},parseZIP64ExtraField:function(){if(this.extraFields[1]){var e=n(this.extraFields[1].value);this.uncompressedSize===s.MAX_VALUE_32BITS&&(this.uncompressedSize=e.readInt(8)),this.compressedSize===s.MAX_VALUE_32BITS&&(this.compressedSize=e.readInt(8)),this.localHeaderOffset===s.MAX_VALUE_32BITS&&(this.localHeaderOffset=e.readInt(8)),this.diskNumberStart===s.MAX_VALUE_32BITS&&(this.diskNumberStart=e.readInt(4))}},readExtraFields:function(e){var t,r,n,i=e.index+this.extraFieldsLength;for(this.extraFields||(this.extraFields={});e.index+4>>6:(r<65536?t[s++]=224|r>>>12:(t[s++]=240|r>>>18,t[s++]=128|r>>>12&63),t[s++]=128|r>>>6&63),t[s++]=128|63&r);return t},r.buf2binstring=function(e){return l(e,e.length)},r.binstring2buf=function(e){for(var t=new h.Buf8(e.length),r=0,n=t.length;r>10&1023,o[n++]=56320|1023&i)}return l(o,n)},r.utf8border=function(e,t){var r;for((t=t||e.length)>e.length&&(t=e.length),r=t-1;0<=r&&128==(192&e[r]);)r--;return r<0?t:0===r?t:r+u[e[r]]>t?r:t}},{"./common":41}],43:[function(e,t,r){"use strict";t.exports=function(e,t,r,n){for(var i=65535&e|0,s=e>>>16&65535|0,a=0;0!==r;){for(r-=a=2e3>>1:e>>>1;t[r]=e}return t}();t.exports=function(e,t,r,n){var i=o,s=n+r;e^=-1;for(var a=n;a>>8^i[255&(e^t[a])];return-1^e}},{}],46:[function(e,t,r){"use strict";var h,c=e("../utils/common"),u=e("./trees"),d=e("./adler32"),p=e("./crc32"),n=e("./messages"),l=0,f=4,m=0,_=-2,g=-1,b=4,i=2,v=8,y=9,s=286,a=30,o=19,w=2*s+1,k=15,x=3,S=258,z=S+x+1,C=42,E=113,A=1,I=2,O=3,B=4;function R(e,t){return e.msg=n[t],t}function T(e){return(e<<1)-(4e.avail_out&&(r=e.avail_out),0!==r&&(c.arraySet(e.output,t.pending_buf,t.pending_out,r,e.next_out),e.next_out+=r,t.pending_out+=r,e.total_out+=r,e.avail_out-=r,t.pending-=r,0===t.pending&&(t.pending_out=0))}function N(e,t){u._tr_flush_block(e,0<=e.block_start?e.block_start:-1,e.strstart-e.block_start,t),e.block_start=e.strstart,F(e.strm)}function U(e,t){e.pending_buf[e.pending++]=t}function P(e,t){e.pending_buf[e.pending++]=t>>>8&255,e.pending_buf[e.pending++]=255&t}function L(e,t){var r,n,i=e.max_chain_length,s=e.strstart,a=e.prev_length,o=e.nice_match,h=e.strstart>e.w_size-z?e.strstart-(e.w_size-z):0,u=e.window,l=e.w_mask,f=e.prev,c=e.strstart+S,d=u[s+a-1],p=u[s+a];e.prev_length>=e.good_match&&(i>>=2),o>e.lookahead&&(o=e.lookahead);do{if(u[(r=t)+a]===p&&u[r+a-1]===d&&u[r]===u[s]&&u[++r]===u[s+1]){s+=2,r++;do{}while(u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&u[++s]===u[++r]&&sh&&0!=--i);return a<=e.lookahead?a:e.lookahead}function j(e){var t,r,n,i,s,a,o,h,u,l,f=e.w_size;do{if(i=e.window_size-e.lookahead-e.strstart,e.strstart>=f+(f-z)){for(c.arraySet(e.window,e.window,f,f,0),e.match_start-=f,e.strstart-=f,e.block_start-=f,t=r=e.hash_size;n=e.head[--t],e.head[t]=f<=n?n-f:0,--r;);for(t=r=f;n=e.prev[--t],e.prev[t]=f<=n?n-f:0,--r;);i+=f}if(0===e.strm.avail_in)break;if(a=e.strm,o=e.window,h=e.strstart+e.lookahead,u=i,l=void 0,l=a.avail_in,u=x)for(s=e.strstart-e.insert,e.ins_h=e.window[s],e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x)if(n=u._tr_tally(e,e.strstart-e.match_start,e.match_length-x),e.lookahead-=e.match_length,e.match_length<=e.max_lazy_match&&e.lookahead>=x){for(e.match_length--;e.strstart++,e.ins_h=(e.ins_h<=x&&(e.ins_h=(e.ins_h<=x&&e.match_length<=e.prev_length){for(i=e.strstart+e.lookahead-x,n=u._tr_tally(e,e.strstart-1-e.prev_match,e.prev_length-x),e.lookahead-=e.prev_length-1,e.prev_length-=2;++e.strstart<=i&&(e.ins_h=(e.ins_h<e.pending_buf_size-5&&(r=e.pending_buf_size-5);;){if(e.lookahead<=1){if(j(e),0===e.lookahead&&t===l)return A;if(0===e.lookahead)break}e.strstart+=e.lookahead,e.lookahead=0;var n=e.block_start+r;if((0===e.strstart||e.strstart>=n)&&(e.lookahead=e.strstart-n,e.strstart=n,N(e,!1),0===e.strm.avail_out))return A;if(e.strstart-e.block_start>=e.w_size-z&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):(e.strstart>e.block_start&&(N(e,!1),e.strm.avail_out),A)}),new M(4,4,8,4,Z),new M(4,5,16,8,Z),new M(4,6,32,32,Z),new M(4,4,16,16,W),new M(8,16,32,32,W),new M(8,16,128,128,W),new M(8,32,128,256,W),new M(32,128,258,1024,W),new M(32,258,258,4096,W)],r.deflateInit=function(e,t){return Y(e,t,v,15,8,0)},r.deflateInit2=Y,r.deflateReset=K,r.deflateResetKeep=G,r.deflateSetHeader=function(e,t){return e&&e.state?2!==e.state.wrap?_:(e.state.gzhead=t,m):_},r.deflate=function(e,t){var r,n,i,s;if(!e||!e.state||5>8&255),U(n,n.gzhead.time>>16&255),U(n,n.gzhead.time>>24&255),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,255&n.gzhead.os),n.gzhead.extra&&n.gzhead.extra.length&&(U(n,255&n.gzhead.extra.length),U(n,n.gzhead.extra.length>>8&255)),n.gzhead.hcrc&&(e.adler=p(e.adler,n.pending_buf,n.pending,0)),n.gzindex=0,n.status=69):(U(n,0),U(n,0),U(n,0),U(n,0),U(n,0),U(n,9===n.level?2:2<=n.strategy||n.level<2?4:0),U(n,3),n.status=E);else{var a=v+(n.w_bits-8<<4)<<8;a|=(2<=n.strategy||n.level<2?0:n.level<6?1:6===n.level?2:3)<<6,0!==n.strstart&&(a|=32),a+=31-a%31,n.status=E,P(n,a),0!==n.strstart&&(P(n,e.adler>>>16),P(n,65535&e.adler)),e.adler=1}if(69===n.status)if(n.gzhead.extra){for(i=n.pending;n.gzindex<(65535&n.gzhead.extra.length)&&(n.pending!==n.pending_buf_size||(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending!==n.pending_buf_size));)U(n,255&n.gzhead.extra[n.gzindex]),n.gzindex++;n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),n.gzindex===n.gzhead.extra.length&&(n.gzindex=0,n.status=73)}else n.status=73;if(73===n.status)if(n.gzhead.name){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.gzindex=0,n.status=91)}else n.status=91;if(91===n.status)if(n.gzhead.comment){i=n.pending;do{if(n.pending===n.pending_buf_size&&(n.gzhead.hcrc&&n.pending>i&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),F(e),i=n.pending,n.pending===n.pending_buf_size)){s=1;break}s=n.gzindexi&&(e.adler=p(e.adler,n.pending_buf,n.pending-i,i)),0===s&&(n.status=103)}else n.status=103;if(103===n.status&&(n.gzhead.hcrc?(n.pending+2>n.pending_buf_size&&F(e),n.pending+2<=n.pending_buf_size&&(U(n,255&e.adler),U(n,e.adler>>8&255),e.adler=0,n.status=E)):n.status=E),0!==n.pending){if(F(e),0===e.avail_out)return n.last_flush=-1,m}else if(0===e.avail_in&&T(t)<=T(r)&&t!==f)return R(e,-5);if(666===n.status&&0!==e.avail_in)return R(e,-5);if(0!==e.avail_in||0!==n.lookahead||t!==l&&666!==n.status){var o=2===n.strategy?function(e,t){for(var r;;){if(0===e.lookahead&&(j(e),0===e.lookahead)){if(t===l)return A;break}if(e.match_length=0,r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++,r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):3===n.strategy?function(e,t){for(var r,n,i,s,a=e.window;;){if(e.lookahead<=S){if(j(e),e.lookahead<=S&&t===l)return A;if(0===e.lookahead)break}if(e.match_length=0,e.lookahead>=x&&0e.lookahead&&(e.match_length=e.lookahead)}if(e.match_length>=x?(r=u._tr_tally(e,1,e.match_length-x),e.lookahead-=e.match_length,e.strstart+=e.match_length,e.match_length=0):(r=u._tr_tally(e,0,e.window[e.strstart]),e.lookahead--,e.strstart++),r&&(N(e,!1),0===e.strm.avail_out))return A}return e.insert=0,t===f?(N(e,!0),0===e.strm.avail_out?O:B):e.last_lit&&(N(e,!1),0===e.strm.avail_out)?A:I}(n,t):h[n.level].func(n,t);if(o!==O&&o!==B||(n.status=666),o===A||o===O)return 0===e.avail_out&&(n.last_flush=-1),m;if(o===I&&(1===t?u._tr_align(n):5!==t&&(u._tr_stored_block(n,0,0,!1),3===t&&(D(n.head),0===n.lookahead&&(n.strstart=0,n.block_start=0,n.insert=0))),F(e),0===e.avail_out))return n.last_flush=-1,m}return t!==f?m:n.wrap<=0?1:(2===n.wrap?(U(n,255&e.adler),U(n,e.adler>>8&255),U(n,e.adler>>16&255),U(n,e.adler>>24&255),U(n,255&e.total_in),U(n,e.total_in>>8&255),U(n,e.total_in>>16&255),U(n,e.total_in>>24&255)):(P(n,e.adler>>>16),P(n,65535&e.adler)),F(e),0=r.w_size&&(0===s&&(D(r.head),r.strstart=0,r.block_start=0,r.insert=0),u=new c.Buf8(r.w_size),c.arraySet(u,t,l-r.w_size,r.w_size,0),t=u,l=r.w_size),a=e.avail_in,o=e.next_in,h=e.input,e.avail_in=l,e.next_in=0,e.input=t,j(r);r.lookahead>=x;){for(n=r.strstart,i=r.lookahead-(x-1);r.ins_h=(r.ins_h<>>=y=v>>>24,p-=y,0===(y=v>>>16&255))C[s++]=65535&v;else{if(!(16&y)){if(0==(64&y)){v=m[(65535&v)+(d&(1<>>=y,p-=y),p<15&&(d+=z[n++]<>>=y=v>>>24,p-=y,!(16&(y=v>>>16&255))){if(0==(64&y)){v=_[(65535&v)+(d&(1<>>=y,p-=y,(y=s-a)>3,d&=(1<<(p-=w<<3))-1,e.next_in=n,e.next_out=s,e.avail_in=n>>24&255)+(e>>>8&65280)+((65280&e)<<8)+((255&e)<<24)}function s(){this.mode=0,this.last=!1,this.wrap=0,this.havedict=!1,this.flags=0,this.dmax=0,this.check=0,this.total=0,this.head=null,this.wbits=0,this.wsize=0,this.whave=0,this.wnext=0,this.window=null,this.hold=0,this.bits=0,this.length=0,this.offset=0,this.extra=0,this.lencode=null,this.distcode=null,this.lenbits=0,this.distbits=0,this.ncode=0,this.nlen=0,this.ndist=0,this.have=0,this.next=null,this.lens=new I.Buf16(320),this.work=new I.Buf16(288),this.lendyn=null,this.distdyn=null,this.sane=0,this.back=0,this.was=0}function a(e){var t;return e&&e.state?(t=e.state,e.total_in=e.total_out=t.total=0,e.msg="",t.wrap&&(e.adler=1&t.wrap),t.mode=P,t.last=0,t.havedict=0,t.dmax=32768,t.head=null,t.hold=0,t.bits=0,t.lencode=t.lendyn=new I.Buf32(n),t.distcode=t.distdyn=new I.Buf32(i),t.sane=1,t.back=-1,N):U}function o(e){var t;return e&&e.state?((t=e.state).wsize=0,t.whave=0,t.wnext=0,a(e)):U}function h(e,t){var r,n;return e&&e.state?(n=e.state,t<0?(r=0,t=-t):(r=1+(t>>4),t<48&&(t&=15)),t&&(t<8||15=s.wsize?(I.arraySet(s.window,t,r-s.wsize,s.wsize,0),s.wnext=0,s.whave=s.wsize):(n<(i=s.wsize-s.wnext)&&(i=n),I.arraySet(s.window,t,r-n,i,s.wnext),(n-=i)?(I.arraySet(s.window,t,r-n,n,0),s.wnext=n,s.whave=s.wsize):(s.wnext+=i,s.wnext===s.wsize&&(s.wnext=0),s.whave>>8&255,r.check=B(r.check,E,2,0),l=u=0,r.mode=2;break}if(r.flags=0,r.head&&(r.head.done=!1),!(1&r.wrap)||(((255&u)<<8)+(u>>8))%31){e.msg="incorrect header check",r.mode=30;break}if(8!=(15&u)){e.msg="unknown compression method",r.mode=30;break}if(l-=4,k=8+(15&(u>>>=4)),0===r.wbits)r.wbits=k;else if(k>r.wbits){e.msg="invalid window size",r.mode=30;break}r.dmax=1<>8&1),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=3;case 3:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>8&255,E[2]=u>>>16&255,E[3]=u>>>24&255,r.check=B(r.check,E,4,0)),l=u=0,r.mode=4;case 4:for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>8),512&r.flags&&(E[0]=255&u,E[1]=u>>>8&255,r.check=B(r.check,E,2,0)),l=u=0,r.mode=5;case 5:if(1024&r.flags){for(;l<16;){if(0===o)break e;o--,u+=n[s++]<>>8&255,r.check=B(r.check,E,2,0)),l=u=0}else r.head&&(r.head.extra=null);r.mode=6;case 6:if(1024&r.flags&&(o<(d=r.length)&&(d=o),d&&(r.head&&(k=r.head.extra_len-r.length,r.head.extra||(r.head.extra=new Array(r.head.extra_len)),I.arraySet(r.head.extra,n,s,d,k)),512&r.flags&&(r.check=B(r.check,n,d,s)),o-=d,s+=d,r.length-=d),r.length))break e;r.length=0,r.mode=7;case 7:if(2048&r.flags){if(0===o)break e;for(d=0;k=n[s+d++],r.head&&k&&r.length<65536&&(r.head.name+=String.fromCharCode(k)),k&&d>9&1,r.head.done=!0),e.adler=r.check=0,r.mode=12;break;case 10:for(;l<32;){if(0===o)break e;o--,u+=n[s++]<>>=7&l,l-=7&l,r.mode=27;break}for(;l<3;){if(0===o)break e;o--,u+=n[s++]<>>=1)){case 0:r.mode=14;break;case 1:if(j(r),r.mode=20,6!==t)break;u>>>=2,l-=2;break e;case 2:r.mode=17;break;case 3:e.msg="invalid block type",r.mode=30}u>>>=2,l-=2;break;case 14:for(u>>>=7&l,l-=7&l;l<32;){if(0===o)break e;o--,u+=n[s++]<>>16^65535)){e.msg="invalid stored block lengths",r.mode=30;break}if(r.length=65535&u,l=u=0,r.mode=15,6===t)break e;case 15:r.mode=16;case 16:if(d=r.length){if(o>>=5,l-=5,r.ndist=1+(31&u),u>>>=5,l-=5,r.ncode=4+(15&u),u>>>=4,l-=4,286>>=3,l-=3}for(;r.have<19;)r.lens[A[r.have++]]=0;if(r.lencode=r.lendyn,r.lenbits=7,S={bits:r.lenbits},x=T(0,r.lens,0,19,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid code lengths set",r.mode=30;break}r.have=0,r.mode=19;case 19:for(;r.have>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=_,l-=_,r.lens[r.have++]=b;else{if(16===b){for(z=_+2;l>>=_,l-=_,0===r.have){e.msg="invalid bit length repeat",r.mode=30;break}k=r.lens[r.have-1],d=3+(3&u),u>>>=2,l-=2}else if(17===b){for(z=_+3;l>>=_)),u>>>=3,l-=3}else{for(z=_+7;l>>=_)),u>>>=7,l-=7}if(r.have+d>r.nlen+r.ndist){e.msg="invalid bit length repeat",r.mode=30;break}for(;d--;)r.lens[r.have++]=k}}if(30===r.mode)break;if(0===r.lens[256]){e.msg="invalid code -- missing end-of-block",r.mode=30;break}if(r.lenbits=9,S={bits:r.lenbits},x=T(D,r.lens,0,r.nlen,r.lencode,0,r.work,S),r.lenbits=S.bits,x){e.msg="invalid literal/lengths set",r.mode=30;break}if(r.distbits=6,r.distcode=r.distdyn,S={bits:r.distbits},x=T(F,r.lens,r.nlen,r.ndist,r.distcode,0,r.work,S),r.distbits=S.bits,x){e.msg="invalid distances set",r.mode=30;break}if(r.mode=20,6===t)break e;case 20:r.mode=21;case 21:if(6<=o&&258<=h){e.next_out=a,e.avail_out=h,e.next_in=s,e.avail_in=o,r.hold=u,r.bits=l,R(e,c),a=e.next_out,i=e.output,h=e.avail_out,s=e.next_in,n=e.input,o=e.avail_in,u=r.hold,l=r.bits,12===r.mode&&(r.back=-1);break}for(r.back=0;g=(C=r.lencode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,r.length=b,0===g){r.mode=26;break}if(32&g){r.back=-1,r.mode=12;break}if(64&g){e.msg="invalid literal/length code",r.mode=30;break}r.extra=15&g,r.mode=22;case 22:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}r.was=r.length,r.mode=23;case 23:for(;g=(C=r.distcode[u&(1<>>16&255,b=65535&C,!((_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>v)])>>>16&255,b=65535&C,!(v+(_=C>>>24)<=l);){if(0===o)break e;o--,u+=n[s++]<>>=v,l-=v,r.back+=v}if(u>>>=_,l-=_,r.back+=_,64&g){e.msg="invalid distance code",r.mode=30;break}r.offset=b,r.extra=15&g,r.mode=24;case 24:if(r.extra){for(z=r.extra;l>>=r.extra,l-=r.extra,r.back+=r.extra}if(r.offset>r.dmax){e.msg="invalid distance too far back",r.mode=30;break}r.mode=25;case 25:if(0===h)break e;if(d=c-h,r.offset>d){if((d=r.offset-d)>r.whave&&r.sane){e.msg="invalid distance too far back",r.mode=30;break}p=d>r.wnext?(d-=r.wnext,r.wsize-d):r.wnext-d,d>r.length&&(d=r.length),m=r.window}else m=i,p=a-r.offset,d=r.length;for(hd?(m=R[T+a[v]],A[I+a[v]]):(m=96,0),h=1<>S)+(u-=h)]=p<<24|m<<16|_|0,0!==u;);for(h=1<>=1;if(0!==h?(E&=h-1,E+=h):E=0,v++,0==--O[b]){if(b===w)break;b=t[r+a[v]]}if(k>>7)]}function U(e,t){e.pending_buf[e.pending++]=255&t,e.pending_buf[e.pending++]=t>>>8&255}function P(e,t,r){e.bi_valid>d-r?(e.bi_buf|=t<>d-e.bi_valid,e.bi_valid+=r-d):(e.bi_buf|=t<>>=1,r<<=1,0<--t;);return r>>>1}function Z(e,t,r){var n,i,s=new Array(g+1),a=0;for(n=1;n<=g;n++)s[n]=a=a+r[n-1]<<1;for(i=0;i<=t;i++){var o=e[2*i+1];0!==o&&(e[2*i]=j(s[o]++,o))}}function W(e){var t;for(t=0;t>1;1<=r;r--)G(e,s,r);for(i=h;r=e.heap[1],e.heap[1]=e.heap[e.heap_len--],G(e,s,1),n=e.heap[1],e.heap[--e.heap_max]=r,e.heap[--e.heap_max]=n,s[2*i]=s[2*r]+s[2*n],e.depth[i]=(e.depth[r]>=e.depth[n]?e.depth[r]:e.depth[n])+1,s[2*r+1]=s[2*n+1]=i,e.heap[1]=i++,G(e,s,1),2<=e.heap_len;);e.heap[--e.heap_max]=e.heap[1],function(e,t){var r,n,i,s,a,o,h=t.dyn_tree,u=t.max_code,l=t.stat_desc.static_tree,f=t.stat_desc.has_stree,c=t.stat_desc.extra_bits,d=t.stat_desc.extra_base,p=t.stat_desc.max_length,m=0;for(s=0;s<=g;s++)e.bl_count[s]=0;for(h[2*e.heap[e.heap_max]+1]=0,r=e.heap_max+1;r<_;r++)p<(s=h[2*h[2*(n=e.heap[r])+1]+1]+1)&&(s=p,m++),h[2*n+1]=s,u>=7;n>>=1)if(1&r&&0!==e.dyn_ltree[2*t])return o;if(0!==e.dyn_ltree[18]||0!==e.dyn_ltree[20]||0!==e.dyn_ltree[26])return h;for(t=32;t>>3,(s=e.static_len+3+7>>>3)<=i&&(i=s)):i=s=r+5,r+4<=i&&-1!==t?J(e,t,r,n):4===e.strategy||s===i?(P(e,2+(n?1:0),3),K(e,z,C)):(P(e,4+(n?1:0),3),function(e,t,r,n){var i;for(P(e,t-257,5),P(e,r-1,5),P(e,n-4,4),i=0;i>>8&255,e.pending_buf[e.d_buf+2*e.last_lit+1]=255&t,e.pending_buf[e.l_buf+e.last_lit]=255&r,e.last_lit++,0===t?e.dyn_ltree[2*r]++:(e.matches++,t--,e.dyn_ltree[2*(A[r]+u+1)]++,e.dyn_dtree[2*N(t)]++),e.last_lit===e.lit_bufsize-1},r._tr_align=function(e){P(e,2,3),L(e,m,z),function(e){16===e.bi_valid?(U(e,e.bi_buf),e.bi_buf=0,e.bi_valid=0):8<=e.bi_valid&&(e.pending_buf[e.pending++]=255&e.bi_buf,e.bi_buf>>=8,e.bi_valid-=8)}(e)}},{"../utils/common":41}],53:[function(e,t,r){"use strict";t.exports=function(){this.input=null,this.next_in=0,this.avail_in=0,this.total_in=0,this.output=null,this.next_out=0,this.avail_out=0,this.total_out=0,this.msg="",this.state=null,this.data_type=2,this.adler=0}},{}],54:[function(e,t,r){(function(e){!function(r,n){"use strict";if(!r.setImmediate){var i,s,t,a,o=1,h={},u=!1,l=r.document,e=Object.getPrototypeOf&&Object.getPrototypeOf(r);e=e&&e.setTimeout?e:r,i="[object process]"==={}.toString.call(r.process)?function(e){process.nextTick(function(){c(e)})}:function(){if(r.postMessage&&!r.importScripts){var e=!0,t=r.onmessage;return r.onmessage=function(){e=!1},r.postMessage("","*"),r.onmessage=t,e}}()?(a="setImmediate$"+Math.random()+"$",r.addEventListener?r.addEventListener("message",d,!1):r.attachEvent("onmessage",d),function(e){r.postMessage(a+e,"*")}):r.MessageChannel?((t=new MessageChannel).port1.onmessage=function(e){c(e.data)},function(e){t.port2.postMessage(e)}):l&&"onreadystatechange"in l.createElement("script")?(s=l.documentElement,function(e){var t=l.createElement("script");t.onreadystatechange=function(){c(e),t.onreadystatechange=null,s.removeChild(t),t=null},s.appendChild(t)}):function(e){setTimeout(c,0,e)},e.setImmediate=function(e){"function"!=typeof e&&(e=new Function(""+e));for(var t=new Array(arguments.length-1),r=0;r Date: Sun, 16 Jul 2023 21:43:03 -0500 Subject: [PATCH 23/32] build(deps-dev): bump eslint from 8.44.0 to 8.45.0 (#754) Bumps [eslint](https://github.com/eslint/eslint) from 8.44.0 to 8.45.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.44.0...v8.45.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- package-lock.json | 26 ++++++++++++-------------- package.json | 2 +- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/package-lock.json b/package-lock.json index 17d82f4ddc..a64b2f43cc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -145,9 +145,9 @@ } }, "acorn": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz", - "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==", + "version": "8.10.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz", + "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==", "dev": true }, "acorn-jsx": { @@ -412,9 +412,9 @@ "dev": true }, "eslint": { - "version": "8.44.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz", - "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==", + "version": "8.45.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.45.0.tgz", + "integrity": "sha512-pd8KSxiQpdYRfYa9Wufvdoct3ZPQQuVuU5O6scNgMuOMYuxvH0IGaYK0wUFjo4UYYQQCUndlXiMbnxopwvvTiw==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", @@ -442,7 +442,6 @@ "globals": "^13.19.0", "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", @@ -454,7 +453,6 @@ "natural-compare": "^1.4.0", "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { @@ -485,9 +483,9 @@ } }, "eslint-scope": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz", - "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.1.tgz", + "integrity": "sha512-CvefSOsDdaYYvxChovdrPo/ZGt8d5lrJWleAc1diXRKhHGiTYEI26cvo8Kle/wGnsizoCJjK73FMg1/IkIwiNA==", "dev": true, "requires": { "esrecurse": "^4.3.0", @@ -501,9 +499,9 @@ "dev": true }, "espree": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz", - "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { "acorn": "^8.9.0", diff --git a/package.json b/package.json index 57f22155ea..470d6ee969 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,7 @@ "image-size": "^1.0.2" }, "devDependencies": { - "eslint": "^8.44.0" + "eslint": "^8.45.0" }, "private": true } From 3b38982d82a23d27333613d54a348c71ddfe1794 Mon Sep 17 00:00:00 2001 From: CST1229 <68464103+CST1229@users.noreply.github.com> Date: Tue, 18 Jul 2023 14:12:19 +0200 Subject: [PATCH 24/32] CST1229/zip: fix going to `/` (#755) * CST1229/zip: fix going to root * CST1229/zip: add sentence about going to .. and / in docs --- extensions/CST1229/zip.js | 2 +- website/CST1229/zip.html | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/CST1229/zip.js b/extensions/CST1229/zip.js index 9bbb0392ce..1be08830d0 100644 --- a/extensions/CST1229/zip.js +++ b/extensions/CST1229/zip.js @@ -824,7 +824,7 @@ try { let newPath = this.normalize(this.zipPath, DIR); if (!newPath.endsWith("/")) newPath += "/"; - if (!this.getObj(newPath)) return; + if (!this.getObj(newPath) && newPath !== "/") return; this.zipPath = newPath; } catch (e) { console.error(`Error going to directory ${DIR}:`, e); diff --git a/website/CST1229/zip.html b/website/CST1229/zip.html index 0c2b767646..140f033d88 100644 --- a/website/CST1229/zip.html +++ b/website/CST1229/zip.html @@ -490,7 +490,9 @@

Moves the current directory (the default origin of most file operations) - to the speficied directory. If it doesn't exist, this block will do nothing. + to the specified directory. If it doesn't exist, this block will do nothing. + Use .. to go to the previous (parent) directory, and + / to go to the root.

From 84053a41420782257803daf1183a955e35775bbc Mon Sep 17 00:00:00 2001 From: LilyMakesThings <127533508+LilyMakesThings@users.noreply.github.com> Date: Sat, 22 Jul 2023 22:53:07 +0100 Subject: [PATCH 25/32] DT/cameracontrols: minor fixes (#768) - Set cameraBG value - Disabled interpolation when loading --- extensions/DT/cameracontrols.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/extensions/DT/cameracontrols.js b/extensions/DT/cameracontrols.js index 0c5f0cc4ab..960dca6c99 100644 --- a/extensions/DT/cameracontrols.js +++ b/extensions/DT/cameracontrols.js @@ -19,6 +19,7 @@ vm.runtime.runtimeOptions.fencing = false; vm.renderer.offscreenTouching = true; + vm.setInterpolation(false); function updateCamera(x = cameraX, y = cameraY, scale = cameraZoom / 100, rot = -cameraDirection + 90) { rot = rot / 180 * Math.PI; @@ -347,6 +348,7 @@ setCol(args, util) { const rgb = Scratch.Cast.toRgbColorList(args.val); Scratch.vm.renderer.setBackgroundColor(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255); + cameraBG = args.val; } getCol() { return cameraBG; From d4c4678fcb89c86d941b1d3cf6eba919e5842aac Mon Sep 17 00:00:00 2001 From: NexusKitten <127152751+NexusKitten@users.noreply.github.com> Date: Sun, 23 Jul 2023 18:06:22 -0400 Subject: [PATCH 26/32] Add NexusKitten/moremotion extension (#732) --- extensions/NexusKitten/moremotion.js | 360 +++++++++++++++++++++++++++ website/index.ejs | 6 + 2 files changed, 366 insertions(+) create mode 100644 extensions/NexusKitten/moremotion.js diff --git a/extensions/NexusKitten/moremotion.js b/extensions/NexusKitten/moremotion.js new file mode 100644 index 0000000000..fef57e9f43 --- /dev/null +++ b/extensions/NexusKitten/moremotion.js @@ -0,0 +1,360 @@ +(function(Scratch) { + 'use strict'; + + if (!Scratch.extensions.unsandboxed) { + throw new Error('More Motion must run unsandboxed'); + } + + class nkmoremotion { + getInfo() { + return { + id: 'nkmoremotion', + name: 'More Motion', + color1: '#4c97ff', + color2: '#3373cc', + blocks: [ + { + filter: [Scratch.TargetType.STAGE], + blockType: Scratch.BlockType.LABEL, + text: 'Stage selected: no motion blocks' + }, + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'changexy', + blockType: Scratch.BlockType.COMMAND, + text: 'change x: [X] y: [Y]', + arguments: { + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + } + } + }, + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'pointto', + blockType: Scratch.BlockType.COMMAND, + text: 'point towards x: [X] y: [Y]', + arguments: { + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + } + } + }, + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'rotationStyle', + blockType: Scratch.BlockType.REPORTER, + text: 'rotation style', + disableMonitor: true + }, + '---', + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'fence', + blockType: Scratch.BlockType.COMMAND, + text: 'manually fence' + }, + '---', + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'steptowards', + blockType: Scratch.BlockType.COMMAND, + text: 'move [STEPS] steps towards x: [X] y: [Y]', + arguments: { + STEPS: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '10' + }, + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + } + } + }, + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'tweentowards', + blockType: Scratch.BlockType.COMMAND, + text: 'move [PERCENT]% of the way to x: [X] y: [Y]', + arguments: { + PERCENT: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '10' + }, + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + } + } + }, + '---', + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'directionto', + blockType: Scratch.BlockType.REPORTER, + text: 'direction to x: [X] y: [Y]', + arguments: { + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + } + } + }, + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'distanceto', + blockType: Scratch.BlockType.REPORTER, + text: 'distance from x: [X] y: [Y]', + arguments: { + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + } + } + }, + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'spritewh', + blockType: Scratch.BlockType.REPORTER, + text: 'sprite [WHAT]', + disableMonitor: true, + arguments: { + WHAT: { + type: Scratch.ArgumentType.STRING, + menu: 'WHAT' + } + } + }, + '---', + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'touchingxy', + blockType: Scratch.BlockType.BOOLEAN, + text: 'touching x: [X] y: [Y]?', + arguments: { + X: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + }, + Y: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '0' + } + } + }, + { + filter: [Scratch.TargetType.SPRITE], + opcode: 'touchingrect', + blockType: Scratch.BlockType.BOOLEAN, + text: 'touching rectangle x1: [X1] y1: [Y1] x2: [X2] y2: [Y2]?', + arguments: { + X1: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '-100' + }, + Y1: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '-100' + }, + X2: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '100' + }, + Y2: { + type: Scratch.ArgumentType.NUMBER, + defaultValue: '100' + } + } + }, + ], + menus: { + WHAT: { + acceptreporters: true, + items: [ + 'width', + 'height', + 'costume width', + 'costume height' + ] + } + } + }; + } + + changexy(args, util) { + const x = Scratch.Cast.toNumber(args.X); + const y = Scratch.Cast.toNumber(args.Y); + util.target.setXY(util.target.x + x, util.target.y + y); + } + + // LORAX APPROVED + pointto(args, util) { + const x = Scratch.Cast.toNumber(args.X); + const y = Scratch.Cast.toNumber(args.Y); + if (util.target.y > y) { + util.target.setDirection(((180 / Math.PI) * Math.atan((x - util.target.x) / (y - util.target.y))) + 180); + } else { + util.target.setDirection(((180 / Math.PI) * Math.atan((x - util.target.x) / (y - util.target.y)))); + } + } + + rotationStyle(args, util) { + return util.target.rotationStyle; + } + + fence(args, util) { + const newpos = Scratch.vm.renderer.getFencedPositionOfDrawable(util.target.drawableID, [util.target.x, util.target.y]); + util.target.setXY(newpos[0], newpos[1]); + } + + directionto(args, util) { + const x = Scratch.Cast.toNumber(args.X); + const y = Scratch.Cast.toNumber(args.Y); + if (util.target.y > y) { + return ((180 / Math.PI) * Math.atan((x - util.target.x) / (y - util.target.y))) + 180; + } else { + return ((180 / Math.PI) * Math.atan((x - util.target.x) / (y - util.target.y))); + } + } + + distanceto(args, util) { + const x = Scratch.Cast.toNumber(args.X); + const y = Scratch.Cast.toNumber(args.Y); + // Shoutout to Pythagoras! + return Math.sqrt(((x - util.target.x) ** 2) + ((y - util.target.y) ** 2)); + } + + steptowards(args, util) { + const x = Scratch.Cast.toNumber(args.X); + const y = Scratch.Cast.toNumber(args.Y); + const steps = Scratch.Cast.toNumber(args.STEPS); + const val = steps / (Math.sqrt(((x - util.target.x) ** 2) + ((y - util.target.y) ** 2))); + if (val >= 1) { + util.target.setXY(x, y); + } else { + util.target.setXY(((x - util.target.x) * (val)) + util.target.x, ((y - util.target.y) * (val)) + util.target.y); + } + } + + tweentowards(args, util) { + const x = Scratch.Cast.toNumber(args.X); + const y = Scratch.Cast.toNumber(args.Y); + const val = Scratch.Cast.toNumber(args.PERCENT); + // Essentially a smooth glide script. + util.target.setXY(((x - util.target.x) * (val / 100)) + util.target.x, ((y - util.target.y) * (val / 100)) + util.target.y); + } + + touchingrect(args, util) { + let left = Scratch.Cast.toNumber(args.X1); + let right = Scratch.Cast.toNumber(args.X2); + let bottom = Scratch.Cast.toNumber(args.Y1); + let top = Scratch.Cast.toNumber(args.Y2); + + // Fix argument order if they got it backwards + if (left > right) { + let temp = left; + left = right; + right = temp; + } + if (bottom > top) { + let temp = bottom; + bottom = top; + bottom = temp; + } + + const drawable = Scratch.vm.renderer._allDrawables[util.target.drawableID]; + if (!drawable) { + return false; + } + + // See renderer.isTouchingDrawables + + const drawableBounds = drawable.getFastBounds(); + drawableBounds.snapToInt(); + + // This is bad, need to rewrite this when renderer exports Rectangle + const Rectangle = Object.getPrototypeOf(drawableBounds).constructor; + + /** @type {RenderWebGL.Rectangle} */ + const containsBounds = new Rectangle(); + containsBounds.initFromBounds(left, right, bottom, top); + containsBounds.snapToInt(); + + if (!containsBounds.intersects(drawableBounds)) { + return false; + } + + drawable.updateCPURenderAttributes(); + + /** @type {RenderWebGL.Rectangle} */ + const intersectingBounds = Rectangle.intersect(drawableBounds, containsBounds); + for (let x = intersectingBounds.left; x < intersectingBounds.right; x++) { + for (let y = intersectingBounds.bottom; y < intersectingBounds.top; y++) { + // technically should be a twgl vec3, but does not actually need to be + if (drawable.isTouching([x, y])) { + return true; + } + } + } + return false; + } + + touchingxy(args, util) { + const x = Scratch.Cast.toNumber(args.X); + const y = Scratch.Cast.toNumber(args.Y); + const drawable = Scratch.vm.renderer._allDrawables[util.target.drawableID]; + if (!drawable) { + return false; + } + // Position should technically be a twgl vec3, but it doesn't actually need to be + drawable.updateCPURenderAttributes(); + return drawable.isTouching([x, y]); + } + + spritewh(args, util) { + if (args.WHAT === 'width' || args.WHAT === 'height') { + const bounds = Scratch.vm.renderer.getBounds(util.target.drawableID); + if (args.WHAT === 'width') { + return Math.ceil(bounds.width); + } else { + return Math.ceil(bounds.height); + } + } else if (args.WHAT === 'costume width' || args.WHAT === 'costume height') { + const costume = util.target.sprite.costumes[util.target.currentCostume]; + if (args.WHAT === 'costume width') { + return Math.ceil(costume.size[0]); + } else { + return Math.ceil(costume.size[1]); + } + } + } + } + + Scratch.extensions.register(new nkmoremotion()); +})(Scratch); diff --git a/website/index.ejs b/website/index.ejs index c785b75872..5001a74b61 100644 --- a/website/index.ejs +++ b/website/index.ejs @@ -506,6 +506,12 @@

Expands upon the looks category, allowing you to show/hide, get costume data and edit SVG skins on sprites. Created by LilyMakesThings.

+
+ <%- banner('NexusKitten/moremotion') %> +

More Motion

+

More motion-related blocks. Created by NamelessCat.

+
+
<%- banner('navigator') %>

Navigator

From 378f3e9605514f76eab7a2177bdb222b2990aa1d Mon Sep 17 00:00:00 2001 From: TheShovel <68913917+TheShovel@users.noreply.github.com> Date: Mon, 24 Jul 2023 01:10:33 +0300 Subject: [PATCH 27/32] TheShovel/CanvasEffects: add more effects (#747) - Sepia - Transparency - Scale - SkewX - SkewY - Offset X - Offset Y - Rotation - Border radius --- extensions/TheShovel/CanvasEffects.js | 74 +++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 4 deletions(-) diff --git a/extensions/TheShovel/CanvasEffects.js b/extensions/TheShovel/CanvasEffects.js index 4d53b09cc2..ed9c7552e0 100644 --- a/extensions/TheShovel/CanvasEffects.js +++ b/extensions/TheShovel/CanvasEffects.js @@ -7,21 +7,40 @@ const canvas = Scratch.renderer.canvas; const updateStyle = () => { - const filter = `blur(${blur}px) contrast(${contrast / 100}) saturate(${saturation}%) hue-rotate(${color}deg) brightness(${brightness}%) invert(${invert}%)`; + // Gotta keep the translation to % because of the stage size, window size and so on + const transform = `rotate(${rotation}deg) scale(${scale}%) skew(${skewX}deg, ${skewY}deg) translate(${offsetX}%, ${0 - offsetY}%)`; + if (canvas.style.transform !== transform) { + canvas.style.transform = transform; + } + const filter = `blur(${blur}px) contrast(${contrast / 100}) saturate(${saturation}%) hue-rotate(${color}deg) brightness(${brightness}%) invert(${invert}%) sepia(${sepia}%) opacity(${100 - transparency}%)`; if (canvas.style.filter !== filter) { canvas.style.filter = filter; } + const cssBorderRadius = borderRadius === 0 ? '' : `${borderRadius}%`; + if (canvas.style.borderRadius !== cssBorderRadius) { + canvas.style.borderRadius = cssBorderRadius; + } const imageRendering = resizeMode === 'pixelated' ? 'pixelated' : ''; if (canvas.style.imageRendering !== imageRendering) { canvas.style.imageRendering = imageRendering; } }; - // scratch-gui will sometimes reset the cursor when resizing the window or going in/out of fullscreen + // scratch-gui may reset canvas styles when resizing the window or going in/out of fullscreen new MutationObserver(updateStyle).observe(canvas, { attributeFilter: ['style'], attributes: true }); + let borderRadius = 0; + let rotation = 0; + let offsetY = 0; + let offsetX = 0; + let skewY = 0; + let skewX = 0; + let scale = 100; + // Thanks SharkPool for telling me about these + let transparency = 0; + let sepia = 0; let blur = 0; let contrast = 100; let saturation = 100; @@ -96,7 +115,7 @@ menus: { EFFECTMENU: { acceptReporters: true, - items: ['blur', 'contrast', 'saturation', 'color shift', 'brightness', 'invert'] + items: ['blur', 'contrast', 'saturation', 'color shift', 'brightness', 'invert', 'sepia', 'transparency', 'scale', 'skew X', 'skew Y', 'offset X', 'offset Y', 'rotation', 'border radius'] }, RENDERMODE: { acceptReporters: true, @@ -104,7 +123,8 @@ }, EFFECTGETMENU: { acceptReporters: true, - items: ['blur', 'contrast', 'saturation', 'color shift', 'brightness', 'invert', 'resize rendering mode'] + // this contains 'resize rendering mode', EFFECTMENU does not + items: ['blur', 'contrast', 'saturation', 'color shift', 'brightness', 'invert', 'resize rendering mode', 'sepia', 'transparency', 'scale', 'skew X', 'skew Y', 'offset X', 'offset Y', 'rotation', 'border radius'] } } }; @@ -124,10 +144,29 @@ return invert; } else if (EFFECT === 'resize rendering mode') { return resizeMode; + } else if (EFFECT === 'sepia') { + return sepia; + } else if (EFFECT === 'transparency') { + return transparency; + } else if (EFFECT === 'scale') { + return scale; + } else if (EFFECT === 'skew X') { + return skewX; + } else if (EFFECT === 'skew Y') { + return skewY; + } else if (EFFECT === 'offset X') { + return offsetX; + } else if (EFFECT === 'offset Y') { + return offsetY; + } else if (EFFECT === 'rotation') { + return rotation; + } else if (EFFECT === 'border radius') { + return borderRadius; } return ''; } seteffect({EFFECT, NUMBER}) { + NUMBER = Scratch.Cast.toNumber(NUMBER); if (EFFECT === 'blur') { blur = NUMBER; } else if (EFFECT === 'contrast') { @@ -140,10 +179,37 @@ brightness = NUMBER; } else if (EFFECT === 'invert') { invert = NUMBER; + } else if (EFFECT === 'sepia') { + sepia = NUMBER; + } else if (EFFECT === 'transparency') { + transparency = NUMBER; + } else if (EFFECT === 'scale') { + scale = NUMBER; + } else if (EFFECT === 'skew X') { + skewX = NUMBER; + } else if (EFFECT === 'skew Y') { + skewY = NUMBER; + } else if (EFFECT === 'offset X') { + offsetX = NUMBER; + } else if (EFFECT === 'offset Y') { + offsetY = NUMBER; + } else if (EFFECT === 'rotation') { + rotation = NUMBER; + } else if (EFFECT === 'border radius') { + borderRadius = NUMBER; } updateStyle(); } cleareffects() { + borderRadius = 0; + rotation = 0; + offsetY = 0; + offsetX = 0; + skewY = 0; + skewX = 0; + scale = 100; + transparency = 0; + sepia = 0; blur = 0; contrast = 100; saturation = 100; From 36f80eab99ab72863da714b7dc572f114699841f Mon Sep 17 00:00:00 2001 From: CST1229 <68464103+CST1229@users.noreply.github.com> Date: Thu, 27 Jul 2023 23:46:59 +0200 Subject: [PATCH 28/32] CST1229/zip: fix compression level menu (#791) --- extensions/CST1229/zip.js | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/extensions/CST1229/zip.js b/extensions/CST1229/zip.js index 1be08830d0..07091f33d8 100644 --- a/extensions/CST1229/zip.js +++ b/extensions/CST1229/zip.js @@ -92,7 +92,7 @@ }, COMPRESSION: { type: Scratch.ArgumentType.NUMBER, - defaultValue: 6, + defaultValue: "6", menu: "compressionLevel", }, }, @@ -326,16 +326,16 @@ compressionLevel: { acceptReporters: true, items: [ - { text: "no compression (fastest)", value: 0 }, - { text: "1 (fast, large)", value: 1 }, - { text: "2", value: 2 }, - { text: "3", value: 3 }, - { text: "4", value: 4 }, - { text: "5", value: 5 }, - { text: "6", value: 6 }, - { text: "7", value: 7 }, - { text: "8", value: 8 }, - { text: "9 (slowest, smallest)", value: 9 }, + { text: "no compression (fastest)", value: "0" }, + { text: "1 (fast, large)", value: "1" }, + { text: "2", value: "2" }, + { text: "3", value: "3" }, + { text: "4", value: "4" }, + { text: "5", value: "5" }, + { text: "6", value: "6" }, + { text: "7", value: "7" }, + { text: "8", value: "8" }, + { text: "9 (slowest, smallest)", value: "9" }, ], }, fileMeta: { From 54cd0d19f874fef594f5386748ba5c1be9ea9baa Mon Sep 17 00:00:00 2001 From: Obvious Alex C <76855369+David-Orangemoon@users.noreply.github.com> Date: Thu, 27 Jul 2023 22:56:00 -0400 Subject: [PATCH 29/32] obviousAlexC/newgroundsIO: fix API problems (#792) --- extensions/obviousAlexC/newgroundsIO.js | 1027 ++++++++++++++++++++--- 1 file changed, 914 insertions(+), 113 deletions(-) diff --git a/extensions/obviousAlexC/newgroundsIO.js b/extensions/obviousAlexC/newgroundsIO.js index f40aec5e52..985627460c 100644 --- a/extensions/obviousAlexC/newgroundsIO.js +++ b/extensions/obviousAlexC/newgroundsIO.js @@ -1,7 +1,7 @@ (function (Scratch) { "use strict"; - /*! + /*! The following code is from NewgroundsIO-JS The original code is available at https://github.com/PsychoGoldfishNG/NewgroundsIO-JS @@ -30,6 +30,8 @@ */ /* eslint-disable */ + //Newgrounds.io JS library taken from https://github.com/PsychoGoldfishNG/NewgroundsIO-JS/blob/main/dist/NewgroundsIO.js the official Github for Newgrounds.io + /* ====================== ./NewgroundsIO-JS/src/NGIO.js ====================== */ /** Start Class NGIO **/ @@ -1530,38 +1532,829 @@ (c) 2009-2013 by Jeff Mott. All rights reserved. code.google.com/p/crypto-js/wiki/License */ - /* eslint-disable */ - var CryptoJS=CryptoJS||function(u,p){var d={},l=d.lib={},s=function(){},t=l.Base={extend:function(a){s.prototype=this;var c=new s;a&&c.mixIn(a);c.hasOwnProperty("init")||(c.init=function(){c.$super.init.apply(this,arguments)});c.init.prototype=c;c.$super=this;return c},create:function(){var a=this.extend();a.init.apply(a,arguments);return a},init:function(){},mixIn:function(a){for(var c in a)a.hasOwnProperty(c)&&(this[c]=a[c]);a.hasOwnProperty("toString")&&(this.toString=a.toString)},clone:function(){return this.init.prototype.extend(this)}}, - r=l.WordArray=t.extend({init:function(a,c){a=this.words=a||[];this.sigBytes=c!=p?c:4*a.length},toString:function(a){return(a||v).stringify(this)},concat:function(a){var c=this.words,e=a.words,j=this.sigBytes;a=a.sigBytes;this.clamp();if(j%4)for(var k=0;k>>2]|=(e[k>>>2]>>>24-8*(k%4)&255)<<24-8*((j+k)%4);else if(65535>>2]=e[k>>>2];else c.push.apply(c,e);this.sigBytes+=a;return this},clamp:function(){var a=this.words,c=this.sigBytes;a[c>>>2]&=4294967295<< - 32-8*(c%4);a.length=u.ceil(c/4)},clone:function(){var a=t.clone.call(this);a.words=this.words.slice(0);return a},random:function(a){for(var c=[],e=0;e>>2]>>>24-8*(j%4)&255;e.push((k>>>4).toString(16));e.push((k&15).toString(16))}return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j>>3]|=parseInt(a.substr(j, - 2),16)<<24-4*(j%8);return new r.init(e,c/2)}},b=w.Latin1={stringify:function(a){var c=a.words;a=a.sigBytes;for(var e=[],j=0;j>>2]>>>24-8*(j%4)&255));return e.join("")},parse:function(a){for(var c=a.length,e=[],j=0;j>>2]|=(a.charCodeAt(j)&255)<<24-8*(j%4);return new r.init(e,c)}},x=w.Utf8={stringify:function(a){try{return decodeURIComponent(escape(b.stringify(a)))}catch(c){throw Error("Malformed UTF-8 data");}},parse:function(a){return b.parse(unescape(encodeURIComponent(a)))}}, - q=l.BufferedBlockAlgorithm=t.extend({reset:function(){this._data=new r.init;this._nDataBytes=0},_append:function(a){"string"==typeof a&&(a=x.parse(a));this._data.concat(a);this._nDataBytes+=a.sigBytes},_process:function(a){var c=this._data,e=c.words,j=c.sigBytes,k=this.blockSize,b=j/(4*k),b=a?u.ceil(b):u.max((b|0)-this._minBufferSize,0);a=b*k;j=u.min(4*a,j);if(a){for(var q=0;q>>2]>>>24-8*(r%4)&255)<<16|(l[r+1>>>2]>>>24-8*((r+1)%4)&255)<<8|l[r+2>>>2]>>>24-8*((r+2)%4)&255,v=0;4>v&&r+0.75*v>>6*(3-v)&63));if(l=t.charAt(64))for(;d.length%4;)d.push(l);return d.join("")},parse:function(d){var l=d.length,s=this._map,t=s.charAt(64);t&&(t=d.indexOf(t),-1!=t&&(l=t));for(var t=[],r=0,w=0;w< - l;w++)if(w%4){var v=s.indexOf(d.charAt(w-1))<<2*(w%4),b=s.indexOf(d.charAt(w))>>>6-2*(w%4);t[r>>>2]|=(v|b)<<24-8*(r%4);r++}return p.create(t,r)},_map:"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/="}})(); - (function(u){function p(b,n,a,c,e,j,k){b=b+(n&a|~n&c)+e+k;return(b<>>32-j)+n}function d(b,n,a,c,e,j,k){b=b+(n&c|a&~c)+e+k;return(b<>>32-j)+n}function l(b,n,a,c,e,j,k){b=b+(n^a^c)+e+k;return(b<>>32-j)+n}function s(b,n,a,c,e,j,k){b=b+(a^(n|~c))+e+k;return(b<>>32-j)+n}for(var t=CryptoJS,r=t.lib,w=r.WordArray,v=r.Hasher,r=t.algo,b=[],x=0;64>x;x++)b[x]=4294967296*u.abs(u.sin(x+1))|0;r=r.MD5=v.extend({_doReset:function(){this._hash=new w.init([1732584193,4023233417,2562383102,271733878])}, - _doProcessBlock:function(q,n){for(var a=0;16>a;a++){var c=n+a,e=q[c];q[c]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360}var a=this._hash.words,c=q[n+0],e=q[n+1],j=q[n+2],k=q[n+3],z=q[n+4],r=q[n+5],t=q[n+6],w=q[n+7],v=q[n+8],A=q[n+9],B=q[n+10],C=q[n+11],u=q[n+12],D=q[n+13],E=q[n+14],x=q[n+15],f=a[0],m=a[1],g=a[2],h=a[3],f=p(f,m,g,h,c,7,b[0]),h=p(h,f,m,g,e,12,b[1]),g=p(g,h,f,m,j,17,b[2]),m=p(m,g,h,f,k,22,b[3]),f=p(f,m,g,h,z,7,b[4]),h=p(h,f,m,g,r,12,b[5]),g=p(g,h,f,m,t,17,b[6]),m=p(m,g,h,f,w,22,b[7]), - f=p(f,m,g,h,v,7,b[8]),h=p(h,f,m,g,A,12,b[9]),g=p(g,h,f,m,B,17,b[10]),m=p(m,g,h,f,C,22,b[11]),f=p(f,m,g,h,u,7,b[12]),h=p(h,f,m,g,D,12,b[13]),g=p(g,h,f,m,E,17,b[14]),m=p(m,g,h,f,x,22,b[15]),f=d(f,m,g,h,e,5,b[16]),h=d(h,f,m,g,t,9,b[17]),g=d(g,h,f,m,C,14,b[18]),m=d(m,g,h,f,c,20,b[19]),f=d(f,m,g,h,r,5,b[20]),h=d(h,f,m,g,B,9,b[21]),g=d(g,h,f,m,x,14,b[22]),m=d(m,g,h,f,z,20,b[23]),f=d(f,m,g,h,A,5,b[24]),h=d(h,f,m,g,E,9,b[25]),g=d(g,h,f,m,k,14,b[26]),m=d(m,g,h,f,v,20,b[27]),f=d(f,m,g,h,D,5,b[28]),h=d(h,f, - m,g,j,9,b[29]),g=d(g,h,f,m,w,14,b[30]),m=d(m,g,h,f,u,20,b[31]),f=l(f,m,g,h,r,4,b[32]),h=l(h,f,m,g,v,11,b[33]),g=l(g,h,f,m,C,16,b[34]),m=l(m,g,h,f,E,23,b[35]),f=l(f,m,g,h,e,4,b[36]),h=l(h,f,m,g,z,11,b[37]),g=l(g,h,f,m,w,16,b[38]),m=l(m,g,h,f,B,23,b[39]),f=l(f,m,g,h,D,4,b[40]),h=l(h,f,m,g,c,11,b[41]),g=l(g,h,f,m,k,16,b[42]),m=l(m,g,h,f,t,23,b[43]),f=l(f,m,g,h,A,4,b[44]),h=l(h,f,m,g,u,11,b[45]),g=l(g,h,f,m,x,16,b[46]),m=l(m,g,h,f,j,23,b[47]),f=s(f,m,g,h,c,6,b[48]),h=s(h,f,m,g,w,10,b[49]),g=s(g,h,f,m, - E,15,b[50]),m=s(m,g,h,f,r,21,b[51]),f=s(f,m,g,h,u,6,b[52]),h=s(h,f,m,g,k,10,b[53]),g=s(g,h,f,m,B,15,b[54]),m=s(m,g,h,f,e,21,b[55]),f=s(f,m,g,h,v,6,b[56]),h=s(h,f,m,g,x,10,b[57]),g=s(g,h,f,m,t,15,b[58]),m=s(m,g,h,f,D,21,b[59]),f=s(f,m,g,h,z,6,b[60]),h=s(h,f,m,g,C,10,b[61]),g=s(g,h,f,m,j,15,b[62]),m=s(m,g,h,f,A,21,b[63]);a[0]=a[0]+f|0;a[1]=a[1]+m|0;a[2]=a[2]+g|0;a[3]=a[3]+h|0},_doFinalize:function(){var b=this._data,n=b.words,a=8*this._nDataBytes,c=8*b.sigBytes;n[c>>>5]|=128<<24-c%32;var e=u.floor(a/ - 4294967296);n[(c+64>>>9<<4)+15]=(e<<8|e>>>24)&16711935|(e<<24|e>>>8)&4278255360;n[(c+64>>>9<<4)+14]=(a<<8|a>>>24)&16711935|(a<<24|a>>>8)&4278255360;b.sigBytes=4*(n.length+1);this._process();b=this._hash;n=b.words;for(a=0;4>a;a++)c=n[a],n[a]=(c<<8|c>>>24)&16711935|(c<<24|c>>>8)&4278255360;return b},clone:function(){var b=v.clone.call(this);b._hash=this._hash.clone();return b}});t.MD5=v._createHelper(r);t.HmacMD5=v._createHmacHelper(r)})(Math); - (function(){var u=CryptoJS,p=u.lib,d=p.Base,l=p.WordArray,p=u.algo,s=p.EvpKDF=d.extend({cfg:d.extend({keySize:4,hasher:p.MD5,iterations:1}),init:function(d){this.cfg=this.cfg.extend(d)},compute:function(d,r){for(var p=this.cfg,s=p.hasher.create(),b=l.create(),u=b.words,q=p.keySize,p=p.iterations;u.length>>2]&255}};d.BlockCipher=v.extend({cfg:v.cfg.extend({mode:b,padding:q}),reset:function(){v.reset.call(this);var a=this.cfg,b=a.iv,a=a.mode;if(this._xformMode==this._ENC_XFORM_MODE)var c=a.createEncryptor;else c=a.createDecryptor,this._minBufferSize=1;this._mode=c.call(a, - this,b&&b.words)},_doProcessBlock:function(a,b){this._mode.processBlock(a,b)},_doFinalize:function(){var a=this.cfg.padding;if(this._xformMode==this._ENC_XFORM_MODE){a.pad(this._data,this.blockSize);var b=this._process(!0)}else b=this._process(!0),a.unpad(b);return b},blockSize:4});var n=d.CipherParams=l.extend({init:function(a){this.mixIn(a)},toString:function(a){return(a||this.formatter).stringify(this)}}),b=(p.format={}).OpenSSL={stringify:function(a){var b=a.ciphertext;a=a.salt;return(a?s.create([1398893684, - 1701076831]).concat(a).concat(b):b).toString(r)},parse:function(a){a=r.parse(a);var b=a.words;if(1398893684==b[0]&&1701076831==b[1]){var c=s.create(b.slice(2,4));b.splice(0,4);a.sigBytes-=16}return n.create({ciphertext:a,salt:c})}},a=d.SerializableCipher=l.extend({cfg:l.extend({format:b}),encrypt:function(a,b,c,d){d=this.cfg.extend(d);var l=a.createEncryptor(c,d);b=l.finalize(b);l=l.cfg;return n.create({ciphertext:b,key:c,iv:l.iv,algorithm:a,mode:l.mode,padding:l.padding,blockSize:a.blockSize,formatter:d.format})}, - decrypt:function(a,b,c,d){d=this.cfg.extend(d);b=this._parse(b,d.format);return a.createDecryptor(c,d).finalize(b.ciphertext)},_parse:function(a,b){return"string"==typeof a?b.parse(a,this):a}}),p=(p.kdf={}).OpenSSL={execute:function(a,b,c,d){d||(d=s.random(8));a=w.create({keySize:b+c}).compute(a,d);c=s.create(a.words.slice(b),4*c);a.sigBytes=4*b;return n.create({key:a,iv:c,salt:d})}},c=d.PasswordBasedCipher=a.extend({cfg:a.cfg.extend({kdf:p}),encrypt:function(b,c,d,l){l=this.cfg.extend(l);d=l.kdf.execute(d, - b.keySize,b.ivSize);l.iv=d.iv;b=a.encrypt.call(this,b,c,d.key,l);b.mixIn(d);return b},decrypt:function(b,c,d,l){l=this.cfg.extend(l);c=this._parse(c,l.format);d=l.kdf.execute(d,b.keySize,b.ivSize,c.salt);l.iv=d.iv;return a.decrypt.call(this,b,c,d.key,l)}})}(); - (function(){for(var u=CryptoJS,p=u.lib.BlockCipher,d=u.algo,l=[],s=[],t=[],r=[],w=[],v=[],b=[],x=[],q=[],n=[],a=[],c=0;256>c;c++)a[c]=128>c?c<<1:c<<1^283;for(var e=0,j=0,c=0;256>c;c++){var k=j^j<<1^j<<2^j<<3^j<<4,k=k>>>8^k&255^99;l[e]=k;s[k]=e;var z=a[e],F=a[z],G=a[F],y=257*a[k]^16843008*k;t[e]=y<<24|y>>>8;r[e]=y<<16|y>>>16;w[e]=y<<8|y>>>24;v[e]=y;y=16843009*G^65537*F^257*z^16843008*e;b[k]=y<<24|y>>>8;x[k]=y<<16|y>>>16;q[k]=y<<8|y>>>24;n[k]=y;e?(e=z^a[a[a[G^z]]],j^=a[a[j]]):e=j=1}var H=[0,1,2,4,8, - 16,32,64,128,27,54],d=d.AES=p.extend({_doReset:function(){for(var a=this._key,c=a.words,d=a.sigBytes/4,a=4*((this._nRounds=d+6)+1),e=this._keySchedule=[],j=0;j>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255]):(k=k<<8|k>>>24,k=l[k>>>24]<<24|l[k>>>16&255]<<16|l[k>>>8&255]<<8|l[k&255],k^=H[j/d|0]<<24);e[j]=e[j-d]^k}c=this._invKeySchedule=[];for(d=0;dd||4>=j?k:b[l[k>>>24]]^x[l[k>>>16&255]]^q[l[k>>> - 8&255]]^n[l[k&255]]},encryptBlock:function(a,b){this._doCryptBlock(a,b,this._keySchedule,t,r,w,v,l)},decryptBlock:function(a,c){var d=a[c+1];a[c+1]=a[c+3];a[c+3]=d;this._doCryptBlock(a,c,this._invKeySchedule,b,x,q,n,s);d=a[c+1];a[c+1]=a[c+3];a[c+3]=d},_doCryptBlock:function(a,b,c,d,e,j,l,f){for(var m=this._nRounds,g=a[b]^c[0],h=a[b+1]^c[1],k=a[b+2]^c[2],n=a[b+3]^c[3],p=4,r=1;r>>24]^e[h>>>16&255]^j[k>>>8&255]^l[n&255]^c[p++],s=d[h>>>24]^e[k>>>16&255]^j[n>>>8&255]^l[g&255]^c[p++],t= - d[k>>>24]^e[n>>>16&255]^j[g>>>8&255]^l[h&255]^c[p++],n=d[n>>>24]^e[g>>>16&255]^j[h>>>8&255]^l[k&255]^c[p++],g=q,h=s,k=t;q=(f[g>>>24]<<24|f[h>>>16&255]<<16|f[k>>>8&255]<<8|f[n&255])^c[p++];s=(f[h>>>24]<<24|f[k>>>16&255]<<16|f[n>>>8&255]<<8|f[g&255])^c[p++];t=(f[k>>>24]<<24|f[n>>>16&255]<<16|f[g>>>8&255]<<8|f[h&255])^c[p++];n=(f[n>>>24]<<24|f[g>>>16&255]<<16|f[h>>>8&255]<<8|f[k&255])^c[p++];a[b]=q;a[b+1]=s;a[b+2]=t;a[b+3]=n},keySize:8});u.AES=p._createHelper(d)})(); - /* eslint-enable */ - /* ====================== ./NewgroundsIO-JS/src/NewgroundsIO/Core.js ====================== */ + var CryptoJS = + CryptoJS || + (function (u, p) { + var d = {}, + l = (d.lib = {}), + s = function () {}, + t = (l.Base = { + extend: function (a) { + s.prototype = this; + var c = new s(); + a && c.mixIn(a); + c.hasOwnProperty("init") || + (c.init = function () { + c.$super.init.apply(this, arguments); + }); + c.init.prototype = c; + c.$super = this; + return c; + }, + create: function () { + var a = this.extend(); + a.init.apply(a, arguments); + return a; + }, + init: function () {}, + mixIn: function (a) { + for (var c in a) a.hasOwnProperty(c) && (this[c] = a[c]); + a.hasOwnProperty("toString") && (this.toString = a.toString); + }, + clone: function () { + return this.init.prototype.extend(this); + }, + }), + r = (l.WordArray = t.extend({ + init: function (a, c) { + a = this.words = a || []; + this.sigBytes = c != p ? c : 4 * a.length; + }, + toString: function (a) { + return (a || v).stringify(this); + }, + concat: function (a) { + var c = this.words, + e = a.words, + j = this.sigBytes; + a = a.sigBytes; + this.clamp(); + if (j % 4) + for (var k = 0; k < a; k++) + c[(j + k) >>> 2] |= + ((e[k >>> 2] >>> (24 - 8 * (k % 4))) & 255) << + (24 - 8 * ((j + k) % 4)); + else if (65535 < e.length) + for (k = 0; k < a; k += 4) c[(j + k) >>> 2] = e[k >>> 2]; + else c.push.apply(c, e); + this.sigBytes += a; + return this; + }, + clamp: function () { + var a = this.words, + c = this.sigBytes; + a[c >>> 2] &= 4294967295 << (32 - 8 * (c % 4)); + a.length = u.ceil(c / 4); + }, + clone: function () { + var a = t.clone.call(this); + a.words = this.words.slice(0); + return a; + }, + random: function (a) { + for (var c = [], e = 0; e < a; e += 4) + c.push((4294967296 * u.random()) | 0); + return new r.init(c, a); + }, + })), + w = (d.enc = {}), + v = (w.Hex = { + stringify: function (a) { + var c = a.words; + a = a.sigBytes; + for (var e = [], j = 0; j < a; j++) { + var k = (c[j >>> 2] >>> (24 - 8 * (j % 4))) & 255; + e.push((k >>> 4).toString(16)); + e.push((k & 15).toString(16)); + } + return e.join(""); + }, + parse: function (a) { + for (var c = a.length, e = [], j = 0; j < c; j += 2) + e[j >>> 3] |= parseInt(a.substr(j, 2), 16) << (24 - 4 * (j % 8)); + return new r.init(e, c / 2); + }, + }), + b = (w.Latin1 = { + stringify: function (a) { + var c = a.words; + a = a.sigBytes; + for (var e = [], j = 0; j < a; j++) + e.push( + String.fromCharCode((c[j >>> 2] >>> (24 - 8 * (j % 4))) & 255) + ); + return e.join(""); + }, + parse: function (a) { + for (var c = a.length, e = [], j = 0; j < c; j++) + e[j >>> 2] |= (a.charCodeAt(j) & 255) << (24 - 8 * (j % 4)); + return new r.init(e, c); + }, + }), + x = (w.Utf8 = { + stringify: function (a) { + try { + return decodeURIComponent(escape(b.stringify(a))); + } catch (c) { + throw Error("Malformed UTF-8 data"); + } + }, + parse: function (a) { + return b.parse(unescape(encodeURIComponent(a))); + }, + }), + q = (l.BufferedBlockAlgorithm = t.extend({ + reset: function () { + this._data = new r.init(); + this._nDataBytes = 0; + }, + _append: function (a) { + "string" == typeof a && (a = x.parse(a)); + this._data.concat(a); + this._nDataBytes += a.sigBytes; + }, + _process: function (a) { + var c = this._data, + e = c.words, + j = c.sigBytes, + k = this.blockSize, + b = j / (4 * k), + b = a ? u.ceil(b) : u.max((b | 0) - this._minBufferSize, 0); + a = b * k; + j = u.min(4 * a, j); + if (a) { + for (var q = 0; q < a; q += k) this._doProcessBlock(e, q); + q = e.splice(0, a); + c.sigBytes -= j; + } + return new r.init(q, j); + }, + clone: function () { + var a = t.clone.call(this); + a._data = this._data.clone(); + return a; + }, + _minBufferSize: 0, + })); + l.Hasher = q.extend({ + cfg: t.extend(), + init: function (a) { + this.cfg = this.cfg.extend(a); + this.reset(); + }, + reset: function () { + q.reset.call(this); + this._doReset(); + }, + update: function (a) { + this._append(a); + this._process(); + return this; + }, + finalize: function (a) { + a && this._append(a); + return this._doFinalize(); + }, + blockSize: 16, + _createHelper: function (a) { + return function (b, e) { + return new a.init(e).finalize(b); + }; + }, + _createHmacHelper: function (a) { + return function (b, e) { + return new n.HMAC.init(a, e).finalize(b); + }; + }, + }); + var n = (d.algo = {}); + return d; + })(Math); + (function () { + var u = CryptoJS, + p = u.lib.WordArray; + u.enc.Base64 = { + stringify: function (d) { + var l = d.words, + p = d.sigBytes, + t = this._map; + d.clamp(); + d = []; + for (var r = 0; r < p; r += 3) + for ( + var w = + (((l[r >>> 2] >>> (24 - 8 * (r % 4))) & 255) << 16) | + (((l[(r + 1) >>> 2] >>> (24 - 8 * ((r + 1) % 4))) & 255) << 8) | + ((l[(r + 2) >>> 2] >>> (24 - 8 * ((r + 2) % 4))) & 255), + v = 0; + 4 > v && r + 0.75 * v < p; + v++ + ) + d.push(t.charAt((w >>> (6 * (3 - v))) & 63)); + if ((l = t.charAt(64))) for (; d.length % 4; ) d.push(l); + return d.join(""); + }, + parse: function (d) { + var l = d.length, + s = this._map, + t = s.charAt(64); + t && ((t = d.indexOf(t)), -1 != t && (l = t)); + for (var t = [], r = 0, w = 0; w < l; w++) + if (w % 4) { + var v = s.indexOf(d.charAt(w - 1)) << (2 * (w % 4)), + b = s.indexOf(d.charAt(w)) >>> (6 - 2 * (w % 4)); + t[r >>> 2] |= (v | b) << (24 - 8 * (r % 4)); + r++; + } + return p.create(t, r); + }, + _map: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=", + }; + })(); + (function (u) { + function p(b, n, a, c, e, j, k) { + b = b + ((n & a) | (~n & c)) + e + k; + return ((b << j) | (b >>> (32 - j))) + n; + } + function d(b, n, a, c, e, j, k) { + b = b + ((n & c) | (a & ~c)) + e + k; + return ((b << j) | (b >>> (32 - j))) + n; + } + function l(b, n, a, c, e, j, k) { + b = b + (n ^ a ^ c) + e + k; + return ((b << j) | (b >>> (32 - j))) + n; + } + function s(b, n, a, c, e, j, k) { + b = b + (a ^ (n | ~c)) + e + k; + return ((b << j) | (b >>> (32 - j))) + n; + } + for ( + var t = CryptoJS, + r = t.lib, + w = r.WordArray, + v = r.Hasher, + r = t.algo, + b = [], + x = 0; + 64 > x; + x++ + ) + b[x] = (4294967296 * u.abs(u.sin(x + 1))) | 0; + r = r.MD5 = v.extend({ + _doReset: function () { + this._hash = new w.init([ + 1732584193, 4023233417, 2562383102, 271733878, + ]); + }, + _doProcessBlock: function (q, n) { + for (var a = 0; 16 > a; a++) { + var c = n + a, + e = q[c]; + q[c] = + (((e << 8) | (e >>> 24)) & 16711935) | + (((e << 24) | (e >>> 8)) & 4278255360); + } + var a = this._hash.words, + c = q[n + 0], + e = q[n + 1], + j = q[n + 2], + k = q[n + 3], + z = q[n + 4], + r = q[n + 5], + t = q[n + 6], + w = q[n + 7], + v = q[n + 8], + A = q[n + 9], + B = q[n + 10], + C = q[n + 11], + u = q[n + 12], + D = q[n + 13], + E = q[n + 14], + x = q[n + 15], + f = a[0], + m = a[1], + g = a[2], + h = a[3], + f = p(f, m, g, h, c, 7, b[0]), + h = p(h, f, m, g, e, 12, b[1]), + g = p(g, h, f, m, j, 17, b[2]), + m = p(m, g, h, f, k, 22, b[3]), + f = p(f, m, g, h, z, 7, b[4]), + h = p(h, f, m, g, r, 12, b[5]), + g = p(g, h, f, m, t, 17, b[6]), + m = p(m, g, h, f, w, 22, b[7]), + f = p(f, m, g, h, v, 7, b[8]), + h = p(h, f, m, g, A, 12, b[9]), + g = p(g, h, f, m, B, 17, b[10]), + m = p(m, g, h, f, C, 22, b[11]), + f = p(f, m, g, h, u, 7, b[12]), + h = p(h, f, m, g, D, 12, b[13]), + g = p(g, h, f, m, E, 17, b[14]), + m = p(m, g, h, f, x, 22, b[15]), + f = d(f, m, g, h, e, 5, b[16]), + h = d(h, f, m, g, t, 9, b[17]), + g = d(g, h, f, m, C, 14, b[18]), + m = d(m, g, h, f, c, 20, b[19]), + f = d(f, m, g, h, r, 5, b[20]), + h = d(h, f, m, g, B, 9, b[21]), + g = d(g, h, f, m, x, 14, b[22]), + m = d(m, g, h, f, z, 20, b[23]), + f = d(f, m, g, h, A, 5, b[24]), + h = d(h, f, m, g, E, 9, b[25]), + g = d(g, h, f, m, k, 14, b[26]), + m = d(m, g, h, f, v, 20, b[27]), + f = d(f, m, g, h, D, 5, b[28]), + h = d(h, f, m, g, j, 9, b[29]), + g = d(g, h, f, m, w, 14, b[30]), + m = d(m, g, h, f, u, 20, b[31]), + f = l(f, m, g, h, r, 4, b[32]), + h = l(h, f, m, g, v, 11, b[33]), + g = l(g, h, f, m, C, 16, b[34]), + m = l(m, g, h, f, E, 23, b[35]), + f = l(f, m, g, h, e, 4, b[36]), + h = l(h, f, m, g, z, 11, b[37]), + g = l(g, h, f, m, w, 16, b[38]), + m = l(m, g, h, f, B, 23, b[39]), + f = l(f, m, g, h, D, 4, b[40]), + h = l(h, f, m, g, c, 11, b[41]), + g = l(g, h, f, m, k, 16, b[42]), + m = l(m, g, h, f, t, 23, b[43]), + f = l(f, m, g, h, A, 4, b[44]), + h = l(h, f, m, g, u, 11, b[45]), + g = l(g, h, f, m, x, 16, b[46]), + m = l(m, g, h, f, j, 23, b[47]), + f = s(f, m, g, h, c, 6, b[48]), + h = s(h, f, m, g, w, 10, b[49]), + g = s(g, h, f, m, E, 15, b[50]), + m = s(m, g, h, f, r, 21, b[51]), + f = s(f, m, g, h, u, 6, b[52]), + h = s(h, f, m, g, k, 10, b[53]), + g = s(g, h, f, m, B, 15, b[54]), + m = s(m, g, h, f, e, 21, b[55]), + f = s(f, m, g, h, v, 6, b[56]), + h = s(h, f, m, g, x, 10, b[57]), + g = s(g, h, f, m, t, 15, b[58]), + m = s(m, g, h, f, D, 21, b[59]), + f = s(f, m, g, h, z, 6, b[60]), + h = s(h, f, m, g, C, 10, b[61]), + g = s(g, h, f, m, j, 15, b[62]), + m = s(m, g, h, f, A, 21, b[63]); + a[0] = (a[0] + f) | 0; + a[1] = (a[1] + m) | 0; + a[2] = (a[2] + g) | 0; + a[3] = (a[3] + h) | 0; + }, + _doFinalize: function () { + var b = this._data, + n = b.words, + a = 8 * this._nDataBytes, + c = 8 * b.sigBytes; + n[c >>> 5] |= 128 << (24 - (c % 32)); + var e = u.floor(a / 4294967296); + n[(((c + 64) >>> 9) << 4) + 15] = + (((e << 8) | (e >>> 24)) & 16711935) | + (((e << 24) | (e >>> 8)) & 4278255360); + n[(((c + 64) >>> 9) << 4) + 14] = + (((a << 8) | (a >>> 24)) & 16711935) | + (((a << 24) | (a >>> 8)) & 4278255360); + b.sigBytes = 4 * (n.length + 1); + this._process(); + b = this._hash; + n = b.words; + for (a = 0; 4 > a; a++) + (c = n[a]), + (n[a] = + (((c << 8) | (c >>> 24)) & 16711935) | + (((c << 24) | (c >>> 8)) & 4278255360)); + return b; + }, + clone: function () { + var b = v.clone.call(this); + b._hash = this._hash.clone(); + return b; + }, + }); + t.MD5 = v._createHelper(r); + t.HmacMD5 = v._createHmacHelper(r); + })(Math); + (function () { + var u = CryptoJS, + p = u.lib, + d = p.Base, + l = p.WordArray, + p = u.algo, + s = (p.EvpKDF = d.extend({ + cfg: d.extend({ keySize: 4, hasher: p.MD5, iterations: 1 }), + init: function (d) { + this.cfg = this.cfg.extend(d); + }, + compute: function (d, r) { + for ( + var p = this.cfg, + s = p.hasher.create(), + b = l.create(), + u = b.words, + q = p.keySize, + p = p.iterations; + u.length < q; + + ) { + n && s.update(n); + var n = s.update(d).finalize(r); + s.reset(); + for (var a = 1; a < p; a++) (n = s.finalize(n)), s.reset(); + b.concat(n); + } + b.sigBytes = 4 * q; + return b; + }, + })); + u.EvpKDF = function (d, l, p) { + return s.create(p).compute(d, l); + }; + })(); + CryptoJS.lib.Cipher || + (function (u) { + var p = CryptoJS, + d = p.lib, + l = d.Base, + s = d.WordArray, + t = d.BufferedBlockAlgorithm, + r = p.enc.Base64, + w = p.algo.EvpKDF, + v = (d.Cipher = t.extend({ + cfg: l.extend(), + createEncryptor: function (e, a) { + return this.create(this._ENC_XFORM_MODE, e, a); + }, + createDecryptor: function (e, a) { + return this.create(this._DEC_XFORM_MODE, e, a); + }, + init: function (e, a, b) { + this.cfg = this.cfg.extend(b); + this._xformMode = e; + this._key = a; + this.reset(); + }, + reset: function () { + t.reset.call(this); + this._doReset(); + }, + process: function (e) { + this._append(e); + return this._process(); + }, + finalize: function (e) { + e && this._append(e); + return this._doFinalize(); + }, + keySize: 4, + ivSize: 4, + _ENC_XFORM_MODE: 1, + _DEC_XFORM_MODE: 2, + _createHelper: function (e) { + return { + encrypt: function (b, k, d) { + return ("string" == typeof k ? c : a).encrypt(e, b, k, d); + }, + decrypt: function (b, k, d) { + return ("string" == typeof k ? c : a).decrypt(e, b, k, d); + }, + }; + }, + })); + d.StreamCipher = v.extend({ + _doFinalize: function () { + return this._process(!0); + }, + blockSize: 1, + }); + var b = (p.mode = {}), + x = function (e, a, b) { + var c = this._iv; + c ? (this._iv = u) : (c = this._prevBlock); + for (var d = 0; d < b; d++) e[a + d] ^= c[d]; + }, + q = (d.BlockCipherMode = l.extend({ + createEncryptor: function (e, a) { + return this.Encryptor.create(e, a); + }, + createDecryptor: function (e, a) { + return this.Decryptor.create(e, a); + }, + init: function (e, a) { + this._cipher = e; + this._iv = a; + }, + })).extend(); + q.Encryptor = q.extend({ + processBlock: function (e, a) { + var b = this._cipher, + c = b.blockSize; + x.call(this, e, a, c); + b.encryptBlock(e, a); + this._prevBlock = e.slice(a, a + c); + }, + }); + q.Decryptor = q.extend({ + processBlock: function (e, a) { + var b = this._cipher, + c = b.blockSize, + d = e.slice(a, a + c); + b.decryptBlock(e, a); + x.call(this, e, a, c); + this._prevBlock = d; + }, + }); + b = b.CBC = q; + q = (p.pad = {}).Pkcs7 = { + pad: function (a, b) { + for ( + var c = 4 * b, + c = c - (a.sigBytes % c), + d = (c << 24) | (c << 16) | (c << 8) | c, + l = [], + n = 0; + n < c; + n += 4 + ) + l.push(d); + c = s.create(l, c); + a.concat(c); + }, + unpad: function (a) { + a.sigBytes -= a.words[(a.sigBytes - 1) >>> 2] & 255; + }, + }; + d.BlockCipher = v.extend({ + cfg: v.cfg.extend({ mode: b, padding: q }), + reset: function () { + v.reset.call(this); + var a = this.cfg, + b = a.iv, + a = a.mode; + if (this._xformMode == this._ENC_XFORM_MODE) + var c = a.createEncryptor; + else (c = a.createDecryptor), (this._minBufferSize = 1); + this._mode = c.call(a, this, b && b.words); + }, + _doProcessBlock: function (a, b) { + this._mode.processBlock(a, b); + }, + _doFinalize: function () { + var a = this.cfg.padding; + if (this._xformMode == this._ENC_XFORM_MODE) { + a.pad(this._data, this.blockSize); + var b = this._process(!0); + } else (b = this._process(!0)), a.unpad(b); + return b; + }, + blockSize: 4, + }); + var n = (d.CipherParams = l.extend({ + init: function (a) { + this.mixIn(a); + }, + toString: function (a) { + return (a || this.formatter).stringify(this); + }, + })), + b = ((p.format = {}).OpenSSL = { + stringify: function (a) { + var b = a.ciphertext; + a = a.salt; + return ( + a ? s.create([1398893684, 1701076831]).concat(a).concat(b) : b + ).toString(r); + }, + parse: function (a) { + a = r.parse(a); + var b = a.words; + if (1398893684 == b[0] && 1701076831 == b[1]) { + var c = s.create(b.slice(2, 4)); + b.splice(0, 4); + a.sigBytes -= 16; + } + return n.create({ ciphertext: a, salt: c }); + }, + }), + a = (d.SerializableCipher = l.extend({ + cfg: l.extend({ format: b }), + encrypt: function (a, b, c, d) { + d = this.cfg.extend(d); + var l = a.createEncryptor(c, d); + b = l.finalize(b); + l = l.cfg; + return n.create({ + ciphertext: b, + key: c, + iv: l.iv, + algorithm: a, + mode: l.mode, + padding: l.padding, + blockSize: a.blockSize, + formatter: d.format, + }); + }, + decrypt: function (a, b, c, d) { + d = this.cfg.extend(d); + b = this._parse(b, d.format); + return a.createDecryptor(c, d).finalize(b.ciphertext); + }, + _parse: function (a, b) { + return "string" == typeof a ? b.parse(a, this) : a; + }, + })), + p = ((p.kdf = {}).OpenSSL = { + execute: function (a, b, c, d) { + d || (d = s.random(8)); + a = w.create({ keySize: b + c }).compute(a, d); + c = s.create(a.words.slice(b), 4 * c); + a.sigBytes = 4 * b; + return n.create({ key: a, iv: c, salt: d }); + }, + }), + c = (d.PasswordBasedCipher = a.extend({ + cfg: a.cfg.extend({ kdf: p }), + encrypt: function (b, c, d, l) { + l = this.cfg.extend(l); + d = l.kdf.execute(d, b.keySize, b.ivSize); + l.iv = d.iv; + b = a.encrypt.call(this, b, c, d.key, l); + b.mixIn(d); + return b; + }, + decrypt: function (b, c, d, l) { + l = this.cfg.extend(l); + c = this._parse(c, l.format); + d = l.kdf.execute(d, b.keySize, b.ivSize, c.salt); + l.iv = d.iv; + return a.decrypt.call(this, b, c, d.key, l); + }, + })); + })(); + (function () { + for ( + var u = CryptoJS, + p = u.lib.BlockCipher, + d = u.algo, + l = [], + s = [], + t = [], + r = [], + w = [], + v = [], + b = [], + x = [], + q = [], + n = [], + a = [], + c = 0; + 256 > c; + c++ + ) + a[c] = 128 > c ? c << 1 : (c << 1) ^ 283; + for (var e = 0, j = 0, c = 0; 256 > c; c++) { + var k = j ^ (j << 1) ^ (j << 2) ^ (j << 3) ^ (j << 4), + k = (k >>> 8) ^ (k & 255) ^ 99; + l[e] = k; + s[k] = e; + var z = a[e], + F = a[z], + G = a[F], + y = (257 * a[k]) ^ (16843008 * k); + t[e] = (y << 24) | (y >>> 8); + r[e] = (y << 16) | (y >>> 16); + w[e] = (y << 8) | (y >>> 24); + v[e] = y; + y = (16843009 * G) ^ (65537 * F) ^ (257 * z) ^ (16843008 * e); + b[k] = (y << 24) | (y >>> 8); + x[k] = (y << 16) | (y >>> 16); + q[k] = (y << 8) | (y >>> 24); + n[k] = y; + e ? ((e = z ^ a[a[a[G ^ z]]]), (j ^= a[a[j]])) : (e = j = 1); + } + var H = [0, 1, 2, 4, 8, 16, 32, 64, 128, 27, 54], + d = (d.AES = p.extend({ + _doReset: function () { + for ( + var a = this._key, + c = a.words, + d = a.sigBytes / 4, + a = 4 * ((this._nRounds = d + 6) + 1), + e = (this._keySchedule = []), + j = 0; + j < a; + j++ + ) + if (j < d) e[j] = c[j]; + else { + var k = e[j - 1]; + j % d + ? 6 < d && + 4 == j % d && + (k = + (l[k >>> 24] << 24) | + (l[(k >>> 16) & 255] << 16) | + (l[(k >>> 8) & 255] << 8) | + l[k & 255]) + : ((k = (k << 8) | (k >>> 24)), + (k = + (l[k >>> 24] << 24) | + (l[(k >>> 16) & 255] << 16) | + (l[(k >>> 8) & 255] << 8) | + l[k & 255]), + (k ^= H[(j / d) | 0] << 24)); + e[j] = e[j - d] ^ k; + } + c = this._invKeySchedule = []; + for (d = 0; d < a; d++) + (j = a - d), + (k = d % 4 ? e[j] : e[j - 4]), + (c[d] = + 4 > d || 4 >= j + ? k + : b[l[k >>> 24]] ^ + x[l[(k >>> 16) & 255]] ^ + q[l[(k >>> 8) & 255]] ^ + n[l[k & 255]]); + }, + encryptBlock: function (a, b) { + this._doCryptBlock(a, b, this._keySchedule, t, r, w, v, l); + }, + decryptBlock: function (a, c) { + var d = a[c + 1]; + a[c + 1] = a[c + 3]; + a[c + 3] = d; + this._doCryptBlock(a, c, this._invKeySchedule, b, x, q, n, s); + d = a[c + 1]; + a[c + 1] = a[c + 3]; + a[c + 3] = d; + }, + _doCryptBlock: function (a, b, c, d, e, j, l, f) { + for ( + var m = this._nRounds, + g = a[b] ^ c[0], + h = a[b + 1] ^ c[1], + k = a[b + 2] ^ c[2], + n = a[b + 3] ^ c[3], + p = 4, + r = 1; + r < m; + r++ + ) + var q = + d[g >>> 24] ^ + e[(h >>> 16) & 255] ^ + j[(k >>> 8) & 255] ^ + l[n & 255] ^ + c[p++], + s = + d[h >>> 24] ^ + e[(k >>> 16) & 255] ^ + j[(n >>> 8) & 255] ^ + l[g & 255] ^ + c[p++], + t = + d[k >>> 24] ^ + e[(n >>> 16) & 255] ^ + j[(g >>> 8) & 255] ^ + l[h & 255] ^ + c[p++], + n = + d[n >>> 24] ^ + e[(g >>> 16) & 255] ^ + j[(h >>> 8) & 255] ^ + l[k & 255] ^ + c[p++], + g = q, + h = s, + k = t; + q = + ((f[g >>> 24] << 24) | + (f[(h >>> 16) & 255] << 16) | + (f[(k >>> 8) & 255] << 8) | + f[n & 255]) ^ + c[p++]; + s = + ((f[h >>> 24] << 24) | + (f[(k >>> 16) & 255] << 16) | + (f[(n >>> 8) & 255] << 8) | + f[g & 255]) ^ + c[p++]; + t = + ((f[k >>> 24] << 24) | + (f[(n >>> 16) & 255] << 16) | + (f[(g >>> 8) & 255] << 8) | + f[h & 255]) ^ + c[p++]; + n = + ((f[n >>> 24] << 24) | + (f[(g >>> 16) & 255] << 16) | + (f[(h >>> 8) & 255] << 8) | + f[k & 255]) ^ + c[p++]; + a[b] = q; + a[b + 1] = s; + a[b + 2] = t; + a[b + 3] = n; + }, + keySize: 8, + })); + u.AES = p._createHelper(d); + })(); + + /* ====================== ./NewgroundsIO-JS/src/NewgroundsIO/Core.js ====================== */ /** * NewgroundsIO Namespace @@ -1874,47 +2667,47 @@ let response = new NewgroundsIO.objects.Response(); Scratch.canFetch(this.GATEWAY_URI).then(allowed => { - if (!allowed) return callback(null); - // eslint-disable-next-line no-restricted-syntax - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - var o_return; - try { - o_return = JSON.parse(xhr.responseText); - } catch (e) { - o_return = { success: false, app_id: core.app_id }; - o_return.error = { message: String(e), code: 8002 }; - } - - let response = core._populateResponse(o_return); - - core.dispatchEvent( - new CustomEvent("serverResponse", { detail: response }) - ); - - if (callback) { - if (thisArg) callback.call(thisArg, response); - else callback(response); + if (!allowed) return callback(null); + // eslint-disable-next-line no-restricted-syntax + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + var o_return; + try { + o_return = JSON.parse(xhr.responseText); + } catch (e) { + o_return = { success: false, app_id: core.app_id }; + o_return.error = { message: String(e), code: 8002 }; + } + + let response = core._populateResponse(o_return); + + core.dispatchEvent( + new CustomEvent("serverResponse", { detail: response }) + ); + + if (callback) { + if (thisArg) callback.call(thisArg, response); + else callback(response); + } } - } - }; - - // jhax is a hack to get around JS frameworks that add a toJSON method to Array (wich breaks the native implementation). - var jhax = - typeof Array.prototype.toJSON != "undefined" - ? Array.prototype.toJSON - : null; - if (jhax) delete Array.prototype.toJSON; - - let formData = new FormData(); - formData.append("request", JSON.stringify(request)); - if (jhax) Array.prototype.toJSON = jhax; - - xhr.open("POST", this.GATEWAY_URI, true); - - xhr.send(formData); - }); + }; + + // jhax is a hack to get around JS frameworks that add a toJSON method to Array (wich breaks the native implementation). + var jhax = + typeof Array.prototype.toJSON != "undefined" + ? Array.prototype.toJSON + : null; + if (jhax) delete Array.prototype.toJSON; + + let formData = new FormData(); + formData.append("request", JSON.stringify(request)); + if (jhax) Array.prototype.toJSON = jhax; + + xhr.open("POST", this.GATEWAY_URI, true); + + xhr.send(formData); + }); } /** @@ -2568,11 +3361,11 @@ class startSession extends NewgroundsIO.BaseComponent { /** - * Constructor - * @param {object} props An object of initial properties for this instance - * @param {Boolean} props.force If true, will create a new session even if the user already has an existing one. + * Constructor + * @param {object} props An object of initial properties for this instance + * @param {Boolean} props.force If true, will create a new session even if the user already has an existing one. undefined * Note: Any previous session ids will no longer be valid if this is used. - */ + */ constructor(props) { super(); let _this = this; @@ -5232,18 +6025,18 @@ } Scratch.canFetch(this.url).then(allowed => { - if (!allowed) return callback(null); - // eslint-disable-next-line no-restricted-syntax - var xhr = new XMLHttpRequest(); - xhr.onreadystatechange = function () { - if (xhr.readyState == 4) { - if (thisArg) callback.call(thisArg, xhr.responseText); - else callback(xhr.responseText); - } - }; - xhr.open("GET", this.url, true); - xhr.send(); - }); + if (!allowed) return callback(null); + // eslint-disable-next-line no-restricted-syntax + var xhr = new XMLHttpRequest(); + xhr.onreadystatechange = function () { + if (xhr.readyState == 4) { + if (thisArg) callback.call(thisArg, xhr.responseText); + else callback(xhr.responseText); + } + }; + xhr.open("GET", this.url, true); + xhr.send(); + }); } /** @@ -6166,14 +6959,14 @@ }, this); /* - this.__ngioCore.executeComponent(endSession, function(response) { - this._onEndSession(response); - if (typeof(callback) === "function") { - if (thisArg) callback.call(thisArg, this); - else callback(this); - } - }, this); - */ + this.__ngioCore.executeComponent(endSession, function(response) { + this._onEndSession(response); + if (typeof(callback) === "function") { + if (thisArg) callback.call(thisArg, this); + else callback(this); + } + }, this); + */ } /** @@ -8227,6 +9020,7 @@ NewgroundsIO.results.ScoreBoard = {}; NewgroundsIO.results.ScoreBoard.postScore = postScore; })(); + /* eslint-enable */ let menuIco = @@ -8267,10 +9061,14 @@ } const vm = Scratch.vm; + const runtime = vm.runtime; + const url_Location = window.location.href.split("/")[2]; + let isNG = url_Location == "www.newgrounds.com" || url_Location == "uploads.ungrounded.net"; + let ConnectionStatus = "Awaiting"; let loggedIn = false; let saveCompleted = false; @@ -8318,46 +9116,53 @@ ConnectionStatus = "Illegal Host"; NGIO.loadOfficialUrl(); } + break; // user needs to log in case NGIO.STATUS_LOGIN_REQUIRED: ConnectionStatus = "Login Required"; loggedIn = false; + break; // user needs to log in case NGIO.STATUS_READY: if (NGIO.hasUser) { ConnectionStatus = "Logged In"; - userDat.logged = NGIO.hasUser; loggedIn = true; + userDat.icon = NGIO.user.icons.large; + userDat.name = NGIO.user.name; + userDat.supporter = NGIO.user.supporter; + userDat.id = NGIO.user.id; + break; } else { ConnectionStatus = "Opted Out"; loggedIn = false; + break; } - break; // user needs to log in case NGIO.STATUS_WAITING_FOR_USER: ConnectionStatus = "Awaiting"; loggedIn = false; + break; } } function onSaveComplete(slot) { saveCompleted = true; - console.log("Slot " + slot.id + " was updated"); } let scorePosted = false; + ("use strict"); class NewgroundsAPI { getInfo() { return { id: "NGIO", - name: "Newgrounds", + name: "Newgrounds!", color1: "#EB7522", color2: "#4F280E", @@ -8747,6 +9552,7 @@ onLoginSuccess() { if (!userDat.logged) { + userDat.logged = NGIO.hasUser; if (userDat.logged == true) { userDat.icon = NGIO.user.icons.large; userDat.name = NGIO.user.name; @@ -8789,7 +9595,6 @@ } connect({ gameID, code }) { - console.log("Trying to init game"); NGIO.init(gameID, code, NGOptions); //Add a hook for the connection status to Newgrounds. NGIO.getConnectionStatus(statusReport); @@ -8821,7 +9626,7 @@ } getUserDat({ datType }) { - if (isNG && userDat.logged) { + if (isNG && loggedIn == true) { if (datType == "MedalScore") { return NGIO.medalScore; } else { @@ -8854,7 +9659,6 @@ saveData({ Data, Slot }) { if (isNG) { - console.log("saving " + Data + " to slot " + Slot); NGIO.setSaveSlotData(Slot, Data, onSaveComplete); } } @@ -8874,7 +9678,7 @@ return saveDat; }); } else { - return "Nothing. Newgrounds can't return Data!"; + return "Not Newgrounds can't return Data!"; } } @@ -8889,10 +9693,9 @@ //Medals unlockMedal({ medalID }) { - NGIO.getConnectionStatus(statusReport); - if (isNG && userDat.logged) { + if (isNG && loggedIn == true) { + NGIO.getConnectionStatus(statusReport); if (loggedIn) { - console.log("NGIO Tick"); NGIO.keepSessionAlive(); } NGIO.unlockMedal(medalID); @@ -8900,10 +9703,10 @@ } isMedalUnlocked({ medalID }) { - NGIO.getConnectionStatus(statusReport); - if (isNG && userDat.logged) { + if (isNG && loggedIn == true) { + NGIO.getConnectionStatus(statusReport); if (loggedIn) { - return NGIO.getMedal(medalID).unlocked; + NGIO.keepSessionAlive(); } return NGIO.getMedal(medalID).unlocked; } else { @@ -8914,10 +9717,8 @@ //Keep Session alive if game is connected. setInterval(() => { - userDat.logged = NGIO.hasUser; NGIO.getConnectionStatus(statusReport); if (loggedIn) { - console.log("NGIO Tick"); NGIO.keepSessionAlive(); } }, 1500); From 8ea952801960254cc54347ba6584662a8956fa05 Mon Sep 17 00:00:00 2001 From: CST1229 <68464103+CST1229@users.noreply.github.com> Date: Fri, 28 Jul 2023 05:06:37 +0200 Subject: [PATCH 30/32] cloudlink: add docsURI (#783) --- extensions/cloudlink.js | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/cloudlink.js b/extensions/cloudlink.js index 03ac77a836..618b1ae0bf 100644 --- a/extensions/cloudlink.js +++ b/extensions/cloudlink.js @@ -153,6 +153,7 @@ class CloudLink { "name": 'CloudLink', "blockIconURI": this.cl_block, "menuIconURI": this.cl_icon, + "docsURI": "https://hackmd.io/@MikeDEV/HJiNYwOfo", "blocks": [ { "opcode": 'returnGlobalData', From 633f02a5d9b076205e4b5fe7243f5650c573b07e Mon Sep 17 00:00:00 2001 From: GarboMuffin Date: Fri, 28 Jul 2023 19:31:11 -0500 Subject: [PATCH 31/32] Update CONTRIBUTING.md (#797) --- CONTRIBUTING.md | 123 ++++++++++++++++++++++-------------------------- 1 file changed, 57 insertions(+), 66 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 96b706319c..736f0cdef8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,6 +1,6 @@ # Contributing extensions -Before you submit extensions, please read the NEW custom extension tutorial in full: +Before you submit extensions, please read the custom extension tutorial **in full**: - https://docs.turbowarp.org/development/extensions/introduction @@ -9,77 +9,61 @@ Please pay special attention to: - Unsandboxed extensions: https://docs.turbowarp.org/development/extensions/unsandboxed - Maintaining backward compatibility: https://docs.turbowarp.org/development/extensions/compatibility - A better development server: https://docs.turbowarp.org/development/extensions/better-development-server + - Maintaining compatibility: https://docs.turbowarp.org/development/extensions/compatibility -Pull requests that don't follow the guidelines outlined in these documents tend to take much longer to be reviewed and merged. +Read this document **in full** too. Pull requests that don't follow the guidelines will take *much* longer to be reviewed. -## Local development server +## Acceptance criteria -We recommend using our local development server: +Strictly, nothing is banned, but the following are *highly* discouraged: -```bash -# Clone the repository -git clone https://github.com/TurboWarp/extensions.git -cd extensions - -# Install dependencies -npm ci - -# Start development server -npm run dev -``` - -This starts an HTTP server on [http://localhost:8000/](http://localhost:8000/) in development mode which adds a couple of extra tools to the homepage. - -After installing npm dependencies, TypeScript aware editors such as Visual Studio Code will give you smart autocomplete suggestions for most Scratch and extension APIs based on [@turbowarp/types](https://github.com/TurboWarp/types) and [@turbowarp/types-tw](https://github.com/TurboWarp/types-tw). Note that these types are not perfect; some methods are missing or incorrect. Please report any issues you find. + - Broad "Utilities" extensions (break them up into multiple extensions, see https://github.com/TurboWarp/extensions/issues/674) + - Extensions that are very similar to existing ones (consider modifying the existing one instead) + - Novelties or one-use personal extensions (load the extension as a local file instead) + - Joke extensions (they aren't funny when they cause us to get bug reports) -If you encounter a TypeScript error, as long as you understand the error, feel free to add `// @ts-ignore`, `// @ts-expect-error`, or just ignore the error entirely. We currently do not require extensions to pass type checking. - -## Alternative development server - -If for some reason you can't set up our local development server, you can start any other HTTP server in the `extensions` folder. You won't get some of the nice things our server has, but it may be good enough. If you have Python 3 installed this is very simple: - -```bash -cd extensions -python3 -m http.server -``` +Some extensions were added before these rules existed. That doesn't mean you will be exempted too. -Note that browsers tend to aggressively cache JavaScript files that don't opt out of caching as our development server does, so you may have to do hard reloads to ensure that changes to your scripts are applied. +## Important context -## Types of extensions we accept +Every merged extension is more code that we will be expected to maintain indefinitely, even if you disappear. Remember: broken extensions mean that real projects by real people break. If the renderer is rewritten one day, we will have to ensure that extensions like Clipping and blending, RGB channels, and Augmented Reality still work. That's not a small commitment. -We strive to be tolerant of accepting almost any extension, including one-use novelty extensions or extensions that are similar to ones that already exist. +We're all volunteers who all have lives outside of Scratch extensions. Many have full time jobs or are full time students. We'll get to you as soon as we can, so please be patient. -Extensions end up in one of these categories depending on various qualities: +## Writing extensions - - Extensions that are in the repository, but not listed on the website - - Extensions that are listed on the website - - Extensions that are listed in the editor's builtin extension library +Extension source code goes in the [`extensions`](extensions) folder. For example, an extension placed at `extensions/hello-world.js` would be accessible at [http://localhost:8000/hello-world.js](http://localhost:8000/hello-world.js) using our development server. -## Writing extensions +New extensions should be added in a user folder. You can name your folder anything you want; common choices are your GitHub username or your Scratch username. If your username is `TestMuffin123`, `TestMuffin123`, `TestMuffin` and `Muffin` are all accepted -- we are very lenient about this. Do note that user folders are just for organization; other people are still allowed to edit your extension. Renaming your folder later isn't something we allow (rare exceptions, open an issue), so please get it right the first time. -Extension source code goes in the `extensions` folder. For example, an extension placed at `extensions/hello-world.js` would be accessible at [http://localhost:8000/hello-world.js](http://localhost:8000/hello-world.js). +Extensions must be self-contained. All libraries and hardcoded resources should be embedded into the extension's JavaScript file. If you include minified code, please link where to find the unminified code and include a copy of the license. -New extensions should be added in a user folder. You can name your folder your GitHub username, your Scratch username, or something else. For example, if your GitHub username is "TestMuffin", you could make a `TestMuffin` folder inside of the `extensions` folder and put your extensions inside there. You could then access a file placed at `extensions/TestMuffin/hello-world.js` at [http://localhost:8000/TestMuffin/hello-world.js](http://localhost:8000/TestMuffin/hello-world.js). +Static resources go in the `website` folder. This is where some example assets used by extensions such as fetch are placed. This is also where documentation goes for now, though we are in the process of modernizing that. -Static resources go in the `website` folder. This is where some example resources used by extensions such as fetch are placed. It works similarly to the `extensions` folder. +To add an extension to the website homepage, modify [`website/index.ejs`](website/index.ejs). See the existing entries for a template to copy. Place your extension wherever you want in the list. We will move it for you if we disagree. -Extensions must not use `eval()`, `new Function()`, untrusted `