diff --git a/client/modules/IDE/components/Editor/index.jsx b/client/modules/IDE/components/Editor/index.jsx index 90a0b450fb..494d7c2052 100644 --- a/client/modules/IDE/components/Editor/index.jsx +++ b/client/modules/IDE/components/Editor/index.jsx @@ -73,6 +73,8 @@ import { EditorContainer, EditorHolder } from './MobileEditor'; import { FolderIcon } from '../../../../common/icons'; import IconButton from '../../../../common/IconButton'; +import contextAwareHinter from '../contextAwareHinter'; + emmet(CodeMirror); window.JSHINT = JSHINT; @@ -465,11 +467,8 @@ class Editor extends React.Component { () => { const c = _cm.getCursor(); const token = _cm.getTokenAt(c); - - const hints = this.hinter - .search(token.string) - .filter((h) => h.item.text[0] === token.string[0]); - + const hints = contextAwareHinter(_cm, { hinter: this.hinter }); + console.log('hints= ', hints); return { list: hints, from: CodeMirror.Pos(c.line, token.start), @@ -478,6 +477,26 @@ class Editor extends React.Component { }, hintOptions ); + + // CodeMirror.showHint( + // _cm, + // () => { + // const c = _cm.getCursor(); + // const token = _cm.getTokenAt(c); + // const hints = this.hinter + // .search(token.string) + // .filter((h) => h.item.text[0] === token.string[0]); + // console.log('c= ', c); + // console.log('token= ', token); + // console.log('hints= ', hints); + // return { + // list: hints, + // from: CodeMirror.Pos(c.line, token.start), + // to: CodeMirror.Pos(c.line, c.ch) + // }; + // }, + // hintOptions + // ); } else if (_cm.options.mode === 'css') { // CSS CodeMirror.showHint(_cm, CodeMirror.hint.css, hintOptions); diff --git a/client/modules/IDE/components/class-with-methods-map.json b/client/modules/IDE/components/class-with-methods-map.json new file mode 100644 index 0000000000..2e96ed4205 --- /dev/null +++ b/client/modules/IDE/components/class-with-methods-map.json @@ -0,0 +1,661 @@ +{ + "p5.Color": { + "createMethods": [ + "color", + "p5.Color" + ], + "methods": [ + "setAlpha", + "setBlue", + "setGreen", + "setRed", + "toString" + ] + }, + "p5.Geometry": { + "createMethods": [ + "beginGeometry", + "buildGeometry", + "endGeometry", + "freeGeometry", + "loadModel" + ], + "methods": [ + "calculateBoundingBox", + "clearColors", + "computeFaces", + "computeNormals", + "faces", + "flipU", + "flipV", + "normalize", + "saveObj", + "saveStl", + "uvs", + "vertexNormals", + "vertices" + ] + }, + "p5.MediaElement": { + "createMethods": [ + "createAudio", + "createCapture", + "createVideo", + "p5.MediaElement" + ], + "methods": [ + "addCue", + "autoplay", + "clearCues", + "connect", + "disconnect", + "duration", + "hideControls", + "loop", + "noLoop", + "onended", + "pause", + "play", + "removeCue", + "showControls", + "speed", + "src", + "stop", + "time", + "volume" + ] + }, + "p5.Camera": { + "createMethods": [ + "createCamera", + "p5.Camera" + ], + "methods": [ + "camera", + "centerX", + "centerY", + "centerZ", + "eyeX", + "eyeY", + "eyeZ", + "frustum", + "lookAt", + "move", + "ortho", + "pan", + "perspective", + "roll", + "set", + "setPosition", + "slerp", + "tilt", + "upX", + "upY", + "upZ" + ] + }, + "p5.Element": { + "createMethods": [ + "createCheckbox", + "createColorPicker", + "createElement", + "createImg", + "createRadio", + "createSelect", + "p5.Element", + "select", + "selectAll" + ], + "methods": [ + "addClass", + "attribute", + "center", + "child", + "class", + "doubleClicked", + "dragLeave", + "dragOver", + "draggable", + "drop", + "elt", + "hasClass", + "height", + "hide", + "html", + "id", + "mouseClicked", + "mouseMoved", + "mouseOut", + "mouseOver", + "mousePressed", + "mouseReleased", + "mouseWheel", + "parent", + "position", + "remove", + "removeAttribute", + "removeClass", + "show", + "size", + "style", + "toggleClass", + "touchEnded", + "touchMoved", + "touchStarted", + "value", + "width" + ] + }, + "p5.File": { + "createMethods": [ + "createFileInput", + "p5.File" + ], + "methods": [ + "data", + "file", + "name", + "size", + "subtype", + "type" + ] + }, + "p5.Shader": { + "createMethods": [ + "createFilterShader", + "createShader", + "loadShader", + "p5.Shader", + "shader" + ], + "methods": [ + "copyToContext", + "inspectHooks", + "modify", + "setUniform" + ] + }, + "p5.Framebuffer": { + "createMethods": [ + "createFramebuffer", + "p5.Framebuffer" + ], + "methods": [ + "autoSized", + "begin", + "color", + "createCamera", + "depth", + "draw", + "end", + "get", + "loadPixels", + "pixelDensity", + "pixels", + "remove", + "resize", + "updatePixels" + ] + }, + "p5.Graphics": { + "createMethods": [ + "createGraphics", + "p5.Graphics" + ], + "methods": [ + "createFramebuffer", + "remove", + "reset" + ] + }, + "p5.Image": { + "createMethods": [ + "createImage", + "get", + "loadImage", + "p5.Image" + ], + "methods": [ + "blend", + "copy", + "delay", + "filter", + "get", + "getCurrentFrame", + "height", + "loadPixels", + "mask", + "numFrames", + "pause", + "pixelDensity", + "pixels", + "play", + "reset", + "resize", + "save", + "set", + "setFrame", + "updatePixels", + "width" + ] + }, + "p5.NumberDict": { + "createMethods": [ + "createNumberDict" + ], + "methods": [ + "add", + "div", + "maxKey", + "maxValue", + "minKey", + "minValue", + "mult", + "sub" + ] + }, + "p5.StringDict": { + "createMethods": [ + "createStringDict" + ], + "methods": [] + }, + "p5.Vector": { + "createMethods": [ + "createVector", + "p5.Vector" + ], + "methods": [ + "add", + "angleBetween", + "array", + "clampToZero", + "copy", + "cross", + "dist", + "div", + "dot", + "equals", + "fromAngle", + "fromAngles", + "heading", + "lerp", + "limit", + "mag", + "magSq", + "mult", + "normalize", + "random2D", + "random3D", + "reflect", + "rem", + "rotate", + "set", + "setHeading", + "setMag", + "slerp", + "sub", + "toString", + "x", + "y", + "z" + ] + }, + "p5.PrintWriter": { + "createMethods": [ + "createWriter", + "p5.PrintWriter" + ], + "methods": [ + "clear", + "close", + "print", + "write" + ] + }, + "p5.Font": { + "createMethods": [ + "loadFont" + ], + "methods": [ + "font", + "textBounds", + "textToPoints" + ] + }, + "p5.Table": { + "createMethods": [ + "loadTable" + ], + "methods": [ + "addColumn", + "addRow", + "clearRows", + "columns", + "findRow", + "findRows", + "get", + "getArray", + "getColumn", + "getColumnCount", + "getNum", + "getObject", + "getRow", + "getRowCount", + "getRows", + "getString", + "matchRow", + "matchRows", + "removeColumn", + "removeRow", + "removeTokens", + "rows", + "set", + "setNum", + "setString", + "trim" + ] + }, + "p5.XML": { + "createMethods": [ + "loadXML" + ], + "methods": [ + "addChild", + "getAttributeCount", + "getChild", + "getChildren", + "getContent", + "getName", + "getNum", + "getParent", + "getString", + "hasAttribute", + "hasChildren", + "listAttributes", + "listChildren", + "removeChild", + "serialize", + "setAttribute", + "setContent", + "setName" + ] + }, + "p5.Envelope": { + "createMethods": [], + "methods": [ + "add", + "attackLevel", + "attackTime", + "decayLevel", + "decayTime", + "mult", + "play", + "ramp", + "releaseLevel", + "releaseTime", + "scale", + "set", + "setADSR", + "setExp", + "setInput", + "setRange", + "triggerAttack", + "triggerRelease" + ] + }, + "p5.FFT": { + "createMethods": [], + "methods": [ + "analyze", + "getCentroid", + "getEnergy", + "getOctaveBands", + "linAverages", + "logAverages", + "setInput", + "smooth", + "waveform" + ] + }, + "p5.Filter": { + "createMethods": [], + "methods": [ + "biquadFilter", + "freq", + "gain", + "process", + "res", + "set", + "setType", + "toggle" + ] + }, + "p5.Gain": { + "createMethods": [], + "methods": [ + "amp", + "connect", + "disconnect", + "setInput" + ] + }, + "p5.MonoSynth": { + "createMethods": [], + "methods": [ + "amp", + "attack", + "connect", + "disconnect", + "dispose", + "play", + "setADSR", + "triggerAttack", + "triggerRelease" + ] + }, + "p5.Noise": { + "createMethods": [], + "methods": [ + "setType" + ] + }, + "p5.Oscillator": { + "createMethods": [], + "methods": [ + "add", + "amp", + "connect", + "disconnect", + "freq", + "getAmp", + "getFreq", + "getPan", + "getType", + "mult", + "pan", + "phase", + "scale", + "setType", + "start", + "stop" + ] + }, + "p5.Panner3D": { + "createMethods": [], + "methods": [ + "maxDist", + "orient", + "orientX", + "orientY", + "orientZ", + "panner", + "positionX", + "positionY", + "positionZ", + "process", + "rollof", + "set", + "setFalloff" + ] + }, + "p5.Part": { + "createMethods": [], + "methods": [ + "addPhrase", + "getBPM", + "getPhrase", + "loop", + "noLoop", + "onStep", + "pause", + "removePhrase", + "replaceSequence", + "setBPM", + "start", + "stop" + ] + }, + "p5.PeakDetect": { + "createMethods": [], + "methods": [ + "onPeak", + "update" + ] + }, + "p5.Phrase": { + "createMethods": [], + "methods": [ + "sequence" + ] + }, + "p5.PolySynth": { + "createMethods": [], + "methods": [ + "AudioVoice", + "connect", + "disconnect", + "dispose", + "noteADSR", + "noteAttack", + "noteRelease", + "notes", + "play", + "polyvalue", + "setADSR" + ] + }, + "p5.Pulse": { + "createMethods": [], + "methods": [ + "width" + ] + }, + "p5.Reverb": { + "createMethods": [], + "methods": [ + "amp", + "connect", + "disconnect", + "process", + "set" + ] + }, + "p5.Score": { + "createMethods": [], + "methods": [ + "loop", + "noLoop", + "pause", + "setBPM", + "start", + "stop" + ] + }, + "p5.SoundFile": { + "createMethods": [], + "methods": [ + "addCue", + "channels", + "clearCues", + "connect", + "currentTime", + "disconnect", + "duration", + "frames", + "getBlob", + "getPan", + "getPeaks", + "isLoaded", + "isLooping", + "isPaused", + "isPlaying", + "jump", + "loop", + "onended", + "pan", + "pause", + "play", + "playMode", + "rate", + "removeCue", + "reverseBuffer", + "sampleRate", + "save", + "setBuffer", + "setLoop", + "setPath", + "setVolume", + "stop" + ] + }, + "p5.SoundLoop": { + "createMethods": [], + "methods": [ + "bpm", + "interval", + "iterations", + "maxIterations", + "musicalTimeMode", + "pause", + "start", + "stop", + "syncedStart", + "timeSignature" + ] + }, + "p5.SoundRecorder": { + "createMethods": [], + "methods": [ + "record", + "setInput", + "stop" + ] + }, + "p5.TableRow": { + "createMethods": [], + "methods": [ + "get", + "getNum", + "getString", + "set", + "setNum", + "setString" + ] + }, + "p5.TypedDict": { + "createMethods": [], + "methods": [ + "clear", + "create", + "get", + "hasKey", + "print", + "remove", + "saveJSON", + "saveTable", + "set", + "size" + ] + } +} \ No newline at end of file diff --git a/client/modules/IDE/components/contextAwareHinter.js b/client/modules/IDE/components/contextAwareHinter.js index ac4ca6452c..0a4b08e9f8 100644 --- a/client/modules/IDE/components/contextAwareHinter.js +++ b/client/modules/IDE/components/contextAwareHinter.js @@ -1,100 +1,161 @@ import CodeMirror from 'codemirror'; import parseCode from './parseCode'; +import parseCodeVars from './parseCodeVariables'; +import classMap from './class-with-methods-map.json'; const scopeMap = require('./finalScopeMap.json'); +function formatHintDisplay(name, isBlacklisted) { + return ` +
+ ${name} + ${ + isBlacklisted + ? `
⚠️ "${name}" is discouraged in this context.
` + : '' + } +
+ `; +} + +function getExpressionBeforeCursor(cm) { + const cursor = cm.getCursor(); + const line = cm.getLine(cursor.line); + const uptoCursor = line.slice(0, cursor.ch); + console.log('the line is: ', line); + console.log('the line uptocursor is: ', uptoCursor); + + const match = uptoCursor.match( + /([a-zA-Z_$][\w$]*(?:\.[a-zA-Z_$][\w$]*)*)\.(?:[a-zA-Z_$][\w$]*)?$/ + ); + return match ? match[1] : null; +} + export default function contextAwareHinter(cm, options = {}) { + const variableTypes = parseCodeVars(cm); + console.log('var types= ', variableTypes); + const { hinter } = options; if (!hinter || typeof hinter.search !== 'function') { console.warn('Hinter is not available or invalid.'); - return { list: [], from: cm.getCursor(), to: cm.getCursor() }; + return []; } - const { line, ch } = cm.getCursor(); // getCursor has line, ch, sticky - console.log('cm.getcursor ', cm.getCursor()); - const { start, end, string } = cm.getTokenAt({ line, ch }); - // console.log('cm.gettokenat', cm.getTokenAt()); + const baseExpression = getExpressionBeforeCursor(cm); + const className = variableTypes[baseExpression]; // e.g., p5.XML + console.log('base expression is= ', baseExpression); + + // If we're completing after a dot + if (baseExpression && className) { + console.log('Detected object expression:', baseExpression); + + console.log('Class of', baseExpression, '=', className); + + const methods = classMap[className]?.methods || []; + console.log('Available methods for class:', methods); + + const cursor = cm.getCursor(); + const lineText = cm.getLine(cursor.line); + const dotMatch = lineText + .slice(0, cursor.ch) + .match(/\.([a-zA-Z_$][\w$]*)?$/); + + let from = cursor; + if (dotMatch) { + const fullMatch = dotMatch[0]; + const methodStart = cursor.ch - fullMatch.length + 1; // +1 to skip the dot itself + from = { line: cursor.line, ch: methodStart }; + } else { + from = cursor; + } + + console.log('fromm, dotmatch= ', from, dotMatch); + + const to = { line: cursor.line, ch: cursor.ch }; + let tokenLength = 0; + if (dotMatch) { + const typed = dotMatch[1] || ''; // what's typed after the dot + tokenLength = typed.length; + } + + const typed = dotMatch?.[1]?.toLowerCase() || ''; + + const methodHints = methods + .filter((method) => method.toLowerCase().startsWith(typed)) + .map((method) => ({ + item: { + text: method, + type: 'fun' + }, + displayText: method, + from, + to + })); + + return methodHints; + } + + const { line, ch } = cm.getCursor(); + const { string } = cm.getTokenAt({ line, ch }); const currentWord = string.trim(); - console.log('currentwork ', currentWord); + console.log('current word= ', currentWord); + + const context = parseCode(cm); + const allHints = hinter.search(currentWord); - const context = parseCode(cm); // e.g. 'draw' - const allHints = hinter.search(currentWord); // <- from options, not cm.hinter const whitelist = scopeMap[context]?.whitelist || []; const blacklist = scopeMap[context]?.blacklist || []; - console.log('allhints: ', allHints); - // for each hint, only keep ones that match the typed prefix + const lowerCurrentWord = currentWord.toLowerCase(); + const filteredHints = allHints .filter( (h) => h && h.item && typeof h.item.text === 'string' && - h.item.text.startsWith(currentWord) + h.item.text.toLowerCase().startsWith(lowerCurrentWord) ) - .map((h) => { - const name = h.item.text; - const isWhitelisted = whitelist.includes(name); + .map((hint) => { + const name = hint.item?.text || ''; const isBlacklisted = blacklist.includes(name); - const from = CodeMirror.Pos(line, start); - const to = CodeMirror.Pos(line, end); - - let className = ''; - if (isBlacklisted) { - className = 'blacklisted-hint'; - } else if (isWhitelisted) { - className = 'whitelisted-hint'; - } - return { - text: name, // Ensure `text` is explicitly defined - displayText: h.item.displayText || name, - className, - from, - to, - render: (el, self, data) => { - el.innerText = data.text; - if (isBlacklisted) { - el.style.color = 'red'; - el.style.opacity = 0.6; - } else if (isWhitelisted) { - el.style.fontWeight = 'bold'; - } - }, - hint: (editor, data, completion) => { - const { from: fromPos, to: toPos } = completion; - - if (!completion.text || typeof completion.text !== 'string') { - console.error('Invalid completion.text:', completion); - return; - } - - editor.replaceRange(completion.text, fromPos, toPos); - - if (blacklist.includes(completion.text)) { - console.warn( - `Using "${completion.text}" inside "${context}" is not recommended.` - ); - } - } + ...hint, + isBlacklisted, + displayText: formatHintDisplay(name, isBlacklisted) }; }); - console.log('filtered hints: ', filteredHints); + const typePriority = { + fun: 0, + var: 1, + keyword: 2, + other: 3 + }; const sorted = filteredHints.sort((a, b) => { - const score = (name) => { - if (whitelist.includes(name)) return 0; - if (blacklist.includes(name)) return 2; - return 1; - }; - return score(a.text) - score(b.text) || a.text.localeCompare(b.text); + const nameA = a.item?.text || ''; + const nameB = b.item?.text || ''; + const typeA = a.item?.type || 'other'; + const typeB = b.item?.type || 'other'; + + const isBlacklistedA = a.isBlacklisted ? 1 : 0; + const isBlacklistedB = b.isBlacklisted ? 1 : 0; + + const typeScoreA = typePriority[typeA] ?? typePriority.other; + const typeScoreB = typePriority[typeB] ?? typePriority.other; + + if (isBlacklistedA !== isBlacklistedB) { + return isBlacklistedA - isBlacklistedB; + } + + if (typeScoreA !== typeScoreB) { + return typeScoreA - typeScoreB; + } + + return nameA.localeCompare(nameB); }); - return { - list: sorted, - from: CodeMirror.Pos(line, start), - to: CodeMirror.Pos(line, end) - }; + return sorted; } diff --git a/client/modules/IDE/components/parseCode.js b/client/modules/IDE/components/parseCode.js index bcaaf9f0ac..dc066b9ae2 100644 --- a/client/modules/IDE/components/parseCode.js +++ b/client/modules/IDE/components/parseCode.js @@ -1,6 +1,3 @@ -// parseCode.js -// import * as acorn from 'acorn'; -// import * as walk from 'acorn-walk'; const acorn = require('acorn'); const walk = require('acorn-walk'); diff --git a/client/modules/IDE/components/parseCodeBabel.js b/client/modules/IDE/components/parseCodeBabel.js new file mode 100644 index 0000000000..14e50d2e14 --- /dev/null +++ b/client/modules/IDE/components/parseCodeBabel.js @@ -0,0 +1,46 @@ +// parseCodeWithBabel.js +const parser = require('@babel/parser'); +const traverse = require('@babel/traverse').default; + +export default function parseCode(_cm) { + const code = _cm.getValue(); + const cursor = _cm.getCursor(); + const offset = _cm.indexFromPos(cursor); + + let ast; + try { + ast = parser.parse(code, { + sourceType: 'script', + plugins: ['jsx', 'typescript'] // add plugins as needed + }); + } catch (e) { + console.warn('Failed to parse code with Babel:', e.message); + return 'global'; + } + + let context = 'global'; + + traverse(ast, { + Function(path) { + const { node } = path; + if (offset >= node.start && offset <= node.end) { + if (node.id && node.id.name) { + context = node.id.name; + } else { + const parent = path.parentPath.node; + if ( + parent.type === 'VariableDeclarator' && + parent.id.type === 'Identifier' + ) { + context = parent.id.name; + } else { + context = '(anonymous)'; + } + } + path.stop(); // Stop traversal once we found the function context + } + } + }); + + return context; +} diff --git a/client/modules/IDE/components/parseCodeVariables.js b/client/modules/IDE/components/parseCodeVariables.js new file mode 100644 index 0000000000..c7a29f0e68 --- /dev/null +++ b/client/modules/IDE/components/parseCodeVariables.js @@ -0,0 +1,64 @@ +import * as acorn from 'acorn'; +import * as walk from 'acorn-walk'; +import classMap from './class-with-methods-map.json'; + +const functionToClass = {}; + +Object.entries(classMap).forEach(([className, classData]) => { + const createMethods = classData.createMethods || []; + createMethods.forEach((fnName) => { + functionToClass[fnName] = className; + }); +}); + +export default function parseCodeVariables(_cm) { + const code = _cm.getValue(); + let ast; + + try { + ast = acorn.parse(code, { + ecmaVersion: 'latest', + sourceType: 'script' + }); + } catch (e) { + console.warn('Failed to parse code', e.message); + return {}; + } + + const variableMap = {}; + + walk.simple(ast, { + AssignmentExpression(node) { + if ( + node.left.type === 'Identifier' && + node.right.type === 'CallExpression' && + node.right.callee.type === 'Identifier' + ) { + const varName = node.left.name; + const fnName = node.right.callee.name; + const cls = functionToClass[fnName]; + if (cls) { + variableMap[varName] = cls; + } + } + }, + + VariableDeclarator(node) { + if ( + node.id.type === 'Identifier' && + node.init?.type === 'CallExpression' && + node.init.callee.type === 'Identifier' + ) { + const varName = node.id.name; + const fnName = node.init.callee.name; + const cls = functionToClass[fnName]; + if (cls) { + variableMap[varName] = cls; + } + } + } + }); + console.log('varmap= ', variableMap); + + return variableMap; +} diff --git a/client/modules/IDE/components/show-hint.js b/client/modules/IDE/components/show-hint.js index 99f7552006..308dbd6bed 100644 --- a/client/modules/IDE/components/show-hint.js +++ b/client/modules/IDE/components/show-hint.js @@ -7,6 +7,12 @@ // declare global: DOMRect +// The first function (mod) is a wrapper to support different JavaScript environments. +// The second function (inside) contains the actual implementation. +import parseCode from './parseCode'; +import CodeMirror from 'codemirror'; +import warnIfBlacklisted from './warn'; + (function (mod) { if (typeof exports == 'object' && typeof module == 'object') // CommonJS @@ -16,6 +22,8 @@ define(['codemirror'], mod); // Plain browser env else mod(CodeMirror); + + // This part uptill here makes the code compatible with multiple JavaScript environments, so it can run in different places })(function (CodeMirror) { 'use strict'; @@ -25,16 +33,24 @@ // This is the old interface, kept around for now to stay // backwards-compatible. CodeMirror.showHint = function (cm, getHints, options) { - if (!getHints) return cm.showHint(options); + console.log('showhint was called: ', cm, getHints, options); + if (!getHints) return cm.showHint(options); // if not getHints function passed, it assumes youre using the newer interface + // restructured options to call the new c.showHint() method if (options && options.async) getHints.async = true; var newOpts = { hint: getHints }; if (options) for (var prop in options) newOpts[prop] = options[prop]; + console.log('newopts: ', newOpts); + const context = parseCode(cm); + console.log('Cursor context =', context); return cm.showHint(newOpts); }; + // this adds a method called showHint to every cm editor instance (editor.showHint()) CodeMirror.defineExtension('showHint', function (options) { options = parseOptions(this, this.getCursor('start'), options); + console.log('options are: '); var selections = this.listSelections(); + console.log('selections are: ', selections); if (selections.length > 1) return; // By default, don't allow completion when something is selected. // A hint function can have a `supportsSelection` property to @@ -42,18 +58,20 @@ if (this.somethingSelected()) { if (!options.hint.supportsSelection) return; // Don't try with cross-line selections + // if selection spans multiple lines, bail out for (var i = 0; i < selections.length; i++) if (selections[i].head.line != selections[i].anchor.line) return; } - if (this.state.completionActive) this.state.completionActive.close(); + if (this.state.completionActive) this.state.completionActive.close(); // close an already active autocomplete session if active + // create a new completion object and saves it to this.state.completionActive var completion = (this.state.completionActive = new Completion( this, options )); - if (!completion.options.hint) return; + if (!completion.options.hint) return; // safety check to ensure hint is valid - CodeMirror.signal(this, 'startCompletion', this); + CodeMirror.signal(this, 'startCompletion', this); // emits a signal; fires a startCompletion event on editor instance completion.update(true); }); @@ -61,19 +79,22 @@ if (this.state.completionActive) this.state.completionActive.close(); }); + // defines a constructor function function Completion(cm, options) { this.cm = cm; this.options = options; - this.widget = null; + this.widget = null; // will hold a reference to the dropdown menu that shows suggestions this.debounce = 0; this.tick = 0; - this.startPos = this.cm.getCursor('start'); + this.startPos = this.cm.getCursor('start'); // startPos is a {line,ch} object used to remember where hinting started + // startLen is the len of the line minus length of any selected text this.startLen = this.cm.getLine(this.startPos.line).length - this.cm.getSelection().length; if (this.options.updateOnCursorActivity) { - var self = this; + var self = this; // stores ref to this as self so it can be accessed inside the nested function + // adds an event listener to the editor; called when the cursor moves cm.on( 'cursorActivity', (this.activityFunc = function () { @@ -95,12 +116,14 @@ if (!this.active()) return; this.cm.state.completionActive = null; this.tick = null; + // removes the current activity listener if (this.options.updateOnCursorActivity) { this.cm.off('cursorActivity', this.activityFunc); } - + // signals and removes the widget if (this.widget && this.data) CodeMirror.signal(this.data, 'close'); if (this.widget) this.widget.close(); + // emits a completition end event CodeMirror.signal(this.cm, 'endCompletion', this.cm); }, @@ -109,26 +132,40 @@ }, pick: function (data, i) { + // selects an item from the suggestion list + console.log('data, i= ', data, i); var completion = data.list[i], self = this; + this.cm.operation(function () { - if (completion.hint) completion.hint(self.cm, data, completion); - else + // this is how cm allows custom behavior per suggestion + // if hint is provided on a hint object, it will be called instead of the default replace range + const name = completion.item?.text; + if (name) warnIfBlacklisted(self.cm, name); + + if (completion.hint) { + completion.hint(self.cm, data, completion); + } else { + console.log('gettext(C)= ', getText(completion)); self.cm.replaceRange( getText(completion), completion.from || data.from, completion.to || data.to, 'complete' ); + } + // signals that a hint was picked and scrolls to it CodeMirror.signal(data, 'pick', completion); self.cm.scrollIntoView(); }); + // closes widget if closeOnPick is enabled if (this.options.closeOnPick) { this.close(); } }, cursorActivity: function () { + // if a debounce is scheduled, cancel it to avoid outdated updates if (this.debounce) { cancelAnimationFrame(this.debounce); this.debounce = 0; @@ -149,6 +186,7 @@ !pos.ch || this.options.closeCharacters.test(line.charAt(pos.ch - 1)) ) { + console.log('this.close called'); this.close(); } else { var self = this; @@ -160,6 +198,7 @@ }, update: function (first) { + console.log('update called'); if (this.tick == null) return; var self = this, myTick = ++this.tick; @@ -192,6 +231,7 @@ function parseOptions(cm, pos, options) { var editor = cm.options.hintOptions; var out = {}; + // copies all default hint settings into out for (var prop in defaultOptions) out[prop] = defaultOptions[prop]; if (editor) for (var prop in editor) @@ -200,14 +240,17 @@ for (var prop in options) if (options[prop] !== undefined) out[prop] = options[prop]; if (out.hint.resolve) out.hint = out.hint.resolve(cm, pos); + console.log('out is ', out); return out; } - + // extracts the visible text from a completion entry function getText(completion) { + console.log('gettext called'); if (typeof completion === 'string') return completion; else return completion.item.text; } + // builds a key mapping object to define keyboard behavior for autocomplete function buildKeyMap(completion, handle) { var baseMap = { Up: function () { @@ -232,7 +275,7 @@ Tab: handle.pick, Esc: handle.close }; - + // checks if the user is on macOS and adds shortcuts accordingly var mac = /Mac/.test(navigator.platform); if (mac) { @@ -244,6 +287,7 @@ }; } + // user defined custom key bindings var custom = completion.options.customKeys; var ourMap = custom ? {} : baseMap; function addBinding(key, val) { @@ -257,6 +301,7 @@ else bound = val; ourMap[key] = bound; } + // apply all custom key bindings and extraKeys if (custom) for (var key in custom) if (custom.hasOwnProperty(key)) addBinding(key, custom[key]); @@ -267,38 +312,88 @@ return ourMap; } + // hintsElement is the parent for hints and el is the clicked element within that container function getHintElement(hintsElement, el) { + console.log('el is ', el); while (el && el != hintsElement) { - if (el.nodeName.toUpperCase() === 'LI' && el.parentNode == hintsElement) + if (el.nodeName.toUpperCase() === 'LI' && el.parentNode == hintsElement) { + console.log('new el is ', el); return el; + } el = el.parentNode; } } - function displayHint(name, type, p5) { - return `

\ -${name}\ -, \ -${type}\ -, \ -${ - p5 - ? `\ -open ${name} reference\ -` - : `no reference for ${name}` -}

`; + // function displayHint(name, type, p5, isBlacklistedFunction) { + // console.log('name is', name, type, p5, isBlacklistedFunction); + // return `

\ + // ${name}\ + // , \ + // ${type}\ + // , \ + // ${ + // p5 + // ? `\ + // open ${name} reference\ + // ` + // : `no reference for ${name}` + // }

`; + // } + + function displayHint(name, type, p5, isBlacklistedFunction) { + console.log('name is', name, type, p5, isBlacklistedFunction); + + const linkOrPlaceholder = p5 + ? ` + open ${name} reference + + ` + : ` + no reference for ${name} + `; + + const hintHTML = ` +
+ ${name} + ${type} + ${linkOrPlaceholder} +
+ `; + + const warningHTML = isBlacklistedFunction + ? `
⚠️ Be careful — this function is discouraged in this context.
` + : ''; + + return `
+ ${hintHTML} + ${warningHTML} +
`; } - function getInlineHintSuggestion(focus, tokenLength) { + function getInlineHintSuggestion(cm, focus, tokenLength) { + const name = focus.item?.text; + console.log('the focus is: ', focus, name); + if (name) warnIfBlacklisted(cm, name); const suggestionItem = focus.item; + // builds the remainder of the suggestion excluding what user already typed const baseCompletion = `${suggestionItem.text.slice( tokenLength )}`; if (suggestionItem.type !== 'fun') return baseCompletion; + console.log( + 'tokenLength =', + tokenLength, + 'suggestion =', + suggestionItem.text + ); + // for functions return ( baseCompletion + @@ -310,6 +405,7 @@ ${ ); } + // clears existing inline hint (like the part is suggested) function removeInlineHint(cm) { if (cm.state.inlineHint) { cm.state.inlineHint.clear(); @@ -318,7 +414,6 @@ ${ } function changeInlineHint(cm, focus) { - // Copilot-style inline suggestion for autocomplete feature removeInlineHint(cm); const cursor = cm.getCursor(); @@ -326,6 +421,7 @@ ${ if (token && focus.item) { const suggestionHTML = getInlineHintSuggestion( + cm, focus, token.string.length ); @@ -336,12 +432,16 @@ ${ const widget = cm.setBookmark(cursor, { widget: widgetElement }); cm.state.inlineHint = widget; - cm.setCursor(cursor); } } + // defines the autocomplete dropdown ui; renders the suggestions + // completion = the autocomplete context having cm and options + // data = object with the list of suggestions function Widget(completion, data) { + console.log('widget completetition= ', completion); + console.log('widget data= ', data); this.id = 'cm-complete-' + Math.floor(Math.random(1e6)); this.completion = completion; this.data = data; @@ -365,32 +465,41 @@ ${ changeInlineHint(cm, data.list[this.selectedHint]); var completions = data.list; - for (var i = 0; i < completions.length; ++i) { - var elt = hints.appendChild(ownerDocument.createElement('li')), - cur = completions[i]; - var className = + const cur = completions[i]; + + const elt = ownerDocument.createElement('li'); + elt.className = HINT_ELEMENT_CLASS + - (i != this.selectedHint ? '' : ' ' + ACTIVE_HINT_ELEMENT_CLASS); - if (cur.className != null) className = cur.className + ' ' + className; - elt.className = className; - if (i == this.selectedHint) elt.setAttribute('aria-selected', 'true'); + (i !== this.selectedHint ? '' : ' ' + ACTIVE_HINT_ELEMENT_CLASS) + + (cur.isBlacklisted ? ' blacklisted' : ''); + + if (cur.className != null) + elt.className = cur.className + ' ' + elt.className; + + if (i === this.selectedHint) elt.setAttribute('aria-selected', 'true'); elt.id = this.id + '-' + i; elt.setAttribute('role', 'option'); - if (cur.render) cur.render(elt, data, cur); - else { - const e = ownerDocument.createElement('p'); - const name = getText(cur); + elt.hintId = i; + if (cur.render) { + cur.render(elt, data, cur); + } else { + const name = getText(cur); if (cur.item && cur.item.type) { - cur.displayText = displayHint(name, cur.item.type, cur.item.p5); + cur.displayText = displayHint( + name, + cur.item.type, + cur.item.p5, + cur.isBlacklisted + ); } - elt.appendChild(e); - e.outerHTML = - cur.displayText || `${name}`; + elt.innerHTML = + cur.displayText || `${name}`; } - elt.hintId = i; + + hints.appendChild(elt); } var container = completion.options.container || ownerDocument.body; @@ -701,6 +810,7 @@ ${ hint(cm, callback, options); } else { var result = hint(cm, options); + console.log('fetchhints result= ', result); if (result && result.then) result.then(callback); else callback(result); } diff --git a/client/modules/IDE/components/warn.js b/client/modules/IDE/components/warn.js new file mode 100644 index 0000000000..4e377b616e --- /dev/null +++ b/client/modules/IDE/components/warn.js @@ -0,0 +1,21 @@ +import parseCode from './parseCode'; + +const scopeMap = require('./finalScopeMap.json'); + +/** + * Checks if a completion is blacklisted in the current context and logs a warning if so. + * @param {CodeMirror.Editor} cm - The CodeMirror instance + * @param {string} text - The name of the selected function + */ +export default function warnIfBlacklisted(cm, text) { + const context = parseCode(cm); + const blacklist = scopeMap[context]?.blacklist || []; + + const isBlacklisted = blacklist.includes(text); + if (isBlacklisted) { + console.warn( + `⚠️ Function "${text}" is usually not used in "${context}" context. Please be careful.` + ); + } + return isBlacklisted; +} diff --git a/client/styles/components/_hints.scss b/client/styles/components/_hints.scss index 6c01abb721..5cf58ff3b3 100644 --- a/client/styles/components/_hints.scss +++ b/client/styles/components/_hints.scss @@ -29,8 +29,59 @@ border-bottom: #{math.div(1, $base-font-size)}rem solid getThemifyVariable('hint-item-border-bottom-color'); } - .hint-name { + .hint-container { + display: flex; + flex-direction: column; + justify-content: center; + width: 100%; height: 100%; + + // Widen the entire row only if a warning is present + &.has-warning { + width: 100%; // Let it fill the parent .CodeMirror-hint width + max-width: 24rem; + } + } + + .hint-main { + display: flex; + justify-content: space-between; + align-items: center; + flex-grow: 1; + padding: 0 0.5rem; + width: 100%; + height: 100%; + } + + .hint-name { + font-size: 1.2rem; + font-weight: bold; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } + + .hint-type { + font-size: 1rem; + font-weight: normal; + color: #999; + margin-left: 1rem; + margin-right: 2.5rem; // leaves space for the arrow icon + white-space: nowrap; + flex-shrink: 0; + } + + // Warning box + .blacklist-warning { + background-color: #fff3cd; + border: 1px solid #ffc107; + color: #856404; + padding: 6px 10px; + border-radius: 4px; + font-size: 0.85rem; + margin: 0.25rem 0.5rem 0 0.5rem; + width: calc(100% - 1rem); // Match padding + box-sizing: border-box; } .fun-name, .obj-name { @@ -174,6 +225,11 @@ outline: 0; } } + + .CodeMirror-hint.blacklisted { + height: auto; + min-height: 3.2rem; // enough to show the warning + content + } } // Inline hinter diff --git a/client/utils/p5-hinter.js b/client/utils/p5-hinter.js index 7f20031df5..25d68c59f2 100644 --- a/client/utils/p5-hinter.js +++ b/client/utils/p5-hinter.js @@ -1,3 +1,1734 @@ /* eslint-disable */ /* generated: do not edit! helper file for hinter. generated by update-p5-hinter script */ -exports.p5Hinter = [{"text":"describe","type":"fun","params":[{"p":"text","o":false},{"p":"display","o":true}],"p5":true},{"text":"describeElement","type":"fun","params":[{"p":"name","o":false},{"p":"text","o":false},{"p":"display","o":true}],"p5":true},{"text":"textOutput","type":"fun","params":[{"p":"display","o":true}],"p5":true},{"text":"gridOutput","type":"fun","params":[{"p":"display","o":true}],"p5":true},{"text":"alpha","type":"fun","params":[{"p":"color","o":false}],"p5":true},{"text":"blue","type":"fun","params":[{"p":"color","o":false}],"p5":true},{"text":"brightness","type":"fun","params":[{"p":"color","o":false}],"p5":true},{"text":"color","type":"fun","p5":true},{"text":"green","type":"fun","params":[{"p":"color","o":false}],"p5":true},{"text":"hue","type":"fun","params":[{"p":"color","o":false}],"p5":true},{"text":"lerpColor","type":"fun","params":[{"p":"c1","o":false},{"p":"c2","o":false},{"p":"amt","o":false}],"p5":true},{"text":"lightness","type":"fun","params":[{"p":"color","o":false}],"p5":true},{"text":"red","type":"fun","params":[{"p":"color","o":false}],"p5":true},{"text":"saturation","type":"fun","params":[{"p":"color","o":false}],"p5":true},{"text":"beginClip","type":"fun","params":[{"p":"options","o":true}],"p5":true},{"text":"endClip","type":"fun","p5":true},{"text":"clip","type":"fun","params":[{"p":"callback","o":false},{"p":"options","o":true}],"p5":true},{"text":"background","type":"fun","p5":true},{"text":"clear","type":"fun","params":[{"p":"r","o":true},{"p":"g","o":true},{"p":"b","o":true},{"p":"a","o":true}],"p5":true},{"text":"colorMode","type":"fun","p5":true},{"text":"fill","type":"fun","p5":true},{"text":"noFill","type":"fun","p5":true},{"text":"noStroke","type":"fun","p5":true},{"text":"stroke","type":"fun","p5":true},{"text":"erase","type":"fun","params":[{"p":"strengthFill","o":true},{"p":"strengthStroke","o":true}],"p5":true},{"text":"noErase","type":"fun","p5":true},{"text":"arc","type":"fun","params":[{"p":"x","o":false},{"p":"y","o":false},{"p":"w","o":false},{"p":"h","o":false},{"p":"start","o":false},{"p":"stop","o":false},{"p":"mode","o":true},{"p":"detail","o":true}],"p5":true},{"text":"ellipse","type":"fun","p5":true},{"text":"circle","type":"fun","params":[{"p":"x","o":false},{"p":"y","o":false},{"p":"d","o":false}],"p5":true},{"text":"line","type":"fun","p5":true},{"text":"point","type":"fun","p5":true},{"text":"quad","type":"fun","p5":true},{"text":"rect","type":"fun","p5":true},{"text":"square","type":"fun","params":[{"p":"x","o":false},{"p":"y","o":false},{"p":"s","o":false},{"p":"tl","o":true},{"p":"tr","o":true},{"p":"br","o":true},{"p":"bl","o":true}],"p5":true},{"text":"triangle","type":"fun","params":[{"p":"x1","o":false},{"p":"y1","o":false},{"p":"x2","o":false},{"p":"y2","o":false},{"p":"x3","o":false},{"p":"y3","o":false}],"p5":true},{"text":"ellipseMode","type":"fun","params":[{"p":"mode","o":false}],"p5":true},{"text":"noSmooth","type":"fun","p5":true},{"text":"rectMode","type":"fun","params":[{"p":"mode","o":false}],"p5":true},{"text":"smooth","type":"fun","p5":true},{"text":"strokeCap","type":"fun","params":[{"p":"cap","o":false}],"p5":true},{"text":"strokeJoin","type":"fun","params":[{"p":"join","o":false}],"p5":true},{"text":"strokeWeight","type":"fun","params":[{"p":"weight","o":false}],"p5":true},{"text":"bezier","type":"fun","p5":true},{"text":"bezierDetail","type":"fun","params":[{"p":"detail","o":false}],"p5":true},{"text":"bezierPoint","type":"fun","params":[{"p":"a","o":false},{"p":"b","o":false},{"p":"c","o":false},{"p":"d","o":false},{"p":"t","o":false}],"p5":true},{"text":"bezierTangent","type":"fun","params":[{"p":"a","o":false},{"p":"b","o":false},{"p":"c","o":false},{"p":"d","o":false},{"p":"t","o":false}],"p5":true},{"text":"curve","type":"fun","p5":true},{"text":"curveDetail","type":"fun","params":[{"p":"resolution","o":false}],"p5":true},{"text":"curveTightness","type":"fun","params":[{"p":"amount","o":false}],"p5":true},{"text":"curvePoint","type":"fun","params":[{"p":"a","o":false},{"p":"b","o":false},{"p":"c","o":false},{"p":"d","o":false},{"p":"t","o":false}],"p5":true},{"text":"curveTangent","type":"fun","params":[{"p":"a","o":false},{"p":"b","o":false},{"p":"c","o":false},{"p":"d","o":false},{"p":"t","o":false}],"p5":true},{"text":"beginContour","type":"fun","p5":true},{"text":"beginShape","type":"fun","params":[{"p":"kind","o":true}],"p5":true},{"text":"bezierVertex","type":"fun","p5":true},{"text":"curveVertex","type":"fun","p5":true},{"text":"endContour","type":"fun","p5":true},{"text":"endShape","type":"fun","params":[{"p":"mode","o":true},{"p":"count","o":true}],"p5":true},{"text":"quadraticVertex","type":"fun","p5":true},{"text":"vertex","type":"fun","p5":true},{"text":"normal","type":"fun","p5":true},{"text":"VERSION","type":"var","params":[],"p5":true},{"text":"P2D","type":"var","params":[],"p5":true},{"text":"WEBGL","type":"var","params":[],"p5":true},{"text":"WEBGL2","type":"var","params":[],"p5":true},{"text":"ARROW","type":"var","params":[],"p5":true},{"text":"CROSS","type":"var","params":[],"p5":true},{"text":"HAND","type":"var","params":[],"p5":true},{"text":"MOVE","type":"var","params":[],"p5":true},{"text":"TEXT","type":"var","params":[],"p5":true},{"text":"WAIT","type":"var","params":[],"p5":true},{"text":"HALF_PI","type":"var","params":[],"p5":true},{"text":"PI","type":"var","params":[],"p5":true},{"text":"QUARTER_PI","type":"var","params":[],"p5":true},{"text":"TAU","type":"var","params":[],"p5":true},{"text":"TWO_PI","type":"var","params":[],"p5":true},{"text":"DEGREES","type":"var","params":[],"p5":true},{"text":"RADIANS","type":"var","params":[],"p5":true},{"text":"CORNER","type":"var","params":[],"p5":true},{"text":"CORNERS","type":"var","params":[],"p5":true},{"text":"RADIUS","type":"var","params":[],"p5":true},{"text":"RIGHT","type":"var","params":[],"p5":true},{"text":"LEFT","type":"var","params":[],"p5":true},{"text":"CENTER","type":"var","params":[],"p5":true},{"text":"TOP","type":"var","params":[],"p5":true},{"text":"BOTTOM","type":"var","params":[],"p5":true},{"text":"BASELINE","type":"var","params":[],"p5":true},{"text":"POINTS","type":"var","params":[],"p5":true},{"text":"LINES","type":"var","params":[],"p5":true},{"text":"LINE_STRIP","type":"var","params":[],"p5":true},{"text":"LINE_LOOP","type":"var","params":[],"p5":true},{"text":"TRIANGLES","type":"var","params":[],"p5":true},{"text":"TRIANGLE_FAN","type":"var","params":[],"p5":true},{"text":"TRIANGLE_STRIP","type":"var","params":[],"p5":true},{"text":"QUADS","type":"var","params":[],"p5":true},{"text":"QUAD_STRIP","type":"var","params":[],"p5":true},{"text":"TESS","type":"var","params":[],"p5":true},{"text":"CLOSE","type":"var","params":[],"p5":true},{"text":"OPEN","type":"var","params":[],"p5":true},{"text":"CHORD","type":"var","params":[],"p5":true},{"text":"PIE","type":"var","params":[],"p5":true},{"text":"PROJECT","type":"var","params":[],"p5":true},{"text":"SQUARE","type":"var","params":[],"p5":true},{"text":"ROUND","type":"var","params":[],"p5":true},{"text":"BEVEL","type":"var","params":[],"p5":true},{"text":"MITER","type":"var","params":[],"p5":true},{"text":"RGB","type":"var","params":[],"p5":true},{"text":"HSB","type":"var","params":[],"p5":true},{"text":"HSL","type":"var","params":[],"p5":true},{"text":"AUTO","type":"var","params":[],"p5":true},{"text":"ALT","type":"var","params":[],"p5":true},{"text":"BACKSPACE","type":"var","params":[],"p5":true},{"text":"CONTROL","type":"var","params":[],"p5":true},{"text":"DELETE","type":"var","params":[],"p5":true},{"text":"DOWN_ARROW","type":"var","params":[],"p5":true},{"text":"ENTER","type":"var","params":[],"p5":true},{"text":"ESCAPE","type":"var","params":[],"p5":true},{"text":"LEFT_ARROW","type":"var","params":[],"p5":true},{"text":"OPTION","type":"var","params":[],"p5":true},{"text":"RETURN","type":"var","params":[],"p5":true},{"text":"RIGHT_ARROW","type":"var","params":[],"p5":true},{"text":"SHIFT","type":"var","params":[],"p5":true},{"text":"TAB","type":"var","params":[],"p5":true},{"text":"UP_ARROW","type":"var","params":[],"p5":true},{"text":"BLEND","type":"var","params":[],"p5":true},{"text":"REMOVE","type":"var","params":[],"p5":true},{"text":"ADD","type":"var","params":[],"p5":true},{"text":"DARKEST","type":"var","params":[],"p5":true},{"text":"LIGHTEST","type":"var","params":[],"p5":true},{"text":"DIFFERENCE","type":"var","params":[],"p5":true},{"text":"SUBTRACT","type":"var","params":[],"p5":true},{"text":"EXCLUSION","type":"var","params":[],"p5":true},{"text":"MULTIPLY","type":"var","params":[],"p5":true},{"text":"SCREEN","type":"var","params":[],"p5":true},{"text":"REPLACE","type":"var","params":[],"p5":true},{"text":"OVERLAY","type":"var","params":[],"p5":true},{"text":"HARD_LIGHT","type":"var","params":[],"p5":true},{"text":"SOFT_LIGHT","type":"var","params":[],"p5":true},{"text":"DODGE","type":"var","params":[],"p5":true},{"text":"BURN","type":"var","params":[],"p5":true},{"text":"THRESHOLD","type":"var","params":[],"p5":true},{"text":"GRAY","type":"var","params":[],"p5":true},{"text":"OPAQUE","type":"var","params":[],"p5":true},{"text":"INVERT","type":"var","params":[],"p5":true},{"text":"POSTERIZE","type":"var","params":[],"p5":true},{"text":"DILATE","type":"var","params":[],"p5":true},{"text":"ERODE","type":"var","params":[],"p5":true},{"text":"BLUR","type":"var","params":[],"p5":true},{"text":"NORMAL","type":"var","params":[],"p5":true},{"text":"ITALIC","type":"var","params":[],"p5":true},{"text":"BOLD","type":"var","params":[],"p5":true},{"text":"BOLDITALIC","type":"var","params":[],"p5":true},{"text":"CHAR","type":"var","params":[],"p5":true},{"text":"WORD","type":"var","params":[],"p5":true},{"text":"LINEAR","type":"var","params":[],"p5":true},{"text":"QUADRATIC","type":"var","params":[],"p5":true},{"text":"BEZIER","type":"var","params":[],"p5":true},{"text":"CURVE","type":"var","params":[],"p5":true},{"text":"STROKE","type":"var","params":[],"p5":true},{"text":"FILL","type":"var","params":[],"p5":true},{"text":"TEXTURE","type":"var","params":[],"p5":true},{"text":"IMMEDIATE","type":"var","params":[],"p5":true},{"text":"IMAGE","type":"var","params":[],"p5":true},{"text":"NEAREST","type":"var","params":[],"p5":true},{"text":"REPEAT","type":"var","params":[],"p5":true},{"text":"CLAMP","type":"var","params":[],"p5":true},{"text":"MIRROR","type":"var","params":[],"p5":true},{"text":"FLAT","type":"var","params":[],"p5":true},{"text":"SMOOTH","type":"var","params":[],"p5":true},{"text":"LANDSCAPE","type":"var","params":[],"p5":true},{"text":"PORTRAIT","type":"var","params":[],"p5":true},{"text":"GRID","type":"var","params":[],"p5":true},{"text":"AXES","type":"var","params":[],"p5":true},{"text":"LABEL","type":"var","params":[],"p5":true},{"text":"FALLBACK","type":"var","params":[],"p5":true},{"text":"CONTAIN","type":"var","params":[],"p5":true},{"text":"COVER","type":"var","params":[],"p5":true},{"text":"UNSIGNED_BYTE","type":"var","params":[],"p5":true},{"text":"UNSIGNED_INT","type":"var","params":[],"p5":true},{"text":"FLOAT","type":"var","params":[],"p5":true},{"text":"HALF_FLOAT","type":"var","params":[],"p5":true},{"text":"RGBA","type":"var","params":[],"p5":true},{"text":"print","type":"fun","params":[{"p":"contents","o":false}],"p5":true},{"text":"frameCount","type":"var","params":[],"p5":true},{"text":"deltaTime","type":"var","params":[],"p5":true},{"text":"focused","type":"var","params":[],"p5":true},{"text":"cursor","type":"fun","params":[{"p":"type","o":false},{"p":"x","o":true},{"p":"y","o":true}],"p5":true},{"text":"frameRate","type":"fun","p5":true},{"text":"getTargetFrameRate","type":"fun","p5":true},{"text":"noCursor","type":"fun","p5":true},{"text":"webglVersion","type":"var","params":[],"p5":true},{"text":"displayWidth","type":"var","params":[],"p5":true},{"text":"displayHeight","type":"var","params":[],"p5":true},{"text":"windowWidth","type":"var","params":[],"p5":true},{"text":"windowHeight","type":"var","params":[],"p5":true},{"text":"windowResized","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"width","type":"var","params":[],"p5":true},{"text":"height","type":"var","params":[],"p5":true},{"text":"fullscreen","type":"fun","params":[{"p":"val","o":true}],"p5":true},{"text":"pixelDensity","type":"fun","p5":true},{"text":"displayDensity","type":"fun","p5":true},{"text":"getURL","type":"fun","p5":true},{"text":"getURLPath","type":"fun","p5":true},{"text":"getURLParams","type":"fun","p5":true},{"text":"preload","type":"fun","p5":true},{"text":"setup","type":"fun","p5":true},{"text":"draw","type":"fun","p5":true},{"text":"remove","type":"fun","p5":true},{"text":"disableFriendlyErrors","type":"var","params":[],"p5":true},{"text":"createCanvas","type":"fun","p5":true},{"text":"resizeCanvas","type":"fun","params":[{"p":"width","o":false},{"p":"height","o":false},{"p":"noRedraw","o":true}],"p5":true},{"text":"noCanvas","type":"fun","p5":true},{"text":"createGraphics","type":"fun","p5":true},{"text":"createFramebuffer","type":"fun","params":[{"p":"options","o":true}],"p5":true},{"text":"clearDepth","type":"fun","params":[{"p":"depth","o":true}],"p5":true},{"text":"blendMode","type":"fun","params":[{"p":"mode","o":false}],"p5":true},{"text":"drawingContext","type":"var","params":[],"p5":true},{"text":"noLoop","type":"fun","p5":true},{"text":"loop","type":"fun","p5":true},{"text":"isLooping","type":"fun","p5":true},{"text":"push","type":"fun","p5":true},{"text":"pop","type":"fun","p5":true},{"text":"redraw","type":"fun","params":[{"p":"n","o":true}],"p5":true},{"text":"p5","type":"fun","params":[{"p":"sketch","o":false},{"p":"node","o":false}],"p5":true},{"text":"applyMatrix","type":"fun","p5":true},{"text":"resetMatrix","type":"fun","p5":true},{"text":"rotate","type":"fun","params":[{"p":"angle","o":false},{"p":"axis","o":true}],"p5":true},{"text":"rotateX","type":"fun","params":[{"p":"angle","o":false}],"p5":true},{"text":"rotateY","type":"fun","params":[{"p":"angle","o":false}],"p5":true},{"text":"rotateZ","type":"fun","params":[{"p":"angle","o":false}],"p5":true},{"text":"scale","type":"fun","p5":true},{"text":"shearX","type":"fun","params":[{"p":"angle","o":false}],"p5":true},{"text":"shearY","type":"fun","params":[{"p":"angle","o":false}],"p5":true},{"text":"translate","type":"fun","p5":true},{"text":"storeItem","type":"fun","params":[{"p":"key","o":false},{"p":"value","o":false}],"p5":true},{"text":"getItem","type":"fun","params":[{"p":"key","o":false}],"p5":true},{"text":"clearStorage","type":"fun","p5":true},{"text":"removeItem","type":"fun","params":[{"p":"key","o":false}],"p5":true},{"text":"createStringDict","type":"fun","p5":true},{"text":"createNumberDict","type":"fun","p5":true},{"text":"select","type":"fun","params":[{"p":"selectors","o":false},{"p":"container","o":true}],"p5":true},{"text":"selectAll","type":"fun","params":[{"p":"selectors","o":false},{"p":"container","o":true}],"p5":true},{"text":"removeElements","type":"fun","p5":true},{"text":"changed","type":"fun","params":[{"p":"fxn","o":false}],"p5":true},{"text":"input","type":"fun","params":[{"p":"fxn","o":false}],"p5":true},{"text":"createDiv","type":"fun","params":[{"p":"html","o":true}],"p5":true},{"text":"createP","type":"fun","params":[{"p":"html","o":true}],"p5":true},{"text":"createSpan","type":"fun","params":[{"p":"html","o":true}],"p5":true},{"text":"createImg","type":"fun","p5":true},{"text":"createA","type":"fun","params":[{"p":"href","o":false},{"p":"html","o":false},{"p":"target","o":true}],"p5":true},{"text":"createSlider","type":"fun","params":[{"p":"min","o":false},{"p":"max","o":false},{"p":"value","o":true},{"p":"step","o":true}],"p5":true},{"text":"createButton","type":"fun","params":[{"p":"label","o":false},{"p":"value","o":true}],"p5":true},{"text":"createCheckbox","type":"fun","params":[{"p":"label","o":true},{"p":"value","o":true}],"p5":true},{"text":"createSelect","type":"fun","p5":true},{"text":"createRadio","type":"fun","p5":true},{"text":"createColorPicker","type":"fun","params":[{"p":"value","o":true}],"p5":true},{"text":"createInput","type":"fun","p5":true},{"text":"createFileInput","type":"fun","params":[{"p":"callback","o":false},{"p":"multiple","o":true}],"p5":true},{"text":"createVideo","type":"fun","params":[{"p":"src","o":false},{"p":"callback","o":true}],"p5":true},{"text":"createAudio","type":"fun","params":[{"p":"src","o":true},{"p":"callback","o":true}],"p5":true},{"text":"createCapture","type":"fun","params":[{"p":"type","o":true},{"p":"flipped","o":true},{"p":"callback","o":true}],"p5":true},{"text":"createElement","type":"fun","params":[{"p":"tag","o":false},{"p":"content","o":true}],"p5":true},{"text":"deviceOrientation","type":"var","params":[],"p5":true},{"text":"accelerationX","type":"var","params":[],"p5":true},{"text":"accelerationY","type":"var","params":[],"p5":true},{"text":"accelerationZ","type":"var","params":[],"p5":true},{"text":"pAccelerationX","type":"var","params":[],"p5":true},{"text":"pAccelerationY","type":"var","params":[],"p5":true},{"text":"pAccelerationZ","type":"var","params":[],"p5":true},{"text":"rotationX","type":"var","params":[],"p5":true},{"text":"rotationY","type":"var","params":[],"p5":true},{"text":"rotationZ","type":"var","params":[],"p5":true},{"text":"pRotationX","type":"var","params":[],"p5":true},{"text":"pRotationY","type":"var","params":[],"p5":true},{"text":"pRotationZ","type":"var","params":[],"p5":true},{"text":"turnAxis","type":"var","params":[],"p5":true},{"text":"setMoveThreshold","type":"fun","params":[{"p":"value","o":false}],"p5":true},{"text":"setShakeThreshold","type":"fun","params":[{"p":"value","o":false}],"p5":true},{"text":"deviceMoved","type":"fun","p5":true},{"text":"deviceTurned","type":"fun","p5":true},{"text":"deviceShaken","type":"fun","p5":true},{"text":"keyIsPressed","type":"var","params":[],"p5":true},{"text":"key","type":"var","params":[],"p5":true},{"text":"keyCode","type":"var","params":[],"p5":true},{"text":"keyPressed","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"keyReleased","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"keyTyped","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"keyIsDown","type":"fun","params":[{"p":"code","o":false}],"p5":true},{"text":"movedX","type":"var","params":[],"p5":true},{"text":"movedY","type":"var","params":[],"p5":true},{"text":"mouseX","type":"var","params":[],"p5":true},{"text":"mouseY","type":"var","params":[],"p5":true},{"text":"pmouseX","type":"var","params":[],"p5":true},{"text":"pmouseY","type":"var","params":[],"p5":true},{"text":"winMouseX","type":"var","params":[],"p5":true},{"text":"winMouseY","type":"var","params":[],"p5":true},{"text":"pwinMouseX","type":"var","params":[],"p5":true},{"text":"pwinMouseY","type":"var","params":[],"p5":true},{"text":"mouseButton","type":"var","params":[],"p5":true},{"text":"mouseIsPressed","type":"var","params":[],"p5":true},{"text":"mouseMoved","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"mouseDragged","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"mousePressed","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"mouseReleased","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"mouseClicked","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"doubleClicked","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"mouseWheel","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"requestPointerLock","type":"fun","p5":true},{"text":"exitPointerLock","type":"fun","p5":true},{"text":"touches","type":"var","params":[],"p5":true},{"text":"touchStarted","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"touchMoved","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"touchEnded","type":"fun","params":[{"p":"event","o":true}],"p5":true},{"text":"createImage","type":"fun","params":[{"p":"width","o":false},{"p":"height","o":false}],"p5":true},{"text":"saveCanvas","type":"fun","p5":true},{"text":"saveFrames","type":"fun","params":[{"p":"filename","o":false},{"p":"extension","o":false},{"p":"duration","o":false},{"p":"framerate","o":false},{"p":"callback","o":true}],"p5":true},{"text":"loadImage","type":"fun","params":[{"p":"path","o":false},{"p":"successCallback","o":true},{"p":"failureCallback","o":true}],"p5":true},{"text":"saveGif","type":"fun","params":[{"p":"filename","o":false},{"p":"duration","o":false},{"p":"options","o":true}],"p5":true},{"text":"image","type":"fun","p5":true},{"text":"tint","type":"fun","p5":true},{"text":"noTint","type":"fun","p5":true},{"text":"imageMode","type":"fun","params":[{"p":"mode","o":false}],"p5":true},{"text":"pixels","type":"var","params":[],"p5":true},{"text":"blend","type":"fun","p5":true},{"text":"copy","type":"fun","p5":true},{"text":"filter","type":"fun","p5":true},{"text":"get","type":"fun","p5":true},{"text":"loadPixels","type":"fun","p5":true},{"text":"set","type":"fun","params":[{"p":"x","o":false},{"p":"y","o":false},{"p":"c","o":false}],"p5":true},{"text":"updatePixels","type":"fun","params":[{"p":"x","o":true},{"p":"y","o":true},{"p":"w","o":true},{"p":"h","o":true}],"p5":true},{"text":"loadJSON","type":"fun","params":[{"p":"path","o":false},{"p":"successCallback","o":true},{"p":"errorCallback","o":true}],"p5":true},{"text":"loadStrings","type":"fun","params":[{"p":"path","o":false},{"p":"successCallback","o":true},{"p":"errorCallback","o":true}],"p5":true},{"text":"loadTable","type":"fun","params":[{"p":"filename","o":false},{"p":"extension","o":true},{"p":"header","o":true},{"p":"callback","o":true},{"p":"errorCallback","o":true}],"p5":true},{"text":"loadXML","type":"fun","params":[{"p":"path","o":false},{"p":"successCallback","o":true},{"p":"errorCallback","o":true}],"p5":true},{"text":"loadBytes","type":"fun","params":[{"p":"file","o":false},{"p":"callback","o":true},{"p":"errorCallback","o":true}],"p5":true},{"text":"httpGet","type":"fun","p5":true},{"text":"httpPost","type":"fun","p5":true},{"text":"httpDo","type":"fun","p5":true},{"text":"createWriter","type":"fun","params":[{"p":"name","o":false},{"p":"extension","o":true}],"p5":true},{"text":"save","type":"fun","params":[{"p":"objectOrFilename","o":true},{"p":"filename","o":true},{"p":"options","o":true}],"p5":true},{"text":"saveJSON","type":"fun","params":[{"p":"json","o":false},{"p":"filename","o":false},{"p":"optimize","o":true}],"p5":true},{"text":"saveStrings","type":"fun","params":[{"p":"list","o":false},{"p":"filename","o":false},{"p":"extension","o":true},{"p":"isCRLF","o":true}],"p5":true},{"text":"saveTable","type":"fun","params":[{"p":"Table","o":false},{"p":"filename","o":false},{"p":"options","o":true}],"p5":true},{"text":"abs","type":"fun","params":[{"p":"n","o":false}],"p5":true},{"text":"ceil","type":"fun","params":[{"p":"n","o":false}],"p5":true},{"text":"constrain","type":"fun","params":[{"p":"n","o":false},{"p":"low","o":false},{"p":"high","o":false}],"p5":true},{"text":"dist","type":"fun","p5":true},{"text":"exp","type":"fun","params":[{"p":"n","o":false}],"p5":true},{"text":"floor","type":"fun","params":[{"p":"n","o":false}],"p5":true},{"text":"lerp","type":"fun","params":[{"p":"start","o":false},{"p":"stop","o":false},{"p":"amt","o":false}],"p5":true},{"text":"log","type":"fun","params":[{"p":"n","o":false}],"p5":true},{"text":"mag","type":"fun","params":[{"p":"x","o":false},{"p":"y","o":false}],"p5":true},{"text":"map","type":"fun","params":[{"p":"value","o":false},{"p":"start1","o":false},{"p":"stop1","o":false},{"p":"start2","o":false},{"p":"stop2","o":false},{"p":"withinBounds","o":true}],"p5":true},{"text":"max","type":"fun","p5":true},{"text":"min","type":"fun","p5":true},{"text":"norm","type":"fun","params":[{"p":"value","o":false},{"p":"start","o":false},{"p":"stop","o":false}],"p5":true},{"text":"pow","type":"fun","params":[{"p":"n","o":false},{"p":"e","o":false}],"p5":true},{"text":"round","type":"fun","params":[{"p":"n","o":false},{"p":"decimals","o":true}],"p5":true},{"text":"sq","type":"fun","params":[{"p":"n","o":false}],"p5":true},{"text":"sqrt","type":"fun","params":[{"p":"n","o":false}],"p5":true},{"text":"fract","type":"fun","params":[{"p":"n","o":false}],"p5":true},{"text":"createVector","type":"fun","params":[{"p":"x","o":true},{"p":"y","o":true},{"p":"z","o":true}],"p5":true},{"text":"noise","type":"fun","params":[{"p":"x","o":false},{"p":"y","o":true},{"p":"z","o":true}],"p5":true},{"text":"noiseDetail","type":"fun","params":[{"p":"lod","o":false},{"p":"falloff","o":false}],"p5":true},{"text":"noiseSeed","type":"fun","params":[{"p":"seed","o":false}],"p5":true},{"text":"randomSeed","type":"fun","params":[{"p":"seed","o":false}],"p5":true},{"text":"random","type":"fun","p5":true},{"text":"randomGaussian","type":"fun","params":[{"p":"mean","o":true},{"p":"sd","o":true}],"p5":true},{"text":"acos","type":"fun","params":[{"p":"value","o":false}],"p5":true},{"text":"asin","type":"fun","params":[{"p":"value","o":false}],"p5":true},{"text":"atan","type":"fun","params":[{"p":"value","o":false}],"p5":true},{"text":"atan2","type":"fun","params":[{"p":"y","o":false},{"p":"x","o":false}],"p5":true},{"text":"cos","type":"fun","params":[{"p":"angle","o":false}],"p5":true},{"text":"sin","type":"fun","params":[{"p":"angle","o":false}],"p5":true},{"text":"tan","type":"fun","params":[{"p":"angle","o":false}],"p5":true},{"text":"degrees","type":"fun","params":[{"p":"radians","o":false}],"p5":true},{"text":"radians","type":"fun","params":[{"p":"degrees","o":false}],"p5":true},{"text":"angleMode","type":"fun","p5":true},{"text":"textAlign","type":"fun","p5":true},{"text":"textLeading","type":"fun","p5":true},{"text":"textSize","type":"fun","p5":true},{"text":"textStyle","type":"fun","p5":true},{"text":"textWidth","type":"fun","params":[{"p":"str","o":false}],"p5":true},{"text":"textAscent","type":"fun","p5":true},{"text":"textDescent","type":"fun","p5":true},{"text":"textWrap","type":"fun","params":[{"p":"style","o":false}],"p5":true},{"text":"loadFont","type":"fun","params":[{"p":"path","o":false},{"p":"successCallback","o":true},{"p":"failureCallback","o":true}],"p5":true},{"text":"text","type":"fun","params":[{"p":"str","o":false},{"p":"x","o":false},{"p":"y","o":false},{"p":"maxWidth","o":true},{"p":"maxHeight","o":true}],"p5":true},{"text":"textFont","type":"fun","p5":true},{"text":"append","type":"fun","params":[{"p":"array","o":false},{"p":"value","o":false}],"p5":true},{"text":"arrayCopy","type":"fun","p5":true},{"text":"concat","type":"fun","params":[{"p":"a","o":false},{"p":"b","o":false}],"p5":true},{"text":"reverse","type":"fun","params":[{"p":"list","o":false}],"p5":true},{"text":"shorten","type":"fun","params":[{"p":"list","o":false}],"p5":true},{"text":"shuffle","type":"fun","params":[{"p":"array","o":false},{"p":"bool","o":true}],"p5":true},{"text":"sort","type":"fun","params":[{"p":"list","o":false},{"p":"count","o":true}],"p5":true},{"text":"splice","type":"fun","params":[{"p":"list","o":false},{"p":"value","o":false},{"p":"position","o":false}],"p5":true},{"text":"subset","type":"fun","params":[{"p":"list","o":false},{"p":"start","o":false},{"p":"count","o":true}],"p5":true},{"text":"float","type":"fun","p5":true},{"text":"int","type":"fun","p5":true},{"text":"str","type":"fun","params":[{"p":"n","o":false}],"p5":true},{"text":"boolean","type":"fun","p5":true},{"text":"byte","type":"fun","p5":true},{"text":"char","type":"fun","p5":true},{"text":"unchar","type":"fun","p5":true},{"text":"hex","type":"fun","p5":true},{"text":"unhex","type":"fun","p5":true},{"text":"join","type":"fun","params":[{"p":"list","o":false},{"p":"separator","o":false}],"p5":true},{"text":"match","type":"fun","params":[{"p":"str","o":false},{"p":"regexp","o":false}],"p5":true},{"text":"matchAll","type":"fun","params":[{"p":"str","o":false},{"p":"regexp","o":false}],"p5":true},{"text":"nf","type":"fun","p5":true},{"text":"nfc","type":"fun","p5":true},{"text":"nfp","type":"fun","p5":true},{"text":"nfs","type":"fun","p5":true},{"text":"split","type":"fun","params":[{"p":"value","o":false},{"p":"delim","o":false}],"p5":true},{"text":"splitTokens","type":"fun","params":[{"p":"value","o":false},{"p":"delim","o":true}],"p5":true},{"text":"trim","type":"fun","p5":true},{"text":"day","type":"fun","p5":true},{"text":"hour","type":"fun","p5":true},{"text":"minute","type":"fun","p5":true},{"text":"millis","type":"fun","p5":true},{"text":"month","type":"fun","p5":true},{"text":"second","type":"fun","p5":true},{"text":"year","type":"fun","p5":true},{"text":"beginGeometry","type":"fun","p5":true},{"text":"endGeometry","type":"fun","p5":true},{"text":"buildGeometry","type":"fun","params":[{"p":"callback","o":false}],"p5":true},{"text":"freeGeometry","type":"fun","params":[{"p":"geometry","o":false}],"p5":true},{"text":"plane","type":"fun","params":[{"p":"width","o":true},{"p":"height","o":true},{"p":"detailX","o":true},{"p":"detailY","o":true}],"p5":true},{"text":"box","type":"fun","params":[{"p":"width","o":true},{"p":"height","o":true},{"p":"depth","o":true},{"p":"detailX","o":true},{"p":"detailY","o":true}],"p5":true},{"text":"sphere","type":"fun","params":[{"p":"radius","o":true},{"p":"detailX","o":true},{"p":"detailY","o":true}],"p5":true},{"text":"cylinder","type":"fun","params":[{"p":"radius","o":true},{"p":"height","o":true},{"p":"detailX","o":true},{"p":"detailY","o":true},{"p":"bottomCap","o":true},{"p":"topCap","o":true}],"p5":true},{"text":"cone","type":"fun","params":[{"p":"radius","o":true},{"p":"height","o":true},{"p":"detailX","o":true},{"p":"detailY","o":true},{"p":"cap","o":true}],"p5":true},{"text":"ellipsoid","type":"fun","params":[{"p":"radiusX","o":true},{"p":"radiusY","o":true},{"p":"radiusZ","o":true},{"p":"detailX","o":true},{"p":"detailY","o":true}],"p5":true},{"text":"torus","type":"fun","params":[{"p":"radius","o":true},{"p":"tubeRadius","o":true},{"p":"detailX","o":true},{"p":"detailY","o":true}],"p5":true},{"text":"orbitControl","type":"fun","params":[{"p":"sensitivityX","o":true},{"p":"sensitivityY","o":true},{"p":"sensitivityZ","o":true},{"p":"options","o":true}],"p5":true},{"text":"debugMode","type":"fun","p5":true},{"text":"noDebugMode","type":"fun","p5":true},{"text":"ambientLight","type":"fun","p5":true},{"text":"specularColor","type":"fun","p5":true},{"text":"directionalLight","type":"fun","p5":true},{"text":"pointLight","type":"fun","p5":true},{"text":"imageLight","type":"fun","params":[{"p":"img","o":false}],"p5":true},{"text":"panorama","type":"fun","params":[{"p":"img","o":false}],"p5":true},{"text":"lights","type":"fun","p5":true},{"text":"lightFalloff","type":"fun","params":[{"p":"constant","o":false},{"p":"linear","o":false},{"p":"quadratic","o":false}],"p5":true},{"text":"spotLight","type":"fun","p5":true},{"text":"noLights","type":"fun","p5":true},{"text":"loadModel","type":"fun","p5":true},{"text":"model","type":"fun","params":[{"p":"model","o":false}],"p5":true},{"text":"loadShader","type":"fun","params":[{"p":"vertFilename","o":false},{"p":"fragFilename","o":false},{"p":"successCallback","o":true},{"p":"failureCallback","o":true}],"p5":true},{"text":"createShader","type":"fun","params":[{"p":"vertSrc","o":false},{"p":"fragSrc","o":false}],"p5":true},{"text":"createFilterShader","type":"fun","params":[{"p":"fragSrc","o":false}],"p5":true},{"text":"shader","type":"fun","params":[{"p":"s","o":false}],"p5":true},{"text":"resetShader","type":"fun","p5":true},{"text":"texture","type":"fun","params":[{"p":"tex","o":false}],"p5":true},{"text":"textureMode","type":"fun","params":[{"p":"mode","o":false}],"p5":true},{"text":"textureWrap","type":"fun","params":[{"p":"wrapX","o":false},{"p":"wrapY","o":true}],"p5":true},{"text":"normalMaterial","type":"fun","p5":true},{"text":"ambientMaterial","type":"fun","p5":true},{"text":"emissiveMaterial","type":"fun","p5":true},{"text":"specularMaterial","type":"fun","p5":true},{"text":"shininess","type":"fun","params":[{"p":"shine","o":false}],"p5":true},{"text":"metalness","type":"fun","params":[{"p":"metallic","o":false}],"p5":true},{"text":"camera","type":"fun","params":[{"p":"x","o":true},{"p":"y","o":true},{"p":"z","o":true},{"p":"centerX","o":true},{"p":"centerY","o":true},{"p":"centerZ","o":true},{"p":"upX","o":true},{"p":"upY","o":true},{"p":"upZ","o":true}],"p5":true},{"text":"perspective","type":"fun","params":[{"p":"fovy","o":true},{"p":"aspect","o":true},{"p":"near","o":true},{"p":"far","o":true}],"p5":true},{"text":"linePerspective","type":"fun","p5":true},{"text":"ortho","type":"fun","params":[{"p":"left","o":true},{"p":"right","o":true},{"p":"bottom","o":true},{"p":"top","o":true},{"p":"near","o":true},{"p":"far","o":true}],"p5":true},{"text":"frustum","type":"fun","params":[{"p":"left","o":true},{"p":"right","o":true},{"p":"bottom","o":true},{"p":"top","o":true},{"p":"near","o":true},{"p":"far","o":true}],"p5":true},{"text":"createCamera","type":"fun","p5":true},{"text":"setCamera","type":"fun","params":[{"p":"cam","o":false}],"p5":true},{"text":"setAttributes","type":"fun","p5":true},{"text":"getAudioContext","type":"fun","p5":true},{"text":"userStartAudio","type":"fun","params":[{"p":"elements","o":true},{"p":"callback","o":true}],"p5":true},{"text":"getOutputVolume","type":"fun","p5":true},{"text":"outputVolume","type":"fun","params":[{"p":"volume","o":false},{"p":"rampTime","o":true},{"p":"timeFromNow","o":true}],"p5":true},{"text":"soundOut","type":"var","params":[],"p5":true},{"text":"sampleRate","type":"fun","p5":true},{"text":"freqToMidi","type":"fun","params":[{"p":"frequency","o":false}],"p5":true},{"text":"midiToFreq","type":"fun","params":[{"p":"midiNote","o":false}],"p5":true},{"text":"soundFormats","type":"fun","params":[{"p":"formats","o":true}],"p5":true},{"text":"saveSound","type":"fun","params":[{"p":"soundFile","o":false},{"p":"fileName","o":false}],"p5":true},{"text":"loadSound","type":"fun","params":[{"p":"path","o":false},{"p":"successCallback","o":true},{"p":"errorCallback","o":true},{"p":"whileLoading","o":true}],"p5":true},{"text":"createConvolver","type":"fun","params":[{"p":"path","o":false},{"p":"callback","o":true},{"p":"errorCallback","o":true}],"p5":true},{"text":"setBPM","type":"fun","params":[{"p":"BPM","o":false},{"p":"rampTime","o":false}],"p5":true},{"text":"true","type":"boolean","p5":"boolean"},{"text":"false","type":"boolean","p5":"boolean"},{"text":"await","type":"keyword","p5":false},{"text":"break","type":"keyword","p5":false},{"text":"case","type":"keyword","p5":false},{"text":"catch","type":"keyword","p5":false},{"text":"class","type":"keyword","p5":"class"},{"text":"const","type":"keyword","p5":"const"},{"text":"continue","type":"keyword","p5":false},{"text":"debugger","type":"keyword","p5":false},{"text":"default","type":"keyword","p5":false},{"text":"delete","type":"keyword","p5":false},{"text":"do","type":"keyword","p5":false},{"text":"else","type":"keyword","p5":"if-else"},{"text":"export","type":"keyword","p5":false},{"text":"extends","type":"keyword","p5":false},{"text":"finally","type":"keyword","p5":false},{"text":"for","type":"keyword","p5":"for"},{"text":"function","type":"keyword","p5":"function"},{"text":"if","type":"keyword","p5":"if-else"},{"text":"import","type":"keyword","p5":false},{"text":"in","type":"keyword","p5":false},{"text":"instanceof","type":"keyword","p5":false},{"text":"new","type":"keyword","p5":false},{"text":"return","type":"keyword","p5":"return"},{"text":"super","type":"keyword","p5":false},{"text":"switch","type":"keyword","p5":false},{"text":"this","type":"keyword","p5":false},{"text":"throw","type":"keyword","p5":false},{"text":"try","type":"keyword","p5":false},{"text":"typeof","type":"keyword","p5":false},{"text":"var","type":"keyword","p5":false},{"text":"void","type":"keyword","p5":false},{"text":"while","type":"keyword","p5":"while"},{"text":"with","type":"keyword","p5":false},{"text":"yield","type":"keyword","p5":false},{"text":"let","type":"keyword","p5":"let"},{"text":"Array","type":"obj","p5":false},{"text":"Boolean","type":"obj","p5":false},{"text":"Date","type":"obj","p5":false},{"text":"Error","type":"obj","p5":false},{"text":"Function","type":"obj","p5":false},{"text":"JSON","type":"obj","p5":"JSON"},{"text":"Math","type":"obj","p5":false},{"text":"Number","type":"obj","p5":false},{"text":"Object","type":"obj","p5":false},{"text":"RegExp","type":"obj","p5":false},{"text":"String","type":"obj","p5":false},{"text":"Promise","type":"obj","p5":false},{"text":"Set","type":"obj","p5":false},{"text":"Map","type":"obj","p5":false},{"text":"Symbol","type":"obj","p5":false},{"text":"WeakMap","type":"obj","p5":false},{"text":"WeakSet","type":"obj","p5":false},{"text":"ArrayBuffer","type":"obj","p5":false},{"text":"DataView","type":"obj","p5":false},{"text":"Int32Array","type":"obj","p5":false},{"text":"Uint32Array","type":"obj","p5":false},{"text":"Float32Array","type":"obj","p5":false},{"text":"window","type":"obj","p5":false},{"text":"document","type":"obj","p5":false},{"text":"navigator","type":"obj","p5":false},{"text":"console","type":"obj","p5":"console"},{"text":"localStorage","type":"obj","p5":false},{"text":"sessionStorage","type":"obj","p5":false},{"text":"history","type":"obj","p5":false},{"text":"location","type":"obj","p5":false}]; +exports.p5Hinter = [ + { + text: 'describe', + type: 'fun', + params: [ + { p: 'text', o: false }, + { p: 'display', o: true } + ], + p5: true + }, + { + text: 'describeElement', + type: 'fun', + params: [ + { p: 'name', o: false }, + { p: 'text', o: false }, + { p: 'display', o: true } + ], + p5: true + }, + { + text: 'textOutput', + type: 'fun', + params: [{ p: 'display', o: true }], + p5: true + }, + { + text: 'gridOutput', + type: 'fun', + params: [{ p: 'display', o: true }], + p5: true + }, + { text: 'alpha', type: 'fun', params: [{ p: 'color', o: false }], p5: true }, + { text: 'blue', type: 'fun', params: [{ p: 'color', o: false }], p5: true }, + { + text: 'brightness', + type: 'fun', + params: [{ p: 'color', o: false }], + p5: true + }, + { text: 'color', type: 'fun', p5: true }, + { text: 'green', type: 'fun', params: [{ p: 'color', o: false }], p5: true }, + { text: 'hue', type: 'fun', params: [{ p: 'color', o: false }], p5: true }, + { + text: 'lerpColor', + type: 'fun', + params: [ + { p: 'c1', o: false }, + { p: 'c2', o: false }, + { p: 'amt', o: false } + ], + p5: true + }, + { + text: 'lightness', + type: 'fun', + params: [{ p: 'color', o: false }], + p5: true + }, + { text: 'red', type: 'fun', params: [{ p: 'color', o: false }], p5: true }, + { + text: 'saturation', + type: 'fun', + params: [{ p: 'color', o: false }], + p5: true + }, + { + text: 'beginClip', + type: 'fun', + params: [{ p: 'options', o: true }], + p5: true + }, + { text: 'endClip', type: 'fun', p5: true }, + { + text: 'clip', + type: 'fun', + params: [ + { p: 'callback', o: false }, + { p: 'options', o: true } + ], + p5: true + }, + { text: 'background', type: 'fun', p5: true }, + { + text: 'clear', + type: 'fun', + params: [ + { p: 'r', o: true }, + { p: 'g', o: true }, + { p: 'b', o: true }, + { p: 'a', o: true } + ], + p5: true + }, + { text: 'colorMode', type: 'fun', p5: true }, + { text: 'fill', type: 'fun', p5: true }, + { text: 'noFill', type: 'fun', p5: true }, + { text: 'noStroke', type: 'fun', p5: true }, + { text: 'stroke', type: 'fun', p5: true }, + { + text: 'erase', + type: 'fun', + params: [ + { p: 'strengthFill', o: true }, + { p: 'strengthStroke', o: true } + ], + p5: true + }, + { text: 'noErase', type: 'fun', p5: true }, + { + text: 'arc', + type: 'fun', + params: [ + { p: 'x', o: false }, + { p: 'y', o: false }, + { p: 'w', o: false }, + { p: 'h', o: false }, + { p: 'start', o: false }, + { p: 'stop', o: false }, + { p: 'mode', o: true }, + { p: 'detail', o: true } + ], + p5: true + }, + { text: 'ellipse', type: 'fun', p5: true }, + { + text: 'circle', + type: 'fun', + params: [ + { p: 'x', o: false }, + { p: 'y', o: false }, + { p: 'd', o: false } + ], + p5: true + }, + { text: 'line', type: 'fun', p5: true }, + { text: 'point', type: 'fun', p5: true }, + { text: 'quad', type: 'fun', p5: true }, + { text: 'rect', type: 'fun', p5: true }, + { + text: 'square', + type: 'fun', + params: [ + { p: 'x', o: false }, + { p: 'y', o: false }, + { p: 's', o: false }, + { p: 'tl', o: true }, + { p: 'tr', o: true }, + { p: 'br', o: true }, + { p: 'bl', o: true } + ], + p5: true + }, + { + text: 'triangle', + type: 'fun', + params: [ + { p: 'x1', o: false }, + { p: 'y1', o: false }, + { p: 'x2', o: false }, + { p: 'y2', o: false }, + { p: 'x3', o: false }, + { p: 'y3', o: false } + ], + p5: true + }, + { + text: 'ellipseMode', + type: 'fun', + params: [{ p: 'mode', o: false }], + p5: true + }, + { text: 'noSmooth', type: 'fun', p5: true }, + { + text: 'rectMode', + type: 'fun', + params: [{ p: 'mode', o: false }], + p5: true + }, + { text: 'smooth', type: 'fun', p5: true }, + { + text: 'strokeCap', + type: 'fun', + params: [{ p: 'cap', o: false }], + p5: true + }, + { + text: 'strokeJoin', + type: 'fun', + params: [{ p: 'join', o: false }], + p5: true + }, + { + text: 'strokeWeight', + type: 'fun', + params: [{ p: 'weight', o: false }], + p5: true + }, + { text: 'bezier', type: 'fun', p5: true }, + { + text: 'bezierDetail', + type: 'fun', + params: [{ p: 'detail', o: false }], + p5: true + }, + { + text: 'bezierPoint', + type: 'fun', + params: [ + { p: 'a', o: false }, + { p: 'b', o: false }, + { p: 'c', o: false }, + { p: 'd', o: false }, + { p: 't', o: false } + ], + p5: true + }, + { + text: 'bezierTangent', + type: 'fun', + params: [ + { p: 'a', o: false }, + { p: 'b', o: false }, + { p: 'c', o: false }, + { p: 'd', o: false }, + { p: 't', o: false } + ], + p5: true + }, + { text: 'curve', type: 'fun', p5: true }, + { + text: 'curveDetail', + type: 'fun', + params: [{ p: 'resolution', o: false }], + p5: true + }, + { + text: 'curveTightness', + type: 'fun', + params: [{ p: 'amount', o: false }], + p5: true + }, + { + text: 'curvePoint', + type: 'fun', + params: [ + { p: 'a', o: false }, + { p: 'b', o: false }, + { p: 'c', o: false }, + { p: 'd', o: false }, + { p: 't', o: false } + ], + p5: true + }, + { + text: 'curveTangent', + type: 'fun', + params: [ + { p: 'a', o: false }, + { p: 'b', o: false }, + { p: 'c', o: false }, + { p: 'd', o: false }, + { p: 't', o: false } + ], + p5: true + }, + { text: 'beginContour', type: 'fun', p5: true }, + { + text: 'beginShape', + type: 'fun', + params: [{ p: 'kind', o: true }], + p5: true + }, + { text: 'bezierVertex', type: 'fun', p5: true }, + { text: 'curveVertex', type: 'fun', p5: true }, + { text: 'endContour', type: 'fun', p5: true }, + { + text: 'endShape', + type: 'fun', + params: [ + { p: 'mode', o: true }, + { p: 'count', o: true } + ], + p5: true + }, + { text: 'quadraticVertex', type: 'fun', p5: true }, + { text: 'vertex', type: 'fun', p5: true }, + { text: 'normal', type: 'fun', p5: true }, + { text: 'VERSION', type: 'var', params: [], p5: true }, + { text: 'P2D', type: 'var', params: [], p5: true }, + { text: 'WEBGL', type: 'var', params: [], p5: true }, + { text: 'WEBGL2', type: 'var', params: [], p5: true }, + { text: 'ARROW', type: 'var', params: [], p5: true }, + { text: 'CROSS', type: 'var', params: [], p5: true }, + { text: 'HAND', type: 'var', params: [], p5: true }, + { text: 'MOVE', type: 'var', params: [], p5: true }, + { text: 'TEXT', type: 'var', params: [], p5: true }, + { text: 'WAIT', type: 'var', params: [], p5: true }, + { text: 'HALF_PI', type: 'var', params: [], p5: true }, + { text: 'PI', type: 'var', params: [], p5: true }, + { text: 'QUARTER_PI', type: 'var', params: [], p5: true }, + { text: 'TAU', type: 'var', params: [], p5: true }, + { text: 'TWO_PI', type: 'var', params: [], p5: true }, + { text: 'DEGREES', type: 'var', params: [], p5: true }, + { text: 'RADIANS', type: 'var', params: [], p5: true }, + { text: 'CORNER', type: 'var', params: [], p5: true }, + { text: 'CORNERS', type: 'var', params: [], p5: true }, + { text: 'RADIUS', type: 'var', params: [], p5: true }, + { text: 'RIGHT', type: 'var', params: [], p5: true }, + { text: 'LEFT', type: 'var', params: [], p5: true }, + { text: 'CENTER', type: 'var', params: [], p5: true }, + { text: 'TOP', type: 'var', params: [], p5: true }, + { text: 'BOTTOM', type: 'var', params: [], p5: true }, + { text: 'BASELINE', type: 'var', params: [], p5: true }, + { text: 'POINTS', type: 'var', params: [], p5: true }, + { text: 'LINES', type: 'var', params: [], p5: true }, + { text: 'LINE_STRIP', type: 'var', params: [], p5: true }, + { text: 'LINE_LOOP', type: 'var', params: [], p5: true }, + { text: 'TRIANGLES', type: 'var', params: [], p5: true }, + { text: 'TRIANGLE_FAN', type: 'var', params: [], p5: true }, + { text: 'TRIANGLE_STRIP', type: 'var', params: [], p5: true }, + { text: 'QUADS', type: 'var', params: [], p5: true }, + { text: 'QUAD_STRIP', type: 'var', params: [], p5: true }, + { text: 'TESS', type: 'var', params: [], p5: true }, + { text: 'CLOSE', type: 'var', params: [], p5: true }, + { text: 'OPEN', type: 'var', params: [], p5: true }, + { text: 'CHORD', type: 'var', params: [], p5: true }, + { text: 'PIE', type: 'var', params: [], p5: true }, + { text: 'PROJECT', type: 'var', params: [], p5: true }, + { text: 'SQUARE', type: 'var', params: [], p5: true }, + { text: 'ROUND', type: 'var', params: [], p5: true }, + { text: 'BEVEL', type: 'var', params: [], p5: true }, + { text: 'MITER', type: 'var', params: [], p5: true }, + { text: 'RGB', type: 'var', params: [], p5: true }, + { text: 'HSB', type: 'var', params: [], p5: true }, + { text: 'HSL', type: 'var', params: [], p5: true }, + { text: 'AUTO', type: 'var', params: [], p5: true }, + { text: 'ALT', type: 'var', params: [], p5: true }, + { text: 'BACKSPACE', type: 'var', params: [], p5: true }, + { text: 'CONTROL', type: 'var', params: [], p5: true }, + { text: 'DELETE', type: 'var', params: [], p5: true }, + { text: 'DOWN_ARROW', type: 'var', params: [], p5: true }, + { text: 'ENTER', type: 'var', params: [], p5: true }, + { text: 'ESCAPE', type: 'var', params: [], p5: true }, + { text: 'LEFT_ARROW', type: 'var', params: [], p5: true }, + { text: 'OPTION', type: 'var', params: [], p5: true }, + { text: 'RETURN', type: 'var', params: [], p5: true }, + { text: 'RIGHT_ARROW', type: 'var', params: [], p5: true }, + { text: 'SHIFT', type: 'var', params: [], p5: true }, + { text: 'TAB', type: 'var', params: [], p5: true }, + { text: 'UP_ARROW', type: 'var', params: [], p5: true }, + { text: 'BLEND', type: 'var', params: [], p5: true }, + { text: 'REMOVE', type: 'var', params: [], p5: true }, + { text: 'ADD', type: 'var', params: [], p5: true }, + { text: 'DARKEST', type: 'var', params: [], p5: true }, + { text: 'LIGHTEST', type: 'var', params: [], p5: true }, + { text: 'DIFFERENCE', type: 'var', params: [], p5: true }, + { text: 'SUBTRACT', type: 'var', params: [], p5: true }, + { text: 'EXCLUSION', type: 'var', params: [], p5: true }, + { text: 'MULTIPLY', type: 'var', params: [], p5: true }, + { text: 'SCREEN', type: 'var', params: [], p5: true }, + { text: 'REPLACE', type: 'var', params: [], p5: true }, + { text: 'OVERLAY', type: 'var', params: [], p5: true }, + { text: 'HARD_LIGHT', type: 'var', params: [], p5: true }, + { text: 'SOFT_LIGHT', type: 'var', params: [], p5: true }, + { text: 'DODGE', type: 'var', params: [], p5: true }, + { text: 'BURN', type: 'var', params: [], p5: true }, + { text: 'THRESHOLD', type: 'var', params: [], p5: true }, + { text: 'GRAY', type: 'var', params: [], p5: true }, + { text: 'OPAQUE', type: 'var', params: [], p5: true }, + { text: 'INVERT', type: 'var', params: [], p5: true }, + { text: 'POSTERIZE', type: 'var', params: [], p5: true }, + { text: 'DILATE', type: 'var', params: [], p5: true }, + { text: 'ERODE', type: 'var', params: [], p5: true }, + { text: 'BLUR', type: 'var', params: [], p5: true }, + { text: 'NORMAL', type: 'var', params: [], p5: true }, + { text: 'ITALIC', type: 'var', params: [], p5: true }, + { text: 'BOLD', type: 'var', params: [], p5: true }, + { text: 'BOLDITALIC', type: 'var', params: [], p5: true }, + { text: 'CHAR', type: 'var', params: [], p5: true }, + { text: 'WORD', type: 'var', params: [], p5: true }, + { text: 'LINEAR', type: 'var', params: [], p5: true }, + { text: 'QUADRATIC', type: 'var', params: [], p5: true }, + { text: 'BEZIER', type: 'var', params: [], p5: true }, + { text: 'CURVE', type: 'var', params: [], p5: true }, + { text: 'STROKE', type: 'var', params: [], p5: true }, + { text: 'FILL', type: 'var', params: [], p5: true }, + { text: 'TEXTURE', type: 'var', params: [], p5: true }, + { text: 'IMMEDIATE', type: 'var', params: [], p5: true }, + { text: 'IMAGE', type: 'var', params: [], p5: true }, + { text: 'NEAREST', type: 'var', params: [], p5: true }, + { text: 'REPEAT', type: 'var', params: [], p5: true }, + { text: 'CLAMP', type: 'var', params: [], p5: true }, + { text: 'MIRROR', type: 'var', params: [], p5: true }, + { text: 'FLAT', type: 'var', params: [], p5: true }, + { text: 'SMOOTH', type: 'var', params: [], p5: true }, + { text: 'LANDSCAPE', type: 'var', params: [], p5: true }, + { text: 'PORTRAIT', type: 'var', params: [], p5: true }, + { text: 'GRID', type: 'var', params: [], p5: true }, + { text: 'AXES', type: 'var', params: [], p5: true }, + { text: 'LABEL', type: 'var', params: [], p5: true }, + { text: 'FALLBACK', type: 'var', params: [], p5: true }, + { text: 'CONTAIN', type: 'var', params: [], p5: true }, + { text: 'COVER', type: 'var', params: [], p5: true }, + { text: 'UNSIGNED_BYTE', type: 'var', params: [], p5: true }, + { text: 'UNSIGNED_INT', type: 'var', params: [], p5: true }, + { text: 'FLOAT', type: 'var', params: [], p5: true }, + { text: 'HALF_FLOAT', type: 'var', params: [], p5: true }, + { text: 'RGBA', type: 'var', params: [], p5: true }, + { + text: 'print', + type: 'fun', + params: [{ p: 'contents', o: false }], + p5: true + }, + { text: 'frameCount', type: 'var', params: [], p5: true }, + { text: 'deltaTime', type: 'var', params: [], p5: true }, + { text: 'focused', type: 'var', params: [], p5: true }, + { + text: 'cursor', + type: 'fun', + params: [ + { p: 'type', o: false }, + { p: 'x', o: true }, + { p: 'y', o: true } + ], + p5: true + }, + { text: 'frameRate', type: 'fun', p5: true }, + { text: 'getTargetFrameRate', type: 'fun', p5: true }, + { text: 'noCursor', type: 'fun', p5: true }, + { text: 'webglVersion', type: 'var', params: [], p5: true }, + { text: 'displayWidth', type: 'var', params: [], p5: true }, + { text: 'displayHeight', type: 'var', params: [], p5: true }, + { text: 'windowWidth', type: 'var', params: [], p5: true }, + { text: 'windowHeight', type: 'var', params: [], p5: true }, + { + text: 'windowResized', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { text: 'width', type: 'var', params: [], p5: true }, + { text: 'height', type: 'var', params: [], p5: true }, + { + text: 'fullscreen', + type: 'fun', + params: [{ p: 'val', o: true }], + p5: true + }, + { text: 'pixelDensity', type: 'fun', p5: true }, + { text: 'displayDensity', type: 'fun', p5: true }, + { text: 'getURL', type: 'fun', p5: true }, + { text: 'getURLPath', type: 'fun', p5: true }, + { text: 'getURLParams', type: 'fun', p5: true }, + { text: 'preload', type: 'fun', p5: true }, + { text: 'setup', type: 'fun', p5: true }, + { text: 'draw', type: 'fun', p5: true }, + { text: 'remove', type: 'fun', p5: true }, + { text: 'disableFriendlyErrors', type: 'var', params: [], p5: true }, + { text: 'createCanvas', type: 'fun', p5: true }, + { + text: 'resizeCanvas', + type: 'fun', + params: [ + { p: 'width', o: false }, + { p: 'height', o: false }, + { p: 'noRedraw', o: true } + ], + p5: true + }, + { text: 'noCanvas', type: 'fun', p5: true }, + { text: 'createGraphics', type: 'fun', p5: true }, + { + text: 'createFramebuffer', + type: 'fun', + params: [{ p: 'options', o: true }], + p5: true + }, + { + text: 'clearDepth', + type: 'fun', + params: [{ p: 'depth', o: true }], + p5: true + }, + { + text: 'blendMode', + type: 'fun', + params: [{ p: 'mode', o: false }], + p5: true + }, + { text: 'drawingContext', type: 'var', params: [], p5: true }, + { text: 'noLoop', type: 'fun', p5: true }, + { text: 'loop', type: 'fun', p5: true }, + { text: 'isLooping', type: 'fun', p5: true }, + { text: 'push', type: 'fun', p5: true }, + { text: 'pop', type: 'fun', p5: true }, + { text: 'redraw', type: 'fun', params: [{ p: 'n', o: true }], p5: true }, + { + text: 'p5', + type: 'fun', + params: [ + { p: 'sketch', o: false }, + { p: 'node', o: false } + ], + p5: true + }, + { text: 'applyMatrix', type: 'fun', p5: true }, + { text: 'resetMatrix', type: 'fun', p5: true }, + { + text: 'rotate', + type: 'fun', + params: [ + { p: 'angle', o: false }, + { p: 'axis', o: true } + ], + p5: true + }, + { + text: 'rotateX', + type: 'fun', + params: [{ p: 'angle', o: false }], + p5: true + }, + { + text: 'rotateY', + type: 'fun', + params: [{ p: 'angle', o: false }], + p5: true + }, + { + text: 'rotateZ', + type: 'fun', + params: [{ p: 'angle', o: false }], + p5: true + }, + { text: 'scale', type: 'fun', p5: true }, + { text: 'shearX', type: 'fun', params: [{ p: 'angle', o: false }], p5: true }, + { text: 'shearY', type: 'fun', params: [{ p: 'angle', o: false }], p5: true }, + { text: 'translate', type: 'fun', p5: true }, + { + text: 'storeItem', + type: 'fun', + params: [ + { p: 'key', o: false }, + { p: 'value', o: false } + ], + p5: true + }, + { text: 'getItem', type: 'fun', params: [{ p: 'key', o: false }], p5: true }, + { text: 'clearStorage', type: 'fun', p5: true }, + { + text: 'removeItem', + type: 'fun', + params: [{ p: 'key', o: false }], + p5: true + }, + { text: 'createStringDict', type: 'fun', p5: true }, + { text: 'createNumberDict', type: 'fun', p5: true }, + { + text: 'select', + type: 'fun', + params: [ + { p: 'selectors', o: false }, + { p: 'container', o: true } + ], + p5: true + }, + { + text: 'selectAll', + type: 'fun', + params: [ + { p: 'selectors', o: false }, + { p: 'container', o: true } + ], + p5: true + }, + { text: 'removeElements', type: 'fun', p5: true }, + { text: 'changed', type: 'fun', params: [{ p: 'fxn', o: false }], p5: true }, + { text: 'input', type: 'fun', params: [{ p: 'fxn', o: false }], p5: true }, + { + text: 'createDiv', + type: 'fun', + params: [{ p: 'html', o: true }], + p5: true + }, + { text: 'createP', type: 'fun', params: [{ p: 'html', o: true }], p5: true }, + { + text: 'createSpan', + type: 'fun', + params: [{ p: 'html', o: true }], + p5: true + }, + { text: 'createImg', type: 'fun', p5: true }, + { + text: 'createA', + type: 'fun', + params: [ + { p: 'href', o: false }, + { p: 'html', o: false }, + { p: 'target', o: true } + ], + p5: true + }, + { + text: 'createSlider', + type: 'fun', + params: [ + { p: 'min', o: false }, + { p: 'max', o: false }, + { p: 'value', o: true }, + { p: 'step', o: true } + ], + p5: true + }, + { + text: 'createButton', + type: 'fun', + params: [ + { p: 'label', o: false }, + { p: 'value', o: true } + ], + p5: true + }, + { + text: 'createCheckbox', + type: 'fun', + params: [ + { p: 'label', o: true }, + { p: 'value', o: true } + ], + p5: true + }, + { text: 'createSelect', type: 'fun', p5: true }, + { text: 'createRadio', type: 'fun', p5: true }, + { + text: 'createColorPicker', + type: 'fun', + params: [{ p: 'value', o: true }], + p5: true + }, + { text: 'createInput', type: 'fun', p5: true }, + { + text: 'createFileInput', + type: 'fun', + params: [ + { p: 'callback', o: false }, + { p: 'multiple', o: true } + ], + p5: true + }, + { + text: 'createVideo', + type: 'fun', + params: [ + { p: 'src', o: false }, + { p: 'callback', o: true } + ], + p5: true + }, + { + text: 'createAudio', + type: 'fun', + params: [ + { p: 'src', o: true }, + { p: 'callback', o: true } + ], + p5: true + }, + { + text: 'createCapture', + type: 'fun', + params: [ + { p: 'type', o: true }, + { p: 'flipped', o: true }, + { p: 'callback', o: true } + ], + p5: true + }, + { + text: 'createElement', + type: 'fun', + params: [ + { p: 'tag', o: false }, + { p: 'content', o: true } + ], + p5: true + }, + { text: 'deviceOrientation', type: 'var', params: [], p5: true }, + { text: 'accelerationX', type: 'var', params: [], p5: true }, + { text: 'accelerationY', type: 'var', params: [], p5: true }, + { text: 'accelerationZ', type: 'var', params: [], p5: true }, + { text: 'pAccelerationX', type: 'var', params: [], p5: true }, + { text: 'pAccelerationY', type: 'var', params: [], p5: true }, + { text: 'pAccelerationZ', type: 'var', params: [], p5: true }, + { text: 'rotationX', type: 'var', params: [], p5: true }, + { text: 'rotationY', type: 'var', params: [], p5: true }, + { text: 'rotationZ', type: 'var', params: [], p5: true }, + { text: 'pRotationX', type: 'var', params: [], p5: true }, + { text: 'pRotationY', type: 'var', params: [], p5: true }, + { text: 'pRotationZ', type: 'var', params: [], p5: true }, + { text: 'turnAxis', type: 'var', params: [], p5: true }, + { + text: 'setMoveThreshold', + type: 'fun', + params: [{ p: 'value', o: false }], + p5: true + }, + { + text: 'setShakeThreshold', + type: 'fun', + params: [{ p: 'value', o: false }], + p5: true + }, + { text: 'deviceMoved', type: 'fun', p5: true }, + { text: 'deviceTurned', type: 'fun', p5: true }, + { text: 'deviceShaken', type: 'fun', p5: true }, + { text: 'keyIsPressed', type: 'var', params: [], p5: true }, + { text: 'key', type: 'var', params: [], p5: true }, + { text: 'keyCode', type: 'var', params: [], p5: true }, + { + text: 'keyPressed', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'keyReleased', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'keyTyped', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'keyIsDown', + type: 'fun', + params: [{ p: 'code', o: false }], + p5: true + }, + { text: 'movedX', type: 'var', params: [], p5: true }, + { text: 'movedY', type: 'var', params: [], p5: true }, + { text: 'mouseX', type: 'var', params: [], p5: true }, + { text: 'mouseY', type: 'var', params: [], p5: true }, + { text: 'pmouseX', type: 'var', params: [], p5: true }, + { text: 'pmouseY', type: 'var', params: [], p5: true }, + { text: 'winMouseX', type: 'var', params: [], p5: true }, + { text: 'winMouseY', type: 'var', params: [], p5: true }, + { text: 'pwinMouseX', type: 'var', params: [], p5: true }, + { text: 'pwinMouseY', type: 'var', params: [], p5: true }, + { text: 'mouseButton', type: 'var', params: [], p5: true }, + { text: 'mouseIsPressed', type: 'var', params: [], p5: true }, + { + text: 'mouseMoved', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'mouseDragged', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'mousePressed', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'mouseReleased', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'mouseClicked', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'doubleClicked', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'mouseWheel', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { text: 'requestPointerLock', type: 'fun', p5: true }, + { text: 'exitPointerLock', type: 'fun', p5: true }, + { text: 'touches', type: 'var', params: [], p5: true }, + { + text: 'touchStarted', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'touchMoved', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'touchEnded', + type: 'fun', + params: [{ p: 'event', o: true }], + p5: true + }, + { + text: 'createImage', + type: 'fun', + params: [ + { p: 'width', o: false }, + { p: 'height', o: false } + ], + p5: true + }, + { text: 'saveCanvas', type: 'fun', p5: true }, + { + text: 'saveFrames', + type: 'fun', + params: [ + { p: 'filename', o: false }, + { p: 'extension', o: false }, + { p: 'duration', o: false }, + { p: 'framerate', o: false }, + { p: 'callback', o: true } + ], + p5: true + }, + { + text: 'loadImage', + type: 'fun', + params: [ + { p: 'path', o: false }, + { p: 'successCallback', o: true }, + { p: 'failureCallback', o: true } + ], + p5: true + }, + { + text: 'saveGif', + type: 'fun', + params: [ + { p: 'filename', o: false }, + { p: 'duration', o: false }, + { p: 'options', o: true } + ], + p5: true + }, + { text: 'image', type: 'fun', p5: true }, + { text: 'tint', type: 'fun', p5: true }, + { text: 'noTint', type: 'fun', p5: true }, + { + text: 'imageMode', + type: 'fun', + params: [{ p: 'mode', o: false }], + p5: true + }, + { text: 'pixels', type: 'var', params: [], p5: true }, + { text: 'blend', type: 'fun', p5: true }, + { text: 'copy', type: 'fun', p5: true }, + { text: 'filter', type: 'fun', p5: true }, + { text: 'get', type: 'fun', p5: true }, + { text: 'loadPixels', type: 'fun', p5: true }, + { + text: 'set', + type: 'fun', + params: [ + { p: 'x', o: false }, + { p: 'y', o: false }, + { p: 'c', o: false } + ], + p5: true + }, + { + text: 'updatePixels', + type: 'fun', + params: [ + { p: 'x', o: true }, + { p: 'y', o: true }, + { p: 'w', o: true }, + { p: 'h', o: true } + ], + p5: true + }, + { + text: 'loadJSON', + type: 'fun', + params: [ + { p: 'path', o: false }, + { p: 'successCallback', o: true }, + { p: 'errorCallback', o: true } + ], + p5: true + }, + { + text: 'loadStrings', + type: 'fun', + params: [ + { p: 'path', o: false }, + { p: 'successCallback', o: true }, + { p: 'errorCallback', o: true } + ], + p5: true + }, + { + text: 'loadTable', + type: 'fun', + params: [ + { p: 'filename', o: false }, + { p: 'extension', o: true }, + { p: 'header', o: true }, + { p: 'callback', o: true }, + { p: 'errorCallback', o: true } + ], + p5: true + }, + { + text: 'loadXML', + type: 'fun', + params: [ + { p: 'path', o: false }, + { p: 'successCallback', o: true }, + { p: 'errorCallback', o: true } + ], + p5: true + }, + { + text: 'loadBytes', + type: 'fun', + params: [ + { p: 'file', o: false }, + { p: 'callback', o: true }, + { p: 'errorCallback', o: true } + ], + p5: true + }, + { text: 'httpGet', type: 'fun', p5: true }, + { text: 'httpPost', type: 'fun', p5: true }, + { text: 'httpDo', type: 'fun', p5: true }, + { + text: 'createWriter', + type: 'fun', + params: [ + { p: 'name', o: false }, + { p: 'extension', o: true } + ], + p5: true + }, + { + text: 'save', + type: 'fun', + params: [ + { p: 'objectOrFilename', o: true }, + { p: 'filename', o: true }, + { p: 'options', o: true } + ], + p5: true + }, + { + text: 'saveJSON', + type: 'fun', + params: [ + { p: 'json', o: false }, + { p: 'filename', o: false }, + { p: 'optimize', o: true } + ], + p5: true + }, + { + text: 'saveStrings', + type: 'fun', + params: [ + { p: 'list', o: false }, + { p: 'filename', o: false }, + { p: 'extension', o: true }, + { p: 'isCRLF', o: true } + ], + p5: true + }, + { + text: 'saveTable', + type: 'fun', + params: [ + { p: 'Table', o: false }, + { p: 'filename', o: false }, + { p: 'options', o: true } + ], + p5: true + }, + { text: 'abs', type: 'fun', params: [{ p: 'n', o: false }], p5: true }, + { text: 'ceil', type: 'fun', params: [{ p: 'n', o: false }], p5: true }, + { + text: 'constrain', + type: 'fun', + params: [ + { p: 'n', o: false }, + { p: 'low', o: false }, + { p: 'high', o: false } + ], + p5: true + }, + { text: 'dist', type: 'fun', p5: true }, + { text: 'exp', type: 'fun', params: [{ p: 'n', o: false }], p5: true }, + { text: 'floor', type: 'fun', params: [{ p: 'n', o: false }], p5: true }, + { + text: 'lerp', + type: 'fun', + params: [ + { p: 'start', o: false }, + { p: 'stop', o: false }, + { p: 'amt', o: false } + ], + p5: true + }, + { text: 'log', type: 'fun', params: [{ p: 'n', o: false }], p5: true }, + { + text: 'mag', + type: 'fun', + params: [ + { p: 'x', o: false }, + { p: 'y', o: false } + ], + p5: true + }, + { + text: 'map', + type: 'fun', + params: [ + { p: 'value', o: false }, + { p: 'start1', o: false }, + { p: 'stop1', o: false }, + { p: 'start2', o: false }, + { p: 'stop2', o: false }, + { p: 'withinBounds', o: true } + ], + p5: true + }, + { text: 'max', type: 'fun', p5: true }, + { text: 'min', type: 'fun', p5: true }, + { + text: 'norm', + type: 'fun', + params: [ + { p: 'value', o: false }, + { p: 'start', o: false }, + { p: 'stop', o: false } + ], + p5: true + }, + { + text: 'pow', + type: 'fun', + params: [ + { p: 'n', o: false }, + { p: 'e', o: false } + ], + p5: true + }, + { + text: 'round', + type: 'fun', + params: [ + { p: 'n', o: false }, + { p: 'decimals', o: true } + ], + p5: true + }, + { text: 'sq', type: 'fun', params: [{ p: 'n', o: false }], p5: true }, + { text: 'sqrt', type: 'fun', params: [{ p: 'n', o: false }], p5: true }, + { text: 'fract', type: 'fun', params: [{ p: 'n', o: false }], p5: true }, + { + text: 'createVector', + type: 'fun', + params: [ + { p: 'x', o: true }, + { p: 'y', o: true }, + { p: 'z', o: true } + ], + p5: true + }, + { + text: 'noise', + type: 'fun', + params: [ + { p: 'x', o: false }, + { p: 'y', o: true }, + { p: 'z', o: true } + ], + p5: true + }, + { + text: 'noiseDetail', + type: 'fun', + params: [ + { p: 'lod', o: false }, + { p: 'falloff', o: false } + ], + p5: true + }, + { + text: 'noiseSeed', + type: 'fun', + params: [{ p: 'seed', o: false }], + p5: true + }, + { + text: 'randomSeed', + type: 'fun', + params: [{ p: 'seed', o: false }], + p5: true + }, + { text: 'random', type: 'fun', p5: true }, + { + text: 'randomGaussian', + type: 'fun', + params: [ + { p: 'mean', o: true }, + { p: 'sd', o: true } + ], + p5: true + }, + { text: 'acos', type: 'fun', params: [{ p: 'value', o: false }], p5: true }, + { text: 'asin', type: 'fun', params: [{ p: 'value', o: false }], p5: true }, + { text: 'atan', type: 'fun', params: [{ p: 'value', o: false }], p5: true }, + { + text: 'atan2', + type: 'fun', + params: [ + { p: 'y', o: false }, + { p: 'x', o: false } + ], + p5: true + }, + { text: 'cos', type: 'fun', params: [{ p: 'angle', o: false }], p5: true }, + { text: 'sin', type: 'fun', params: [{ p: 'angle', o: false }], p5: true }, + { text: 'tan', type: 'fun', params: [{ p: 'angle', o: false }], p5: true }, + { + text: 'degrees', + type: 'fun', + params: [{ p: 'radians', o: false }], + p5: true + }, + { + text: 'radians', + type: 'fun', + params: [{ p: 'degrees', o: false }], + p5: true + }, + { text: 'angleMode', type: 'fun', p5: true }, + { text: 'textAlign', type: 'fun', p5: true }, + { text: 'textLeading', type: 'fun', p5: true }, + { text: 'textSize', type: 'fun', p5: true }, + { text: 'textStyle', type: 'fun', p5: true }, + { + text: 'textWidth', + type: 'fun', + params: [{ p: 'str', o: false }], + p5: true + }, + { text: 'textAscent', type: 'fun', p5: true }, + { text: 'textDescent', type: 'fun', p5: true }, + { + text: 'textWrap', + type: 'fun', + params: [{ p: 'style', o: false }], + p5: true + }, + { + text: 'loadFont', + type: 'fun', + params: [ + { p: 'path', o: false }, + { p: 'successCallback', o: true }, + { p: 'failureCallback', o: true } + ], + p5: true + }, + { + text: 'text', + type: 'fun', + params: [ + { p: 'str', o: false }, + { p: 'x', o: false }, + { p: 'y', o: false }, + { p: 'maxWidth', o: true }, + { p: 'maxHeight', o: true } + ], + p5: true + }, + { text: 'textFont', type: 'fun', p5: true }, + { + text: 'append', + type: 'fun', + params: [ + { p: 'array', o: false }, + { p: 'value', o: false } + ], + p5: true + }, + { text: 'arrayCopy', type: 'fun', p5: true }, + { + text: 'concat', + type: 'fun', + params: [ + { p: 'a', o: false }, + { p: 'b', o: false } + ], + p5: true + }, + { text: 'reverse', type: 'fun', params: [{ p: 'list', o: false }], p5: true }, + { text: 'shorten', type: 'fun', params: [{ p: 'list', o: false }], p5: true }, + { + text: 'shuffle', + type: 'fun', + params: [ + { p: 'array', o: false }, + { p: 'bool', o: true } + ], + p5: true + }, + { + text: 'sort', + type: 'fun', + params: [ + { p: 'list', o: false }, + { p: 'count', o: true } + ], + p5: true + }, + { + text: 'splice', + type: 'fun', + params: [ + { p: 'list', o: false }, + { p: 'value', o: false }, + { p: 'position', o: false } + ], + p5: true + }, + { + text: 'subset', + type: 'fun', + params: [ + { p: 'list', o: false }, + { p: 'start', o: false }, + { p: 'count', o: true } + ], + p5: true + }, + { text: 'float', type: 'fun', p5: true }, + { text: 'int', type: 'fun', p5: true }, + { text: 'str', type: 'fun', params: [{ p: 'n', o: false }], p5: true }, + { text: 'boolean', type: 'fun', p5: true }, + { text: 'byte', type: 'fun', p5: true }, + { text: 'char', type: 'fun', p5: true }, + { text: 'unchar', type: 'fun', p5: true }, + { text: 'hex', type: 'fun', p5: true }, + { text: 'unhex', type: 'fun', p5: true }, + { + text: 'join', + type: 'fun', + params: [ + { p: 'list', o: false }, + { p: 'separator', o: false } + ], + p5: true + }, + { + text: 'match', + type: 'fun', + params: [ + { p: 'str', o: false }, + { p: 'regexp', o: false } + ], + p5: true + }, + { + text: 'matchAll', + type: 'fun', + params: [ + { p: 'str', o: false }, + { p: 'regexp', o: false } + ], + p5: true + }, + { text: 'nf', type: 'fun', p5: true }, + { text: 'nfc', type: 'fun', p5: true }, + { text: 'nfp', type: 'fun', p5: true }, + { text: 'nfs', type: 'fun', p5: true }, + { + text: 'split', + type: 'fun', + params: [ + { p: 'value', o: false }, + { p: 'delim', o: false } + ], + p5: true + }, + { + text: 'splitTokens', + type: 'fun', + params: [ + { p: 'value', o: false }, + { p: 'delim', o: true } + ], + p5: true + }, + { text: 'trim', type: 'fun', p5: true }, + { text: 'day', type: 'fun', p5: true }, + { text: 'hour', type: 'fun', p5: true }, + { text: 'minute', type: 'fun', p5: true }, + { text: 'millis', type: 'fun', p5: true }, + { text: 'month', type: 'fun', p5: true }, + { text: 'second', type: 'fun', p5: true }, + { text: 'year', type: 'fun', p5: true }, + { text: 'beginGeometry', type: 'fun', p5: true }, + { text: 'endGeometry', type: 'fun', p5: true }, + { + text: 'buildGeometry', + type: 'fun', + params: [{ p: 'callback', o: false }], + p5: true + }, + { + text: 'freeGeometry', + type: 'fun', + params: [{ p: 'geometry', o: false }], + p5: true + }, + { + text: 'plane', + type: 'fun', + params: [ + { p: 'width', o: true }, + { p: 'height', o: true }, + { p: 'detailX', o: true }, + { p: 'detailY', o: true } + ], + p5: true + }, + { + text: 'box', + type: 'fun', + params: [ + { p: 'width', o: true }, + { p: 'height', o: true }, + { p: 'depth', o: true }, + { p: 'detailX', o: true }, + { p: 'detailY', o: true } + ], + p5: true + }, + { + text: 'sphere', + type: 'fun', + params: [ + { p: 'radius', o: true }, + { p: 'detailX', o: true }, + { p: 'detailY', o: true } + ], + p5: true + }, + { + text: 'cylinder', + type: 'fun', + params: [ + { p: 'radius', o: true }, + { p: 'height', o: true }, + { p: 'detailX', o: true }, + { p: 'detailY', o: true }, + { p: 'bottomCap', o: true }, + { p: 'topCap', o: true } + ], + p5: true + }, + { + text: 'cone', + type: 'fun', + params: [ + { p: 'radius', o: true }, + { p: 'height', o: true }, + { p: 'detailX', o: true }, + { p: 'detailY', o: true }, + { p: 'cap', o: true } + ], + p5: true + }, + { + text: 'ellipsoid', + type: 'fun', + params: [ + { p: 'radiusX', o: true }, + { p: 'radiusY', o: true }, + { p: 'radiusZ', o: true }, + { p: 'detailX', o: true }, + { p: 'detailY', o: true } + ], + p5: true + }, + { + text: 'torus', + type: 'fun', + params: [ + { p: 'radius', o: true }, + { p: 'tubeRadius', o: true }, + { p: 'detailX', o: true }, + { p: 'detailY', o: true } + ], + p5: true + }, + { + text: 'orbitControl', + type: 'fun', + params: [ + { p: 'sensitivityX', o: true }, + { p: 'sensitivityY', o: true }, + { p: 'sensitivityZ', o: true }, + { p: 'options', o: true } + ], + p5: true + }, + { text: 'debugMode', type: 'fun', p5: true }, + { text: 'noDebugMode', type: 'fun', p5: true }, + { text: 'ambientLight', type: 'fun', p5: true }, + { text: 'specularColor', type: 'fun', p5: true }, + { text: 'directionalLight', type: 'fun', p5: true }, + { text: 'pointLight', type: 'fun', p5: true }, + { + text: 'imageLight', + type: 'fun', + params: [{ p: 'img', o: false }], + p5: true + }, + { text: 'panorama', type: 'fun', params: [{ p: 'img', o: false }], p5: true }, + { text: 'lights', type: 'fun', p5: true }, + { + text: 'lightFalloff', + type: 'fun', + params: [ + { p: 'constant', o: false }, + { p: 'linear', o: false }, + { p: 'quadratic', o: false } + ], + p5: true + }, + { text: 'spotLight', type: 'fun', p5: true }, + { text: 'noLights', type: 'fun', p5: true }, + { text: 'loadModel', type: 'fun', p5: true }, + { text: 'model', type: 'fun', params: [{ p: 'model', o: false }], p5: true }, + { + text: 'loadShader', + type: 'fun', + params: [ + { p: 'vertFilename', o: false }, + { p: 'fragFilename', o: false }, + { p: 'successCallback', o: true }, + { p: 'failureCallback', o: true } + ], + p5: true + }, + { + text: 'createShader', + type: 'fun', + params: [ + { p: 'vertSrc', o: false }, + { p: 'fragSrc', o: false } + ], + p5: true + }, + { + text: 'createFilterShader', + type: 'fun', + params: [{ p: 'fragSrc', o: false }], + p5: true + }, + { text: 'shader', type: 'fun', params: [{ p: 's', o: false }], p5: true }, + { text: 'resetShader', type: 'fun', p5: true }, + { text: 'texture', type: 'fun', params: [{ p: 'tex', o: false }], p5: true }, + { + text: 'textureMode', + type: 'fun', + params: [{ p: 'mode', o: false }], + p5: true + }, + { + text: 'textureWrap', + type: 'fun', + params: [ + { p: 'wrapX', o: false }, + { p: 'wrapY', o: true } + ], + p5: true + }, + { text: 'normalMaterial', type: 'fun', p5: true }, + { text: 'ambientMaterial', type: 'fun', p5: true }, + { text: 'emissiveMaterial', type: 'fun', p5: true }, + { text: 'specularMaterial', type: 'fun', p5: true }, + { + text: 'shininess', + type: 'fun', + params: [{ p: 'shine', o: false }], + p5: true + }, + { + text: 'metalness', + type: 'fun', + params: [{ p: 'metallic', o: false }], + p5: true + }, + { + text: 'camera', + type: 'fun', + params: [ + { p: 'x', o: true }, + { p: 'y', o: true }, + { p: 'z', o: true }, + { p: 'centerX', o: true }, + { p: 'centerY', o: true }, + { p: 'centerZ', o: true }, + { p: 'upX', o: true }, + { p: 'upY', o: true }, + { p: 'upZ', o: true } + ], + p5: true + }, + { + text: 'perspective', + type: 'fun', + params: [ + { p: 'fovy', o: true }, + { p: 'aspect', o: true }, + { p: 'near', o: true }, + { p: 'far', o: true } + ], + p5: true + }, + { text: 'linePerspective', type: 'fun', p5: true }, + { + text: 'ortho', + type: 'fun', + params: [ + { p: 'left', o: true }, + { p: 'right', o: true }, + { p: 'bottom', o: true }, + { p: 'top', o: true }, + { p: 'near', o: true }, + { p: 'far', o: true } + ], + p5: true + }, + { + text: 'frustum', + type: 'fun', + params: [ + { p: 'left', o: true }, + { p: 'right', o: true }, + { p: 'bottom', o: true }, + { p: 'top', o: true }, + { p: 'near', o: true }, + { p: 'far', o: true } + ], + p5: true + }, + { text: 'createCamera', type: 'fun', p5: true }, + { + text: 'setCamera', + type: 'fun', + params: [{ p: 'cam', o: false }], + p5: true + }, + { text: 'setAttributes', type: 'fun', p5: true }, + { text: 'getAudioContext', type: 'fun', p5: true }, + { + text: 'userStartAudio', + type: 'fun', + params: [ + { p: 'elements', o: true }, + { p: 'callback', o: true } + ], + p5: true + }, + { text: 'getOutputVolume', type: 'fun', p5: true }, + { + text: 'outputVolume', + type: 'fun', + params: [ + { p: 'volume', o: false }, + { p: 'rampTime', o: true }, + { p: 'timeFromNow', o: true } + ], + p5: true + }, + { text: 'soundOut', type: 'var', params: [], p5: true }, + { text: 'sampleRate', type: 'fun', p5: true }, + { + text: 'freqToMidi', + type: 'fun', + params: [{ p: 'frequency', o: false }], + p5: true + }, + { + text: 'midiToFreq', + type: 'fun', + params: [{ p: 'midiNote', o: false }], + p5: true + }, + { + text: 'soundFormats', + type: 'fun', + params: [{ p: 'formats', o: true }], + p5: true + }, + { + text: 'saveSound', + type: 'fun', + params: [ + { p: 'soundFile', o: false }, + { p: 'fileName', o: false } + ], + p5: true + }, + { + text: 'loadSound', + type: 'fun', + params: [ + { p: 'path', o: false }, + { p: 'successCallback', o: true }, + { p: 'errorCallback', o: true }, + { p: 'whileLoading', o: true } + ], + p5: true + }, + { + text: 'createConvolver', + type: 'fun', + params: [ + { p: 'path', o: false }, + { p: 'callback', o: true }, + { p: 'errorCallback', o: true } + ], + p5: true + }, + { + text: 'setBPM', + type: 'fun', + params: [ + { p: 'BPM', o: false }, + { p: 'rampTime', o: false } + ], + p5: true + }, + { text: 'true', type: 'boolean', p5: 'boolean' }, + { text: 'false', type: 'boolean', p5: 'boolean' }, + { text: 'await', type: 'keyword', p5: false }, + { text: 'break', type: 'keyword', p5: false }, + { text: 'case', type: 'keyword', p5: false }, + { text: 'catch', type: 'keyword', p5: false }, + { text: 'class', type: 'keyword', p5: 'class' }, + { text: 'const', type: 'keyword', p5: 'const' }, + { text: 'continue', type: 'keyword', p5: false }, + { text: 'debugger', type: 'keyword', p5: false }, + { text: 'default', type: 'keyword', p5: false }, + { text: 'delete', type: 'keyword', p5: false }, + { text: 'do', type: 'keyword', p5: false }, + { text: 'else', type: 'keyword', p5: 'if-else' }, + { text: 'export', type: 'keyword', p5: false }, + { text: 'extends', type: 'keyword', p5: false }, + { text: 'finally', type: 'keyword', p5: false }, + { text: 'for', type: 'keyword', p5: 'for' }, + { text: 'function', type: 'keyword', p5: 'function' }, + { text: 'if', type: 'keyword', p5: 'if-else' }, + { text: 'import', type: 'keyword', p5: false }, + { text: 'in', type: 'keyword', p5: false }, + { text: 'instanceof', type: 'keyword', p5: false }, + { text: 'new', type: 'keyword', p5: false }, + { text: 'return', type: 'keyword', p5: 'return' }, + { text: 'super', type: 'keyword', p5: false }, + { text: 'switch', type: 'keyword', p5: false }, + { text: 'this', type: 'keyword', p5: false }, + { text: 'throw', type: 'keyword', p5: false }, + { text: 'try', type: 'keyword', p5: false }, + { text: 'typeof', type: 'keyword', p5: false }, + { text: 'var', type: 'keyword', p5: false }, + { text: 'void', type: 'keyword', p5: false }, + { text: 'while', type: 'keyword', p5: 'while' }, + { text: 'with', type: 'keyword', p5: false }, + { text: 'yield', type: 'keyword', p5: false }, + { text: 'let', type: 'keyword', p5: 'let' }, + { text: 'Array', type: 'obj', p5: false }, + { text: 'Boolean', type: 'obj', p5: false }, + { text: 'Date', type: 'obj', p5: false }, + { text: 'Error', type: 'obj', p5: false }, + { text: 'Function', type: 'obj', p5: false }, + { text: 'JSON', type: 'obj', p5: 'JSON' }, + { text: 'Math', type: 'obj', p5: false }, + { text: 'Number', type: 'obj', p5: false }, + { text: 'Object', type: 'obj', p5: false }, + { text: 'RegExp', type: 'obj', p5: false }, + { text: 'String', type: 'obj', p5: false }, + { text: 'Promise', type: 'obj', p5: false }, + { text: 'Set', type: 'obj', p5: false }, + { text: 'Map', type: 'obj', p5: false }, + { text: 'Symbol', type: 'obj', p5: false }, + { text: 'WeakMap', type: 'obj', p5: false }, + { text: 'WeakSet', type: 'obj', p5: false }, + { text: 'ArrayBuffer', type: 'obj', p5: false }, + { text: 'DataView', type: 'obj', p5: false }, + { text: 'Int32Array', type: 'obj', p5: false }, + { text: 'Uint32Array', type: 'obj', p5: false }, + { text: 'Float32Array', type: 'obj', p5: false }, + { text: 'window', type: 'obj', p5: false }, + { text: 'document', type: 'obj', p5: false }, + { text: 'navigator', type: 'obj', p5: false }, + { text: 'console', type: 'obj', p5: 'console' }, + { text: 'localStorage', type: 'obj', p5: false }, + { text: 'sessionStorage', type: 'obj', p5: false }, + { text: 'history', type: 'obj', p5: false }, + { text: 'location', type: 'obj', p5: false } +];