473 lines
60 KiB
C
473 lines
60 KiB
C
/*
|
|
* More web UI HTML source arrays.
|
|
* This file is auto generated, please don't make any changes manually.
|
|
* Instead, see https://kno.wled.ge/advanced/custom-features/#changing-web-ui
|
|
* to find out how to easily modify the web UI source!
|
|
*/
|
|
|
|
// Autogenerated from wled00/data/style.css, do not edit!!
|
|
const char PAGE_settingsCss[] PROGMEM = R"=====(<style>body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%%;margin:0}hr{border-color:#666}a{color:#28f;text-decoration:none}.btn,button{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:12px 8px 8px;padding:1px 6px;cursor:pointer;text-decoration:none}.lnk{border:0}.helpB{text-align:left;position:absolute;width:60px}input{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}input:disabled{color:#888}input[type=number]{width:4em;margin:2px}input[type=number].xxl{width:100px}input[type=number].xl{width:85px}input[type=number].l{width:63px}input[type=number].m{width:56px}input[type=number].s{width:49px}input[type=number].xs{width:42px}input[type=checkbox]{transform:scale(1.5)}select{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.5ch solid #333}td{padding:2px}.d5{width:4.5em!important}#toast{opacity:0;background-color:#444;border-radius:5px;bottom:64px;color:#fff;font-size:17px;padding:16px;pointer-events:none;position:fixed;text-align:center;z-index:5;transform:translateX(-50%%);max-width:90%%;left:50%%}#toast.show{opacity:1;background-color:#264;animation:fadein .5s,fadein .5s 2.5s reverse}#toast.error{opacity:1;background-color:#b21;animation:fadein .5s}</style>)=====";
|
|
|
|
|
|
// Autogenerated from wled00/data/settings.htm, do not edit!!
|
|
const char PAGE_settings[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><title>WLED Settings
|
|
</title><style>
|
|
body{text-align:center;background:#222;height:100px;margin:0}html{--h:10.2vh}button{background:#333;color:#fff;font-family:Verdana,Helvetica,sans-serif;border:1px solid #333;border-radius:var(--h);font-size:6vmin;height:var(--h);width:calc(100%% - 40px);margin-top:2vh}
|
|
</style></head><body><form action="/"><button type="submit" id="b">Back</button>
|
|
</form><form action="/settings/wifi"><button type="submit">WiFi Setup</button>
|
|
</form><form action="/settings/leds"><button type="submit">LED Preferences
|
|
</button></form><form action="/settings/ui"><button type="submit">User Interface
|
|
</button></form><form action="/settings/sync"><button type="submit">
|
|
Sync Interfaces</button></form><form action="/settings/time"><button
|
|
type="submit">Time & Macros</button></form><form action="/settings/um"><button
|
|
type="submit">Usermods</button></form>%DMXMENU%<form action="/settings/sec"><button
|
|
type="submit">Security & Updates</button></form></body></html>)=====";
|
|
|
|
|
|
// Autogenerated from wled00/data/settings_wifi.htm, do not edit!!
|
|
const char PAGE_settings_wifi[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta
|
|
name="viewport" content="width=500"><title>WiFi Settings</title><script>
|
|
function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#wifi-settings")}function B(){window.open("/settings","_self")}function GetV() {var d=document;
|
|
%CSS%%SCSS%</head><body onload="GetV()">
|
|
<form id="form_s" name="Sf" method="post"><div class="helpB"><button
|
|
type="button" onclick="H()">?</button></div><button type="button" onclick="B()">
|
|
Back</button><button type="submit">Save & Connect</button><hr><h2>WiFi setup
|
|
</h2><h3>Connect to existing network</h3>
|
|
Network name (SSID, empty to not connect):<br><input name="CS" maxlength="32">
|
|
<br>Network password:<br><input type="password" name="CP" maxlength="63"><br>
|
|
Static IP (leave at 0.0.0.0 for DHCP):<br><input name="I0" type="number"
|
|
class="s" min="0" max="255" required> . <input name="I1" type="number"
|
|
class="s" min="0" max="255" required> . <input name="I2" type="number"
|
|
class="s" min="0" max="255" required> . <input name="I3" type="number"
|
|
class="s" min="0" max="255" required><br>Static gateway:<br><input name="G0"
|
|
type="number" class="s" min="0" max="255" required> . <input name="G1"
|
|
type="number" class="s" min="0" max="255" required> . <input name="G2"
|
|
type="number" class="s" min="0" max="255" required> . <input name="G3"
|
|
type="number" class="s" min="0" max="255" required><br>Static subnet mask:<br>
|
|
<input name="S0" type="number" class="s" min="0" max="255" required> . <input
|
|
name="S1" type="number" class="s" min="0" max="255" required> . <input
|
|
name="S2" type="number" class="s" min="0" max="255" required> . <input
|
|
name="S3" type="number" class="s" min="0" max="255" required><br>
|
|
mDNS address (leave empty for no mDNS):<br>http:// <input name="CM"
|
|
maxlength="32"> .local<br>Client IP: <span class="sip">Not connected</span><br>
|
|
<h3>Configure Access Point</h3>AP SSID (leave empty for no AP):<br><input
|
|
name="AS" maxlength="32"><br>Hide AP name: <input type="checkbox" name="AH"><br>
|
|
AP password (leave empty for open):<br><input type="password" name="AP"
|
|
maxlength="63" pattern="(.{8,63})|()" title="Empty or min. 8 characters"><br>
|
|
Access Point WiFi channel: <input name="AC" type="number" class="xs" min="1"
|
|
max="13" required><br>AP opens: <select name="AB"><option value="0">
|
|
No connection after boot</option><option value="1">Disconnected</option><option
|
|
value="2">Always</option><option value="3">Never (not recommended)</option>
|
|
</select><br>AP IP: <span class="sip">Not active</span><br><h3>Experimental</h3>
|
|
Disable WiFi sleep: <input type="checkbox" name="WS"><br><i>
|
|
Can help with connectivity issues.<br>
|
|
Do not enable if WiFi is working correctly, increases power consumption.</i><div
|
|
id="ethd"><h3>Ethernet Type</h3><select name="ETH"><option value="0">None
|
|
</option><option value="2">ESP32-POE</option><option value="6">ESP32Deux
|
|
</option><option value="4">QuinLED-ESP32</option><option value="5">
|
|
TwilightLord-ESP32</option><option value="3">WESP32</option><option value="1">
|
|
WT32-ETH01</option></select><br><br></div><hr><button type="button"
|
|
onclick="B()">Back</button><button type="submit">Save & Connect</button></form>
|
|
</body></html>)=====";
|
|
|
|
|
|
// Autogenerated from wled00/data/settings_leds.htm, do not edit!!
|
|
const char PAGE_settings_leds[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta
|
|
name="viewport" content="width=500"><title>LED Settings</title><script>
|
|
var timeout,d=document,laprev=55,maxB=1,maxM=4e3,maxPB=4096,maxL=1333,maxLbquot=0,customStarts=!1,startsDirty=[],maxCOOverrides=5;function H(){window.open("https://kno.wled.ge/features/settings/#led-settings")}function B(){window.open("/settings","_self")}function gId(e){return d.getElementById(e)}function off(e){d.getElementsByName(e)[0].value=-1}function showToast(e,n=!1){var t=gId("toast");t.innerHTML=e,t.className=n?"error":"show",clearTimeout(timeout),t.style.animation="none",timeout=setTimeout((function(){t.className=t.className.replace("show","")}),2900)}function bLimits(e,n,t,a){maxB=e,maxM=t,maxPB=n,maxL=a}function pinsOK(){var e=d.getElementsByTagName("input");for(i=0;i<e.length;i++){var n=e[i].name.substring(0,2);if("L0"==n||"L1"==n||"L2"==n||"L3"==n){var t=e[i].name.substring(2);if(parseInt(d.getElementsByName("LT"+t)[0].value,10)>=80)continue}if(("L0"==n||"L1"==n||"L2"==n||"L3"==n||"L4"==n||"RL"==n||"BT"==n||"IR"==n)&&""!=e[i].value&&"-1"!=e[i].value){if(d.um_p&&d.um_p.some(n=>n==parseInt(e[i].value,10)))return alert(`Sorry, pins ${JSON.stringify(d.um_p)} can't be used.`),e[i].value="",e[i].focus(),!1;if(e[i].value>5&&e[i].value<12)return alert("Sorry, pins 6-11 can not be used."),e[i].value="",e[i].focus(),!1;if("IR"!=n&&"BT"!=n&&e[i].value>33)return alert("Sorry, pins >33 are input only."),e[i].value="",e[i].focus(),!1;for(j=i+1;j<e.length;j++){var a=e[j].name.substring(0,2);if("L0"==a||"L1"==a||"L2"==a||"L3"==a||"L4"==a||"RL"==a||"BT"==a||"IR"==a){if("L"===a.substring(0,1)){var s=e[j].name.substring(2);if(parseInt(d.getElementsByName("LT"+s)[0].value,10)>=80)continue}if(""!=e[j].value&&e[i].value==e[j].value)return alert(`Pin conflict between ${e[i].name}/${e[j].name}!`),e[j].value="",e[j].focus(),!1}}}}return!0}function trySubmit(e){if(d.Sf.data.value="",e.preventDefault(),!pinsOK())return e.stopPropagation(),!1;if(bquot>100){var n="Too many LEDs for me to handle!";maxM<1e4&&(n+="\n\rConsider using an ESP32."),alert(n)}d.Sf.checkValidity()&&d.Sf.submit()}function S(){GetV(),checkSi(),setABL()}function enABL(){var e=gId("able").checked;d.Sf.LA.value=e?laprev:0,gId("abl").style.display=e?"inline":"none",gId("psu2").style.display=e?"inline":"none",d.Sf.LA.value>0&&setABL()}function enLA(){var e=d.Sf.LAsel.value;d.Sf.LA.value=e,gId("LAdis").style.display=50==e?"inline":"none",UI()}function setABL(){switch(gId("able").checked=!0,d.Sf.LAsel.value=50,parseInt(d.Sf.LA.value)){case 0:gId("able").checked=!1,enABL();break;case 30:d.Sf.LAsel.value=30;break;case 35:d.Sf.LAsel.value=35;break;case 55:d.Sf.LAsel.value=55;break;case 255:d.Sf.LAsel.value=255;break;default:gId("LAdis").style.display="inline"}gId("m1").innerHTML=maxM,d.getElementsByName("Sf")[0].addEventListener("submit",trySubmit),UI()}function getMem(e,n,t){return e<32?maxM<1e4&&3==t?e>29?20*n:15*n:maxM>=1e4?e>29?8*n:6*n:e>29?4*n:3*n:e>31&&e<48?5:44==e||45==e?4*n:3*n}function UI(e=!1){var n=!1,t=0;gId("ampwarning").style.display=d.Sf.MA.value>7200?"inline":"none",255==d.Sf.LA.value?laprev=12:d.Sf.LA.value>0&&(laprev=d.Sf.LA.value);var a=d.getElementsByTagName("select");for(i=0;i<a.length;i++)if("LT"==a[i].name.substring(0,2)){var s=a[i].name.substring(2),l=parseInt(a[i].value,10);gId("p0d"+s).innerHTML=l>=80&&l<96?"IP address:":l>49?"Data GPIO:":l>41?"GPIOs:":"GPIO:",gId("p1d"+s).innerHTML=l>49&&l<64?"Clk GPIO:":"";var o=d.getElementsByName("L1"+s)[0];for(t+=getMem(l,d.getElementsByName("LC"+s)[0].value,d.getElementsByName("L0"+s)[0].value),f=1;f<5;f++){(o=d.getElementsByName("L"+f+s)[0])&&(l>=80&&l<96&&f<4||l>49&&1==f||l>41&&l<50&&f+40<l?(o.style.display="inline",o.required=!0):(o.style.display="none",o.required=!1,o.value=""))}e&&(gId("rf"+s).checked=gId("rf"+s).checked||31==l,l>31&&l<48&&(d.getElementsByName("LC"+s)[0].value=1)),gId("rf"+s).onclick=31==l?function(){return!1}:function(){},n|=30==l||31==l||l>40&&l<46&&43!=l,gId("co"+s).style.display=l>=80&&l<96||41==l||42==l?"none":"inline",gId("dig"+s+"c").style.display=l>40&&l<48?"none":"inline",gId("dig"+s+"r").style.display=l>=80&&l<96?"none":"inline",gId("dig"+s+"s").style.display=l>=80&&l<96||l>40&&l<48?"none":"inline",gId("dig"+s+"f").style.display=l>=16&&l<32||l>=50&&l<64?"inline":"none",gId("rev"+s).innerHTML=l>40&&l<48?"Inverted output":"Reversed (rotated 180°)",gId("psd"+s).innerHTML=l>40&&l<48?"Index:":"Start:"}var r=d.querySelectorAll(".wc"),u=r.length;for(i=0;i<u;i++)r[i].style.display=n?"inline":"none";var p=d.getElementsByTagName("input"),m=0,v=0,c=0;for(i=0;i<p.length;i++){var g=p[i].name.substring(0,2);s=p[i].name.substring(2);if("LC"!=g){if("L0"==g||"L1"==g)d.getElementsByName("LC"+s)[0].max=maxPB;if("L0"==g||"L1"==g||"L2"==g||"L3"==g){if((l=parseInt(d.getElementsByName("LT"+s)[0].value))>=80){p[i].max=255,p[i].min=0,p[i].style.color="#fff";continue}p[i].max=33,p[i].min=-1}if(("L0"==g||"L1"==g||"L2"==g||"L3"==g||"L4"==g||"RL"==g||"BT"==g||"IR"==g)&&""!=p[i].value&&"-1"!=p[i].value){var f=[];if(d.um_p&&Array.isArray(d.um_p))for(k=0;k<d.um_p.length;k++)f.push(d.um_p[k]);for(j=0;j<p.length;j++)if(i!=j){var y=p[j].name.substring(0,2);if("L0"==y||"L1"==y||"L2"==y||"L3"==y||"L4"==y||"RL"==y||"BT"==y||"IR"==y){if("L"===y.substring(0,1)){var L=p[j].name.substring(2);if(parseInt(d.getElementsByName("LT"+L)[0].value,10)>=80)continue}""!=p[j].value&&"-1"!=p[j].value&&f.push(parseInt(p[j].value,10))}}f.some(e=>e==parseInt(p[i].value,10))?p[i].style.color="red":p[i].style.color=parseInt(p[i].value,10)>33?"orange":"#fff"}}else{var I=parseInt(p[i].value,10);customStarts&&startsDirty[s]||(gId("ls"+s).value=m),gId("ls"+s).disabled=!customStarts,I&&((a=parseInt(gId("ls"+s).value))+I>m&&(m=a+I),I>c&&(c=I),(l=parseInt(d.getElementsByName("LT"+s)[0].value))<80&&(v+=I))}}gId("lc").textContent=m,gId("pc").textContent=m==v?"":"("+v+" physical)",gId("m0").innerHTML=t,bquot=t/maxM*100,gId("dbar").style.background=`linear-gradient(90deg, ${bquot>60?bquot>90?"red":"orange":"#ccc"} 0 ${bquot}%%, #444 ${bquot}%% 100%%)`,gId("ledwarning").style.display=c>Math.min(maxPB,800)||bquot>80?"inline":"none",gId("ledwarning").style.color=c>Math.max(maxPB,800)||bquot>100?"red":"orange",gId("wreason").innerHTML=bquot>80?"80% of max. LED memory"+(bquot>100?` (<b>ERROR: Using over ${maxM}B!</b>)`:""):"800 LEDs per output";var h=Math.ceil((100+v*laprev)/500)/2;h=h>5?Math.ceil(h):h;a="";var B=30==d.Sf.LAsel.value,b=255==d.Sf.LAsel.value;h<1.02&&!B&&!b?a="ESP 5V pin with 1A USB supply":(a+=B?"12V ":b?"WS2815 12V ":"5V ",a+=h,a+="A supply connected to LEDs");var x=Math.ceil((100+v*laprev)/1500)/2,S="(for most effects, ~";S+=x=x>5?Math.ceil(x):x,S+="A is enough)<br>",gId("psu").innerHTML=a,gId("psu2").innerHTML=b?"":S,gId("json").style.display=8==d.Sf.IT.value?"":"none"}function lastEnd(e){if(e<1)return 0;v=parseInt(d.getElementsByName("LS"+(e-1))[0].value)+parseInt(d.getElementsByName("LC"+(e-1))[0].value);var n=parseInt(d.getElementsByName("LT"+(e-1))[0].value);return n>31&&n<48&&(v=1),isNaN(v)?0:v}function addLEDs(e,n=!0){var t=d.getElementsByClassName("iST"),a=t.length;if(!(1==e&&a>=maxB||-1==e&&0==a)){var i=gId("mLC");if(1==e){var s=`<div class="iST">\n<hr style="width:260px">\n${a+1}:\n<select name="LT${a}" onchange="UI(true)">\n<option value="22" selected>WS281x</option>\n<option value="30">SK6812 RGBW</option>\n<option value="31">TM1814</option>\n<option value="24">400kHz</option>\n<option value="50">WS2801</option>\n<option value="51">APA102</option>\n<option value="52">LPD8806</option>\n<option value="53">P9813</option>\n<option value="41">PWM White</option>\n<option value="42">PWM CCT</option>\n<option value="43">PWM RGB</option>\n<option value="44">PWM RGBW</option>\n<option value="45">PWM RGB+CCT</option>\n\x3c!--option value="46">PWM RGB+DCCT</option--\x3e\n<option value="80">DDP RGB (network)</option>\n\x3c!--option value="81">E1.31 RGB (network)</option--\x3e\n\x3c!--option value="82">ArtNet RGB (network)</option--\x3e\n</select> \n<div id="co${a}" style="display:inline">Color Order:\n<select name="CO${a}">\n<option value="0">GRB</option>\n<option value="1">RGB</option>\n<option value="2">BRG</option>\n<option value="3">RBG</option>\n<option value="4">BGR</option>\n<option value="5">GBR</option>\n</select></div>\n<br>\n<span id="psd${a}">Start:</span> <input type="number" name="LS${a}" id="ls${a}" class="l starts" min="0" max="8191" value="${lastEnd(a)}" oninput="startsDirty[${a}]=true;UI();" required /> \n<div id="dig${a}c" style="display:inline">Length: <input type="number" name="LC${a}" class="l" min="1" max="${maxPB}" value="1" required oninput="UI()" /></div>\n<br>\n<span id="p0d${a}">GPIO:</span> <input type="number" name="L0${a}" min="0" max="33" required class="xs" onchange="UI()"/>\n<span id="p1d${a}"></span><input type="number" name="L1${a}" min="0" max="33" class="xs" onchange="UI()"/>\n<span id="p2d${a}"></span><input type="number" name="L2${a}" min="0" max="33" class="xs" onchange="UI()"/>\n<span id="p3d${a}"></span><input type="number" name="L3${a}" min="0" max="33" class="xs" onchange="UI()"/>\n<span id="p4d${a}"></span><input type="number" name="L4${a}" min="0" max="33" class="xs" onchange="UI()"/>\n<div id="dig${a}r" style="display:inline"><br><span id="rev${a}">Reversed</span>: <input type="checkbox" name="CV${a}"></div>\n<div id="dig${a}s" style="display:inline"><br>Skip 1<sup>st</sup> LED: <input id="sl${a}" type="checkbox" name="SL${a}"></div>\n<div id="dig${a}f" style="display:inline"><br>Off Refresh: <input id="rf${a}" type="checkbox" name="RF${a}"></div>\n</div>`;i.insertAdjacentHTML("beforeend",s)}-1==e&&(t[--a].remove(),--a),gId("+").style.display=a<maxB-1?"inline":"none",gId("-").style.display=a>0?"inline":"none",n||UI()}}function addCOM(e=0,n=1,t=0){var a=d.getElementsByClassName("com_entry").length;if(!(a>=10)){var i=`<div class="com_entry">\n<hr style="width:260px">\n${a+1}: Start: <input type="number" name="XS${a}" id="xs${a}" class="l starts" min="0" max="65535" value="${e}" oninput="UI();" required=""> \nLength: <input type="number" name="XC${a}" id="xc${a}" class="l" min="1" max="65535" value="${n}" required="" oninput="UI()">\n<div style="display:inline">Color Order:\n<select id="xo${a}" name="XO${a}">\n<option value="0">GRB</option>\n<option value="1">RGB</option>\n<option value="2">BRG</option>\n<option value="3">RBG</option>\n<option value="4">BGR</option>\n<option value="5">GBR</option>\n</select>\n</div><br></div>`;gId("com_entries").insertAdjacentHTML("beforeend",i),gId("xo"+a).value=t,btnCOM(a+1)}}function remCOM(){var e=d.getElementsByClassName("com_entry"),n=e.length;0!==n&&(e[n-1].remove(),btnCOM(n-1))}function resetCOM(e){e&&(maxCOOverrides=e);for(let e of d.getElementsByClassName("com_entry"))e.remove();btnCOM(0)}function btnCOM(e){gId("com_add").style.display=e<maxCOOverrides?"inline":"none",gId("com_rem").style.display=e>0?"inline":"none"}function addBtn(e,n,t){var a=gId("btns").innerHTML,i="BT"+String.fromCharCode((e<10?48:55)+e);a+=`Button ${e} GPIO: <input type="number" min="-1" max="40" name="${i}" onchange="UI()" class="xs" value="${n}">`,a+=` <select name="${"BE"+String.fromCharCode((e<10?48:55)+e)}">`,a+=`<option value="0" ${0==t?"selected":""}>Disabled</option>`,a+=`<option value="2" ${2==t?"selected":""}>Pushbutton</option>`,a+=`<option value="3" ${3==t?"selected":""}>Push inverted</option>`,a+=`<option value="4" ${4==t?"selected":""}>Switch</option>`,a+=`<option value="5" ${5==t?"selected":""}>PIR sensor</option>`,a+=`<option value="6" ${6==t?"selected":""}>Touch</option>`,a+=`<option value="7" ${7==t?"selected":""}>Analog</option>`,a+=`<option value="8" ${8==t?"selected":""}>Analog inverted</option>`,a+="</select>",a+=`<span style="cursor: pointer;" onclick="off('${i}')"> ×</span><br>`,gId("btns").innerHTML=a}function tglSi(e){(customStarts=e)||(startsDirty=[]),UI()}function checkSi(){for(var e=!1,n=1;n<d.getElementsByClassName("iST").length;n++){parseInt(gId("ls"+(n-1)).value)+parseInt(d.getElementsByName("LC"+(n-1))[0].value)!=parseInt(gId("ls"+n).value)&&(e=!0,startsDirty[n]=!0)}0!=parseInt(gId("ls0").value)&&(e=!0,startsDirty[0]=!0),gId("si").checked=e,tglSi(e)}function uploadFile(e){var n=new XMLHttpRequest;n.addEventListener("load",(function(){showToast(this.responseText,this.status>=400)})),n.addEventListener("error",(function(e){showToast(e.stack,!0)})),n.open("POST","/upload");var t=new FormData;return t.append("data",d.Sf.data.files[0],e),n.send(t),d.Sf.data.value="",!1}function loadCfg(e){var n,t;"function"==typeof window.FileReader?(e.files?e.files[0]?(n=e.files[0],(t=new FileReader).onload=function(e){let n=e.target.result;var t=JSON.parse(n);if(t.hw){if(t.hw.led){for(var a=0;a<10;a++)addLEDs(-1);t.hw.led.ins.forEach((e,n,t)=>{addLEDs(1);for(var a=0;a<e.pin.length;a++)d.getElementsByName(`L${a}${n}`)[0].value=e.pin[a];d.getElementsByName("LT"+n)[0].value=e.type,d.getElementsByName("LS"+n)[0].value=e.start,d.getElementsByName("LC"+n)[0].value=e.len,d.getElementsByName("CO"+n)[0].value=e.order,d.getElementsByName("SL"+n)[0].checked=e.skip,d.getElementsByName("RF"+n)[0].checked=e.ref,d.getElementsByName("CV"+n)[0].checked=e.rev})}if(t.hw.com&&(resetCOM(),t.hw.com.forEach(e=>{addCOM(e.start,e.len,e.order)})),t.hw.btn){var i=t.hw.btn;Array.isArray(i.ins)&&(gId("btns").innerHTML=""),i.ins.forEach((e,n,t)=>{addBtn(n,e.pin[0],e.type)}),d.getElementsByName("TT")[0].value=i.tt}t.hw.ir&&(d.getElementsByName("IR")[0].value=t.hw.ir.pin,d.getElementsByName("IT")[0].value=t.hw.ir.type),t.hw.relay&&(d.getElementsByName("RL")[0].value=t.hw.relay.pin,d.getElementsByName("RM")[0].checked=t.hw.relay.inv),UI()}},t.readAsText(n)):alert("Please select a JSON file first!"):alert("This browser doesn't support the `files` property of file inputs."),e.value=""):alert("The file API isn't supported on this browser yet.")}function GetV() {var d=document;
|
|
%CSS%%SCSS%</head><body onload="S()"><form
|
|
id="form_s" name="Sf" method="post"><div class="helpB"><button type="button"
|
|
onclick="H()">?</button></div><button type="button" onclick="B()">Back</button>
|
|
<button type="submit">Save</button><hr><h2>LED & Hardware setup</h2>
|
|
Total LEDs: <span id="lc">?</span> <span id="pc"></span><br><i>
|
|
Recommended power supply for brightest white:</i><br><b><span id="psu">?</span>
|
|
</b><br><span id="psu2"><br></span><br>Enable automatic brightness limiter:
|
|
<input type="checkbox" name="ABen" onchange="enABL()" id="able"><br><div
|
|
id="abl">Maximum Current: <input name="MA" type="number" class="l" min="250"
|
|
max="65000" oninput="UI()" required> mA<br><div id="ampwarning"
|
|
style="color:orange;display:none">
|
|
⚠ Your power supply provides high current.<br>
|
|
To improve the safety of your setup,<br>please use thick cables,<br>
|
|
multiple power injection points and a fuse!<br></div><i>
|
|
Automatically limits brightness to stay close to the limit.<br>
|
|
Keep at <1A if powering LEDs directly from the ESP 5V pin!<br>
|
|
If you are using an external power supply, enter its rating.<br>
|
|
(Current estimated usage: <span class="pow">unknown</span>)</i><br><br>
|
|
LED voltage (Max. current for a single LED):<br><select name="LAsel"
|
|
onchange="enLA()"><option value="55" selected="selected">5V default (55mA)
|
|
</option><option value="35">5V efficient (35mA)</option><option value="30">
|
|
12V (30mA)</option><option value="255">WS2815 (12mA)</option><option value="50">
|
|
Custom</option></select><br><span id="LAdis" style="display:none">
|
|
Custom max. current per LED: <input name="LA" type="number" min="0" max="255"
|
|
id="la" oninput="UI()" required> mA<br></span><i>
|
|
Keep at default if you are unsure about your type of LEDs.</i><br></div><h3>
|
|
Hardware setup</h3><div id="mLC">LED outputs:</div><hr style="width:260px">
|
|
<button type="button" id="+" onclick="addLEDs(1,!1)"
|
|
style="display:none;border-radius:20px;height:36px">+</button> <button
|
|
type="button" id="-" onclick="addLEDs(-1,!1)"
|
|
style="display:none;border-radius:20px;width:36px;height:36px">-</button><br>
|
|
LED Memory Usage: <span id="m0">0</span> / <span id="m1">?</span> B<br><div
|
|
id="dbar"
|
|
style="display:inline-block;width:100px;height:10px;border-radius:20px"></div>
|
|
<br><div id="ledwarning" style="color:orange;display:none">
|
|
⚠ You might run into stability or lag issues.<br>Use less than <span
|
|
id="wreason">800 LEDs per output</span> for the best experience!<br></div><hr
|
|
style="width:260px">Make a segment for each output: <input type="checkbox"
|
|
name="MS"><br>Custom bus start indices: <input type="checkbox"
|
|
onchange="tglSi(this.checked)" id="si"><br><hr style="width:260px"><div
|
|
id="color_order_mapping">Color Order Override:<div id="com_entries"></div><hr
|
|
style="width:260px"><button type="button" id="com_add" onclick="addCOM(),UI()"
|
|
style="display:none;border-radius:20px;height:36px">+</button> <button
|
|
type="button" id="com_rem" onclick="remCOM(),UI()"
|
|
style="display:none;border-radius:20px;width:36px;height:36px">-</button><br>
|
|
</div><hr style="width:260px"><div id="btns"></div>Touch threshold: <input
|
|
type="number" class="s" min="0" max="100" name="TT" required><br>IR GPIO: <input
|
|
type="number" min="-1" max="40" name="IR" onchange="UI()" class="xs"><select
|
|
name="IT" onchange="UI()"><option value="0">Remote disabled</option><option
|
|
value="1">24-key RGB</option><option value="2">24-key with CT</option><option
|
|
value="3">40-key blue</option><option value="4">44-key RGB</option><option
|
|
value="5">21-key RGB</option><option value="6">6-key black</option><option
|
|
value="7">9-key red</option><option value="8">JSON remote</option></select><span
|
|
style="cursor:pointer" onclick='off("IR")'> ×</span><br><div
|
|
id="json" style="display:none">JSON file: <input type="file" name="data"
|
|
accept=".json"> <input type="button" value="Upload"
|
|
onclick='uploadFile("/ir.json")'><br></div><div id="toast"></div><a
|
|
href="https://kno.wled.ge/interfaces/infrared/" target="_blank">IR info</a><br>
|
|
Relay GPIO: <input type="number" min="-1" max="33" name="RL" onchange="UI()"
|
|
class="xs"> Invert <input type="checkbox" name="RM"><span
|
|
style="cursor:pointer" onclick='off("RL")'> ×</span><br><hr
|
|
style="width:260px"><h3>Defaults</h3>Turn LEDs on after power up/reset: <input
|
|
type="checkbox" name="BO"><br>Default brightness: <input name="CA"
|
|
type="number" class="s" min="0" max="255" required> (0-255)<br><br>Apply preset
|
|
<input name="BP" type="number" class="s" min="0" max="250" required>
|
|
at boot (0 uses defaults)<br><br>Use Gamma correction for color: <input
|
|
type="checkbox" name="GC"> (strongly recommended)<br>
|
|
Use Gamma correction for brightness: <input type="checkbox" name="GB">
|
|
(not recommended)<br><br>Brightness factor: <input name="BF" type="number"
|
|
class="s" min="1" max="255" required> %%<h3>Transitions</h3>Crossfade: <input
|
|
type="checkbox" name="TF"><br>Transition Time: <input name="TD" type="number"
|
|
class="l" min="0" max="65500"> ms<br>Enable Palette transitions: <input
|
|
type="checkbox" name="PF"><h3>Timed light</h3>Default Duration: <input
|
|
name="TL" type="number" class="s" min="1" max="255" required> min<br>
|
|
Default Target brightness: <input name="TB" type="number" class="s" min="0"
|
|
max="255" required><br>Mode: <select name="TW"><option value="0">Wait and set
|
|
</option><option value="1">Fade</option><option value="2">Fade Color</option>
|
|
<option value="3">Sunrise</option></select><h3>White management</h3>
|
|
White Balance correction: <input type="checkbox" name="CCT"><br><span
|
|
class="wc">Auto-calculate white channel from RGB:<br><select name="AW"><option
|
|
value="0">None</option><option value="1">Brighter</option><option value="2">
|
|
Accurate</option><option value="3">Dual</option></select><br>
|
|
Calculate CCT from RGB: <input type="checkbox" name="CR"><br>
|
|
CCT additive blending: <input type="number" class="s" min="0" max="100"
|
|
name="CB" required> %%</span><h3>Advanced</h3>Palette blending: <select
|
|
name="PB"><option value="0">Linear (wrap if moving)</option><option value="1">
|
|
Linear (always wrap)</option><option value="2">Linear (never wrap)</option>
|
|
<option value="3">None (not recommended)</option></select><br>
|
|
Target refresh rate: <input type="number" class="s" min="1" max="120" name="FR"
|
|
required> FPS<hr style="width:260px"><div id="cfg">Config template: <input
|
|
type="file" name="data2" accept=".json"> <input type="button" value="Apply"
|
|
onclick="loadCfg(d.Sf.data2)"><br></div><hr><button type="button" onclick="B()">
|
|
Back</button><button type="submit">Save</button></form></body></html>)=====";
|
|
|
|
|
|
#ifdef WLED_ENABLE_DMX
|
|
|
|
// Autogenerated from wled00/data/settings_dmx.htm, do not edit!!
|
|
const char PAGE_settings_dmx[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
|
|
<meta charset="utf-8"><title>DMX Settings</title><script>
|
|
function GCH(n){for(d=document,d.getElementById("dmxchannels").innerHTML+="",i=0;i<n;i++)d.getElementById("dmxchannels").innerHTML+="<span id=CH"+(i+1)+"s >Channel "+(i+1)+": <select name=CH"+(i+1)+' id="CH'+(i+1)+'"><option value=0>Set to 0</option><option value=1>Red</option><option value=2>Green</option><option value=3>Blue</option><option value=4>White</option><option value=5>Shutter (Brightness)</option><option value=6>Set to 255</option></select></span><br />\n'}function mMap(){for(d=document,numCh=document.Sf.CN.value,numGap=document.Sf.CG.value,parseInt(numCh)>parseInt(numGap)?d.getElementById("gapwarning").style.display="block":d.getElementById("gapwarning").style.display="none",i=0;i<15;i++)i>=numCh?(d.getElementById("CH"+(i+1)+"s").style.opacity="0.5",d.getElementById("CH"+(i+1)).disabled=!0):(d.getElementById("CH"+(i+1)+"s").style.opacity="1",d.getElementById("CH"+(i+1)).disabled=!1)}function S(){GCH(15),GetV(),mMap()}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/DMX")}function B(){window.history.back()}function GetV() {var d=document;
|
|
%CSS%%SCSS%</head><body onload="S()"><form
|
|
id="form_s" name="Sf" method="post"><div class="helpB"><button type="button"
|
|
onclick="H()">?</button></div><button type="button" onclick="B()">Back</button>
|
|
<button type="submit">Save</button><hr><h2>
|
|
Imma firin ma lazer (if it has DMX support)</h2>Proxy Universe <input name="PU"
|
|
type="number" min="0" max="63999" required> from E1.31 to DMX (0=disabled)<br>
|
|
<i>This will disable the LED data output to DMX configurable below</i><br><br>
|
|
<i>Number of fixtures is taken from LED config page</i><br>
|
|
Channels per fixture (15 max): <input type="number" min="1" max="15" name="CN"
|
|
maxlength="2" onchange="mMap()"><br>Start channel: <input type="number" min="1"
|
|
max="512" name="CS" maxlength="2"><br>Spacing between start channels: <input
|
|
type="number" min="1" max="512" name="CG" maxlength="2" onchange="mMap()"> [ <a
|
|
href="javascript:alert('if set to 10, first fixture will start at 10,\nsecond will start at 20 etc.\nRegardless of the channel count.\nMakes memorizing channel numbers easier.');">
|
|
info</a> ]<br><div id="gapwarning" style="color:orange;display:none">
|
|
WARNING: Channel gap is lower than channels per fixture.<br>
|
|
This will cause overlap.</div><button type="button"
|
|
onclick='location.href="/dmxmap"'>DMX Map</button><br>DMX fixtures start LED:
|
|
<input type="number" min="0" max="1500" name="SL"><h3>Channel functions</h3><div
|
|
id="dmxchannels"></div><hr><button type="button" onclick="B()">Back</button>
|
|
<button type="submit">Save</button></form></body></html>)=====";
|
|
|
|
|
|
#else
|
|
const char PAGE_settings_dmx[] PROGMEM = R"=====()=====";
|
|
#endif
|
|
|
|
// Autogenerated from wled00/data/settings_ui.htm, do not edit!!
|
|
const char PAGE_settings_ui[] PROGMEM = R"=====(<!DOCTYPE html><html><head lang="en"><meta charset="utf-8"><meta
|
|
name="viewport" content="width=500"><title>UI Settings</title><script>
|
|
var initial_ds,initial_st,timeout,d=document,sett=null,l={comp:{labels:"Show button labels",colors:{LABEL:"Color selection methods",picker:"Color Wheel",rgb:"RGB sliders",quick:"Quick color selectors",hex:"HEX color input"},pcmbot:"Show bottom tab bar in PC mode",pid:"Show preset IDs",seglen:"Set segment length instead of stop LED",css:"Enable custom CSS",hdays:"Enable custom Holidays list"},theme:{alpha:{bg:"Background opacity",tab:"Button opacity"},bg:{url:"BG image URL",random:"Random BG image"},color:{bg:"BG HEX color"}}};function gId(e){return d.getElementById(e)}function isObject(e){return e&&"object"==typeof e&&!Array.isArray(e)}function set(e,t,i){for(var n=t,s=e.split("_"),o=s.length,a=0;a<o-1;a++){var l=s[a];n[l]||(n[l]={}),n=n[l]}n[s[o-1]]=i}function showToast(e,t=!1){var i=gId("toast");i.innerHTML=e,i.className=t?"error":"show",clearTimeout(timeout),i.style.animation="none",timeout=setTimeout((function(){i.className=i.className.replace("show","")}),2900)}function addRec(e,t="",n=null){var s="";for(i in e){var o=t+(t?"_":"")+i;if(isObject(e[i]))n&&n[i]&&n[i].LABEL&&(s+=`<h3>${n[i].LABEL}</h3>`),s+=addRec(e[i],o,n?n[i]:null);else{var a=o;if(n&&n[i]?a=n[i]:e[i+"LABEL"]&&(a=e[i+"LABEL"]),i.indexOf("LABEL")>0)continue;var l=typeof e[i];gId(o)?("boolean"===l?gId(o).checked=e[i]:gId(o).value=e[i],gId(o).previousElementSibling.matches(".l")&&(gId(o).previousElementSibling.innerHTML=a)):"boolean"===l?s+=`${a}: <input class="agi cb" type="checkbox" id=${o} ${e[i]?"checked":""}><br>`:"number"===l?s+=`${a}: <input class="agi" type="number" id=${o} value=${e[i]}><br>`:"string"===l&&(s+=`${a}:<br><input class="agi" id=${o} value=${e[i]}><br>`)}}return s}function genForm(e){var t;t=addRec(e,"",l),gId("gen").innerHTML=t}function GetLS(){(sett=localStorage.getItem("wledUiCfg"))||(gId("lserr").style.display="inline");try{sett=JSON.parse(sett)}catch(e){sett={},gId("lserr").style.display="inline",gId("lserr").innerHTML="⚠ Settings JSON parsing failed. ("+e+")"}genForm(sett),gId("dm").checked="light"===gId("theme_base").value}function SetLS(){for(var e=d.querySelectorAll(".agi"),t=0;t<e.length;t++){var i=e[t],n=i.classList.contains("cb")?i.checked:i.value;set(i.id,sett,n),console.log(`${i.id} set to ${n}`)}try{localStorage.setItem("wledUiCfg",JSON.stringify(sett)),gId("lssuc").style.display="inline"}catch(i){gId("lssuc").style.display="none",gId("lserr").style.display="inline",gId("lserr").innerHTML="⚠ Settings JSON saving failed. ("+i+")"}}function Save(){SetLS(),d.Sf.DS.value==initial_ds&&d.Sf.ST.checked==initial_st||d.Sf.submit()}function S(){GetV(),initial_ds=d.Sf.DS.value,initial_st=d.Sf.ST.checked,GetLS()}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#user-interface-settings")}function B(){window.open("/settings","_self")}function UI(){gId("idonthateyou").style.display=gId("dm").checked?"inline":"none";var e=gId("theme_base");e&&(e.value=gId("dm").checked?"light":"dark")}function setRandomBg(){gId("theme_bg_random").checked?gId("theme_bg_url").value="https://picsum.photos/1920/1080":gId("theme_bg_url").value=""}function checkRandomBg(){"https://picsum.photos/1920/1080"===gId("theme_bg_url").value?gId("theme_bg_random").checked=!0:gId("theme_bg_random").checked=!1}function uploadFile(e,t){var i=new XMLHttpRequest;i.addEventListener("load",(function(){showToast(this.responseText,this.status>=400)})),i.addEventListener("error",(function(e){showToast(e.stack,!0)})),i.open("POST","/upload");var n=new FormData;return n.append("data",e.files[0],t),i.send(n),e.value="",!1}function GetV() {var d=document;
|
|
%CSS%%SCSS%</head><body onload="S()"><form
|
|
id="form_s" name="Sf" method="post"><div
|
|
style="position:sticky;top:0;background-color:#222;z-index:1"><div
|
|
class="helpB"><button type="button" onclick="H()">?</button></div><button
|
|
type="button" onclick="B()">Back</button><button type="button" onclick="Save()">
|
|
Save</button><br><span id="lssuc" style="color:green;display:none">
|
|
✔ Local UI settings saved!</span> <span id="lserr"
|
|
style="color:red;display:none">
|
|
⚠ Could not access local storage. Make sure it is enabled in your browser.
|
|
</span><hr></div><h2>Web Setup</h2>Server description: <input name="DS"
|
|
maxlength="32"><br>Sync button toggles both send and receive: <input
|
|
type="checkbox" name="ST"><br><i>
|
|
The following UI customization settings are unique both to the WLED device and this browser.
|
|
<br>
|
|
You will need to set them again if using a different browser, device or WLED IP address.
|
|
<br>Refresh the main UI to apply changes.</i><br><div id="gen">
|
|
Loading settings...</div><h3>UI Appearance</h3><span class="l"></span>: <input
|
|
type="checkbox" id="comp_labels" class="agi cb"><br><span class="l"></span>:
|
|
<input type="checkbox" id="comp_pcmbot" class="agi cb"><br><span class="l">
|
|
</span>: <input type="checkbox" id="comp_pid" class="agi cb"><br><span
|
|
class="l"></span>: <input type="checkbox" id="comp_seglen" class="agi cb"><br>
|
|
I hate dark mode: <input type="checkbox" id="dm" onchange="UI()"><br><span
|
|
id="idonthateyou" style="display:none"><i>Why would you? </i>🥺<br>
|
|
</span><span class="l"></span>: <input type="number" min="0.0" max="1.0"
|
|
step="0.01" id="theme_alpha_tab" class="agi"><br><span class="l"></span>: <input
|
|
type="number" min="0.0" max="1.0" step="0.01" id="theme_alpha_bg" class="agi">
|
|
<br><span class="l"></span>: <input id="theme_color_bg" maxlength="9"
|
|
class="agi"><br><span class="l">BG image URL</span>: <input id="theme_bg_url"
|
|
class="agi" oninput="checkRandomBg()"><br><span class="l">Random BG image</span>
|
|
: <input type="checkbox" id="theme_bg_random" class="agi cb"
|
|
onchange="setRandomBg()"><br><input id="theme_base" class="agi"
|
|
style="display:none"> <span class="l"></span>: <input type="checkbox"
|
|
id="comp_css" class="agi cb"><br><div id="skin">Custom CSS: <input type="file"
|
|
name="data" accept=".css"> <input type="button" value="Upload"
|
|
onclick='uploadFile(d.Sf.data,"/skin.css")'><br></div><span class="l"></span>:
|
|
<input type="checkbox" id="comp_hdays" class="agi cb"><br><div id="holidays">
|
|
Holidays: <input type="file" name="data2" accept=".json"> <input type="button"
|
|
value="Upload" onclick='uploadFile(d.Sf.data2,"/holidays.json")'><br></div><div
|
|
id="toast"></div><hr><button type="button" onclick="B()">Back</button><button
|
|
type="button" onclick="Save()">Save</button></form></body></html>)=====";
|
|
|
|
|
|
// Autogenerated from wled00/data/settings_sync.htm, do not edit!!
|
|
const char PAGE_settings_sync[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
|
|
<meta charset="utf-8"><title>Sync Settings</title><script>
|
|
var d=document;function gId(e){return d.getElementById(e)}function H(){window.open("https://kno.wled.ge/interfaces/udp-notifier/")}function B(){window.open("/settings","_self")}function adj(){6454==d.Sf.DI.value?(1==d.Sf.DA.value&&(d.Sf.DA.value=0),1==d.Sf.EU.value&&(d.Sf.EU.value=0)):5568==d.Sf.DI.value&&(0==d.Sf.DA.value&&(d.Sf.DA.value=1),0==d.Sf.EU.value&&(d.Sf.EU.value=1))}function FC(){for(j=0;j<8;j++)gId("G"+(j+1)).checked=gId("GS").value>>j&1,gId("R"+(j+1)).checked=gId("GR").value>>j&1}function GC(){var e=0,d=0,n=1;for(j=0;j<8;j++)e+=gId("G"+(j+1)).checked*n,d+=gId("R"+(j+1)).checked*n,n*=2;gId("GS").value=e,gId("GR").value=d}function SP(){var e=d.Sf.DI.value;gId("xp").style.display=e>0?"none":"block",e>0&&(d.Sf.EP.value=e)}function SetVal(){switch(parseInt(d.Sf.EP.value)){case 5568:d.Sf.DI.value=5568;break;case 6454:d.Sf.DI.value=6454;break;case 4048:d.Sf.DI.value=4048}SP(),FC()}function S(){GetV(),SetVal()}function GetV() {
|
|
%CSS%%SCSS%</head><body onload="S()"><form
|
|
id="form_s" name="Sf" method="post" onsubmit="GC()"><div class="helpB"><button
|
|
type="button" onclick="H()">?</button></div><button type="button" onclick="B()">
|
|
Back</button><button type="submit">Save</button><hr><h2>Sync setup</h2><h3>
|
|
WLED Broadcast</h3>UDP Port: <input name="UP" type="number" min="1" max="65535"
|
|
class="d5" required><br>2nd Port: <input name="U2" type="number" min="1"
|
|
max="65535" class="d5" required><br><br><input name="GS" id="GS" type="number"
|
|
style="display:none"> <input name="GR" id="GR" type="number"
|
|
style="display:none"><table style="margin:0 auto"><tr><td>Sync groups</td><td>1
|
|
</td><td>2</td><td>3</td><td>4</td><td>5</td><td>6</td><td>7</td><td>8</td></tr>
|
|
<tr><td>Send:</td><td><input type="checkbox" id="G1" name="G1"></td><td><input
|
|
type="checkbox" id="G2" name="G2"></td><td><input type="checkbox" id="G3"
|
|
name="G3"></td><td><input type="checkbox" id="G4" name="G4"></td><td><input
|
|
type="checkbox" id="G5" name="G5"></td><td><input type="checkbox" id="G6"
|
|
name="G6"></td><td><input type="checkbox" id="G7" name="G7"></td><td><input
|
|
type="checkbox" id="G8" name="G8"></td></tr><tr><td>Receive:</td><td><input
|
|
type="checkbox" id="R1" name="R1"></td><td><input type="checkbox" id="R2"
|
|
name="R2"></td><td><input type="checkbox" id="R3" name="R3"></td><td><input
|
|
type="checkbox" id="R4" name="R4"></td><td><input type="checkbox" id="R5"
|
|
name="R5"></td><td><input type="checkbox" id="R6" name="R6"></td><td><input
|
|
type="checkbox" id="R7" name="R7"></td><td><input type="checkbox" id="R8"
|
|
name="R8"></td></tr></table><br>Receive: <input type="checkbox" name="RB">
|
|
Brightness, <input type="checkbox" name="RC"> Color, and <input
|
|
type="checkbox" name="RX"> Effects<br><input type="checkbox" name="SO">
|
|
Segment options<br>Send notifications on direct change: <input type="checkbox"
|
|
name="SD"><br>Send notifications on button press or IR: <input type="checkbox"
|
|
name="SB"><br>Send Alexa notifications: <input type="checkbox" name="SA"><br>
|
|
Send Philips Hue change notifications: <input type="checkbox" name="SH"><br>
|
|
Send Macro notifications: <input type="checkbox" name="SM"><br>
|
|
Send notifications twice: <input type="checkbox" name="S2"><br><i>
|
|
Reboot required to apply changes.</i><h3>Instance List</h3>
|
|
Enable instance list: <input type="checkbox" name="NL"><br>
|
|
Make this instance discoverable: <input type="checkbox" name="NB"><h3>Realtime
|
|
</h3>Receive UDP realtime: <input type="checkbox" name="RD"><br><br><i>
|
|
Network DMX input</i><br>Type: <select name="DI" onchange="SP(),adj()"><option
|
|
value="5568">E1.31 (sACN)</option><option value="6454">Art-Net</option><option
|
|
value="0" selected="selected">Custom port</option></select><br><div id="xp">
|
|
Port: <input name="EP" type="number" min="1" max="65535" value="5568"
|
|
class="d5" required><br></div>Multicast: <input type="checkbox" name="EM"><br>
|
|
Start universe: <input name="EU" type="number" min="0" max="63999" required><br>
|
|
<i>Reboot required.</i> Check out <a href="https://github.com/LedFx/LedFx"
|
|
target="_blank">LedFx</a>!<br>Skip out-of-sequence packets: <input
|
|
type="checkbox" name="ES"><br>DMX start address: <input name="DA" type="number"
|
|
min="0" max="510" required><br>DMX mode: <select name="DM"><option value="0">
|
|
Disabled</option><option value="1">Single RGB</option><option value="2">
|
|
Single DRGB</option><option value="3">Effect</option><option value="4">Multi RGB
|
|
</option><option value="5">Dimmer + Multi RGB</option><option value="6">
|
|
Multi RGBW</option></select><br><a
|
|
href="https://kno.wled.ge/interfaces/e1.31-dmx/" target="_blank">E1.31 info</a>
|
|
<br>Timeout: <input name="ET" type="number" min="1" max="65000" required> ms<br>
|
|
Force max brightness: <input type="checkbox" name="FB"><br>
|
|
Disable realtime gamma correction: <input type="checkbox" name="RG"><br>
|
|
Realtime LED offset: <input name="WO" type="number" min="-255" max="255"
|
|
required><h3>Alexa Voice Assistant</h3>Emulate Alexa device: <input
|
|
type="checkbox" name="AL"><br>Alexa invocation name: <input type="text"
|
|
name="AI" maxlength="32"><h3>Blynk</h3><b>
|
|
Blynk, MQTT and Hue sync all connect to external hosts!<br>
|
|
This may impact the responsiveness of the ESP8266.</b><br>
|
|
For best results, only use one of these services at a time.<br>
|
|
(alternatively, connect a second ESP to them and use the UDP sync)<br><br>Host:
|
|
<input type="text" name="BH" maxlength="32"> Port: <input name="BP"
|
|
type="number" min="1" max="65535" value="80" class="d5"><br>Device Auth token:
|
|
<input name="BK" maxlength="33"><br><i>Clear the token field to disable. </i><a
|
|
href="https://kno.wled.ge/interfaces/blynk/" target="_blank">Setup info</a><h3>
|
|
MQTT</h3>Enable MQTT: <input type="checkbox" name="MQ"><br>Broker: <input
|
|
type="text" name="MS" maxlength="32"> Port: <input name="MQPORT" type="number"
|
|
min="1" max="65535" class="d5"><br><b>
|
|
The MQTT credentials are sent over an unsecured connection.<br>
|
|
Never use the MQTT password for another service!</b><br>Username: <input
|
|
type="text" name="MQUSER" maxlength="40"><br>Password: <input type="password"
|
|
name="MQPASS" maxlength="64"><br>Client ID: <input type="text" name="MQCID"
|
|
maxlength="40"><br>Device Topic: <input type="text" name="MD" maxlength="32">
|
|
<br>Group Topic: <input type="text" name="MG" maxlength="32"><br>
|
|
Publish on button press: <input type="checkbox" name="BM"><br><i>
|
|
Reboot required to apply changes. </i><a
|
|
href="https://kno.wled.ge/interfaces/mqtt/" target="_blank">MQTT info</a><h3>
|
|
Philips Hue</h3><i>
|
|
You can find the bridge IP and the light number in the 'About' section of the hue app.
|
|
</i><br>Poll Hue light <input name="HL" type="number" min="1" max="99"> every
|
|
<input name="HI" type="number" min="100" max="65000"> ms: <input
|
|
type="checkbox" name="HP"><br>Then, receive <input type="checkbox" name="HO">
|
|
On/Off, <input type="checkbox" name="HB"> Brightness, and <input
|
|
type="checkbox" name="HC"> Color<br>Hue Bridge IP:<br><input name="H0"
|
|
type="number" class="s" min="0" max="255"> . <input name="H1" type="number"
|
|
class="s" min="0" max="255"> . <input name="H2" type="number" class="s" min="0"
|
|
max="255"> . <input name="H3" type="number" class="s" min="0" max="255"><br><b>
|
|
Press the pushlink button on the bridge, after that save this page!</b><br>
|
|
(when first connecting)<br>Hue status: <span class="sip">Disabled in this build
|
|
</span><hr><button type="button" onclick="B()">Back</button><button
|
|
type="submit">Save</button></form></body></html>)=====";
|
|
|
|
|
|
// Autogenerated from wled00/data/settings_time.htm, do not edit!!
|
|
const char PAGE_settings_time[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
|
|
<meta charset="utf-8"><title>Time Settings</title><script>
|
|
var d=document,ms=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],cals='style="font-size:27px;margin-top:-6px;cursor:pointer"';function H(){window.open("https://kno.wled.ge/features/settings/#time-settings")}function B(){window.open("/settings","_self")}function S(){BTa(),GetV(),updLoc(),Cs(),FC()}function gId(t){return d.getElementById(t)}function gN(t){return d.getElementsByName(t)[0]}function expand(t,e){var n=gId("WD"+e);n.style.display="none"!==n.style.display?"none":"",t.innerHTML="none"===n.style.display?"🗓":"✕"}function Cs(){gId("cac").style.display="none",gId("coc").style.display="block",gId("ccc").style.display="none",gId("ca").selected&&(gId("cac").style.display="block"),gId("cc").selected&&(gId("coc").style.display="none",gId("ccc").style.display="block"),gId("cn").selected&&(gId("coc").style.display="none")}function BTa(){var t="<tr><th>En.</th><th>Hour</th><th>Minute</th><th>Preset</th><th></th></tr>";for(i=0;i<8;i++){for(t+=`<tr><td><input name="W${i}" id="W${i}" type="hidden"><input id="W${i}0" type="checkbox"></td>\n<td><input name="H${i}" class="xs" type="number" min="0" max="24"></td>\n<td><input name="N${i}" class="xs" type="number" min="0" max="59"></td>\n<td><input name="T${i}" class="s" type="number" min="0" max="250"></td>\n<td><div id="CB${i}" onclick="expand(this,${i})" ${cals}>🗓</div></td></tr>`,t+=`<tr><td colspan=5><div id="WD${i}" style="display:none;">Run on weekdays`,t+='<table style="width:100%%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>',j=1;j<8;j++)t+=`<td><input id="W${i}${j}" type="checkbox"></td>`;for(t+=`</tr></table>from\n<select name="M${i}">`,j=0;j<12;j++)t+=`<option value="${j+1}">${ms[j]}</option>`;for(t+=`</select><input name="D${i}" class="xs" type="number" min="1" max="31"></input> to\n<select name="P${i}">`,j=0;j<12;j++)t+=`<option value="${j+1}">${ms[j]}</option>`;t+=`</select><input name="E${i}" class="xs" type="number" min="1" max="31"></input>\n\t\t<hr></div></td></tr>`}for(t+=`<tr><td><input name="W8" id="W8" type="hidden"><input id="W80" type="checkbox"></td>\n<td>Sunrise<input name="H8" value="255" type="hidden"></td>\n<td><input name="N8" class="xs" type="number" min="-59" max="59"></td>\n<td><input name="T8" class="s" type="number" min="0" max="250"></td>\n<td><div id="CB8" onclick="expand(this,8)" ${cals}>🗓</div></td></tr><tr><td colspan=5>`,t+='<div id="WD8"style="display:none;"><table style="width:100%%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>',j=1;j<8;j++)t+=`<td><input id="W8${j}" type="checkbox"></td>`;for(t+="</tr></table><hr></div></td></tr>",t+=`<tr><td><input name="W9" id="W9" type="hidden"><input id="W90" type="checkbox"></td>\n<td>Sunset<input name="H9" value="255" type="hidden"></td>\n<td><input name="N9" class="xs" type="number" min="-59" max="59"></td>\n<td><input name="T9" class="s" type="number" min="0" max="250"></td>\n<td><div id="CB9" onclick="expand(this,9)" ${cals}>🗓</div></td></tr><tr><td colspan=5>`,t+='<div id="WD9" style="display:none;"><table style="width:100%%;"><tr><th>M</th><th>T</th><th>W</th><th>T</th><th>F</th><th>S</th><th>S</th></tr><tr>',j=1;j<8;j++)t+=`<td><input id="W9${j}" type="checkbox"></td>`;t+="</tr></table><hr></div></td></tr>",gId("TMT").innerHTML=t}function FC(){for(i=0;i<10;i++){let t=gId("W"+i).value;for(j=0;j<8;j++)gId("W"+i+j).checked=t>>j&1;(127!=(127&t)||i<8&&(1!=gN("M"+i).value||1!=gN("D"+i).value||12!=gN("P"+i).value||31!=gN("E"+i).value))&&expand(gId("CB"+i),i)}}function Wd(){for(a=[0,0,0,0,0,0,0,0,0,0],i=0;i<10;i++){for(m=1,j=0;j<8;j++)a[i]+=gId("W"+i+j).checked*m,m*=2;gId("W"+i).value=a[i]}"S"===d.Sf.LTR.value&&(d.Sf.LT.value=-1*parseFloat(d.Sf.LT.value)),"W"===d.Sf.LNR.value&&(d.Sf.LN.value=-1*parseFloat(d.Sf.LN.value))}function addRow(t,e,n,i){var d=gId("macros"),a=d.rows.length,l=d.insertRow(a),s=String.fromCharCode((t<10?48:55)+t);document.createElement("td");l.insertCell(0).innerHTML=`Button ${t}:`,l.insertCell(1).innerHTML=`<input name="MP${s}" type="number" class="s" min="0" max="250" value="${e}" required>`,l.insertCell(2).innerHTML=`<input name="ML${s}" type="number" class="s" min="0" max="250" value="${n}" required>`,l.insertCell(3).innerHTML=`<input name="MD${s}" type="number" class="s" min="0" max="250" value="${i}" required>`}function updLoc(t){parseFloat(d.Sf.LT.value)<0?(d.Sf.LTR.value="S",d.Sf.LT.value=-1*parseFloat(d.Sf.LT.value)):d.Sf.LTR.value="N",parseFloat(d.Sf.LN.value)<0?(d.Sf.LNR.value="W",d.Sf.LN.value=-1*parseFloat(d.Sf.LN.value)):d.Sf.LNR.value="E"}function GetV() {
|
|
%CSS%%SCSS%</head><body onload="S()"><form
|
|
id="form_s" name="Sf" method="post" onsubmit="Wd()"><div class="helpB"><button
|
|
type="button" onclick="H()">?</button></div><button type="button" onclick="B()">
|
|
Back</button><button type="submit">Save</button><hr><h2>Time setup</h2>
|
|
Get time from NTP server: <input type="checkbox" name="NT"><br><input
|
|
type="text" name="NS" maxlength="32"><br>Use 24h format: <input type="checkbox"
|
|
name="CF"><br>Time zone: <select name="TZ"><option value="0"
|
|
selected="selected">GMT(UTC)</option><option value="1">GMT/BST</option><option
|
|
value="2">CET/CEST</option><option value="3">EET/EEST</option><option value="4">
|
|
US-EST/EDT</option><option value="5">US-CST/CDT</option><option value="6">
|
|
US-MST/MDT</option><option value="7">US-AZ</option><option value="8">US-PST/PDT
|
|
</option><option value="9">CST(AWST)</option><option value="10">JST(KST)
|
|
</option><option value="11">AEST/AEDT</option><option value="12">NZST/NZDT
|
|
</option><option value="13">North Korea</option><option value="14">IST (India)
|
|
</option><option value="15">CA-Saskatchewan</option><option value="16">ACST
|
|
</option><option value="17">ACST/ACDT</option><option value="18">HST (Hawaii)
|
|
</option><option value="19">NOVT (Novosibirsk)</option><option value="20">
|
|
AKST/AKDT (Anchorage)</option><option value="21">MX-CST/CDT</option></select>
|
|
<br>UTC offset: <input name="UO" type="number" min="-65500" max="65500"
|
|
required> seconds (max. 18 hours)<br>Current local time is <span class="times">
|
|
unknown</span>.<br>Latitude: <select name="LTR"><option value="N">N</option>
|
|
<option value="S">S</option></select><input name="LT" type="number" class="xl"
|
|
min="0" max="66.6" step="0.01"><br>Longitude: <select name="LNR"><option
|
|
value="E">E</option><option value="W">W</option></select><input name="LN"
|
|
type="number" class="xl" min="0" max="180" step="0.01"><div id="sun"
|
|
class="times"></div><h3>Clock</h3>Clock Overlay: <select name="OL"
|
|
onchange="Cs()"><option value="0" id="cn" selected="selected">None</option>
|
|
<option value="1" id="ca">Analog Clock</option><option value="2">
|
|
Single Digit Clock</option><option value="3" id="cc">Cronixie Clock</option>
|
|
</select><br><div id="coc">First LED: <input name="O1" type="number" min="0"
|
|
max="255" required> Last LED: <input name="O2" type="number" min="0" max="255"
|
|
required><br><div id="cac">12h LED: <input name="OM" type="number" min="0"
|
|
max="255" required><br>Show 5min marks: <input type="checkbox" name="O5"><br>
|
|
</div>Seconds (as trail): <input type="checkbox" name="OS"><br></div><div
|
|
id="ccc">Cronixie Display: <input name="CX" maxlength="6"><br>
|
|
Cronixie Backlight: <input type="checkbox" name="CB"><br></div>Countdown Mode:
|
|
<input type="checkbox" name="CE"><br>Countdown Goal:<br>Date: <nowrap>20
|
|
<input name="CY" class="xs" type="number" min="0" max="99" required>-<input
|
|
name="CI" class="xs" type="number" min="1" max="12" required>-<input name="CD"
|
|
class="xs" type="number" min="1" max="31" required></nowrap><br>Time:<nowrap>
|
|
<input name="CH" class="xs" type="number" min="0" max="23" required>:<input
|
|
name="CM" class="xs" type="number" min="0" max="59" required>:<input name="CS"
|
|
class="xs" type="number" min="0" max="59" required></nowrap><br><h3>
|
|
Macro presets</h3><b>Macros have moved!</b><br><i>
|
|
Presets now also can be used as macros to save both JSON and HTTP API commands.
|
|
<br>Just enter the preset ID below!</i> <i>
|
|
Use 0 for the default action instead of a preset</i><br>Alexa On/Off Preset:
|
|
<input name="A0" class="m" type="number" min="0" max="250" required> <input
|
|
name="A1" class="m" type="number" min="0" max="250" required><br>
|
|
Countdown-Over Preset: <input name="MC" class="m" type="number" min="0"
|
|
max="250" required><br>Timed-Light-Over Presets: <input name="MN" class="m"
|
|
type="number" min="0" max="250" required><br><h3>Button actions</h3><table
|
|
style="margin:0 auto" id="macros"><thead><tr><td>push<br>switch</td><td>short
|
|
<br>on->off</td><td>long<br>off->on</td><td>double<br>N/A</td></tr>
|
|
</thead><tbody></tbody></table><a
|
|
href="https://kno.wled.ge/features/macros/#analog-button" target="_blank">
|
|
Analog Button setup</a><h3>Time-controlled presets</h3><div
|
|
style="display:inline-block"><table id="TMT" style="min-width:330px"></table>
|
|
</div><hr><button type="button" onclick="B()">Back</button><button
|
|
type="submit">Save</button></form></body></html>)=====";
|
|
|
|
|
|
// Autogenerated from wled00/data/settings_sec.htm, do not edit!!
|
|
const char PAGE_settings_sec[] PROGMEM = R"=====(<!DOCTYPE html><html lang="en"><head><meta name="viewport" content="width=500">
|
|
<meta charset="utf-8"><title>Misc Settings</title><script>
|
|
var timeout,d=document;function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#security-settings")}function B(){window.open("/settings","_self")}function U(){window.open("/update","_self")}function gId(t){return d.getElementById(t)}function isObject(t){return t&&"object"==typeof t&&!Array.isArray(t)}function showToast(t,e=!1){var n=gId("toast");n.innerHTML=t,n.className=e?"error":"show",clearTimeout(timeout),n.style.animation="none",timeout=setTimeout((function(){n.className=n.className.replace("show","")}),2900)}function uploadFile(t,e){var n=new XMLHttpRequest;n.addEventListener("load",(function(){showToast(this.responseText,this.status>=400)})),n.addEventListener("error",(function(t){showToast(t.stack,!0)})),n.open("POST","/upload");var o=new FormData;return o.append("data",t.files[0],e),n.send(o),t.value="",!1}function GetV() {var d=document;
|
|
%CSS%%SCSS%</head><body onload="GetV()">
|
|
<form id="form_s" name="Sf" method="post"><div class="helpB"><button
|
|
type="button" onclick="H()">?</button></div><button type="button" onclick="B()">
|
|
Back</button><button type="submit">Save & Reboot</button><hr><h2>
|
|
Security & Update setup</h2>Lock wireless (OTA) software update: <input
|
|
type="checkbox" name="NO"><br>Passphrase: <input type="password" name="OP"
|
|
maxlength="32"><br>
|
|
To enable OTA, for security reasons you need to also enter the correct password!
|
|
<br>The password should be changed when OTA is enabled.<br><b>
|
|
Disable OTA when not in use, otherwise an attacker can reflash device software!
|
|
</b><br><i>Settings on this page are only changable if OTA lock is disabled!</i>
|
|
<br>Deny access to WiFi settings if locked: <input type="checkbox" name="OW">
|
|
<br><br>Factory reset: <input type="checkbox" name="RS"><br>
|
|
All settings and presets will be erased.<br><br>
|
|
HTTP traffic is unencrypted. An attacker in the same network can intercept form data!
|
|
<h3>Software Update</h3><button type="button" onclick="U()">Manual OTA Update
|
|
</button><br>Enable ArduinoOTA: <input type="checkbox" name="AO"><br><h3>
|
|
Backup & Restore</h3><a class="btn lnk" href="/presets.json?download"
|
|
target="download-frame">Backup presets</a><br><div>Restore presets<br><input
|
|
type="file" name="data" accept=".json"> <input type="button" value="Upload"
|
|
onclick='uploadFile(d.Sf.data,"/presets.json")'><br></div><br><a
|
|
class="btn lnk" href="/cfg.json?download" target="download-frame">
|
|
Backup configuration</a><br><div>Restore configuration<br><input type="file"
|
|
name="data2" accept=".json"> <input type="button" value="Upload"
|
|
onclick='uploadFile(d.Sf.data2,"/cfg.json")'><br></div><div style="color:#fa0">
|
|
⚠ Restoring presets/configuration will OVERWRITE your current presets/configuration.
|
|
<br>
|
|
Incorrect configuration may require a factory reset or re-flashing of your ESP.
|
|
</div>For security reasons, passwords are not backed up.<h3>About</h3><a
|
|
href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a>
|
|
version 0.13.0-b6<br><br><a
|
|
href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits"
|
|
target="_blank">Contributors, dependencies and special thanks</a><br>
|
|
A huge thank you to everyone who helped me create WLED!<br><br>
|
|
(c) 2016-2022 Christian Schwinne<br><i>Licensed under the <a
|
|
href="https://github.com/Aircoookie/WLED/blob/master/LICENSE" target="_blank">
|
|
MIT license</a></i><br><br>Server message: <span class="sip">Response error!
|
|
</span><hr><div id="toast"></div><button type="button" onclick="B()">Back
|
|
</button><button type="submit">Save & Reboot</button></form><iframe
|
|
name="download-frame" style="display:none"></iframe></body></html>)=====";
|
|
|
|
|
|
// Autogenerated from wled00/data/settings_um.htm, do not edit!!
|
|
const char PAGE_settings_um[] PROGMEM = R"=====(<!DOCTYPE html><html><head lang="en"><meta charset="utf-8"><meta
|
|
name="viewport" content="width=500"><title>Usermod Settings</title><script>
|
|
var owner,locip,urows,d=document,umCfg={},pins=[6,7,8,9,10,11],pinO=["rsvd","rsvd","rsvd","rsvd","rsvd","rsvd"],loc=!1,numM=0;function gId(e){return d.getElementById(e)}function isO(e){return e&&"object"==typeof e&&!Array.isArray(e)}function H(){window.open("https://github.com/Aircoookie/WLED/wiki/Settings#usermod-settings")}function B(){window.open("/settings","_self")}function S(){"file:"==window.location.protocol&&(loc=!0,(locip=localStorage.getItem("locIp"))||(locip=prompt("File Mode. Please enter WLED IP!"),localStorage.setItem("locIp",locip))),GetV(),numM>0||locip?ldS():gId("um").innerHTML="No Usermods installed."}function isF(e){return e===+e&&e!==(0|e)}function isI(e){return e===+e&&e===(0|e)}function check(e,n){var i=e.name.replace("[]","").substr(-3);if("number"==e.type&&"pin"==i.substr(0,3))for(var t=0;t<pins.length;t++)if(n!=pinO[t]){if(e.value==pins[t]||e.value<-1||e.value>39){e.style.color="red";break}e.style.color=e.value>33?"orange":"#fff"}}function getPins(e){if(isO(e))for(const[i,t]of Object.entries(e))if(isO(t))owner=i,getPins(t);else if("pin"==i.replace("[]","").substr(-3))if(Array.isArray(t))for(var n=0;n<t.length;n++)t[n]>=0&&(pins.push(t[n]),pinO.push(owner));else t>=0&&(pins.push(t),pinO.push(owner));else if(Array.isArray(t))for(n=0;n<t.length;n++)getPins(t[n])}function addField(e,n,i,t=!1){if(isO(i))for(const[t,o]of Object.entries(i))"unknown"===n||e.includes(":")?addField(e,t,o):addField(e+":"+n,t,o);else if(Array.isArray(i))for(var o=0;o<i.length;o++)addField(e,n,i[o],!0);else{var s,r=typeof i;switch(r){case"boolean":r="checkbox",s='value="true"'+(i?" checked":"");break;case"number":s=`value="${i}"`,"pin"===n.substr(-3)?(s+=' max="39" min="-1" style="width:40px;"',r="int"):s+=' step="any" style="width:100px;"';break;default:r="text",s=`value="${i}" style="width:250px;"`}e.includes(":")&&(urows+=e.substr(e.indexOf(":")+1)),urows+=` ${n}: `,"checkbox"==r?urows+=`<input type="hidden" name="${e}:${n}${t?"[]":""}" value="false">`:t||(urows+=`<input type="hidden" name="${e}:${n}${t?"[]":""}" value="${r}">`),urows+=`<input type="${"int"===r?"number":r}" name="${e}:${n}${t?"[]":""}" ${s} oninput="check(this,'${e.substr(e.indexOf(":")+1)}')"><br>`}}function ldS(){fetch((loc?"http://"+locip:"")+"/cfg.json",{method:"get"}).then(e=>(e.ok||(gId("lserr").style.display="inline"),e.json())).then(e=>{if(umCfg=e.um,getPins(e),urows="",isO(umCfg))for(const[e,n]of Object.entries(umCfg))urows+=`<hr><h3>${e}</h3>`,addField(e,"unknown",n);""===urows&&(urows="Usermods configuration not found.<br>Press <i>Save</i> to initialize defaults."),gId("um").innerHTML=urows}).catch((function(e){gId("lserr").style.display="inline",console.log(e)}))}function svS(e){e.preventDefault(),console.log(d.Sf),d.Sf.checkValidity()&&d.Sf.submit()}function GetV() {var d=document;
|
|
%CSS%%SCSS%</head><body onload="S()"><form
|
|
id="form_s" name="Sf" method="post" onsubmit="svS(event)"><div class="toprow">
|
|
<div class="helpB"><button type="button" onclick="H()">?</button></div><button
|
|
type="button" onclick="B()">Back</button><button type="submit">Save</button><br>
|
|
<span id="lssuc" style="color:green;display:none">✔ Configuration saved!
|
|
</span> <span id="lserr" style="color:red;display:none">
|
|
⚠ Could not load configuration.</span><hr></div><h2>Usermod Setup</h2><div
|
|
id="um">Loading settings...</div><hr><button type="button" onclick="B()">Back
|
|
</button><button type="submit">Save</button></form></body></html>)=====";
|
|
|