-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathespeasy.min.js
More file actions
8 lines (8 loc) · 24.9 KB
/
espeasy.min.js
File metadata and controls
8 lines (8 loc) · 24.9 KB
1
2
3
4
5
6
7
8
var rEdit,commonAtoms=["And","Or"],commonKeywords=["If","Else","Elseif","Endif"],commonCommands=["AccessInfo","Background","Build","ClearAccessBlock","ClearRTCam","Config","ControllerDisable","ControllerEnable","DateTime","Debug","Dec","DeepSleep","DisablePriorityTask","DNS","DST","EraseSDKWiFi","ExecuteRules","FactoryReset","Gateway","I2Cscanner","Inc","IP","Let","LetStr","Load","LogEntry","LogPortStatus","LoopTimerSet","LoopTimerSet_ms","LoopTimerSetAndRun","LoopTimerSetAndRun_ms","MemInfo","MemInfoDetail","Name","Password","PostToHTTP","PostToHTTPS","Publish","PublishR","Reboot","Save","SendTo","SendToHTTP","SendToHTTPS","SendToUDP","SendToUDPMix","Settings","Subnet","Subscribe","TaskClear","TaskClearAll","PutToHTTP","PutToHTTPS","TaskDisable","TaskEnable","TaskRun","TaskValueSet","TaskValueSetAndRun","TaskValueSetDerived","TaskValueSetPresentation","TimerPause","TimerResume","TimerSet","TimerSet_ms","TimeZone","UdpPort","UdpTest","Unit","UseNTP","WdConfig","WdRead","WiFi","WiFiAllowAP","WiFiAPMode","WiFiConnect","WiFiDisconnect","WiFiKey","WiFiKey2","WiFiMode","WiFiScan","WiFiSSID","WiFiSSID2","WiFiSTAMode","Event","AsyncEvent","GPIO","GPIOToggle","LongPulse","LongPulse_mS","Monitor","Pulse","PWM","Servo","Status","Tone","RTTTL","UnMonitor","Provision","Provision,Config","Provision,Security","Provision,Notification","Provision,Provision","Provision,Rules","Provision,CustomCdnUrl","Provision,Firmware"],commonEvents=["Clock#Time","Login#Failed","MQTT#Connected","MQTT#Disconnected","MQTTimport#Connected","MQTTimport#Disconnected","Rules#Timer","System#Boot","System#BootMode","System#Sleep","System#Wake","TaskExit#","TaskInit#","ThingspeakReply","Time#Initialized","Time#Set","WiFi#APmodeDisabled","WiFi#APmodeEnabled","WiFi#ChangedAccesspoint","WiFi#ChangedWiFichannel","WiFi#Connected","WiFi#Disconnected"],commonPlugins=["ResetPulseCounter","SetPulseCounterTotal","LogPulseStatistic","analogout","MCPGPIO","MCPGPIOToggle","MCPLongPulse","MCPLongPulse_ms","MCPPulse","Status,MCP","Monitor,MCP","MonitorRange,MCP","UnMonitorRange,MCP","UnMonitor,MCP","MCPGPIORange","MCPGPIOPattern","MCPMode","MCPModeRange","ExtGpio","ExtPwm","ExtPulse","ExtLongPulse","Status,EXT,","LCDCmd","LCD","PCFGPIO","PCFGPIOToggle","PCFLongPulse","PCFLongPulse_ms","PCFPulse","Status,PCF","Monitor,PCF","MonitorRange,PCF","UnMonitorRange,PCF","UnMonitor,PCF","PCFGPIORange","PCFGPIOpattern","PCFMode","PCFmodeRange","SerialSend","SerialSendMix","Ser2NetClientSend","SerialSend_test","pcapwm","pcafrq","mode2","OLED","OLEDCMD","OLEDCMD,on","OLEDCMD,off","OLEDCMD,clear","IRSEND","IRSENDAC","OledFramedCmd","OledFramedCmd,Display","OledFramedCmd,low","OledFramedCmd,med","OledFramedCmd,high","OledFramedCmd,Frame","OledFramedCmd,linecount","OledFramedCmd,leftalign","OledFramedCmd,align","OledFramedCmd,userDef1","OledFramedCmd,userDef2","NeoPixel","NeoPixelAll","NeoPixelLine","NeoPixelHSV","NeoPixelAllHSV","NeoPixelLineHSV","NeoPixelBright","MotorShieldCmd,DCMotor","MotorShieldCmd,Stepper","MHZCalibrateZero","MHZReset","MHZABCEnable","MHZABCDisable","Sensair_SetRelay","PMSX003","PMSX003,Wake","PMSX003,Sleep","PMSX003,Reset","encwrite","Play","Vol","Eq","Mode","Repeat","tareChanA","tareChanB","7dn","7dst","7dsd","7dtext","7ddt","7dt","7dtfont","7dtbin","7don","7doff","7output","HLWCalibrate","HLWReset","csecalibrate","cseclearpulses","csereset","WemosMotorShieldCMD","LolinMotorShieldCMD","GPS","GPS,Sleep","GPS,Wake","GPS#GotFix","GPS#LostFix","GPS#Travelled","homieValueSet","SerialProxy_Write","SerialProxy_WriteMix","SerialProxy_Test","HeatPumpir","MitsubishiHP","MitsubishiHP,temperature","MitsubishiHP,power","MitsubishiHP,mode","MitsubishiHP,fan","MitsubishiHP,vane","MitsubishiHP,widevane","Culreader_Write","Touch","Touch,Rot","Touch,Flip","Touch,Enable","Touch,Disable","Touch,On","Touch,Off","Touch,Toggle","Touch,Setgrp","Touch,Incgrp","Touch,Decgrp","Touch,Incpage","Touch,Decpage","Touch,Updatebutton","WakeOnLan","DotMatrix","DotMatrix,clear","DotMatrix,update","DotMatrix,size","DotMatrix,txt","DotMatrix,settxt","DotMatrix,content","DotMatrix,alignment","DotMatrix,anim.in","DotMatrix,anim.out","DotMatrix,speed","DotMatrix,pause","DotMatrix,font","DotMatrix,layout","DotMatrix,inverted","DotMatrix,specialeffect","DotMatrix,offset","DotMatrix,brightness","DotMatrix,repeat","DotMatrix,setbar","DotMatrix,bar","Thermo","Thermo,Up","Thermo,Down","Thermo,Mode","Thermo,ModeBtn","Thermo,Setpoint","Max1704xclearalert","scdgetabc","scdgetalt","scdgettmp","scdsetcalibration","scdsetfrc","scdgetinterval","multirelay","multirelay,on","multirelay,off","multirelay,set","multirelay,get","multirelay,loop","ShiftOut","ShiftOut,Set","ShiftOut,SetNoUpdate","ShiftOut,Update","ShiftOut,SetAll","ShiftOut,SetAllNoUpdate","ShiftOut,SetAllLow","ShiftOut,SetAllHigh","ShiftOut,SetChipCount","ShiftOut,SetHexBin","cdmrst","nfx","nfx,off","nfx,on","nfx,dim","nfx,line,","nfx,hsvline,","nfx,one,","nfx,hsvone,","nfx,all,","nfx,rgb,","nfx,fade,","nfx,hsv,","nfx,colorfade,","nfx,rainbow","nfx,kitt,","nfx,comet,","nfx,theatre,","nfx,scan,","nfx,dualscan,","nfx,twinkle,","nfx,twinklefade,","nfx,sparkle,","nfx,wipe,","nfx,dualwipe","nfx,fire","nfx,fireflicker","nfx,faketv","nfx,simpleclock","nfx,stop","nfx,statusrequest","nfx,fadetime,","nfx,fadedelay,","nfx,speed,","nfx,count,","nfx,bgcolor","ShiftIn","ShiftIn,PinEvent","ShiftIn,ChipEvent","ShiftIn,SetChipCount","ShiftIn,SampleFrequency","ShiftIn,EventPerPin","scd4x","scd4x,storesettings","scd4x,facoryreset","scd4x,selftest","scd4x,setfrc,","axp","axp,ldo2","axp,ldo3","axp,ldoio","axp,gpio0","axp,gpio1","axp,gpio2","axp,gpio3","axp,gpio4","axp,dcdc2","axp,dcdc3","axp,ldo2map","axp,ldo3map","axp,ldoiomap","axp,dcdc2map","axp,dcdc3map","axp,ldo2perc","axp,ldo3perc","axp,ldoioperc","axp,dcdc2perc","axp,dcdc3perc","I2CEncoder","I2CEncoder,bright","I2CEncoder,led1","I2CEncoder,led2","I2CEncoder,gain","I2CEncoder,set","cachereader","cachereader,readpos","cachereader,sendtaskinfo","cachereader,flush","tm1621","tm1621,write,","tm1621,writerow,","tm1621,voltamp,","tm1621,energy,","tm1621,celcius,","tm1621,fahrenheit,","tm1621,humidity,","tm1621,raw,","dac","dac,1","dac,2","sht4x","sht4x,startup","ld2410","ld2410,factoryreset","ld2410,logall","digipot","digipot,reset","digipot,shutdown","digipot,","7dextra","7dbefore","7dgroup","7digit","7color","7digitcolor","7groupcolor","gp8403","gp8403,volt,","gp8403,mvolt,","gp8403,range,","gp8403,preset,","gp8403,init,","sen5x","sen5x,startclean","sen5x,techlog,","as3935","as3935,clearstats","as3935,calibrate","as3935,setgain,","as3935,setnf,","as3935,setwd,","as3925,setsrej,","lu9685","lu9685,servo,","lu9685,enable,","lu9685,disable,","lu9685,setrange,","geni2c","geni2c,cmd,","geni2c,exec,","geni2c,log,",],pluginDispKind=["tft","ili9341","ili9342","ili9481","ili9486","ili9488","epd","eink","epaper","il3897","uc8151d","ssd1680","ws2in7","ws1in54","st77xx","st7735","st7789","st7796","neomatrix","neo","pcd8544",],pluginDispCmd=["cmd,on","cmd,off","cmd,clear","cmd,backlight","cmd,bright","cmd,deepsleep","cmd,seq_start","cmd,seq_end","cmd,inv","cmd,rot",",clear",",rot",",tpm",",txt",",txp",",txz",",txc",",txs",",txtfull",",asciitable",",font",",l",",lh",",lv",",lm",",lmr",",r",",rf",",c",",cf",",rf",",t",",tf",",rr",",rrf",",px",",pxh",",pxv",",bmp",",btn",",win",",defwin",",delwin",],commonTag=["On","Do","Endon"],commonNumber=["toBin","toHex","Constrain","XOR","AND:","OR:","Ord","bitRead","bitSet","bitClear","bitWrite","urlencode"],commonMath=["Log","Ln","Abs","Exp","Sqrt","Sq","Round","Sin","Cos","Tan","aSin","aCos","aTan","Sin_d","Cos_d","Tan_d","aSin_d","aCos_d","aTan_d","map","mapc"],commonWarning=["delay","Delay","ResetFlashWriteCounter"],taskSpecifics=["settings.Enabled","settings.Interval","settings.ValueCount","settings.Controller1.Enabled","settings.Controller2.Enabled","settings.Controller3.Enabled","settings.Controller1.Idx","settings.Controller2.Idx","settings.Controller3.Idx"],AnythingElse=["%eventvalue%","%eventpar%","%eventname%","%sysname%","%bootcause%","%systime%","%systm_hm%","%systm_hm_0%","%systm_hm_sp%","%systime_am%","%systime_am_0%","%systime_am_sp%","%systm_hm_am%","%systm_hm_am_0%","%systm_hm_am_sp%","%lcltime%","%sunrise%","%s_sunrise%","%m_sunrise%","%sunset%","%s_sunset%","%m_sunset%","%lcltime_am%","%syshour%","%syshour_0%","%sysmin%","%sysmin_0%","%syssec%","%syssec_0%","%sysday%","%sysday_0%","%sysmonth%","%sysmonth_0%","%systzoffset%","%systzoffset_s%","%sysyear%","%sysyear_0%","%sysyears%","%sysweekday%","%sysweekday_s%","%unixtime%","%unixtime_lcl%","%uptime%","%uptime_ms%","%rssi%","%ip%","%unit%","%unit_0%","%ssid%","%bssid%","%wi_ch%","%iswifi%","%vcc%","%mac%","%mac_int%","%isntp%","%ismqtt%","%dns%","%dns1%","%dns2%","%flash_freq%","%flash_size%","%flash_chip_vendor%","%flash_chip_model%","%fs_free%","%fs_size%","%cpu_id%","%cpu_freq%","%cpu_model%","%cpu_rev%","%cpu_cores%","%board_name%","%inttemp%","%islimited_build%","%isvar_double%","substring","lookup","indexOf","indexOf_ci","equals","equals_ci","strtol","timeToMin","timeToSec","%ethwifimode%","%ethconnected%","%ethduplex%","%ethspeed%","%ethstate%","%ethspeedstate%","%c_w_dir%","%c_c2f%","%c_ms2Bft%","%c_dew_th%","%c_alt_pres_sea%","%c_sea_pres_alt%","%c_cm2imp%","%c_isnum%","%c_mm2imp%","%c_m2day%","%c_m2dh%","%c_m2dhm%","%c_s2dhms%","%c_ts2date%","%c_ts2wday%","%c_random%","%c_2hex%","%c_u2ip%","%c_uname%","%c_uage%","%c_ubuild%","%c_ubuildstr%","%c_uload%","%c_utype%","%c_utypestr%","%c_strf%","var","int","str","length"];for(const element2 of pluginDispKind)commonPlugins=commonPlugins.concat(element2);for(const element2 of pluginDispKind)for(const element3 of pluginDispCmd){let e=element2+element3;commonPlugins=commonPlugins.concat(e)}var EXTRAWORDS=commonAtoms.concat(commonPlugins,commonKeywords,commonCommands,commonEvents,commonTag,commonNumber,commonMath,commonWarning,taskSpecifics,AnythingElse),confirmR=!0,android=/Android/.test(navigator.userAgent);function initCM(){function e(e){}android&&(confirmR=!!confirm("Do you want to enable colored rules on your Android device?\nThis feature hasn't been fully tested yet and may still have some issues.\nIt is currently expected to work with Chrome, Firefox, and Vivaldi.\nPlease report any problems you encounter.")),confirmR&&(CodeMirror.commands.autocomplete=function(e){e.showHint({hint:CodeMirror.hint.anyword})},(rEdit=CodeMirror.fromTextArea(document.getElementById("rules"),{tabSize:2,indentWithTabs:!1,lineNumbers:!0,autoCloseBrackets:!0,extraKeys:{"Ctrl-Space":"autocomplete",Tab(e){"null"===e.getMode().name?e.execCommand("insertTab"):e.somethingSelected()?e.execCommand("indentMore"):e.execCommand("insertSoftTab")},"Shift-Tab":e=>e.execCommand("indentLess")}})).on("change",function(){rEdit.save()}),android||rEdit.on("inputRead",function(e,t){var n=e.getCursor(),i=e.getTokenAt(n);/[\w%,.]/.test(t.text)&&"comment"!=i.type&&e.showHint({completeSingle:!1})}),CodeMirror.keyMap.default["Ctrl-F"]=function(e){openFind()},CodeMirror.keyMap.default["Cmd-F"]=function(e){openFind()},CodeMirror.keyMap.default["Ctrl-G"]=e,CodeMirror.keyMap.default["Cmd-G"]=e,CodeMirror.keyMap.default["Shift-Ctrl-G"]=e,CodeMirror.keyMap.default["Shift-Cmd-G"]=e,CodeMirror.keyMap.default["Ctrl-H"]=e,CodeMirror.keyMap.default["Cmd-H"]=e,CodeMirror.keyMap.default["Shift-Ctrl-F"]=e,CodeMirror.keyMap.default["Shift-Cmd-F"]=e,CodeMirror.keyMap.default["Ctrl-Shift-R"]=e,CodeMirror.keyMap.default["Cmd-Shift-R"]=e)}function closeSearchDialog(){let e=document.querySelectorAll(".CodeMirror-dialog");e.length>0&&(e.forEach(e=>e.remove()),document.body.classList.remove("dialog-opened")),rEdit.execCommand("clearSearch")}function removeHighlight(){requestAnimationFrame(()=>{let e=document.querySelectorAll(".search-next-highlight");e.forEach(e=>e.classList.remove("search-next-highlight"))}),console.log("Removing highlights")}let findDialogObserver=null;function openFind(){findDialogObserver&&(document.querySelectorAll(".CodeMirror-dialog").forEach(e=>e.remove()),findDialogObserver.disconnect(),findDialogObserver=null),(findDialogObserver=new MutationObserver(()=>{document.querySelector(".CodeMirror-dialog")||(removeHighlight(),findDialogObserver.disconnect(),findDialogObserver=null)})).observe(document.body,{childList:!0,subtree:!0}),clearSearchNextHighlight(rEdit),rEdit.execCommand("findPersistent"),addFindButtons()}function clearSearchNextHighlight(e){removeHighlight(),e.__searchNextHighlight&&(e.__searchNextHighlight.clear(),e.__searchNextHighlight=null)}function addFindButtons(){document.querySelector(".CodeMirror-selected");let e=document.querySelector(".CodeMirror-dialog");if(!e||e.querySelector(".search-button-group"))return;let t=[{title:"Find Previous",symbol:"▲",action:()=>rEdit.execCommand("findPersistentPrev")},{title:"Find Next",symbol:"▼",action:()=>rEdit.execCommand("findPersistentNext")},{title:"Replace",symbol:"Replace",action(){closeSearchDialog(),rEdit.execCommand("replace"),addFindButtons()}},{title:"Close",symbol:"❌",action:closeSearchDialog},{title:"Help",symbol:"?",action(){alert(`Available shortcuts:
• Ctrl+F / Cmd+F: Open search
• Enter: Find next
• Shift+Enter: Find previous
• Use /re/ syntax for regex search`)}}];t.forEach(({title:t,symbol:n,action:i})=>{let o=document.createElement("span");o.title=t,o.className="help"===t.toLowerCase()?"button help":"button",o.innerHTML=n,o.style.cssText=`
cursor: pointer;
user-select: none;
`,o.addEventListener("click",e=>{e.preventDefault(),i()}),e.appendChild(o)})}function triggerFormatting(){let e,t,n,i,o;if(confirmR){let r=rEdit.getDoc();e=rEdit.getScrollInfo(),n=0===(t=r.getCursor()).ch?t.line-1:t.line,i=rEdit.getLine(n)||"",o=rEdit.getValue()}else o=document.getElementById("rules").value;if(o=formatLogic(o=initalAutocorrection(o)),confirmR){rEdit.setValue(o);let s=n,a=0===t.ch&&i.length>0?i.length:t.ch;rEdit.setCursor({line:s,ch:a}),setTimeout(()=>{rEdit.scrollTo(e.left,e.top),rEdit.focus()},0),rEdit.save()}else document.getElementById("rules").value=o}function initalAutocorrection(e){for(let t of EXTRAWORDS)if("Do"===t){let n=/(^|\s)(do)(\s*)(\/\/.*)?$/gmi;e=e.replace(n,(e,t,n,i,o)=>`${t}Do${i}${o??""}`)}else{let i=RegExp(`^\\s*\\b${t}\\b`,"gmi");e=e.replace(i,e=>e.replace(RegExp(t,"i"),t))}return e}function formatLogic(e){let t=e.split("\n").map(e=>{let t=e.trimStart();return t.startsWith("//")?e:t}),n=[],i=[],o=!1,r=null,s=[],a=[];function l(e){return e.trim().startsWith("//")}function c(e){return""===e.trim()}function d(e){return e.trim().toLowerCase().startsWith("on")}function m(e){return e.trim().toLowerCase().endsWith("do")}function u(e){return"endon"===e.trim().toLowerCase()}function f(e){return e.trim().toLowerCase().startsWith("if")}function h(e){return"else"===e.trim().toLowerCase()}function p(e){return e.trim().toLowerCase().startsWith("elseif")}function g(e){return"endif"===e.trim().toLowerCase()}let x=0;function C(){s.length>0&&(i.push(`• Missing ${s.length} Endif(s):`),i.push(` - Unclosed If block(s) starting at line(s): ${a.join(", ")}`)),s=[],a=[]}for(let S=0;S<t.length;S++){let y=t[S],P=y.trim();if(l(P)){n.push(y);continue}if(c(P)){n.push("");continue}if(d(P)){m(P)||i.push(`• Line ${S+1}: "On" statement must end with "Do"`),o&&(i.push(`• Line ${S+1}: Found "On..." before previous "On...Do" (line ${r+1}) was closed with "Endon"`),C()),o=!0,r=S,x=1,n.push(P);continue}if(u(P)){o?(C(),o=!1,r=null,x=0):i.push(`• Line ${S+1}: Found "Endon" without a matching "On...Do"`),n.push(" ".repeat(x)+P);continue}if(o){if(f(P)){n.push(" ".repeat(x)+P),s.push("if"),a.push(S+1),x++;continue}if(h(P)){console.log("Else found:",P),0===s.length?i.push(`• Line ${S+1}: "Else" without matching "If"`):x=Math.max(x-1,0),n.push(" ".repeat(x)+P),x++;continue}if(p(P)){console.log("Elseif found:",P),0===s.length?i.push(`• Line ${S+1}: "Elseif" without matching "If"`):x=Math.max(x-1,0),n.push(" ".repeat(x)+P),x++;continue}if(g(P)){0===s.length?i.push(`• Line ${S+1}: "Endif" without matching "If"`):(x=Math.max(x-1,0),s.pop(),a.pop()),n.push(" ".repeat(x)+P);continue}n.push(" ".repeat(x)+P);continue}n.push(P)}if(o&&(i.push(`• Missing "Endon" for "On...Do" starting at line ${r+1}`),C()),i.length>0){let b=extractFirstErrorLine(i);if(alert("Errors found:\n"+i.join("\n")),!isNaN(b)){if(confirmR)setTimeout(()=>{jumpToLine(b)},50);else{let v=document.getElementById("rules");setTimeout(()=>{jumpToLineInTextarea(v,b)},50)}}}return n.join("\n")}function jumpToLine(e){let t=Math.max(0,e-1);rEdit.setCursor({line:t,ch:0}),rEdit.focus(),rEdit.scrollIntoView({line:t,ch:0},100)}function extractFirstErrorLine(e){for(let t of e){let n=t.match(/• Line (\d+)/);if(n||(n=t.match(/starting at line (\d+)/))||(n=t.match(/starting at line\(s\):\s*(\d+)/)))return parseInt(n[1])}return null}function jumpToLineInTextarea(e,t){let n=e.value.split("\n"),i=Math.max(1,Math.min(t,n.length)),o=0;for(let r=0;r<i-1;r++)o+=n[r].length+1;e.focus(),e.selectionStart=e.selectionEnd=o,e.scrollTop=e.scrollHeight,e.scrollTop=e.scrollTop-e.clientHeight/2}document.addEventListener("DOMContentLoaded",()=>{let e=document.getElementById("rulesselect");if(e){if(confirmR){let t=document.createElement("button");t.type="button",t.id="searchBtn",t.innerHTML="🔎︎",t.style.padding="2px 5px",t.className="button help",e.appendChild(t),t.addEventListener("click",()=>{void 0!==rEdit&&openFind()})}let n=document.createElement("button");n.type="button",n.id="formatBtn",n.textContent="Format",n.className="button",e.appendChild(n),n.addEventListener("click",()=>{console.log("Format button clicked"),triggerFormatting()})}let i="";if(document.addEventListener("keydown",function(e){let t=e.key;(["Backspace","Delete","ArrowLeft","ArrowRight","ArrowUp","ArrowDown","Enter","Tab","Escape","Shift","Control","Alt","Meta"].includes(t)||1!==t.length)&&(i="")}),android){var o=!1;rEdit.on("keydown",(e,t)=>{["Enter","Backspace"," "].includes(t.key)&&(i=""),o=!0});let r="",s=rEdit.getInputField();function a(e,t=!1){if(!rEdit.hasFocus()||!rEdit||!e.data||!o)return;o=!1;let n=e.data,s=rEdit.getDoc(),a=s.getCursor(),l=rEdit.getTokenAt(a);if(" "===n){console.log("Clearing buffer due to space"),i="",r="";return}if(n!==r||!(i.length>0)){if(/[\w%,.]/.test(n)&&"comment"!==l.type){let c=a.ch<=1?n.slice(-1):n;i+=c,r=i,i.startsWith(String(a.line+1))&&0===a.ch&&(i=i.slice(String(a.line).length)),console.log("Buffer updated:",i);let d={line:a.line,ch:a.ch-i.length+1},m=()=>{s.replaceRange(i,d,a),rEdit.setCursor({line:d.line,ch:d.ch+i.length}),rEdit.showHint({completeSingle:!1})};t?m():setTimeout(m,0)}else i=""}}let l=navigator.userAgent.toLowerCase(),c=/firefox/.test(l),d=/chrome/.test(l)&&!c;c?s.addEventListener("beforeinput",e=>{e.preventDefault(),a(e,!0)}):d&&document.addEventListener("input",e=>{a(e,!1)}),rEdit.on("endCompletion",function(){setTimeout(()=>{m()},100)})}function m(){let e=document.createElement("input");e.type="text",e.style.position="absolute",e.style.opacity="0",e.style.height="0",e.style.width="0",e.style.border="none",e.style.top="0",e.style.left="-9999",e.style.padding="0",e.style.zIndex="-1",e.style.fontSize="16px",document.body.appendChild(e),e.focus(),setTimeout(()=>{e.remove(),rEdit.focus()},10)}}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("codemirror")):"function"==typeof define&&define.amd?define(["codemirror"],e):e(CodeMirror)}(function(e){"use strict";e.defineMode("espeasy",function(){var e={};function t(t,n){for(var i=0;i<n.length;i++)e[n[i]]=t}var n=commonCommands.map(e=>e.toLowerCase());commonCommands=commonCommands.concat(n);var i=commonEvents.map(e=>e.toLowerCase());commonEvents=commonEvents.concat(i);var o=commonPlugins.map(e=>e.toLowerCase());commonPlugins=commonPlugins.concat(o);var r=commonAtoms.map(e=>e.toLowerCase());commonAtoms=commonAtoms.concat(r);var s=commonKeywords.map(e=>e.toLowerCase());commonKeywords=commonKeywords.concat(s);var a=commonTag.map(e=>e.toLowerCase());commonTag=commonTag.concat(a);var l=commonNumber.map(e=>e.toLowerCase());commonNumber=commonNumber.concat(l);var c=commonMath.map(e=>e.toLowerCase());commonMath=commonMath.concat(c);var d=AnythingElse.map(e=>e.toLowerCase());AnythingElse=AnythingElse.concat(d);var m=taskSpecifics.map(e=>e.toLowerCase());function u(t,n){if(t.eatSpace())return null;t.sol();var i=t.next();if(/\d/.test(i)){if("0"==i)return"x"===t.next()?(t.eatWhile(/\w/),"number"):(t.eatWhile(/\d|\./),"number");if(t.eatWhile(/\d|\./),!t.match("d")&&!t.match("output")&&(t.eol()||/\D/.test(t.peek())))return"number"}if(/\w/.test(i))for(let o of EXTRAWORDS){let r=o.substring(1);(o.includes(":")||o.includes(",")||o.includes("."))&&t.match(r)}if(/\w/.test(i)&&(t.eatWhile(/[\w]/),t.match(".gpio")||t.match(".pulse")||t.match(".frq")||t.match(".pwm")))return"def";if("\\"===i)return t.next(),null;if("("===i||")"===i)return"bracket";if("{"===i||"}"===i||":"===i)return"number";if("/"==i)return/\//.test(t.peek())?(t.skipToEnd(),"comment"):"operator";if("'"==i&&(t.eatWhile(/[^']/),t.match("'")))return"attribute";if("+"===i||"="===i||"<"===i||">"===i||"-"===i||","===i||"*"===i||"!"===i)return"operator";if("%"==i){if(/\d/.test(t.next()))return"number";if(t.eatWhile(/[^\s\%]/),t.match("%"))return"hr"}if("["==i&&(t.eatWhile(/[^\s\]]/),t.eat("]")))return"hr";t.eatWhile(/\w/);var s=t.current();return/\w/.test(i)&&t.match("#")?(t.eatWhile(/[\w.#]/),"events"):"#"===i?(t.eatWhile(/\w/),"number"):e.hasOwnProperty(s)?e[s]:null}return taskSpecifics=taskSpecifics.concat(m),t("atom",commonAtoms),t("keyword",commonKeywords),t("builtin",commonCommands),t("events",commonEvents),t("def",commonPlugins),t("tag",commonTag),t("number",commonNumber),t("bracket",commonMath),t("warning",commonWarning),t("hr",AnythingElse),t("comment",taskSpecifics),{startState:function(){return{tokens:[]}},token:function(e,t){var n,i;return n=e,((i=t).tokens[0]||u)(n,i)},closeBrackets:"[]{}''\"\"``()",lineComment:"//",fold:"brace"}})}),function(e){"object"==typeof exports&&"object"==typeof module?e(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],mod):e(CodeMirror)}(function(e){var t={pairs:"()[]{}''\"\"",closeBefore:")]}'\":;>",triples:"",explode:"[]{}"},n=e.Pos;function i(e,n){return"pairs"==n&&"string"==typeof e?e:"object"==typeof e&&null!=e[n]?e[n]:t[n]}e.defineOption("autoCloseBrackets",!1,function(t,n,s){s&&s!=e.Init&&(t.removeKeyMap(o),t.state.closeBrackets=null),n&&(r(i(n,"pairs")),t.state.closeBrackets=n,t.addKeyMap(o))});var o={Backspace:function t(o){var r=a(o);if(!r||o.getOption("disableInput"))return e.Pass;for(var s=i(r,"pairs"),l=o.listSelections(),c=0;c<l.length;c++){if(!l[c].empty())return e.Pass;var m=d(o,l[c].head);if(!m||s.indexOf(m)%2!=0)return e.Pass}for(var c=l.length-1;c>=0;c--){var u=l[c].head;o.replaceRange("",n(u.line,u.ch-1),n(u.line,u.ch+1),"+delete")}},Enter:function t(n){var o=a(n),r=o&&i(o,"explode");if(!r||n.getOption("disableInput"))return e.Pass;for(var s=n.listSelections(),c=0;c<s.length;c++){if(!s[c].empty())return e.Pass;var m=d(n,s[c].head);if(!m||r.indexOf(m)%2!=0)return e.Pass}n.operation(function(){var e=n.lineSeparator()||"\n";n.replaceSelection(e+e,null),l(n,-1),s=n.listSelections();for(var t=0;t<s.length;t++){var i=s[t].head.line;n.indentLine(i,null,!0),n.indentLine(i+1,null,!0)}})}};function r(e){for(var t=0;t<e.length;t++){var n=e.charAt(t),i="'"+n+"'";o[i]||(o[i]=s(n))}}function s(t){return function(o){return function t(o,r){var s=a(o);if(!s||o.getOption("disableInput"))return e.Pass;var d=i(s,"pairs"),u=d.indexOf(r);if(-1==u)return e.Pass;for(var f=i(s,"closeBefore"),h=i(s,"triples"),p=d.charAt(u+1)==r,g=o.listSelections(),x=u%2==0,C=0;C<g.length;C++){var S,y,P=g[C],b=P.head,v=o.getRange(b,n(b.line,b.ch+1));if(x&&!P.empty())y="surround";else if((p||!x)&&v==r)y=p&&m(o,b)?"both":h.indexOf(r)>=0&&o.getRange(b,n(b.line,b.ch+3))==r+r+r?"skipThree":"skip";else if(p&&b.ch>1&&h.indexOf(r)>=0&&o.getRange(n(b.line,b.ch-2),b)==r+r){if(b.ch>2&&/\bstring/.test(o.getTokenTypeAt(n(b.line,b.ch-2))))return e.Pass;y="addFour"}else if(p){var T=0==b.ch?" ":o.getRange(n(b.line,b.ch-1),b);if(e.isWordChar(v)||T==r||e.isWordChar(T))return e.Pass;y="both"}else{if(!(x&&(0===v.length||/\s/.test(v)||f.indexOf(v)>-1)))return e.Pass;y="both"}if(S){if(S!=y)return e.Pass}else S=y}var E=u%2?d.charAt(u-1):r,M=u%2?r:d.charAt(u+1);o.operation(function(){if("skip"==S)l(o,1);else if("skipThree"==S)l(o,3);else if("surround"==S){for(var e=o.getSelections(),t=0;t<e.length;t++)e[t]=E+e[t]+M;o.replaceSelections(e,"around"),e=o.listSelections().slice();for(var t=0;t<e.length;t++)e[t]=c(e[t]);o.setSelections(e)}else"both"==S?(o.replaceSelection(E+M,null),o.triggerElectric(E+M),l(o,-1)):"addFour"==S&&(o.replaceSelection(E+E+E+E,"before"),l(o,1))})}(o,t)}}function a(e){var t=e.state.closeBrackets;return!t||t.override?t:e.getModeAt(e.getCursor()).closeBrackets||t}function l(e,t){for(var n=[],i=e.listSelections(),o=0,r=0;r<i.length;r++){var s=i[r];s.head==e.getCursor()&&(o=r);var a=s.head.ch||t>0?{line:s.head.line,ch:s.head.ch+t}:{line:s.head.line-1};n.push({anchor:a,head:a})}e.setSelections(n,o)}function c(t){var i=e.cmpPos(t.anchor,t.head)>0;return{anchor:new n(t.anchor.line,t.anchor.ch+(i?-1:1)),head:new n(t.head.line,t.head.ch+(i?1:-1))}}function d(e,t){var i=e.getRange(n(t.line,t.ch-1),n(t.line,t.ch+1));return 2==i.length?i:null}function m(e,t){var i=e.getTokenAt(n(t.line,t.ch+1));return/\bstring/.test(i.type)&&i.start==t.ch&&(0==t.ch||!/\bstring/.test(e.getTokenTypeAt(t)))}r(t.pairs+"`")});