您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
none
当前为
// ==UserScript== // @name lib:all functions // @version 1.5 // @description none // @license GPLv3 // @run-at document-start // @author You // @match *://*/* // @icon data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEgAAABICAMAAABiM0N1AAAAAXNSR0IB2cksfwAAAAlwSFlzAAAOxAAADsQBlSsOGwAAAHJQTFRFAAAAEIijAo2yAI60BYyuF4WaFIifAY6zBI2wB4usGIaZEYigIoiZCIyrE4igG4iYD4mjEomhFoedCoqpDIqnDomlBYyvE4efEYmiDYqlA42xBoytD4mkCYqqGYSUFYidC4qoC4upAo6yCoupDYqmCYur4zowOQAAACZ0Uk5TAO////9vr////1+/D/+/L+/Pf/////+f3///////H4////////+5G91rAAACgUlEQVR4nM2Y22KjIBCGidg1264liZqDadK03X3/V2wNKHMC7MpF/xthHD5mgERAqZhWhfYqH6K+Qf2qNNf625hCoFj9/gblMUi5q5jLkXLCKudgyiRm0FMK82cWJp1fLbV5VmvJbCIc0GCYaFqqlDJgADdBjncqAXYobm1xh72aFMflbysteFfdy2Yi1XGOm5HGBzQ1dq7TzEoxjeNTjQZb7VA3e1c7+ImgasAgQ9+xusNVNZIo5xmOMgihIS2PbCQIiHEUdTvhxCcS/kPomfFI2zHy2PkWmA6aNatIJpKFJyekyy02xh5Y3DI9T4aOT6VhIUrsNTFp1pf79Z4SIIVDegl6IJO6cHiL/GimIZDhgTu/BlYWCQzHMl0zBWT/T3KAhtxOuUB9FtBrpsz0RV4xsjHmW+UCaffcSy/5viMGer0/6HdFNMZBq/vjJL38H9Dqx4Fuy0Em12DbZy+9pGtiDijbglwAehyj11n0tRD3WUBm+lwulE/8h4BuA+iWAQQnteg2Xm63WQLTpnMnpjdge0Mgu/GRPsV4xdjQ94Lfi624fabhDkfUqIKNrM64Q837v8yL0prasepCgrtvw1sJpoqanGEX7b5mQboNW8eawXaWXTMfMGxub472hzWzHSn6Sg2G9+6TAyRruE71s+zAzjWaknoyJCQzwxrghH2k5FDT4eqWunuNxyN9QCGcxVod5oADbYnIUkDTGZEf1xDJnSFteQ3KdsT8zYDMQXcHxsevcLH1TrsABzkNPyA/L7b0jg704viMMlpQI96WsHknCt/3YH0kOEo9zcGkwrFK39ck72rmoehmKqo2RKlilzSy/nJKEV45CT38myJp456fezktHjN5aeMAAAAASUVORK5CYII= // @grant none // @namespace https://gf.qytechs.cn/users/1184528 // ==/UserScript== ;(async function () { const { savelib } = loadlib("libloader", "allfuncs.js") const proxy_set = new WeakSet() const oldproxy = Proxy window.Proxy = new Proxy(oldproxy, { construct(_target, args) { const proxy = new oldproxy(...args) proxy_set.add(proxy) return proxy }, }) const isproxy = function (proxy) { return proxy_set.has(proxy) } Object.keys(console).forEach((e) => { window[e] = function (...args) { var z = [] let pi = 0 args.forEach((y) => { let rand = `{${pi}}${a().randstr().val}` while (true) { if (isa(y)) { z.push("function_chain >") y = y.val continue } else if (a(y).gettype("promise").val) { pi++ y.then((...args) => window[e]("RESOLVED - " + rand, ...args)).catch( (...args) => window[e]("REJECTED - " + rand, ...args) ) y = "PROMISE - " + rand continue } z.push(y) break } }) if (e == "error") debugger console[e](...z) return z } }) const warn = console.warn.bind(window) const log = console.log.bind(window) const error = console.error.bind(window) const time = console.time.bind(window) const timeEnd = console.timeEnd.bind(window) // Object.assign(window, console) // if (window.a) error("allfuncs allready exists") var getvm = function () { const oldBind = Function.prototype.bind Function.prototype.bind = function (...args) { if ( args[0] && args[0]?.hasOwnProperty?.("editingTarget") && args[0].hasOwnProperty("runtime") ) { Function.prototype.bind = oldBind savelib("scratch", { vm: args[0] }) } return oldBind.apply(this, args) } } getvm() function isa(inp1) { return ( inp1?.[Math.random()]?.name === "function_chain" || inp1?.name === "function_chain" ) } function noa(inp1) { return isa(inp1) ? inp1.val : inp1 } const blank = {} const isstrict = {} const ischaining = {} function a(inp1, ic, temparr) { if (ic !== ischaining) { temparr = [] } inp1 = noa(inp1) return new Proxy( {}, { set(_obj, _prop, _val) {}, get(_obj, prop) { if (prop == Symbol.toStringTag) { warn(Symbol.toStringTag) return "testing" } if (prop == Symbol.iterator) { switch (a(inp1).gettype().val) { case "string": return function* () { for (var i in inp1.split("")) yield inp1[i] } case "number": return function* () { for (var i in String(inp1).split("")) yield inp1[i] } case "array": return function* () { for (var i in inp1) yield inp1[i] } case "object": return function* () { for (var i in Object.entries(inp1)) yield inp1[i] } default: return function* () { yield inp1 } } } if (prop == Symbol.toPrimitive) { return function (hint) { switch (hint) { case "number": if (Number(inp1) != inp1) error(`"${inp1}" is not a number or is nan`, inp1) return Number(inp1) case "string": if (a(inp1).gettype(["array", "object"]).val) return JSON.stringify(inp1) return String(inp1) case "default": if (a(inp1).gettype("string").val) if (String(Number(inp1)) == inp1) return Number(inp1) else return String(inp1) if (a(inp1).gettype(["array", "object"]).val) return JSON.stringify(inp1) if (a(inp1).gettype(["undefined", "null", "nan"])) return String(inp1) } error(prop, hint) return hint } } if (typeof prop == "symbol") log(prop) if (["end", "out", "ret", "done", "value", "val"].includes(prop)) { if (temparr.length) { var x = [...temparr] temparr = [] return x } return inp1 } if (prop == "allfuncs") return new Proxy(allfuncs, { set(_a, s) { throw new Error( `you can't overwrite property "${s}" on "allfuncs". if you are trying to add a new function use allfuncs.new(function_name, function, folders)` ) }, deleteProperty(_a, s) { throw new Error( `you can't delete property "${s}" on "allfuncs".` ) }, }) if (prop == "push") return new Proxy( {}, { get(_a, s) { temparr.push(inp1[s]) return a(inp1, ischaining, temparr) }, } ) if (prop == "get") return new Proxy( {}, { get(_a, s) { return a(inp1[s], ischaining, temparr) }, } ) if (prop == "set") return new Proxy( {}, { get(_a, s) { return function (val) { inp1[s] = val return a(inp1, ischaining, temparr) } }, } ) if (prop == "run") return new Proxy( {}, { get(_a, s) { if (s == "same") { return new Proxy( {}, { get(_a, s) { return function (...args) { var inp = inp1 inp1[s](...args) return a(inp, ischaining, temparr) } }, } ) } else return function (...args) { return a(inp1[s](...args), ischaining, temparr) } }, } ) const { gettype } = allfuncs const function_chain = function (...rest) { if (gettype(allfuncs[prop]) !== "function") if (!gettype(inp1, ["undefined", "null", "nan"])) if (gettype(Object.getPrototypeOf(inp1)[prop], "function")) return a( Object.getPrototypeOf(inp1)[prop].call(inp1, ...rest) ) else throw new Error(`"${prop}" is not a function`) var inps = inp1 === blank ? rest : [inp1, ...rest] var ret = allfuncs[prop](...inps) if ( gettype(ret, "array") && inp1?.strictargs?.[0] === isstrict && ret?.strictargs?.[0] !== isstrict ) switch (inp1.strictargs[1]) { case "object": ret = strictobj( inp1.strictargs[2], inp1.strictargs[3], ret, inp1.strictargs[5] ) break case "array": ret = strictarr( inp1.strictargs[2], inp1.strictargs[3], ret, inp1.strictargs[5] ) break } return a(ret) } var temp = {} Object.assign(temp, allfuncs[prop]?.function ?? {}) Object.assign(temp, allfuncs[prop]) Object.keys(temp).forEach((e) => { let func = temp[e] function_chain[e] = function (...args) { return a(func(...args)) } }) if (gettype(allfuncs[prop], "function")) function_chain.inputs = getprops(allfuncs[prop]) function_chain.same = function (...args) { var inp = inp1 a(inp1, ischaining, temparr)[prop](...args) return a(inp, ischaining, temparr) } function_chain.run = function (obj) { var m = [...function_chain.inputs] m = m.vars.map((e, i) => i == 0 ? e.var in obj ? obj[e.var] : inp1 == blank ? undefined : inp1 : obj[e.var] ) var ret = allfuncs[prop](...m) if (inp1?.strictargs[0] === isstrict) switch (inp1.strictargs[1]) { case "object": ret = strictobj( inp1.strictargs[2], inp1.strictargs[3], ret, inp1.strictargs[5] ) break case "array": ret = strictarr( inp1.strictargs[2], inp1.strictargs[3], ret, inp1.strictargs[5] ) break } var shouldret = getprops(allfuncs[prop]).return if ( shouldret .split("|") .find((type) => type == "any" || type == gettype(ret)) ) return a(ret) throw new Error( `the function "${prop}" returned a type of "${gettype( ret )}",\nwhich doesn't match type of "${shouldret}"` ) } return function_chain }, } ) } function expandederror( //error obj //object ) { error(obj) return Error(obj.message) } const strictfunction = function ( //any func, //function|class name, //string|none notrequired //boolean|none ) { if (notrequired) { if (getprops(func).broken) { warn("the function is missing type data") return func } } else { if (getprops(func).broken) { error(getprops(func)) throw new Error(`the function doesn't have the required type data`) } } var temp = function (...args) { var vars = getprops(func).vars if ( vars.filter( (e) => !( e.type.includes("?") || e.type.split("|").includes("none") || e.type.split("|").includes("undefined") ) ).length > args.length ) { error( `function [${ Object.getPrototypeOf(func).name || name || "unknown" }] - requires ${ vars.filter((e) => !e.type.includes("?")).length } arguments but only found ${args.length}` ) } vars.length = args.length vars.map(function (thing, index) { if (thing.type) { if (index > args.length - 1) { if (thing.type.includes("?") || thing.type.includes("none")) return true throw expandederror({ message: `function [${ Object.getPrototypeOf(func).name || name || "unknown" }] - input "${thing.var}" is not optional`, function_name: Object.getPrototypeOf(func).name || name || "unknown", function: func, values: args, function_string: String(func), }) } if ( thing.type.split("|").includes("array") && a(args[index]).gettype("htmlcollection").val ) { args[index] = [...args[index]] } if ( thing.type .split("|") .find( (type) => (!!args[index] === true && type == "true") || (!!args[index] === false && type == "false") || (a(args[index]).gettype(["null", "undefined", "nan"]).val && type == "none") || type == "any" || a(args[index]).gettype(type).val ) ) return true else if ( thing.type.split("|").includes("elements") && a(args[index]).toelem().gettype("array").val ) { args[index] = a(args[index]).toelem().val if ( thing.type.split("|").includes("element") && args[index].length === 1 ) args[index] = args[index][0] return true } else if ( thing.type.split("|").includes("element") && a(args[index]).toelem(true).gettype("element").val ) args[index] = a(args[index]).toelem(true).val if ( thing.type.split("|").includes("element") && a(args[index]).toelem(true).gettype("element").val ) { args[index] = a(args[index]).toelem(true).val return true } else { throw expandederror({ message: `function [${ Object.getPrototypeOf(func).name || name || "unknown" }] - in "${thing.var}", the input of "${ args[index] }" is a type of "${ a(args[index]).gettype().val }", which doesn't match required type of "${thing.type}"`, function_name: Object.getPrototypeOf(func).name || name || "unknown", function: func, function_string: String(func), }) } } else return true }) var shouldret = getprops(func).return if (a(func).gettype("function").val) { var ret = func( ...args //...getprops(func).vars.map((_e, index) => args[index]) ) } else { var ret = new func(...args) } // if (args[0]?.strictargs?.[0] === isstrict) // switch (args[0].strictargs[1]) { // case "object": // ret = strictobj( // args[0].strictargs[2], // args[0].strictargs[3], // ret, // args[0].strictargs[5] // ) // break // case "array": // ret = strictarr( // args[0].strictargs[2], // args[0].strictargs[3], // ret, // args[0].strictargs[5] // ) // break // } if ( shouldret .split("|") .find( (type) => (!!ret === true && type == "true") || (!!ret === false && type == "false") || (["null", "undefined", "nan"].includes(a(ret).gettype().val) && type == "none") || type == "any" || a(ret).gettype(type).val ) ) return ret throw expandederror({ message: `the function [${ Object.getPrototypeOf(func).name || name || "unknown" }] returned a type of "${ a(ret).gettype().val }", which doesn't match type of "${shouldret}"`, function_name: Object.getPrototypeOf(func).name || name || "unknown", function: func, function_string: String(func), }) } temp.function = func return temp } const getprops = (function () { var cache = {} return function ( //array func //function ) { var test = String(func).match(/\(([^]*)/)[1] if (cache[test]) return cache[test] var arr = [] var x test = test .replaceAll(/\\./g, "") .replaceAll(/`[^]*?(?<!\\)`/g, "") .replaceAll(/'.*?(?<!\\)'/g, "") .replaceAll(/".*?(?<!\\)"/g, "") .replaceAll(/(\/\/).*|\/\*[^]*?\*(?<!\\)\//g, function (e, a) { arr.push( a ? e.replace("//", "") : e.replace(/^\/\*/, "").replace(/\*\/$/, "") ) return `\u1111${arr.length - 1}\u1111` }) .replaceAll(/\/.*?(?<!\\)\//g) var prevtest = test while (prevtest.match(/(?<![\]})])[{\[(]/)) { test = prevtest x = prevtest.match(/(?<![\]})].*?)[{\[(]/) if (!x) break var count = 0 var i = 0 var start = x.index var end = x.index while (i++ < 40) { if (/[\[{(]/.test(x[0])) count++ else count-- if (count == 0) break test = test.slice(x.index + 1) x = test.match(/[{\[(\])}]/) end += x.index + 1 } prevtest = prevtest.slice(0, start) + "<><><>" + prevtest.slice(end + 1) } var fualtyreturn = false var temp = { return: arr[0], vars: [ ...[ ...prevtest .match(/[^]*?(?=\))/)[0] .matchAll( /(?<=(?:,|^)[^=]*)([a-zA-Z_$][\da-zA-Z_$]*)(?:(?:[^](?![a-zA-Z_$][\da-zA-Z_$].*,|,.*[a-zA-Z_$][\da-zA-Z_$]))*?(?:\s*=\s*)?[^\u1111]*\u1111(\d+)\u1111)?/g ), ].map((e, _i) => { if (e[2] == 0) fualtyreturn = true return { var: e[1], type: arr[e[2]], } }), ], } if (fualtyreturn) temp.return = undefined temp.broken = false if (temp.return == undefined) temp.broken = true temp.vars.forEach((e) => { if (e.type === undefined) temp.broken = true }) // temp.return||='any' // temp.broken // temp.vars = temp.vars.map(e=>{return{...e, type:e.type||'any'}}) cache[String(func).match(/\(([^]*)/)[1]] = temp return temp } })() const allfuncs = { new(name, func, folder) { if (this[name]) { name += Math.random() error(name) } this[name] = name == "gettype" || name == "toelem" ? func : strictfunction(func, name, true) var arr = getprops(func) arr = [ ...arr.vars, { return: arr.return, }, ] if ( arr.map((e) => e.type || e?.return).filter((e) => typeof e !== "string") .length ) warn(name) this[name].help = arr this[name].function = func this[name].table = function () { var x = getprops(this?.function || allfuncs[name].function) var arr = {} x.vars.forEach((e) => { arr = { ...arr, ...{ [e.var]: e.type, }, } }) table({ ...arr, broken: x.broken, return: x.return, }) } if (!folder) folder = "unknown" if (folder.includes("/")) folder = folder.split("/") else if (typeof folder == "string") folder = [folder] folder.forEach((folder) => { if (!this.folders) this.folders = {} if (!this.folders[folder]) this.folders[folder] = {} this.folders[folder][name] = func this.folders[folder][name].help = arr }) this[name].folders = folder Object.defineProperty(a, "length", { //new //folders value: Object.keys(allfuncs).length - 2, }) return this[name] }, } class tween { #from #to #time #delay #loopondone #reverseondone #updatefunc = [] #donefunc = [] #active = 0 #firstfrom #firstto constructor( //object from, //number to, //number time, //number delay, //number loopondone, //boolean|none reverseondone, //boolean|none ignorefocusloss //boolean|none ) { if (typeof from == "number") { this.#from = from this.#to = to this.#time = time this.#delay = delay this.#loopondone = loopondone this.#reverseondone = reverseondone } else if (typeof from == "object") { a(from).foreach(function (key, value) { this["#" + key] = value }) } this.restart = this.restart this.onchange = this.onchange this.ondone = this.ondone this.#firstfrom = this.#from this.#firstto = this.#to const top = this if (!ignorefocusloss) { a(window).listen("blur", function () { if (!top.paused) top.paused = 1 }) a(window).listen("focus", function () { if (top.paused === 1) top.paused = false }) } if (this.#loopondone) this.#reverseondone = false this.#updatefunc = [] this.#donefunc = [] this.#go() } restart() { this.#from = this.#firstfrom this.#to = this.#firstto this.#go() } async #go() { this.#active++ var lastactive = this.#active var from = this.#from var to = this.#to var time = this.#time var delay = this.#delay || 30 this.out = this.#from var i = 0 var last = Date.now() var dt = 0 while (i < time) { if (lastactive !== this.#active) return await a(() => !this.paused).waituntil().val a(() => this.#updatefunc.forEach((e) => e(this.out))).ignore() last = Date.now() var lastwait = delay - dt var dt = await a(lastwait).wait().val dt = Date.now() - last i += dt dt -= lastwait if (lastactive !== this.#active) return this.out = a(i).rerange(0, time, from, to).val } if (lastactive !== this.#active) return this.out = to a(() => this.#updatefunc.forEach((e) => e(this.out))).ignore() a(() => this.#donefunc.forEach((e) => e())).ignore() if (lastactive !== this.#active) return if (this.#reverseondone) { this.#flip() this.#go() } if (this.#loopondone) this.#go() } #flip() { var x = this.#from this.#from = this.#to this.#to = x } onchange(func) { this.#updatefunc.push(func) } ondone(func) { this.#donefunc.push(func) } destroy() { this.#active = null this.paused = false this.#updatefunc = undefined this.#donefunc = undefined var top = this a(this).foreach(function (a) { delete top[a] }) } } allfuncs.new("tween", tween, "time", false) allfuncs.new( "foreach", function ( //none arr, //array|object|any func //function ) { var type = a(arr).gettype().val if (type == "array") arr.forEach(func) else if (type == "object") { Reflect.ownKeys(arr).forEach((e, i) => { func(e, arr[e], i) }) } else { ;[arr].forEach(func) } }, "array", true ) allfuncs.new( "sendevent", function ( //element element, //element eventName //string ) { function extend(destination, source) { for (var property in source) destination[property] = source[property] return destination } var eventMatchers = { HTMLEvents: /^(?:load|unload|abort|error|select|change|submit|reset|focus|blur|resize|scroll)$/, MouseEvents: /^(?:click|dblclick|mouse(?:down|up|over|move|out))$/, } var defaultOptions = { pointerX: 0, pointerY: 0, button: 0, ctrlKey: false, altKey: false, shiftKey: false, metaKey: false, bubbles: true, cancelable: true, } var options = extend(defaultOptions, arguments[2] || {}) var oEvent, eventType = null for (var name in eventMatchers) { if (eventMatchers[name].test(eventName)) { eventType = name break } } if (!eventType) throw new SyntaxError( "Only HTMLEvents and MouseEvents interfaces are supported" ) if (document.createEvent) { oEvent = document.createEvent(eventType) if (eventType == "HTMLEvents") { oEvent.initEvent(eventName, options.bubbles, options.cancelable) } else { oEvent.initMouseEvent( eventName, options.bubbles, options.cancelable, document.defaultView, options.button, options.pointerX, options.pointerY, options.pointerX, options.pointerY, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, options.button, element ) } element.dispatchEvent(oEvent) } else { options.clientX = options.pointerX options.clientY = options.pointerY var evt = document.createEventObject() oEvent = extend(evt, options) element.fireEvent("on" + eventName, oEvent) } return element }, "element/event/automation" ) allfuncs.new( "ignore", function ( //any func, //function senderr, //boolean|none ...args //any|none ) { try { return func(...args) } catch (e) { return senderr ? e.message : undefined } }, "error", true ) allfuncs.new( "wait", function ( //promise ms //number ) { return new Promise(function (a) { var last = Date.now() setTimeout(() => a(Date.now() - last - ms), ms) }) }, "time", true ) allfuncs.new( "waituntil", function ( //promise q, //function cb //function|none ) { return new Promise((resolve) => { var last = Date.now() // if (!!q()) { // ignore(() => cb(Date.now() - last)) // return resolve(Date.now() - last) // } var int = setInterval( function (q, cb) { if (!!q()) { clearInterval(int) a(() => cb(Date.now() - last)).ignore() resolve(Date.now() - last) } }, 0, q, cb ) }) }, "time", true ) allfuncs.new( "keeponlyone", function ( //array arr //array ) { return [...new Set(arr)] }, "array", true ) allfuncs.new( "inin", function ( //any x, //any y, //array z //array ) { return z[y.indexOf(x)] }, "array", true ) allfuncs.new( "matchall", function ( //array|string x, //string y //regex ) { return [...x.matchAll(y)].map((e) => (e[1] !== undefined ? [...e] : e[0])) }, "regex", true ) allfuncs.new( "matchany", function ( //boolean x, //any ...y //any ) { return y.includes(x) }, "string", true ) allfuncs.new( "randfrom", function ( //any min, //array|number max //undefined|number ) { if (max === undefined) return min.length ? min[a(0).randfrom(min.length - 1).val] : "" if (min == max) return min if (max) return Math.round(Math.random() * (max - min)) + min return min[Math.round(Math.random() * (min.length - 1))] }, "number/array", true ) allfuncs.new( "unlisten", function ( //array data //array ) { data.forEach((data) => data[0].removeEventListener(data[1], data[2])) return data }, "event/elem", true ) allfuncs.new( "listen", function ( //array elem, //element type, //string|object|array cb //function|array|undefined ) { var all = [] if (a(type).gettype("array").val) { var temp = {} a(type).foreach((e) => (temp[e] = cb)) type = temp } if (a(type).gettype("object").val) a(type).foreach(function (type, cb) { if (a(type).gettype("string").val) type = a(type).matchall(/[a-z]+/g).val type.forEach((type) => { const newcb = function (...e) { cb(...e) } elem.addEventListener(type, newcb) all.push([elem, type, newcb]) }) }) else if (a(type).gettype("string").val) { type = a(type).matchall(/[a-z]+/g).val type.forEach((type) => { const newcb = function (e) { cb(e, type) } elem.addEventListener(type, newcb) all.push([elem, type, newcb]) }) } return all }, "event/elem", true ) allfuncs.new( "toelem", function ( //element|undefined|array elem, //any single //boolean|none ) { if (a(elem).gettype("element").val) return elem switch (a(elem).gettype().val) { case "string": return single ? a(elem).qs().val : a(elem).qsa().val case "array": return elem.map((elem) => { return a(elem).toelem(single).val }) case "object": var newobj = { ...elem, } if (single) return { [Object.keys(newobj)[0]]: a( newobj[Object.keys(newobj)[0]] ).toelem(single).val, } a(newobj).foreach(function (a, s) { newobj[a] = a(s).toelem().val }) return newobj default: error(elem, "inside [toelem] - not an element?") return undefined } }, "elem", true ) allfuncs.new( "geturlperams", function ( //object e = location.href //undefined|string ) { var arr = {} ;[...e.matchAll(/[?&]([^&\s]+?)(?:=([^&\s]*?))?(?=&|$|\s)/g)].forEach( (e) => { if (e[1].includes("#")) arr["#"] = e[1].match(/#(.*$)/)[1] if (e[2].includes("#")) arr["#"] = e[2].match(/#(.*$)/)[1] e[1] = e[1].replace(/#.*$/, "") e[2] = e[2].replace(/#.*$/, "") arr[decodeURIComponent(e[1]).replaceAll("+", " ")] = e[2] === undefined ? undefined : decodeURIComponent(e[2]).replaceAll("+", " ") } ) return arr }, "url", false ) allfuncs.new( "updateurlperam", function ( //string key, //string value, //string|undefined cangoback //undefined|boolean ) { var g = { ...a().geturlperams().val, [key]: value, } var k = "" var hash = "" a(g).foreach(function (key, value) { if (key == "#") return (hash = key + value) key = encodeURIComponent(key) value = encodeURIComponent(value) k += "&" + (value === undefined ? key : key + "=" + value) }) k = k.replace("&", "?") k += hash cangoback ? history.pushState(null, null, k) : history.replaceState(null, null, k) return key }, "url", true ) allfuncs.new( "newvarfunc", function ( //undefined name, //string func, //function obj = window //undefined|object ) { Object.defineProperty(obj, name, { configurable: false, get() { return func.call({}) }, set(a) { return func.call(a, a, true) }, }) }, "var", true ) allfuncs.new( "rerange", function ( //number val, //number low1, //number high1, //number low2, //number high2 //number ) { return ((val - low1) / (high1 - low1)) * (high2 - low2) + low2 }, "number", false ) allfuncs.new( "destring", function ( //any inp //string ) { var out = inp if (/^[\-0-9]+$/.test(inp)) return Number(inp) if (a((out = JSON.parse(inp))).gettype("array").val) return out if ( a( (out = JSON.parse(inp.replaceAll("'", '"').replaceAll("`", '"'))) ).gettype("object").val ) return out if (inp == "true") return true if (inp == "false") return false if (inp == "undefined") return undefined if (inp == "NaN") return NaN return inp }, "string/parse", true ) allfuncs.new( "eachelem", function ( //array arr1, //array cb //function ) { var arr = [] var elem = [] if (a(arr1).gettype("array").val) { arr1.foreach((e) => { elem = [ ...elem, ...(a(e).gettype("string").val ? a(e).qsa().val : [e]), ] }) } else { elem = a(arr1).gettype("string").val ? a(ar1).qsa().val : [arr1] } elem = elem.filter((e) => { return e instanceof Element }) elem.foreach(function (...a) { arr.push(cb(...a)) }) if (arr.length == 1) arr = arr[0] return arr }, "elem", true ) allfuncs.new( "remove", function ( //array arr, //array idx, //number|any isidx //boolean|undefined ) { arr = [...arr] idx = isidx ? idx : arr.indexOf(idx) if (idx < 0 || typeof idx !== "number") return arr arr.splice(idx, 1) return arr }, "array", true ) allfuncs.new( "download", function ( //string|file|blob data, //string|file|blob filename = "temp.txt", //string|undefined type, //string|undefined isurl //boolean|undefined ) { var url if (isurl) { url = data } else { var file = a(data).gettype("string").val ? new Blob([data], { type, }) : (data.name ? (filename = data.name) : "", data) url = URL.createObjectURL(file) } a() .bodyload() .then(() => { var link = a(document.body).createelem("a", { href: url, download: filename, }).val link.click() link.remove() if (!isurl) window.URL.revokeObjectURL(url) }) return data }, "file", true ) allfuncs.new( "idx", function ( //array arr, //array|string idx //number ) { return idx >= 0 ? arr[idx] : arr[arr.length + idx] }, "array", true ) allfuncs.new( "compare", function ( //boolean x, //string|any y //string|any ) { return x && y ? (typeof x == "string" ? x.toLowerCase() : x) == (typeof y == "string" ? y.toLowerCase() : y) : true }, "check", true ) allfuncs.new( "createelem", function ( //element parent, //element|none elem, //string data //object ) { //if (!parent) warn("no parent set", elem, data) var type = elem var issvg = elem == "svg" || parent?.tagName?.toLowerCase?.() == "svg" // warn(issvg, 'issvg', elem, parent, parent?.tagName) elem = issvg ? document.createElementNS("http://www.w3.org/2000/svg", elem) : document.createElement(elem) if (data.class) data.class.split(" ").forEach((e) => { elem.classList.add(e) }) if (data.options && type == "select") data.options = data.options.map( (e) => a(elem).createelem("option", { innerHTML: e, value: e, }).val ) if (type == "label" && "for" in data) { data.htmlFor = data.for } Object.assign(elem.style, data) if (type == "select") { a(data).foreach(function (a, s) { elem[a] = s }) } else if (issvg) { Object.keys(data).forEach((e) => (elem[e] = data[e])) } else { Object.assign(elem, data) } if (typeof parent == "string") parent = a(parent).qs().val a(() => parent.appendChild(elem)).ignore() return elem }, "elem", true ) allfuncs.new( "gettype", function ( //string thing, //any match //undefined|string|array ) { if ( !match || (Object.prototype.toString .call(match) .toLowerCase() .match(/^\[[a-z]+ (\w+)\]$/)[1] == "string" && !match.includes("|")) ) { var type = Object.prototype.toString .call(thing) .toLowerCase() .match(/^\[[a-z]+ (\w+)\]$/)[1] if (type !== "function") if (type == match) return true if (match == "normalfunction") return type == "function" if (type == "htmldocument" && match == "document") return true if (match == "body" && type == "htmlbodyelement") return true if (match && new RegExp(`^html${match}element$`).test(type)) return true if (/^html\w+element$/.test(type)) type = "element" if (type == "htmldocument") type = "element" if (type == "asyncfunction") type = "function" if (type == "generatorfunction") type = "function" if (type == "regexp") type = "regex" if (match == "regexp") match = "regex" if (match == "element" && type == "window") return true if (match == "element" && type == "shadowroot") return true if (/^(html|svg).*element$/.test(type)) type = "element" if (type == "function") { type = /^\s*class\s/.test(Function.prototype.toString.call(thing)) ? "class" : "function" } if (match == "none") return type == "nan" || type == "undefined" || type == "null" try { if (type === "number" && isNaN(thing) && match == "nan") return true } catch (e) { error(thing) } return match ? match === type : type } else { if (match.includes("|")) match = match.split("|") match = [...new Set(match)] return match.filter((e) => a(thing).gettype(e).val).length > 0 } }, "check", true ) allfuncs.new( "waitforelem", async function ( //promise selector //string|array ) { if (a(selector).gettype("string").val) { selector = [selector] } await a().bodyload() var g = false return new Promise((resolve) => { var observer = new MutationObserver(check) observer.observe(document.body, { childList: true, subtree: true, attributes: true, characterData: false, }) check() function check() { if (g) return if (selector.find((selector) => !a(selector).qs().val)) return observer.disconnect() resolve( selector.length == 1 ? a(selector[0]).qs().val : selector.map((e) => a(e).qs().val) ) } }) }, "time/elem" ) allfuncs.new( "findvar", function ( //any obj, //object|element findkey, //any objectname = "obj", //string exact, //boolean all //boolean ) { var vvv = [] var allarr = [] var chain = objectname var arr = [] var arr2 = [ { chain, value: obj, }, ] var visited = [] var i = 0 while (arr2.length && i++ < 800) { if ( arr2 .map((e) => e.chain) .join("/") .includes("." + findkey + (exact ? "/" : "")) ) { if (all) vvv.push( arr2.filter((e) => exact ? e.chain.endsWith("." + findkey) : e.chain.includes("." + findkey) ) ) else return arr2.filter((e) => exact ? e.chain.endsWith("." + findkey) : e.chain.includes("." + findkey) )[0] } var oldarr2 = [...arr2] allarr.push(arr2) arr2 = [] oldarr2.forEach((e) => { if ( a(e.value).gettype("object").val || a(e.value).gettype("element").val ) a(e.value).foreach(function (key, value) { if (a(key).gettype().val !== "string") return warn(key, a(key).gettype().val) var newchain = /^[a-z_][_a-z0-9]*$/i.test(key) ? "." + key : `["${key.replaceAll('"', '\\"')}"]` arr.push(e.chain + newchain) if (visited.includes(e.value)) return arr2.push({ chain: e.chain + newchain, value, }) }) visited.push(e.value) }) } return vvv.length > 0 ? vvv : allarr }, "debug", false ) allfuncs.new( "getallvars", function () { //object var obj = {} var variables = [] for (var name in this) if ( !`window self document name location customElements history locationbar menubar personalbar scrollbars statusbar toolbar status closed frames length top opener parent frameElement navigator origin external screen innerWidth innerHeight scrollX pageXOffset scrollY pageYOffset visualViewport screenX screenY outerWidth outerHeight devicePixelRatio clientInformation screenLeft screenTop styleMedia onsearch isSecureContext trustedTypes performance onappinstalled onbeforeinstallprompt crypto indexedDB sessionStorage localStorage onbeforexrselect onabort onbeforeinput onblur oncancel oncanplay oncanplaythrough onchange onclick onclose oncontextlost oncontextmenu oncontextrestored oncuechange ondblclick ondrag ondragend ondragenter ondragleave ondragover ondragstart ondrop ondurationchange onemptied onended onerror onfocus onformdata oninput oninvalid onkeydown onkeypress onkeyup onload onloadeddata onloadedmetadata onloadstart onmousedown onmouseenter onmouseleave onmousemove onmouseout onmouseover onmouseup onmousewheel onpause onplay onplaying onprogress onratechange onreset onresize onscroll onsecuritypolicyviolation onseeked onseeking onselect onslotchange onstalled onsubmit onsuspend ontimeupdate ontoggle onvolumechange onwaiting onwebkitanimationend onwebkitanimationiteration onwebkitanimationstart onwebkittransitionend onwheel onauxclick ongotpointercapture onlostpointercapture onpointerdown onpointermove onpointerrawupdate onpointerup onpointercancel onpointerover onpointerout onpointerenter onpointerleave onselectstart onselectionchange onanimationend onanimationiteration onanimationstart ontransitionrun ontransitionstart ontransitionend ontransitioncancel onafterprint onbeforeprint onbeforeunload onhashchange onlanguagechange onmessage onmessageerror onoffline ononline onpagehide onpageshow onpopstate onrejectionhandled onstorage onunhandledrejection onunload crossOriginIsolated scheduler alert atob blur btoa cancelAnimationFrame cancelIdleCallback captureEvents clearInterval clearTimeout close confirm createImageBitmap fetch find focus getComputedStyle getSelection matchMedia moveBy moveTo open postMessage print prompt queueMicrotask releaseEvents reportError requestAnimationFrame requestIdleCallback resizeBy resizeTo scroll scrollBy scrollTo setInterval setTimeout stop structuredClone webkitCancelAnimationFrame webkitRequestAnimationFrame originAgentCluster navigation webkitStorageInfo speechSynthesis oncontentvisibilityautostatechange openDatabase webkitRequestFileSystem webkitResolveLocalFileSystemURL chrome caches cookieStore ondevicemotion ondeviceorientation ondeviceorientationabsolute launchQueue onbeforematch getDigitalGoodsService getScreenDetails queryLocalFonts showDirectoryPicker showOpenFilePicker showSaveFilePicker TEMPORARY PERSISTENT addEventListener dispatchEvent removeEventListener` .split(" ") .includes(name) ) variables.push(name) variables.forEach((e) => { var c = String(a(this[e]).gettype().val) if (c === "object") c = "variable" if (!obj[c]) obj[c] = [] obj[c].push(e) }) return obj }, "debug", false ) allfuncs.new( "scratch_getallkeys", function () { //object var m = vm.runtime var f = { bools: m.targets .map((e) => { return { name: e.sprite.name, blocks: Object.values(e.blocks._blocks) .filter((e) => e.opcode === "sensing_keypressed") .map((e) => e.inputs.KEY_OPTION.block), otherblocks: e.blocks._blocks, } }) .filter((e) => e.blocks.length) .map((e) => { return { name: e.name, value: [ ...new Set( e.blocks .map((y) => e.otherblocks[y]) .map( (e) => e.fields?.KEY_OPTION?.value || e.fields?.VALUE?.value || error(e) ) ), ], } }), hats: m.targets .map((e) => { return { name: e.name, blocks: Object.values(e.blocks) .filter((e) => e.opcode === "event_whenkeypressed") .map((e) => e.fields.KEY_OPTION.value), } }) .filter((e) => e.blocks.length), } f.all = [ ...f.hats.map((e) => e.blocks).flat(), ...f.bools.map((e) => e.value).flat(), ] f.all = [...new Set(f.all)] return f }, "scratch", false ) allfuncs.new( "newfunc", function ( //undefined func1, //string func2 //function ) { eval(`var a = ${func1} var s = ${func2} ${func1} = function (...args) { a.call(this, ...args) s(arguments) }`) }, "function/jank", true ) allfuncs.new( "findall", function ( //array obj, //object objectname = "obj" //string ) { var chain = objectname var arr = [] var arr2 = [ { chain, value: obj, }, ] var visited = [] var i = 0 while (arr2.length && i++ < 800) { var oldarr2 = [...arr2] arr2 = [] oldarr2.forEach((e) => { if (a(e.value).gettype("object").val) a(e.value).foreach(function (key, value) { var newchain = /^[_a-z][_a-z0-9]*$/i.test(key) ? "." + key : `["${key.replaceAll('"', '\\"')}"]` arr.push(e.chain + newchain) if (visited.includes(e.value)) return log({ key, value, chain: e.chain + newchain, }) arr2.push({ chain: e.chain + newchain, value, }) }) visited.push(e.value) }) } return visited }, "debug", true ) allfuncs.new( "sha", function ( //string s = "", //string includesymbols //boolean|string ) { var tab if (typeof includesymbols == "string") { tab = includesymbols } else if (includesymbols) { tab = "`~\\|[];',./{}:<>?\"!@#$%^&*ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" } else { tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789" } return binb2b64(core_sha1(str2binb(s), s.length * 8)) function core_sha1(x, len) { x[len >> 5] |= 0x80 << (24 - len) x[(((len + 64) >> 9) << 4) + 15] = len var w = Array(80) var a = 1732584193 var b = -271733879 var c = -1732584194 var d = 271733878 var e = -1009589776 for (var i = 0; i < x.length; i += 16) { var olda = a var oldb = b var oldc = c var oldd = d var olde = e for (var j = 0; j < 80; j++) { if (j < 16) w[j] = x[i + j] else w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1) var t = safe_add( safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)) ) e = d d = c c = rol(b, 30) b = a a = t } a = safe_add(a, olda) b = safe_add(b, oldb) c = safe_add(c, oldc) d = safe_add(d, oldd) e = safe_add(e, olde) } return Array(a, b, c, d, e) } function sha1_ft(t, b, c, d) { if (t < 20) return (b & c) | (~b & d) if (t < 40) return b ^ c ^ d if (t < 60) return (b & c) | (b & d) | (c & d) return b ^ c ^ d } function sha1_kt(t) { return t < 20 ? 1518500249 : t < 40 ? 1859775393 : t < 60 ? -1894007588 : -899497514 } function safe_add(x, y) { var lsw = (x & 0xffff) + (y & 0xffff) var msw = (x >> 16) + (y >> 16) + (lsw >> 16) return (msw << 16) | (lsw & 0xffff) } function rol(num, cnt) { return (num << cnt) | (num >>> (32 - cnt)) } function str2binb(str) { var bin = Array() var mask = (1 << 8) - 1 for (var i = 0; i < str.length * 8; i += 8) bin[i >> 5] |= (str.charCodeAt(i / 8) & mask) << (24 - i) return bin } function binb2b64(binarray) { var str = "" for (var i = 0; i < binarray.length * 4; i += 3) { var triplet = (((binarray[i >> 2] >> (8 * (3 - (i % 4)))) & 0xff) << 16) | (((binarray[(i + 1) >> 2] >> (8 * (3 - ((i + 1) % 4)))) & 0xff) << 8) | ((binarray[(i + 2) >> 2] >> (8 * (3 - ((i + 2) % 4)))) & 0xff) for (var j = 0; j < 4; j++) { if (i * 8 + j * 6 > binarray.length * 32) str += "" else str += tab.charAt((triplet >> (6 * (3 - j))) & 0x3f) } } return str } }, "code", true ) allfuncs.new( "qs", function ( //element|none text, //string parent = document //element|none ) { return parent.querySelector(text) }, "elem", true ) allfuncs.new( "qsa", function ( //array text, //string parent = document //element|none ) { return Array.from(parent.querySelectorAll(text)) }, "elem", true ) allfuncs.new( "csspath", function ( //string|array el //elements|element ) { if (a(el).gettype("array").val) return a(el).map((e) => a(e).csspath().val) if (!(el instanceof Element)) return var path = [] while (el.nodeType === Node.ELEMENT_NODE) { var selector = el.nodeName.toLowerCase() if (el.id) { selector += "#" + el.id path.unshift(selector) break } else { var sib = el, nth = 1 while ((sib = sib.previousElementSibling)) { if (sib.nodeName.toLowerCase() == selector) nth++ } if (nth != 1) selector += ":nth-of-type(" + nth + ")" } path.unshift(selector) el = el.parentNode } return path.join(" > ") }, "elem", true ) allfuncs.new( "fromms", function ( //object ms //number ) { //returns a unix timestamp as an object where "ms" is the unixtimestamp ms = Number(ms) return { years: Math.floor(ms / 1000 / 60 / 60 / 24 / 365), days: Math.floor(ms / 1000 / 60 / 60 / 24) % 365, hours: Math.floor(ms / 1000 / 60 / 60) % 24, mins: Math.floor(ms / 1000 / 60) % 60, secs: Math.floor(ms / 1000) % 60, ms: Math.floor(ms) % 1000, } }, "time", true ) allfuncs.new( "toms", function ( //number { ms = 0, secs = 0, mins = 0, hours = 0, days = 0, years = 0 } //object ) { return ( ms + secs * 1000 + mins * 60000 + hours * 3600000 + days * 86400000 + years * 31560000000 ) }, "time", true ) allfuncs.new( "rect", function ( //object e //element ) { if (a(e).gettype("string").val) e = a(e).qs().val var { x, y, width, height } = e.getBoundingClientRect().toJSON() return { x, y, w: width, h: height, } }, "elem", true ) allfuncs.new( "setelem", function ( //element|array elem, //elements|element data //object ) { if (data.class) data.class.split(" ").forEach((e) => { elem.classList.add(e) }) if (data.options && elem.tagName.toLowerCase() == "select") data.options = data.options.map( (e) => a(elem).createelem("option", { innerHTML: e, value: e, }).val ) Object.assign(elem.style, data) if (elem.tagName.toLowerCase() == "select") { a(data).foreach(function (a, s) { elem[a] = s }) } else if (issvg) { Object.keys(data).forEach((e) => (elem[e] = data[e])) } else { Object.assign(elem, data) } if (typeof parent == "string") parent = a(parent).qs().val a(() => parent.appendChild(elem)).ignore() return elem }, "elem", true ) allfuncs.new( "watchvar", function ( //undefined varname, //string onset, //function onget, //function|none obj = window //object|window ) { //creates a new var and runs "onset" on the change of "varname", and "onget" when "varname" is read obj = obj || window obj[`_${varname}`] = undefined obj[`${varname}`] = undefined Object.defineProperty(obj, varname, { configurable: false, get() { if (onget) return onget(obj[`_${varname}`]) return obj[`_${varname}`] }, set(value) { if (value === obj[`_${value}`]) { return } var s = onset(value, obj[`_${varname}`]) if (s) obj[`_${varname}`] = value }, }) }, "var/debug", true ) allfuncs.new( "randomizeorder", function ( //array arr //array ) { arr = [...arr] var arr2 = [] var count = arr.length for (var i = 0; i < count; i++) { var idx = randfrom(0, arr.length - 1) arr2.push(arr[idx]) arr.splice(idx, 1) } return arr2 }, "array", true ) allfuncs.new( "constrainvar", function ( //undefined varname, //string min, //number max //number ) { //creates a new var that can't go beyond the bounds of "min" and "max" window[`_${varname}`] = undefined window[`${varname}`] = undefined Object.defineProperty(window, varname, { configurable: false, get() { return window[`_${varname}`] }, set(value) { if (value === window[`_${varname}`]) { return } if (value > max) value = max if (value < min) value = min window[`_${varname}`] = value }, }) }, "var", true ) allfuncs.new( "isbetween", function ( //boolean z, //number x, //number c //number ) { //returns true if "z" is between "x" and "c" if (x == c) return false var big, small if (x > c) { big = x small = c } else { big = c small = x return z > big && z < small } }, "check", true ) allfuncs.new( "indexsof", function ( //array y, //string x //string ) { var i = 0 var arr = [] y.split(x).forEach((e, k) => { i += e.length arr.push(i + k) }) arr.pop() return arr }, "array", true ) allfuncs.new( "export", function () { //string //saves the data of text inputs and checkboxes var s = [] a("input, textarea") .qsa() .foreach((e) => { s.push({ path: a(e).csspath().val, value: escape(e.value), checked: e.checked, }) }) return JSON.stringify(s) }, "data", false ) allfuncs.new( "import", function ( //string data //string ) { //loads the data of text inputs and checkboxes data.forEach((e) => { var s = a(e.path).qs().val s.checked = e.checked s.value = unescape(e.value) }) return data }, "data", true ) allfuncs.new( "popup", function ( //window data, //string x, //number|none y, //number|none w, //number|none h //number|none ) { //creates a popup window if (x || x === 0) { x = (screen.width / 100) * x y = (screen.height / 100) * y w = (screen.width / 100) * w h = (screen.height / 100) * h var win = open("", "", `left=${x}, top=${y} width=${w},height=${h}`) win.document.write(data) return win } else { var win = open("") win.document.write(data) return win } }, "window", true ) allfuncs.new( "same", function ( //boolean ...a //any ) { if (a.length == 1) a = a[0] return [...new Set(a.map((e) => JSON.stringify(e)))].length === 1 }, "check", true ) allfuncs.new( "containsany", function ( //boolean arr1, //array|string arr2 //array ) { return !!arr2.find((e) => arr1.includes(e)) }, "array" ) allfuncs.new( "run", function ( //any func, //function obj //object ) { return func(...getprops(func).vars.map((e) => obj[e.var])) }, "function", true ) allfuncs.new( "getprops", function ( //array|object func, //function peramsonly /*?|boolean*/ ) { return peramsonly ? getprops(func) .vars.map((e) => e.var) .filter((e) => e) : getprops(func) }, "function/parse", true ) allfuncs.new( "bodyload", function () { //promise return new Promise((resolve) => { if (document.body) resolve() const int = setInterval(() => { if (document.body) resolve(clearInterval(int)) }) }) }, "elem/time", false ) ;(async function () { const { bodyload } = allfuncs await bodyload() // var optionselem = loadlib("addnewoption", "optionselem") // delete localStorage.buttonsheight // delete localStorage.buttonswidth // delete localStorage.buttonsx // delete localStorage.buttonsy if (!localStorage.buttonsheight) localStorage.buttonsheight = "100px" if (!localStorage.buttonswidth) localStorage.buttonswidth = "120px" var c = document.body if (!window.optionselem) { c = a(c) .createelem("div", { position: "fixed", top: (Number(localStorage.buttonsy) || 10) + "px", left: (Number(localStorage.buttonsx) || Number(localStorage.buttonswidth.match(/[0-9]+/)[0]) / 2) + "px", width: 0, height: 0, zIndex: 999999999999999, pointerEvents: "all", backgroundColor: "#0000", }) .val.attachShadow({ mode: "closed", }) window.optionselem = a(c).createelem("div", { overflow: "hidden", position: "fixed", top: constrain( (Number(localStorage.buttonsy) || 10, 0 + 50 / 2), innerHeight - this.clientHeight / 2 ) + "px", left: constrain( localStorage.buttonswidth, 0 + this.clientWidth / 2, innerWidth - this.clientWidth / 2 ) + "px", zIndex: 999999999999999, height: "20px", pointerEvents: "all", backgroundColor: "#0f09", test(e) { if (!this.moving && e) return if (!e) { this.style.translate = "0 0" e = { clientX: this.getBoundingClientRect().toJSON().x, clientY: this.getBoundingClientRect().toJSON().y, } } // this.style.translate = "-50% -50%" this.style.top = constrain(e.clientY - 10, 0, innerHeight - this.clientHeight) + "px" this.style.left = constrain( e.clientX - this.clientWidth / 2, 0, innerWidth - this.clientWidth ) + "px" localStorage.buttonsx = e.clientX localStorage.buttonsy = e.clientY }, onmouseup() { this.moving = false }, }).val optionselem.style.left = constrain( Number(localStorage.buttonswidth) || 0, 0 + optionselem.clientWidth / 2, innerWidth - optionselem.clientWidth / 2 ) + "px" optionselem.style.top = constrain( Number(localStorage.buttonsy) || 10, 0 + 50 / 2, innerHeight - optionselem.clientHeight / 2 ) + "px" var ismain try { ismain = window?.parent?.location?.href === location.href } catch (e) { ismain = false } a(window.optionselem).createelem("div", { backgroundColor: ismain ? "#00f" : "#f00", width: "100%", height: "20px", oncontextmenu(e) { e.preventDefault() log(window.optionselem) if (window.optionselem.style.height === "20px") window.optionselem.style.height = "auto" else window.optionselem.style.height = "20px" }, onmousedown(e) { e.preventDefault() if (e.which == 3 || e.button == 2) return window.optionselem.moving = true }, onmouseup() { window.optionselem.moving = false }, }) } function constrain(inp, max, min) { if (min > max) { var c = min min = max max = c } return Math.min(max, Math.max(min, inp)) } a(window).listen({ resize() { window.optionselem.moving = false optionselem.test.call(optionselem) }, blur() { window.optionselem.moving = false }, focus() { window.optionselem.moving = false }, mousemove(e) { optionselem.test.call(optionselem, e) }, }) function addnewoption( //undefined ...z //object|undefined ) { var zz = z[0] // trymatch(zz.host, location.host) // trymatch(zz.href, location.n) // trymatch(zz.hostname, location.n) // trymatch(zz.origin, location.n) // trymatch(zz.pathname, location.n) var s = a(optionselem).createelem("div", { textAlign: "center", width: localStorage.buttonswidth, minHeight: localStorage.buttonsheight, backgroundColor: zz.backgroundColor || "#0000", }).val a(s).createelem("p", { innerHTML: zz.title || " ", textAlign: "center", color: zz.titlecolor, }) ;[...z].forEach((z, i) => { if (i === 0) return var elem switch (z.type) { case "button": elem = a(s).createelem("button", { id: z.id, itemnumber: i, index: i, innerHTML: z.text, onclick: z.onclick, textAlign: "center", }).val break case "toggle": elem = a(s).createelem("input", { id: z.id, itemnumber: i, index: i, type: "checkbox", onclick(e) { if (this.checked) z.onon?.call?.(this, e) else z.onoff?.call?.(this, e) z.onclick?.call?.(this, e) }, }).val break case "select": var x = a(s).createelem("select", { id: z.id, options: z.options, index: i, itemnumber: i, value: z.value, onchange: z.onchange, }).val elem = x break case "input": elem = a(s).createelem("input", { id: z.id, itemnumber: i, index: i, width: "90%", value: z.value, placeholder: z.placeholder, onchange(e) { z.onchange.call(this, e) }, }).val break case "p": elem = a(s).createelem("p", { id: z.id, innerHTML: z.text, }).val break case "br": elem = a(s).createelem("br", {}).val break default: error(`type not found: "${z.type}"`) } if (z.id) window[z.id] = elem }) } // addnewoption({ title: "asddssa" }, { type: "button" }) allfuncs.new("addnewoption", addnewoption, "elem", true) })() allfuncs.new( "scratch_gettarget", function ( //object sprite //string|none ) { if (sprite) var x = vm.runtime.getSpriteTargetByName(sprite) else var x = vm.runtime.getTargetForStage() x.getvar = x.lookupVariableByNameAndType return x }, "scratch", true ) allfuncs.new( "scratch_sendbroadcast", function ( //string data //string ) { vm.runtime.startHats("event_whenbroadcastreceived", { BROADCAST_OPTION: data, }) return data }, "scratch", true ) allfuncs.new( "scratch_canvas", function () { //element return ( window?.vm?.runtime?.renderer?.canvas || a( "#app > div > div.gui_body-wrapper_-N0sA.box_box_2jjDp > div > div.gui_stage-and-target-wrapper_69KBf.box_box_2jjDp > div.stage-wrapper_stage-wrapper_2bejr.box_box_2jjDp > div.stage-wrapper_stage-canvas-wrapper_3ewmd.box_box_2jjDp > div > div.stage_stage_1fD7k.box_box_2jjDp > div:nth-child(1) > canvas" ).qs().val || a( "#view > div > div.inner > div:nth-child(2) > div.guiPlayer > div.stage-wrapper_stage-wrapper_2bejr.box_box_2jjDp > div.stage-wrapper_stage-canvas-wrapper_3ewmd.box_box_2jjDp > div > div.stage_stage_1fD7k.box_box_2jjDp > div:nth-child(1) > canvas" ).qs().val || a( "#app > div > div > div > div.gui_body-wrapper_-N0sA.box_box_2jjDp > div > div.gui_stage-and-target-wrapper_69KBf.box_box_2jjDp > div.stage-wrapper_stage-wrapper_2bejr.box_box_2jjDp > div.stage-wrapper_stage-canvas-wrapper_3ewmd.box_box_2jjDp > div > div.stage_stage_1fD7k.box_box_2jjDp > div:nth-child(1) > canvas" ).qs().val ) }, "scratch", false ) allfuncs.new( "replacealltext", function ( //string|regex pattern, //string|regex string, //string element = document.body //element|none ) { ;[ element, ...element.querySelectorAll("*:not(script):not(noscript):not(style)"), ].forEach(({ childNodes: [...nodes] }) => nodes .filter(({ nodeType }) => nodeType === Node.TEXT_NODE) .forEach( (textNode) => (textNode.textContent = textNode.textContent.replaceAll( pattern, string )) ) ) return pattern }, "string", true ) allfuncs.new( "repeat", function ( //promise|undefined func, //function count, //number delay, //number|none instantstart, //boolean|none waituntildone //boolean|none ) { if (delay || waituntildone) return new Promise(async (resolve) => { if (delay) { var extra = 0 for (var i = 0; i < count; i++) { if (instantstart) waituntildone ? await func(i) : func(i) extra = await a(delay - extra).wait().val if (!instantstart) waituntildone ? await func(i) : func(i) } resolve() } else for (var i = 0; i < count; i++) waituntildone ? await func(i) : func(i) resolve() }) for (var i = 0; i < count; i++) func(i) return }, "repeat", true ) allfuncs.new( "repeatuntil", function ( //promise func, //function donecheck, //function delay, //number|none instantstart, //boolean|none waituntildone //boolean|none ) { return new Promise(async (resolve) => { if (delay) { var extra = 0 var i = 0 while (!donecheck()) { i++ if (instantstart) { waituntildone ? await func(i) : func(i) } extra = await a(delay - extra).wait().val if (!instantstart) { waituntildone ? await func(i) : func(i) } } resolve() } else { var i = 0 while (!donecheck()) { i++ waituntildone ? await func(i) : func(i) } resolve() } }) }, "repeat", true ) // ;(async function () { // const { bodyload } = allfuncs // await bodyload() // const listeners = [] // a(document).listen({ // dragover(e) { // e.stopPropagation() // e.preventDefault() // }, // drop(e) { // e.stopPropagation() // e.preventDefault() // var files = [...e.dataTransfer.files] // listeners.forEach((y) => y[0](y[1] ? files[0] : files)) // }, // }) // allfuncs.new( // "newdrop", // function ( // //undefined // func, //function // onlyone //boolean // ) { // listeners.push([func, onlyone]) // }, // "file" // ) // })() ;(async () => { const drops = [] await a().bodyload() a(document.body).listen({ dragover(e) { e.preventDefault() }, async drop(e) { e.preventDefault() drops.forEach(async ({ types, multi, func, elem }) => { if (elem) if (e.target !== elem) return if (multi) var ret = [] for (const item of e.dataTransfer.items) { if (item.kind == "file") { if (types.includes("file") || types.includes("directory")) { const entry = await item.getAsFileSystemHandle() if (entry.kind === "file" && types.includes("file")) { if (!multi) return func(entry, e) ret.push(entry) } else if ( entry.kind === "directory" && types.includes("directory") ) { if (!multi) return func(entry, e) ret.push(entry) } } } } if (multi && ret.length) return func(ret, e) }) }, }) allfuncs.new( "ondrop", function ( //object obj //object ) { if (!obj.types) obj.types = "all" obj.types = a(obj.types).toarray().val if (!obj.func) throw new Error('object is missing "func"') var oldelem = obj.elem if (obj.elem) obj.elem = a(obj.elem).toelem(true).val if (obj.elem && !a(obj.elem).gettype("element").val) throw new Error(`elem is not an elem, ${oldelem} -> ${obj.elem}`) drops.push(obj) return obj }, "file" ) })() allfuncs.new( "getfolderpath", async function ( //promise folder //filesystemdirectoryhandle ) { async function parsedir(dir, x) { if (!x) { return [ { name: dir.name, inside: await parsedir(dir, true), type: "folder", handle: dir, }, ] } else var arr = [] for await (const [name, handle] of dir.entries()) { arr.push( a(handle).gettype("filesystemdirectoryhandle").val ? { type: "folder", inside: await parsedir(handle, true), name, handle, } : { type: "file", handle, name } ) } return arr } return parsedir(folder) }, "file", false ) allfuncs.new( "getfiles", async function ( //promise oldway, //boolean|none multiple, //boolean|none accept = [], //array|string|none options = {} //object|undefined ) { const supportsFileSystemAccess = "showOpenFilePicker" in window && (() => { try { return window.self === window.top } catch { return false } })() if (!oldway) { if (!supportsFileSystemAccess) throw new Error("no access") let fileOrFiles = undefined try { const handles = await showOpenFilePicker({ types: [ { accept: { "*/*": accept, }, }, ], multiple, ...options, }) if (!multiple) { fileOrFiles = handles[0] } else { fileOrFiles = await Promise.all(handles) } } catch (err) { if (err.name !== "AbortError") { error(err.name, err.message) } } return fileOrFiles } return new Promise(async (resolve) => { await a().bodyload().val const input = document.createElement("input") input.style.display = "none" input.type = "file" if (accept) input.accept = accept document.body.append(input) if (multiple) { input.multiple = true } input.addEventListener("change", () => { input.remove() // if (!input.files) { // return // } resolve(multiple ? Array.from(input.files) : input.files[0]) }) if ("showPicker" in HTMLInputElement.prototype) { input.showPicker() } else { input.click() } }) }, "file", true ) allfuncs.new( "map", function ( //array|object arr, //array|object|any func //function ) { var type = a(arr).gettype().val if (type == "array") return arr.map(func) else if (type == "object") { var temparr = {} Reflect.ownKeys(arr).forEach((e, i) => { temparr = { ...temparr, ...func(e, arr[e], i), } }) return temparr } else { return [arr].map(func) } }, "array", true ) allfuncs.new( "find", function ( //any arr, //array|object|any func //function ) { var type = a(arr).gettype().val if (type == "array") return arr.find(func) else if (type == "object") { return Reflect.ownKeys(arr).find((e, i) => { return func(e, arr[e], i) }) } else { return [arr].find(func) } }, "array", true ) allfuncs.new( "filteridx", function ( //array arr, //array|any func //function ) { if (a(arr).gettype("object").val) arr = [arr] return a(arr) .map((e, i) => (func(e, i) ? i : undefined)) .filter((e) => e !== undefined) }, "array" ) allfuncs.new( "filter", function ( //array|object arr, //array|object|any func //function ) { var type = a(arr).gettype().val if (type == "array") return arr.filter(func) else if (type == "object") { var temparr = {} Reflect.ownKeys(arr).forEach((e, i) => { if (func(e, arr[e], i)) temparr = { ...temparr, [e]: arr[e], } }) return temparr } else { return [arr].filter(func) } }, "array", true ) ;(function () { var last var different = allfuncs.new( "unique", function () /*object*/ { return last || (last = different.new()) }, "check", false ) different.new = function (name) { var $ = new Proxy( {}, { get(_a, s) { return s == "name" ? name || "different" : $ }, set() { return $ }, } ) return (last = $) } })() allfuncs.new( "elif", function ( //any cond, //any iftrue, //any iffalse //any ) { return cond ? iftrue : iffalse }, "check", true ) allfuncs.new( "tonumber", function ( //number e //any ) { return Number(e) }, "number/format", true ) allfuncs.new( "toarray", function ( //array e, //any split //string|none|undefined ) { if (a(e).gettype("string").val) { if (split) e = e.split(split) else return [e] } return [...e] }, "number/format", true ) allfuncs.new( "tostring", function ( //string e //any ) { if (["object", "array"].includes(a(e).gettype().val)) return JSON.stringify(e) if (a(e).gettype("element").val) return a(e).csspath().val return String(e) }, "string/format", true ) allfuncs.new( "eval", function ( //any a //any ) { return eval(a) }, "js/eval", true ) allfuncs.new( "toregex", function ( //regex d, //string|array|regex s //undefined|string ) { if (a(d).gettype("array").val) var temp = d if (s) var temp = [d, s] else if (String(d).match(/^\/(.*)\/(\w*)$/)) { var m = String(d).match(/^\/(.*)\/(\w*)$/) var temp = [m[1], m[2]] } else var temp = [String(d), ""] temp[1] = temp[1].toLowerCase() if (temp[1].includes("w")) { temp[1] = temp[1].replace("w", "") temp[0] = `(?<=[^a-z0-9]|^)${temp[0]}(?=[^a-z0-9]|$)` } return new RegExp(temp[0], temp[1].replaceAll(/(.)(?=.*\1)/g, "")) }, "regex", true ) allfuncs.new( "isregex", function ( //boolean s //string|regex ) { if (a(s).gettype("regex").val) return true return /^\/.*(?<!\\)\/[gimusy]*$/.test(s) && !/^\/\*.*\*\/$/.test(s) }, "check", true ) allfuncs.new( "ispressed", function ( //boolean e /*event*/, code //string ) { code = code.toLowerCase() var temp = e.shiftKey == code.includes("shift") && e.altKey == code.includes("alt") && e.ctrlKey == code.includes("ctrl") && e.metaKey == code.includes("meta") && e.key.toLowerCase() == code.replaceAll(/alt|ctrl|shift|meta/g, "").trim() if (temp && !a) e.preventDefault() return temp }, "check/input/event", true ) allfuncs.new( "controller_vibrate", function ( //number pad, //number duration = 1000, //number|none strongMagnitude = 0, //number|none weakMagnitude = 0 //number|none ) { getpad(pad).vibrationActuator.playEffect("dual-rumble", { duration, strongMagnitude, weakMagnitude, }) return pad }, "controller/haptic", true ) allfuncs.new( "controller_getbutton", function ( //number pad, //number button //number|none ) { return button ? getpad(pad).buttons[button].value : getpad(pad).buttons.map((e) => e.value) }, "controller/input", true ) allfuncs.new( "controller_getaxes", function ( //array|number pad, //number axes //number|none ) { return axes ? getpad(pad).axes[axes] : getpad(pad).axes }, "controller/input", true ) allfuncs.new( "controller_exists", function ( //boolean|number pad //number|none ) { return pad === undefined ? getpad().filter((e) => e).length : !!getpad(pad) }, "controller/check", true ) allfuncs.new( "runall", function ( //array|function funcs, //array|function args //array|any ) { if (!a(args).gettype("array").val) args = [args] if (!a(funcs).gettype("array").val) funcs = [funcs] funcs.map((func) => func(...args)) return funcs }, "function" ) allfuncs.new( "readfile", async function ( //promise file, //file type = "Text" //string|none ) { return new Promise(function (done, error) { var f = new FileReader() f.onerror = error f.onload = () => done(type == "json" ? JSON.parse(f.result) : f.result) f["readAs" + (type == "json" ? "Text" : type)](file) }) }, "file" ) allfuncs.new( "writefile", async function writefile( //promise file, //filesystemfilehandle text //string ) { var f = await await file.createWritable() await f.write(text) await f.close() return file }, "file" ) allfuncs.new( "getfileperms", async function ( //promise fileHandle, //filesystemfilehandle readWrite //boolean|none ) { const options = {} if (readWrite) { options.mode = "readwrite" } return ( (await fileHandle.queryPermission(options)) === "granted" || (await fileHandle.requestPermission(options)) === "granted" ) }, "file/permission", true ) allfuncs.new( "indexeddb_set", async function ( //promise place, //object obj //object ) { return new Promise((done, error) => place.put( obj, (e) => done(e), (e) => error(e) ) ) }, "indexeddb", true ) allfuncs.new( "indexeddb_get", async function ( //promise place, //object obj //string ) { return new Promise((done, error) => place.get( obj, (e) => done(e), (e) => error(e) ) ) }, "indexeddb", true ) allfuncs.new( "indexeddb_getall", async function ( //promise place //object ) { return new Promise((done, error) => place.getAll( (e) => done(e), (e) => error(e) ) ) }, "indexeddb", true ) allfuncs.new( "indexeddb_clearall", async function ( //promise place //object ) { return new Promise((done, error) => place.clear( (e) => done(e), (e) => error(e) ) ) }, "indexeddb", true ) allfuncs.new( "indexeddb_remove", async function ( //promise place, //object obj //string|number ) { return new Promise((done, error) => place.remove( obj, (e) => done(e), (e) => error(e) ) ) }, "indexeddb", true ) allfuncs.new( "indexeddb_setup", async function ( //promise obj //object|none ) { return new Promise((e) => { var x obj = { ...{ dbVersion: 1, storeName: "tempstorename", keyPath: "id", autoIncrement: true, }, ...obj, onStoreReady() { e(x) }, } if (!window.IDBStore) { //IDBStore start ;(function (p, h, k) { "function" === typeof define ? define(h) : "undefined" !== typeof module && module.exports ? (module.exports = h()) : (k[p] = h()) })( "IDBStore", function () { function p(a, b) { var c, d for (c in b) (d = b[c]), d !== u[c] && d !== a[c] && (a[c] = d) return a } var h = function (a) { throw a }, k = function () {}, r = { storeName: "Store", storePrefix: "IDBWrapper-", dbVersion: 1, keyPath: "id", autoIncrement: !0, onStoreReady: function () {}, onError: h, indexes: [], implementationPreference: [ "indexedDB", "webkitIndexedDB", "mozIndexedDB", "shimIndexedDB", ], }, q = function (a, b) { "undefined" == typeof b && "function" == typeof a && (b = a) "[object Object]" != Object.prototype.toString.call(a) && (a = {}) for (var c in r) this[c] = "undefined" != typeof a[c] ? a[c] : r[c] this.dbName = this.storePrefix + this.storeName this.dbVersion = parseInt(this.dbVersion, 10) || 1 b && (this.onStoreReady = b) var d = "object" == typeof window ? window : self this.implementation = this.implementationPreference.filter( function (a) { return a in d } )[0] this.idb = d[this.implementation] this.keyRange = d.IDBKeyRange || d.webkitIDBKeyRange || d.mozIDBKeyRange this.consts = { READ_ONLY: "readonly", READ_WRITE: "readwrite", VERSION_CHANGE: "versionchange", NEXT: "next", NEXT_NO_DUPLICATE: "nextunique", PREV: "prev", PREV_NO_DUPLICATE: "prevunique", } this.openDB() }, t = { constructor: q, version: "1.7.2", db: null, dbName: null, dbVersion: null, store: null, storeName: null, storePrefix: null, keyPath: null, autoIncrement: null, indexes: null, implementationPreference: null, implementation: "", onStoreReady: null, onError: null, _insertIdCount: 0, openDB: function () { var a = this.idb.open(this.dbName, this.dbVersion), b = !1 a.onerror = function (a) { var b b = "error" in a.target ? "VersionError" == a.target.error.name : "errorCode" in a.target ? 12 == a.target.errorCode : !1 if (b) this.onError( Error( "The version number provided is lower than the existing one." ) ) else a.target.error ? (a = a.target.error) : ((b = "IndexedDB unknown error occurred when opening DB " + this.dbName + " version " + this.dbVersion), "errorCode" in a.target && (b += " with error code " + a.target.errorCode), (a = Error(b))), this.onError(a) }.bind(this) a.onsuccess = function (a) { if (!b) if (this.db) this.onStoreReady() else if ( ((this.db = a.target.result), "string" == typeof this.db.version) ) this.onError( Error( "The IndexedDB implementation in this browser is outdated. Please upgrade your browser." ) ) else if ( this.db.objectStoreNames.contains(this.storeName) ) { this.store = this.db .transaction( [this.storeName], this.consts.READ_ONLY ) .objectStore(this.storeName) var d = Array.prototype.slice.call( this.getIndexList() ) this.indexes.forEach(function (a) { var c = a.name if (c) if ( (this.normalizeIndexData(a), this.hasIndex(c)) ) { var g = this.store.index(c) this.indexComplies(g, a) || ((b = !0), this.onError( Error( 'Cannot modify index "' + c + '" for current version. Please bump version number to ' + (this.dbVersion + 1) + "." ) )) d.splice(d.indexOf(c), 1) } else (b = !0), this.onError( Error( 'Cannot create new index "' + c + '" for current version. Please bump version number to ' + (this.dbVersion + 1) + "." ) ) else (b = !0), this.onError( Error( "Cannot create index: No index name given." ) ) }, this) d.length && ((b = !0), this.onError( Error( 'Cannot delete index(es) "' + d.toString() + '" for current version. Please bump version number to ' + (this.dbVersion + 1) + "." ) )) b || this.onStoreReady() } else this.onError( Error("Object store couldn't be created.") ) }.bind(this) a.onupgradeneeded = function (a) { this.db = a.target.result this.db.objectStoreNames.contains(this.storeName) ? (this.store = a.target.transaction.objectStore( this.storeName )) : ((a = { autoIncrement: this.autoIncrement }), null !== this.keyPath && (a.keyPath = this.keyPath), (this.store = this.db.createObjectStore( this.storeName, a ))) var d = Array.prototype.slice.call(this.getIndexList()) this.indexes.forEach(function (a) { var c = a.name c || ((b = !0), this.onError( Error("Cannot create index: No index name given.") )) this.normalizeIndexData(a) if (this.hasIndex(c)) { var g = this.store.index(c) this.indexComplies(g, a) || (this.store.deleteIndex(c), this.store.createIndex(c, a.keyPath, { unique: a.unique, multiEntry: a.multiEntry, })) d.splice(d.indexOf(c), 1) } else this.store.createIndex(c, a.keyPath, { unique: a.unique, multiEntry: a.multiEntry, }) }, this) d.length && d.forEach(function (a) { this.store.deleteIndex(a) }, this) }.bind(this) }, deleteDatabase: function (a, b) { if (this.idb.deleteDatabase) { this.db.close() var c = this.idb.deleteDatabase(this.dbName) c.onsuccess = a c.onerror = b } else b( Error( "Browser does not support IndexedDB deleteDatabase!" ) ) }, put: function (a, b, c, d) { null !== this.keyPath && ((d = c), (c = b), (b = a)) d || (d = h) c || (c = k) var f = !1, e = null, g = this.db.transaction( [this.storeName], this.consts.READ_WRITE ) g.oncomplete = function () { ;(f ? c : d)(e) } g.onabort = d g.onerror = d null !== this.keyPath ? (this._addIdPropertyIfNeeded(b), (a = g .objectStore(this.storeName) .put(isproxy(b) ? JSON.parse(JSON.stringify(b)) : b))) : (a = g.objectStore(this.storeName).put(b, a)) a.onsuccess = function (a) { f = !0 e = a.target.result } a.onerror = d return g }, get: function (a, b, c) { c || (c = h) b || (b = k) var d = !1, f = null, e = this.db.transaction( [this.storeName], this.consts.READ_ONLY ) e.oncomplete = function () { ;(d ? b : c)(f) } e.onabort = c e.onerror = c a = e.objectStore(this.storeName).get(a) a.onsuccess = function (a) { d = !0 f = a.target.result } a.onerror = c return e }, remove: function (a, b, c) { c || (c = h) b || (b = k) var d = !1, f = null, e = this.db.transaction( [this.storeName], this.consts.READ_WRITE ) e.oncomplete = function () { ;(d ? b : c)(f) } e.onabort = c e.onerror = c a = e.objectStore(this.storeName)["delete"](a) a.onsuccess = function (a) { d = !0 f = a.target.result } a.onerror = c return e }, batch: function (a, b, c) { c || (c = h) b || (b = k) if ("[object Array]" != Object.prototype.toString.call(a)) c(Error("dataArray argument must be of type Array.")) else if (0 === a.length) return b(!0) var d = a.length, f = !1, e = !1, g = this.db.transaction( [this.storeName], this.consts.READ_WRITE ) g.oncomplete = function () { ;(e ? b : c)(e) } g.onabort = c g.onerror = c var l = function () { d-- 0 !== d || f || (e = f = !0) } a.forEach(function (a) { var b = a.type, d = a.key, e = a.value a = function (a) { g.abort() f || ((f = !0), c(a, b, d)) } "remove" == b ? ((e = g.objectStore(this.storeName)["delete"](d)), (e.onsuccess = l), (e.onerror = a)) : "put" == b && (null !== this.keyPath ? (this._addIdPropertyIfNeeded(e), (e = g.objectStore(this.storeName).put(e))) : (e = g.objectStore(this.storeName).put(e, d)), (e.onsuccess = l), (e.onerror = a)) }, this) return g }, putBatch: function (a, b, c) { a = a.map(function (a) { return { type: "put", value: a } }) return this.batch(a, b, c) }, upsertBatch: function (a, b, c, d) { "function" == typeof b && ((d = c = b), (b = {})) d || (d = h) c || (c = k) b || (b = {}) "[object Array]" != Object.prototype.toString.call(a) && d(Error("dataArray argument must be of type Array.")) var f = b.keyField || this.keyPath, e = a.length, g = !1, l = !1, n = 0, m = this.db.transaction( [this.storeName], this.consts.READ_WRITE ) m.oncomplete = function () { l ? c(a) : d(!1) } m.onabort = d m.onerror = d var v = function (b) { a[n++][f] = b.target.result e-- 0 !== e || g || (l = g = !0) } a.forEach(function (a) { var b = a.key null !== this.keyPath ? (this._addIdPropertyIfNeeded(a), (a = m.objectStore(this.storeName).put(a))) : (a = m.objectStore(this.storeName).put(a, b)) a.onsuccess = v a.onerror = function (a) { m.abort() g || ((g = !0), d(a)) } }, this) return m }, removeBatch: function (a, b, c) { a = a.map(function (a) { return { type: "remove", key: a } }) return this.batch(a, b, c) }, getBatch: function (a, b, c, d) { c || (c = h) b || (b = k) d || (d = "sparse") if ("[object Array]" != Object.prototype.toString.call(a)) c(Error("keyArray argument must be of type Array.")) else if (0 === a.length) return b([]) var f = [], e = a.length, g = !1, l = null, n = this.db.transaction( [this.storeName], this.consts.READ_ONLY ) n.oncomplete = function () { ;(g ? b : c)(l) } n.onabort = c n.onerror = c var m = function (a) { a.target.result || "dense" == d ? f.push(a.target.result) : "sparse" == d && f.length++ e-- 0 === e && ((g = !0), (l = f)) } a.forEach(function (a) { a = n.objectStore(this.storeName).get(a) a.onsuccess = m a.onerror = function (a) { l = a c(a) n.abort() } }, this) return n }, getAll: function (a, b) { b || (b = h) a || (a = k) var c = this.db.transaction( [this.storeName], this.consts.READ_ONLY ), d = c.objectStore(this.storeName) d.getAll ? this._getAllNative(c, d, a, b) : this._getAllCursor(c, d, a, b) return c }, _getAllNative: function (a, b, c, d) { var f = !1, e = null a.oncomplete = function () { ;(f ? c : d)(e) } a.onabort = d a.onerror = d a = b.getAll() a.onsuccess = function (a) { f = !0 e = a.target.result } a.onerror = d }, _getAllCursor: function (a, b, c, d) { var f = [], e = !1, g = null a.oncomplete = function () { ;(e ? c : d)(g) } a.onabort = d a.onerror = d a = b.openCursor() a.onsuccess = function (a) { ;(a = a.target.result) ? (f.push(a.value), a["continue"]()) : ((e = !0), (g = f)) } a.onError = d }, clear: function (a, b) { b || (b = h) a || (a = k) var c = !1, d = null, f = this.db.transaction( [this.storeName], this.consts.READ_WRITE ) f.oncomplete = function () { ;(c ? a : b)(d) } f.onabort = b f.onerror = b var e = f.objectStore(this.storeName).clear() e.onsuccess = function (a) { c = !0 d = a.target.result } e.onerror = b return f }, _addIdPropertyIfNeeded: function (a) { "undefined" == typeof a[this.keyPath] && (a[this.keyPath] = this._insertIdCount++ + Date.now()) }, getIndexList: function () { return this.store.indexNames }, hasIndex: function (a) { return this.store.indexNames.contains(a) }, normalizeIndexData: function (a) { a.keyPath = a.keyPath || a.name a.unique = !!a.unique a.multiEntry = !!a.multiEntry }, indexComplies: function (a, b) { return ["keyPath", "unique", "multiEntry"].every(function ( c ) { if ("multiEntry" == c && void 0 === a[c] && !1 === b[c]) return !0 if ( "keyPath" == c && "[object Array]" == Object.prototype.toString.call(b[c]) ) { c = b.keyPath var d = a.keyPath if ("string" == typeof d) return c.toString() == d if ( ("function" != typeof d.contains && "function" != typeof d.indexOf) || d.length !== c.length ) return !1 for (var f = 0, e = c.length; f < e; f++) if ( !( (d.contains && d.contains(c[f])) || d.indexOf(-1 !== c[f]) ) ) return !1 return !0 } return b[c] == a[c] }) }, iterate: function (a, b) { b = p( { index: null, order: "ASC", autoContinue: !0, filterDuplicates: !1, keyRange: null, writeAccess: !1, onEnd: null, onError: h, limit: Infinity, offset: 0, allowItemRejection: !1, }, b || {} ) var c = "desc" == b.order.toLowerCase() ? "PREV" : "NEXT" b.filterDuplicates && (c += "_NO_DUPLICATE") var d = !1, f = this.db.transaction( [this.storeName], this.consts[b.writeAccess ? "READ_WRITE" : "READ_ONLY"] ), e = f.objectStore(this.storeName) b.index && (e = e.index(b.index)) var g = 0 f.oncomplete = function () { if (d) if (b.onEnd) b.onEnd() else a(null) else b.onError(null) } f.onabort = b.onError f.onerror = b.onError c = e.openCursor(b.keyRange, this.consts[c]) c.onerror = b.onError c.onsuccess = function (c) { if ((c = c.target.result)) if (b.offset) c.advance(b.offset), (b.offset = 0) else { var e = a(c.value, c, f) ;(b.allowItemRejection && !1 === e) || g++ if (b.autoContinue) if (g + b.offset < b.limit) c["continue"]() else d = !0 } else d = !0 } return f }, query: function (a, b) { var c = [], d = 0 b = b || {} b.autoContinue = !0 b.writeAccess = !1 b.allowItemRejection = !!b.filter b.onEnd = function () { a(c, d) } return this.iterate(function (a) { d++ var e = b.filter ? b.filter(a) : !0 !1 !== e && c.push(a) return e }, b) }, count: function (a, b) { b = p({ index: null, keyRange: null }, b || {}) var c = b.onError || h, d = !1, f = null, e = this.db.transaction( [this.storeName], this.consts.READ_ONLY ) e.oncomplete = function () { ;(d ? a : c)(f) } e.onabort = c e.onerror = c var g = e.objectStore(this.storeName) b.index && (g = g.index(b.index)) g = g.count(b.keyRange) g.onsuccess = function (a) { d = !0 f = a.target.result } g.onError = c return e }, makeKeyRange: function (a) { var b = "undefined" != typeof a.lower, c = "undefined" != typeof a.upper, d = "undefined" != typeof a.only switch (!0) { case d: a = this.keyRange.only(a.only) break case b && c: a = this.keyRange.bound( a.lower, a.upper, a.excludeLower, a.excludeUpper ) break case b: a = this.keyRange.lowerBound(a.lower, a.excludeLower) break case c: a = this.keyRange.upperBound(a.upper, a.excludeUpper) break default: throw Error( 'Cannot create KeyRange. Provide one or both of "lower" or "upper" value, or an "only" value.' ) } return a }, }, u = {} q.prototype = t q.version = t.version return q }, this ) //IDBStore end } x = new IDBStore(obj) }) }, "indexeddb", true ) allfuncs.new( "keepsame", function ( //object|any thing //object|element ) { var all = [] var x = new Proxy(thing, { get(_obj, prop) { if (prop == "val") return _obj if (prop == "all") return all if (prop == "func") return function (e) { all.push(e(thing)) return x } return function (...args) { try { all.push(thing[prop](thing, ...args)) } catch (e) { all.push(thing[prop]) } return x } }, }) return x }, "function", true ) allfuncs.new( "scratch_press", function ( //string key //string ) { if (key == " ") key = "space" if (/^[a-z]$/.test(key)) key = key.toUpperCase() var index = vm.runtime.ioDevices.keyboard._keysPressed.indexOf(key) if (index !== -1) { vm.runtime.ioDevices.keyboard._keysPressed.splice(index, 1) } vm.runtime.ioDevices.keyboard._keysPressed.push(key) vm.runtime.startHats("event_whenkeypressed", { KEY_OPTION: key, }) vm.runtime.startHats("event_whenkeypressed", { KEY_OPTION: "any", }) return key }, "scratch" ) allfuncs.new( "scratch_unpress", function ( //undefined key //string ) { if (key == " ") key = "space" if (/^[a-z]$/.test(key)) key = key.toUpperCase() var index = vm.runtime.ioDevices.keyboard._keysPressed.indexOf(key) if (index !== -1) { vm.runtime.ioDevices.keyboard._keysPressed.splice(index, 1) } }, "scratch" ) allfuncs.new("strictfunction", strictfunction, "function/typescript", true) allfuncs.new( "readfileslow", function ( //undefined file, //file type = "Text", //string|undefined cb1 = (e) => e, //function|undefined cb2 = (e) => e //function|undefined ) { var fileSize = file.size var chunkSize = 64 * 1024 * 50 // bytes var offset = 0 var chunkReaderBlock = null var arr = [] var lastidx var readEventHandler = function (evt, idx) { if (evt.target.error == null) { arr.push([idx, evt.target.result]) cb1(a(arr.length).rerange(0, lastidx, 0, 100).val) if (arr.length === lastidx) cb2(arr.sort((e) => e[0]).map((e) => e[1])) } else { return error("Read error: " + evt.target.error) } } chunkReaderBlock = function (_offset, length, _file, idx) { var r = new FileReader() var blob = _file.slice(_offset, length + _offset) const zzz = idx + 1 r.onload = function (e) { readEventHandler(e, zzz - 1) } r["readAs" + type](blob) } let idx = 0 while (offset < fileSize) { idx++ chunkReaderBlock(offset, chunkSize, file, idx) offset += chunkSize } lastidx = idx }, "file" ) allfuncs.new( "cbtoasync", function ( //promise func, //function ...args //any ) { return new Promise(function (resolve) { func(...args, resolve) }) }, "function" ) allfuncs.new( "asynctocb", function ( //undefined func, //function ...args //any ) { var cb = args.pop() return func(...args).then(cb) }, "function" ) // ;(function () { // const samerand = function () //string // { // return ( // lastrand || // (lastrand = samerand.new(20, { // lower: true, // upper: true, // })) // ) // } // allfuncs.new("samerand", samerand, "function/random", false) // var lastrand = "" // samerand.new = ( // e = 20, // { lower = true, upper = false, number = false, symbol = false } = { // lower: true, // upper: false, // number: false, // symbol: false, // } // ) => ( // (lastrand = ""), // a( // () => // (lastrand += a( // `${lower ? "asdfghjklzxcvbnmqwertyuiop" : ""}${ // upper ? "ASDFGHJKLQWERTYUIOPZXCVBNM" : "" // }${number ? "0123456789" : ""}${ // symbol ? ",./;'[]-=\\`~!@#$%^&*()_+|{}:\"<>?" : "" // }`.split("") // ).randfrom().val) // ).repeat(e), // lastrand // ) // })() allfuncs.new( "randstr", function ( /*string|input of object: { lower = true, //boolean|undefined upper = false, //boolean|undefined number = false, //boolean|undefined symbol = false, //boolean|undefined length = 20, //number|undefined } */ { lower = true, upper = false, number = false, symbol = false, length = 20, } = { lower: true, upper: false, number: false, symbol: false, length: 20, } ) { var rand = "" a(() => { rand += a( `${lower ? "asdfghjklzxcvbnmqwertyuiop" : ""}${ upper ? "ASDFGHJKLQWERTYUIOPZXCVBNM" : "" }${number ? "0123456789" : ""}${ symbol ? ",./;'[]-=\\`~!@#$%^&*()_+|{}:\"<>?" : "" }`.split("") ).randfrom().val }).repeat(length) return rand }, "random/string" ) allfuncs.new( "toplaces", function ( //string num, //number|string pre, //number|none post = 0, //number|undefined func = Math.round //function ) { num = String(num).split(".") if (num.length == 1) num.push("") if (pre !== undefined) { num[0] = num[0].substring(num[0].length - pre, num[0].length) while (num[0].length < pre) num[0] = "0" + num[0] } var temp = num[1].substring(post, post + 1) ?? 0 num[1] = num[1].substring(0, post) while (num[1].length < post) num[1] += "0" if (post > 0) { temp = func(num[1].at(-1) + "." + temp) num[1] = num[1].split("") num[1].pop() num[1].push(temp) num[1] = num[1].join("") num = num.join(".") } else num = num[0] return num }, "number/format", true ) allfuncs.new( "forcenumlength", function ( //string string, //string lengths //array|number|object ) { var i = -1 if (a(lengths).gettype("object").val) { lengths = lengths[[...string.matchAll(/\d+(?:\.\d+)?/g)].length] } if (!lengths) { log(string) debugger } return string.replaceAll(/\d+(?:\.\d+)?/g, function (v) { i++ try { return a(lengths[i]).gettype("array").val ? a(Number(v)).toplaces(lengths[i][0], lengths[i][1]).val : a(Number(v)).toplaces(lengths[i], 0).val } catch (e) { log(string, lengths, i) debugger } }) }, "number/format", true ) ;(function () { var lasttime = Date.now() allfuncs.new( "tick", function () { //number var time = Date.now() - lasttime lasttime = Date.now() return time }, "time" ) })() allfuncs.new("expandederror", expandederror, "error", true) allfuncs.new( "fetch", async function ( //promise url, //string type = "text", //string|none ...args //any|undefined ) { return await (await fetch(url, ...args))[type]() }, "url/web" ) allfuncs.new( "copy", function ( //string text //string ) { navigator.clipboard.writeText(text) return "" try { var temp = a(document.body) .createelem("textarea", { value: text, width: 0, height: 0, position: "fixed", top: 0, left: 0, }) .run.same.focus() .run.same.select() document.execCommand("copy") temp.run.remove() } catch (e) { navigator.clipboard.writeText(text) } return text }, "clipboard" ) // allfuncs.new( // "cache", // (function () { // var cac = {} // function cache( //any // args, //arguments|any // data, //function // notfoundincache //function|undefined // ) { // // if (a(args).gettype(["array", "arguments"]).val) // // args = [...args].join("\u1111") // args = JSON.stringify(args) // var c = String(arguments.callee.caller).replaceAll(/\s\s+/g, " ").trim() // // log(structuredClone(cac)) // if (!cac[c]) cac[c] = {} // if (args in cac[c]) return cac[c][args] // cac[c][args] = data() // if (notfoundincache) notfoundincache(cac[c][args]) // return cac[c][args] // } // cache.getall = function () { // return cac // } // cache.setall = function (e) { // return (cac = e) // } // cache.add = function (e) { // return (cac = { ...cac, ...e }) // } // cache.clear = function () { // cac = {} // } // return cache // })(), // "data/storage" // ) Object.keys(console).forEach((e) => allfuncs.new( e, (/*undefined*/ ...z /*any*/) => console[e](...z), "console/debug" ) ) allfuncs.new( "replaceall", function ( //string text, //string regex, //regex|string|array replacewith //string|function ) { return text.replaceAll( a(String(a(regex).toregex().val) + "g").toregex().val, replacewith ) }, "" ) allfuncs.new( "setrange", function ( //number num, //number min, //number max //number ) { return num < min ? min : num > max ? max : num }, "number" ) allfuncs.new( "isstrict", function ( //boolean thing //array|object ) { return thing?.strictargs?.[0] === isstrict }, "typescript" ) allfuncs.new( "runonalltext", function ( //undefined func, //function ignoretags = ["STYLE", "SCRIPT", "NOSCRIPT"] //array|undefined ) { // log(String(func)) a("*").qsa().foreach(repl) watch(document.documentElement) function watch(elem) { new MutationObserver((e) => { if (location.href.includes("scratch.mit.edu/projects")) return ;[...e].forEach((e) => repl(e.target)) // ;[...e].forEach((e) => [...e.addedNodes].forEach(repl)) }).observe(elem, { childList: true, subtree: true, attributes: true, characterData: false, }) } function repl(node) { if (node.shadowRoot) { a("*").qsa(node.shadowRoot).foreach(repl) watch(node.shadowRoot) return repl(node.shadowRoot) } if (ignoretags.includes(node.tagName)) return var nodes = node?.childNodes if (!nodes) return for (var i = 0, m = nodes.length; i < m; i++) { var n = nodes[i] // if (n.textContent.includes("Jul 17, 2021")) log(n, n.textContent) if (n.nodeType == n.TEXT_NODE) { func(n) } else { repl(n) } } } }, "text/elem" ) allfuncs.new( "runonallelems", function ( //undefined func, //function selector = "*", //string|undefined ignoretags = [] //array|undefined ) { a("*").qsa().foreach(repl) watch(document.documentElement) function watch(elem) { new MutationObserver((e) => { if (location.href.includes("scratch.mit.edu/projects")) return ;[...e].forEach((e) => repl(e.target)) }).observe(elem, { childList: true, subtree: true, attributes: true, characterData: true, }) } function repl(elem) { if (elem.shadowRoot) { repl(elem.shadowRoot) a("*").qsa(elem.shadowRoot).foreach(repl) watch(elem.shadowRoot) } if (elem.children) [...elem.children].forEach(repl) if (!elem.matches) return if (ignoretags.includes(elem.tagName)) return if (elem.matches(selector)) func(elem) } }, "elem" ) savelib("allfuncs", a) function extras() { ;(() => { if (!window.showDirectoryPicker) return if (!window.showOpenFilePicker) return if (!window.showSaveFilePicker) return const old = { showDirectoryPicker: showDirectoryPicker.bind(window), showOpenFilePicker: showOpenFilePicker.bind(window), showSaveFilePicker: showSaveFilePicker.bind(window), } showDirectoryPicker = a(function ( //promise obj = false //object|boolean|undefined ) { if (obj === true) { obj = { mode: "readwrite" } } else if (obj === false) { obj = { mode: "read" } } return old.showDirectoryPicker(obj) }).strictfunction("showDirectoryPicker").val showOpenFilePicker = a(async function ( //promise obj = {}, //object|undefined write, //boolean|undefined multiple, //boolean|undefined types, //array|undefined exts, //array|string|undefined excludeAcceptAllOption = false //boolean|undefined ) { if (obj.types && !types) { types = obj.types delete obj.types } if (obj.exts && !exts) { exts = obj.exts delete obj.exts } if (excludeAcceptAllOption) obj.excludeAcceptAllOption = true if (obj.name) obj.suggestedName = obj.name if (multiple !== undefined) { obj.multiple = multiple delete obj.name } if (exts) { obj.types = { accept: { "*/*": exts, }, } } if (types) { if (!obj.type) obj.type = { accept: {} } types.forEach((type) => (obj.type.accept[type] = ["*"])) } if (obj.multiple) return await old.showOpenFilePicker(obj) var x = await old.showOpenFilePicker(obj) x = x[0] ?? x if (obj.mode == "readwrite" || write) if ((await x.requestPermission({ mode: "readwrite" })) !== "granted") throw new Error("user didn't grant write permission") return x }).strictfunction("showOpenFilePicker").val showSaveFilePicker = a(function ( //promise obj = {}, //object|none|string multiple = false, //boolean|none types, //array|none exts, //array|string|none excludeAcceptAllOption = false //boolean|undefined ) { if (typeof obj == "string") obj = { suggestedName: obj } if (obj.types && !types) { types = obj.types delete obj.types } if (obj.exts && !exts) { exts = obj.exts delete obj.exts } if (excludeAcceptAllOption) obj.excludeAcceptAllOption = true if (obj.name) obj.suggestedName = obj.name if (multiple !== undefined) { obj.multiple = multiple delete obj.name } if (exts) { obj.types = { accept: { "*/*": exts, }, } } if (types) { if (!obj.type) obj.type = { accept: {} } types.forEach((type) => (obj.type.accept[type] = ["*"])) } return old.showSaveFilePicker(obj) }).strictfunction("showSaveFilePicker").val })() } extras() //log(...Object.keys( allfuncs).map(e=>[e, allfuncs[e].help, allfuncs[e]]||warn(e))) })()
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址