{
	"functions": {
		"increase": {
			"js": "let args = arguments[0]; let count = js.element({path:args}) || 0; count+=1; js.element({path:args, value: count}); "
		},
		"decrease": {
			"js": "let args = arguments[0]; let count = js.element({path:args}) || 0; count-=1; js.element({path:args, value: count}); "
		},
		"random": {
			"js": "let args = arguments[0]; let from=0, to=Infinity, decimals=0; if (Array.isArray(args)) {[from, to, decimals] = args;} else {to = args;} from = Number(from); to = Number(to); decimals = Number(decimals); return Number((from + (to-from)*Math.random()).toFixed(decimals))"
		},
		"removeFromArray": {
			"js": "let args = arguments[0]; let arr = js.element({path:args.from}); let index = arr.indexOf(args.value); if (index > -1) arr.splice(index, 1); js.element({path:args.from, value:arr});"
		},
		"substr": {
			"js": "let args = arguments[0]; let str, from=0, length; if (Array.isArray(args)) {[str, from, length] = args;} else {str = args;} console.warn('from:'+from + ' length:'+length + 'str:'+str); return str.substr(from, length);"
		},
		"stringify": {
			"js": "let args = arguments[0]; return JSON.strinfigy(args);"
		},
		"exportJSON": {
			"arguments": {
				"type": "object",
				"properties": {
					"name": {
						"type": "string"
					},
					"data": {
						"type": "object"
					}
				},
				"required": [
					"name",
					"data"
				]
			},
			"js": "let args = arguments[0]; let el = document.createElement('a'); el.style.display = 'none'; el.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(JSON.stringify(args.data, null, '\t'))); el.setAttribute('download', args.name); document.body.appendChild(el); el.click(); document.body.removeChild(el);"
		},
		"fetch": {
			"note": "check if can be replaced with fetchJson adding the type parameter (json, form)",
			"js": "let args = arguments[0], formData = new FormData(); window.formData = formData; if (args.data) for (key in args.data) formData.append(key, args.data[key]); if (args.data) args.options.body = formData; fetch(args.url, args.options).then(response => response.json()).then(data => {js.callback({do:args.success, to:args.to, var:args.var, value:data}) }).catch((error)=>{console.warn('ERROR fetching '+args.url); console.warn(error); js.callback({do:args.error}) })"
		},
		"fetchToken": {
			"js": "let args = arguments[0]; if (args.options.body && typeof args.options.body !== 'string') args.options.body = JSON.stringify(args.options.body); fetch(args.url, args.options).then(response => response.json()).then(data => {console.log('fetchJson success'); console.log(data);}).catch((err) => {console.log('fetchJson error');console.log(err);})"
		},
		"fetchJson": {
			"js": "let args = arguments[0]; console.log('fetchJson'); console.log(args); if (args.options.body) args.options.body = JSON.stringify(args.options.body); fetch(args.url, args.options).then(response => response.json()).then(data => {console.log('data'); console.log(data); if (data) {js.callback({do:args.success, to:args.to, var:args.var, value:data})} }).catch((err)=>{console.log('fetchJson error'); console.log(err); if (args.error) js.callback({do:args.error}) })"
		},
		"formDataToJson": {
			"js": "let args = arguments[0]; let selector = args[0]; var object = {}; let formData = new FormData(document.querySelector(selector)); formData.forEach((value, key) => object[key] = value); return JSON.stringify(object);"
		},
		"uploadFromUrl": {
			"note": "add: if args.data[dataKey] not string -> JSON.stringify(args.data[dataKey])",
			"js": "let args = arguments[0]; if (!args.options) args.options = {method: 'POST'}; let el = document.createElement('a'); document.documentElement.append(el); el.append(document.createElement('img')); fetch(args.file.url).then(res => res.blob()).then(blob => {const myFile = new File([blob], 'image.jpg', blob); let formData = new FormData(); if (args.data) for (dataKey in args.data) formData.append(dataKey, args.data[dataKey]); formData.append(args.file.key, myFile); let options = JSON.parse(JSON.stringify(args.options)); options.body = formData; fetch(args.url, options).then(response => response.json()).then(data => { js.callback({ do: args.success, to: args.to, var: args.var, value: data }) }).catch((error) => { console.warn('ERROR fetching ' + args.url); console.warn(error); js.callback({ do: args.error }) }) })"
		},
		"upload": {
			"js": "let args = arguments[0], inp = document.querySelector(args.file.selector); for (let fileKey=0; fileKey < inp.files.length; fileKey++) {let formData = new FormData(); if (args.data) for (dataKey in args.data) formData.append(dataKey, args.data[dataKey]); formData.append(args.file.key, inp.files[fileKey]); let options = JSON.parse(JSON.stringify(args.options)); options.body = formData; fetch(args.url, options).then(response => response.json()).then(data => { js.callback({ do: args.success, to: args.to, var: args.var, value: data }) }).catch((error) => { console.warn('ERROR fetching ' + args.url); console.warn(error); js.callback({ do: args.error }) }) }"
		},
		"fileFromUrl": {
			"js": "let args = arguments[0]; let el = document.createElement('a'); document.documentElement.append(el); el.append(document.createElement('img')); fetch(args.url).then(res => res.blob()).then(blob => {console.log(blob); const myFile = new File([blob], 'image.jpg', blob);console.log(myFile); return myFile })"
		},
		"downloadImage": {
			"js": "let args = arguments[0]; let el = document.createElement('a'); document.documentElement.append(el); el.append(document.createElement('img')); fetch(args.url).then(res => res.blob()).then(blob => {el.download = args.name; el.href = URL.createObjectURL(blob); el.click(); document.documentElement.removeChild(el);})"
		}
	},
	"note": {
		"split": {
			"note": "use var x: '{var list}'.split(',')",
			"js": "let args = arguments[0]; let splitter=',', elements=''; if (Array.isArray(args)) {[elements, splitter] = args;} else {elements = args;} return elements.split(splitter);"
		},
		"reverse": {
			"note": "or use set var x: {var y}.reverse()",
			"js": "let args = arguments[0]; let path = ''; if (Array.isArray(args)) {[path] = args;} else {path = args;} let arr = js.element({path:path}); return arr.reverse() "
		},
		"sort": {
			"note": "work in progress",
			"js": "let args = arguments[0]; let el = js.element({path:args.list}); "
		},
		"push": {
			"js": "let args = arguments[0]; let arr = js.element({path:args.to}); arr.push(args.value); js.element({path:args.to, value:arr});"
		},
		"pop": {
			"js": "let args = arguments[0]; let arr = js.element({path:args.from}); arr.pop(args.value); js.element({path:args.from, value:arr});"
		}
	},
	"parts": {
		"objects": {
			"exportData": {
				"do": [
					{
						"exportJSON": {
							"name": "{arguments}.json",
							"data": "{data {arguments}}"
						}
					}
				]
			}
		}
	}
}