-
Notifications
You must be signed in to change notification settings - Fork 7
/
build.js
89 lines (89 loc) · 40.9 KB
/
build.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
(()=>{"use strict";var __webpack_modules__={582:function(__unused_webpack_module,exports,__webpack_require__){var _a,_b,__createBinding=this&&this.__createBinding||(Object.create?function(o,m,k,k2){void 0===k2&&(k2=k);var desc=Object.getOwnPropertyDescriptor(m,k);desc&&!("get"in desc?!m.__esModule:desc.writable||desc.configurable)||(desc={enumerable:!0,get:function(){return m[k]}}),Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){void 0===k2&&(k2=k),o[k2]=m[k]
}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(o,v){Object.defineProperty(o,"default",{enumerable:!0,value:v})}:function(o,v){o.default=v}),__importStar=this&&this.__importStar||function(mod){if(mod&&mod.__esModule)return mod;var result={};if(null!=mod)for(var k in mod)"default"!==k&&Object.prototype.hasOwnProperty.call(mod,k)&&__createBinding(result,mod,k);return __setModuleDefault(result,mod),result};Object.defineProperty(exports,"__esModule",{value:!0})
;const Chalk=__importStar(__webpack_require__(22)),child_process_1=__webpack_require__(81),fs=__importStar(__webpack_require__(147)),os=__importStar(__webpack_require__(37)),readline=__importStar(__webpack_require__(521)),util_1=__webpack_require__(402),path=__importStar(__webpack_require__(17)),rpi_pin_conversions_1=__webpack_require__(538),process_util_1=__webpack_require__(816),util_2=__webpack_require__(837),enoughRam=os.totalmem()/1073741824>1.5;let copyfiles=__webpack_require__(517)
;copyfiles.default&&(copyfiles=copyfiles.default),readline.emitKeypressEvents(process.stdin),process.stdin.setRawMode(!0);const isWindows="win32"===process.platform;let doAdmin,spinStep=0,lastSpin=0,doUpdateUpgrade=!0,doNpmI=!0,npmInitDone=!1,doAcu=!1,clearAcu=!1,doDht=!1,clearDht=!1,doKiosk=!0,clearKiosk=!1,doStdDeploy=!1,doDedicated=!1,doLaunch=!1,doReboot=!1,noStop=!1,prod=!1,viaBash=!1,interactive=!1,treatAsRaspberryPi=process.argv.includes("--tarp"),isRaspberryPi=!1,spin=()=>{const now=(0,
util_1.processMillis)();lastSpin<now-100&&(lastSpin=now,write(backspace+"|/-\\".charAt(spinStep)),spinStep=(spinStep+1)%4)};const chalk=new Chalk.Instance;chalk.mediumGray=chalk.hex("#808080"),chalk.paleBlue=chalk.hex("#66CCFF"),chalk.paleYellow=chalk.hex("#FFFFAA");let backspace="\b",sol="[1G",trailingSpace=" ",totalSteps=2,currentStep=0;const settings={AWC_ALLOW_ADMIN:"false",AWC_ALLOW_CORS:"true",AWC_KIOSK_MODE:"true",AWC_LOG_CACHE_ACTIVITY:"false",AWC_NTP_SERVERS:"",AWC_PORT:"8080",
AWC_PREFERRED_WS:"wunderground",AWC_WIRED_TH_GPIO:"17",AWC_WIRELESS_TH_GPIO:"27"},userHome=(0,process_util_1.getUserHome)(),sudoUser=(0,process_util_1.getSudoUser)(),user=process.env.SUDO_USER||process.env.USER||"pi";let uid;const cpuPath2="/sys/firmware/devicetree/base/model",settingsPath="/etc/default/weatherService",rpiSetupStuff=path.join(__dirname,"raspberry_pi_setup"),serviceSrc=rpiSetupStuff+"/weatherService",fontSrc=rpiSetupStuff+"/fonts/",fontDst="/usr/local/share/fonts/"
;let chromium="chromium",autostartDst=".config/lxsession/LXDE";let nodePath=process.env.PATH;if("linux"===process.platform)try{if(fs.existsSync("/proc/cpuinfo")){const lines=(0,util_1.asLines)(fs.readFileSync("/proc/cpuinfo").toString());fs.existsSync(cpuPath2)&&lines.push(...(0,util_1.asLines)(fs.readFileSync(cpuPath2).toString()));for(const line of lines)if(/\b(Raspberry Pi|BCM\d+)\b/i.test(line)){isRaspberryPi=treatAsRaspberryPi=!0,autostartDst+="-pi",chromium+="-browser";break}}}catch(err){
console.error(chalk.redBright("Raspberry Pi check failed"))}!isRaspberryPi&&!treatAsRaspberryPi||process.env.DISPLAY||(process.env.DISPLAY=":0.0");let launchChromium=chromium+" http://localhost:8080/";const launchChromiumPattern=new RegExp(`^@${chromium}\\b.*\\bhttp:\\/\\/localhost:\\d+\\/$`);/\b(ts-)?node\b/.test(null!==(_a=process.argv[0])&&void 0!==_a?_a:"")&&process.argv.splice(0,1),/\bbuild(\.[jt]s)?\b/.test(null!==(_b=process.argv[0])&&void 0!==_b?_b:"")&&process.argv.splice(0,1),
0===process.argv.length&&treatAsRaspberryPi&&!viaBash&&(console.warn(chalk.yellow("Warning: no build options specified.")),console.warn(chalk.yellow("This could be OK, or this could mean you forgot the leading ")+chalk.white("--")+chalk.yellow(" before your options.")));const onlyOnRaspberryPi=[],onlyDedicated=[];let helpMsg,getPathArg=!1;if(process.argv.forEach((arg=>{if(getPathArg)return process.env.NODE_PATH=arg.trim(),process.env.PATH=nodePath=arg.trim()+(nodePath?":"+nodePath:nodePath),
void(getPathArg=!1);switch(arg){case"--":case"--tarp":break;case"--acu":doAcu=!0;break;case"--acu-":doAcu=!1,clearAcu=!0;break;case"--admin":doAdmin=!0;break;case"--admin-":doAdmin=!1;break;case"--bash":viaBash=!0,delete process.env.SHLVL;break;case"--ddev":doDedicated=doStdDeploy=!0,onlyOnRaspberryPi.push(arg);break;case"--dht":doDht=!0,onlyOnRaspberryPi.push(arg);break;case"--dht-":doDht=!1,clearDht=!0;break;case"-i":interactive=doStdDeploy=doDedicated=!0,onlyOnRaspberryPi.push(arg),
delete process.env.SHLVL;break;case"--kiosk":doKiosk=!0,clearKiosk=!1;break;case"--kiosk-":doKiosk=!1,clearKiosk=!0;break;case"--launch":doLaunch=!0,onlyOnRaspberryPi.push(arg),onlyDedicated.push(arg);break;case"--nostop":noStop=!0;break;case"-p":prod=!0;break;case"--path":getPathArg=!0;break;case"--pt":spin=void 0,chalk.level=0,backspace="",sol="",trailingSpace=" ";break;case"--reboot":doReboot=!0,doLaunch=!1,onlyOnRaspberryPi.push(arg),onlyDedicated.push(arg);break;case"--sd":doStdDeploy=!0,
onlyOnRaspberryPi.push(arg);break;case"--skip-upgrade":doUpdateUpgrade=!1,onlyOnRaspberryPi.push(arg);break;case"--skip-npm-i":doNpmI=!1;break;default:helpMsg="Usage: sudo ./build.sh [--acu] [--admin] [--ddev] [--dht] [--gps] [--help] [-i]\n [--launch] [--kiosk] [-p] [--pt] [--reboot] [--sd]\n [--skip-upgrade] [--tarp]\n\nThe options --acu, --admin, --dht, and --kiosk can be followed by an extra\ndash (e.g. --acu-) to clear a previously enabled option.",
viaBash||(helpMsg=helpMsg.replace("sudo ./build.sh","npm run build").replace(/\n {2}/g,"\n")),"--help"!==arg&&"-h"!==arg&&console.error('Unrecognized option "'+chalk.redBright(arg)+'"'),console.log(helpMsg),process.exit(1)}})),noStop&&(doReboot=doLaunch=!1),!treatAsRaspberryPi&&onlyOnRaspberryPi.length>0&&(onlyOnRaspberryPi.forEach((opt=>console.error(chalk.redBright(opt)+" option is only valid on Raspberry Pi"))),process.exit(1)),
!doDedicated&&onlyDedicated.length>0&&(onlyDedicated.forEach((opt=>console.error(chalk.redBright(opt)+" option is only valid when used with the --ddev or -i options"))),process.exit(1)),treatAsRaspberryPi)try{if(fs.existsSync(settingsPath)){const lines=(0,util_1.asLines)(fs.readFileSync(settingsPath).toString()),oldSettings={};lines.forEach((line=>{const $=/^\s*(\w+)\s*=\s*(\S+)/.exec(line);$&&(oldSettings[$[1]]=settings[$[1]]=$[2])})),void 0===doAdmin?doAdmin=(0,
util_1.toBoolean)(oldSettings.AWC_ALLOW_ADMIN):settings.AWC_ALLOW_ADMIN=null==doAdmin?void 0:doAdmin.toString(),!oldSettings.AWC_WIRED_TH_GPIO&&(0,util_1.toBoolean)(oldSettings.AWC_HAS_INDOOR_SENSOR)&&(oldSettings.AWC_WIRED_TH_GPIO=settings.AWC_WIRED_TH_GPIO=settings.AWC_TH_SENSOR_GPIO||"4"),!clearDht&&oldSettings.AWC_WIRED_TH_GPIO&&(doDht=!0),!settings.AWC_WIRELESS_TH_GPIO&&oldSettings.AWC_WIRELESS_TEMP&&(oldSettings.AWC_WIRELESS_TH_GPIO=settings.AWC_WIRELESS_TH_GPIO=settings.AWC_WIRELESS_TEMP),
!clearAcu&&oldSettings.AWC_WIRELESS_TH_GPIO&&(doAcu=!0),settings.AWC_NTP_SERVERS||("pool.ntp.org"===oldSettings.AWC_NTP_SERVER?settings.AWC_NTP_SERVERS="":oldSettings.AWC_NTP_SERVER&&(settings.AWC_NTP_SERVERS=oldSettings.AWC_NTP_SERVER)),delete settings.AWC_HAS_INDOOR_SENSOR,delete settings.AWC_TH_SENSOR_GPIO,delete settings.AWC_WIRELESS_TEMP,delete settings.AWC_NTP_SERVER,doKiosk=!clearKiosk&&(0,util_1.toBoolean)(oldSettings.AWC_KIOSK_MODE,doKiosk),settings.AWC_KIOSK_MODE=doKiosk.toString()}}catch(err){
console.warn(chalk.yellow("Existing settings check failed. Defaults will be used."))}async function readUserInput(){return new Promise((resolve=>{let buffer="",length=0;const clearLine=()=>write("\b \b".repeat(length)),callback=(ch,key)=>{""===ch?(write("^C\n"),process.exit(130)):""===ch?(clearLine(),length=0):"enter"===key.name||"return"===key.name?(write("\n"),process.stdin.off("keypress",callback),
resolve(buffer.substr(0,length).trim())):"backspace"===key.name||"left"===key.name?length>0&&(write("\b \b"),--length):"delete"===key.name?length>0&&(write("\b \b"),buffer=buffer.substr(0,--length)+buffer.substr(length+1)):"up"===key.name?(clearLine(),write("\n"),process.stdin.off("keypress",callback),resolve("")):"right"===key.name?length<buffer.length&&write(buffer.charAt(length++)):null!=ch&&ch>=" "&&!key.ctrl&&!key.meta&&(write(ch),buffer=buffer.substr(0,length)+ch+buffer.substr(length++))}
;process.stdin.on("keypress",callback)}))}function write(s){process.stdout.write(s)}function stepDone(){console.log(backspace+chalk.green("✔"))}async function isInstalled(command){var _a;return!!(null===(_a=await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("command",["-v",command],{shell:!0}),null,process_util_1.ErrorMode.ANY_ERROR))||void 0===_a?void 0:_a.trim())}async function install(cmdPkg,viaNpm=!1,realOnly=!1,quiet=!1){let packageArgs=[cmdPkg],name=cmdPkg;return quiet||showStep(),
realOnly&&!isRaspberryPi?(console.log(`${chalk.bold(cmdPkg)} won't be installed (not real Raspberry Pi)`+trailingSpace+backspace+chalk.green("✔")),!1):("pigpio"===cmdPkg&&(packageArgs=["pigpio","python-pigpio","python3-pigpio"],name="pigpiod"),await isInstalled(name)?(quiet?stepDone():console.log(`${chalk.bold(cmdPkg)} already installed`+trailingSpace+backspace+chalk.green("✔")),!1):(quiet||write(`Installing ${chalk.bold(cmdPkg)}`+trailingSpace),viaNpm?await(0,process_util_1.monitorProcess)((0,
process_util_1.spawn)("npm",["install","-g",...packageArgs]),spin,process_util_1.ErrorMode.ANY_ERROR):await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("apt-get",["install","-y",...packageArgs]),spin,process_util_1.ErrorMode.ANY_ERROR),stepDone(),!0))}function getWebpackSummary(s){const lines=(0,util_1.asLines)(s),summary=[];for(let line of lines)/(^(hash|version|time|built at):)|by path assets\/ |runtime modules|javascript modules|compiled successfully in/i.test(line)&&(line=line.trim(),
summary.push(line.substr(0,72)+(line.length>72?"...":"")));return" "+summary.join("\n ")}var RepoStatus;async function getRepoStatus(){const lines=(0,util_1.asLines)((await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("git",["status","--porcelain","-b"]))).trim());let status=RepoStatus.CLEAN;lines.length>0&&lines.splice(0,1);for(const line of lines){if(!/\bpackage-lock.json$/.test(line)){status=RepoStatus.DIRTY;break}status=RepoStatus.PACKAGE_LOCK_CHANGES_ONLY}return status}
function showStep(){write(`Step ${++currentStep} of ${totalSteps}: `)}function chalkUp(s,currentStyle=(s=>s)){var _a;const closed=/(.*?)(\[([a-z]+)])(.*?)(\[\/\3])(.*)/.exec(s),open=/(.*?)(\[([a-z]+)])(.*)/.exec(s);if(!closed&&!open)return s;let $;$=closed&&open?open[1].length<closed[1].length?open:closed:null!=closed?closed:open;let style,chalked=$[4],end=null!==(_a=$[6])&&void 0!==_a?_a:"";switch($[5]||(chalked+=end,end=""),$[3]){case"pb":style=chalk.paleBlue;break;case"w":style=chalk.whiteBright}
return $[1]+chalkUp(style(chalked),style)+currentStyle(chalkUp(end))}!isRaspberryPi&&doAcu&&console.warn(chalk.yellow("Warning: this setup will only generate fake wireless sensor data")),function(RepoStatus){RepoStatus[RepoStatus.CLEAN=0]="CLEAN",RepoStatus[RepoStatus.PACKAGE_LOCK_CHANGES_ONLY=1]="PACKAGE_LOCK_CHANGES_ONLY",RepoStatus[RepoStatus.DIRTY=2]="DIRTY"}(RepoStatus||(RepoStatus={}))
;const DOMAIN_PATTERN=/^(((?!-))(xn--|_)?[-a-z\d]{0,61}[a-z\d]\.)*(xn--)?([a-z\d][-a-z\d]{0,60}|[-a-z\d]{1,30}\.[a-z]{2,})(:\d{1,5})?$/i;function yesOrNo(s,assign){return/^[yn]/i.test(s)?(assign(/^y/i.test(s)),!0):(console.log(chalk.redBright("Response must be (y)es or (n)o")),!1)}function pinValidate(s){return!((0,rpi_pin_conversions_1.convertPinToGpio)(s)<0)||(console.log(chalk.redBright(s+" is not a valid pin number")),!1)}
"darksky"===process.env.AWC_PREFERRED_WS&&(process.env.AWC_PREFERRED_WS="wunderground");const finalAction=doReboot?"R":doLaunch?"L":"#",finalOptions="(l/r/n)".replace(finalAction.toLowerCase(),finalAction);let questions=[{prompt:"Perform initial update/upgrade?",ask:!0,yn:!0,deflt:doUpdateUpgrade?"Y":"N",validate:function(s){return yesOrNo(s,(isYes=>doUpdateUpgrade=isYes))}},{prompt:"Perform npm install? (N option for debug only)",ask:!0,yn:!0,deflt:doNpmI?"Y":"N",validate:function(s){
return yesOrNo(s,(isYes=>doNpmI=isYes))}},{name:"AWC_PORT",prompt:"HTTP server port.",ask:!0,validate:function(s){const port=Number(s);return!(isNaN(port)||port<1||port>65535)||(console.log(chalk.redBright("Port must be a number from 1 to 65535")),!1)}},{prompt:"Allow user to reboot, shutdown, update, etc.?",ask:!0,yn:!0,deflt:doAdmin?"Y":"N",validate:function(s){return yesOrNo(s,(isYes=>settings.AWC_ALLOW_ADMIN=isYes?"true":"false"))}},{name:"AWC_NTP_SERVERS",
prompt:"time servers (comma-separated domains, blank for defaults)",ask:!0,validate:function(s){const domains=s.split(",").map((d=>d.trim()));return""===s.trim()||domains.length>0&&domains.findIndex((d=>!DOMAIN_PATTERN.test(d)))<0||(console.log(chalk.redBright("NTP servers must be a valid domain names (with optional port numbers)")),!1)}},{name:"AWC_GOOGLE_API_KEY",
prompt:"Optional Google geocoding API key (for city names from\n GPS coordinates)."+(settings.AWC_GOOGLE_API_KEY?"\n Enter - (dash) to remove old API key":""),ask:!0},{name:"AWC_PREFERRED_WS",prompt:"preferred weather service, (w)underground, weather(b)it,\n or (v)isual crossing).",ask:!0,validate:function(s){
return/^w[-b]*$/i.test(s)?"wunderground":/b/i.test(s)?"weatherbit":/^v/i.test(s)?"visual_x":(console.log(chalk.redBright("Weather service must be either (w)underground, weather(b)it, or (v)isual crossing")),!1)},after:function(s){/^w[-b]*$/i.test(s)?(console.log(chalk.paleBlue(" Weather Underground chosen, but Weatherbit.io or Visual Crossing can be used")),
console.log(chalk.paleBlue(" as fallback weather services."))):/b/i.test(s)?(console.log(chalk.paleBlue(" Weatherbit.io chosen, but Weather Underground will be used")),console.log(chalk.paleBlue(" as a fallback weather service."))):/^v/i.test(s)&&(console.log(chalk.paleBlue(" Visual Crossing chosen, but Weather Underground will be used")),console.log(chalk.paleBlue(" as a fallback weather service.")))}},{name:"AWC_WEATHERBIT_API_KEY",
prompt:"Optional Weatherbit.io (via RapidAPI) key, for\n weather and geocoding."+(settings.AWC_WEATHERBIT_API_KEY?"\n Enter - (dash) to remove old API key":""),ask:!0},{name:"AWC_VISUAL_CROSSING_API_KEY",prompt:"Optional Visual Crossing weather API key."+(settings.AWC_VISUAL_CROSSING_API_KEY?"\n Enter - (dash) to remove old API key":""),ask:!0},{prompt:"Use wired DHT temperature/humidity sensor?",ask:!0,yn:!0,deflt:doDht?"Y":"N",validate:function(s){return yesOrNo(s,(isYes=>doDht=isYes))}},{
name:"AWC_WIRED_TH_GPIO",prompt:"GPIO pin number for wired temp/humidity sensor",ask:()=>doDht,validate:pinValidate},{prompt:"Use wireless temperature/humidity sensors?",ask:!0,yn:!0,deflt:doAcu?"Y":"N",validate:function(s){return yesOrNo(s,(isYes=>doAcu=isYes))}},{name:"AWC_WIRELESS_TH_GPIO",prompt:"GPIO pin number for wireless temp/humidity sensors",ask:()=>doAcu,validate:pinValidate},{prompt:`When finished, (l)aunch A/W clock, (r)eboot, or (n)o action ${finalOptions}?`,ask:!0,deflt:finalAction,
validate:function(s){let $;return($=/^([lrn])/i.exec(s.toLowerCase()))?("l"===$[1]?(doLaunch=!0,doReboot=!1):"r"===$[1]?(doLaunch=!1,doReboot=!0):doLaunch=doReboot=!1,!0):(console.log(chalk.redBright("Response must be (l)aunch, (r)eboot, or (n)o action")),!1)}}];async function doServerBuild(){!doNpmI&&fs.existsSync("server/node_modules")&&fs.existsSync("server/package-lock.json")||(showStep(),write("Updating server"+trailingSpace),await(0,process_util_1.monitorProcess)((0,
process_util_1.spawn)("npm",uid,["i","--no-save"],{cwd:path.join(__dirname,"server")}),spin),stepDone()),showStep(),write("Building server"+trailingSpace),fs.existsSync("server/dist")&&await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("rm",uid,["-Rf","server/dist"]),spin);const opts={shell:!0,cwd:path.join(__dirname,"server"),env:process.env},output=getWebpackSummary(await(0,process_util_1.monitorProcess)((0,
process_util_1.spawn)("npm",uid,["run",isWindows?"build-win":"build"+(enoughRam?"":":tiny")],opts),spin));if(stepDone(),(null==output?void 0:output.trim())&&console.log(chalk.mediumGray(output)),doAcu||doDht){showStep();const args=["i","-P","rpi-acu-rite-temperature@2","node-dht-sensor@0.4"];doAcu&&doDht?write("Adding wireless and wired temp/humidity sensor support"+trailingSpace):doAcu?(args.splice(3,1),write("Adding Acu-Rite wireless temperature/humidity sensor support"+trailingSpace)):(args.splice(2,1),
write("Adding DHT wired temperature/humidity sensor support"+trailingSpace)),await async function(){if(!npmInitDone){const file=path.join(__dirname,"server","dist","package.json"),packageJson={name:"aw-clock-server",version:"0.0.0",description:"AW-Clock Server",main:"app.js",license:"MIT",dependencies:{}};fs.writeFileSync(file,JSON.stringify(packageJson,null,2)),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("chown",[user,file]),spin,process_util_1.ErrorMode.ANY_ERROR),npmInitDone=!0}}(),
await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("npm",uid,args,{cwd:path.join(__dirname,"server","dist")}),spin),stepDone()}}doDedicated&&questions.splice(questions.length-1,0,{prompt:"Launch browser in kiosk mode?",ask:!0,yn:!0,deflt:doKiosk?"Y":"N",validate:function(s){return yesOrNo(s,(isYes=>doKiosk=isYes))}}),noStop&&(questions=questions.slice(0,-1)),(async()=>{var _a;try{uid=Number((await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("id",["-u",user]))).trim()||"1000")
;const nodeVersionStr=(await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("node",uid,["--version"]))).trim(),nodeVersion=(0,util_1.toNumber)((null!==(_a=/v(\d+)/.exec(nodeVersionStr))&&void 0!==_a?_a:[])[1]);if(isRaspberryPi&&(nodeVersion<10||nodeVersion>14)&&(console.error(chalk.redBright(`Node.js version 10.x-14.x required. Version ${nodeVersionStr} found.`)),process.exit(1)),treatAsRaspberryPi&&!isRaspberryPi){const isDebian=/^Linux\b.+\bDebian\b/i.test(await(0,
process_util_1.monitorProcess)((0,process_util_1.spawn)("uname",["-a"]))),isLxde=await isInstalled("lxpanel");isDebian&&isLxde||(console.error(chalk.redBright("--tarp option (Treat As Raspberry Pi) only available for Linux Debian with LXDE")),process.exit(1))}if(isRaspberryPi&&await async function(){console.log(chalk.cyan("- GPS test -"))
;const hasGpsTools=await isInstalled("gpsd")&&await isInstalled("gpspipe"),hasNtpTools=await isInstalled("ntpd")&&await isInstalled("ntpq"),hasPpsTools=await isInstalled("ppstest");let gpsLocationIsWorking=!1,gpsTimeIsWorking=!1;if(hasGpsTools){const gpsInfo=await new Promise(((resolve,reject)=>{const proc=(0,process_util_1.spawn)("gpspipe",["-w","-n","12"]);let finished=!1;(0,process_util_1.monitorProcessLines)(proc,null,process_util_1.ErrorMode.NO_ERRORS).then((lines=>{finished=!0,resolve(lines)
})).catch((err=>{finished=!0,reject(err)})),setTimeout((()=>{finished||(proc.kill(),console.warn(chalk.yellow("Warning: gpspipe timed out.")),resolve([]))}),1e4)}));for(const line of gpsInfo)try{const obj=JSON.parse(line);if((0,util_1.isObject)(obj)&&(0,util_1.isNumber)(obj.lat)&&(0,util_1.isNumber)(obj.lon)){gpsLocationIsWorking=!0;break}}catch(_a){}}if(hasNtpTools){const ntpInfo=await new Promise(((resolve,reject)=>{const proc=(0,process_util_1.spawn)("ntpq",["-p"]);let finished=!1;(0,
process_util_1.monitorProcessLines)(proc,null,process_util_1.ErrorMode.NO_ERRORS).then((lines=>{finished=!0,resolve(lines)})).catch((err=>{finished=!0,reject(err)})),setTimeout((()=>{finished||(proc.kill(),console.warn(chalk.yellow("Warning: ntpq timed out.")),resolve([]))}),1e4)}));for(const line of ntpInfo)if(/^\*SHM\b.+\.PPS\.\s+0\s+l\s+.+?\s[-+]?[.\d]+\s+[.\d]+\s*$/.test(line)){gpsTimeIsWorking=!0;break}}
if(gpsLocationIsWorking&&gpsTimeIsWorking)console.log("GPS time and location services found "+chalk.green("✔"));else{const hasChrony=await isInstalled("chrony");console.log(chalk.yellow("GPS time and/or location services not found")),console.log(chalk.yellow("The following updates/changes are suggested if GPS support is desired:")),hasChrony&&console.log(chalkUp(" [pb]• Remove [w]chrony[/w] package to avoid conflict with ntpd.")),
hasGpsTools?console.log(chalkUp(" [pb]• Check [w]gpsd[/w] configuration")):console.log(chalkUp(" [pb]• Install [w]gpsd[/w] and [w]gpspipe[/w]")),hasNtpTools?console.log(chalkUp(" [pb]• Check [w]ntpd[/w] configuration")):console.log(chalkUp(" [pb]• Install [w]ntpd[/w] and [w]ntpq[/w]")),hasPpsTools||console.log(chalkUp(" [pb]• Install [w]ppstest[/w]"))}}(),interactive&&await async function(){console.log(chalk.cyan(sol+"- Configuration -"));for(let i=0;i<questions.length;++i){const q=questions[i]
;if(!((0,util_1.isFunction)(q.ask)?q.ask():q.ask))continue;q.name?write(chalk.bold(q.name)+" - "+q.prompt+"\n "+(settings[q.name]?"(default: "+chalk.paleYellow(settings[q.name])+")":"")+": "):(write(q.prompt),q.yn&&write("Y"===q.deflt?" (Y/n)":" (y/N)"),write(": "));const response=await readUserInput();if(""!==response){if(response){const validation=!q.validate||q.validate(response);if((0,util_1.isString)(validation))settings[q.name]=validation;else{if(!validation){--i;continue}
q.name&&("-"===response?delete settings[q.name]:settings[q.name]=response)}}else response||"#"!==q.deflt||(--i,console.log(chalk.redBright("Response required")));q.after&&q.after(settings[q.name])}else i=Math.max(i-2,-1)}}(),process.stdin.setRawMode(!1),totalSteps+=noStop?0:1,totalSteps+=!doNpmI&&fs.existsSync("node_modules")&&fs.existsSync("package-lock.json")?0:1,totalSteps+=!doNpmI&&fs.existsSync("server/node_modules")&&fs.existsSync("server/package-lock.json")?0:1,totalSteps+=doAcu||doDht?1:0,
totalSteps+=doStdDeploy||doDedicated?1:0,totalSteps+=doLaunch||doReboot?1:0,doDht||delete settings.AWC_WIRED_TH_GPIO,doAcu||delete settings.AWC_WIRELESS_TH_GPIO,doDedicated){if(totalSteps+=9+(doUpdateUpgrade?1:0),console.log(chalk.cyan(sol+"- Dedicated device setup -")),doUpdateUpgrade&&(showStep(),write("Updating/upgrading packages (can take a long time!)"+trailingSpace),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("apt-get",["update","-y"]),spin,process_util_1.ErrorMode.NO_ERRORS),
await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("apt-get",["upgrade","-y"]),spin,process_util_1.ErrorMode.NO_ERRORS),stepDone()),!noStop){showStep(),write("Stopping weatherService if currently running"+trailingSpace);try{await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("service",["weatherService","stop"]),spin,process_util_1.ErrorMode.ANY_ERROR)}catch(err){const msg=err.message||err.toString()
;/Interactive authentication required/i.test(msg)&&(console.log(backspace+trailingSpace),console.error(err),console.log("\npolkit is requiring interactive authentication to stop weatherService."),console.log('Please enter "sudo service weatherService stop" at the prompt below.'),console.log("\nWhen that is done, restart this installation with either: "),console.log(" sudo ./build.sh --nostop -i (for interactive set-up)"),
console.log(" sudo ./build.sh --nostop -ddev (for automated set-up)"),process.exit(1))}stepDone()}await install("pigpio",!1,!0),await install(chromium),await install("unclutter");for(let i=0;i<2;++i)try{await install("forever",!0,!1,i>0);break}catch(_b){i>0&&console.log(backspace+chalk.paleYellow("✘"))}await async function(){showStep();const fontsToAdd=fs.readdirSync(fontSrc).filter((name=>/.\.ttf/i.test(name))).filter((font=>!fs.existsSync(fontDst+font)));if(fontsToAdd.length>0){
write("Installing fonts"+trailingSpace);for(const font of fontsToAdd)await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("cp",[fontSrc+font,fontDst+font]),spin,process_util_1.ErrorMode.ANY_ERROR);await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("fc-cache",["-f"]),spin,process_util_1.ErrorMode.ANY_ERROR)}else write("Fonts already installed"+trailingSpace);stepDone()}();try{await async function(uid){var _a
;const screenSaverJustInstalled=await install("xscreensaver"),settingsFile=`${userHome}/.xscreensaver`;if(showStep(),write("Disabling screen saver"+trailingSpace),screenSaverJustInstalled||!fs.existsSync(settingsFile)){const procList=await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("ps",["-ax"]),spin);/\d\s+xscreensaver\b/.test(procList)||((0,process_util_1.spawn)("xscreensaver",[],{uid,detached:!0,env:process.env}),await(0,process_util_1.sleep)(500));const settingsProcess=(0,
process_util_1.spawn)("xscreensaver-demo",[],{uid,env:process.env});await(0,process_util_1.sleep)(3e3,spin),settingsProcess.kill("SIGTERM"),await(0,process_util_1.sleep)(500,spin)}await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("sed",["-i","-r","'s/^(mode:\\s+)\\w+$/\\1off/'",settingsFile],{uid,shell:!0}),spin,process_util_1.ErrorMode.ANY_ERROR);const procList=await(0,process_util_1.monitorProcess)((0,
process_util_1.spawn)("ps",["-ax"]),spin),ssProcessNo=(null!==(_a=/^(\d+)\s+.*\d\s+xscreensaver\b/.exec(procList))&&void 0!==_a?_a:[])[1];ssProcessNo&&await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("kill",[ssProcessNo]),spin),(0,process_util_1.spawn)("xscreensaver",[],{uid,detached:!0}),stepDone()}(uid)}catch(_c){console.log(backspace+chalk.paleYellow("✘"))}}settings.AWC_GIT_REPO_PATH=(await(0,process_util_1.monitorProcess)((0,
process_util_1.spawn)("pwd"),spin,process_util_1.ErrorMode.NO_ERRORS)).trim()||settings.AWC_GIT_REPO_PATH,settings.AWC_GIT_REPO_PATH||delete settings.AWC_GIT_REPO_PATH,console.log(chalk.cyan(sol+"- Building application -"));const repoStatus1=await getRepoStatus();await async function(){!doNpmI&&fs.existsSync("node_modules")&&fs.existsSync("package-lock.json")||(showStep(),write("Updating client"+trailingSpace),await(0,process_util_1.monitorProcess)((0,
process_util_1.spawn)("npm",uid,["i","--no-save"]),spin),stepDone()),showStep(),write("Building client"+trailingSpace),fs.existsSync("dist")&&await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("rm",uid,["-Rf","dist"]),spin);const opts={shell:!0,env:process.env},args=["run","build:client"+(enoughRam?"":":tiny")];prod&&args.push("--","--env","mode=prod");const output=getWebpackSummary(await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("npm",uid,args,opts),spin));stepDone(),
(null==output?void 0:output.trim())&&console.log(chalk.mediumGray(output))}(),await doServerBuild();const repoStatus2=await getRepoStatus();if(viaBash&&repoStatus1===RepoStatus.CLEAN&&repoStatus2===RepoStatus.PACKAGE_LOCK_CHANGES_ONLY&&await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("git",["reset","--hard"])),showStep(),write("Copying server to top-level dist directory"+trailingSpace),await(0,util_2.promisify)(copyfiles)(["server/dist/**/*","dist/"],{up:2}),await(0,
process_util_1.monitorProcess)((0,process_util_1.spawn)("chown",["-R",sudoUser,"dist"],{shell:!0}),spin,process_util_1.ErrorMode.ANY_ERROR),stepDone(),doStdDeploy&&(showStep(),write("Moving server to ~/weather directory"+trailingSpace),fs.existsSync(userHome+"/awc-alarm-tones")||fs.mkdirSync(userHome+"/awc-alarm-tones"),fs.existsSync(userHome+"/weather")?await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("rm",["-Rf",userHome+"/weather/*"],{shell:!0
}),spin,process_util_1.ErrorMode.ANY_ERROR):await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("mkdir",[userHome+"/weather"]),spin),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("mv",["dist/*",userHome+"/weather"],{shell:!0}),spin,process_util_1.ErrorMode.ANY_ERROR),stepDone()),doDedicated&&(console.log(chalk.cyan(sol+"- Dedicated device service deployment -")),await async function(){let autostartDir=path.join(userHome,autostartDst),morePi_ish=!1
;if(!autostartDir.endsWith("-pi")){const lxdePiCheckDir=path.join(userHome,".config/lxpanel/LXDE-pi");fs.existsSync(lxdePiCheckDir)&&(morePi_ish=!0,autostartDir+="-pi")}showStep(),write("Create or redeploy weatherService"+trailingSpace),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("cp",[serviceSrc,"/etc/init.d/."],{shell:!0}),spin,process_util_1.ErrorMode.ANY_ERROR),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("chmod",["+x","/etc/init.d/weatherService"],{shell:!0
}),spin,process_util_1.ErrorMode.ANY_ERROR);const settingsText=`# If you edit AWC_PORT below, be sure to update\n# ${userHome}/${autostartDst}/autostart accordingly.\n`+Object.keys(settings).sort().map((key=>key+"="+settings[key])).join("\n")+"\n";fs.writeFileSync(settingsPath,settingsText),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("update-rc.d",["weatherService","defaults"]),spin),await(0,process_util_1.monitorProcess)((0,
process_util_1.spawn)("systemctl",["enable","weatherService"]),spin),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("mkdir",uid,["-p",autostartDir]),spin),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("cp",uid,[rpiSetupStuff+"/autostart_extra.sh",autostartDir]),spin,process_util_1.ErrorMode.ANY_ERROR),doKiosk&&(launchChromium=launchChromium.replace(/\s+/," --kiosk --autoplay-policy=no-user-gesture-required "))
;const autostartPath=autostartDir+"/autostart",autostartLine1=autostartDir+"/autostart_extra.sh",autostartLine2="@"+launchChromium.replace(/:8080\b/,":"+settings.AWC_PORT);let lines=[];try{lines=(0,util_1.asLines)(fs.readFileSync(autostartPath).toString()).filter((line=>!!line.trim()))}catch(err){(isRaspberryPi||morePi_ish)&&(lines=["@lxpanel --profile LXDE-pi","@pcmanfm --desktop --profile LXDE-pi","@xscreensaver -no-splash"],await isInstalled("point-rpi")&&lines.push("@point-rpi"))}let update=!1
;lines.includes(autostartLine1)||(lines.push(autostartLine1),update=!0);for(let i=0;i<=lines.length;++i){if(i===lines.length){lines.push(autostartLine2),update=!0;break}if(lines[i]===autostartLine2)break;if(launchChromiumPattern.test(lines[i])){lines[i]=autostartLine2,update=!0;break}}update&&fs.writeFileSync(autostartPath,lines.join("\n")+"\n"),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("chown",0,[sudoUser,autostartDir+"/autostart*"],{shell:!0
}),spin,process_util_1.ErrorMode.ANY_ERROR),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("chmod",uid,["+x",autostartDir+"/autostart*"],{shell:!0}),spin,process_util_1.ErrorMode.ANY_ERROR),noStop?console.log(backspace+trailingSpace+"\n\nReboot to complete set-up."):await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("service",["weatherService","start"]),spin),stepDone()}()),doLaunch){console.log(chalk.cyan(sol+"- Launching Astronomy/Weather Clock -")),showStep(),write(" "),
await(0,process_util_1.sleep)(3e3,spin),stepDone(),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("pkill",uid,["-o",chromium]),spin,process_util_1.ErrorMode.NO_ERRORS),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)("pkill",uid,["-o",chromium.substr(0,15)]),spin,process_util_1.ErrorMode.NO_ERRORS),await(0,process_util_1.sleep)(500,spin);const args=launchChromium.split(/\s/).slice(1);args.splice(args.length-1,0,`--user-data-dir='${userHome}'`),
setTimeout((()=>process.exit(0)),5e3),await(0,process_util_1.monitorProcess)((0,process_util_1.spawn)(chromium,uid,args,{detached:!0}))}doReboot&&(console.log(chalk.cyan(sol+"- Rebooting system in 5 seconds... -")),showStep(),write("Press any key to stop reboot:"+trailingSpace),await(0,process_util_1.sleep)(5e3,spin,!0)?console.log():(console.log(),(0,child_process_1.exec)("reboot"))),process.exit(0)}catch(err){console.log(backspace+chalk.red("✘")),console.error(err),process.exit(1)}})()},
816:function(__unused_webpack_module,exports,__webpack_require__){var __createBinding=this&&this.__createBinding||(Object.create?function(o,m,k,k2){void 0===k2&&(k2=k);var desc=Object.getOwnPropertyDescriptor(m,k);desc&&!("get"in desc?!m.__esModule:desc.writable||desc.configurable)||(desc={enumerable:!0,get:function(){return m[k]}}),Object.defineProperty(o,k2,desc)}:function(o,m,k,k2){void 0===k2&&(k2=k),o[k2]=m[k]}),__setModuleDefault=this&&this.__setModuleDefault||(Object.create?function(o,v){
Object.defineProperty(o,"default",{enumerable:!0,value:v})}:function(o,v){o.default=v}),__importStar=this&&this.__importStar||function(mod){if(mod&&mod.__esModule)return mod;var result={};if(null!=mod)for(var k in mod)"default"!==k&&Object.prototype.hasOwnProperty.call(mod,k)&&__createBinding(result,mod,k);return __setModuleDefault(result,mod),result};Object.defineProperty(exports,"__esModule",{value:!0}),
exports.sleep=exports.monitorProcessLines=exports.monitorProcess=exports.spawn=exports.stripFormatting=exports.ErrorMode=exports.getSudoUser=exports.getUserHome=void 0;const child_process_1=__webpack_require__(81),readline=__importStar(__webpack_require__(521)),util_1=__webpack_require__(402),isMacOS="darwin"===process.platform,isWindows="win32"===process.platform,sudoUser=process.env.SUDO_USER||process.env.USER||"pi";let userHome="/home/pi";try{
userHome=isMacOS?process.env.HOME:isWindows?process.env.USERPROFILE:(0,child_process_1.execSync)(`grep ${sudoUser} /etc/passwd`).toString().split(":")[5]||userHome}catch(err){console.error(err)}var ErrorMode;exports.getUserHome=function(){return userHome},exports.getSudoUser=function(){return sudoUser},function(ErrorMode){ErrorMode[ErrorMode.DEFAULT=0]="DEFAULT",ErrorMode[ErrorMode.ANY_ERROR=1]="ANY_ERROR",ErrorMode[ErrorMode.NO_ERRORS=2]="NO_ERRORS"}(ErrorMode=exports.ErrorMode||(exports.ErrorMode={}))
;const NO_OP=()=>{};function stripFormatting(s){return null==s?void 0:s.replace(/\x1B\[[\d;]*[A-Za-z]/g,"")}function errorish(s){return s=stripFormatting(s),/\b(failed|exception|invalid|operation not permitted|isn't a valid|Cannot resolve|must be specified|must implement|need to install|doesn't exist|are required|should be strings?)\b/i.test(s)||/[_\da-z](Error|Exception|Invalid)\b/.test(s)||/\[ERR_|code: 'ERR/.test(s)}function monitorProcess(proc,markTime,errorMode=ErrorMode.DEFAULT){
let errors="",output="";return new Promise(((resolve,reject)=>{const slowSpin=((null==(timer=setInterval(markTime||NO_OP,100))?void 0:timer.unref)&&timer.unref(),timer);var timer;proc.stderr.on("data",(data=>{(markTime||NO_OP)(),data=stripFormatting(data.toString()),/(\[webpack.Progress])|Warning\b/.test(data)||(errors+=data)})),proc.stdout.on("data",(data=>{(markTime||NO_OP)(),data=data.toString(),output+=data,errorish(data)&&(errors=errors?errors+"\n"+data:data)})),proc.on("error",(err=>{
clearInterval(slowSpin),errorMode===ErrorMode.NO_ERRORS?resolve(output):reject(err)})),proc.on("close",(()=>{clearInterval(slowSpin),errorMode!==ErrorMode.NO_ERRORS&&errors&&(errorMode===ErrorMode.ANY_ERROR||errorish(errors))?reject(errors.replace(/\bE:\s+/g,"").trim()):resolve(output)}))}))}exports.stripFormatting=stripFormatting,exports.spawn=function(command,uidOrArgs,optionsOrArgs,options){let uid,args;if((0,util_1.isNumber)(uidOrArgs)?(uid=uidOrArgs,args=optionsOrArgs||[]):(args=uidOrArgs||[],
uid=null==(options=optionsOrArgs)?void 0:options.uid),null!=uid&&((options=null!=options?options:{}).uid=uid,options.env||(options.env={},Object.assign(options.env,process.env)),options.env.HOME=userHome,options.env.LOGNAME=sudoUser,options.env.npm_config_cache=userHome+"/.npm",options.env.USER=sudoUser),isWindows){/^(chmod|chown|id)$/.test(command)?(command="rundll32",args=[]):"rm"===command?(command="rmdir",args=["/S","/Q",args[1].replace(/\//g,"\\")]):"which"===command&&(command="where")
;const cmd=process.env.comspec||"cmd";return null!=(null==options?void 0:options.uid)&&delete(options=Object.assign({},options)).uid,(0,child_process_1.spawn)(cmd,["/c",command,...args],options)}return(0,child_process_1.spawn)(command,args,options)},exports.monitorProcess=monitorProcess,exports.monitorProcessLines=async function(proc,markTime,errorMode=ErrorMode.DEFAULT){return(0,util_1.asLines)(await monitorProcess(proc,markTime,errorMode))},exports.sleep=function(delay,markTime,stopOnKeypress=!1){
return new Promise((resolve=>{const slowSpin=setInterval(markTime||NO_OP,100),timeout=setTimeout((()=>{clearInterval(slowSpin),resolve(!1)}),delay);stopOnKeypress&&(readline.emitKeypressEvents(process.stdin),process.stdin.setRawMode(!0),process.stdin.on("keypress",(()=>{clearInterval(slowSpin),clearTimeout(timeout),resolve(!0)})))}))}},538:function(__unused_webpack_module,exports,__webpack_require__){var __importDefault=this&&this.__importDefault||function(mod){return mod&&mod.__esModule?mod:{default:mod}}
;Object.defineProperty(exports,"__esModule",{value:!0}),exports.convertPinToGpio=exports.convertPin=exports.PinSystem=void 0;const fs_1=__importDefault(__webpack_require__(147)),util_1=__webpack_require__(402),wpiToGpioR1=[17,18,21,22,23,24,25,4,0,1,8,7,10,9,11,14,15,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
;let wpiToGpio=[17,18,27,22,23,24,25,4,2,3,8,7,10,9,11,14,15,28,29,30,31,5,6,13,19,26,12,16,20,21,0,1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1];const physToGpioR1=[-1,-1,-1,0,-1,1,-1,4,14,-1,15,17,18,21,-1,22,23,-1,24,10,-1,9,25,11,8,-1,7,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1]
;let physToGpio=[-1,-1,-1,2,-1,3,-1,4,14,-1,15,17,18,27,-1,22,23,-1,24,10,-1,9,25,11,8,-1,7,0,1,5,-1,6,12,13,-1,19,16,26,20,-1,21,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,28,29,30,31,-1,-1,-1,-1,-1,-1,-1];var GpioLayout,PinSystem;!function(GpioLayout){GpioLayout[GpioLayout.UNCHECKED=0]="UNCHECKED",GpioLayout[GpioLayout.LAYOUT_1=1]="LAYOUT_1",GpioLayout[GpioLayout.LAYOUT_2=2]="LAYOUT_2",GpioLayout[GpioLayout.UNKNOWN=3]="UNKNOWN"}(GpioLayout||(GpioLayout={})),function(PinSystem){
PinSystem[PinSystem.GPIO=0]="GPIO",PinSystem[PinSystem.PHYS=1]="PHYS",PinSystem[PinSystem.WIRING_PI=2]="WIRING_PI",PinSystem[PinSystem.VIRTUAL=2]="VIRTUAL"}(PinSystem=exports.PinSystem||(exports.PinSystem={}));let gpioLayout=GpioLayout.UNCHECKED,supportPhysPins=!1;let convertInit=!1;const gpioToPhys=new Array(32).fill(-1),gpioToWPi=new Array(32).fill(-1);function getConversions(){if(function(){if(gpioLayout===GpioLayout.UNCHECKED){let lines;gpioLayout=GpioLayout.UNKNOWN;try{lines=(0,
util_1.asLines)(fs_1.default.readFileSync("/proc/cpuinfo",{encoding:"ascii"}))}catch(_a){return void console.error("Can't read /proc/cpuinfo")}for(const line of lines){const $=/^Revision\s*:\s*\w*(\w{4})$/.exec(line);if($){"0002"===$[1]||"0003"===$[1]?(gpioLayout=GpioLayout.LAYOUT_1,wpiToGpio=wpiToGpioR1,physToGpio=physToGpioR1):gpioLayout=GpioLayout.LAYOUT_2,supportPhysPins=!0;break}}}}(),!convertInit&&gpioLayout!==GpioLayout.UNKNOWN){for(let i=0;i<64;++i){let gpio=wpiToGpio[i]
;gpio>=0&&(gpioToWPi[gpio]=i),gpio=physToGpio[i],gpio>=0&&(gpioToPhys[gpio]=i)}convertInit=!0}}function convertPin(pin,pinSystem0,pinSystem1){let pinNumber,pinSystemFrom,pinSystemTo;if((0,util_1.isString)(pin)){const $=/^(\d+)\s*([gpvw]?)$/.exec(pin.trim().toLowerCase());if(!$)return-1;{pinNumber=parseFloat($[1]),pinNumber=isNaN(pinNumber)?-1:pinNumber;const pinSystemIndex="pvw".indexOf($[2]||"g")+1;pinSystemFrom=[PinSystem.GPIO,PinSystem.PHYS,PinSystem.VIRTUAL,PinSystem.WIRING_PI][pinSystemIndex],
pinSystemTo=pinSystem0}}else pinNumber=pin,null==pinSystem1?(pinSystemFrom=PinSystem.GPIO,pinSystemTo=pinSystem0):(pinSystemFrom=pinSystem0,pinSystemTo=pinSystem1);return function(pinNumber,pinSysFrom,pinSysTo){if(getConversions(),!(supportPhysPins||pinSysFrom!==PinSystem.PHYS&&pinSysTo!==PinSystem.PHYS))throw new Error("Unknown hardware - physical pin numbering not supported");if(pinNumber<0||pinNumber>63||pinSysFrom!==PinSystem.PHYS&&pinNumber>31)return-1;let gpio;switch(pinSysFrom){case PinSystem.GPIO:
switch(pinSysTo){case PinSystem.GPIO:return pinNumber;case PinSystem.PHYS:return gpioToPhys[pinNumber];case PinSystem.WIRING_PI:return gpioToWPi[pinNumber]}break;case PinSystem.PHYS:switch(pinSysTo){case PinSystem.GPIO:return physToGpio[pinNumber];case PinSystem.PHYS:return pinNumber;case PinSystem.WIRING_PI:return(gpio=physToGpio[pinNumber])>=0?gpioToWPi[gpio]:-1}break;case PinSystem.WIRING_PI:switch(pinSysTo){case PinSystem.GPIO:return wpiToGpio[pinNumber];case PinSystem.PHYS:
return(gpio=wpiToGpio[pinNumber])>=0?gpioToPhys[gpio]:-1;case PinSystem.WIRING_PI:return pinNumber}}return-1}(pinNumber,pinSystemFrom,pinSystemTo)}exports.convertPin=convertPin,exports.convertPinToGpio=function(pinNumber,pinSys=PinSystem.GPIO){return(0,util_1.isString)(pinNumber)?convertPin(pinNumber,PinSystem.GPIO):convertPin(pinNumber,pinSys,PinSystem.GPIO)}},402:module=>{module.exports=require("@tubular/util")},22:module=>{module.exports=require("chalk")},517:module=>{module.exports=require("copyfiles")
},81:module=>{module.exports=require("child_process")},147:module=>{module.exports=require("fs")},37:module=>{module.exports=require("os")},17:module=>{module.exports=require("path")},521:module=>{module.exports=require("readline")},837:module=>{module.exports=require("util")}},__webpack_module_cache__={};(function __webpack_require__(moduleId){var cachedModule=__webpack_module_cache__[moduleId];if(void 0!==cachedModule)return cachedModule.exports;var module=__webpack_module_cache__[moduleId]={exports:{}}
;return __webpack_modules__[moduleId].call(module.exports,module,module.exports,__webpack_require__),module.exports})(582)})();