diff --git a/build-backend/lib/consts.js b/build-backend/lib/consts.js new file mode 100644 index 00000000..ee3432f3 --- /dev/null +++ b/build-backend/lib/consts.js @@ -0,0 +1,346 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.astroListLow = exports.astroList = exports.monthShort = exports.monthFullGen = exports.monthFull = exports.dayOfWeeksShort = exports.dayOfWeeksFull = void 0; +exports.dayOfWeeksFull = { + en: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'], + de: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'], + ru: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'], + pt: ['Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado'], + nl: ['Zondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag'], + fr: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'], + it: ['Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato'], + es: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'], + pl: ['Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'], + uk: ['неділя', 'понеділок', 'вівторок', 'Середа', 'четвер', "П'ятниця", 'Субота'], + 'zh-cn': ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'], +}; +exports.dayOfWeeksShort = { + en: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'], + de: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'], + ru: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'], + pt: ['Do', 'Se', 'Te', 'Qu', 'Qu', 'Se', 'Sá'], + nl: ['Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'], + fr: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'], + it: ['Do', 'Lu', 'Ma', 'Me', 'Gi', 'Ve', 'Sa'], + es: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá'], + pl: ['Ni', 'Po', 'Wt', 'Śr', 'Cz', 'Pi', 'So'], + uk: ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'], + 'zh-cn': ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'], +}; +exports.monthFull = { + en: [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ], + de: [ + 'Januar', + 'Februar', + 'März', + 'April', + 'Mai', + 'Juni', + 'Juli', + 'August', + 'September', + 'Oktober', + 'November', + 'Dezember', + ], + ru: [ + 'Январь', + 'Февраль', + 'Март', + 'Апрель', + 'Май', + 'Июнь', + 'Июль', + 'Август', + 'Сентябрь', + 'Октябрь', + 'Ноябрь', + 'Декабрь', + ], + pt: [ + 'Janeiro', + 'Fevereiro', + 'Março', + 'Abril', + 'Maio', + 'Junho', + 'Julho', + 'Agosto', + 'Setembro', + 'Outubro', + 'Novembro', + 'Dezembro', + ], + nl: [ + 'Januari', + 'Februari', + 'Maart', + 'April', + 'Mei', + 'Juni', + 'Juli', + 'Augustus', + 'September', + 'Oktober', + 'November', + 'December', + ], + fr: [ + 'Janvier', + 'Février', + 'Mars', + 'Avril', + 'Mai', + 'Juin', + 'Juillet', + 'Août', + 'Septembre', + 'Octobre', + 'Novembre', + 'Décembre', + ], + it: [ + 'Gennaio', + 'Febbraio', + 'Marzo', + 'Aprile', + 'Maggio', + 'Giugno', + 'Luglio', + 'Agosto', + 'Settembre', + 'Ottobre', + 'Novembre', + 'Dicembre', + ], + es: [ + 'Enero', + 'Febrero', + 'Marzo', + 'Abril', + 'Mayo', + 'Junio', + 'Julio', + 'Agosto', + 'Septiembre', + 'Octubre', + 'Noviembre', + 'Diciembre', + ], + pl: [ + 'Styczeń', + 'Luty', + 'Marzec', + 'Kwiecień', + 'Maj', + 'Czerwiec', + 'Lipiec', + 'Sierpień', + 'Wrzesień', + 'Październik', + 'Listopad', + 'Grudzień', + ], + uk: [ + 'Січень', + 'Лютий', + 'Березень', + 'Квітень', + 'Травень', + 'Червень', + 'Липень', + 'Серпень', + 'Вересень', + 'Жовтень', + 'Листопад', + 'Грудень', + ], + 'zh-cn': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], +}; +exports.monthFullGen = { + en: [ + 'January', + 'February', + 'March', + 'April', + 'May', + 'June', + 'July', + 'August', + 'September', + 'October', + 'November', + 'December', + ], + de: [ + 'Januar', + 'Februar', + 'März', + 'April', + 'Mai', + 'Juni', + 'Juli', + 'August', + 'September', + 'Oktober', + 'November', + 'Dezember', + ], + ru: [ + 'Января', + 'Февраля', + 'Марта', + 'Апреля', + 'Мая', + 'Июня', + 'Июля', + 'Августа', + 'Сентября', + 'Октября', + 'Ноября', + 'Декабря', + ], + pt: [ + 'Janeiro', + 'Fevereiro', + 'Março', + 'Abril', + 'Maio', + 'Junho', + 'Julho', + 'Agosto', + 'Setembro', + 'Outubro', + 'Novembro', + 'Dezembro', + ], + nl: [ + 'Januari', + 'Februari', + 'Maart', + 'April', + 'Mei', + 'Juni', + 'Juli', + 'Augustus', + 'September', + 'Oktober', + 'November', + 'December', + ], + fr: [ + 'Janvier', + 'Février', + 'Mars', + 'Avril', + 'Mai', + 'Juin', + 'Juillet', + 'Août', + 'Septembre', + 'Octobre', + 'Novembre', + 'Décembre', + ], + it: [ + 'Gennaio', + 'Febbraio', + 'Marzo', + 'Aprile', + 'Maggio', + 'Giugno', + 'Luglio', + 'Agosto', + 'Settembre', + 'Ottobre', + 'Novembre', + 'Dicembre', + ], + es: [ + 'Enero', + 'Febrero', + 'Marzo', + 'Abril', + 'Mayo', + 'Junio', + 'Julio', + 'Agosto', + 'Septiembre', + 'Octubre', + 'Noviembre', + 'Diciembre', + ], + pl: [ + 'Styczeń', + 'Luty', + 'Marzec', + 'Kwiecień', + 'Maj', + 'Czerwiec', + 'Lipiec', + 'Sierpień', + 'Wrzesień', + 'Październik', + 'Listopad', + 'Grudzień', + ], + uk: [ + 'Січень', + 'Лютий', + 'Березень', + 'Квітень', + 'Травень', + 'Червень', + 'Липень', + 'Серпень', + 'Вересень', + 'Жовтень', + 'Листопад', + 'Грудень', + ], + 'zh-cn': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], +}; +exports.monthShort = { + en: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'], + de: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'], + ru: ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июнь', 'Июль', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'], + pt: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'], + nl: ['Jan', 'Feb', 'Maa', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'], + fr: ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jui', 'Jui', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc'], + it: ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'], + es: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'], + pl: ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'], + uk: ['Січ', 'Лют', 'Бер', 'Кві', 'Тра', 'Чер', 'Лип', 'Сер', 'Вер', 'Жов', 'Лис', 'Гру'], + 'zh-cn': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'], +}; +exports.astroList = [ + 'sunrise', + 'sunset', + 'sunriseEnd', + 'sunsetStart', + 'dawn', + 'dusk', + 'nauticalDawn', + 'nauticalDusk', + 'nadir', + 'nightEnd', + 'night', + 'goldenHourEnd', + 'goldenHour', + 'solarNoon', +]; +exports.astroListLow = exports.astroList.map(str => str.toLowerCase()); +//# sourceMappingURL=consts.js.map \ No newline at end of file diff --git a/build-backend/lib/consts.js.map b/build-backend/lib/consts.js.map new file mode 100644 index 00000000..039200fd --- /dev/null +++ b/build-backend/lib/consts.js.map @@ -0,0 +1 @@ +{"version":3,"file":"consts.js","sourceRoot":"","sources":["../../src/lib/consts.ts"],"names":[],"mappings":";;;AAAa,QAAA,cAAc,GAAyC;IAChE,EAAE,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,UAAU,CAAC;IAClF,EAAE,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,SAAS,EAAE,SAAS,CAAC;IACrF,EAAE,EAAE,CAAC,aAAa,EAAE,aAAa,EAAE,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;IACvF,EAAE,EAAE,CAAC,SAAS,EAAE,eAAe,EAAE,aAAa,EAAE,cAAc,EAAE,cAAc,EAAE,aAAa,EAAE,QAAQ,CAAC;IACxG,EAAE,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC;IACpF,EAAE,EAAE,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,CAAC;IAC7E,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC;IAClF,EAAE,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,CAAC;IAC9E,EAAE,EAAE,CAAC,WAAW,EAAE,cAAc,EAAE,QAAQ,EAAE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,CAAC;IACpF,EAAE,EAAE,CAAC,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,QAAQ,CAAC;IACjF,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;CAC7D,CAAC;AACW,QAAA,eAAe,GAAyC;IACjE,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,EAAE,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IAC9C,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;CAC7D,CAAC;AAEW,QAAA,SAAS,GAAyC;IAC3D,EAAE,EAAE;QACA,SAAS;QACT,UAAU;QACV,OAAO;QACP,OAAO;QACP,KAAK;QACL,MAAM;QACN,MAAM;QACN,QAAQ;QACR,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,QAAQ;QACR,SAAS;QACT,MAAM;QACN,OAAO;QACP,KAAK;QACL,MAAM;QACN,MAAM;QACN,QAAQ;QACR,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,QAAQ;QACR,SAAS;QACT,MAAM;QACN,QAAQ;QACR,KAAK;QACL,MAAM;QACN,MAAM;QACN,QAAQ;QACR,UAAU;QACV,SAAS;QACT,QAAQ;QACR,SAAS;KACZ;IACD,EAAE,EAAE;QACA,SAAS;QACT,WAAW;QACX,OAAO;QACP,OAAO;QACP,MAAM;QACN,OAAO;QACP,OAAO;QACP,QAAQ;QACR,UAAU;QACV,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,SAAS;QACT,UAAU;QACV,OAAO;QACP,OAAO;QACP,KAAK;QACL,MAAM;QACN,MAAM;QACN,UAAU;QACV,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,SAAS;QACT,SAAS;QACT,MAAM;QACN,OAAO;QACP,KAAK;QACL,MAAM;QACN,SAAS;QACT,MAAM;QACN,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,SAAS;QACT,UAAU;QACV,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,OAAO;QACP,SAAS;QACT,OAAO;QACP,OAAO;QACP,MAAM;QACN,OAAO;QACP,OAAO;QACP,QAAQ;QACR,YAAY;QACZ,SAAS;QACT,WAAW;QACX,WAAW;KACd;IACD,EAAE,EAAE;QACA,SAAS;QACT,MAAM;QACN,QAAQ;QACR,UAAU;QACV,KAAK;QACL,UAAU;QACV,QAAQ;QACR,UAAU;QACV,UAAU;QACV,aAAa;QACb,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,QAAQ;QACR,OAAO;QACP,UAAU;QACV,SAAS;QACT,SAAS;QACT,SAAS;QACT,QAAQ;QACR,SAAS;QACT,UAAU;QACV,SAAS;QACT,UAAU;QACV,SAAS;KACZ;IACD,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;CACvF,CAAC;AAEW,QAAA,YAAY,GAAyC;IAC9D,EAAE,EAAE;QACA,SAAS;QACT,UAAU;QACV,OAAO;QACP,OAAO;QACP,KAAK;QACL,MAAM;QACN,MAAM;QACN,QAAQ;QACR,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,QAAQ;QACR,SAAS;QACT,MAAM;QACN,OAAO;QACP,KAAK;QACL,MAAM;QACN,MAAM;QACN,QAAQ;QACR,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,QAAQ;QACR,SAAS;QACT,OAAO;QACP,QAAQ;QACR,KAAK;QACL,MAAM;QACN,MAAM;QACN,SAAS;QACT,UAAU;QACV,SAAS;QACT,QAAQ;QACR,SAAS;KACZ;IACD,EAAE,EAAE;QACA,SAAS;QACT,WAAW;QACX,OAAO;QACP,OAAO;QACP,MAAM;QACN,OAAO;QACP,OAAO;QACP,QAAQ;QACR,UAAU;QACV,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,SAAS;QACT,UAAU;QACV,OAAO;QACP,OAAO;QACP,KAAK;QACL,MAAM;QACN,MAAM;QACN,UAAU;QACV,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,SAAS;QACT,SAAS;QACT,MAAM;QACN,OAAO;QACP,KAAK;QACL,MAAM;QACN,SAAS;QACT,MAAM;QACN,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,SAAS;QACT,UAAU;QACV,OAAO;QACP,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,WAAW;QACX,SAAS;QACT,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,OAAO;QACP,SAAS;QACT,OAAO;QACP,OAAO;QACP,MAAM;QACN,OAAO;QACP,OAAO;QACP,QAAQ;QACR,YAAY;QACZ,SAAS;QACT,WAAW;QACX,WAAW;KACd;IACD,EAAE,EAAE;QACA,SAAS;QACT,MAAM;QACN,QAAQ;QACR,UAAU;QACV,KAAK;QACL,UAAU;QACV,QAAQ;QACR,UAAU;QACV,UAAU;QACV,aAAa;QACb,UAAU;QACV,UAAU;KACb;IACD,EAAE,EAAE;QACA,QAAQ;QACR,OAAO;QACP,UAAU;QACV,SAAS;QACT,SAAS;QACT,SAAS;QACT,QAAQ;QACR,SAAS;QACT,UAAU;QACV,SAAS;QACT,UAAU;QACV,SAAS;KACZ;IACD,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;CACvF,CAAC;AAEW,QAAA,UAAU,GAAyC;IAC5D,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC3F,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxF,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC1F,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxF,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxF,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxF,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxF,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxF,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxF,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IACxF,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;CACvF,CAAC;AAkBW,QAAA,SAAS,GAAiB;IACnC,SAAS;IACT,QAAQ;IACR,YAAY;IACZ,aAAa;IACb,MAAM;IACN,MAAM;IACN,cAAc;IACd,cAAc;IACd,OAAO;IACP,UAAU;IACV,OAAO;IACP,eAAe;IACf,YAAY;IACZ,WAAW;CACd,CAAC;AACW,QAAA,YAAY,GAAG,iBAAS,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC","sourcesContent":["export const dayOfWeeksFull: Record = {\n en: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],\n de: ['Sonntag', 'Montag', 'Dienstag', 'Mittwoch', 'Donnerstag', 'Freitag', 'Samstag'],\n ru: ['Воскресенье', 'Понедельник', 'Вторник', 'Среда', 'Четверг', 'Пятница', 'Суббота'],\n pt: ['Domingo', 'Segunda-feira', 'Terça-feira', 'Quarta-feira', 'Quinta-feira', 'Sexta-feira', 'Sábado'],\n nl: ['Zondag', 'Maandag', 'Dinsdag', 'Woensdag', 'Donderdag', 'Vrijdag', 'Zaterdag'],\n fr: ['Dimanche', 'Lundi', 'Mardi', 'Mercredi', 'Jeudi', 'Vendredi', 'Samedi'],\n it: ['Domenica', 'Lunedì', 'Martedì', 'Mercoledì', 'Giovedì', 'Venerdì', 'Sabato'],\n es: ['Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'],\n pl: ['Niedziela', 'Poniedziałek', 'Wtorek', 'Środa', 'Czwartek', 'Piątek', 'Sobota'],\n uk: ['неділя', 'понеділок', 'вівторок', 'Середа', 'четвер', \"П'ятниця\", 'Субота'],\n 'zh-cn': ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],\n};\nexport const dayOfWeeksShort: Record = {\n en: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],\n de: ['So', 'Mo', 'Di', 'Mi', 'Do', 'Fr', 'Sa'],\n ru: ['Вс', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],\n pt: ['Do', 'Se', 'Te', 'Qu', 'Qu', 'Se', 'Sá'],\n nl: ['Zo', 'Ma', 'Di', 'Wo', 'Do', 'Vr', 'Za'],\n fr: ['Di', 'Lu', 'Ma', 'Me', 'Je', 'Ve', 'Sa'],\n it: ['Do', 'Lu', 'Ma', 'Me', 'Gi', 'Ve', 'Sa'],\n es: ['Do', 'Lu', 'Ma', 'Mi', 'Ju', 'Vi', 'Sá'],\n pl: ['Ni', 'Po', 'Wt', 'Śr', 'Cz', 'Pi', 'So'],\n uk: ['Нд', 'Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб'],\n 'zh-cn': ['星期日', '星期一', '星期二', '星期三', '星期四', '星期五', '星期六'],\n};\n\nexport const monthFull: Record = {\n en: [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ],\n de: [\n 'Januar',\n 'Februar',\n 'März',\n 'April',\n 'Mai',\n 'Juni',\n 'Juli',\n 'August',\n 'September',\n 'Oktober',\n 'November',\n 'Dezember',\n ],\n ru: [\n 'Январь',\n 'Февраль',\n 'Март',\n 'Апрель',\n 'Май',\n 'Июнь',\n 'Июль',\n 'Август',\n 'Сентябрь',\n 'Октябрь',\n 'Ноябрь',\n 'Декабрь',\n ],\n pt: [\n 'Janeiro',\n 'Fevereiro',\n 'Março',\n 'Abril',\n 'Maio',\n 'Junho',\n 'Julho',\n 'Agosto',\n 'Setembro',\n 'Outubro',\n 'Novembro',\n 'Dezembro',\n ],\n nl: [\n 'Januari',\n 'Februari',\n 'Maart',\n 'April',\n 'Mei',\n 'Juni',\n 'Juli',\n 'Augustus',\n 'September',\n 'Oktober',\n 'November',\n 'December',\n ],\n fr: [\n 'Janvier',\n 'Février',\n 'Mars',\n 'Avril',\n 'Mai',\n 'Juin',\n 'Juillet',\n 'Août',\n 'Septembre',\n 'Octobre',\n 'Novembre',\n 'Décembre',\n ],\n it: [\n 'Gennaio',\n 'Febbraio',\n 'Marzo',\n 'Aprile',\n 'Maggio',\n 'Giugno',\n 'Luglio',\n 'Agosto',\n 'Settembre',\n 'Ottobre',\n 'Novembre',\n 'Dicembre',\n ],\n es: [\n 'Enero',\n 'Febrero',\n 'Marzo',\n 'Abril',\n 'Mayo',\n 'Junio',\n 'Julio',\n 'Agosto',\n 'Septiembre',\n 'Octubre',\n 'Noviembre',\n 'Diciembre',\n ],\n pl: [\n 'Styczeń',\n 'Luty',\n 'Marzec',\n 'Kwiecień',\n 'Maj',\n 'Czerwiec',\n 'Lipiec',\n 'Sierpień',\n 'Wrzesień',\n 'Październik',\n 'Listopad',\n 'Grudzień',\n ],\n uk: [\n 'Січень',\n 'Лютий',\n 'Березень',\n 'Квітень',\n 'Травень',\n 'Червень',\n 'Липень',\n 'Серпень',\n 'Вересень',\n 'Жовтень',\n 'Листопад',\n 'Грудень',\n ],\n 'zh-cn': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],\n};\n\nexport const monthFullGen: Record = {\n en: [\n 'January',\n 'February',\n 'March',\n 'April',\n 'May',\n 'June',\n 'July',\n 'August',\n 'September',\n 'October',\n 'November',\n 'December',\n ],\n de: [\n 'Januar',\n 'Februar',\n 'März',\n 'April',\n 'Mai',\n 'Juni',\n 'Juli',\n 'August',\n 'September',\n 'Oktober',\n 'November',\n 'Dezember',\n ],\n ru: [\n 'Января',\n 'Февраля',\n 'Марта',\n 'Апреля',\n 'Мая',\n 'Июня',\n 'Июля',\n 'Августа',\n 'Сентября',\n 'Октября',\n 'Ноября',\n 'Декабря',\n ],\n pt: [\n 'Janeiro',\n 'Fevereiro',\n 'Março',\n 'Abril',\n 'Maio',\n 'Junho',\n 'Julho',\n 'Agosto',\n 'Setembro',\n 'Outubro',\n 'Novembro',\n 'Dezembro',\n ],\n nl: [\n 'Januari',\n 'Februari',\n 'Maart',\n 'April',\n 'Mei',\n 'Juni',\n 'Juli',\n 'Augustus',\n 'September',\n 'Oktober',\n 'November',\n 'December',\n ],\n fr: [\n 'Janvier',\n 'Février',\n 'Mars',\n 'Avril',\n 'Mai',\n 'Juin',\n 'Juillet',\n 'Août',\n 'Septembre',\n 'Octobre',\n 'Novembre',\n 'Décembre',\n ],\n it: [\n 'Gennaio',\n 'Febbraio',\n 'Marzo',\n 'Aprile',\n 'Maggio',\n 'Giugno',\n 'Luglio',\n 'Agosto',\n 'Settembre',\n 'Ottobre',\n 'Novembre',\n 'Dicembre',\n ],\n es: [\n 'Enero',\n 'Febrero',\n 'Marzo',\n 'Abril',\n 'Mayo',\n 'Junio',\n 'Julio',\n 'Agosto',\n 'Septiembre',\n 'Octubre',\n 'Noviembre',\n 'Diciembre',\n ],\n pl: [\n 'Styczeń',\n 'Luty',\n 'Marzec',\n 'Kwiecień',\n 'Maj',\n 'Czerwiec',\n 'Lipiec',\n 'Sierpień',\n 'Wrzesień',\n 'Październik',\n 'Listopad',\n 'Grudzień',\n ],\n uk: [\n 'Січень',\n 'Лютий',\n 'Березень',\n 'Квітень',\n 'Травень',\n 'Червень',\n 'Липень',\n 'Серпень',\n 'Вересень',\n 'Жовтень',\n 'Листопад',\n 'Грудень',\n ],\n 'zh-cn': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],\n};\n\nexport const monthShort: Record = {\n en: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'June', 'July', 'Aug', 'Sept', 'Oct', 'Nov', 'Dec'],\n de: ['Jan', 'Feb', 'Mär', 'Apr', 'Mai', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dez'],\n ru: ['Янв', 'Фев', 'Мар', 'Апр', 'Май', 'Июнь', 'Июль', 'Авг', 'Сен', 'Окт', 'Ноя', 'Дек'],\n pt: ['Jan', 'Fev', 'Mar', 'Abr', 'Mai', 'Jun', 'Jul', 'Ago', 'Set', 'Out', 'Nov', 'Dez'],\n nl: ['Jan', 'Feb', 'Maa', 'Apr', 'Mei', 'Jun', 'Jul', 'Aug', 'Sep', 'Okt', 'Nov', 'Dec'],\n fr: ['Jan', 'Fév', 'Mar', 'Avr', 'Mai', 'Jui', 'Jui', 'Aoû', 'Sep', 'Oct', 'Nov', 'Déc'],\n it: ['Gen', 'Feb', 'Mar', 'Apr', 'Mag', 'Giu', 'Lug', 'Ago', 'Set', 'Ott', 'Nov', 'Dic'],\n es: ['Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic'],\n pl: ['Sty', 'Lut', 'Mar', 'Kwi', 'Maj', 'Cze', 'Lip', 'Sie', 'Wrz', 'Paź', 'Lis', 'Gru'],\n uk: ['Січ', 'Лют', 'Бер', 'Кві', 'Тра', 'Чер', 'Лип', 'Сер', 'Вер', 'Жов', 'Лис', 'Гру'],\n 'zh-cn': ['1月', '2月', '3月', '4月', '5月', '6月', '7月', '8月', '9月', '10月', '11月', '12月'],\n};\n\nexport type AstroEvent =\n | 'sunrise'\n | 'sunset'\n | 'sunriseEnd'\n | 'sunsetStart'\n | 'dawn'\n | 'dusk'\n | 'nauticalDawn'\n | 'nauticalDusk'\n | 'nadir'\n | 'nightEnd'\n | 'night'\n | 'goldenHourEnd'\n | 'goldenHour'\n | 'solarNoon';\n\nexport const astroList: AstroEvent[] = [\n 'sunrise',\n 'sunset',\n 'sunriseEnd',\n 'sunsetStart',\n 'dawn',\n 'dusk',\n 'nauticalDawn',\n 'nauticalDusk',\n 'nadir',\n 'nightEnd',\n 'night',\n 'goldenHourEnd',\n 'goldenHour',\n 'solarNoon',\n];\nexport const astroListLow = astroList.map(str => str.toLowerCase());\n"]} \ No newline at end of file diff --git a/build-backend/lib/convert.js b/build-backend/lib/convert.js new file mode 100644 index 00000000..5da830d7 --- /dev/null +++ b/build-backend/lib/convert.js @@ -0,0 +1,120 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.stringify = stringify; +exports.parse = parse; +// controller uses this file when build uploads +function stringify(data) { + const obj = data.data; + let id = data.id; + let result; + if (data.data.type === 'channel') { + id = `${id.replace(/\./g, '/').substring('script.js.'.length)}/_dir.json`; + result = JSON.stringify(obj, null, 2); + } + else if (data.data.type === 'script') { + id = `${id.replace(/\./g, '/').substring('script.js.'.length)}.json`; + if (obj.common?.source) { + const source = obj.common.source; + if (obj.common.enabled) { + // @ts-expect-error We do not use it + delete obj.common.enabled; + } + if (obj.common.engine === 'system.adapter.javascript.0') { + // @ts-expect-error We do not use it + delete obj.common.engine; + } + if (obj.common.engineType === 'Javascript/js') { + // @ts-expect-error We do not use it + delete obj.common.engineType; + } + // @ts-expect-error We do not use it + delete obj.common.name; + // @ts-expect-error We do not use it + delete obj.common.source; + if (JSON.stringify(obj.common) !== '{}') { + result = `/* -- do not edit following lines - START --\n${JSON.stringify(obj.common, null, 2)}\n-- do not edit previous lines - END --*/\n${source}`; + } + else { + result = source; + } + } + else { + result = JSON.stringify(obj, null, 2); + } + } + return { id, data: result }; +} +function parse(data) { + let obj = data.data; + let id = data.id; + let error; + let name; + let result; + if (id[id.length - 1] === '/') { + id = id.substring(0, id.length - 1); + } + if (!id.match(/\.json$/)) { + return null; + } + if (id.match(/_dir\.json$/)) { + name = id.substring(0, id.length - '/_dir.json'.length).replace(/\//g, '.'); + try { + result = JSON.parse(obj); + } + catch (err) { + error = `Cannot parse object "${name}": ${err}`; + result = { + common: { + name: name.split('.').pop() || name, + }, + type: 'channel', + _id: `script.js.${name}`, + native: {}, + }; + } + id = `script.js.${name}`; + } + else { + //script + name = id.substring(0, id.length - '.json'.length).replace(/\//g, '.'); + let source; + if (obj.match(/^\/\*\s--\sdo\snot/)) { + obj = obj.replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + const lines = obj.split('\n'); + let stringObj = ''; + let line = 1; + while (line < lines.length) { + if (lines[line].match(/^--\sdo\snot/)) { + break; + } + stringObj += lines[line]; + line++; + } + lines.splice(0, line + 1); + source = lines.join('\n'); + try { + result = {}; + result.common = JSON.parse(stringObj); + result.common.source = source; + } + catch (err) { + error = `Cannot parse object "${id}": ${err}`; + } + } + else { + source = obj; + } + result = {}; + result.common = result.common || {}; + result._id = `script.js.${name}`; + result.type = 'script'; + result.common.name = name.split('.').pop() || name; + result.common.enabled = result.common.enabled === undefined ? true : result.common.enabled; + result.common.engine = result.common.engine || 'system.adapter.javascript.0'; + result.common.engineType = result.common.engineType || 'Javascript/js'; + result.common.source = result.common.source || source; + id = `script.js.${name}`; + } + return { id: id, data: result, error: error }; +} +//# sourceMappingURL=convert.js.map \ No newline at end of file diff --git a/build-backend/lib/convert.js.map b/build-backend/lib/convert.js.map new file mode 100644 index 00000000..b6cd954a --- /dev/null +++ b/build-backend/lib/convert.js.map @@ -0,0 +1 @@ +{"version":3,"file":"convert.js","sourceRoot":"","sources":["../../src/lib/convert.ts"],"names":[],"mappings":";;AACA,8BAyCC;AAED,sBA2EC;AAvHD,+CAA+C;AAC/C,SAAgB,SAAS,CAAC,IAA0E;IAIhG,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC;IACtB,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;IACjB,IAAI,MAA0B,CAAC;IAC/B,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC/B,EAAE,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,YAAY,CAAC;QAC1E,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;IAC1C,CAAC;SAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,EAAE,GAAG,GAAG,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,OAAO,CAAC;QACrE,IAAK,GAA6B,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC;YAChD,MAAM,MAAM,GAAI,GAA6B,CAAC,MAAM,CAAC,MAAM,CAAC;YAC5D,IAAK,GAA6B,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBAChD,oCAAoC;gBACpC,OAAQ,GAA6B,CAAC,MAAM,CAAC,OAAO,CAAC;YACzD,CAAC;YACD,IAAK,GAA6B,CAAC,MAAM,CAAC,MAAM,KAAK,6BAA6B,EAAE,CAAC;gBACjF,oCAAoC;gBACpC,OAAQ,GAA6B,CAAC,MAAM,CAAC,MAAM,CAAC;YACxD,CAAC;YACD,IAAK,GAA6B,CAAC,MAAM,CAAC,UAAU,KAAK,eAAe,EAAE,CAAC;gBACvE,oCAAoC;gBACpC,OAAQ,GAA6B,CAAC,MAAM,CAAC,UAAU,CAAC;YAC5D,CAAC;YACD,oCAAoC;YACpC,OAAQ,GAA6B,CAAC,MAAM,CAAC,IAAI,CAAC;YAClD,oCAAoC;YACpC,OAAQ,GAA6B,CAAC,MAAM,CAAC,MAAM,CAAC;YACpD,IAAI,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,KAAK,IAAI,EAAE,CAAC;gBACtC,MAAM,GAAG,iDAAiD,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,+CAA+C,MAAM,EAAE,CAAC;YACzJ,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,MAAM,CAAC;YACpB,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC;QAC1C,CAAC;IACL,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAChC,CAAC;AAED,SAAgB,KAAK,CAAC,IAGrB;IACG,IAAI,GAAG,GAAW,IAAI,CAAC,IAAI,CAAC;IAC5B,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;IACjB,IAAI,KAAyB,CAAC;IAC9B,IAAI,IAAY,CAAC;IACjB,IAAI,MAAmC,CAAC;IACxC,IAAI,EAAE,CAAC,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;QAC5B,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACxC,CAAC;IAED,IAAI,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,IAAI,EAAE,CAAC,KAAK,CAAC,aAAa,CAAC,EAAE,CAAC;QAC1B,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QAE5E,IAAI,CAAC;YACD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,KAAK,GAAG,wBAAwB,IAAI,MAAM,GAAY,EAAE,CAAC;YACzD,MAAM,GAAG;gBACL,MAAM,EAAE;oBACJ,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI;iBACtC;gBACD,IAAI,EAAE,SAAS;gBACf,GAAG,EAAE,aAAa,IAAI,EAAE;gBACxB,MAAM,EAAE,EAAE;aACb,CAAC;QACN,CAAC;QACD,EAAE,GAAG,aAAa,IAAI,EAAE,CAAC;IAC7B,CAAC;SAAM,CAAC;QACJ,QAAQ;QACR,IAAI,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACvE,IAAI,MAAc,CAAC;QACnB,IAAI,GAAG,CAAC,KAAK,CAAC,oBAAoB,CAAC,EAAE,CAAC;YAClC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YACtD,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC9B,IAAI,SAAS,GAAG,EAAE,CAAC;YACnB,IAAI,IAAI,GAAG,CAAC,CAAC;YACb,OAAO,IAAI,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;gBACzB,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,cAAc,CAAC,EAAE,CAAC;oBACpC,MAAM;gBACV,CAAC;gBACD,SAAS,IAAI,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzB,IAAI,EAAE,CAAC;YACX,CAAC;YACD,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,CAAC,CAAC;YAC1B,MAAM,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,IAAI,CAAC;gBACD,MAAM,GAAG,EAAqB,CAAC;gBAC/B,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;gBACtC,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC;YAClC,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACpB,KAAK,GAAG,wBAAwB,EAAE,MAAM,GAAY,EAAE,CAAC;YAC3D,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,GAAG,CAAC;QACjB,CAAC;QACD,MAAM,GAAG,EAAqB,CAAC;QAC/B,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;QACpC,MAAM,CAAC,GAAG,GAAG,aAAa,IAAI,EAAE,CAAC;QACjC,MAAM,CAAC,IAAI,GAAG,QAAQ,CAAC;QACvB,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC;QACnD,MAAM,CAAC,MAAM,CAAC,OAAO,GAAG,MAAM,CAAC,MAAM,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QAC3F,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,6BAA6B,CAAC;QAC7E,MAAM,CAAC,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,UAAU,IAAI,eAAe,CAAC;QACvE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC;QACtD,EAAE,GAAG,aAAa,IAAI,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAA+B,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC3E,CAAC","sourcesContent":["// controller uses this file when build uploads\nexport function stringify(data: { data: ioBroker.ScriptObject | ioBroker.ChannelObject; id: string }): {\n id: string;\n data: string | undefined;\n} {\n const obj = data.data;\n let id = data.id;\n let result: string | undefined;\n if (data.data.type === 'channel') {\n id = `${id.replace(/\\./g, '/').substring('script.js.'.length)}/_dir.json`;\n result = JSON.stringify(obj, null, 2);\n } else if (data.data.type === 'script') {\n id = `${id.replace(/\\./g, '/').substring('script.js.'.length)}.json`;\n if ((obj as ioBroker.ScriptObject).common?.source) {\n const source = (obj as ioBroker.ScriptObject).common.source;\n if ((obj as ioBroker.ScriptObject).common.enabled) {\n // @ts-expect-error We do not use it\n delete (obj as ioBroker.ScriptObject).common.enabled;\n }\n if ((obj as ioBroker.ScriptObject).common.engine === 'system.adapter.javascript.0') {\n // @ts-expect-error We do not use it\n delete (obj as ioBroker.ScriptObject).common.engine;\n }\n if ((obj as ioBroker.ScriptObject).common.engineType === 'Javascript/js') {\n // @ts-expect-error We do not use it\n delete (obj as ioBroker.ScriptObject).common.engineType;\n }\n // @ts-expect-error We do not use it\n delete (obj as ioBroker.ScriptObject).common.name;\n // @ts-expect-error We do not use it\n delete (obj as ioBroker.ScriptObject).common.source;\n if (JSON.stringify(obj.common) !== '{}') {\n result = `/* -- do not edit following lines - START --\\n${JSON.stringify(obj.common, null, 2)}\\n-- do not edit previous lines - END --*/\\n${source}`;\n } else {\n result = source;\n }\n } else {\n result = JSON.stringify(obj, null, 2);\n }\n }\n\n return { id, data: result };\n}\n\nexport function parse(data: {\n data: string;\n id: string;\n}): { id: string; data: ioBroker.ScriptObject; error: string | undefined } | null {\n let obj: string = data.data;\n let id = data.id;\n let error: string | undefined;\n let name: string;\n let result: ioBroker.Object | undefined;\n if (id[id.length - 1] === '/') {\n id = id.substring(0, id.length - 1);\n }\n\n if (!id.match(/\\.json$/)) {\n return null;\n }\n\n if (id.match(/_dir\\.json$/)) {\n name = id.substring(0, id.length - '/_dir.json'.length).replace(/\\//g, '.');\n\n try {\n result = JSON.parse(obj);\n } catch (err: unknown) {\n error = `Cannot parse object \"${name}\": ${err as Error}`;\n result = {\n common: {\n name: name.split('.').pop() || name,\n },\n type: 'channel',\n _id: `script.js.${name}`,\n native: {},\n };\n }\n id = `script.js.${name}`;\n } else {\n //script\n name = id.substring(0, id.length - '.json'.length).replace(/\\//g, '.');\n let source: string;\n if (obj.match(/^\\/\\*\\s--\\sdo\\snot/)) {\n obj = obj.replace(/\\r\\n/g, '\\n').replace(/\\r/g, '\\n');\n const lines = obj.split('\\n');\n let stringObj = '';\n let line = 1;\n while (line < lines.length) {\n if (lines[line].match(/^--\\sdo\\snot/)) {\n break;\n }\n stringObj += lines[line];\n line++;\n }\n lines.splice(0, line + 1);\n source = lines.join('\\n');\n try {\n result = {} as ioBroker.Object;\n result.common = JSON.parse(stringObj);\n result.common.source = source;\n } catch (err: unknown) {\n error = `Cannot parse object \"${id}\": ${err as Error}`;\n }\n } else {\n source = obj;\n }\n result = {} as ioBroker.Object;\n result.common = result.common || {};\n result._id = `script.js.${name}`;\n result.type = 'script';\n result.common.name = name.split('.').pop() || name;\n result.common.enabled = result.common.enabled === undefined ? true : result.common.enabled;\n result.common.engine = result.common.engine || 'system.adapter.javascript.0';\n result.common.engineType = result.common.engineType || 'Javascript/js';\n result.common.source = result.common.source || source;\n id = `script.js.${name}`;\n }\n\n return { id: id, data: result as ioBroker.ScriptObject, error: error };\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/debug.js b/build-backend/lib/debug.js new file mode 100644 index 00000000..ab0dfcee --- /dev/null +++ b/build-backend/lib/debug.js @@ -0,0 +1,163 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const node_child_process_1 = require("node:child_process"); +const adapter = { + log: { + error: (text) => console.error(text), + info: (text) => console.log(text), + warn: (text) => console.warn(text), + debug: (text) => console.log(text), + }, + setState: (id, val) => { + try { + val = JSON.parse(val); + } + catch (e) { + console.error(e); + } + console.log(`FROM: ${JSON.stringify(val)}`); + }, + extendForeignObjectAsync: (id, obj) => { + console.log(`EXTEND: ${id} ${JSON.stringify(obj)}`); + return Promise.resolve(); + }, +}; +const context = { + objects: {}, +}; +const debugState = { + scriptName: '', + child: null, + promiseOnEnd: null, + paused: false, + endTimeout: null, + running: false, + breakOnStart: false, + started: 0, +}; +function stopDebug() { + if (debugState.child) { + sendToInspector({ cmd: 'end' }); + debugState.endTimeout = setTimeout(() => { + debugState.endTimeout = null; + debugState.child?.kill('SIGTERM'); + }); + debugState.promiseOnEnd = debugState.promiseOnEnd || Promise.resolve(0); + } + else { + debugState.promiseOnEnd = Promise.resolve(0); + } + return debugState.promiseOnEnd.then(() => { + debugState.child = null; + debugState.running = false; + debugState.scriptName = ''; + if (debugState.endTimeout) { + clearTimeout(debugState.endTimeout); + debugState.endTimeout = null; + } + }); +} +function disableScript(id) { + const obj = context.objects[id]; + if (obj?.common?.enabled) { + return adapter.extendForeignObjectAsync(obj._id, { + common: { enabled: false }, + }); + } + return Promise.resolve(); +} +function sendToInspector(message) { + if (typeof message === 'string') { + try { + message = JSON.parse(message); + } + catch { + adapter.log.error(`Cannot parse message to inspector: ${JSON.stringify(message)}`); + return adapter.setState('debug.from', JSON.stringify({ error: 'Cannot parse message to inspector' })); + } + } + if (debugState.child) { + debugState.child.send(JSON.stringify(message)); + } + else { + adapter.log.error(`Cannot send command to terminated inspector`); + return adapter.setState('debug.from', JSON.stringify({ error: `Cannot send command to terminated inspector` })); + } +} +/* +function childPrint(text: string): void { + console.log( + text + .toString() + .split(/\r\n|\r|\n/g) + .filter(chunk => !!chunk) + .map(chunk => `< ${chunk}`) + .join('\n'), + ); +} +*/ +function debugScript(data) { + // stop a script if it is running + return disableScript(data.scriptName) + .then(() => stopDebug()) + .then(() => { + debugState.scriptName = data.scriptName; + debugState.breakOnStart = data.breakOnStart; + const options = { + stdio: ['ignore', 'inherit', 'inherit', 'ipc'], + }; + debugState.child = (0, node_child_process_1.fork)(`${__dirname}/../inspect.js`, [], options); + /* + debugState.child.stdout.setEncoding('utf8'); + debugState.child.stderr.setEncoding('utf8'); + debugState.child.stdout.on('data', childPrint); + debugState.child.stderr.on('data', childPrint); + */ + debugState.child.on('message', (message) => { + let debugMessage; + try { + debugMessage = JSON.parse(message); + } + catch { + return adapter.log.error(`Cannot parse message from inspector: ${message}`); + } + adapter.setState('debug.from', JSON.stringify(debugMessage)); + switch (debugMessage.cmd) { + case 'ready': { + debugState.child?.send(JSON.stringify({ cmd: 'start', scriptName: debugState.scriptName })); + break; + } + case 'watched': { + console.log(`WATCHED: ${JSON.stringify(debugMessage)}`); + break; + } + case 'paused': { + debugState.paused = true; + console.log(`PAUSED`); + break; + } + case 'resumed': { + debugState.paused = false; + console.log(`STARTED`); + break; + } + case 'log': { + console.log(`[${debugMessage.severity}] ${debugMessage.text}`); + break; + } + case 'readyToDebug': { + console.log(`readyToDebug (set breakpoints): [${debugMessage.scriptId}] ${debugMessage.script}`); + break; + } + } + }); + }); +} +debugScript({ scriptName: 'script.js.Skript_1' }) + .then(() => { + console.log('Debugging started'); +}) + .catch(e => { + console.error(e); +}); +//# sourceMappingURL=debug.js.map \ No newline at end of file diff --git a/build-backend/lib/debug.js.map b/build-backend/lib/debug.js.map new file mode 100644 index 00000000..b38f4f69 --- /dev/null +++ b/build-backend/lib/debug.js.map @@ -0,0 +1 @@ +{"version":3,"file":"debug.js","sourceRoot":"","sources":["../../src/lib/debug.ts"],"names":[],"mappings":"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","sourcesContent":["import { fork, type ForkOptions } from 'node:child_process';\nimport type { DebugState } from '../types';\n\nconst adapter = {\n log: {\n error: (text: string) => console.error(text),\n info: (text: string) => console.log(text),\n warn: (text: string) => console.warn(text),\n debug: (text: string) => console.log(text),\n },\n setState: (id: string, val: any): void => {\n try {\n val = JSON.parse(val);\n } catch (e) {\n console.error(e);\n }\n console.log(`FROM: ${JSON.stringify(val)}`);\n },\n extendForeignObjectAsync: (id: string, obj: Partial) => {\n console.log(`EXTEND: ${id} ${JSON.stringify(obj)}`);\n return Promise.resolve();\n },\n};\nconst context: {\n objects: Record;\n} = {\n objects: {},\n};\n\nconst debugState: DebugState = {\n scriptName: '',\n child: null,\n promiseOnEnd: null,\n paused: false,\n endTimeout: null,\n running: false,\n breakOnStart: false,\n started: 0,\n};\n\nfunction stopDebug(): Promise {\n if (debugState.child) {\n sendToInspector({ cmd: 'end' });\n debugState.endTimeout = setTimeout(() => {\n debugState.endTimeout = null;\n debugState.child?.kill('SIGTERM');\n });\n debugState.promiseOnEnd = debugState.promiseOnEnd || Promise.resolve(0);\n } else {\n debugState.promiseOnEnd = Promise.resolve(0);\n }\n\n return debugState.promiseOnEnd.then(() => {\n debugState.child = null;\n debugState.running = false;\n debugState.scriptName = '';\n if (debugState.endTimeout) {\n clearTimeout(debugState.endTimeout);\n debugState.endTimeout = null;\n }\n });\n}\n\nfunction disableScript(id: string): Promise {\n const obj = context.objects[id];\n if (obj?.common?.enabled) {\n return adapter.extendForeignObjectAsync(obj._id, {\n common: { enabled: false },\n } as Partial);\n }\n return Promise.resolve();\n}\n\nfunction sendToInspector(message: string | Record): void {\n if (typeof message === 'string') {\n try {\n message = JSON.parse(message);\n } catch {\n adapter.log.error(`Cannot parse message to inspector: ${JSON.stringify(message)}`);\n return adapter.setState('debug.from', JSON.stringify({ error: 'Cannot parse message to inspector' }));\n }\n }\n\n if (debugState.child) {\n debugState.child.send(JSON.stringify(message));\n } else {\n adapter.log.error(`Cannot send command to terminated inspector`);\n return adapter.setState('debug.from', JSON.stringify({ error: `Cannot send command to terminated inspector` }));\n }\n}\n/*\nfunction childPrint(text: string): void {\n console.log(\n text\n .toString()\n .split(/\\r\\n|\\r|\\n/g)\n .filter(chunk => !!chunk)\n .map(chunk => `< ${chunk}`)\n .join('\\n'),\n );\n}\n*/\n\nfunction debugScript(data: { breakOnStart?: boolean; scriptName: string }): Promise {\n // stop a script if it is running\n\n return disableScript(data.scriptName)\n .then(() => stopDebug())\n .then(() => {\n debugState.scriptName = data.scriptName;\n debugState.breakOnStart = data.breakOnStart;\n\n const options: ForkOptions = {\n stdio: ['ignore', 'inherit', 'inherit', 'ipc'],\n };\n\n debugState.child = fork(`${__dirname}/../inspect.js`, [], options);\n\n /*\n debugState.child.stdout.setEncoding('utf8');\n debugState.child.stderr.setEncoding('utf8');\n debugState.child.stdout.on('data', childPrint);\n debugState.child.stderr.on('data', childPrint);\n */\n\n debugState.child.on('message', (message: string): void => {\n let debugMessage: {\n severity: string;\n text: string;\n cmd: string;\n scriptId: string;\n script: string;\n };\n try {\n debugMessage = JSON.parse(message);\n } catch {\n return adapter.log.error(`Cannot parse message from inspector: ${message}`);\n }\n\n adapter.setState('debug.from', JSON.stringify(debugMessage));\n\n switch (debugMessage.cmd) {\n case 'ready': {\n debugState.child?.send(JSON.stringify({ cmd: 'start', scriptName: debugState.scriptName }));\n break;\n }\n\n case 'watched': {\n console.log(`WATCHED: ${JSON.stringify(debugMessage)}`);\n break;\n }\n\n case 'paused': {\n debugState.paused = true;\n console.log(`PAUSED`);\n break;\n }\n\n case 'resumed': {\n debugState.paused = false;\n console.log(`STARTED`);\n break;\n }\n\n case 'log': {\n console.log(`[${debugMessage.severity}] ${debugMessage.text}`);\n break;\n }\n\n case 'readyToDebug': {\n console.log(\n `readyToDebug (set breakpoints): [${debugMessage.scriptId}] ${debugMessage.script}`,\n );\n break;\n }\n }\n });\n });\n}\n\ndebugScript({ scriptName: 'script.js.Skript_1' })\n .then(() => {\n console.log('Debugging started');\n })\n .catch(e => {\n console.error(e);\n });\n"]} \ No newline at end of file diff --git a/build-backend/lib/debugger.js b/build-backend/lib/debugger.js new file mode 100644 index 00000000..e6c5369e --- /dev/null +++ b/build-backend/lib/debugger.js @@ -0,0 +1,1141 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.default = createRepl; +/* + * Copyright Node.js contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +const node_path_1 = require("node:path"); +const repl_1 = require("repl"); +const node_util_1 = require("node:util"); +const node_vm_1 = require("node:vm"); +const node_url_1 = require("node:url"); +const node_module_1 = require("node:module"); +const debuglog = (0, node_util_1.debuglog)('inspect'); +/*const SHORTCUTS = { + cont: 'c', + next: 'n', + step: 's', + out: 'o', + backtrace: 'bt', + setBreakpoint: 'sb', + clearBreakpoint: 'cb', + run: 'r', +}; + +const HELP = ` +run, restart, r Run the application or reconnect +kill Kill a running application or disconnect + +cont, c Resume execution +next, n Continue to next line in current file +step, s Step into, potentially entering a function +out, o Step out, leaving the current function +backtrace, bt Print the current backtrace +list Print the source around the current line where execution + is currently paused + +setBreakpoint, sb Set a breakpoint +clearBreakpoint, cb Clear a breakpoint +breakpoints List all known breakpoints +breakOnException Pause execution whenever an exception is thrown +breakOnUncaught Pause execution whenever an exception isn't caught +breakOnNone Don't pause on exceptions (this is the default) + +watch(expr) Start watching the given expression +unwatch(expr) Stop watching an expression +watchers Print all watched expressions and their current values + +exec(expr) Evaluate the expression and print the value +repl Enter a debug repl that works like exec + +scripts List application scripts that are currently loaded +scripts(true) List all scripts (including node-internals) + +profile Start CPU profiling session. +profileEnd Stop current CPU profiling session. +profiles Array of completed CPU profiling sessions. +profiles[n].save(filepath = 'node.cpuprofile') + Save CPU profiling session to disk as JSON. + +takeHeapSnapshot(filepath = 'node.heapsnapshot') + Take a heap snapshot and save to disk as JSON. +`.trim();*/ +const FUNCTION_NAME_PATTERN = /^(?:function\*? )?([^(\s]+)\(/; +function extractFunctionName(description) { + const fnNameMatch = description?.match(FUNCTION_NAME_PATTERN); + return fnNameMatch ? `: ${fnNameMatch[1]}` : ''; +} +// process.binding is a method available on the process object, which allows you to load internal modules written in C++ +// @ts-expect-error binding is internal function +const NATIVES = node_module_1.builtinModules ? process.binding('natives') : {}; +function isNativeUrl(url) { + url = url.replace(/\.js$/, ''); + if (node_module_1.builtinModules) { + if (url.startsWith('internal/') || node_module_1.builtinModules.includes(url)) { + return true; + } + } + return url in NATIVES || url === 'bootstrap_node'; +} +function getRelativePath(filenameOrURL) { + const dir = (0, node_path_1.join)((0, node_path_1.resolve)(), 'x').slice(0, -1); + const filename = filenameOrURL.startsWith('file://') ? (0, node_url_1.fileURLToPath)(filenameOrURL) : filenameOrURL; + // Change a path to relative, if possible + if (filename.indexOf(dir) === 0) { + return filename.slice(dir.length); + } + return filename; +} +function toCallback(promise, callback) { + function forward(...args) { + process.nextTick(() => callback(...args)); + } + promise.then(forward.bind(null, null), forward); +} +// Adds spaces and prefix to number +// maxN is a maximum number we should have space for +function leftPad(n, prefix, maxN) { + const s = n.toString(); + const nchars = Math.max(2, String(maxN).length) + 1; + const nspaces = nchars - s.length - 1; + return prefix + ' '.repeat(nspaces) + s; +} +function markSourceColumn(sourceText, position, useColors) { + if (!sourceText) { + return ''; + } + const head = sourceText.slice(0, position); + let tail = sourceText.slice(position); + // Colorize char if stdout supports colours + if (useColors) { + tail = tail.replace(/(.+?)([^\w]|$)/, '\u001b[32m$1\u001b[39m$2'); + } + // Return source line with coloured char at `position` + return [head, tail].join(''); +} +function extractErrorMessage(stack) { + if (!stack) { + return ''; + } + const m = stack.match(/^\w+: ([^\n]+)/); + return m ? m[1] : stack; +} +function convertResultToError(result) { + const { className, description } = result; + const err = new Error(extractErrorMessage(description)); + err.stack = description; + Object.defineProperty(err, 'name', { value: className }); + return err; +} +class RemoteObject { + type; + subtype; + className; + value; + unserializableValue; + description; + objectId; + preview; + customPreview; + constructor(attributes) { + this.type = 'undefined'; + Object.assign(this, attributes); + if (this.type === 'number') { + this.value = this.unserializableValue ? +this.unserializableValue : +this.value; + } + } + [node_util_1.inspect.custom](_depth, opts) { + function formatProperty(prop) { + switch (prop.type) { + case 'string': + case 'undefined': + return (0, node_util_1.inspect)(prop.value, opts); + case 'number': + case 'boolean': + return opts.stylize(prop.value, prop.type); + case 'object': + case 'symbol': + if (prop.subtype === 'date') { + return (0, node_util_1.inspect)(new Date(prop.value), opts); + } + if (prop.subtype === 'array') { + return opts.stylize(prop.value, 'special'); + } + return opts.stylize(prop.value, prop.subtype || 'special'); + default: + return prop.value; + } + } + switch (this.type) { + case 'boolean': + case 'number': + case 'string': + case 'undefined': + return (0, node_util_1.inspect)(this.value, opts); + case 'symbol': + return opts.stylize(this.description, 'special'); + case 'function': { + const fnName = extractFunctionName(this.description); + const formatted = `[${this.className}${fnName}]`; + return opts.stylize(formatted, 'special'); + } + case 'object': + switch (this.subtype) { + case 'date': + return (0, node_util_1.inspect)(new Date(this.description), opts); + case 'null': + return (0, node_util_1.inspect)(null, opts); + case 'regexp': + return opts.stylize(this.description, 'regexp'); + default: + break; + } + if (this.preview) { + const props = this.preview.properties.map((prop, idx) => { + const value = formatProperty(prop); + if (prop.name === `${idx}`) { + return value; + } + return `${prop.name}: ${value}`; + }); + if (this.preview.overflow) { + props.push('...'); + } + const singleLine = props.join(', '); + const propString = singleLine.length > 60 ? props.join(',\n ') : singleLine; + return this.subtype === 'array' ? `[ ${propString} ]` : `{ ${propString} }`; + } + return this.description || ''; + default: + return this.description || ''; + } + } + static fromEvalResult({ result, wasThrown }) { + if (wasThrown) { + return convertResultToError(result); + } + return new RemoteObject(result); + } +} +class ScopeSnapshot { + /** + * Scope type. + */ + type; + /** + * Object representing the scope. For global and with scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties. + */ + object; + name; + /** + * Location in the source code where scope starts + */ + startLocation; + /** + * Location in the source code where scope ends + */ + endLocation; + properties; + completionGroup; + constructor(scope, properties) { + this.type = scope.type; + this.object = scope.object; + Object.assign(this, scope); + this.properties = new Map(properties.map(prop => { + const value = new RemoteObject(prop.value); + return [prop.name, value]; + })); + this.completionGroup = properties.map(prop => prop.name); + } + [node_util_1.inspect.custom](_depth, opts) { + const type = `${this.type[0].toUpperCase()}${this.type.slice(1)}`; + const name = this.name ? `<${this.name}>` : ''; + const prefix = `${type}${name} `; + return (0, node_util_1.inspect)(this.properties, opts).replace(/^Map /, prefix); + } +} +/* +function copyOwnProperties(target: any, source: any): void { + Object.getOwnPropertyNames(source).forEach(prop => { + const descriptor = Object.getOwnPropertyDescriptor(source, prop); + if (descriptor) { + Object.defineProperty(target, prop, descriptor); + } + }); +} + +function aliasProperties(target, mapping) { + Object.keys(mapping).forEach((key) => { + const descriptor = Object.getOwnPropertyDescriptor(target, key); + Object.defineProperty(target, mapping[key], descriptor); + }); +} +*/ +function createRepl(inspector) { + const { Debugger, /*HeapProfiler, Profiler,*/ Runtime } = inspector; + let repl; + // Things we want to keep around + // const history = { control: [], debug: [] }; + // const watchedExpressions = []; + // const knownBreakpoints = []; + // let pauseOnExceptionState = 'none'; + let lastCommand; + // Things we need to reset when the app restarts + let knownScripts = {}; + let currentBacktrace; + let selectedFrame; + let exitDebugRepl; + function resetOnStart() { + knownScripts = {}; + currentBacktrace = undefined; + selectedFrame = undefined; + if (exitDebugRepl) { + exitDebugRepl(); + } + exitDebugRepl = undefined; + } + resetOnStart(); + const INSPECT_OPTIONS = { colors: inspector.stdout.isTTY }; + function inspect(value) { + return (0, node_util_1.inspect)(value, INSPECT_OPTIONS); + } + function print(value, oneline = false) { + const text = typeof value === 'string' ? value : inspect(value); + return inspector.print(text, oneline); + } + function getCurrentLocation() { + if (!selectedFrame) { + throw new Error('Requires execution to be paused'); + } + return selectedFrame.location; + } + function isCurrentScript(script) { + return !!selectedFrame && getCurrentLocation().scriptId === script.scriptId; + } + function formatScripts(displayNatives = false) { + function isVisible(script) { + if (displayNatives) { + return true; + } + return !script.isNative || isCurrentScript(script); + } + return Object.keys(knownScripts) + .map(scriptId => knownScripts[scriptId]) + .filter(isVisible) + .map(script => { + const isCurrent = isCurrentScript(script); + const { isNative, url } = script; + const name = `${getRelativePath(url)}${isNative ? ' ' : ''}`; + return `${isCurrent ? '*' : ' '} ${script.scriptId}: ${name}`; + }) + .join('\n'); + } + function listScripts(displayNatives = false) { + print(formatScripts(displayNatives)); + } + // @ts-expect-error no idea what this is + listScripts[node_util_1.inspect.custom] = function listWithoutInternal() { + return formatScripts(); + }; + /* + const profiles = []; + class Profile { + constructor(data) { + this.data = data; + } + + static createAndRegister({ profile }) { + const p = new Profile(profile); + profiles.push(p); + return p; + } + + [util.inspect.custom](depth, { stylize }) { + const { startTime, endTime } = this.data; + return stylize(`[Profile ${endTime - startTime}μs]`, 'special'); + } + + save(filename = 'node.cpuprofile') { + const absoluteFile = Path.resolve(filename); + const json = JSON.stringify(this.data); + FS.writeFileSync(absoluteFile, json); + print('Saved profile to ' + absoluteFile); + } + } +*/ + class SourceSnippet { + scriptSource; + /** + * Script identifier as reported in the Debugger.scriptParsed. + */ + scriptId; + /** + * Line number in the script (0-based). + */ + lineNumber; + /** + * Column number in the script (0-based). + */ + columnNumber; + delta; + constructor(location, delta, scriptSource) { + this.lineNumber = location.lineNumber; + this.columnNumber = location.columnNumber || 0; + this.scriptId = location.scriptId; + this.scriptSource = scriptSource; + this.delta = delta; + Object.assign(this, location); + } + [node_util_1.inspect.custom](_depth, options) { + const { /* scriptId, */ lineNumber, columnNumber, delta, scriptSource } = this; + const start = Math.max(1, lineNumber - delta + 1); + const end = lineNumber + delta + 1; + const lines = scriptSource.split('\n'); + return lines + .slice(start - 1, end) + .map((lineText, offset) => { + const i = start + offset; + const isCurrent = i === lineNumber + 1; + const markedLine = isCurrent ? markSourceColumn(lineText, columnNumber, options.colors) : lineText; + /* + let isBreakpoint = false; + knownBreakpoints.forEach(({ location }) => { + if (!location) return; + if (scriptId === location.scriptId && + i === (location.lineNumber + 1)) { + isBreakpoint = true; + } + }); + */ + let prefixChar = ' '; + if (isCurrent) { + prefixChar = '>'; + } /*else if (isBreakpoint) { + prefixChar = '*'; + }*/ + return `${leftPad(i, prefixChar, end)} ${markedLine}`; + }) + .join('\n'); + } + } + function getSourceSnippet(location, delta = 5) { + const { scriptId } = location; + return Debugger.getScriptSource({ scriptId }).then(({ scriptSource }) => new SourceSnippet(location, delta, scriptSource)); + } + class CallFrame { + /** + * Call frame identifier. This identifier is only valid while the virtual machine is paused. + */ + callFrameId; + /** + * Name of the JavaScript function called on this call frame. + */ + functionName; + /** + * Location in the source code. + */ + functionLocation; + /** + * Location in the source code. + */ + location; + /** + * JavaScript script name or url. + */ + url; + /** + * Scope chain for this call frame. + */ + scopeChain; + /** + * this object for this call frame. + */ + this; + /** + * The value being returned if the function is at return point. + */ + returnValue; + constructor(callFrame) { + this.functionName = callFrame.functionName; + this.url = callFrame.url; + this.scopeChain = callFrame.scopeChain; + this.this = callFrame.this; + this.returnValue = callFrame.returnValue; + this.location = callFrame.location; + this.callFrameId = callFrame.callFrameId; + Object.assign(this, callFrame); + } + loadScopes() { + return Promise.all(this.scopeChain + .filter(scope => scope.type !== 'global') + .map(scope => { + const { objectId } = scope.object; + return Runtime.getProperties({ + objectId, + generatePreview: true, + }).then(({ result }) => { + return new ScopeSnapshot(scope, result); + }); + })); + } + list(delta = 5) { + return getSourceSnippet(this.location, delta); + } + } + class Backtrace extends Array { + [node_util_1.inspect.custom]() { + return this.map((callFrame, idx) => { + const { location: { scriptId, lineNumber, columnNumber }, functionName, } = callFrame; + const name = functionName || '(anonymous)'; + const script = knownScripts[scriptId]; + const relativeUrl = (script && getRelativePath(script.url)) || ''; + const frameLocation = `${relativeUrl}:${lineNumber + 1}:${columnNumber}`; + return `#${idx} ${name} ${frameLocation}`; + }).join('\n'); + } + static from(callFrames) { + return super.from(Array.from(callFrames).map(callFrame => { + if (callFrame instanceof CallFrame) { + return callFrame; + } + return new CallFrame(callFrame); + })); + } + } + function prepareControlCode(input) { + if (input === '\n') { + return lastCommand; + } + // exec process.title => exec("process.title"); + const match = input.match(/^\s*exec\s+([^\n]*)/); + if (match) { + lastCommand = `exec(${JSON.stringify(match[1])})`; + } + else { + lastCommand = input; + } + return lastCommand; + } + // function evalInCurrentContext(code) { + // // Repl asked for scope variables + // if (code === '.scope') { + // if (!selectedFrame) { + // return Promise.reject(new Error('Requires execution to be paused')); + // } + // return selectedFrame.loadScopes().then((scopes) => { + // return scopes.map((scope) => scope.completionGroup); + // }); + // } + // + // if (selectedFrame) { + // return Debugger.evaluateOnCallFrame({ + // callFrameId: selectedFrame.callFrameId, + // expression: code, + // objectGroup: 'node-inspect', + // generatePreview: true, + // }).then(RemoteObject.fromEvalResult); + // } + // return Runtime.evaluate({ + // expression: code, + // objectGroup: 'node-inspect', + // generatePreview: true, + // }).then(RemoteObject.fromEvalResult); + // } + function controlEval(input, context, filename, callback) { + debuglog('eval:', input); + function returnToCallback(error, result) { + debuglog('end-eval:', input, error); + callback(error, result); + } + try { + const code = prepareControlCode(input); + const result = (0, node_vm_1.runInContext)(code, context, filename); + if (result && typeof result.then === 'function') { + toCallback(result, returnToCallback); + return; + } + returnToCallback(null, result); + } + catch (e) { + returnToCallback(e); + } + } + // function debugEval(input, context, filename, callback) { + // debuglog('eval:', input); + // function returnToCallback(error, result) { + // debuglog('end-eval:', input, error); + // callback(error, result); + // } + // + // try { + // const result = evalInCurrentContext(input); + // + // if (result && typeof result.then === 'function') { + // toCallback(result, returnToCallback); + // return; + // } + // returnToCallback(null, result); + // } catch (e) { + // returnToCallback(e); + // } + // } + /*function formatWatchers(verbose = false) { + if (!watchedExpressions.length) { + return Promise.resolve(''); + } + + const inspectValue = (expr) => + evalInCurrentContext(expr) + // .then(formatValue) + .catch((error) => `<${error.message}>`); + const lastIndex = watchedExpressions.length - 1; + + return Promise.all(watchedExpressions.map(inspectValue)) + .then((values) => { + const lines = watchedExpressions + .map((expr, idx) => { + const prefix = `${leftPad(idx, ' ', lastIndex)}: ${expr} =`; + const value = inspect(values[idx], { colors: true }); + if (value.indexOf('\n') === -1) { + return `${prefix} ${value}`; + } + return `${prefix}\n ${value.split('\n').join('\n ')}`; + }); + return lines.join('\n'); + }) + .then((valueList) => { + return verbose ? `Watchers:\n${valueList}\n` : valueList; + }); + }*/ + //function watchers(verbose = false) { + // return formatWatchers(verbose).then(print); + //} + // List source code + // function list(delta = 5) { + // return selectedFrame.list(delta) + // .then(null, (error) => { + // print('You can\'t list source code right now'); + // throw error; + // }); + // } + //function handleBreakpointResolved({ breakpointId, location }) { + // const script = knownScripts[location.scriptId]; + // const scriptUrl = script && script.url; + // if (scriptUrl) { + // Object.assign(location, { scriptUrl }); + // } + // const isExisting = knownBreakpoints.some((bp) => { + // if (bp.breakpointId === breakpointId) { + // Object.assign(bp, { location }); + // return true; + // } + // return false; + // }); + // if (!isExisting) { + // knownBreakpoints.push({ breakpointId, location }); + // } + //} + // function listBreakpoints() { + // if (!knownBreakpoints.length) { + // print('No breakpoints yet'); + // return; + // } + // + // function formatLocation(location) { + // if (!location) return ''; + // const script = knownScripts[location.scriptId]; + // const scriptUrl = script ? script.url : location.scriptUrl; + // return `${getRelativePath(scriptUrl)}:${location.lineNumber + 1}`; + // } + // const breaklist = knownBreakpoints + // .map((bp, idx) => `#${idx} ${formatLocation(bp.location)}`) + // .join('\n'); + // print(breaklist); + // } + // function setBreakpoint(script, line, condition, silent) { + // function registerBreakpoint({ breakpointId, actualLocation }) { + // handleBreakpointResolved({ breakpointId, location: actualLocation }); + // if (actualLocation && actualLocation.scriptId) { + // if (!silent) return getSourceSnippet(actualLocation, 5); + // } else { + // print(`Warning: script '${script}' was not loaded yet.`); + // } + // return undefined; + // } + // + // // setBreakpoint(): set breakpoint at current location + // if (script === undefined) { + // return Debugger + // .setBreakpoint({ location: getCurrentLocation(), condition }) + // .then(registerBreakpoint); + // } + // + // // setBreakpoint(line): set breakpoint in current script at specific line + // if (line === undefined && typeof script === 'number') { + // const location = { + // scriptId: getCurrentLocation().scriptId, + // lineNumber: script - 1, + // }; + // return Debugger.setBreakpoint({ location, condition }) + // .then(registerBreakpoint); + // } + // + // if (typeof script !== 'string') { + // throw new TypeError(`setBreakpoint() expects a string, got ${script}`); + // } + // + // // setBreakpoint('fn()'): Break when a function is called + // if (script.endsWith('()')) { + // const debugExpr = `debug(${script.slice(0, -2)})`; + // const debugCall = selectedFrame + // ? Debugger.evaluateOnCallFrame({ + // callFrameId: selectedFrame.callFrameId, + // expression: debugExpr, + // includeCommandLineAPI: true, + // }) + // : Runtime.evaluate({ + // expression: debugExpr, + // includeCommandLineAPI: true, + // }); + // return debugCall.then(({ result, wasThrown }) => { + // if (wasThrown) return convertResultToError(result); + // return undefined; // This breakpoint can't be removed the same way + // }); + // } + // + // // setBreakpoint('scriptname') + // let scriptId = null; + // let ambiguous = false; + // if (knownScripts[script]) { + // scriptId = script; + // } else { + // for (const id of Object.keys(knownScripts)) { + // const scriptUrl = knownScripts[id].url; + // if (scriptUrl && scriptUrl.indexOf(script) !== -1) { + // if (scriptId !== null) { + // ambiguous = true; + // } + // scriptId = id; + // } + // } + // } + // + // if (ambiguous) { + // print('Script name is ambiguous'); + // return undefined; + // } + // if (line <= 0) { + // print('Line should be a positive value'); + // return undefined; + // } + // + // if (scriptId !== null) { + // const location = { scriptId, lineNumber: line - 1 }; + // return Debugger.setBreakpoint({ location, condition }) + // .then(registerBreakpoint); + // } + // + // const escapedPath = script.replace(/([/\\.?*()^${}|[\]])/g, '\\$1'); + // const urlRegex = `^(.*[\\/\\\\])?${escapedPath}$`; + // + // return Debugger + // .setBreakpointByUrl({ urlRegex, lineNumber: line - 1, condition }) + // .then((bp) => { + // // TODO: handle bp.locations in case the regex matches existing files + // if (!bp.location) { // Fake it for now. + // Object.assign(bp, { + // actualLocation: { + // scriptUrl: `.*/${script}$`, + // lineNumber: line - 1, + // }, + // }); + // } + // return registerBreakpoint(bp); + // }); + // } + // + // function clearBreakpoint(url, line) { + // const breakpoint = knownBreakpoints.find(({ location }) => { + // if (!location) return false; + // const script = knownScripts[location.scriptId]; + // if (!script) return false; + // return ( + // script.url.indexOf(url) !== -1 && (location.lineNumber + 1) === line + // ); + // }); + // if (!breakpoint) { + // print(`Could not find breakpoint at ${url}:${line}`); + // return Promise.resolve(); + // } + // return Debugger.removeBreakpoint({ breakpointId: breakpoint.breakpointId }) + // .then(() => { + // const idx = knownBreakpoints.indexOf(breakpoint); + // knownBreakpoints.splice(idx, 1); + // }); + // } + // + // function restoreBreakpoints() { + // const lastBreakpoints = knownBreakpoints.slice(); + // knownBreakpoints.length = 0; + // const newBreakpoints = lastBreakpoints + // .filter(({ location }) => !!location.scriptUrl) + // .map(({ location }) => + // setBreakpoint(location.scriptUrl, location.lineNumber + 1)); + // if (!newBreakpoints.length) return Promise.resolve(); + // return Promise.all(newBreakpoints).then((results) => { + // print(`${results.length} breakpoints restored.`); + // }); + // } + // function setPauseOnExceptions(state) { + // return Debugger.setPauseOnExceptions({ state }) + // .then(() => { + // pauseOnExceptionState = state; + // }); + // } + Debugger.on('paused', (data) => { + const callFrames = data.callFrames; + const reason = data.reason; + if (process.env.NODE_INSPECT_RESUME_ON_START === '1' && reason === 'Break on start') { + debuglog('Paused on start, but NODE_INSPECT_RESUME_ON_START environment variable is set to 1, resuming'); + inspector.client.callMethod('Debugger.resume'); + return; + } + // Save execution context's data + currentBacktrace = Backtrace.from(callFrames); + selectedFrame = currentBacktrace[0]; + const { scriptId, lineNumber } = selectedFrame.location; + const breakType = reason === 'other' ? 'break' : reason; + const script = knownScripts[scriptId]; + const scriptUrl = script ? getRelativePath(script.url) : '[unknown]'; + const header = `${breakType} in ${scriptUrl}:${lineNumber + 1}`; + inspector.suspendReplWhile(() => Promise.all([/*formatWatchers(true), */ selectedFrame?.list(3)]) + .then(([/*watcherList, */ context]) => { + /*if (watcherList) { + return `${watcherList}\n${inspect(context)}`; + }*/ + return inspect(context); + }) + .then(breakContext => { + print(`${header}\n${breakContext}`); + })); + }); + function handleResumed() { + currentBacktrace = undefined; + selectedFrame = undefined; + } + Debugger.on('resumed', handleResumed); + //Debugger.on('breakpointResolved', handleBreakpointResolved); + Debugger.on('scriptParsed', (script) => { + const { scriptId, url } = script; + if (url) { + knownScripts[scriptId] = Object.assign({ + isNative: isNativeUrl(url), + }, script); + } + }); + /*Profiler.on('consoleProfileFinished', ({ profile }) => { + Profile.createAndRegister({ profile }); + print([ + 'Captured new CPU profile.', + `Access it with profiles[${profiles.length - 1}]` + ].join('\n')); + });*/ + function initializeContext(context) { + Object.defineProperty(context, 'Debugger', { + value: inspector.Debugger, + enumerable: true, + configurable: true, + // @ts-expect-error fix later + writeable: false, + }); + Object.defineProperty(context, 'HeapProfiler', { + value: inspector.HeapProfiler, + enumerable: true, + configurable: true, + // @ts-expect-error fix later + writeable: false, + }); + Object.defineProperty(context, 'Profiler', { + value: inspector.Profiler, + enumerable: true, + configurable: true, + // @ts-expect-error fix later + writeable: false, + }); + Object.defineProperty(context, 'Runtime', { + value: inspector.Runtime, + enumerable: true, + configurable: true, + // @ts-expect-error fix later + writeable: false, + }); + /*copyOwnProperties(context, { + get help() { + print(HELP); + }, + + get run() { + return inspector.run(); + }, + + get kill() { + return inspector.killChild(); + }, + + get restart() { + return inspector.run(); + }, + + get cont() { + handleResumed(); + return Debugger.resume(); + }, + + get next() { + handleResumed(); + return Debugger.stepOver(); + }, + + get step() { + handleResumed(); + return Debugger.stepInto(); + }, + + get out() { + handleResumed(); + return Debugger.stepOut(); + }, + + get pause() { + return Debugger.pause(); + }, + + get backtrace() { + return currentBacktrace; + }, + + get breakpoints() { + return listBreakpoints(); + }, + + exec(expr) { + return evalInCurrentContext(expr); + }, + + get profile() { + return Profiler.start(); + }, + + get profileEnd() { + return Profiler.stop() + .then(Profile.createAndRegister); + }, + + get profiles() { + return profiles; + }, + + takeHeapSnapshot(filename = 'node.heapsnapshot') { + return new Promise((resolve, reject) => { + const absoluteFile = Path.resolve(filename); + const writer = FS.createWriteStream(absoluteFile); + let sizeWritten = 0; + function onProgress({ done, total, finished }) { + if (finished) { + print('Heap snaphost prepared.'); + } else { + print(`Heap snapshot: ${done}/${total}`, true); + } + } + function onChunk({ chunk }) { + sizeWritten += chunk.length; + writer.write(chunk); + print(`Writing snapshot: ${sizeWritten}`, true); + } + function onResolve() { + writer.end(() => { + teardown(); + print(`Wrote snapshot: ${absoluteFile}`); + resolve(); + }); + } + function onReject(error) { + teardown(); + reject(error); + } + function teardown() { + HeapProfiler.removeListener( + 'reportHeapSnapshotProgress', onProgress); + HeapProfiler.removeListener('addHeapSnapshotChunk', onChunk); + } + + HeapProfiler.on('reportHeapSnapshotProgress', onProgress); + HeapProfiler.on('addHeapSnapshotChunk', onChunk); + + print('Heap snapshot: 0/0', true); + HeapProfiler.takeHeapSnapshot({ reportProgress: true }) + .then(onResolve, onReject); + }); + }, + + get watchers() { + return watchers(); + }, + + watch(expr) { + watchedExpressions.push(expr); + }, + + unwatch(expr) { + const index = watchedExpressions.indexOf(expr); + + // Unwatch by expression + // or + // Unwatch by watcher number + watchedExpressions.splice(index !== -1 ? index : +expr, 1); + }, + + get repl() { + // Don't display any default messages + const listeners = repl.listeners('SIGINT').slice(0); + repl.removeAllListeners('SIGINT'); + + const oldContext = repl.context; + + exitDebugRepl = () => { + // Restore all listeners + process.nextTick(() => { + listeners.forEach((listener) => { + repl.on('SIGINT', listener); + }); + }); + + // Exit debug repl + repl.eval = controlEval; + + // Swap history + history.debug = repl.history; + repl.history = history.control; + + repl.context = oldContext; + repl.setPrompt('debug> '); + repl.displayPrompt(); + + repl.removeListener('SIGINT', exitDebugRepl); + repl.removeListener('exit', exitDebugRepl); + + exitDebugRepl = null; + }; + + // Exit debug repl on SIGINT + repl.on('SIGINT', exitDebugRepl); + + // Exit debug repl on repl exit + repl.on('exit', exitDebugRepl); + + // Set new + repl.eval = debugEval; + repl.context = {}; + + // Swap history + history.control = repl.history; + repl.history = history.debug; + + repl.setPrompt('> '); + + print('Press Ctrl + C to leave debug repl'); + repl.displayPrompt(); + }, + + get version() { + return Runtime.evaluate({ + expression: 'process.versions.v8', + contextId: 1, + returnByValue: true, + }).then(({ result }) => { + print(result.value); + }); + }, + + scripts: listScripts, + + //setBreakpoint, + //clearBreakpoint, + setPauseOnExceptions, + get breakOnException() { + return setPauseOnExceptions('all'); + }, + get breakOnUncaught() { + return setPauseOnExceptions('uncaught'); + }, + get breakOnNone() { + return setPauseOnExceptions('none'); + }, + + list, + });*/ + //aliasProperties(context, SHORTCUTS); + } + function initAfterStart() { + const setupTasks = [ + Runtime.enable(), + //Profiler.enable(), + //Profiler.setSamplingInterval({ interval: 100 }), + Debugger.enable(), + Debugger.setPauseOnExceptions({ state: 'none' }), + Debugger.setAsyncCallStackDepth({ maxDepth: 1 }), + Debugger.setBlackboxPatterns({ patterns: [] }), + // Debugger.setPauseOnExceptions({ state: 'all' }), + //restoreBreakpoints(), + Runtime.runIfWaitingForDebugger(), + ]; + return Promise.all(setupTasks); + } + return function startRepl() { + inspector.client.on('close', () => resetOnStart()); + inspector.client.on('ready', () => { + initAfterStart().catch(err => { + print(`Error starting inspector: ${err.message}`); + }); + }); + const replOptions = { + prompt: 'debug> ', + input: inspector.stdin, + output: inspector.stdout, + eval: controlEval, + useGlobal: false, + ignoreUndefined: true, + }; + repl = (0, repl_1.start)(replOptions); + initializeContext(repl.context); + repl.on('reset', initializeContext); + repl.defineCommand('interrupt', () => { + // We want this for testing purposes where sending CTRL-C can be tricky. + repl.emit('SIGINT'); + }); + // Init once for the initial connection + initAfterStart().catch(err => { + print(`Error starting inspector: ${err.message}`); + }); + return repl; + }; +} +//# sourceMappingURL=debugger.js.map \ No newline at end of file diff --git a/build-backend/lib/debugger.js.map b/build-backend/lib/debugger.js.map new file mode 100644 index 00000000..44f0078e --- /dev/null +++ b/build-backend/lib/debugger.js.map @@ -0,0 +1 @@ +{"version":3,"file":"debugger.js","sourceRoot":"","sources":["../../src/lib/debugger.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Node.js contributors. All rights reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\nimport { join, resolve } from 'node:path';\nimport { type ReplOptions, type REPLServer, start } from 'repl';\nimport {\n debuglog as debuglogUtil,\n inspect as inspectUtil,\n type InspectOptions,\n type InspectOptionsStylized,\n type Style,\n} from 'node:util';\nimport { type Context, runInContext } from 'node:vm';\nimport { fileURLToPath } from 'node:url';\nimport { builtinModules as PUBLIC_BUILTINS } from 'node:module';\nimport type { Debugger, Runtime } from 'node:inspector';\n\nimport type { NodeInspector } from './inspect';\n\nconst debuglog = debuglogUtil('inspect');\n\ninterface PropertyPreview {\n /**\n * Property name.\n */\n name: string;\n /**\n * Object type. Accessor means that the property itself is an accessor property.\n */\n type: string;\n /**\n * User-friendly property value string.\n */\n value?: string | undefined;\n /**\n * Object subtype hint. Specified for object type values only.\n */\n subtype?: string | undefined;\n}\n/*const SHORTCUTS = {\n cont: 'c',\n next: 'n',\n step: 's',\n out: 'o',\n backtrace: 'bt',\n setBreakpoint: 'sb',\n clearBreakpoint: 'cb',\n run: 'r',\n};\n\nconst HELP = `\nrun, restart, r Run the application or reconnect\nkill Kill a running application or disconnect\n\ncont, c Resume execution\nnext, n Continue to next line in current file\nstep, s Step into, potentially entering a function\nout, o Step out, leaving the current function\nbacktrace, bt Print the current backtrace\nlist Print the source around the current line where execution\n is currently paused\n\nsetBreakpoint, sb Set a breakpoint\nclearBreakpoint, cb Clear a breakpoint\nbreakpoints List all known breakpoints\nbreakOnException Pause execution whenever an exception is thrown\nbreakOnUncaught Pause execution whenever an exception isn't caught\nbreakOnNone Don't pause on exceptions (this is the default)\n\nwatch(expr) Start watching the given expression\nunwatch(expr) Stop watching an expression\nwatchers Print all watched expressions and their current values\n\nexec(expr) Evaluate the expression and print the value\nrepl Enter a debug repl that works like exec\n\nscripts List application scripts that are currently loaded\nscripts(true) List all scripts (including node-internals)\n\nprofile Start CPU profiling session.\nprofileEnd Stop current CPU profiling session.\nprofiles Array of completed CPU profiling sessions.\nprofiles[n].save(filepath = 'node.cpuprofile')\n Save CPU profiling session to disk as JSON.\n\ntakeHeapSnapshot(filepath = 'node.heapsnapshot')\n Take a heap snapshot and save to disk as JSON.\n`.trim();*/\n\nconst FUNCTION_NAME_PATTERN = /^(?:function\\*? )?([^(\\s]+)\\(/;\nfunction extractFunctionName(description: string | undefined): string {\n const fnNameMatch = description?.match(FUNCTION_NAME_PATTERN);\n return fnNameMatch ? `: ${fnNameMatch[1]}` : '';\n}\n\n// process.binding is a method available on the process object, which allows you to load internal modules written in C++\n// @ts-expect-error binding is internal function\nconst NATIVES = PUBLIC_BUILTINS ? process.binding('natives') : {};\n\nfunction isNativeUrl(url: string): boolean {\n url = url.replace(/\\.js$/, '');\n if (PUBLIC_BUILTINS) {\n if (url.startsWith('internal/') || PUBLIC_BUILTINS.includes(url)) {\n return true;\n }\n }\n\n return url in NATIVES || url === 'bootstrap_node';\n}\n\nfunction getRelativePath(filenameOrURL: string): string {\n const dir = join(resolve(), 'x').slice(0, -1);\n\n const filename = filenameOrURL.startsWith('file://') ? fileURLToPath(filenameOrURL) : filenameOrURL;\n\n // Change a path to relative, if possible\n if (filename.indexOf(dir) === 0) {\n return filename.slice(dir.length);\n }\n return filename;\n}\n\nfunction toCallback(promise: Promise, callback: (...args: any[]) => void): void {\n function forward(...args: any[]): void {\n process.nextTick(() => callback(...args));\n }\n\n promise.then(forward.bind(null, null), forward);\n}\n\n// Adds spaces and prefix to number\n// maxN is a maximum number we should have space for\nfunction leftPad(n: number, prefix: string, maxN: number): string {\n const s = n.toString();\n const nchars = Math.max(2, String(maxN).length) + 1;\n const nspaces = nchars - s.length - 1;\n\n return prefix + ' '.repeat(nspaces) + s;\n}\n\nfunction markSourceColumn(sourceText: string, position: number, useColors?: boolean): string {\n if (!sourceText) {\n return '';\n }\n\n const head = sourceText.slice(0, position);\n let tail = sourceText.slice(position);\n\n // Colorize char if stdout supports colours\n if (useColors) {\n tail = tail.replace(/(.+?)([^\\w]|$)/, '\\u001b[32m$1\\u001b[39m$2');\n }\n\n // Return source line with coloured char at `position`\n return [head, tail].join('');\n}\n\nfunction extractErrorMessage(stack: string | undefined): string {\n if (!stack) {\n return '';\n }\n const m = stack.match(/^\\w+: ([^\\n]+)/);\n return m ? m[1] : stack;\n}\n\nfunction convertResultToError(result: Runtime.RemoteObject): Error {\n const { className, description } = result;\n const err = new Error(extractErrorMessage(description));\n err.stack = description;\n Object.defineProperty(err, 'name', { value: className });\n return err;\n}\n\nclass RemoteObject implements Runtime.RemoteObject {\n type: string;\n subtype?: string | undefined;\n className?: string | undefined;\n\n value: any;\n unserializableValue?: Runtime.UnserializableValue | undefined;\n description: string | undefined;\n objectId?: Runtime.RemoteObjectId | undefined;\n preview?: Runtime.ObjectPreview | undefined;\n customPreview?: Runtime.CustomPreview | undefined;\n\n constructor(attributes: Runtime.RemoteObject | undefined) {\n this.type = 'undefined';\n Object.assign(this, attributes);\n if (this.type === 'number') {\n this.value = this.unserializableValue ? +this.unserializableValue : +this.value;\n }\n }\n\n [inspectUtil.custom](_depth: number, opts: InspectOptionsStylized): string {\n function formatProperty(prop: PropertyPreview): any {\n switch (prop.type) {\n case 'string':\n case 'undefined':\n return inspectUtil(prop.value, opts);\n\n case 'number':\n case 'boolean':\n return opts.stylize(prop.value as string, prop.type);\n\n case 'object':\n case 'symbol':\n if (prop.subtype === 'date') {\n return inspectUtil(new Date(prop.value as string), opts);\n }\n if (prop.subtype === 'array') {\n return opts.stylize(prop.value as string, 'special');\n }\n return opts.stylize(prop.value as string, (prop.subtype as Style) || 'special');\n\n default:\n return prop.value;\n }\n }\n\n switch (this.type) {\n case 'boolean':\n case 'number':\n case 'string':\n case 'undefined':\n return inspectUtil(this.value, opts);\n\n case 'symbol':\n return opts.stylize(this.description as string, 'special');\n\n case 'function': {\n const fnName = extractFunctionName(this.description);\n const formatted = `[${this.className}${fnName}]`;\n return opts.stylize(formatted, 'special');\n }\n\n case 'object':\n switch (this.subtype) {\n case 'date':\n return inspectUtil(new Date(this.description as string), opts);\n\n case 'null':\n return inspectUtil(null, opts);\n\n case 'regexp':\n return opts.stylize(this.description as string, 'regexp');\n\n default:\n break;\n }\n if (this.preview) {\n const props: any[] = this.preview.properties.map((prop, idx) => {\n const value = formatProperty(prop);\n if (prop.name === `${idx}`) {\n return value;\n }\n return `${prop.name}: ${value}`;\n });\n if (this.preview.overflow) {\n props.push('...');\n }\n const singleLine = props.join(', ');\n const propString = singleLine.length > 60 ? props.join(',\\n ') : singleLine;\n\n return this.subtype === 'array' ? `[ ${propString} ]` : `{ ${propString} }`;\n }\n return this.description || '';\n\n default:\n return this.description || '';\n }\n }\n\n static fromEvalResult({ result, wasThrown }: { result: RemoteObject; wasThrown?: boolean }): RemoteObject | Error {\n if (wasThrown) {\n return convertResultToError(result);\n }\n return new RemoteObject(result);\n }\n}\n\nclass ScopeSnapshot implements Debugger.Scope {\n /**\n * Scope type.\n */\n type: string;\n /**\n * Object representing the scope. For global and with scopes it represents the actual object; for the rest of the scopes, it is artificial transient object enumerating scope variables as its properties.\n */\n object: Runtime.RemoteObject;\n\n name?: string | undefined;\n /**\n * Location in the source code where scope starts\n */\n startLocation?: Debugger.Location | undefined;\n /**\n * Location in the source code where scope ends\n */\n endLocation?: Debugger.Location | undefined;\n\n properties: Map;\n\n completionGroup: string[];\n\n constructor(scope: Debugger.Scope, properties: Runtime.PropertyDescriptor[]) {\n this.type = scope.type;\n this.object = scope.object;\n\n Object.assign(this, scope);\n\n this.properties = new Map(\n properties.map(prop => {\n const value = new RemoteObject(prop.value);\n return [prop.name, value];\n }),\n );\n\n this.completionGroup = properties.map(prop => prop.name);\n }\n\n [inspectUtil.custom](_depth: number, opts: InspectOptions): string {\n const type = `${this.type[0].toUpperCase()}${this.type.slice(1)}`;\n const name = this.name ? `<${this.name}>` : '';\n const prefix = `${type}${name} `;\n return inspectUtil(this.properties, opts).replace(/^Map /, prefix);\n }\n}\n/*\nfunction copyOwnProperties(target: any, source: any): void {\n Object.getOwnPropertyNames(source).forEach(prop => {\n const descriptor = Object.getOwnPropertyDescriptor(source, prop);\n if (descriptor) {\n Object.defineProperty(target, prop, descriptor);\n }\n });\n}\n\nfunction aliasProperties(target, mapping) {\n Object.keys(mapping).forEach((key) => {\n const descriptor = Object.getOwnPropertyDescriptor(target, key);\n Object.defineProperty(target, mapping[key], descriptor);\n });\n}\n*/\nexport default function createRepl(inspector: NodeInspector): () => REPLServer {\n const { Debugger, /*HeapProfiler, Profiler,*/ Runtime } = inspector;\n\n let repl: REPLServer;\n\n // Things we want to keep around\n // const history = { control: [], debug: [] };\n // const watchedExpressions = [];\n // const knownBreakpoints = [];\n // let pauseOnExceptionState = 'none';\n let lastCommand: string;\n\n // Things we need to reset when the app restarts\n let knownScripts: Record = {};\n let currentBacktrace: CallFrame[] | undefined;\n let selectedFrame: CallFrame | undefined;\n let exitDebugRepl: undefined | (() => void);\n\n function resetOnStart(): void {\n knownScripts = {};\n currentBacktrace = undefined;\n selectedFrame = undefined;\n\n if (exitDebugRepl) {\n exitDebugRepl();\n }\n exitDebugRepl = undefined;\n }\n\n resetOnStart();\n\n const INSPECT_OPTIONS: InspectOptions = { colors: inspector.stdout.isTTY };\n function inspect(value: any): string {\n return inspectUtil(value, INSPECT_OPTIONS);\n }\n\n function print(value: any, oneline = false): void {\n const text = typeof value === 'string' ? value : inspect(value);\n return inspector.print(text, oneline);\n }\n\n function getCurrentLocation(): Debugger.Location {\n if (!selectedFrame) {\n throw new Error('Requires execution to be paused');\n }\n return selectedFrame.location;\n }\n\n function isCurrentScript(script: Debugger.ScriptParsedEventDataType & { isNative: boolean }): boolean {\n return !!selectedFrame && getCurrentLocation().scriptId === script.scriptId;\n }\n\n function formatScripts(displayNatives = false): string {\n function isVisible(script: Debugger.ScriptParsedEventDataType & { isNative: boolean }): boolean {\n if (displayNatives) {\n return true;\n }\n return !script.isNative || isCurrentScript(script);\n }\n\n return Object.keys(knownScripts)\n .map(scriptId => knownScripts[scriptId])\n .filter(isVisible)\n .map(script => {\n const isCurrent = isCurrentScript(script);\n const { isNative, url } = script;\n const name = `${getRelativePath(url)}${isNative ? ' ' : ''}`;\n return `${isCurrent ? '*' : ' '} ${script.scriptId}: ${name}`;\n })\n .join('\\n');\n }\n function listScripts(displayNatives = false): void {\n print(formatScripts(displayNatives));\n }\n // @ts-expect-error no idea what this is\n listScripts[inspectUtil.custom] = function listWithoutInternal(): string {\n return formatScripts();\n };\n /*\n const profiles = [];\n class Profile {\n constructor(data) {\n this.data = data;\n }\n\n static createAndRegister({ profile }) {\n const p = new Profile(profile);\n profiles.push(p);\n return p;\n }\n\n [util.inspect.custom](depth, { stylize }) {\n const { startTime, endTime } = this.data;\n return stylize(`[Profile ${endTime - startTime}μs]`, 'special');\n }\n\n save(filename = 'node.cpuprofile') {\n const absoluteFile = Path.resolve(filename);\n const json = JSON.stringify(this.data);\n FS.writeFileSync(absoluteFile, json);\n print('Saved profile to ' + absoluteFile);\n }\n }\n*/\n class SourceSnippet {\n scriptSource: string;\n /**\n * Script identifier as reported in the Debugger.scriptParsed.\n */\n scriptId: Runtime.ScriptId;\n /**\n * Line number in the script (0-based).\n */\n lineNumber: number;\n /**\n * Column number in the script (0-based).\n */\n columnNumber: number;\n delta: number;\n constructor(location: Debugger.Location, delta: number, scriptSource: string) {\n this.lineNumber = location.lineNumber;\n this.columnNumber = location.columnNumber || 0;\n this.scriptId = location.scriptId;\n this.scriptSource = scriptSource;\n this.delta = delta;\n Object.assign(this, location);\n }\n\n [inspectUtil.custom](_depth: number, options: InspectOptions): string {\n const { /* scriptId, */ lineNumber, columnNumber, delta, scriptSource } = this;\n const start = Math.max(1, lineNumber - delta + 1);\n const end = lineNumber + delta + 1;\n\n const lines = scriptSource.split('\\n');\n return lines\n .slice(start - 1, end)\n .map((lineText, offset) => {\n const i = start + offset;\n const isCurrent = i === lineNumber + 1;\n\n const markedLine = isCurrent ? markSourceColumn(lineText, columnNumber, options.colors) : lineText;\n\n /*\n let isBreakpoint = false;\n knownBreakpoints.forEach(({ location }) => {\n if (!location) return;\n if (scriptId === location.scriptId &&\n i === (location.lineNumber + 1)) {\n isBreakpoint = true;\n }\n });\n */\n\n let prefixChar = ' ';\n if (isCurrent) {\n prefixChar = '>';\n } /*else if (isBreakpoint) {\n prefixChar = '*';\n }*/\n return `${leftPad(i, prefixChar, end)} ${markedLine}`;\n })\n .join('\\n');\n }\n }\n\n function getSourceSnippet(location: Debugger.Location, delta: number = 5): SourceSnippet {\n const { scriptId } = location;\n return Debugger.getScriptSource({ scriptId }).then(\n ({ scriptSource }: Debugger.GetScriptSourceReturnType) => new SourceSnippet(location, delta, scriptSource),\n );\n }\n\n class CallFrame implements Debugger.CallFrame {\n /**\n * Call frame identifier. This identifier is only valid while the virtual machine is paused.\n */\n callFrameId: Debugger.CallFrameId;\n /**\n * Name of the JavaScript function called on this call frame.\n */\n functionName: string;\n /**\n * Location in the source code.\n */\n functionLocation?: Debugger.Location | undefined;\n /**\n * Location in the source code.\n */\n location: Debugger.Location;\n /**\n * JavaScript script name or url.\n */\n url: string;\n /**\n * Scope chain for this call frame.\n */\n scopeChain: Debugger.Scope[];\n /**\n * this object for this call frame.\n */\n this: Runtime.RemoteObject;\n /**\n * The value being returned if the function is at return point.\n */\n returnValue?: Runtime.RemoteObject | undefined;\n\n constructor(callFrame: Debugger.CallFrame) {\n this.functionName = callFrame.functionName;\n this.url = callFrame.url;\n this.scopeChain = callFrame.scopeChain;\n this.this = callFrame.this;\n this.returnValue = callFrame.returnValue;\n this.location = callFrame.location;\n this.callFrameId = callFrame.callFrameId;\n\n Object.assign(this, callFrame);\n }\n\n loadScopes(): Promise {\n return Promise.all(\n this.scopeChain\n .filter(scope => scope.type !== 'global')\n .map(scope => {\n const { objectId } = scope.object;\n return Runtime.getProperties({\n objectId,\n generatePreview: true,\n } as Runtime.GetPropertiesParameterType).then(({ result }: Runtime.GetPropertiesReturnType) => {\n return new ScopeSnapshot(scope, result);\n });\n }),\n );\n }\n\n list(delta: number = 5): SourceSnippet {\n return getSourceSnippet(this.location, delta);\n }\n }\n\n class Backtrace extends Array {\n [inspectUtil.custom](): string {\n return this.map((callFrame, idx) => {\n const {\n location: { scriptId, lineNumber, columnNumber },\n functionName,\n } = callFrame;\n const name = functionName || '(anonymous)';\n\n const script = knownScripts[scriptId];\n const relativeUrl = (script && getRelativePath(script.url)) || '';\n const frameLocation = `${relativeUrl}:${lineNumber + 1}:${columnNumber}`;\n\n return `#${idx} ${name} ${frameLocation}`;\n }).join('\\n');\n }\n\n static from(callFrames: CallFrame[]): CallFrame[] {\n return super.from(\n Array.from(callFrames).map(callFrame => {\n if (callFrame instanceof CallFrame) {\n return callFrame;\n }\n return new CallFrame(callFrame);\n }),\n );\n }\n }\n\n function prepareControlCode(input: string): string {\n if (input === '\\n') {\n return lastCommand;\n }\n // exec process.title => exec(\"process.title\");\n const match = input.match(/^\\s*exec\\s+([^\\n]*)/);\n if (match) {\n lastCommand = `exec(${JSON.stringify(match[1])})`;\n } else {\n lastCommand = input;\n }\n return lastCommand;\n }\n\n // function evalInCurrentContext(code) {\n // // Repl asked for scope variables\n // if (code === '.scope') {\n // if (!selectedFrame) {\n // return Promise.reject(new Error('Requires execution to be paused'));\n // }\n // return selectedFrame.loadScopes().then((scopes) => {\n // return scopes.map((scope) => scope.completionGroup);\n // });\n // }\n //\n // if (selectedFrame) {\n // return Debugger.evaluateOnCallFrame({\n // callFrameId: selectedFrame.callFrameId,\n // expression: code,\n // objectGroup: 'node-inspect',\n // generatePreview: true,\n // }).then(RemoteObject.fromEvalResult);\n // }\n // return Runtime.evaluate({\n // expression: code,\n // objectGroup: 'node-inspect',\n // generatePreview: true,\n // }).then(RemoteObject.fromEvalResult);\n // }\n\n function controlEval(\n input: string,\n context: Context,\n filename: string,\n callback: (error: Error | null, result?: any) => void,\n ): void {\n debuglog('eval:', input);\n function returnToCallback(error: Error | null, result?: any): void {\n debuglog('end-eval:', input, error);\n callback(error, result);\n }\n\n try {\n const code = prepareControlCode(input);\n const result = runInContext(code, context, filename);\n\n if (result && typeof result.then === 'function') {\n toCallback(result, returnToCallback);\n return;\n }\n returnToCallback(null, result);\n } catch (e: any) {\n returnToCallback(e as Error);\n }\n }\n\n // function debugEval(input, context, filename, callback) {\n // debuglog('eval:', input);\n // function returnToCallback(error, result) {\n // debuglog('end-eval:', input, error);\n // callback(error, result);\n // }\n //\n // try {\n // const result = evalInCurrentContext(input);\n //\n // if (result && typeof result.then === 'function') {\n // toCallback(result, returnToCallback);\n // return;\n // }\n // returnToCallback(null, result);\n // } catch (e) {\n // returnToCallback(e);\n // }\n // }\n\n /*function formatWatchers(verbose = false) {\n if (!watchedExpressions.length) {\n return Promise.resolve('');\n }\n\n const inspectValue = (expr) =>\n evalInCurrentContext(expr)\n // .then(formatValue)\n .catch((error) => `<${error.message}>`);\n const lastIndex = watchedExpressions.length - 1;\n\n return Promise.all(watchedExpressions.map(inspectValue))\n .then((values) => {\n const lines = watchedExpressions\n .map((expr, idx) => {\n const prefix = `${leftPad(idx, ' ', lastIndex)}: ${expr} =`;\n const value = inspect(values[idx], { colors: true });\n if (value.indexOf('\\n') === -1) {\n return `${prefix} ${value}`;\n }\n return `${prefix}\\n ${value.split('\\n').join('\\n ')}`;\n });\n return lines.join('\\n');\n })\n .then((valueList) => {\n return verbose ? `Watchers:\\n${valueList}\\n` : valueList;\n });\n }*/\n\n //function watchers(verbose = false) {\n // return formatWatchers(verbose).then(print);\n //}\n\n // List source code\n // function list(delta = 5) {\n // return selectedFrame.list(delta)\n // .then(null, (error) => {\n // print('You can\\'t list source code right now');\n // throw error;\n // });\n // }\n\n //function handleBreakpointResolved({ breakpointId, location }) {\n // const script = knownScripts[location.scriptId];\n // const scriptUrl = script && script.url;\n // if (scriptUrl) {\n // Object.assign(location, { scriptUrl });\n // }\n // const isExisting = knownBreakpoints.some((bp) => {\n // if (bp.breakpointId === breakpointId) {\n // Object.assign(bp, { location });\n // return true;\n // }\n // return false;\n // });\n // if (!isExisting) {\n // knownBreakpoints.push({ breakpointId, location });\n // }\n //}\n\n // function listBreakpoints() {\n // if (!knownBreakpoints.length) {\n // print('No breakpoints yet');\n // return;\n // }\n //\n // function formatLocation(location) {\n // if (!location) return '';\n // const script = knownScripts[location.scriptId];\n // const scriptUrl = script ? script.url : location.scriptUrl;\n // return `${getRelativePath(scriptUrl)}:${location.lineNumber + 1}`;\n // }\n // const breaklist = knownBreakpoints\n // .map((bp, idx) => `#${idx} ${formatLocation(bp.location)}`)\n // .join('\\n');\n // print(breaklist);\n // }\n\n // function setBreakpoint(script, line, condition, silent) {\n // function registerBreakpoint({ breakpointId, actualLocation }) {\n // handleBreakpointResolved({ breakpointId, location: actualLocation });\n // if (actualLocation && actualLocation.scriptId) {\n // if (!silent) return getSourceSnippet(actualLocation, 5);\n // } else {\n // print(`Warning: script '${script}' was not loaded yet.`);\n // }\n // return undefined;\n // }\n //\n // // setBreakpoint(): set breakpoint at current location\n // if (script === undefined) {\n // return Debugger\n // .setBreakpoint({ location: getCurrentLocation(), condition })\n // .then(registerBreakpoint);\n // }\n //\n // // setBreakpoint(line): set breakpoint in current script at specific line\n // if (line === undefined && typeof script === 'number') {\n // const location = {\n // scriptId: getCurrentLocation().scriptId,\n // lineNumber: script - 1,\n // };\n // return Debugger.setBreakpoint({ location, condition })\n // .then(registerBreakpoint);\n // }\n //\n // if (typeof script !== 'string') {\n // throw new TypeError(`setBreakpoint() expects a string, got ${script}`);\n // }\n //\n // // setBreakpoint('fn()'): Break when a function is called\n // if (script.endsWith('()')) {\n // const debugExpr = `debug(${script.slice(0, -2)})`;\n // const debugCall = selectedFrame\n // ? Debugger.evaluateOnCallFrame({\n // callFrameId: selectedFrame.callFrameId,\n // expression: debugExpr,\n // includeCommandLineAPI: true,\n // })\n // : Runtime.evaluate({\n // expression: debugExpr,\n // includeCommandLineAPI: true,\n // });\n // return debugCall.then(({ result, wasThrown }) => {\n // if (wasThrown) return convertResultToError(result);\n // return undefined; // This breakpoint can't be removed the same way\n // });\n // }\n //\n // // setBreakpoint('scriptname')\n // let scriptId = null;\n // let ambiguous = false;\n // if (knownScripts[script]) {\n // scriptId = script;\n // } else {\n // for (const id of Object.keys(knownScripts)) {\n // const scriptUrl = knownScripts[id].url;\n // if (scriptUrl && scriptUrl.indexOf(script) !== -1) {\n // if (scriptId !== null) {\n // ambiguous = true;\n // }\n // scriptId = id;\n // }\n // }\n // }\n //\n // if (ambiguous) {\n // print('Script name is ambiguous');\n // return undefined;\n // }\n // if (line <= 0) {\n // print('Line should be a positive value');\n // return undefined;\n // }\n //\n // if (scriptId !== null) {\n // const location = { scriptId, lineNumber: line - 1 };\n // return Debugger.setBreakpoint({ location, condition })\n // .then(registerBreakpoint);\n // }\n //\n // const escapedPath = script.replace(/([/\\\\.?*()^${}|[\\]])/g, '\\\\$1');\n // const urlRegex = `^(.*[\\\\/\\\\\\\\])?${escapedPath}$`;\n //\n // return Debugger\n // .setBreakpointByUrl({ urlRegex, lineNumber: line - 1, condition })\n // .then((bp) => {\n // // TODO: handle bp.locations in case the regex matches existing files\n // if (!bp.location) { // Fake it for now.\n // Object.assign(bp, {\n // actualLocation: {\n // scriptUrl: `.*/${script}$`,\n // lineNumber: line - 1,\n // },\n // });\n // }\n // return registerBreakpoint(bp);\n // });\n // }\n //\n // function clearBreakpoint(url, line) {\n // const breakpoint = knownBreakpoints.find(({ location }) => {\n // if (!location) return false;\n // const script = knownScripts[location.scriptId];\n // if (!script) return false;\n // return (\n // script.url.indexOf(url) !== -1 && (location.lineNumber + 1) === line\n // );\n // });\n // if (!breakpoint) {\n // print(`Could not find breakpoint at ${url}:${line}`);\n // return Promise.resolve();\n // }\n // return Debugger.removeBreakpoint({ breakpointId: breakpoint.breakpointId })\n // .then(() => {\n // const idx = knownBreakpoints.indexOf(breakpoint);\n // knownBreakpoints.splice(idx, 1);\n // });\n // }\n //\n // function restoreBreakpoints() {\n // const lastBreakpoints = knownBreakpoints.slice();\n // knownBreakpoints.length = 0;\n // const newBreakpoints = lastBreakpoints\n // .filter(({ location }) => !!location.scriptUrl)\n // .map(({ location }) =>\n // setBreakpoint(location.scriptUrl, location.lineNumber + 1));\n // if (!newBreakpoints.length) return Promise.resolve();\n // return Promise.all(newBreakpoints).then((results) => {\n // print(`${results.length} breakpoints restored.`);\n // });\n // }\n\n // function setPauseOnExceptions(state) {\n // return Debugger.setPauseOnExceptions({ state })\n // .then(() => {\n // pauseOnExceptionState = state;\n // });\n // }\n\n Debugger.on('paused', (data: Debugger.PausedEventDataType): void => {\n const callFrames: CallFrame[] = data.callFrames as CallFrame[];\n const reason: string = data.reason;\n\n if (process.env.NODE_INSPECT_RESUME_ON_START === '1' && reason === 'Break on start') {\n debuglog('Paused on start, but NODE_INSPECT_RESUME_ON_START environment variable is set to 1, resuming');\n inspector.client.callMethod('Debugger.resume');\n return;\n }\n\n // Save execution context's data\n currentBacktrace = Backtrace.from(callFrames);\n selectedFrame = currentBacktrace[0];\n const { scriptId, lineNumber } = selectedFrame.location;\n\n const breakType = reason === 'other' ? 'break' : reason;\n const script = knownScripts[scriptId];\n const scriptUrl = script ? getRelativePath(script.url) : '[unknown]';\n\n const header = `${breakType} in ${scriptUrl}:${lineNumber + 1}`;\n\n inspector.suspendReplWhile(() =>\n Promise.all([/*formatWatchers(true), */ selectedFrame?.list(3)])\n .then(([/*watcherList, */ context]) => {\n /*if (watcherList) {\n return `${watcherList}\\n${inspect(context)}`;\n }*/\n return inspect(context);\n })\n .then(breakContext => {\n print(`${header}\\n${breakContext}`);\n }),\n );\n });\n\n function handleResumed(): void {\n currentBacktrace = undefined;\n selectedFrame = undefined;\n }\n\n Debugger.on('resumed', handleResumed);\n\n //Debugger.on('breakpointResolved', handleBreakpointResolved);\n\n Debugger.on('scriptParsed', (script: Debugger.ScriptParsedEventDataType) => {\n const { scriptId, url } = script;\n if (url) {\n knownScripts[scriptId] = Object.assign(\n {\n isNative: isNativeUrl(url),\n },\n script,\n );\n }\n });\n\n /*Profiler.on('consoleProfileFinished', ({ profile }) => {\n Profile.createAndRegister({ profile });\n print([\n 'Captured new CPU profile.',\n `Access it with profiles[${profiles.length - 1}]`\n ].join('\\n'));\n });*/\n\n function initializeContext(context: Context): void {\n Object.defineProperty(context, 'Debugger', {\n value: inspector.Debugger,\n enumerable: true,\n configurable: true,\n // @ts-expect-error fix later\n writeable: false,\n });\n Object.defineProperty(context, 'HeapProfiler', {\n value: inspector.HeapProfiler,\n enumerable: true,\n configurable: true,\n // @ts-expect-error fix later\n writeable: false,\n });\n Object.defineProperty(context, 'Profiler', {\n value: inspector.Profiler,\n enumerable: true,\n configurable: true,\n // @ts-expect-error fix later\n writeable: false,\n });\n Object.defineProperty(context, 'Runtime', {\n value: inspector.Runtime,\n enumerable: true,\n configurable: true,\n // @ts-expect-error fix later\n writeable: false,\n });\n\n /*copyOwnProperties(context, {\n get help() {\n print(HELP);\n },\n\n get run() {\n return inspector.run();\n },\n\n get kill() {\n return inspector.killChild();\n },\n\n get restart() {\n return inspector.run();\n },\n\n get cont() {\n handleResumed();\n return Debugger.resume();\n },\n\n get next() {\n handleResumed();\n return Debugger.stepOver();\n },\n\n get step() {\n handleResumed();\n return Debugger.stepInto();\n },\n\n get out() {\n handleResumed();\n return Debugger.stepOut();\n },\n\n get pause() {\n return Debugger.pause();\n },\n\n get backtrace() {\n return currentBacktrace;\n },\n\n get breakpoints() {\n return listBreakpoints();\n },\n\n exec(expr) {\n return evalInCurrentContext(expr);\n },\n\n get profile() {\n return Profiler.start();\n },\n\n get profileEnd() {\n return Profiler.stop()\n .then(Profile.createAndRegister);\n },\n\n get profiles() {\n return profiles;\n },\n\n takeHeapSnapshot(filename = 'node.heapsnapshot') {\n return new Promise((resolve, reject) => {\n const absoluteFile = Path.resolve(filename);\n const writer = FS.createWriteStream(absoluteFile);\n let sizeWritten = 0;\n function onProgress({ done, total, finished }) {\n if (finished) {\n print('Heap snaphost prepared.');\n } else {\n print(`Heap snapshot: ${done}/${total}`, true);\n }\n }\n function onChunk({ chunk }) {\n sizeWritten += chunk.length;\n writer.write(chunk);\n print(`Writing snapshot: ${sizeWritten}`, true);\n }\n function onResolve() {\n writer.end(() => {\n teardown();\n print(`Wrote snapshot: ${absoluteFile}`);\n resolve();\n });\n }\n function onReject(error) {\n teardown();\n reject(error);\n }\n function teardown() {\n HeapProfiler.removeListener(\n 'reportHeapSnapshotProgress', onProgress);\n HeapProfiler.removeListener('addHeapSnapshotChunk', onChunk);\n }\n\n HeapProfiler.on('reportHeapSnapshotProgress', onProgress);\n HeapProfiler.on('addHeapSnapshotChunk', onChunk);\n\n print('Heap snapshot: 0/0', true);\n HeapProfiler.takeHeapSnapshot({ reportProgress: true })\n .then(onResolve, onReject);\n });\n },\n\n get watchers() {\n return watchers();\n },\n\n watch(expr) {\n watchedExpressions.push(expr);\n },\n\n unwatch(expr) {\n const index = watchedExpressions.indexOf(expr);\n\n // Unwatch by expression\n // or\n // Unwatch by watcher number\n watchedExpressions.splice(index !== -1 ? index : +expr, 1);\n },\n\n get repl() {\n // Don't display any default messages\n const listeners = repl.listeners('SIGINT').slice(0);\n repl.removeAllListeners('SIGINT');\n\n const oldContext = repl.context;\n\n exitDebugRepl = () => {\n // Restore all listeners\n process.nextTick(() => {\n listeners.forEach((listener) => {\n repl.on('SIGINT', listener);\n });\n });\n\n // Exit debug repl\n repl.eval = controlEval;\n\n // Swap history\n history.debug = repl.history;\n repl.history = history.control;\n\n repl.context = oldContext;\n repl.setPrompt('debug> ');\n repl.displayPrompt();\n\n repl.removeListener('SIGINT', exitDebugRepl);\n repl.removeListener('exit', exitDebugRepl);\n\n exitDebugRepl = null;\n };\n\n // Exit debug repl on SIGINT\n repl.on('SIGINT', exitDebugRepl);\n\n // Exit debug repl on repl exit\n repl.on('exit', exitDebugRepl);\n\n // Set new\n repl.eval = debugEval;\n repl.context = {};\n\n // Swap history\n history.control = repl.history;\n repl.history = history.debug;\n\n repl.setPrompt('> ');\n\n print('Press Ctrl + C to leave debug repl');\n repl.displayPrompt();\n },\n\n get version() {\n return Runtime.evaluate({\n expression: 'process.versions.v8',\n contextId: 1,\n returnByValue: true,\n }).then(({ result }) => {\n print(result.value);\n });\n },\n\n scripts: listScripts,\n\n //setBreakpoint,\n //clearBreakpoint,\n setPauseOnExceptions,\n get breakOnException() {\n return setPauseOnExceptions('all');\n },\n get breakOnUncaught() {\n return setPauseOnExceptions('uncaught');\n },\n get breakOnNone() {\n return setPauseOnExceptions('none');\n },\n\n list,\n });*/\n //aliasProperties(context, SHORTCUTS);\n }\n\n function initAfterStart(): Promise {\n const setupTasks = [\n Runtime.enable(),\n //Profiler.enable(),\n //Profiler.setSamplingInterval({ interval: 100 }),\n Debugger.enable(),\n Debugger.setPauseOnExceptions({ state: 'none' }),\n Debugger.setAsyncCallStackDepth({ maxDepth: 1 }),\n Debugger.setBlackboxPatterns({ patterns: [] }),\n // Debugger.setPauseOnExceptions({ state: 'all' }),\n //restoreBreakpoints(),\n Runtime.runIfWaitingForDebugger(),\n ];\n return Promise.all(setupTasks);\n }\n\n return function startRepl(): REPLServer {\n inspector.client.on('close', () => resetOnStart());\n inspector.client.on('ready', () => {\n initAfterStart().catch(err => {\n print(`Error starting inspector: ${err.message}`);\n });\n });\n\n const replOptions: ReplOptions = {\n prompt: 'debug> ',\n input: inspector.stdin,\n output: inspector.stdout,\n eval: controlEval,\n useGlobal: false,\n ignoreUndefined: true,\n };\n\n repl = start(replOptions);\n initializeContext(repl.context);\n repl.on('reset', initializeContext);\n\n repl.defineCommand('interrupt', () => {\n // We want this for testing purposes where sending CTRL-C can be tricky.\n repl.emit('SIGINT');\n });\n\n // Init once for the initial connection\n initAfterStart().catch(err => {\n print(`Error starting inspector: ${err.message}`);\n });\n\n return repl;\n };\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/eventObj.js b/build-backend/lib/eventObj.js new file mode 100644 index 00000000..8a984ab4 --- /dev/null +++ b/build-backend/lib/eventObj.js @@ -0,0 +1,177 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.EventObj = void 0; +exports.getObjectEnumsSync = getObjectEnumsSync; +exports.createEventObject = createEventObject; +let gContext; +function getObjectEnumsSync(context, idObj, enumIds, enumNames) { + if (!enumIds) { + enumIds = []; + } + if (!enumNames) { + enumNames = []; + } + if (context.cacheObjectEnums[idObj]) { + for (const enumId of context.cacheObjectEnums[idObj].enumIds) { + if (!enumIds.includes(enumId)) { + enumIds.push(enumId); + } + } + for (const enumName of context.cacheObjectEnums[idObj].enumNames) { + if (!enumNames.includes(enumName)) { + enumNames.push(enumName); + } + } + return { enumIds: enumIds, enumNames: enumNames }; + } + for (let i = 0, l = context.enums.length; i < l; i++) { + if (context.objects[context.enums[i]]?.common?.members?.includes(idObj)) { + if (!enumIds.includes(context.enums[i])) { + enumIds.push(context.enums[i]); + } + const name = context.objects[context.enums[i]].common.name; + const str = typeof name === 'object' ? name[gContext.language || 'en'] : name; + if (str && !enumNames.includes(str)) { + enumNames.push(str); + } + } + } + if (context.objects[idObj]) { + const pos = idObj.lastIndexOf('.'); + if (pos !== -1) { + const parent = idObj.substring(0, pos); + if (parent && context.objects[parent]) { + const parentEnumIds = []; + const parentEnumNames = []; + //get parent enums but do not propagate our enums to parent. + getObjectEnumsSync(context, parent, parentEnumIds, parentEnumNames); + for (const enumId of parentEnumIds) { + if (!enumIds.includes(enumId)) { + enumIds.push(enumId); + } + } + for (const enumName of parentEnumNames) { + if (!enumNames.includes(enumName)) { + enumNames.push(enumName); + } + } + } + } + } + context.cacheObjectEnums[idObj] = { enumIds: enumIds, enumNames: enumNames }; + return context.cacheObjectEnums[idObj]; +} +function doGetter(obj, name, ret) { + //adapter.log.debug('getter: ' + name + ' returns ' + ret); + Object.defineProperty(obj, name, { value: ret }); + return ret; +} +class EventObj { + id; + state; + newState; + oldState; + constructor(id, state, oldState, context) { + if (context && !gContext) { + gContext = context; + } + this.id = id; + if (!state) { + this.newState = { q: undefined, c: undefined, user: undefined }; + } + else { + this.newState = { + val: state.val, + ts: state.ts, + ack: state.ack, + lc: state.lc, + from: state.from, + q: state.q, + c: state.c, + user: state.user, + }; + } + // if (oldState === undefined) oldState = {}; + if (!oldState) { + this.oldState = { + q: undefined, + c: undefined, + user: undefined, + }; + } + else { + this.oldState = { + val: oldState.val, + ts: oldState.ts, + ack: oldState.ack, + lc: oldState.lc, + from: oldState.from, + q: oldState.q, + c: oldState.c, + user: oldState.user, + }; + } + this.state = this.newState; + } + get common() { + const ret = gContext.objects[this.id] ? gContext.objects[this.id].common : {}; + return doGetter(this, 'common', ret); + } + get native() { + const ret = gContext.objects[this.id] ? gContext.objects[this.id].native : {}; + return doGetter(this, 'native', ret); + } + get name() { + const ret = this.common ? this.common.name : null; + return doGetter(this, 'name', ret); + } + get channelId() { + const ret = this.id.replace(/\.*[^.]+$/, ''); + return doGetter(this, 'channelId', gContext.objects[ret] ? ret : null); + } + get channelName() { + const channelId = this.channelId; + const ret = channelId && gContext.objects[channelId].common ? gContext.objects[channelId].common.name : null; + return doGetter(this, 'channelName', ret); + } + get deviceId() { + let deviceId; + const channelId = this.channelId; + if (!channelId || !(deviceId = channelId.replace(/\.*[^.]+$/, '')) || !gContext.objects[deviceId]) { + Object.defineProperty(this, 'deviceName', { value: null }); + return doGetter(this, 'deviceId', null); + } + return doGetter(this, 'deviceId', deviceId); + } + get deviceName() { + const deviceId = this.deviceId; + const ret = deviceId && gContext.objects[deviceId].common ? gContext.objects[deviceId].common.name : null; + return doGetter(this, 'deviceName', ret); + } + get enumIds() { + if (!gContext.isEnums) { + return undefined; + } + const enumIds = []; + const enumNames = []; + getObjectEnumsSync(gContext, this.id, enumIds, enumNames); + Object.defineProperty(this, 'enumNames', { value: enumNames }); + return doGetter(this, 'enumIds', enumIds); + } + get enumNames() { + if (!gContext.isEnums) { + return undefined; + } + const enumIds = []; + const enumNames = []; + getObjectEnumsSync(gContext, this.id, enumIds, enumNames); + Object.defineProperty(this, 'enumIds', { value: enumIds }); + return doGetter(this, 'enumNames', enumNames); + } +} +exports.EventObj = EventObj; +function createEventObject(context, id, state, oldState) { + gContext = gContext || context; + return new EventObj(id, state, oldState, context); +} +//# sourceMappingURL=eventObj.js.map \ No newline at end of file diff --git a/build-backend/lib/eventObj.js.map b/build-backend/lib/eventObj.js.map new file mode 100644 index 00000000..e8b0c0ba --- /dev/null +++ b/build-backend/lib/eventObj.js.map @@ -0,0 +1 @@ +{"version":3,"file":"eventObj.js","sourceRoot":"","sources":["../../src/lib/eventObj.ts"],"names":[],"mappings":"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","sourcesContent":["import type { JavascriptContext } from '../types';\n\nlet gContext: JavascriptContext;\n\nexport function getObjectEnumsSync(\n context: JavascriptContext,\n idObj: string,\n enumIds?: string[],\n enumNames?: string[],\n): { enumIds: string[]; enumNames: string[] } {\n if (!enumIds) {\n enumIds = [];\n }\n if (!enumNames) {\n enumNames = [];\n }\n\n if (context.cacheObjectEnums[idObj]) {\n for (const enumId of context.cacheObjectEnums[idObj].enumIds) {\n if (!enumIds.includes(enumId)) {\n enumIds.push(enumId);\n }\n }\n for (const enumName of context.cacheObjectEnums[idObj].enumNames) {\n if (!enumNames.includes(enumName)) {\n enumNames.push(enumName);\n }\n }\n return { enumIds: enumIds, enumNames: enumNames };\n }\n\n for (let i = 0, l = context.enums.length; i < l; i++) {\n if (context.objects[context.enums[i]]?.common?.members?.includes(idObj)) {\n if (!enumIds.includes(context.enums[i])) {\n enumIds.push(context.enums[i]);\n }\n const name: ioBroker.StringOrTranslated = context.objects[context.enums[i]].common.name;\n const str: string | undefined = typeof name === 'object' ? name[gContext.language || 'en'] : name;\n if (str && !enumNames.includes(str)) {\n enumNames.push(str);\n }\n }\n }\n\n if (context.objects[idObj]) {\n const pos = idObj.lastIndexOf('.');\n if (pos !== -1) {\n const parent = idObj.substring(0, pos);\n if (parent && context.objects[parent]) {\n const parentEnumIds: string[] = [];\n const parentEnumNames: string[] = [];\n //get parent enums but do not propagate our enums to parent.\n getObjectEnumsSync(context, parent, parentEnumIds, parentEnumNames);\n for (const enumId of parentEnumIds) {\n if (!enumIds.includes(enumId)) {\n enumIds.push(enumId);\n }\n }\n for (const enumName of parentEnumNames) {\n if (!enumNames.includes(enumName)) {\n enumNames.push(enumName);\n }\n }\n }\n }\n }\n\n context.cacheObjectEnums[idObj] = { enumIds: enumIds, enumNames: enumNames };\n return context.cacheObjectEnums[idObj];\n}\n\nfunction doGetter(obj: Record, name: string, ret: any): any {\n //adapter.log.debug('getter: ' + name + ' returns ' + ret);\n Object.defineProperty(obj, name, { value: ret });\n return ret;\n}\n\nexport class EventObj {\n public id: string;\n public state: ioBroker.State;\n public newState: ioBroker.State;\n public oldState: ioBroker.State;\n\n constructor(\n id: string,\n state: ioBroker.State | null | undefined,\n oldState?: ioBroker.State | null,\n context?: JavascriptContext,\n ) {\n if (context && !gContext) {\n gContext = context;\n }\n this.id = id;\n if (!state) {\n this.newState = { q: undefined, c: undefined, user: undefined } as ioBroker.State;\n } else {\n this.newState = {\n val: state.val,\n ts: state.ts,\n ack: state.ack,\n lc: state.lc,\n from: state.from,\n q: state.q,\n c: state.c,\n user: state.user,\n };\n }\n // if (oldState === undefined) oldState = {};\n if (!oldState) {\n this.oldState = {\n q: undefined,\n c: undefined,\n user: undefined,\n } as ioBroker.State;\n } else {\n this.oldState = {\n val: oldState.val,\n ts: oldState.ts,\n ack: oldState.ack,\n lc: oldState.lc,\n from: oldState.from,\n q: oldState.q,\n c: oldState.c,\n user: oldState.user,\n };\n }\n this.state = this.newState;\n }\n\n get common(): ioBroker.ObjectCommon {\n const ret = gContext.objects[this.id] ? gContext.objects[this.id].common : {};\n return doGetter(this, 'common', ret);\n }\n get native(): Record {\n const ret = gContext.objects[this.id] ? gContext.objects[this.id].native : {};\n return doGetter(this, 'native', ret);\n }\n get name(): ioBroker.StringOrTranslated {\n const ret = this.common ? this.common.name : null;\n return doGetter(this, 'name', ret);\n }\n get channelId(): string | null {\n const ret = this.id.replace(/\\.*[^.]+$/, '');\n return doGetter(this, 'channelId', gContext.objects[ret] ? ret : null);\n }\n get channelName(): string | null {\n const channelId = this.channelId;\n const ret = channelId && gContext.objects[channelId].common ? gContext.objects[channelId].common.name : null;\n return doGetter(this, 'channelName', ret);\n }\n get deviceId(): string | null {\n let deviceId: string;\n const channelId = this.channelId;\n if (!channelId || !(deviceId = channelId.replace(/\\.*[^.]+$/, '')) || !gContext.objects[deviceId]) {\n Object.defineProperty(this, 'deviceName', { value: null });\n return doGetter(this, 'deviceId', null);\n }\n return doGetter(this, 'deviceId', deviceId);\n }\n get deviceName(): ioBroker.StringOrTranslated | null {\n const deviceId = this.deviceId;\n const ret = deviceId && gContext.objects[deviceId].common ? gContext.objects[deviceId].common.name : null;\n return doGetter(this, 'deviceName', ret);\n }\n get enumIds(): string[] | undefined {\n if (!gContext.isEnums) {\n return undefined;\n }\n const enumIds: string[] = [];\n const enumNames: string[] = [];\n getObjectEnumsSync(gContext, this.id, enumIds, enumNames);\n Object.defineProperty(this, 'enumNames', { value: enumNames });\n return doGetter(this, 'enumIds', enumIds);\n }\n get enumNames(): string[] | undefined {\n if (!gContext.isEnums) {\n return undefined;\n }\n const enumIds: string[] = [];\n const enumNames: string[] = [];\n getObjectEnumsSync(gContext, this.id, enumIds, enumNames);\n Object.defineProperty(this, 'enumIds', { value: enumIds });\n return doGetter(this, 'enumNames', enumNames);\n }\n}\n\nexport function createEventObject(\n context: JavascriptContext,\n id: string,\n state: ioBroker.State | null | undefined,\n oldState: ioBroker.State | null | undefined,\n): EventObj {\n gContext = gContext || context;\n\n return new EventObj(id, state, oldState, context);\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/inspect.js b/build-backend/lib/inspect.js new file mode 100644 index 00000000..35851552 --- /dev/null +++ b/build-backend/lib/inspect.js @@ -0,0 +1,679 @@ +"use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.NodeInspector = void 0; +/* + * Copyright Node.js contributors. All rights reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ +const node_child_process_1 = require("node:child_process"); +const node_events_1 = require("node:events"); +const node_net_1 = require("node:net"); +const node_util_1 = require("node:util"); +const node_path_1 = require("node:path"); +const node_fs_1 = require("node:fs"); +// @ts-expect-error no types available +const inspect_client_1 = __importDefault(require("node-inspect/lib/internal/inspect_client")); +const debugger_1 = __importDefault(require("./debugger")); +// const runAsStandalone = typeof __dirname !== 'undefined'; +const breakOnStart = process.argv.includes('--breakOnStart'); +const debuglog = (0, node_util_1.debuglog)('inspect'); +let inspector; +let scriptToDebug = ''; // script.js.yy +let instanceToDebug = ''; // adapter.X +let alreadyPausedOnFirstLine = false; +class StartupError extends Error { + constructor(message) { + super(message); + this.name = 'StartupError'; + } +} +function portIsFree(host, port, timeout = 9999) { + if (port === 0) { + // Binding to a random port. + return Promise.resolve(); + } + const retryDelay = 150; + let didTimeOut = false; + return new Promise((resolve, reject) => { + setTimeout(() => { + didTimeOut = true; + reject(new StartupError(`Timeout (${timeout}) waiting for ${host}:${port} to be free`)); + }, timeout); + function pingPort() { + if (didTimeOut) { + return; + } + const socket = (0, node_net_1.connect)(port, host); + let didRetry = false; + function retry() { + if (!didRetry && !didTimeOut) { + didRetry = true; + setTimeout(pingPort, retryDelay); + } + } + socket.on('error', (error) => { + if (error.code === 'ECONNREFUSED') { + resolve(); + } + else { + retry(); + } + }); + socket.on('connect', () => { + socket.destroy(); + retry(); + }); + } + pingPort(); + }); +} +function runScript(script, scriptArgs, inspectHost, inspectPort, childPrint) { + script = (0, node_path_1.normalize)(script); + return portIsFree(inspectHost, inspectPort).then(() => { + return new Promise(resolve => { + const args = [breakOnStart ? `--inspect-brk=${inspectPort}` : `--inspect=${inspectPort}`].concat([script], scriptArgs || []); + const child = (0, node_child_process_1.spawn)(process.execPath, args); + child.stdout.setEncoding('utf8'); + child.stderr.setEncoding('utf8'); + child.stdout.on('data', childPrint); + child.stderr.on('data', text => childPrint(text, true)); + let output = ''; + function waitForListenHint(text) { + output += text; + const res = /Debugger listening on ws:\/\/\[?(.+?)]?:(\d+)\//.exec(output); + if (res) { + const host = res[1]; + const port = Number.parseInt(res[2]); + child.stderr.removeListener('data', waitForListenHint); + resolve([child, port, host]); + } + } + child.stderr.on('data', waitForListenHint); + }); + }); +} +function createAgentProxy(domain, client) { + const agent = new node_events_1.EventEmitter(); + agent.then = (...args) => { + // TODO: potentially fetch the protocol and pretty-print it here. + const descriptor = { + [node_util_1.inspect.custom](_depth, { stylize }) { + return stylize(`[Agent ${domain}]`, 'special'); + }, + }; + return Promise.resolve(descriptor).then(...args); + }; + return new Proxy(agent, { + get(target, name) { + if (name in target) { + return target[name]; + } + return function callVirtualMethod(params) { + return client.callMethod(`${domain}.${name}`, params); + }; + }, + }); +} +class NodeInspector { + options; + stdin; + stdout; + scripts; + delayedContext; + paused; + child; + _runScript; + client; + Debugger; + HeapProfiler; + Profiler; + Runtime; + handleDebugEvent; + mainScriptId; + mainFile; + repl; + constructor(options, stdin, stdout) { + this.options = options; + this.stdin = stdin; + this.stdout = stdout; + this.scripts = {}; + this.delayedContext = null; + this.paused = true; + this.child = null; + if (options.script) { + this._runScript = runScript.bind(null, options.script, options.scriptArgs, options.host, options.port, this.childPrint.bind(this)); + } + else { + this._runScript = () => Promise.resolve([null, options.port, options.host]); + } + this.client = new inspect_client_1.default(); + this.Debugger = createAgentProxy('Debugger', this.client); + this.HeapProfiler = createAgentProxy('HeapProfiler', this.client); + this.Profiler = createAgentProxy('Profiler', this.client); + this.Runtime = createAgentProxy('Runtime', this.client); + this.handleDebugEvent = (fullName, params) => { + const [domain, name] = fullName.split('.'); + if (domain === 'Debugger' && name === 'scriptParsed') { + // console.log(`Parsed: ${params.url}`); + if ((scriptToDebug && params.url.includes(scriptToDebug)) || + (instanceToDebug && params.url.includes(instanceToDebug))) { + console.log(`My scriptID: ${params.scriptId}`); + this.mainScriptId = params.scriptId; + this.mainFile = params.url.replace('file:///', ''); + // load text of a script + this.scripts[this.mainScriptId] = this.Debugger.getScriptSource({ + scriptId: this.mainScriptId, + }).then((script) => ({ + script: script.scriptSource, + scriptId: this.mainScriptId, + })); + // sometimes the pause event comes before scriptParsed + if (this.delayedContext) { + console.log('Send to debugger: readyToDebug'); + this.scripts[this.mainScriptId]?.then(data => { + // console.log('Send to debugger: readyToDebug ' + JSON.stringify(data)); + sendToHost({ + cmd: 'readyToDebug', + scriptId: this.mainScriptId, + script: data.script, + context: this.delayedContext, + url: this.mainFile, + }); + this.delayedContext = null; + }); + } + } + return; + } + else if (domain === 'Debugger' && name === 'resumed') { + this.Debugger.emit(name, params); + sendToHost({ cmd: 'resumed', context: params }); + return; + } + else if (domain === 'Debugger' && name === 'paused') { + console.log(`PAUSED!! ${alreadyPausedOnFirstLine}`); + if (!alreadyPausedOnFirstLine && params.reason === 'exception') { + // ignore all exceptions by start + this.Debugger.resume(); + return; + } + //console.warn(fullName + ': => \n' + JSON.stringify(params, null, 2)); + this.Debugger.emit(name, params); + if (!alreadyPausedOnFirstLine) { + alreadyPausedOnFirstLine = true; + // sometimes the pause event comes before scriptParsed + if (this.mainScriptId && this.scripts[this.mainScriptId]) { + this.scripts[this.mainScriptId]?.then(data => sendToHost({ + cmd: 'readyToDebug', + scriptId: data.scriptId, + script: data.script, + context: params, + url: this.mainFile, + })); + } + else { + // store context to send it later when script ID will be known + this.delayedContext = params; + console.log('PAUSED, but no scriptId'); + } + } + else { + // this.scripts[params.loca] + // .then(data => + sendToHost({ cmd: 'paused', context: params }); + } + return; + } + if (domain === 'Runtime') { + //console.warn(fullName + ': => \n' + JSON.stringify(params, null, 2)); + } + if (domain === 'Runtime' && name === 'consoleAPICalled') { + const text = params.args[0].value; + if (instanceToDebug) { + sendToHost({ + cmd: 'log', + severity: params.type === 'warning' ? 'warn' : 'error', + text, + ts: Date.now(), + }); + } + else if (text.includes(`$$${scriptToDebug}$$`)) { + console.log(`${fullName} [${params.executionContextId}]: => ${text}`); + const [severity, _text] = text.split(`$$${scriptToDebug}$$`); + sendToHost({ + cmd: 'log', + severity: severity, + text: _text, + ts: params.args[1] && params.args[1].value ? params.args[1].value : Date.now(), + }); + } + else if (params.type === 'warning' || params.type === 'error') { + sendToHost({ + cmd: 'log', + severity: params.type === 'warning' ? 'warn' : 'error', + text, + ts: Date.now(), + }); + } + return; + } + else if (domain === 'Runtime' && (params.id === 2 || params.executionContextId === 2)) { + if (name === 'executionContextCreated') { + console.warn(`${fullName}: =>\n${JSON.stringify(params, null, 2)}`); + } + else if (name === 'executionContextDestroyed') { + console.warn(`${fullName}: =>\n${JSON.stringify(params, null, 2)}`); + sendToHost({ cmd: 'finished', context: params }); + } + return; + } + else if (domain === 'Runtime' && + name === 'executionContextDestroyed' && + params.executionContextId === 1) { + sendToHost({ cmd: 'finished', context: params }); + console.log('Exited!'); + setTimeout(() => process.exit(125), 200); + } + else if (domain === 'Debugger' && name === 'scriptFailedToParse') { + // ignore + return; + } + console.warn(`${fullName}: =>\n${JSON.stringify(params, null, 2)}`); + /*if (domain in this) { + this[domain].emit(name, params); + }*/ + }; + this.client.on('debugEvent', this.handleDebugEvent); + const startRepl = (0, debugger_1.default)(this); + // Handle all possible exits + process.on('exit', () => this.killChild()); + process.once('SIGTERM', process.exit.bind(process, 0)); + process.once('SIGHUP', process.exit.bind(process, 0)); + this.run() + .then(() => startRepl()) + .then(repl => { + this.repl = repl; + this.repl.on('exit', () => process.exit(0)); + this.paused = false; + }) + .then(null, error => process.nextTick(() => { + throw error; + })); + } + suspendReplWhile(fn) { + if (this.repl) { + this.repl.pause(); + } + this.stdin.pause(); + this.paused = true; + return new Promise(resolve => resolve(fn())) + .then(() => { + this.paused = false; + if (this.repl) { + this.repl.resume(); + this.repl.displayPrompt(); + } + this.stdin.resume(); + }) + .then(null, error => process.nextTick(() => { + throw error; + })); + } + killChild() { + this.client.reset(); + if (this.child) { + this.child.kill(); + this.child = null; + } + } + run() { + this.killChild(); + return this._runScript().then(([child, port, host]) => { + this.child = child; + let connectionAttempts = 0; + const attemptConnect = () => { + ++connectionAttempts; + debuglog('connection attempt #%d', connectionAttempts); + this.stdout.write('.'); + return this.client.connect(port, host).then(() => { + debuglog('connection established'); + this.stdout.write(' ok'); + }, (error) => { + debuglog('connect failed', error); + // If it's failed to connect 10 times, then print a failed message + if (connectionAttempts >= 10) { + this.stdout.write(' failed to connect, please retry\n'); + process.exit(1); + } + return new Promise(resolve => setTimeout(resolve, 500)).then(attemptConnect); + }); + }; + this.print(`connecting to ${host}:${port} ..`, true); + return attemptConnect(); + }); + } + clearLine() { + if (this.stdout.isTTY) { + this.stdout.cursorTo(0); + this.stdout.clearLine(1); + } + else { + this.stdout.write('\b'); + } + } + print(text, oneLine = false) { + this.clearLine(); + this.stdout.write(oneLine ? text : `${text}\n`); + } + childPrint(text, isError) { + isError && + this.print(text + .toString() + .split(/\r\n|\r|\n/g) + .filter((chunk) => !!chunk) + .map((chunk) => `< ${chunk}`) + .join('\n')); + if (!this.paused) { + this.repl?.displayPrompt(true); + } + if (/Waiting for the debugger to disconnect\.\.\.\n$/.test(text)) { + this.killChild(); + sendToHost({ cmd: 'finished', text }); + } + } +} +exports.NodeInspector = NodeInspector; +function parseArgv([target, ...args]) { + let host = '127.0.0.1'; + let port = 9229; + let isRemote = false; + let script = target; + let scriptArgs = args; + const hostMatch = target.match(/^([^:]+):(\d+)$/); + const portMatch = target.match(/^--port=(\d+)$/); + if (hostMatch) { + // Connecting to remote debugger + // `node-inspect localhost:9229` + host = hostMatch[1]; + port = parseInt(hostMatch[2], 10); + isRemote = true; + script = null; + } + else if (portMatch) { + // start debugee on custom port + // `node inspect --port=9230 script.js` + port = parseInt(portMatch[1], 10); + script = args[0]; + scriptArgs = args.slice(1); + } + else if (args.length === 1 && /^\d+$/.test(args[0]) && target === '-p') { + // Start debugger against a given pid + const pid = parseInt(args[0], 10); + try { + // Windows does not support UNIX signals. To enable debugging, you can use an undocumented API function + // https://github.com/node-inspector/node-inspector?tab=readme-ov-file#windows + // @ts-expect-error undocumented function + process._debugProcess(pid); + } + catch (e) { + if (e.code === 'ESRCH') { + console.error(`Target process: ${pid} doesn't exist.`); + process.exit(1); + } + throw e; + } + script = null; + isRemote = true; + } + return { + host, + port, + isRemote, + script, + scriptArgs, + }; +} +function startInspect(argv = process.argv.slice(2), stdin = process.stdin, stdout = process.stdout) { + /* + if (argv.length < 1) { + const invokedAs = runAsStandalone ? 'node-inspect' : `${process.argv0} ${process.argv[1]}`; + + console.error(`Usage: ${invokedAs} script.js`); + console.error(` ${invokedAs} :`); + console.error(` ${invokedAs} -p `); + process.exit(1); + } + */ + const options = parseArgv(argv); + inspector = new NodeInspector(options, stdin, stdout); + stdin.resume(); + function handleUnexpectedError(e) { + if (!(e instanceof StartupError)) { + console.error('There was an internal error in node-inspect. Please report this bug.'); + console.error(e.message); + console.error(e.stack); + } + else { + console.error(e.message); + } + inspector.child?.kill(); + process.exit(1); + } + process.on('uncaughtException', handleUnexpectedError); +} +function extractErrorMessage(stack) { + if (!stack) { + return ''; + } + const m = stack.match(/^\w+: ([^\n]+)/); + return m ? m[1] : stack; +} +function convertResultToError(result) { + const { className, description } = result; + const err = new Error(extractErrorMessage(description)); + err.stack = description; + Object.defineProperty(err, 'name', { value: className }); + return err; +} +process.on('message', (message) => { + if (typeof message === 'string') { + try { + message = JSON.parse(message); + } + catch { + return console.error(`Cannot parse: ${JSON.stringify(message)}`); + } + } + processCommand(message); +}); +sendToHost({ cmd: 'ready' }); +function processCommand(data) { + if (data.cmd === 'start') { + scriptToDebug = data.scriptName; + // we can request the script by name or iobroker instance to debug + if (scriptToDebug) { + startInspect([ + `${__dirname}/../main.js`, + (data.instance || 0).toString(), + '--debug', + '--debugScript', + scriptToDebug, + ]); + } + else { + instanceToDebug = data.adapterInstance; + const [adapter, instance] = instanceToDebug.split('.'); + let file; + try { + file = require.resolve(`iobroker.${adapter}`); + } + catch (e) { + // try to locate in the same dir + const dir = (0, node_path_1.normalize)((0, node_path_1.join)(__dirname, '..', `iobroker.${adapter}`)); + if ((0, node_fs_1.existsSync)(dir)) { + const pack = require((0, node_path_1.join)(dir, 'package.json')); + if ((0, node_fs_1.existsSync)((0, node_path_1.join)(dir, pack.main || `${adapter}.js`))) { + file = (0, node_path_1.join)(dir, pack.main || `${adapter}.js`); + } + } + if (!file) { + sendToHost({ cmd: 'error', error: `Cannot locate iobroker.${adapter}`, errorContext: e }); + setTimeout(() => { + sendToHost({ cmd: 'finished', context: `Cannot locate iobroker.${adapter}` }); + setTimeout(() => process.exit(124), 500); + }, 200); + return; + } + } + file = file.replace(/\\/g, '/'); + instanceToDebug = file; + console.log(`Start ${file} ${instance} --debug`); + startInspect([file, instance, '--debug']); + } + } + else if (data.cmd === 'end') { + process.exit(); + } + else if (data.cmd === 'source') { + inspector.Debugger.getScriptSource({ scriptId: data.scriptId }).then((script) => sendToHost({ cmd: 'script', scriptId: data.scriptId, text: script.scriptSource })); + } + else if (data.cmd === 'cont') { + inspector.Debugger.resume().catch((e) => sendToHost({ cmd: 'error', error: e })); + } + else if (data.cmd === 'next') { + inspector.Debugger.stepOver().catch((e) => sendToHost({ cmd: 'error', error: e })); + } + else if (data.cmd === 'pause') { + inspector.Debugger.pause().catch((e) => sendToHost({ cmd: 'error', error: e })); + } + else if (data.cmd === 'step') { + inspector.Debugger.stepInto().catch((e) => sendToHost({ cmd: 'error', error: e })); + } + else if (data.cmd === 'out') { + inspector.Debugger.stepOut().catch((e) => sendToHost({ cmd: 'error', error: e })); + } + else if (data.cmd === 'sb') { + console.log(JSON.stringify(data)); + Promise.all(data.breakpoints?.map((bp) => inspector.Debugger.setBreakpoint({ + location: { + scriptId: bp.scriptId, + lineNumber: bp.lineNumber, + columnNumber: bp.columnNumber, + }, + }) + .then((result) => ({ + id: result.breakpointId, + location: result.actualLocation, + })) + .catch((e) => sendToHost({ cmd: 'error', error: `Cannot set breakpoint: ${e}`, errorContext: e, bp }))) || []).then(breakpoints => sendToHost({ cmd: 'sb', breakpoints })); + } + else if (data.cmd === 'cb') { + Promise.all(data.breakpoints?.map(breakpointId => inspector.Debugger.removeBreakpoint({ breakpointId }) + .then(() => breakpointId) + .catch((e) => sendToHost({ + cmd: 'error', + error: `Cannot clear breakpoint: ${e}`, + errorContext: e, + id: breakpointId, + }))) || []).then(breakpoints => sendToHost({ cmd: 'cb', breakpoints })); + } + else if (data.cmd === 'watch') { + Promise.all(data.expressions?.map(expr => inspector.Debugger.watch(expr).catch((e) => sendToHost({ cmd: 'error', error: `Cannot watch expr: ${e}`, errorContext: e, expr }))) || []).then(() => console.log('Watch done')); + } + else if (data.cmd === 'unwatch') { + Promise.all(data.expressions?.map(expr => inspector.Debugger.unwatch(expr).catch((e) => sendToHost({ cmd: 'error', error: `Cannot unwatch expr: ${e}`, errorContext: e, expr }))) || []).then(() => console.log('Watch done')); + } + else if (data.cmd === 'scope') { + Promise.all(data.scopes + ?.filter(scope => scope?.object && scope.object.objectId) + .map(scope => inspector.Runtime.getProperties({ + objectId: scope.object.objectId, + generatePreview: true, + }) + .then((result) => ({ type: scope.type, properties: result })) + .catch((e) => sendToHost({ cmd: 'error', error: `Cannot get scopes expr: ${e}`, errorContext: e }))) || []).then(scopes => sendToHost({ cmd: 'scope', scopes })); + } + else if (data.cmd === 'setValue') { + inspector.Debugger.setVariableValue({ + variableName: data.variableName, + scopeNumber: data.scopeNumber, + newValue: data.newValue, + callFrameId: data.callFrameId, + }) + .catch((e) => sendToHost({ cmd: 'setValue', variableName: `Cannot setValue: ${e}`, errorContext: e })) + .then(() => sendToHost({ + cmd: 'setValue', + variableName: data.variableName, + scopeNumber: data.scopeNumber, + newValue: data.newValue, + callFrameId: data.callFrameId, + })); + } + else if (data.cmd === 'expressions') { + Promise.all(data.expressions?.map(item => inspector.Debugger.evaluateOnCallFrame({ + callFrameId: data.callFrameId, + expression: item.name, + objectGroup: 'node-inspect', + returnByValue: true, + generatePreview: true, + }) + // @ts-expect-error fix later + .then(({ result, wasThrown }) => { + if (wasThrown) { + return { name: item.name, result: convertResultToError(result) }; + } + return { name: item.name, result }; + }) + .catch((e) => sendToHost({ cmd: 'expressions', variableName: `Cannot setValue: ${e}`, errorContext: e }))) || []).then(expressions => sendToHost({ cmd: 'expressions', expressions })); + } + else if (data.cmd === 'stopOnException') { + inspector.Debugger.setPauseOnExceptions({ + state: data.state ? 'all' : 'none', + }).catch((e) => sendToHost({ cmd: 'stopOnException', variableName: `Cannot stopOnException: ${e}`, errorContext: e })); + } + else if (data.cmd === 'getPossibleBreakpoints') { + inspector.Debugger.getPossibleBreakpoints({ start: data.start, end: data.end }) + .then((breakpoints) => sendToHost({ cmd: 'getPossibleBreakpoints', breakpoints: breakpoints.locations })) + .catch((e) => sendToHost({ + cmd: 'getPossibleBreakpoints', + variableName: `Cannot getPossibleBreakpoints: ${e}`, + errorContext: e, + })); + } + else { + console.error(`Unknown command: ${JSON.stringify(data)}`); + } +} +function sendToHost(data) { + if (data.cmd === 'error') { + console.error(data.text); + if (data.expr) { + console.error(`[EXPRESSION] ${JSON.stringify(data.expr)}`); + } + if (data.bp) { + console.error(`[BP] ${JSON.stringify(data.bp)}`); + } + } + process.send && process.send(JSON.stringify(data)); +} +//# sourceMappingURL=inspect.js.map \ No newline at end of file diff --git a/build-backend/lib/inspect.js.map b/build-backend/lib/inspect.js.map new file mode 100644 index 00000000..4c3d8488 --- /dev/null +++ b/build-backend/lib/inspect.js.map @@ -0,0 +1 @@ +{"version":3,"file":"inspect.js","sourceRoot":"","sources":["../../src/lib/inspect.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright Node.js contributors. All rights reserved.\n *\n * Permission is hereby granted, free of charge, to any person obtaining a copy\n * of this software and associated documentation files (the \"Software\"), to\n * deal in the Software without restriction, including without limitation the\n * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or\n * sell copies of the Software, and to permit persons to whom the Software is\n * furnished to do so, subject to the following conditions:\n *\n * The above copyright notice and this permission notice shall be included in\n * all copies or substantial portions of the Software.\n *\n * THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n * IN THE SOFTWARE.\n */\nimport { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process';\nimport { EventEmitter } from 'node:events';\nimport { connect } from 'node:net';\nimport { debuglog as utilDebugLog, inspect, type InspectOptionsStylized } from 'node:util';\nimport { normalize, join } from 'node:path';\nimport { existsSync } from 'node:fs';\nimport type { WriteStream, ReadStream } from 'node:tty';\n\n// @ts-expect-error no types available\nimport InspectClient from 'node-inspect/lib/internal/inspect_client';\nimport type { Debugger, Runtime } from 'node:inspector';\nimport type { REPLServer } from 'repl';\nimport createRepl from './debugger';\n// const runAsStandalone = typeof __dirname !== 'undefined';\n\nconst breakOnStart = process.argv.includes('--breakOnStart');\n\nconst debuglog = utilDebugLog('inspect');\nlet inspector: NodeInspector;\nlet scriptToDebug = ''; // script.js.yy\nlet instanceToDebug = ''; // adapter.X\nlet alreadyPausedOnFirstLine = false;\n\nclass StartupError extends Error {\n constructor(message: string) {\n super(message);\n this.name = 'StartupError';\n }\n}\n\nfunction portIsFree(host: string, port: number, timeout: number = 9999): Promise {\n if (port === 0) {\n // Binding to a random port.\n return Promise.resolve();\n }\n\n const retryDelay = 150;\n let didTimeOut = false;\n\n return new Promise((resolve, reject) => {\n setTimeout(() => {\n didTimeOut = true;\n reject(new StartupError(`Timeout (${timeout}) waiting for ${host}:${port} to be free`));\n }, timeout);\n\n function pingPort(): void {\n if (didTimeOut) {\n return;\n }\n\n const socket = connect(port, host);\n let didRetry = false;\n function retry(): void {\n if (!didRetry && !didTimeOut) {\n didRetry = true;\n setTimeout(pingPort, retryDelay);\n }\n }\n\n socket.on('error', (error: Error) => {\n if ((error as any).code === 'ECONNREFUSED') {\n resolve();\n } else {\n retry();\n }\n });\n socket.on('connect', () => {\n socket.destroy();\n retry();\n });\n }\n pingPort();\n });\n}\n\nfunction runScript(\n script: string,\n scriptArgs: string[] | undefined,\n inspectHost: string,\n inspectPort: number,\n childPrint: (text: string, isError?: boolean) => void,\n): Promise<[ChildProcessWithoutNullStreams, number, string]> {\n script = normalize(script);\n return portIsFree(inspectHost, inspectPort).then(() => {\n return new Promise(resolve => {\n const args = [breakOnStart ? `--inspect-brk=${inspectPort}` : `--inspect=${inspectPort}`].concat(\n [script],\n scriptArgs || [],\n );\n const child = spawn(process.execPath, args);\n child.stdout.setEncoding('utf8');\n child.stderr.setEncoding('utf8');\n child.stdout.on('data', childPrint);\n child.stderr.on('data', text => childPrint(text, true));\n\n let output = '';\n function waitForListenHint(text: string): void {\n output += text;\n const res = /Debugger listening on ws:\\/\\/\\[?(.+?)]?:(\\d+)\\//.exec(output);\n if (res) {\n const host = res[1];\n const port = Number.parseInt(res[2]);\n child.stderr.removeListener('data', waitForListenHint);\n resolve([child, port, host]);\n }\n }\n\n child.stderr.on('data', waitForListenHint);\n });\n });\n}\n\nfunction createAgentProxy(domain: string, client: InspectClient): ProxyConstructor {\n const agent: any = new EventEmitter();\n\n agent.then = (...args: any[]) => {\n // TODO: potentially fetch the protocol and pretty-print it here.\n const descriptor = {\n [inspect.custom](_depth: number, { stylize }: InspectOptionsStylized): string {\n return stylize(`[Agent ${domain}]`, 'special');\n },\n };\n return Promise.resolve(descriptor).then(...args);\n };\n\n return new Proxy(agent, {\n get(target, name: string) {\n if (name in target) {\n return target[name];\n }\n return function callVirtualMethod(params: any) {\n return client.callMethod(`${domain}.${name}`, params);\n };\n },\n });\n}\n\ntype CommandToHostType =\n | 'log'\n | 'paused'\n | 'resumed'\n | 'setValue'\n | 'scope'\n | 'cb'\n | 'sb'\n | 'script'\n | 'ready'\n | 'readyToDebug'\n | 'error'\n | 'finished'\n | 'expressions'\n | 'stopOnException'\n | 'getPossibleBreakpoints';\n\ntype DebuggerContext = {\n url: string;\n scriptId: Runtime.ScriptId;\n reason: string;\n executionContextId: number;\n type: string;\n id: number;\n args: { value: any }[];\n};\n\ntype CommandToHost = {\n cmd: CommandToHostType;\n text?: string;\n expr?: { name: string };\n bp?: Debugger.Location;\n context?: DebuggerContext | null | string;\n error?: any;\n errorContext?: any;\n id?: Debugger.BreakpointId; // breakpoint ID\n breakpoints?: Debugger.Location[];\n scriptId?: Runtime.ScriptId;\n scopes?: Debugger.Scope[];\n variableName?: string;\n scopeNumber?: number;\n newValue?: string;\n callFrameId?: string;\n expressions?: { name: string; result: any }[];\n script?: string;\n url?: string;\n severity?: 'warn' | 'error';\n ts?: number;\n};\n\ninterface NodeInspectorOptions {\n script?: string | null;\n scriptArgs?: string[];\n isRemote?: boolean;\n host: string;\n port: number;\n}\n\nexport class NodeInspector {\n options: NodeInspectorOptions;\n stdin: ReadStream;\n stdout: WriteStream;\n scripts: Record | null>;\n delayedContext: DebuggerContext | null;\n paused: boolean;\n child: ChildProcessWithoutNullStreams | null;\n _runScript: () => Promise<[ChildProcessWithoutNullStreams | null, number, string]>;\n\n client: InspectClient;\n\n Debugger: InspectClient;\n HeapProfiler: InspectClient;\n Profiler: InspectClient;\n Runtime: InspectClient;\n\n handleDebugEvent: (fullName: string, params: DebuggerContext) => void;\n mainScriptId: Runtime.ScriptId | undefined;\n mainFile: string | undefined;\n repl: REPLServer | undefined;\n\n constructor(options: NodeInspectorOptions, stdin: ReadStream, stdout: WriteStream) {\n this.options = options;\n this.stdin = stdin;\n this.stdout = stdout;\n this.scripts = {};\n this.delayedContext = null;\n\n this.paused = true;\n this.child = null;\n\n if (options.script) {\n this._runScript = runScript.bind(\n null,\n options.script,\n options.scriptArgs,\n options.host,\n options.port,\n this.childPrint.bind(this),\n );\n } else {\n this._runScript = () => Promise.resolve([null, options.port, options.host]);\n }\n\n this.client = new InspectClient();\n\n this.Debugger = createAgentProxy('Debugger', this.client);\n this.HeapProfiler = createAgentProxy('HeapProfiler', this.client);\n this.Profiler = createAgentProxy('Profiler', this.client);\n this.Runtime = createAgentProxy('Runtime', this.client);\n\n this.handleDebugEvent = (\n fullName: string,\n params: {\n url: string;\n scriptId: Runtime.ScriptId;\n reason: string;\n executionContextId: number;\n type: string;\n id: number;\n args: { value: any }[];\n },\n ): void => {\n const [domain, name] = fullName.split('.');\n\n if (domain === 'Debugger' && name === 'scriptParsed') {\n // console.log(`Parsed: ${params.url}`);\n if (\n (scriptToDebug && params.url.includes(scriptToDebug)) ||\n (instanceToDebug && params.url.includes(instanceToDebug))\n ) {\n console.log(`My scriptID: ${params.scriptId}`);\n this.mainScriptId = params.scriptId;\n this.mainFile = params.url.replace('file:///', '');\n // load text of a script\n this.scripts[this.mainScriptId] = this.Debugger.getScriptSource({\n scriptId: this.mainScriptId,\n } as Debugger.GetScriptSourceParameterType).then((script: Debugger.GetScriptSourceReturnType) => ({\n script: script.scriptSource,\n scriptId: this.mainScriptId,\n }));\n\n // sometimes the pause event comes before scriptParsed\n if (this.delayedContext) {\n console.log('Send to debugger: readyToDebug');\n this.scripts[this.mainScriptId]?.then(data => {\n // console.log('Send to debugger: readyToDebug ' + JSON.stringify(data));\n sendToHost({\n cmd: 'readyToDebug',\n scriptId: this.mainScriptId,\n script: data.script,\n context: this.delayedContext,\n url: this.mainFile,\n });\n this.delayedContext = null;\n });\n }\n }\n return;\n } else if (domain === 'Debugger' && name === 'resumed') {\n this.Debugger.emit(name, params);\n sendToHost({ cmd: 'resumed', context: params });\n return;\n } else if (domain === 'Debugger' && name === 'paused') {\n console.log(`PAUSED!! ${alreadyPausedOnFirstLine}`);\n if (!alreadyPausedOnFirstLine && params.reason === 'exception') {\n // ignore all exceptions by start\n this.Debugger.resume();\n return;\n }\n //console.warn(fullName + ': => \\n' + JSON.stringify(params, null, 2));\n this.Debugger.emit(name, params);\n\n if (!alreadyPausedOnFirstLine) {\n alreadyPausedOnFirstLine = true;\n // sometimes the pause event comes before scriptParsed\n if (this.mainScriptId && this.scripts[this.mainScriptId]) {\n this.scripts[this.mainScriptId]?.then(data =>\n sendToHost({\n cmd: 'readyToDebug',\n scriptId: data.scriptId,\n script: data.script,\n context: params,\n url: this.mainFile,\n }),\n );\n } else {\n // store context to send it later when script ID will be known\n this.delayedContext = params;\n console.log('PAUSED, but no scriptId');\n }\n } else {\n // this.scripts[params.loca]\n // .then(data =>\n sendToHost({ cmd: 'paused', context: params });\n }\n return;\n }\n\n if (domain === 'Runtime') {\n //console.warn(fullName + ': => \\n' + JSON.stringify(params, null, 2));\n }\n if (domain === 'Runtime' && name === 'consoleAPICalled') {\n const text = params.args[0].value;\n if (instanceToDebug) {\n sendToHost({\n cmd: 'log',\n severity: params.type === 'warning' ? 'warn' : 'error',\n text,\n ts: Date.now(),\n });\n } else if (text.includes(`$$${scriptToDebug}$$`)) {\n console.log(`${fullName} [${params.executionContextId}]: => ${text}`);\n const [severity, _text] = text.split(`$$${scriptToDebug}$$`);\n sendToHost({\n cmd: 'log',\n severity: severity as 'warn' | 'error',\n text: _text,\n ts: params.args[1] && params.args[1].value ? (params.args[1].value as number) : Date.now(),\n });\n } else if (params.type === 'warning' || params.type === 'error') {\n sendToHost({\n cmd: 'log',\n severity: params.type === 'warning' ? 'warn' : 'error',\n text,\n ts: Date.now(),\n });\n }\n return;\n } else if (domain === 'Runtime' && (params.id === 2 || params.executionContextId === 2)) {\n if (name === 'executionContextCreated') {\n console.warn(`${fullName}: =>\\n${JSON.stringify(params, null, 2)}`);\n } else if (name === 'executionContextDestroyed') {\n console.warn(`${fullName}: =>\\n${JSON.stringify(params, null, 2)}`);\n sendToHost({ cmd: 'finished', context: params });\n }\n return;\n } else if (\n domain === 'Runtime' &&\n name === 'executionContextDestroyed' &&\n params.executionContextId === 1\n ) {\n sendToHost({ cmd: 'finished', context: params });\n console.log('Exited!');\n setTimeout(() => process.exit(125), 200);\n } else if (domain === 'Debugger' && name === 'scriptFailedToParse') {\n // ignore\n return;\n }\n\n console.warn(`${fullName}: =>\\n${JSON.stringify(params, null, 2)}`);\n\n /*if (domain in this) {\n this[domain].emit(name, params);\n }*/\n };\n this.client.on('debugEvent', this.handleDebugEvent);\n const startRepl: () => REPLServer = createRepl(this);\n\n // Handle all possible exits\n process.on('exit', () => this.killChild());\n process.once('SIGTERM', process.exit.bind(process, 0));\n process.once('SIGHUP', process.exit.bind(process, 0));\n\n this.run()\n .then(() => startRepl())\n .then(repl => {\n this.repl = repl;\n this.repl.on('exit', () => process.exit(0));\n this.paused = false;\n })\n .then(null, error =>\n process.nextTick(() => {\n throw error;\n }),\n );\n }\n\n suspendReplWhile(fn: () => any): Promise {\n if (this.repl) {\n this.repl.pause();\n }\n this.stdin.pause();\n this.paused = true;\n\n return new Promise(resolve => resolve(fn()))\n .then(() => {\n this.paused = false;\n if (this.repl) {\n this.repl.resume();\n this.repl.displayPrompt();\n }\n this.stdin.resume();\n })\n .then(null, error =>\n process.nextTick(() => {\n throw error;\n }),\n );\n }\n\n killChild(): void {\n this.client.reset();\n if (this.child) {\n this.child.kill();\n this.child = null;\n }\n }\n\n run(): Promise {\n this.killChild();\n\n return this._runScript().then(([child, port, host]) => {\n this.child = child;\n\n let connectionAttempts = 0;\n const attemptConnect = (): void => {\n ++connectionAttempts;\n debuglog('connection attempt #%d', connectionAttempts);\n this.stdout.write('.');\n return this.client.connect(port, host).then(\n () => {\n debuglog('connection established');\n this.stdout.write(' ok');\n },\n (error: unknown): Promise => {\n debuglog('connect failed', error);\n // If it's failed to connect 10 times, then print a failed message\n if (connectionAttempts >= 10) {\n this.stdout.write(' failed to connect, please retry\\n');\n process.exit(1);\n }\n\n return new Promise(resolve => setTimeout(resolve, 500)).then(attemptConnect);\n },\n );\n };\n\n this.print(`connecting to ${host}:${port} ..`, true);\n return attemptConnect();\n });\n }\n\n clearLine(): void {\n if (this.stdout.isTTY) {\n this.stdout.cursorTo(0);\n this.stdout.clearLine(1);\n } else {\n this.stdout.write('\\b');\n }\n }\n\n print(text: string, oneLine: boolean = false): void {\n this.clearLine();\n this.stdout.write(oneLine ? text : `${text}\\n`);\n }\n\n childPrint(text: string, isError?: boolean): void {\n isError &&\n this.print(\n text\n .toString()\n .split(/\\r\\n|\\r|\\n/g)\n .filter((chunk: string) => !!chunk)\n .map((chunk: string) => `< ${chunk}`)\n .join('\\n'),\n );\n if (!this.paused) {\n this.repl?.displayPrompt(true);\n }\n if (/Waiting for the debugger to disconnect\\.\\.\\.\\n$/.test(text)) {\n this.killChild();\n sendToHost({ cmd: 'finished', text });\n }\n }\n}\n\nfunction parseArgv([target, ...args]: string[]): NodeInspectorOptions {\n let host = '127.0.0.1';\n let port = 9229;\n let isRemote = false;\n let script: string | null = target;\n let scriptArgs = args;\n\n const hostMatch = target.match(/^([^:]+):(\\d+)$/);\n const portMatch = target.match(/^--port=(\\d+)$/);\n\n if (hostMatch) {\n // Connecting to remote debugger\n // `node-inspect localhost:9229`\n host = hostMatch[1];\n port = parseInt(hostMatch[2], 10);\n isRemote = true;\n script = null;\n } else if (portMatch) {\n // start debugee on custom port\n // `node inspect --port=9230 script.js`\n port = parseInt(portMatch[1], 10);\n script = args[0];\n scriptArgs = args.slice(1);\n } else if (args.length === 1 && /^\\d+$/.test(args[0]) && target === '-p') {\n // Start debugger against a given pid\n const pid = parseInt(args[0], 10);\n try {\n // Windows does not support UNIX signals. To enable debugging, you can use an undocumented API function\n // https://github.com/node-inspector/node-inspector?tab=readme-ov-file#windows\n // @ts-expect-error undocumented function\n process._debugProcess(pid);\n } catch (e: any) {\n if (e.code === 'ESRCH') {\n console.error(`Target process: ${pid} doesn't exist.`);\n process.exit(1);\n }\n throw e;\n }\n script = null;\n isRemote = true;\n }\n\n return {\n host,\n port,\n isRemote,\n script,\n scriptArgs,\n };\n}\n\nfunction startInspect(\n argv: string[] = process.argv.slice(2),\n stdin: ReadStream = process.stdin,\n stdout: WriteStream = process.stdout,\n): void {\n /*\n if (argv.length < 1) {\n const invokedAs = runAsStandalone ? 'node-inspect' : `${process.argv0} ${process.argv[1]}`;\n\n console.error(`Usage: ${invokedAs} script.js`);\n console.error(` ${invokedAs} :`);\n console.error(` ${invokedAs} -p `);\n process.exit(1);\n }\n */\n\n const options = parseArgv(argv);\n inspector = new NodeInspector(options, stdin, stdout);\n\n stdin.resume();\n\n function handleUnexpectedError(e: Error): void {\n if (!(e instanceof StartupError)) {\n console.error('There was an internal error in node-inspect. Please report this bug.');\n console.error(e.message);\n console.error(e.stack);\n } else {\n console.error(e.message);\n }\n inspector.child?.kill();\n process.exit(1);\n }\n\n process.on('uncaughtException', handleUnexpectedError);\n}\n\nfunction extractErrorMessage(stack: string | undefined): string {\n if (!stack) {\n return '';\n }\n const m = stack.match(/^\\w+: ([^\\n]+)/);\n return m ? m[1] : stack;\n}\n\nfunction convertResultToError(result: Runtime.RemoteObject): Error {\n const { className, description } = result;\n const err = new Error(extractErrorMessage(description));\n err.stack = description;\n Object.defineProperty(err, 'name', { value: className });\n return err;\n}\n\nprocess.on('message', (message: DebugCommand | string): void => {\n if (typeof message === 'string') {\n try {\n message = JSON.parse(message) as DebugCommand;\n } catch {\n return console.error(`Cannot parse: ${JSON.stringify(message)}`);\n }\n }\n processCommand(message);\n});\n\nsendToHost({ cmd: 'ready' });\n\n// possible commands\n// start - {cmd: 'start', scriptName: 'script.js.myName'} - start the debugging\n// end - {cmd: 'end'} - end the debugging and stop process\n// source - {cmd: 'source', scriptId} - read text of script by id\n// watch - {cmd: 'watch', expressions: ['i']} - add to watch the variable\n// unwatch - {cmd: 'unwatch', expressions: ['i']} - add to watch the variable\n\n// sb - {cmd: 'sb', breakpoints: [{scriptId: 50, lineNumber: 4, columnNumber: 0}]} - set breakpoint\n// cb - {cmd: 'cb', breakpoints: [{scriptId: 50, lineNumber: 4, columnNumber: 0}]} - clear breakpoint\n\n// pause - {cmd: 'pause'} - pause execution\n// cont - {cmd: 'cont'} - resume execution\n// next - {cmd: 'next'} - Continue to next line in current file\n// step - {cmd: 'step'} - Step into, potentially entering a function\n// out - {cmd: 'step'} - Step out, leaving the current function\n\ntype DebugCommandType =\n | 'start'\n | 'end'\n | 'source'\n | 'watch'\n | 'unwatch'\n | 'sb'\n | 'cb'\n | 'pause'\n | 'cont'\n | 'next'\n | 'step'\n | 'out'\n | 'scope'\n | 'setValue'\n | 'expressions'\n | 'stopOnException'\n | 'getPossibleBreakpoints'\n | 'error';\n\ntype DebugCommand = {\n cmd: DebugCommandType;\n scriptName?: string;\n scriptId?: Runtime.ScriptId;\n instance?: number;\n adapterInstance?: string;\n breakpoints?: Debugger.Location[] | Debugger.BreakpointId[];\n expressions?: { name: string }[];\n scopes?: Debugger.Scope[];\n\n variableName?: string;\n scopeNumber?: number;\n newValue?: string;\n callFrameId?: string;\n state?: boolean;\n\n start?: number;\n end?: number;\n};\n\nfunction processCommand(data: DebugCommand): void {\n if (data.cmd === 'start') {\n scriptToDebug = data.scriptName as string;\n // we can request the script by name or iobroker instance to debug\n if (scriptToDebug) {\n startInspect([\n `${__dirname}/../main.js`,\n (data.instance || 0).toString(),\n '--debug',\n '--debugScript',\n scriptToDebug,\n ]);\n } else {\n instanceToDebug = data.adapterInstance as string;\n const [adapter, instance] = instanceToDebug.split('.');\n let file: string | undefined;\n try {\n file = require.resolve(`iobroker.${adapter}`);\n } catch (e: any) {\n // try to locate in the same dir\n const dir = normalize(join(__dirname, '..', `iobroker.${adapter}`));\n if (existsSync(dir)) {\n const pack = require(join(dir, 'package.json'));\n if (existsSync(join(dir, pack.main || `${adapter}.js`))) {\n file = join(dir, pack.main || `${adapter}.js`);\n }\n }\n\n if (!file) {\n sendToHost({ cmd: 'error', error: `Cannot locate iobroker.${adapter}`, errorContext: e });\n setTimeout(() => {\n sendToHost({ cmd: 'finished', context: `Cannot locate iobroker.${adapter}` });\n setTimeout(() => process.exit(124), 500);\n }, 200);\n return;\n }\n }\n file = file.replace(/\\\\/g, '/');\n instanceToDebug = file;\n console.log(`Start ${file} ${instance} --debug`);\n startInspect([file, instance, '--debug']);\n }\n } else if (data.cmd === 'end') {\n process.exit();\n } else if (data.cmd === 'source') {\n inspector.Debugger.getScriptSource({ scriptId: data.scriptId } as Debugger.GetScriptSourceParameterType).then(\n (script: Debugger.GetScriptSourceReturnType) =>\n sendToHost({ cmd: 'script', scriptId: data.scriptId, text: script.scriptSource }),\n );\n } else if (data.cmd === 'cont') {\n inspector.Debugger.resume().catch((e: any) => sendToHost({ cmd: 'error', error: e }));\n } else if (data.cmd === 'next') {\n inspector.Debugger.stepOver().catch((e: any) => sendToHost({ cmd: 'error', error: e }));\n } else if (data.cmd === 'pause') {\n inspector.Debugger.pause().catch((e: any) => sendToHost({ cmd: 'error', error: e }));\n } else if (data.cmd === 'step') {\n inspector.Debugger.stepInto().catch((e: any) => sendToHost({ cmd: 'error', error: e }));\n } else if (data.cmd === 'out') {\n inspector.Debugger.stepOut().catch((e: any) => sendToHost({ cmd: 'error', error: e }));\n } else if (data.cmd === 'sb') {\n console.log(JSON.stringify(data));\n\n Promise.all(\n (data.breakpoints as Debugger.Location[])?.map((bp: Debugger.Location) =>\n inspector.Debugger.setBreakpoint({\n location: {\n scriptId: bp.scriptId,\n lineNumber: bp.lineNumber,\n columnNumber: bp.columnNumber,\n },\n } as Debugger.SetBreakpointParameterType)\n .then((result: Debugger.SetBreakpointReturnType) => ({\n id: result.breakpointId,\n location: result.actualLocation,\n }))\n .catch((e: any) =>\n sendToHost({ cmd: 'error', error: `Cannot set breakpoint: ${e}`, errorContext: e, bp }),\n ),\n ) || [],\n ).then(breakpoints => sendToHost({ cmd: 'sb', breakpoints }));\n } else if (data.cmd === 'cb') {\n Promise.all(\n (data.breakpoints as Debugger.BreakpointId[])?.map(breakpointId =>\n inspector.Debugger.removeBreakpoint({ breakpointId } as Debugger.RemoveBreakpointParameterType)\n .then(() => breakpointId)\n .catch((e: any) =>\n sendToHost({\n cmd: 'error',\n error: `Cannot clear breakpoint: ${e}`,\n errorContext: e,\n id: breakpointId,\n }),\n ),\n ) || [],\n ).then(breakpoints => sendToHost({ cmd: 'cb', breakpoints }));\n } else if (data.cmd === 'watch') {\n Promise.all(\n data.expressions?.map(expr =>\n inspector.Debugger.watch(expr).catch((e: any) =>\n sendToHost({ cmd: 'error', error: `Cannot watch expr: ${e}`, errorContext: e, expr }),\n ),\n ) || [],\n ).then(() => console.log('Watch done'));\n } else if (data.cmd === 'unwatch') {\n Promise.all(\n data.expressions?.map(expr =>\n inspector.Debugger.unwatch(expr).catch((e: any) =>\n sendToHost({ cmd: 'error', error: `Cannot unwatch expr: ${e}`, errorContext: e, expr }),\n ),\n ) || [],\n ).then(() => console.log('Watch done'));\n } else if (data.cmd === 'scope') {\n Promise.all(\n data.scopes\n ?.filter(scope => scope?.object && scope.object.objectId)\n .map(scope =>\n inspector.Runtime.getProperties({\n objectId: scope.object.objectId,\n generatePreview: true,\n } as Runtime.GetPropertiesParameterType)\n .then((result: any) => ({ type: scope.type, properties: result }))\n .catch((e: any) =>\n sendToHost({ cmd: 'error', error: `Cannot get scopes expr: ${e}`, errorContext: e }),\n ),\n ) || [],\n ).then(scopes => sendToHost({ cmd: 'scope', scopes }));\n } else if (data.cmd === 'setValue') {\n inspector.Debugger.setVariableValue({\n variableName: data.variableName,\n scopeNumber: data.scopeNumber,\n newValue: data.newValue,\n callFrameId: data.callFrameId,\n } as Debugger.SetVariableValueParameterType)\n .catch((e: any) => sendToHost({ cmd: 'setValue', variableName: `Cannot setValue: ${e}`, errorContext: e }))\n .then(() =>\n sendToHost({\n cmd: 'setValue',\n variableName: data.variableName,\n scopeNumber: data.scopeNumber,\n newValue: data.newValue,\n callFrameId: data.callFrameId,\n }),\n );\n } else if (data.cmd === 'expressions') {\n Promise.all(\n data.expressions?.map(item =>\n inspector.Debugger.evaluateOnCallFrame({\n callFrameId: data.callFrameId,\n expression: item.name,\n objectGroup: 'node-inspect',\n returnByValue: true,\n generatePreview: true,\n } as Debugger.EvaluateOnCallFrameParameterType)\n // @ts-expect-error fix later\n .then(({ result, wasThrown }: Debugger.EvaluateOnCallFrameReturnType) => {\n if (wasThrown) {\n return { name: item.name, result: convertResultToError(result) };\n }\n return { name: item.name, result };\n })\n .catch((e: any) =>\n sendToHost({ cmd: 'expressions', variableName: `Cannot setValue: ${e}`, errorContext: e }),\n ),\n ) || [],\n ).then(expressions => sendToHost({ cmd: 'expressions', expressions }));\n } else if (data.cmd === 'stopOnException') {\n inspector.Debugger.setPauseOnExceptions({\n state: data.state ? 'all' : 'none',\n } as Debugger.SetPauseOnExceptionsParameterType).catch((e: any) =>\n sendToHost({ cmd: 'stopOnException', variableName: `Cannot stopOnException: ${e}`, errorContext: e }),\n );\n } else if (data.cmd === 'getPossibleBreakpoints') {\n inspector.Debugger.getPossibleBreakpoints({ start: data.start, end: data.end })\n .then((breakpoints: Debugger.GetPossibleBreakpointsReturnType) =>\n sendToHost({ cmd: 'getPossibleBreakpoints', breakpoints: breakpoints.locations }),\n )\n .catch((e: any) =>\n sendToHost({\n cmd: 'getPossibleBreakpoints',\n variableName: `Cannot getPossibleBreakpoints: ${e}`,\n errorContext: e,\n }),\n );\n } else {\n console.error(`Unknown command: ${JSON.stringify(data)}`);\n }\n}\n\nfunction sendToHost(data: CommandToHost): void {\n if (data.cmd === 'error') {\n console.error(data.text);\n if (data.expr) {\n console.error(`[EXPRESSION] ${JSON.stringify(data.expr)}`);\n }\n if (data.bp) {\n console.error(`[BP] ${JSON.stringify(data.bp)}`);\n }\n }\n\n process.send && process.send(JSON.stringify(data));\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/mirror.js b/build-backend/lib/mirror.js new file mode 100644 index 00000000..6a967f54 --- /dev/null +++ b/build-backend/lib/mirror.js @@ -0,0 +1,631 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Mirror = void 0; +const node_fs_1 = require("node:fs"); +const node_path_1 = require("node:path"); +const MODE_0777 = 511; +class Mirror { + adapter; + diskRoot; + from; + lastSyncID; + log; + watchedFolder = {}; + diskList; + dbList = {}; + constructor(options) { + if (!options.adapter) { + throw new Error('No adapter defined'); + } + this.adapter = options.adapter; + this.diskRoot = (0, node_path_1.normalize)(options.diskRoot || '').replace(/\\/g, '/'); + this.from = `system.adapter.${this.adapter.namespace}`; + this.lastSyncID = `${this.from}.lastSync`; + this.diskList = {}; + if (options.log) { + this.log = options.log; + this.log.log = this.log.log || ((text) => console.log(text)); + } + else { + this.log = { + silly: text => console.log(text), + debug: text => console.log(text), + info: text => console.log(text), + log: text => console.log(text), + warn: text => console.warn(text), + error: text => console.error(text), + }; + } + if (!options.diskRoot || options.adapter.namespace !== 'javascript.0') { + // only instance 0 can sync objects + return; + } + if (!(0, node_fs_1.existsSync)(this.diskRoot)) { + try { + (0, node_fs_1.mkdirSync)(this.diskRoot); + } + catch (err) { + this.log.error(`Cannot create directory ${this.diskRoot}: ${err}`); + return; + } + } + this.diskList = this.scanDisk(); + this.checkLastSyncObject(lastSyncTime => { + this.scanDB(list => { + this.dbList = list; + this.sync(lastSyncTime); + this.adapter.setForeignState(this.lastSyncID, Date.now(), true); + // monitor all folders + this.watchFolders(this.diskRoot); + }); + }); + } + watchFolders(root_) { + root_ = root_.endsWith('/') ? root_ : `${root_}/`; + // ignore all .xxx folders, like ".git", ".idea", so users may not have scripts starting with "." + try { + const files = (0, node_fs_1.readdirSync)(root_).filter(name => !name.startsWith('.')); + files.forEach(file => { + const name = (0, node_path_1.join)(root_, file).replace(/\\/g, '/'); + const stat = (0, node_fs_1.statSync)(name); + if (stat.isDirectory()) { + this.watchFolders(name); + } + else { + const lstat = (0, node_fs_1.lstatSync)(name); + if (!lstat.isSymbolicLink()) { + return; + } + const linkTarget = (0, node_fs_1.realpathSync)(name); + this.log.info(`Watch symlinked file ${name} -> ${linkTarget}`); + (0, node_fs_1.watch)(linkTarget, (eventType /*, _filename*/) => { + // Pretend the symlink source was changed. + this.log.debug(`File ${name} ${eventType}`); + this.onFileChange(eventType, name); + }); + } + }); + } + catch (err) { + return this.log.warn(`Error while trying to watch folder ${root_}: ${err}`); + } + if (!this.watchedFolder[root_]) { + this.log.info(`Watch ${root_}`); + try { + this.watchedFolder[root_] = (0, node_fs_1.watch)(root_, (eventType, fileName) => { + this.log.debug(`File ${root_}${fileName} ${eventType}`); + this.onFileChange(eventType, root_ + fileName); + }); + } + catch (err) { + this.log.error(`Could not watch folder ${root_}: ${err.message}`); + this.log.error(`Please check that no other processes change data in the mirror directory!`); + } + this.watchedFolder[root_].on('error', () => { + this.log.debug(`Folder ${root_} was deleted`); + try { + this.watchedFolder[root_] && this.watchedFolder[root_].close(); + } + catch { + // ignore error + } + if (this.watchedFolder[root_]) { + delete this.watchedFolder[root_]; + } + }); + } + } + checkLastSyncObject(cb) { + this.adapter.getForeignObject(this.lastSyncID, (_err, obj) => { + if (!obj) { + // create variable + const obj = { + _id: this.lastSyncID, + common: { + name: 'Last sync time', + type: 'number', + role: 'timestamp', + write: false, + min: 0, + read: true, + }, + type: 'state', + native: {}, + }; + this.adapter.setForeignObject(this.lastSyncID, obj, () => this.adapter.setForeignState(this.lastSyncID, 0, true, () => cb && cb(0))); + } + else { + this.adapter.getForeignState(this.lastSyncID, (_err, state) => cb && cb(state?.val)); + } + }); + } + static getDBFolder(id) { + const parts = id.split('.'); + parts.pop(); + return parts.join('.'); + } + static isBlockly(data) { + const pos = data.lastIndexOf('\n'); + if (pos !== -1) { + data = data.substring(pos + 1); + if (data[0] === '/' && data[1] === '/') { + data = Buffer.from(data.substring(2), 'base64').toString('utf8'); + if (data.startsWith('%3Cxml')) { + return true; + } + } + } + return false; + } + static isRules(data) { + const pos = data.lastIndexOf('\n'); + if (pos !== -1) { + data = data.substring(pos + 1); + if (data.startsWith('//{"') && data.endsWith('}')) { + return true; + } + } + return false; + } + static detectType(fileName, data) { + if (fileName.endsWith('.ts')) { + return 'TypeScript/ts'; + } + return Mirror.isBlockly(data) ? 'Blockly' : Mirror.isRules(data) ? 'Rules' : 'JavaScript/js'; + } + updateFolderTime(id) { + this.dbList[id].ts = Date.now(); + this.dbList[id].from = this.from; + this.adapter.setForeignObject(id, this.dbList[id]); + } + _getDiskPath(pathDisk) { + return (0, node_path_1.join)(this.diskRoot, pathDisk.join('/')).replace(/\\/g, '/'); + } + static _getDbPath(pathDB) { + if (!pathDB || !pathDB.length) { + return 'script.js'; + } + return `script.js.${pathDB.join('.')}`; + } + _getFilesInPath(pathDisk) { + pathDisk = pathDisk.substring(this.diskRoot.length + 1); + const id = pathDisk.replace(/\./g, '\\.').replace(/[/\\]/g, '\\.'); + const reg = new RegExp(`script\\.js${id ? `.${id}` : ''}\\.[^.]+$`); + return Object.keys(this.diskList) + .filter(file => reg.test(file)) + .map(id => id.split('.').pop() || ''); + } + _getObjectsInPath(pathDB) { + const reg = new RegExp(`${pathDB.replace(/\./g, '\\.')}\\.[^.]+$`); + return Object.keys(this.dbList) + .filter(id => reg.test(id)) + .map(id => id.split('.').pop() || ''); + } + /** + * Write file to disk, synchron, catch (and print) error. + * + * @param id of script + * @returns true if write was successful + */ + _writeFile(id) { + const diskListEntry = this.diskList[id]; + try { + //check if the directory exists and create if not: + (0, node_fs_1.mkdirSync)((0, node_path_1.dirname)(diskListEntry.name), { recursive: true, mode: MODE_0777 }); + (0, node_fs_1.writeFileSync)(diskListEntry.name, diskListEntry.source, { mode: MODE_0777 }); + diskListEntry.ts = Date.now(); + return true; + } + catch (err) { + this.log.error(`Cannot write file ${diskListEntry ? diskListEntry.name : id}: ${err}`); + return false; + } + } + sync(lastSyncTime, pathDisk, pathDB) { + lastSyncTime = lastSyncTime || 0; + pathDisk = pathDisk || []; + pathDB = pathDB || []; + const dirDisk = this._getDiskPath(pathDisk); + const dirDB = Mirror._getDbPath(pathDB); + const files = this._getFilesInPath(dirDisk); + const objects = this._getObjectsInPath(dirDB); + for (let o = objects.length - 1; o >= 0; o--) { + // if folder + if (this.dbList[`${dirDB}.${objects[o]}`] && this.dbList[`${dirDB}.${objects[o]}`].type === 'channel') { + // dive into + const nextPathDisk = JSON.parse(JSON.stringify(pathDisk)); + nextPathDisk.push(objects[o]); + const nextPathDB = JSON.parse(JSON.stringify(pathDB)); + nextPathDB.push(objects[o]); + objects.splice(o, 1); + this.sync(lastSyncTime, nextPathDisk, nextPathDB); + } + else { + // try to find this DB script on disk + for (let f = files.length - 1; f >= 0; f--) { + if (objects[o] === files[f]) { + const id = `${dirDB}.${objects[o]}`; + if (!this.diskList[id]) { + continue; + } + if (!this.dbList[id].ts || + (this.dbList[id].ts > this.diskList[id].ts && + this.dbList[id].ts - this.diskList[id].ts > 2000)) { + // copy text to file + this.dbList[id].ts = Date.now(); + this.diskList[id].source = this.dbList[id].common.source; + this.log.debug(`Update disk with ${this.diskList[id].name}`); + this._writeFile(id); + } + else if (this.dbList[id].ts && this.diskList[id].ts - this.dbList[id].ts > 2000) { + // copy file to DB + this.dbList[id].common.source = this.diskList[id].source; + this.dbList[id].ts = this.diskList[id].ts; + this.dbList[id].from = this.from; + this.log.debug(`Update DB with ${id}`); + this.adapter.setForeignObject(id, this.dbList[id]); + } + files.splice(f, 1); + objects.splice(o, 1); + break; + } + } + } + } + // go through objects, that does not exist on disk + for (let o = objects.length - 1; o >= 0; o--) { + const fileName = this._scriptId2FileName(`${dirDB}.${objects[o]}`, this.dbList[`${dirDB}.${objects[o]}`].common.engineType); + this.log.info(`Created script file on disk ${fileName}`); + const f = `script.js.${fileName + .substring(this.diskRoot.length) + .replace(/[\\/]/g, '.') + .replace(/\.js$|\.ts$/g, '')}`; + this.diskList[f] = { name: fileName, source: this.dbList[`${dirDB}.${objects[o]}`].common.source, ts: 0 }; + this._writeFile(f); + } + // go through files, that does not exist in DB + for (let f = files.length - 1; f >= 0; f--) { + // read creation time + const id = `${dirDB}.${files[f]}`; + if (this.diskList[id] && this.diskList[id].ts > lastSyncTime) { + // The file was created after last sync. So create it in DB too + this.dbList[id] = { + _id: id, + common: { + name: files[f], + enabled: false, + source: this.diskList[id].source, + engine: `system.adapter.${this.adapter.namespace}`, + engineType: Mirror.detectType(this.diskList[id].name, this.diskList[id].source), + debug: false, + verbose: false, + }, + type: 'script', + ts: this.diskList[id].ts, + native: {}, + }; + this.log.debug(`Create script in DB with ${id}`); + // ensure that every script has a folder and if not, then create it + this._checkIfAllFoldersAreExist(id, this.dbList); + this.adapter.setForeignObject(id, this.dbList[id]); + } + else { + this.log.warn(`Please delete file ${(0, node_path_1.join)(dirDisk, files[f])}`); + } + } + } + _scriptId2FileName(id, type) { + id = id.substring('script.js.'.length); + const parts = id.split('.'); + return ((0, node_path_1.join)(this.diskRoot, parts.join('/')).replace(/\\/g, '/') + + (type && type.toLowerCase() === 'typescript/ts' ? '.ts' : '.js')); + } + _fileName2scriptId(file) { + file = file.substring(this.diskRoot.length).replace(/\.js$/g, '').replace(/\.ts$/g, ''); + const parts = file.replace(/\\/g, '/').split('/'); + if (!parts[0] && parts.length) { + parts.shift(); + } + return `script.js.${parts.join('.')}`; + } + removeScriptsInFolder(folder) { + // get all files in this folder + const folderId = this._fileName2scriptId(folder); + for (const id in this.dbList) { + if (Object.prototype.hasOwnProperty.call(this.dbList, id) && + (id.startsWith(folderId) || id === folderId.replace(/\.$/, ''))) { + // delete it + if (this.dbList[id]) { + this.log.debug(`Delete script ${id} in DB`); + delete this.dbList[id]; + this.adapter.delForeignObject(id); + } + if (this.diskList[id]) { + delete this.diskList[id]; + } + } + } + } + onFileChange(event, file) { + let stats; + const exists = (0, node_fs_1.existsSync)(file); + if (exists) { + try { + stats = (0, node_fs_1.statSync)(file); + } + catch (err) { + this.log.error(`Cannot read file ${file}: ${err}`); + } + if (stats?.isDirectory()) { + file = file.endsWith('/') ? file : `${file}/`; + if (exists) { + !this.watchedFolder[file] && this.watchFolders(file); + try { + // scan folder anew + const files = (0, node_fs_1.readdirSync)(file).filter(name => !name.startsWith('.')); + // update all files in this directory + files.forEach(f => this.onFileChange('change', (0, node_path_1.join)(file, f).replace(/\\/g, '/'))); + } + catch (err) { + this.log.error(`Error while checking files in directory ${file}: ${err}`); + } + } + else { + if (this.watchedFolder[file]) { + this.watchedFolder[file].close(); + delete this.watchedFolder[file]; + } + this.removeScriptsInFolder(file); + } + return; + } + } + else if (this.watchedFolder[file]) { + if (!exists) { + try { + if (this.watchedFolder[file]) { + this.watchedFolder[file].close(); + delete this.watchedFolder[file]; + } + } + catch { + // ignore error + } + this.removeScriptsInFolder(file); + } + return; + } + else if (this.watchedFolder[`${file}/`]) { + if (!exists) { + file = `${file}/`; + // delete all files in this folder + try { + if (this.watchedFolder[file]) { + this.watchedFolder[file].close(); + delete this.watchedFolder[file]; + } + } + catch { + // ignore error + } + this.removeScriptsInFolder(file); + } + return; + } + if (!file.match(/\.ts$|\.js$/)) { + return; + } + const id = this._fileName2scriptId(file); + if (exists && (event === 'change' || event === 'create')) { + try { + stats = stats || (0, node_fs_1.statSync)(file); + const source = (0, node_fs_1.readFileSync)(file).toString(); + const ts = stats?.mtime.getTime() || 0; + this.diskList[id] = { ts, source, name: file }; + if (this.dbList[id]) { + if (this.dbList[id].common.source !== source) { + this.dbList[id].common.source = source; + this.dbList[id].ts = ts; + this.log.debug(`Update script ${id} in DB`); + this.dbList[id].from = this.from; + this.adapter.setForeignObject(id, this.dbList[id]); + } + else { + this.dbList[id].ts = ts; + } + } + else { + this.log.debug(`Create script ${id} in DB`); + const parts = id.split('.'); + // new script + this.dbList[id] = { + _id: id, + common: { + name: parts.pop(), + engineType: Mirror.detectType(file, source), + source, + enabled: false, + engine: `system.adapter.${this.adapter.namespace}`, + debug: false, + verbose: false, + }, + type: 'script', + native: {}, + ts: ts, + }; + this._checkIfAllFoldersAreExist(id, this.dbList); + this.adapter.setForeignObject(id, this.dbList[id]); + } + } + catch (err) { + this.log.error(`Cannot read file ${file}: ${err}`); + } + } + else if (event === 'delete' || event === 'rename') { + // there is a bug: just after creation of a script on disk from ioBroker, "rename" event is generated! + if (event === 'rename' && this.diskList[id] && Date.now() - this.diskList[id].ts < 200) { + console.log(`Interval: ${Date.now() - this.diskList[id].ts}`); + // 'rename' is ignored + this.log.debug(`Rename event for ${id} is ignored`); + } + else { + if (this.dbList[id]) { + this.log.debug(`Delete script ${id} in DB`); + delete this.dbList[id]; + this.adapter.delForeignObject(id); + } + if (this.diskList[id]) { + delete this.diskList[id]; + } + } + } + this.adapter.setForeignState(this.lastSyncID, Date.now(), true); + } + onObjectChange(id, obj) { + if (!this.dbList || !id) { + return; + } + const file = this._scriptId2FileName(id, obj?.common?.engineType); + if (!obj || !obj.common) { + if (this.dbList[id]) { + delete this.dbList[id]; + const folderId = Mirror.getDBFolder(id); + if (this.dbList[folderId]) { + this.updateFolderTime(folderId); + } + if ((0, node_fs_1.existsSync)(file)) { + try { + this.log.debug(`Delete ${file} on disk`); + (0, node_fs_1.unlinkSync)(file); + } + catch (err) { + this.log.error(`Cannot delete ${file}: ${err}`); + } + } + if (this.diskList[id]) { + delete this.diskList[id]; + } + } + } + else if (obj.type === 'script' && id.startsWith('script.js.')) { + if (this.dbList[id]) { + if (this.dbList[id].common.source !== obj.common.source) { + this.dbList[id] = obj; + this.log.debug(`Update ${file} on disk`); + this.diskList[id] = { ts: 0, source: obj.common.source, name: file }; + this._writeFile(id); + } + else if (!this.diskList[id] || this.diskList[id].source !== obj.common.source) { + this.log.debug(`Update ${file} on disk`); + this.diskList[id] = { ts: 0, source: obj.common.source, name: file }; + this._writeFile(id); + } + } + else { + // new script + this.dbList[id] = obj; + if (!this.diskList[id] || this.diskList[id].source !== obj.common.source) { + this.log.debug(`Create ${file} on disk`); + this.diskList[id] = { ts: 0, source: obj.common.source, name: file }; + this._writeFile(id); + } + } + this.dbList[id].ts = Date.now(); + } + this.adapter.setForeignState(this.lastSyncID, Date.now(), true); + } + scanDisk(dirPath, list) { + dirPath = dirPath || this.diskRoot; + list = list || {}; + try { + if (dirPath && !dirPath.startsWith('.') && (0, node_fs_1.existsSync)(dirPath)) { + const files = (0, node_fs_1.readdirSync)(dirPath).filter(name => !name.startsWith('.')); + files.forEach(file => { + const fullName = (0, node_path_1.join)(dirPath, file); + const stats = (0, node_fs_1.statSync)(fullName); + if (stats.isDirectory()) { + this.scanDisk(fullName.replace(/\\/g, '/'), list); + } + else if (file.match(/\.js$|\.ts$/)) { + const f = this._fileName2scriptId(fullName); + list[f] = { + ts: stats.mtime.getTime(), + source: (0, node_fs_1.readFileSync)(fullName).toString(), + name: fullName, + }; + } + }); + } + } + catch (err) { + this.log.error(`Error while checking files in directory ${dirPath}: ${err}`); + } + return list; + } + _checkIfAllFoldersAreExist(id, list) { + const parts = id.split('.'); + for (let i = parts.length - 1; i >= 2; i--) { + parts.pop(); + const folderId = parts.join('.'); + if (!list[folderId]) { + const obj = { + _id: folderId, + common: { + name: parts[parts.length - 1], + }, + type: 'channel', + native: {}, + }; + list[folderId] = obj; + try { + this.adapter.setForeignObject(folderId, obj, err => { + if (err) { + this.log.warn(`Error while checking script folder ${folderId} for id "${id}": ${err}`); + } + }); + } + catch (err) { + this.log.warn(`Error while checking script folder ${folderId} for id "${id}": ${err}`); + } + } + } + } + scanDB(cb) { + this.adapter.getObjectView('system', 'channel', { startkey: 'script.js.', endkey: 'script.js.\u9999' }, (err, res) => { + // this is not required, because JavaScript subscribes on ALL objects + // adapter.subscribeForeignObjects('script.js.*'); + const list = {}; + if (err) { + this.log.error(`Error while checking scripts channel from objects database: ${err}`); + } + if (res?.rows) { + for (let i = 0; i < res.rows.length; i++) { + const value = res.rows[i].value; + if (value?._id && value.common) { + list[res.rows[i].value._id] = res.rows[i].value; + } + } + } + this.adapter.getObjectView('script', 'javascript', { startkey: 'script.js.', endkey: 'script.js.\u9999' }, (err, res) => { + if (err) { + this.log.error(`Error while checking scripts javascript from objects database: ${err}`); + } + if (res?.rows) { + for (let i = 0; i < res.rows.length; i++) { + const value = res.rows[i].value; + if (value?._id && value.common) { + list[res.rows[i].value._id] = res.rows[i].value; + // ensure that every script has a folder and if not, then create it + this._checkIfAllFoldersAreExist(res.rows[i].value._id, list); + } + } + } + if (cb) { + cb(list); + } + }); + }); + } +} +exports.Mirror = Mirror; +//# sourceMappingURL=mirror.js.map \ No newline at end of file diff --git a/build-backend/lib/mirror.js.map b/build-backend/lib/mirror.js.map new file mode 100644 index 00000000..a59ec64a --- /dev/null +++ b/build-backend/lib/mirror.js.map @@ -0,0 +1 @@ +{"version":3,"file":"mirror.js","sourceRoot":"","sources":["../../src/lib/mirror.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n readdirSync,\n lstatSync,\n statSync,\n existsSync,\n readFileSync,\n writeFileSync,\n mkdirSync,\n unlinkSync,\n watch,\n realpathSync,\n type Stats,\n type FSWatcher,\n} from 'node:fs';\nimport { join, normalize, dirname } from 'node:path';\nimport type { ScriptType } from '../types';\n\nconst MODE_0777 = 511;\n\nexport class Mirror {\n private adapter: ioBroker.Adapter;\n private readonly diskRoot: string;\n private readonly from: string;\n private readonly lastSyncID: string;\n private readonly log: {\n log: (text: string) => void;\n silly: (text: string) => void;\n debug: (text: string) => void;\n info: (text: string) => void;\n warn: (text: string) => void;\n error: (text: string) => void;\n };\n private watchedFolder: Record = {};\n private readonly diskList: Record;\n private dbList: Record = {};\n\n constructor(options: { diskRoot: string; adapter: ioBroker.Adapter; log?: ioBroker.Logger }) {\n if (!options.adapter) {\n throw new Error('No adapter defined');\n }\n this.adapter = options.adapter;\n this.diskRoot = normalize(options.diskRoot || '').replace(/\\\\/g, '/');\n this.from = `system.adapter.${this.adapter.namespace}`;\n this.lastSyncID = `${this.from}.lastSync`;\n this.diskList = {};\n\n if (options.log) {\n this.log = options.log as unknown as {\n log: (text: string) => void;\n silly: (text: string) => void;\n debug: (text: string) => void;\n info: (text: string) => void;\n warn: (text: string) => void;\n error: (text: string) => void;\n };\n this.log.log = this.log.log || ((text: string) => console.log(text));\n } else {\n this.log = {\n silly: text => console.log(text),\n debug: text => console.log(text),\n info: text => console.log(text),\n log: text => console.log(text),\n warn: text => console.warn(text),\n error: text => console.error(text),\n };\n }\n if (!options.diskRoot || options.adapter.namespace !== 'javascript.0') {\n // only instance 0 can sync objects\n return;\n }\n\n if (!existsSync(this.diskRoot)) {\n try {\n mkdirSync(this.diskRoot);\n } catch (err: unknown) {\n this.log.error(`Cannot create directory ${this.diskRoot}: ${err as Error}`);\n return;\n }\n }\n\n this.diskList = this.scanDisk();\n this.checkLastSyncObject(lastSyncTime => {\n this.scanDB(list => {\n this.dbList = list;\n this.sync(lastSyncTime);\n\n this.adapter.setForeignState(this.lastSyncID, Date.now(), true);\n\n // monitor all folders\n this.watchFolders(this.diskRoot);\n });\n });\n }\n\n watchFolders(root_: string): void {\n root_ = root_.endsWith('/') ? root_ : `${root_}/`;\n\n // ignore all .xxx folders, like \".git\", \".idea\", so users may not have scripts starting with \".\"\n try {\n const files = readdirSync(root_).filter(name => !name.startsWith('.'));\n files.forEach(file => {\n const name = join(root_, file).replace(/\\\\/g, '/');\n const stat = statSync(name);\n\n if (stat.isDirectory()) {\n this.watchFolders(name);\n } else {\n const lstat = lstatSync(name);\n if (!lstat.isSymbolicLink()) {\n return;\n }\n\n const linkTarget = realpathSync(name);\n\n this.log.info(`Watch symlinked file ${name} -> ${linkTarget}`);\n watch(linkTarget, (eventType /*, _filename*/) => {\n // Pretend the symlink source was changed.\n this.log.debug(`File ${name} ${eventType}`);\n this.onFileChange(eventType, name);\n });\n }\n });\n } catch (err: unknown) {\n return this.log.warn(`Error while trying to watch folder ${root_}: ${err as Error}`);\n }\n\n if (!this.watchedFolder[root_]) {\n this.log.info(`Watch ${root_}`);\n try {\n this.watchedFolder[root_] = watch(root_, (eventType, fileName) => {\n this.log.debug(`File ${root_}${fileName} ${eventType}`);\n this.onFileChange(eventType, root_ + fileName);\n });\n } catch (err: any) {\n this.log.error(`Could not watch folder ${root_}: ${err.message}`);\n this.log.error(`Please check that no other processes change data in the mirror directory!`);\n }\n\n this.watchedFolder[root_].on('error', () => {\n this.log.debug(`Folder ${root_} was deleted`);\n try {\n this.watchedFolder[root_] && this.watchedFolder[root_].close();\n } catch {\n // ignore error\n }\n\n if (this.watchedFolder[root_]) {\n delete this.watchedFolder[root_];\n }\n });\n }\n }\n\n checkLastSyncObject(cb: (lastSyncTime: number) => void): void {\n this.adapter.getForeignObject(this.lastSyncID, (_err, obj) => {\n if (!obj) {\n // create variable\n const obj: ioBroker.StateObject = {\n _id: this.lastSyncID,\n common: {\n name: 'Last sync time',\n type: 'number',\n role: 'timestamp',\n write: false,\n min: 0,\n read: true,\n },\n type: 'state',\n native: {},\n };\n\n this.adapter.setForeignObject(this.lastSyncID, obj, () =>\n this.adapter.setForeignState(this.lastSyncID, 0, true, () => cb && cb(0)),\n );\n } else {\n this.adapter.getForeignState(this.lastSyncID, (_err, state) => cb && cb(state?.val as number));\n }\n });\n }\n\n static getDBFolder(id: string): string {\n const parts = id.split('.');\n parts.pop();\n return parts.join('.');\n }\n\n static isBlockly(data: string): boolean {\n const pos = data.lastIndexOf('\\n');\n if (pos !== -1) {\n data = data.substring(pos + 1);\n if (data[0] === '/' && data[1] === '/') {\n data = Buffer.from(data.substring(2), 'base64').toString('utf8');\n if (data.startsWith('%3Cxml')) {\n return true;\n }\n }\n }\n return false;\n }\n\n static isRules(data: string): boolean {\n const pos = data.lastIndexOf('\\n');\n if (pos !== -1) {\n data = data.substring(pos + 1);\n if (data.startsWith('//{\"') && data.endsWith('}')) {\n return true;\n }\n }\n return false;\n }\n\n static detectType(fileName: string, data: string): ScriptType {\n if (fileName.endsWith('.ts')) {\n return 'TypeScript/ts';\n }\n return Mirror.isBlockly(data) ? 'Blockly' : Mirror.isRules(data) ? 'Rules' : 'JavaScript/js';\n }\n\n updateFolderTime(id: string): void {\n this.dbList[id].ts = Date.now();\n this.dbList[id].from = this.from;\n this.adapter.setForeignObject(id, this.dbList[id] as ioBroker.Object);\n }\n\n private _getDiskPath(pathDisk: string[]): string {\n return join(this.diskRoot, pathDisk.join('/')).replace(/\\\\/g, '/');\n }\n\n private static _getDbPath(pathDB: string[]): string {\n if (!pathDB || !pathDB.length) {\n return 'script.js';\n }\n return `script.js.${pathDB.join('.')}`;\n }\n\n private _getFilesInPath(pathDisk: string): string[] {\n pathDisk = pathDisk.substring(this.diskRoot.length + 1);\n const id = pathDisk.replace(/\\./g, '\\\\.').replace(/[/\\\\]/g, '\\\\.');\n const reg = new RegExp(`script\\\\.js${id ? `.${id}` : ''}\\\\.[^.]+$`);\n return Object.keys(this.diskList)\n .filter(file => reg.test(file))\n .map(id => id.split('.').pop() || '');\n }\n\n private _getObjectsInPath(pathDB: string): string[] {\n const reg = new RegExp(`${pathDB.replace(/\\./g, '\\\\.')}\\\\.[^.]+$`);\n return Object.keys(this.dbList)\n .filter(id => reg.test(id))\n .map(id => id.split('.').pop() || '');\n }\n\n /**\n * Write file to disk, synchron, catch (and print) error.\n *\n * @param id of script\n * @returns true if write was successful\n */\n private _writeFile(id: string): boolean {\n const diskListEntry = this.diskList[id];\n try {\n //check if the directory exists and create if not:\n mkdirSync(dirname(diskListEntry.name), { recursive: true, mode: MODE_0777 });\n writeFileSync(diskListEntry.name, diskListEntry.source, { mode: MODE_0777 });\n diskListEntry.ts = Date.now();\n return true;\n } catch (err: unknown) {\n this.log.error(`Cannot write file ${diskListEntry ? diskListEntry.name : id}: ${err as Error}`);\n return false;\n }\n }\n\n sync(lastSyncTime: number, pathDisk?: string[], pathDB?: string[]): void {\n lastSyncTime = lastSyncTime || 0;\n pathDisk = pathDisk || [];\n pathDB = pathDB || [];\n\n const dirDisk = this._getDiskPath(pathDisk);\n const dirDB = Mirror._getDbPath(pathDB);\n const files = this._getFilesInPath(dirDisk);\n const objects = this._getObjectsInPath(dirDB);\n\n for (let o = objects.length - 1; o >= 0; o--) {\n // if folder\n if (this.dbList[`${dirDB}.${objects[o]}`] && this.dbList[`${dirDB}.${objects[o]}`].type === 'channel') {\n // dive into\n const nextPathDisk = JSON.parse(JSON.stringify(pathDisk));\n nextPathDisk.push(objects[o]);\n const nextPathDB = JSON.parse(JSON.stringify(pathDB));\n nextPathDB.push(objects[o]);\n objects.splice(o, 1);\n this.sync(lastSyncTime, nextPathDisk, nextPathDB);\n } else {\n // try to find this DB script on disk\n for (let f = files.length - 1; f >= 0; f--) {\n if (objects[o] === files[f]) {\n const id = `${dirDB}.${objects[o]}`;\n\n if (!this.diskList[id]) {\n continue;\n }\n\n if (\n !this.dbList[id].ts ||\n (this.dbList[id].ts > this.diskList[id].ts &&\n this.dbList[id].ts - this.diskList[id].ts > 2000)\n ) {\n // copy text to file\n this.dbList[id].ts = Date.now();\n this.diskList[id].source = this.dbList[id].common.source;\n this.log.debug(`Update disk with ${this.diskList[id].name}`);\n this._writeFile(id);\n } else if (this.dbList[id].ts && this.diskList[id].ts - this.dbList[id].ts > 2000) {\n // copy file to DB\n this.dbList[id].common.source = this.diskList[id].source;\n this.dbList[id].ts = this.diskList[id].ts;\n this.dbList[id].from = this.from;\n this.log.debug(`Update DB with ${id}`);\n this.adapter.setForeignObject(id, this.dbList[id] as ioBroker.Object);\n }\n files.splice(f, 1);\n objects.splice(o, 1);\n break;\n }\n }\n }\n }\n\n // go through objects, that does not exist on disk\n for (let o = objects.length - 1; o >= 0; o--) {\n const fileName = this._scriptId2FileName(\n `${dirDB}.${objects[o]}`,\n this.dbList[`${dirDB}.${objects[o]}`].common.engineType,\n );\n this.log.info(`Created script file on disk ${fileName}`);\n const f = `script.js.${fileName\n .substring(this.diskRoot.length)\n .replace(/[\\\\/]/g, '.')\n .replace(/\\.js$|\\.ts$/g, '')}`;\n this.diskList[f] = { name: fileName, source: this.dbList[`${dirDB}.${objects[o]}`].common.source, ts: 0 };\n this._writeFile(f);\n }\n\n // go through files, that does not exist in DB\n for (let f = files.length - 1; f >= 0; f--) {\n // read creation time\n const id = `${dirDB}.${files[f]}`;\n if (this.diskList[id] && this.diskList[id].ts > lastSyncTime) {\n // The file was created after last sync. So create it in DB too\n this.dbList[id] = {\n _id: id,\n common: {\n name: files[f],\n enabled: false,\n source: this.diskList[id].source,\n engine: `system.adapter.${this.adapter.namespace}`,\n engineType: Mirror.detectType(this.diskList[id].name, this.diskList[id].source),\n debug: false,\n verbose: false,\n },\n type: 'script',\n ts: this.diskList[id].ts,\n native: {},\n };\n this.log.debug(`Create script in DB with ${id}`);\n // ensure that every script has a folder and if not, then create it\n this._checkIfAllFoldersAreExist(id, this.dbList);\n this.adapter.setForeignObject(id, this.dbList[id] as ioBroker.Object);\n } else {\n this.log.warn(`Please delete file ${join(dirDisk, files[f])}`);\n }\n }\n }\n\n private _scriptId2FileName(id: string, type: ScriptType): string {\n id = id.substring('script.js.'.length);\n const parts = id.split('.');\n return (\n join(this.diskRoot, parts.join('/')).replace(/\\\\/g, '/') +\n (type && type.toLowerCase() === 'typescript/ts' ? '.ts' : '.js')\n );\n }\n\n private _fileName2scriptId(file: string): string {\n file = file.substring(this.diskRoot.length).replace(/\\.js$/g, '').replace(/\\.ts$/g, '');\n const parts = file.replace(/\\\\/g, '/').split('/');\n if (!parts[0] && parts.length) {\n parts.shift();\n }\n\n return `script.js.${parts.join('.')}`;\n }\n\n removeScriptsInFolder(folder: string): void {\n // get all files in this folder\n const folderId = this._fileName2scriptId(folder);\n for (const id in this.dbList) {\n if (\n Object.prototype.hasOwnProperty.call(this.dbList, id) &&\n (id.startsWith(folderId) || id === folderId.replace(/\\.$/, ''))\n ) {\n // delete it\n if (this.dbList[id]) {\n this.log.debug(`Delete script ${id} in DB`);\n delete this.dbList[id];\n this.adapter.delForeignObject(id);\n }\n if (this.diskList[id]) {\n delete this.diskList[id];\n }\n }\n }\n }\n\n onFileChange(event: 'change' | 'create' | 'delete' | 'rename', file: string): void {\n let stats: Stats | undefined;\n const exists = existsSync(file);\n if (exists) {\n try {\n stats = statSync(file);\n } catch (err: unknown) {\n this.log.error(`Cannot read file ${file}: ${err as Error}`);\n }\n\n if (stats?.isDirectory()) {\n file = file.endsWith('/') ? file : `${file}/`;\n if (exists) {\n !this.watchedFolder[file] && this.watchFolders(file);\n try {\n // scan folder anew\n const files = readdirSync(file).filter(name => !name.startsWith('.'));\n\n // update all files in this directory\n files.forEach(f => this.onFileChange('change', join(file, f).replace(/\\\\/g, '/')));\n } catch (err: unknown) {\n this.log.error(`Error while checking files in directory ${file}: ${err as Error}`);\n }\n } else {\n if (this.watchedFolder[file]) {\n this.watchedFolder[file].close();\n delete this.watchedFolder[file];\n }\n this.removeScriptsInFolder(file);\n }\n return;\n }\n } else if (this.watchedFolder[file]) {\n if (!exists) {\n try {\n if (this.watchedFolder[file]) {\n this.watchedFolder[file].close();\n delete this.watchedFolder[file];\n }\n } catch {\n // ignore error\n }\n this.removeScriptsInFolder(file);\n }\n return;\n } else if (this.watchedFolder[`${file}/`]) {\n if (!exists) {\n file = `${file}/`;\n // delete all files in this folder\n\n try {\n if (this.watchedFolder[file]) {\n this.watchedFolder[file].close();\n delete this.watchedFolder[file];\n }\n } catch {\n // ignore error\n }\n this.removeScriptsInFolder(file);\n }\n return;\n }\n\n if (!file.match(/\\.ts$|\\.js$/)) {\n return;\n }\n const id = this._fileName2scriptId(file);\n\n if (exists && (event === 'change' || event === 'create')) {\n try {\n stats = stats || statSync(file);\n const source = readFileSync(file).toString();\n const ts = stats?.mtime.getTime() || 0;\n this.diskList[id] = { ts, source, name: file };\n\n if (this.dbList[id]) {\n if (this.dbList[id].common.source !== source) {\n this.dbList[id].common.source = source;\n this.dbList[id].ts = ts;\n this.log.debug(`Update script ${id} in DB`);\n this.dbList[id].from = this.from;\n this.adapter.setForeignObject(id, this.dbList[id] as ioBroker.Object);\n } else {\n this.dbList[id].ts = ts;\n }\n } else {\n this.log.debug(`Create script ${id} in DB`);\n const parts = id.split('.');\n // new script\n this.dbList[id] = {\n _id: id,\n common: {\n name: parts.pop(),\n engineType: Mirror.detectType(file, source),\n source,\n enabled: false,\n engine: `system.adapter.${this.adapter.namespace}`,\n debug: false,\n verbose: false,\n },\n type: 'script',\n native: {},\n ts: ts,\n };\n this._checkIfAllFoldersAreExist(id, this.dbList);\n this.adapter.setForeignObject(id, this.dbList[id] as ioBroker.Object);\n }\n } catch (err: unknown) {\n this.log.error(`Cannot read file ${file}: ${err as Error}`);\n }\n } else if (event === 'delete' || event === 'rename') {\n // there is a bug: just after creation of a script on disk from ioBroker, \"rename\" event is generated!\n if (event === 'rename' && this.diskList[id] && Date.now() - this.diskList[id].ts < 200) {\n console.log(`Interval: ${Date.now() - this.diskList[id].ts}`);\n // 'rename' is ignored\n this.log.debug(`Rename event for ${id} is ignored`);\n } else {\n if (this.dbList[id]) {\n this.log.debug(`Delete script ${id} in DB`);\n delete this.dbList[id];\n this.adapter.delForeignObject(id);\n }\n if (this.diskList[id]) {\n delete this.diskList[id];\n }\n }\n }\n this.adapter.setForeignState(this.lastSyncID, Date.now(), true);\n }\n\n onObjectChange(id: string, obj: ioBroker.ScriptObject | null | undefined): void {\n if (!this.dbList || !id) {\n return;\n }\n\n const file = this._scriptId2FileName(id, obj?.common?.engineType as ScriptType);\n\n if (!obj || !obj.common) {\n if (this.dbList[id]) {\n delete this.dbList[id];\n const folderId = Mirror.getDBFolder(id);\n if (this.dbList[folderId]) {\n this.updateFolderTime(folderId);\n }\n\n if (existsSync(file)) {\n try {\n this.log.debug(`Delete ${file} on disk`);\n unlinkSync(file);\n } catch (err: unknown) {\n this.log.error(`Cannot delete ${file}: ${err as Error}`);\n }\n }\n if (this.diskList[id]) {\n delete this.diskList[id];\n }\n }\n } else if (obj.type === 'script' && id.startsWith('script.js.')) {\n if (this.dbList[id]) {\n if (this.dbList[id].common.source !== obj.common.source) {\n this.dbList[id] = obj;\n this.log.debug(`Update ${file} on disk`);\n this.diskList[id] = { ts: 0, source: obj.common.source, name: file };\n this._writeFile(id);\n } else if (!this.diskList[id] || this.diskList[id].source !== obj.common.source) {\n this.log.debug(`Update ${file} on disk`);\n this.diskList[id] = { ts: 0, source: obj.common.source, name: file };\n this._writeFile(id);\n }\n } else {\n // new script\n this.dbList[id] = obj;\n if (!this.diskList[id] || this.diskList[id].source !== obj.common.source) {\n this.log.debug(`Create ${file} on disk`);\n this.diskList[id] = { ts: 0, source: obj.common.source, name: file };\n this._writeFile(id);\n }\n }\n this.dbList[id].ts = Date.now();\n }\n\n this.adapter.setForeignState(this.lastSyncID, Date.now(), true);\n }\n\n scanDisk(\n dirPath?: string,\n list?: Record,\n ): Record {\n dirPath = dirPath || this.diskRoot;\n list = list || {};\n try {\n if (dirPath && !dirPath.startsWith('.') && existsSync(dirPath)) {\n const files = readdirSync(dirPath).filter(name => !name.startsWith('.'));\n files.forEach(file => {\n const fullName = join(dirPath, file);\n const stats = statSync(fullName);\n if (stats.isDirectory()) {\n this.scanDisk(fullName.replace(/\\\\/g, '/'), list);\n } else if (file.match(/\\.js$|\\.ts$/)) {\n const f = this._fileName2scriptId(fullName);\n list[f] = {\n ts: stats.mtime.getTime(),\n source: readFileSync(fullName).toString(),\n name: fullName,\n };\n }\n });\n }\n } catch (err: unknown) {\n this.log.error(`Error while checking files in directory ${dirPath}: ${err as Error}`);\n }\n return list;\n }\n\n private _checkIfAllFoldersAreExist(id: string, list: Record): void {\n const parts = id.split('.');\n for (let i = parts.length - 1; i >= 2; i--) {\n parts.pop();\n const folderId = parts.join('.');\n if (!list[folderId]) {\n const obj: ioBroker.ChannelObject = {\n _id: folderId,\n common: {\n name: parts[parts.length - 1],\n },\n type: 'channel',\n native: {},\n };\n list[folderId] = obj;\n try {\n this.adapter.setForeignObject(folderId, obj, err => {\n if (err) {\n this.log.warn(`Error while checking script folder ${folderId} for id \"${id}\": ${err}`);\n }\n });\n } catch (err: unknown) {\n this.log.warn(`Error while checking script folder ${folderId} for id \"${id}\": ${err as Error}`);\n }\n }\n }\n }\n\n scanDB(cb: (list: Record) => void): void {\n this.adapter.getObjectView(\n 'system',\n 'channel',\n { startkey: 'script.js.', endkey: 'script.js.\\u9999' },\n (err, res) => {\n // this is not required, because JavaScript subscribes on ALL objects\n // adapter.subscribeForeignObjects('script.js.*');\n const list: Record = {};\n if (err) {\n this.log.error(`Error while checking scripts channel from objects database: ${err}`);\n }\n if (res?.rows) {\n for (let i = 0; i < res.rows.length; i++) {\n const value = res.rows[i].value;\n if (value?._id && value.common) {\n list[res.rows[i].value._id] = res.rows[i].value;\n }\n }\n }\n this.adapter.getObjectView(\n 'script',\n 'javascript',\n { startkey: 'script.js.', endkey: 'script.js.\\u9999' },\n (err, res) => {\n if (err) {\n this.log.error(`Error while checking scripts javascript from objects database: ${err}`);\n }\n if (res?.rows) {\n for (let i = 0; i < res.rows.length; i++) {\n const value = res.rows[i].value;\n if (value?._id && value.common) {\n list[res.rows[i].value._id] = res.rows[i].value;\n // ensure that every script has a folder and if not, then create it\n this._checkIfAllFoldersAreExist(res.rows[i].value._id, list);\n }\n }\n }\n if (cb) {\n cb(list);\n }\n },\n );\n },\n );\n }\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/nodeModulesManagement.js b/build-backend/lib/nodeModulesManagement.js new file mode 100644 index 00000000..5a421cad --- /dev/null +++ b/build-backend/lib/nodeModulesManagement.js @@ -0,0 +1,25 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.requestModuleNameByUrl = requestModuleNameByUrl; +const child_process_1 = require("child_process"); +/** + * Request a module name by given url using `npm view` + * + * @param url the url to the package which should be installed via npm + */ +async function requestModuleNameByUrl(url) { + return new Promise((resolve, reject) => { + (0, child_process_1.exec)(`npm view ${url} name`, { windowsHide: true, encoding: 'utf8' }, (error, stdout /* , stderr */) => { + if (error) { + reject(error); + } + else { + if (typeof stdout !== 'string') { + throw new Error(`Could not determine module name for url "${url}". Unexpected stdout: "${stdout ? JSON.stringify(stdout) : ''}"`); + } + return stdout.trim(); + } + }); + }); +} +//# sourceMappingURL=nodeModulesManagement.js.map \ No newline at end of file diff --git a/build-backend/lib/nodeModulesManagement.js.map b/build-backend/lib/nodeModulesManagement.js.map new file mode 100644 index 00000000..fa010c66 --- /dev/null +++ b/build-backend/lib/nodeModulesManagement.js.map @@ -0,0 +1 @@ +{"version":3,"file":"nodeModulesManagement.js","sourceRoot":"","sources":["../../src/lib/nodeModulesManagement.ts"],"names":[],"mappings":";;AAOA,wDAoBC;AA3BD,iDAAyD;AAEzD;;;;GAIG;AACI,KAAK,UAAU,sBAAsB,CAAC,GAAW;IACpD,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACnC,IAAA,oBAAI,EACA,YAAY,GAAG,OAAO,EACtB,EAAE,WAAW,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,EACvC,CAAC,KAA2B,EAAE,MAAc,CAAC,cAAc,EAAE,EAAE;YAC3D,IAAI,KAAK,EAAE,CAAC;gBACR,MAAM,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;oBAC7B,MAAM,IAAI,KAAK,CACX,4CAA4C,GAAG,0BAA0B,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CACnH,CAAC;gBACN,CAAC;gBAED,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;YACzB,CAAC;QACL,CAAC,CACJ,CAAC;IACN,CAAC,CAAC,CAAC;AACP,CAAC","sourcesContent":["import { exec, type ExecException } from 'child_process';\n\n/**\n * Request a module name by given url using `npm view`\n *\n * @param url the url to the package which should be installed via npm\n */\nexport async function requestModuleNameByUrl(url: string): Promise {\n return new Promise((resolve, reject) => {\n exec(\n `npm view ${url} name`,\n { windowsHide: true, encoding: 'utf8' },\n (error: ExecException | null, stdout: string /* , stderr */) => {\n if (error) {\n reject(error);\n } else {\n if (typeof stdout !== 'string') {\n throw new Error(\n `Could not determine module name for url \"${url}\". Unexpected stdout: \"${stdout ? JSON.stringify(stdout) : ''}\"`,\n );\n }\n\n return stdout.trim();\n }\n },\n );\n });\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/patternCompareFunctions.js b/build-backend/lib/patternCompareFunctions.js new file mode 100644 index 00000000..cce1796e --- /dev/null +++ b/build-backend/lib/patternCompareFunctions.js @@ -0,0 +1,321 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.patternCompareFunctions = void 0; +function isRegExp(obj) { + return !!(obj?.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false)); +} +/** + * @param pattern The pattern object to use + * @param propName The name of the property to compare + * @param eventPropertyExtractor If given, this function is used to extract the property value from the event object. Otherwise the propName is used + * @param invert Whether to invert the result + */ +function stringOrRegExpCompare(pattern, propName, eventPropertyExtractor, invert) { + const field = pattern[propName]; + const hasExtractor = typeof eventPropertyExtractor === 'function'; + if (isRegExp(field)) { + return function (event) { + const eventValue = hasExtractor + ? eventPropertyExtractor(event) + : event[propName]; + const ret = eventValue != null && field.test(eventValue); + return invert ? !ret : ret; + }; + } + if (Array.isArray(field)) { + return function (event) { + const eventValue = hasExtractor ? eventPropertyExtractor(event) : event[propName]; + // An array matches when any element is found that satisfies the constraint + const ret = eventValue != null && field.find(f => f === eventValue) != null; + return invert ? !ret : ret; + }; + } + return function (event) { + const eventValue = hasExtractor ? eventPropertyExtractor(event) : event[propName]; + const ret = eventValue != null && field === eventValue; + return invert ? !ret : ret; + }; +} +exports.patternCompareFunctions = { + logic: (_pattern) => { }, + id: (pattern) => stringOrRegExpCompare(pattern, 'id'), + name: (pattern) => stringOrRegExpCompare(pattern, 'name'), + change: (pattern) => { + switch (pattern.change) { + case 'eq': + return (event) => event.newState.val === event.oldState.val; + case 'ne': + return (event) => event.newState.val !== event.oldState.val; + case 'gt': + // @ts-expect-error we assume it could be null + return (event) => event.newState.val > event.oldState.val; + case 'ge': + // @ts-expect-error we assume it could be null + return (event) => event.newState.val >= event.oldState.val; + case 'lt': + // @ts-expect-error we assume it could be null + return (event) => event.newState.val < event.oldState.val; + case 'le': + // @ts-expect-error we assume it could be null + return (event) => event.newState.val <= event.oldState.val; + default: + return (_event) => true; + // on any other logic, just signal about a message + } + }, + ack: (pattern) => { + if (pattern.ack === true || pattern.ack === 'true') { + return (event) => event.newState.ack === true; + } + return (event) => event.newState.ack === false; + }, + oldAck: (pattern) => { + if (pattern.oldAck === true || pattern.oldAck === 'true') { + return (event) => event.oldState.ack === true; + } + return (event) => event.oldState.ack === false; + }, + q: (pattern) => { + const q = pattern.q; + return (event) => q === '*' || q === event.newState.q; + }, + oldQ: (pattern) => { + const q = pattern.oldQ; + return (event) => q === '*' || q === event.oldState.q; + }, + val: (pattern) => { + const pval = pattern.val; + return (event) => pval === event.newState.val; + }, + valGt: (pattern) => { + const pvalGt = pattern.valGt; + // @ts-expect-error we assume it could be null + return (event) => event.newState.val > pvalGt; + }, + valGe: (pattern) => { + const pvalGe = pattern.valGe; + // @ts-expect-error we assume it could be null + return (event) => event.newState.val >= pvalGe; + }, + valLt: (pattern) => { + const pvalLt = pattern.valLt; + // @ts-expect-error we assume it could be null + return (event) => event.newState.val < pvalLt; + }, + valLe: (pattern) => { + const pvalLe = pattern.valLe; + // @ts-expect-error we assume it could be null + return (event) => event.newState.val <= pvalLe; + }, + valNe: (pattern) => { + const pvalNe = pattern.valNe; + return (event) => event.newState.val !== pvalNe; + }, + oldVal: (pattern) => { + const poldVal = pattern.oldVal; + return (event) => poldVal === event.oldState.val; + }, + oldValGt: (pattern) => { + const poldValGt = pattern.oldValGt; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.val > poldValGt; + }, + oldValGe: (pattern) => { + const poldValGe = pattern.oldValGe; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.val >= poldValGe; + }, + oldValLt: (pattern) => { + const poldValLt = pattern.oldValLt; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.val < poldValLt; + }, + oldValLe: (pattern) => { + const poldValLe = pattern.oldValLe; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.val <= poldValLe; + }, + oldValNe: (pattern) => { + const poldValNe = pattern.oldValNe; + return (event) => event.oldState.val !== poldValNe; + }, + ts: (pattern) => { + const pts = pattern.ts; + return (event) => pts === event.newState.ts; + }, + tsGt: (pattern) => { + const ptsGt = pattern.tsGt; + // @ts-expect-error we assume it could be null + return (event) => event.newState.ts > ptsGt; + }, + tsGe: (pattern) => { + const ptsGe = pattern.tsGe; + // @ts-expect-error we assume it could be null + return (event) => event.newState.ts >= ptsGe; + }, + tsLt: (pattern) => { + const ptsLt = pattern.tsLt; + // @ts-expect-error we assume it could be null + return (event) => event.newState.ts < ptsLt; + }, + tsLe: (pattern) => { + const ptsLe = pattern.tsLe; + // @ts-expect-error we assume it could be null + return (event) => event.newState.ts <= ptsLe; + }, + oldTs: (pattern) => { + const poldTs = pattern.oldTs; + return (event) => poldTs === event.oldState.ts; + }, + oldTsGt: (pattern) => { + const poldTsGt = pattern.oldTsGt; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.ts > poldTsGt; + }, + oldTsGe: (pattern) => { + const poldTsGe = pattern.oldTsGe; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.ts >= poldTsGe; + }, + oldTsLt: (pattern) => { + const poldTsLt = pattern.oldTsLt; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.ts < poldTsLt; + }, + oldTsLe: (pattern) => { + const poldTsLe = pattern.oldTsLe; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.ts <= poldTsLe; + }, + lc: (pattern) => { + const plc = pattern.lc; + return (event) => plc === event.newState.lc; + }, + lcGt: (pattern) => { + const plcGt = pattern.lcGt; + // @ts-expect-error we assume it could be null + return (event) => event.newState.lc > plcGt; + }, + lcGe: (pattern) => { + const plcGe = pattern.lcGe; + // @ts-expect-error we assume it could be null + return (event) => event.newState.lc >= plcGe; + }, + lcLt: (pattern) => { + const plcLt = pattern.lcLt; + // @ts-expect-error we assume it could be null + return (event) => event.newState.lc < plcLt; + }, + lcLe: (pattern) => { + const plcLe = pattern.lcLe; + // @ts-expect-error we assume it could be null + return (event) => event.newState.lc <= plcLe; + }, + oldLc: (pattern) => { + const poldLc = pattern.oldLc; + return (event) => poldLc === event.oldState.lc; + }, + oldLcGt: (pattern) => { + const poldLcGt = pattern.oldLcGt; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.lc > poldLcGt; + }, + oldLcGe: (pattern) => { + const poldLcGe = pattern.oldLcGe; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.lc >= poldLcGe; + }, + oldLcLt: (pattern) => { + const poldLcLt = pattern.oldLcLt; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.lc < poldLcLt; + }, + oldLcLe: (pattern) => { + const poldLcLe = pattern.oldLcLe; + // @ts-expect-error we assume it could be null + return (event) => event.oldState.lc <= poldLcLe; + }, + from: (pattern) => stringOrRegExpCompare(pattern, 'from', event => event && event.newState && event.newState.from), + fromNe: (pattern) => stringOrRegExpCompare(pattern, 'fromNe', event => event && event.newState && event.newState.from, true), + oldFrom: (pattern) => stringOrRegExpCompare(pattern, 'oldFrom', event => event && event.oldState && event.oldState.from), + oldFromNe: (pattern) => stringOrRegExpCompare(pattern, 'oldFromNe', event => event && event.oldState && event.oldState.from, true), + channelId: (pattern) => stringOrRegExpCompare(pattern, 'channelId'), + channelName: (pattern) => stringOrRegExpCompare(pattern, 'channelName'), + deviceId: (pattern) => stringOrRegExpCompare(pattern, 'deviceId'), + deviceName: (pattern) => stringOrRegExpCompare(pattern, 'deviceName'), + enumId: (pattern) => { + const penumId = pattern.enumId; + function ensureEnumIDsIsArray(enumIds) { + if (!Array.isArray(enumIds)) { + console.error(`enumIds is of type ${typeof enumIds} but should be an array: ${JSON.stringify(enumIds)}`); + return false; + } + return true; + } + if (isRegExp(penumId)) { + return (event) => { + const enumIds = event.enumIds; + if (enumIds == null || !ensureEnumIDsIsArray(enumIds)) { + return false; + } + // Test if any enum name matches the regex: + return enumIds.find(e => penumId.test(e)) != null; + }; + } + if (Array.isArray(penumId)) { + return (event) => { + const enumIds = event.enumIds; + if (enumIds == null || !ensureEnumIDsIsArray(enumIds)) { + return false; + } + // Test if the enum names of the event and the given array intersect + return enumIds.find(e => penumId.includes(e)) != null; + }; + } + return (event) => { + const enumIds = event.enumIds; + if (enumIds == null || !ensureEnumIDsIsArray(enumIds)) { + return false; + } + return enumIds && enumIds.includes(penumId); + }; + }, + enumName: (pattern) => { + const penumName = pattern.enumName; + function ensureEnumNamesIsArray(enumNames) { + if (!Array.isArray(enumNames)) { + console.error(`enumNames is of type ${typeof enumNames} but should be an array: ${JSON.stringify(enumNames)}`); + return false; + } + return true; + } + if (isRegExp(penumName)) { + return (event) => { + const enumNames = event.enumNames; + if (enumNames == null || !ensureEnumNamesIsArray(enumNames)) { + return false; + } + // Test if any enum name matches the regex: + return enumNames.find(e => penumName.test(e)) != null; + }; + } + if (Array.isArray(penumName)) { + return (event) => { + const enumNames = event.enumNames; + if (enumNames == null || !ensureEnumNamesIsArray(enumNames)) { + return false; + } + // Test if the enum names of the event and the given array intersect + return enumNames.find(e => penumName.includes(e)) != null; + }; + } + return (event) => { + const enumNames = event.enumNames; + if (enumNames == null || !ensureEnumNamesIsArray(enumNames)) { + return false; + } + return enumNames?.includes(penumName); + }; + }, +}; +//# sourceMappingURL=patternCompareFunctions.js.map \ No newline at end of file diff --git a/build-backend/lib/patternCompareFunctions.js.map b/build-backend/lib/patternCompareFunctions.js.map new file mode 100644 index 00000000..5b16e52b --- /dev/null +++ b/build-backend/lib/patternCompareFunctions.js.map @@ -0,0 +1 @@ +{"version":3,"file":"patternCompareFunctions.js","sourceRoot":"","sources":["../../src/lib/patternCompareFunctions.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Pattern } from '../types';\nimport { type EventObj } from './eventObj';\n\nfunction isRegExp(obj: any): boolean {\n return !!(obj?.test && obj.exec && (obj.ignoreCase || obj.ignoreCase === false));\n}\n\nexport type PatternEventCompareFunction = (event: EventObj) => boolean;\n\n/**\n * @param pattern The pattern object to use\n * @param propName The name of the property to compare\n * @param eventPropertyExtractor If given, this function is used to extract the property value from the event object. Otherwise the propName is used\n * @param invert Whether to invert the result\n */\nfunction stringOrRegExpCompare(\n pattern: Pattern,\n propName: string,\n eventPropertyExtractor?: (event: EventObj) => any,\n invert?: boolean,\n): PatternEventCompareFunction {\n const field: RegExp | string | string[] = (pattern as Record)[propName];\n const hasExtractor = typeof eventPropertyExtractor === 'function';\n\n if (isRegExp(field)) {\n return function (event: EventObj): boolean {\n const eventValue: any = hasExtractor\n ? eventPropertyExtractor(event)\n : (event as Record)[propName];\n const ret = eventValue != null && (field as RegExp).test(eventValue);\n return invert ? !ret : ret;\n };\n }\n\n if (Array.isArray(field)) {\n return function (event: EventObj): boolean {\n const eventValue = hasExtractor ? eventPropertyExtractor(event) : (event as Record)[propName];\n // An array matches when any element is found that satisfies the constraint\n const ret = eventValue != null && field.find(f => f === eventValue) != null;\n return invert ? !ret : ret;\n };\n }\n\n return function (event: EventObj): boolean {\n const eventValue = hasExtractor ? eventPropertyExtractor(event) : (event as Record)[propName];\n const ret = eventValue != null && field === eventValue;\n return invert ? !ret : ret;\n };\n}\n\nexport const patternCompareFunctions = {\n logic: (_pattern: Pattern): void => {},\n\n id: (pattern: Pattern): PatternEventCompareFunction => stringOrRegExpCompare(pattern, 'id'),\n\n name: (pattern: Pattern): PatternEventCompareFunction => stringOrRegExpCompare(pattern, 'name'),\n\n change: (pattern: Pattern): PatternEventCompareFunction => {\n switch (pattern.change) {\n case 'eq':\n return (event: EventObj): boolean => event.newState.val === event.oldState.val;\n case 'ne':\n return (event: EventObj): boolean => event.newState.val !== event.oldState.val;\n case 'gt':\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.val > event.oldState.val;\n case 'ge':\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.val >= event.oldState.val;\n case 'lt':\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.val < event.oldState.val;\n case 'le':\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.val <= event.oldState.val;\n default:\n return (_event: EventObj): boolean => true;\n // on any other logic, just signal about a message\n }\n },\n\n ack: (pattern: Pattern): PatternEventCompareFunction => {\n if (pattern.ack === true || pattern.ack === 'true') {\n return (event: EventObj): boolean => event.newState.ack === true;\n }\n return (event: EventObj): boolean => event.newState.ack === false;\n },\n oldAck: (pattern: Pattern): PatternEventCompareFunction => {\n if (pattern.oldAck === true || pattern.oldAck === 'true') {\n return (event: EventObj): boolean => event.oldState.ack === true;\n }\n return (event: EventObj): boolean => event.oldState.ack === false;\n },\n\n q: (pattern: Pattern): PatternEventCompareFunction => {\n const q = pattern.q;\n return (event: EventObj): boolean => q === '*' || q === event.newState.q;\n },\n oldQ: (pattern: Pattern): PatternEventCompareFunction => {\n const q = pattern.oldQ;\n return (event: EventObj): boolean => q === '*' || q === event.oldState.q;\n },\n\n val: (pattern: Pattern): PatternEventCompareFunction => {\n const pval = pattern.val;\n return (event: EventObj): boolean => pval === event.newState.val;\n },\n valGt: (pattern: Pattern): PatternEventCompareFunction => {\n const pvalGt = pattern.valGt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.val > pvalGt;\n },\n valGe: (pattern: Pattern): PatternEventCompareFunction => {\n const pvalGe = pattern.valGe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.val >= pvalGe;\n },\n valLt: (pattern: Pattern): PatternEventCompareFunction => {\n const pvalLt = pattern.valLt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.val < pvalLt;\n },\n valLe: (pattern: Pattern): PatternEventCompareFunction => {\n const pvalLe = pattern.valLe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.val <= pvalLe;\n },\n valNe: (pattern: Pattern): PatternEventCompareFunction => {\n const pvalNe = pattern.valNe;\n return (event: EventObj): boolean => event.newState.val !== pvalNe;\n },\n\n oldVal: (pattern: Pattern): PatternEventCompareFunction => {\n const poldVal = pattern.oldVal;\n return (event: EventObj): boolean => poldVal === event.oldState.val;\n },\n oldValGt: (pattern: Pattern): PatternEventCompareFunction => {\n const poldValGt = pattern.oldValGt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.val > poldValGt;\n },\n oldValGe: (pattern: Pattern): PatternEventCompareFunction => {\n const poldValGe = pattern.oldValGe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.val >= poldValGe;\n },\n oldValLt: (pattern: Pattern): PatternEventCompareFunction => {\n const poldValLt = pattern.oldValLt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.val < poldValLt;\n },\n oldValLe: (pattern: Pattern): PatternEventCompareFunction => {\n const poldValLe = pattern.oldValLe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.val <= poldValLe;\n },\n oldValNe: (pattern: Pattern): PatternEventCompareFunction => {\n const poldValNe = pattern.oldValNe;\n return (event: EventObj): boolean => event.oldState.val !== poldValNe;\n },\n\n ts: (pattern: Pattern): PatternEventCompareFunction => {\n const pts = pattern.ts;\n return (event: EventObj): boolean => pts === event.newState.ts;\n },\n tsGt: (pattern: Pattern): PatternEventCompareFunction => {\n const ptsGt = pattern.tsGt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.ts > ptsGt;\n },\n tsGe: (pattern: Pattern): PatternEventCompareFunction => {\n const ptsGe = pattern.tsGe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.ts >= ptsGe;\n },\n tsLt: (pattern: Pattern): PatternEventCompareFunction => {\n const ptsLt = pattern.tsLt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.ts < ptsLt;\n },\n tsLe: (pattern: Pattern): PatternEventCompareFunction => {\n const ptsLe = pattern.tsLe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.ts <= ptsLe;\n },\n\n oldTs: (pattern: Pattern): PatternEventCompareFunction => {\n const poldTs = pattern.oldTs;\n return (event: EventObj): boolean => poldTs === event.oldState.ts;\n },\n oldTsGt: (pattern: Pattern): PatternEventCompareFunction => {\n const poldTsGt = pattern.oldTsGt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.ts > poldTsGt;\n },\n oldTsGe: (pattern: Pattern): PatternEventCompareFunction => {\n const poldTsGe = pattern.oldTsGe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.ts >= poldTsGe;\n },\n oldTsLt: (pattern: Pattern): PatternEventCompareFunction => {\n const poldTsLt = pattern.oldTsLt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.ts < poldTsLt;\n },\n oldTsLe: (pattern: Pattern): PatternEventCompareFunction => {\n const poldTsLe = pattern.oldTsLe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.ts <= poldTsLe;\n },\n\n lc: (pattern: Pattern): PatternEventCompareFunction => {\n const plc = pattern.lc;\n return (event: EventObj): boolean => plc === event.newState.lc;\n },\n lcGt: (pattern: Pattern): PatternEventCompareFunction => {\n const plcGt = pattern.lcGt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.lc > plcGt;\n },\n lcGe: (pattern: Pattern): PatternEventCompareFunction => {\n const plcGe = pattern.lcGe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.lc >= plcGe;\n },\n lcLt: (pattern: Pattern): PatternEventCompareFunction => {\n const plcLt = pattern.lcLt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.lc < plcLt;\n },\n lcLe: (pattern: Pattern): PatternEventCompareFunction => {\n const plcLe = pattern.lcLe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.newState.lc <= plcLe;\n },\n\n oldLc: (pattern: Pattern): PatternEventCompareFunction => {\n const poldLc = pattern.oldLc;\n return (event: EventObj): boolean => poldLc === event.oldState.lc;\n },\n oldLcGt: (pattern: Pattern): PatternEventCompareFunction => {\n const poldLcGt = pattern.oldLcGt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.lc > poldLcGt;\n },\n oldLcGe: (pattern: Pattern): PatternEventCompareFunction => {\n const poldLcGe = pattern.oldLcGe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.lc >= poldLcGe;\n },\n oldLcLt: (pattern: Pattern): PatternEventCompareFunction => {\n const poldLcLt = pattern.oldLcLt;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.lc < poldLcLt;\n },\n oldLcLe: (pattern: Pattern): PatternEventCompareFunction => {\n const poldLcLe = pattern.oldLcLe;\n // @ts-expect-error we assume it could be null\n return (event: EventObj): boolean => event.oldState.lc <= poldLcLe;\n },\n\n from: (pattern: Pattern): PatternEventCompareFunction =>\n stringOrRegExpCompare(pattern, 'from', event => event && event.newState && event.newState.from),\n\n fromNe: (pattern: Pattern): PatternEventCompareFunction =>\n stringOrRegExpCompare(pattern, 'fromNe', event => event && event.newState && event.newState.from, true),\n\n oldFrom: (pattern: Pattern): PatternEventCompareFunction =>\n stringOrRegExpCompare(pattern, 'oldFrom', event => event && event.oldState && event.oldState.from),\n\n oldFromNe: (pattern: Pattern): PatternEventCompareFunction =>\n stringOrRegExpCompare(pattern, 'oldFromNe', event => event && event.oldState && event.oldState.from, true),\n\n channelId: (pattern: Pattern): PatternEventCompareFunction => stringOrRegExpCompare(pattern, 'channelId'),\n channelName: (pattern: Pattern): PatternEventCompareFunction => stringOrRegExpCompare(pattern, 'channelName'),\n deviceId: (pattern: Pattern): PatternEventCompareFunction => stringOrRegExpCompare(pattern, 'deviceId'),\n deviceName: (pattern: Pattern): PatternEventCompareFunction => stringOrRegExpCompare(pattern, 'deviceName'),\n\n enumId: (pattern: Pattern): PatternEventCompareFunction => {\n const penumId: RegExp | string | string[] | undefined = pattern.enumId;\n\n function ensureEnumIDsIsArray(enumIds: any): boolean {\n if (!Array.isArray(enumIds)) {\n console.error(\n `enumIds is of type ${typeof enumIds} but should be an array: ${JSON.stringify(enumIds)}`,\n );\n return false;\n }\n return true;\n }\n\n if (isRegExp(penumId)) {\n return (event: EventObj): boolean => {\n const enumIds = event.enumIds;\n if (enumIds == null || !ensureEnumIDsIsArray(enumIds)) {\n return false;\n }\n // Test if any enum name matches the regex:\n return enumIds.find(e => (penumId as RegExp).test(e)) != null;\n };\n }\n\n if (Array.isArray(penumId)) {\n return (event: EventObj): boolean => {\n const enumIds = event.enumIds;\n if (enumIds == null || !ensureEnumIDsIsArray(enumIds)) {\n return false;\n }\n // Test if the enum names of the event and the given array intersect\n return enumIds.find(e => penumId.includes(e)) != null;\n };\n }\n\n return (event: EventObj): boolean => {\n const enumIds = event.enumIds;\n if (enumIds == null || !ensureEnumIDsIsArray(enumIds)) {\n return false;\n }\n return enumIds && enumIds.includes(penumId as string);\n };\n },\n\n enumName: (pattern: Pattern): PatternEventCompareFunction => {\n const penumName: RegExp | string | string[] | undefined = pattern.enumName;\n\n function ensureEnumNamesIsArray(enumNames: any): boolean {\n if (!Array.isArray(enumNames)) {\n console.error(\n `enumNames is of type ${typeof enumNames} but should be an array: ${JSON.stringify(enumNames)}`,\n );\n return false;\n }\n return true;\n }\n\n if (isRegExp(penumName)) {\n return (event: EventObj): boolean => {\n const enumNames = event.enumNames;\n if (enumNames == null || !ensureEnumNamesIsArray(enumNames)) {\n return false;\n }\n // Test if any enum name matches the regex:\n return enumNames.find(e => (penumName as RegExp).test(e)) != null;\n };\n }\n if (Array.isArray(penumName)) {\n return (event: EventObj): boolean => {\n const enumNames = event.enumNames;\n if (enumNames == null || !ensureEnumNamesIsArray(enumNames)) {\n return false;\n }\n // Test if the enum names of the event and the given array intersect\n return enumNames.find(e => penumName.includes(e)) != null;\n };\n }\n\n return (event: EventObj): boolean => {\n const enumNames = event.enumNames;\n if (enumNames == null || !ensureEnumNamesIsArray(enumNames)) {\n return false;\n }\n return enumNames?.includes(penumName as string);\n };\n },\n};\n"]} \ No newline at end of file diff --git a/build-backend/lib/protectFs.js b/build-backend/lib/protectFs.js new file mode 100644 index 00000000..1c97fff9 --- /dev/null +++ b/build-backend/lib/protectFs.js @@ -0,0 +1,466 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const nodeFS = __importStar(require("node:fs")); +const node_path_1 = require("node:path"); +class ProtectFs { + log; + ioBrokerDataDir; + promises; + constants; + constructor(log, ioBrokerDataDir) { + this.ioBrokerDataDir = ioBrokerDataDir; + this.log = log || { + silly: (message) => console.log(message), + debug: (message) => console.debug(message), + info: (message) => console.info(message), + warn: (message) => console.warn(message), + error: (message) => console.error(message), + level: 'info', + }; + this.promises = { + access: async (path, mode) => { + this.#checkProtected(path, true); + return nodeFS.promises.access(path, mode); + }, + cp: async (source, destination, opts) => { + this.#checkProtected(source, false); + this.#checkProtected(destination, false); + return nodeFS.promises.cp(source, destination, opts); + }, + readFile: async (path, options) => { + this.#checkProtected(path, true); + return nodeFS.promises.readFile(path, options); // async function readFile(path, options) { + }, + readlink: async (path, options) => { + this.#checkProtected(path, true); + return nodeFS.promises.readlink(path, options); // async function readlink(path, options) { + }, + symlink: async (target, path, type) => { + this.#checkProtected(target, true); + this.#checkProtected(path, false); + return nodeFS.promises.symlink(target, path, type); // async function symlink(target, path, type_) { + }, + writeFile: async (file, data, options) => { + this.#checkProtected(file, true); + return nodeFS.promises.writeFile.call(this, file, data, options); // async function writeFile(path, data, options) { + }, + unlink: async (path) => { + this.#checkProtected(path, false); + return nodeFS.promises.unlink.call(this, path); // async function unlink(path) { + }, + appendFile: async (path, data, options) => { + this.#checkProtected(path, false); + return nodeFS.promises.appendFile.call(this, path, data, options); // async function appendFile(path, data, options) { + }, + chmod: async (path, mode) => { + this.#checkProtected(path, false); + return nodeFS.promises.chmod.call(this, path, mode); // async function chmod(path, mode) { + }, + copyFile: async (src, dest, mode) => { + this.#checkProtected(src, false); + this.#checkProtected(dest, false); + return nodeFS.promises.copyFile.call(this, src, dest, mode); // async function copyFile(src, dest, mode) { + }, + rename: async (oldPath, newPath) => { + this.#checkProtected(oldPath, false); + this.#checkProtected(newPath, false); + return nodeFS.promises.rename.call(this, oldPath, newPath); // async function rename(oldPath, newPath) { + }, + open: async (path, flags, mode) => { + this.#checkProtected(path, true); + return nodeFS.promises.open.call(this, path, flags, mode); // async function open(path, flags, mode) { + }, + truncate: async (path, len) => { + this.#checkProtected(path, false); + return nodeFS.promises.truncate.call(this, path, len); // async function truncate(path, len = 0) { + }, + stat: async (path, opts) => { + this.#checkProtected(path, true); + const result = await nodeFS.promises.stat.call(this, path, opts); // async function stat(path, options = { bigint: false }) { + return result; + }, + utimes: async (path, atime, mtime) => { + this.#checkProtected(path, false); + return nodeFS.promises.utimes.call(this, path, atime, mtime); // async function utimes(path, atime, mtime) { + }, + readdir: async (path, options) => { + this.#checkProtected(path, true); + return nodeFS.promises.readdir.call(this, path, options || { encoding: null, withFileTypes: true }); // async function readdir(path, options) { + }, + lchmod: async (path, mode) => { + this.#checkProtected(path, false); + return nodeFS.promises.lchmod.call(this, path, mode); // async function lchmod(path, mode) { + }, + lchown: async (path, uid, gid) => { + this.#checkProtected(path, false); + return nodeFS.promises.lchown.call(this, path, uid, gid); // async function lchown(path, uid, gid) { + }, + link: async (existingPath, newPath) => { + this.#checkProtected(existingPath, false); + this.#checkProtected(newPath, false); + return nodeFS.promises.link.call(this, existingPath, newPath); // async function link(existingPath, newPath) { + }, + lstat: async (path, opts) => { + this.#checkProtected(path, true); + const res = await nodeFS.promises.lstat.call(this, path, opts); // async function lstat(path, options = { bigint: false }) { + return res; + }, + lutimes: async (path, atime, mtime) => { + this.#checkProtected(path, false); + return nodeFS.promises.lutimes.call(this, path, atime, mtime); // async function lutimes(path, atime, mtime) { + }, + mkdir: async (path, options) => { + this.#checkProtected(path, false); + return nodeFS.promises.mkdir.call(this, path, options); // async function mkdir(path, options) { + }, + mkdtemp: async (prefix, options) => { + this.#checkProtected(prefix, false); + const tmp = await nodeFS.promises.mkdtemp.call(this, prefix, options); // async function mkdtemp(prefix, options) { + return tmp.toString(); + }, + rm: async (path, options) => { + this.#checkProtected(path, false); + return nodeFS.promises.rm.call(this, path, options); // async function rm(path, options) { + }, + rmdir: async (path, options) => { + this.#checkProtected(path, false); + return nodeFS.promises.rmdir.call(this, path, options); // async function rmdir(path, options) { + }, + }; + // Add missing constants + this.constants = nodeFS.constants; + // Add missing functions + for (const m in nodeFS) { + if (typeof nodeFS[m] === 'function' && + Object.hasOwn(nodeFS, m) && + !Object.hasOwn(this, m)) { + // console.debug(`Missing function in ProtectFS: ${m} - adding from node:fs`); + // @ts-expect-error Elsewise we must implement EVERY function in fs + this[m] = nodeFS[m]; + } + } + for (const m in nodeFS.promises) { + if (typeof nodeFS.promises[m] === 'function' && + Object.hasOwn(nodeFS.promises, m) && + !Object.hasOwn(this.promises, m)) { + // console.debug(`Missing function in ProtectFS: ${m} - adding from node:fs/promises`); + // @ts-expect-error Elsewise we must implement EVERY function in fs + this.promises[m] = nodeFS.promises[m]; + } + } + } + #checkProtected(file, readOnly) { + if (file.fd) { + return; + } + const filePath = (0, node_path_1.normalize)(file.toString()); + // todo: protect against file://... + if (filePath.endsWith(`-data${node_path_1.sep}objects.json`) || filePath.endsWith(`-data${node_path_1.sep}objects.jsonl`)) { + this.log.error(`May not read ${file.toString()}`); + throw new Error('Permission denied'); + } + if (!readOnly && filePath.startsWith((0, node_path_1.join)(this.ioBrokerDataDir, 'files'))) { + this.log.error(`May not read ${file.toString()} - use ${readOnly ? 'readFile' : 'writeFile'} instead`); + throw new Error('Permission denied'); + } + } + access(path, callback) { + this.#checkProtected(path, true); + return nodeFS.access(path, callback); + } + accessSync(path, mode) { + this.#checkProtected(path, true); + return nodeFS.accessSync(path, mode); // function accessSync(path, mode) { + } + cp(source, destination, opts, callback) { + this.#checkProtected(source, false); + this.#checkProtected(destination, false); + if (callback) { + return nodeFS.cp(source, destination, opts, callback); + } + if (typeof opts === 'function') { + return nodeFS.cp(source, destination, opts); + } + return nodeFS.cp(source, destination, opts); + } + cpSync(source, destination, opts) { + this.#checkProtected(source, false); + this.#checkProtected(destination, false); + return nodeFS.cpSync.call(this, source, destination, opts); // function cpSync(src, dest, options) { + } + readFile(path, callback) { + if (typeof path !== 'number') { + this.#checkProtected(path, true); + } + return nodeFS.readFile.call(this, path, callback); // function readFile(path, options, callback) { + } + readFileSync(path, options) { + if (typeof path !== 'number') { + this.#checkProtected(path, true); + } + return nodeFS.readFileSync.call(this, path, options); // function readFileSync(path, options) { + } + readlink(path, callback) { + this.#checkProtected(path, true); + return nodeFS.readlink.call(this, path, callback); // function readlink(path, options, callback) { + } + readlinkSync(path, options) { + this.#checkProtected(path, true); + return nodeFS.readlinkSync.call(this, path, options); // function readlinkSync(path, options) { + } + symlink(target, path, type, callback) { + this.#checkProtected(target, true); + this.#checkProtected(path, false); + if (typeof callback === 'function') { + // @ts-expect-error should work + return nodeFS.symlink.call(this, target, path, type, callback); + } + return nodeFS.symlink.call(this, target, path, type); // function symlink(target, path, type_, callback_) { + } + symlinkSync(target, path, type) { + this.#checkProtected(target, true); + this.#checkProtected(path, false); + return nodeFS.symlinkSync.call(this, target, path, type); // function symlinkSync(target, path, type) { + } + writeFile(file, data, options, callback) { + if (typeof file !== 'number') { + this.#checkProtected(file, false); + } + // @ts-expect-error should work + return nodeFS.writeFile.call(this, file, data, options, callback); // function writeFile(path, data, options, callback) { + } + writeFileSync(file, data, options) { + if (typeof file !== 'number') { + this.#checkProtected(file, false); + } + return nodeFS.writeFileSync.call(this, file, data, options); // function writeFileSync(path, data, options) { + } + unlink(path, callback) { + this.#checkProtected(path, false); + return nodeFS.unlink.call(this, path, callback); // function unlink(path, callback) { + } + unlinkSync(path) { + this.#checkProtected(path, false); + return nodeFS.unlinkSync.call(this, path); // function unlinkSync(path) { + } + appendFile(file, data, callback) { + if (typeof file !== 'number') { + this.#checkProtected(file, false); + } + return nodeFS.appendFile.call(this, file, data, callback); // function appendFile(path, data, options, callback) { + } + appendFileSync(file, data) { + if (typeof file !== 'number') { + this.#checkProtected(file, false); + } + return nodeFS.appendFileSync.call(this, file, data); // function appendFileSync(path, data, options) { + } + chmod(path, mode, callback) { + this.#checkProtected(path, false); + return nodeFS.chmod.call(this, path, mode, callback); // function chmod(path, mode, callback) { + } + chmodSync(path, mode) { + this.#checkProtected(path, false); + return nodeFS.chmodSync.call(this, path, mode); // function chmodSync(path, mode) { + } + chown(path, uid, gid, callback) { + this.#checkProtected(path, false); + return nodeFS.chown.call(this, path, uid, gid, callback); // function chown(path, uid, gid, callback) { + } + chownSync(path, uid, gid) { + this.#checkProtected(path, false); + return nodeFS.chownSync.call(this, path, uid, gid); // function chownSync(path, uid, gid) { + } + copyFile(src, dest, mode, callback) { + this.#checkProtected(src, true); + this.#checkProtected(dest, false); + // @ts-expect-error should work + return nodeFS.copyFile.call(this, src, dest, mode, callback); // function copyFile(src, dest, mode, callback) { + } + copyFileSync(src, dest, mode) { + this.#checkProtected(src, true); + this.#checkProtected(dest, false); + return nodeFS.copyFileSync.call(this, src, dest, mode); // function copyFileSync(src, dest, mode) { + } + rename(oldPath, newPath, callback) { + this.#checkProtected(oldPath, false); + this.#checkProtected(newPath, false); + return nodeFS.rename.call(this, oldPath, newPath, callback); // function rename(oldPath, newPath, callback) { + } + renameSync(oldPath, newPath) { + this.#checkProtected(oldPath, false); + this.#checkProtected(newPath, false); + return nodeFS.renameSync.call(this, oldPath, newPath); // function renameSync(oldPath, newPath) { + } + open(path, callback) { + this.#checkProtected(path, true); + return nodeFS.open.call(this, path, callback); // function open(path, flags, mode, callback) { + } + openSync(path, flags, mode) { + this.#checkProtected(path, true); + return nodeFS.openSync.call(this, path, flags, mode); // function openSync(path, flags, mode) { + } + truncate(path, callback) { + this.#checkProtected(path, false); + return nodeFS.truncate.call(this, path, callback); // function truncate(path, len, callback) { + } + truncateSync(path) { + this.#checkProtected(path, false); + return nodeFS.truncateSync.call(this, path); // function truncateSync(path, len) { + } + exists(path, callback) { + this.#checkProtected(path, true); + return nodeFS.exists.call(this, path, callback); // function exists(path, callback) { + } + existsSync(path) { + this.#checkProtected(path, true); + return nodeFS.existsSync.call(this, path); // function existsSync(path) { + } + stat(path, options, callback) { + this.#checkProtected(path, true); + // @ts-expect-error should work + return nodeFS.stat.call(this, path, options, callback); // function stat(path, options = { bigint: false }, callback) { + } + statSync(path, options) { + this.#checkProtected(path, true); + return nodeFS.statSync.call(this, path, options); // function statSync(path, options = { bigint: false, throwIfNoEntry: true }) { + } + utimes(path, atime, mtime, callback) { + this.#checkProtected(path, false); + return nodeFS.utimes.call(this, path, atime, mtime, callback); // function utimes(path, atime, mtime, callback) { + } + utimesSync(path, atime, mtime) { + this.#checkProtected(path, false); + return nodeFS.utimesSync.call(this, path, atime, mtime); // function utimesSync(path, atime, mtime) { + } + readdir(path, options, callback) { + this.#checkProtected(path, true); + // @ts-expect-error should work + return nodeFS.readdir.call(this, path, options, callback); // function readdir(path, options, callback) { + } + readdirSync(path, options) { + this.#checkProtected(path, true); + // @ts-expect-error should work + return nodeFS.readdirSync.call(this, path, options); // function readdirSync(path, options) { + } + createReadStream(path, options) { + this.#checkProtected(path, true); + return nodeFS.createReadStream.call(this, path, options); // function createReadStream(path, options) { + } + createWriteStream(path, options) { + this.#checkProtected(path, false); + return nodeFS.createWriteStream.call(this, path, options); // function createWriteStream(path, options) { + } + lchmod(path, mode, callback) { + this.#checkProtected(path, false); + return nodeFS.lchmod.call(this, path, mode, callback); // function lchmod(path, mode, callback) { + } + lchmodSync(path, mode) { + this.#checkProtected(path, false); + return nodeFS.lchmodSync.call(this, path, mode); // function lchmodSync(path, mode) { + } + lchown(path, uid, gid, callback) { + this.#checkProtected(path, false); + return nodeFS.lchown.call(this, path, uid, gid, callback); // function lchown(path, uid, gid, callback) { + } + lchownSync(path, uid, gid) { + this.#checkProtected(path, false); + return nodeFS.lchownSync.call(this, path, uid, gid); // function lchownSync(path, uid, gid) { + } + link(existingPath, newPath, callback) { + this.#checkProtected(existingPath, false); + this.#checkProtected(newPath, false); + return nodeFS.link.call(this, existingPath, newPath, callback); // function link(existingPath, newPath, callback) { + } + linkSync(existingPath, newPath) { + this.#checkProtected(existingPath, false); + this.#checkProtected(newPath, false); + return nodeFS.linkSync.call(this, existingPath, newPath); // function linkSync(existingPath, newPath) { + } + lstat(path, options, callback) { + this.#checkProtected(path, true); + // @ts-expect-error should work + return nodeFS.lstat.call(this, path, options, callback); // function lstat(path, options = { bigint: false }, callback) { + } + lstatSync(path, options) { + this.#checkProtected(path, true); + return nodeFS.lstatSync.call(this, path, options); // function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) { + } + lutimes(path, atime, mtime, callback) { + this.#checkProtected(path, false); + return nodeFS.lutimes.call(this, path, atime, mtime, callback); // function lutimes(path, atime, mtime, callback) { + } + lutimesSync(path, atime, mtime) { + this.#checkProtected(path, false); + return nodeFS.lutimesSync.call(this, path, atime, mtime); // function lutimesSync(path, atime, mtime) { + } + mkdir(path, options, callback) { + this.#checkProtected(path, false); + // @ts-expect-error should work + return nodeFS.mkdir.call(this, path, options, callback); // function mkdir(path, options, callback) { + } + mkdirSync(path, options) { + this.#checkProtected(path, false); + return nodeFS.mkdirSync.call(this, path, options); // function mkdirSync(path, options) { + } + mkdtemp(prefix, options, callback) { + this.#checkProtected(prefix, false); + // @ts-expect-error should work + return nodeFS.mkdtemp.call(this, prefix, options, callback); // function mkdtemp(prefix, options, callback) { + } + mkdtempSync(prefix, options) { + this.#checkProtected(prefix, false); + return nodeFS.mkdtempSync.call(this, prefix, options); // function mkdtempSync(prefix, options) { + } + rm(path, options, callback) { + this.#checkProtected(path, false); + // @ts-expect-error should work + return nodeFS.rm.call(this, path, options, callback); // function rm(path, options, callback) { + } + rmSync(path, options) { + this.#checkProtected(path, false); + return nodeFS.rmSync.call(this, path, options); // function rmSync(path, options) { + } + rmdir(path, options, callback) { + this.#checkProtected(path, false); + // @ts-expect-error should work + return nodeFS.rmdir.call(this, path, options, callback); // function rmdir(path, options, callback) { + } + rmdirSync(path, options) { + this.#checkProtected(path, false); + return nodeFS.rmdirSync.call(this, path, options); // function rmdirSync(path, options) { + } + watch(filename, listener) { + this.#checkProtected(filename, true); + return nodeFS.watch.call(this, filename, listener); // function watch(filename, options, listener) { + } + watchFile(filename, listener) { + this.#checkProtected(filename, true); + return nodeFS.watchFile.call(this, filename, listener); // function watchFile(filename, options, listener) { + } +} +exports.default = ProtectFs; +//# sourceMappingURL=protectFs.js.map \ No newline at end of file diff --git a/build-backend/lib/protectFs.js.map b/build-backend/lib/protectFs.js.map new file mode 100644 index 00000000..85f2430b --- /dev/null +++ b/build-backend/lib/protectFs.js.map @@ -0,0 +1 @@ +{"version":3,"file":"protectFs.js","sourceRoot":"","sources":["../../src/lib/protectFs.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n BufferEncodingOption,\n CopyOptions,\n Dirent,\n MakeDirectoryOptions,\n Mode,\n ObjectEncodingOptions,\n OpenMode,\n PathLike,\n RmDirOptions,\n RmOptions,\n StatOptions,\n Stats,\n TimeLike,\n CopySyncOptions,\n NoParamCallback,\n PathOrFileDescriptor,\n WriteFileOptions,\n EncodingOption,\n FSWatcher,\n ReadStream,\n StatsListener,\n StatWatcher,\n WatchListener,\n WriteStream,\n} from 'node:fs';\nimport type { Abortable } from 'node:events';\nimport type { FileHandle, FlagAndOpenMode } from 'node:fs/promises';\nimport type { URL } from 'node:url';\nimport type { Stream } from 'node:stream';\n\nimport * as nodeFS from 'node:fs';\nimport { sep, normalize, join } from 'node:path';\n\nexport default class ProtectFs {\n private readonly log: ioBroker.Logger;\n private readonly ioBrokerDataDir: string;\n public readonly promises: {\n access: (path: PathLike, mode?: number) => Promise;\n cp: (source: string | URL, destination: string | URL, opts?: CopyOptions) => Promise;\n readFile: (\n path: PathLike | FileHandle,\n options:\n | ({\n encoding: BufferEncoding;\n flag?: OpenMode | undefined;\n } & Abortable)\n | BufferEncoding,\n ) => Promise;\n readlink: (path: PathLike, options: BufferEncodingOption) => Promise;\n symlink: (target: PathLike, path: PathLike, type?: string | null) => Promise;\n writeFile: (\n file: PathLike | FileHandle,\n data:\n | string\n | NodeJS.ArrayBufferView\n | Iterable\n | AsyncIterable\n | Stream,\n options?:\n | (ObjectEncodingOptions & {\n mode?: Mode | undefined;\n flag?: OpenMode | undefined;\n flush?: boolean | undefined;\n } & Abortable)\n | BufferEncoding\n | null,\n ) => Promise;\n unlink: (path: PathLike) => Promise;\n appendFile: (\n path: PathLike | FileHandle,\n data: string | Uint8Array,\n options?:\n | (ObjectEncodingOptions & FlagAndOpenMode & { flush?: boolean | undefined })\n | BufferEncoding\n | null,\n ) => Promise;\n chmod: (path: PathLike, mode: Mode) => Promise;\n copyFile: (src: PathLike, dest: PathLike, mode?: number) => Promise;\n rename: (oldPath: PathLike, newPath: PathLike) => Promise;\n open: (path: PathLike, flags?: string | number, mode?: Mode) => Promise;\n truncate: (path: PathLike, len?: number) => Promise;\n stat: (path: PathLike, opts?: StatOptions) => Promise;\n utimes: (path: PathLike, atime: TimeLike, mtime: TimeLike) => Promise;\n readdir: (\n path: PathLike,\n options?: ObjectEncodingOptions & {\n withFileTypes: true;\n recursive?: boolean | undefined;\n },\n ) => Promise;\n lchmod: (path: PathLike, mode: Mode) => Promise;\n lchown: (path: PathLike, uid: number, gid: number) => Promise;\n link: (existingPath: PathLike, newPath: PathLike) => Promise;\n lstat: (path: PathLike, opts?: StatOptions) => Promise;\n lutimes: (path: PathLike, atime: TimeLike, mtime: TimeLike) => Promise;\n mkdir: (path: PathLike, options?: Mode | MakeDirectoryOptions | null) => Promise;\n mkdtemp: (prefix: string, options?: ObjectEncodingOptions | BufferEncoding | null) => Promise;\n rm: (path: PathLike, options?: RmOptions) => Promise;\n rmdir: (path: PathLike, options?: RmDirOptions) => Promise;\n };\n public readonly constants: Record;\n\n constructor(log: ioBroker.Logger, ioBrokerDataDir: string) {\n this.ioBrokerDataDir = ioBrokerDataDir;\n this.log = log || {\n silly: (message: string): void => console.log(message),\n debug: (message: string): void => console.debug(message),\n info: (message: string): void => console.info(message),\n warn: (message: string): void => console.warn(message),\n error: (message: string): void => console.error(message),\n level: 'info',\n };\n\n this.promises = {\n access: async (path: PathLike, mode?: number): Promise => {\n this.#checkProtected(path, true);\n return nodeFS.promises.access(path, mode);\n },\n cp: async (source: string | URL, destination: string | URL, opts?: CopyOptions): Promise => {\n this.#checkProtected(source, false);\n this.#checkProtected(destination, false);\n return nodeFS.promises.cp(source, destination, opts);\n },\n readFile: async (\n path: PathLike | FileHandle,\n options:\n | ({\n encoding: BufferEncoding;\n flag?: OpenMode | undefined;\n } & Abortable)\n | BufferEncoding,\n ): Promise => {\n this.#checkProtected(path, true);\n return nodeFS.promises.readFile(path, options); // async function readFile(path, options) {\n },\n readlink: async (path: PathLike, options: BufferEncodingOption): Promise => {\n this.#checkProtected(path, true);\n return nodeFS.promises.readlink(path, options); // async function readlink(path, options) {\n },\n symlink: async (target: PathLike, path: PathLike, type?: string | null): Promise => {\n this.#checkProtected(target, true);\n this.#checkProtected(path, false);\n return nodeFS.promises.symlink(target, path, type); // async function symlink(target, path, type_) {\n },\n writeFile: async (\n file: PathLike | FileHandle,\n data:\n | string\n | NodeJS.ArrayBufferView\n | Iterable\n | AsyncIterable\n | Stream,\n options?:\n | (ObjectEncodingOptions & {\n mode?: Mode | undefined;\n flag?: OpenMode | undefined;\n /**\n * If all data is successfully written to the file, and `flush`\n * is `true`, `filehandle.sync()` is used to flush the data.\n *\n * @default false\n */\n flush?: boolean | undefined;\n } & Abortable)\n | BufferEncoding\n | null,\n ): Promise => {\n this.#checkProtected(file, true);\n return nodeFS.promises.writeFile.call(this, file, data, options); // async function writeFile(path, data, options) {\n },\n unlink: async (path: PathLike): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.unlink.call(this, path); // async function unlink(path) {\n },\n appendFile: async (\n path: PathLike | FileHandle,\n data: string | Uint8Array,\n options?:\n | (ObjectEncodingOptions & FlagAndOpenMode & { flush?: boolean | undefined })\n | BufferEncoding\n | null,\n ): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.appendFile.call(this, path, data, options); // async function appendFile(path, data, options) {\n },\n chmod: async (path: PathLike, mode: Mode): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.chmod.call(this, path, mode); // async function chmod(path, mode) {\n },\n copyFile: async (src: PathLike, dest: PathLike, mode?: number): Promise => {\n this.#checkProtected(src, false);\n this.#checkProtected(dest, false);\n return nodeFS.promises.copyFile.call(this, src, dest, mode); // async function copyFile(src, dest, mode) {\n },\n rename: async (oldPath: PathLike, newPath: PathLike): Promise => {\n this.#checkProtected(oldPath, false);\n this.#checkProtected(newPath, false);\n return nodeFS.promises.rename.call(this, oldPath, newPath); // async function rename(oldPath, newPath) {\n },\n open: async (path: PathLike, flags?: string | number, mode?: Mode): Promise => {\n this.#checkProtected(path, true);\n return nodeFS.promises.open.call(this, path, flags, mode); // async function open(path, flags, mode) {\n },\n truncate: async (path: PathLike, len?: number): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.truncate.call(this, path, len); // async function truncate(path, len = 0) {\n },\n stat: async (path: PathLike, opts?: StatOptions): Promise => {\n this.#checkProtected(path, true);\n const result = await nodeFS.promises.stat.call(this, path, opts); // async function stat(path, options = { bigint: false }) {\n return result as Stats;\n },\n utimes: async (path: PathLike, atime: TimeLike, mtime: TimeLike): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.utimes.call(this, path, atime, mtime); // async function utimes(path, atime, mtime) {\n },\n readdir: async (\n path: PathLike,\n options?: ObjectEncodingOptions & {\n withFileTypes: true;\n recursive?: boolean | undefined;\n },\n ): Promise => {\n this.#checkProtected(path, true);\n return nodeFS.promises.readdir.call(this, path, options || { encoding: null, withFileTypes: true }); // async function readdir(path, options) {\n },\n lchmod: async (path: PathLike, mode: Mode): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.lchmod.call(this, path, mode); // async function lchmod(path, mode) {\n },\n lchown: async (path: PathLike, uid: number, gid: number): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.lchown.call(this, path, uid, gid); // async function lchown(path, uid, gid) {\n },\n link: async (existingPath: PathLike, newPath: PathLike): Promise => {\n this.#checkProtected(existingPath, false);\n this.#checkProtected(newPath, false);\n return nodeFS.promises.link.call(this, existingPath, newPath); // async function link(existingPath, newPath) {\n },\n lstat: async (path: PathLike, opts?: StatOptions): Promise => {\n this.#checkProtected(path, true);\n const res = await nodeFS.promises.lstat.call(this, path, opts); // async function lstat(path, options = { bigint: false }) {\n return res as Stats;\n },\n lutimes: async (path: PathLike, atime: TimeLike, mtime: TimeLike): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.lutimes.call(this, path, atime, mtime); // async function lutimes(path, atime, mtime) {\n },\n mkdir: async (\n path: PathLike,\n options?: Mode | MakeDirectoryOptions | null,\n ): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.mkdir.call(this, path, options); // async function mkdir(path, options) {\n },\n mkdtemp: async (\n prefix: string,\n options?: ObjectEncodingOptions | BufferEncoding | null,\n ): Promise => {\n this.#checkProtected(prefix, false);\n const tmp = await nodeFS.promises.mkdtemp.call(this, prefix, options); // async function mkdtemp(prefix, options) {\n return tmp.toString();\n },\n rm: async (path: PathLike, options?: RmOptions): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.rm.call(this, path, options); // async function rm(path, options) {\n },\n rmdir: async (path: PathLike, options?: RmDirOptions): Promise => {\n this.#checkProtected(path, false);\n return nodeFS.promises.rmdir.call(this, path, options); // async function rmdir(path, options) {\n },\n };\n\n // Add missing constants\n this.constants = nodeFS.constants;\n\n // Add missing functions\n for (const m in nodeFS) {\n if (\n typeof (nodeFS as unknown as Record)[m] === 'function' &&\n Object.hasOwn(nodeFS, m) &&\n !Object.hasOwn(this, m)\n ) {\n // console.debug(`Missing function in ProtectFS: ${m} - adding from node:fs`);\n // @ts-expect-error Elsewise we must implement EVERY function in fs\n this[m] = nodeFS[m];\n }\n }\n\n for (const m in nodeFS.promises) {\n if (\n typeof (nodeFS.promises as unknown as Record)[m] === 'function' &&\n Object.hasOwn(nodeFS.promises, m) &&\n !Object.hasOwn(this.promises, m)\n ) {\n // console.debug(`Missing function in ProtectFS: ${m} - adding from node:fs/promises`);\n // @ts-expect-error Elsewise we must implement EVERY function in fs\n this.promises[m] = nodeFS.promises[m];\n }\n }\n }\n\n #checkProtected(file: PathLike | FileHandle, readOnly: boolean): void {\n if ((file as FileHandle).fd) {\n return;\n }\n const filePath = normalize((file as PathLike).toString());\n\n // todo: protect against file://...\n if (filePath.endsWith(`-data${sep}objects.json`) || filePath.endsWith(`-data${sep}objects.jsonl`)) {\n this.log.error(`May not read ${(file as PathLike).toString()}`);\n throw new Error('Permission denied');\n }\n if (!readOnly && filePath.startsWith(join(this.ioBrokerDataDir, 'files'))) {\n this.log.error(\n `May not read ${(file as PathLike).toString()} - use ${readOnly ? 'readFile' : 'writeFile'} instead`,\n );\n throw new Error('Permission denied');\n }\n }\n\n access(path: PathLike, callback: NoParamCallback): void {\n this.#checkProtected(path, true);\n return nodeFS.access(path, callback);\n }\n\n accessSync(path: PathLike, mode?: number): void {\n this.#checkProtected(path, true);\n return nodeFS.accessSync(path, mode); // function accessSync(path, mode) {\n }\n\n cp(\n source: string | URL,\n destination: string | URL,\n opts: CopyOptions | ((err: NodeJS.ErrnoException | null) => void),\n callback?: (err: NodeJS.ErrnoException | null) => void,\n ): void {\n this.#checkProtected(source, false);\n this.#checkProtected(destination, false);\n if (callback) {\n return nodeFS.cp(source, destination, opts as CopyOptions, callback);\n }\n if (typeof opts === 'function') {\n return nodeFS.cp(source, destination, opts);\n }\n return nodeFS.cp(source, destination, opts as (err: NodeJS.ErrnoException | null) => void);\n }\n\n cpSync(source: string | URL, destination: string | URL, opts?: CopySyncOptions): void {\n this.#checkProtected(source, false);\n this.#checkProtected(destination, false);\n return nodeFS.cpSync.call(this, source, destination, opts); // function cpSync(src, dest, options) {\n }\n\n readFile(path: PathOrFileDescriptor, callback: (err: NodeJS.ErrnoException | null, data: Buffer) => void): void {\n if (typeof path !== 'number') {\n this.#checkProtected(path, true);\n }\n return nodeFS.readFile.call(this, path, callback); // function readFile(path, options, callback) {\n }\n\n readFileSync(\n path: PathOrFileDescriptor,\n options:\n | {\n encoding: BufferEncoding;\n flag?: string | undefined;\n }\n | BufferEncoding,\n ): string | Buffer {\n if (typeof path !== 'number') {\n this.#checkProtected(path, true);\n }\n return nodeFS.readFileSync.call(this, path, options); // function readFileSync(path, options) {\n }\n\n readlink(path: PathLike, callback: (err: NodeJS.ErrnoException | null, linkString: string) => void): void {\n this.#checkProtected(path, true);\n return nodeFS.readlink.call(this, path, callback); // function readlink(path, options, callback) {\n }\n\n readlinkSync(path: PathLike, options?: any): string | Buffer {\n this.#checkProtected(path, true);\n return nodeFS.readlinkSync.call(this, path, options); // function readlinkSync(path, options) {\n }\n\n symlink(\n target: PathLike,\n path: PathLike,\n type: 'dir' | 'file' | 'junction' | undefined | null | NoParamCallback,\n callback: NoParamCallback,\n ): void {\n this.#checkProtected(target, true);\n this.#checkProtected(path, false);\n if (typeof callback === 'function') {\n // @ts-expect-error should work\n return nodeFS.symlink.call(this, target, path, type, callback);\n }\n return nodeFS.symlink.call(this, target, path, type as NoParamCallback); // function symlink(target, path, type_, callback_) {\n }\n\n symlinkSync(target: PathLike, path: PathLike, type?: 'dir' | 'file' | 'junction' | null): void {\n this.#checkProtected(target, true);\n this.#checkProtected(path, false);\n return nodeFS.symlinkSync.call(this, target, path, type); // function symlinkSync(target, path, type) {\n }\n\n writeFile(\n file: PathLike | number,\n data: string | NodeJS.ArrayBufferView,\n options: WriteFileOptions | NoParamCallback,\n callback?: NoParamCallback,\n ): void {\n if (typeof file !== 'number') {\n this.#checkProtected(file, false);\n }\n // @ts-expect-error should work\n return nodeFS.writeFile.call(this, file, data, options, callback); // function writeFile(path, data, options, callback) {\n }\n\n writeFileSync(file: PathLike | number, data: string | NodeJS.ArrayBufferView, options?: WriteFileOptions): void {\n if (typeof file !== 'number') {\n this.#checkProtected(file, false);\n }\n return nodeFS.writeFileSync.call(this, file, data, options); // function writeFileSync(path, data, options) {\n }\n\n unlink(path: PathLike, callback: NoParamCallback): void {\n this.#checkProtected(path, false);\n return nodeFS.unlink.call(this, path, callback); // function unlink(path, callback) {\n }\n\n unlinkSync(path: PathLike): void {\n this.#checkProtected(path, false);\n return nodeFS.unlinkSync.call(this, path); // function unlinkSync(path) {\n }\n\n appendFile(file: PathLike | number, data: string | Uint8Array, callback: NoParamCallback): void {\n if (typeof file !== 'number') {\n this.#checkProtected(file, false);\n }\n return nodeFS.appendFile.call(this, file, data, callback); // function appendFile(path, data, options, callback) {\n }\n\n appendFileSync(file: PathLike | number, data: string | Uint8Array): void {\n if (typeof file !== 'number') {\n this.#checkProtected(file, false);\n }\n return nodeFS.appendFileSync.call(this, file, data); // function appendFileSync(path, data, options) {\n }\n\n chmod(path: PathLike, mode: Mode, callback: NoParamCallback): void {\n this.#checkProtected(path, false);\n return nodeFS.chmod.call(this, path, mode, callback); // function chmod(path, mode, callback) {\n }\n\n chmodSync(path: PathLike, mode: Mode): void {\n this.#checkProtected(path, false);\n return nodeFS.chmodSync.call(this, path, mode); // function chmodSync(path, mode) {\n }\n\n chown(path: PathLike, uid: number, gid: number, callback: NoParamCallback): void {\n this.#checkProtected(path, false);\n return nodeFS.chown.call(this, path, uid, gid, callback); // function chown(path, uid, gid, callback) {\n }\n\n chownSync(path: PathLike, uid: number, gid: number): void {\n this.#checkProtected(path, false);\n return nodeFS.chownSync.call(this, path, uid, gid); // function chownSync(path, uid, gid) {\n }\n\n copyFile(src: PathLike, dest: PathLike, mode: number | NoParamCallback, callback?: NoParamCallback): void {\n this.#checkProtected(src, true);\n this.#checkProtected(dest, false);\n // @ts-expect-error should work\n return nodeFS.copyFile.call(this, src, dest, mode, callback); // function copyFile(src, dest, mode, callback) {\n }\n\n copyFileSync(src: PathLike, dest: PathLike, mode?: number): void {\n this.#checkProtected(src, true);\n this.#checkProtected(dest, false);\n return nodeFS.copyFileSync.call(this, src, dest, mode); // function copyFileSync(src, dest, mode) {\n }\n\n rename(oldPath: PathLike, newPath: PathLike, callback: NoParamCallback): void {\n this.#checkProtected(oldPath, false);\n this.#checkProtected(newPath, false);\n return nodeFS.rename.call(this, oldPath, newPath, callback); // function rename(oldPath, newPath, callback) {\n }\n\n renameSync(oldPath: PathLike, newPath: PathLike): void {\n this.#checkProtected(oldPath, false);\n this.#checkProtected(newPath, false);\n return nodeFS.renameSync.call(this, oldPath, newPath); // function renameSync(oldPath, newPath) {\n }\n\n open(path: PathLike, callback: (err: NodeJS.ErrnoException | null, fd: number) => void): void {\n this.#checkProtected(path, true);\n return nodeFS.open.call(this, path, callback); // function open(path, flags, mode, callback) {\n }\n\n openSync(path: PathLike, flags: OpenMode, mode?: Mode | null): number {\n this.#checkProtected(path, true);\n return nodeFS.openSync.call(this, path, flags, mode); // function openSync(path, flags, mode) {\n }\n\n truncate(path: PathLike, callback: NoParamCallback): void {\n this.#checkProtected(path, false);\n return nodeFS.truncate.call(this, path, callback); // function truncate(path, len, callback) {\n }\n\n truncateSync(path: PathLike): void {\n this.#checkProtected(path, false);\n return nodeFS.truncateSync.call(this, path); // function truncateSync(path, len) {\n }\n\n exists(path: PathLike, callback: (exists: boolean) => void): void {\n this.#checkProtected(path, true);\n return nodeFS.exists.call(this, path, callback); // function exists(path, callback) {\n }\n\n existsSync(path: PathLike): boolean {\n this.#checkProtected(path, true);\n return nodeFS.existsSync.call(this, path); // function existsSync(path) {\n }\n\n stat(\n path: PathLike,\n options: StatOptions | undefined | ((err: NodeJS.ErrnoException | null, stats: Stats) => void),\n callback?: (err: NodeJS.ErrnoException | null, stats: Stats) => void,\n ): void {\n this.#checkProtected(path, true);\n // @ts-expect-error should work\n return nodeFS.stat.call(this, path, options, callback); // function stat(path, options = { bigint: false }, callback) {\n }\n\n statSync(path: PathLike, options?: StatOptions): Stats {\n this.#checkProtected(path, true);\n return nodeFS.statSync.call(this, path, options); // function statSync(path, options = { bigint: false, throwIfNoEntry: true }) {\n }\n\n utimes(path: PathLike, atime: TimeLike, mtime: TimeLike, callback: NoParamCallback): void {\n this.#checkProtected(path, false);\n return nodeFS.utimes.call(this, path, atime, mtime, callback); // function utimes(path, atime, mtime, callback) {\n }\n\n utimesSync(path: PathLike, atime: TimeLike, mtime: TimeLike): void {\n this.#checkProtected(path, false);\n return nodeFS.utimesSync.call(this, path, atime, mtime); // function utimesSync(path, atime, mtime) {\n }\n\n readdir(\n path: PathLike,\n options:\n | (ObjectEncodingOptions & {\n withFileTypes: true;\n recursive?: boolean | undefined;\n })\n | ((err: NodeJS.ErrnoException | null, files: Dirent[]) => void),\n callback?: (err: NodeJS.ErrnoException | null, files: Dirent[]) => void,\n ): void {\n this.#checkProtected(path, true);\n // @ts-expect-error should work\n return nodeFS.readdir.call(this, path, options, callback); // function readdir(path, options, callback) {\n }\n\n readdirSync(\n path: PathLike,\n options?: ObjectEncodingOptions & {\n withFileTypes: true;\n recursive?: boolean | undefined;\n },\n ): void {\n this.#checkProtected(path, true);\n // @ts-expect-error should work\n return nodeFS.readdirSync.call(this, path, options); // function readdirSync(path, options) {\n }\n\n createReadStream(path: PathLike, options?: BufferEncoding): ReadStream {\n this.#checkProtected(path, true);\n return nodeFS.createReadStream.call(this, path, options); // function createReadStream(path, options) {\n }\n\n createWriteStream(path: PathLike, options?: BufferEncoding): WriteStream {\n this.#checkProtected(path, false);\n return nodeFS.createWriteStream.call(this, path, options); // function createWriteStream(path, options) {\n }\n\n lchmod(path: PathLike, mode: Mode, callback: NoParamCallback): void {\n this.#checkProtected(path, false);\n return nodeFS.lchmod.call(this, path, mode, callback); // function lchmod(path, mode, callback) {\n }\n\n lchmodSync(path: PathLike, mode: Mode): void {\n this.#checkProtected(path, false);\n return nodeFS.lchmodSync.call(this, path, mode); // function lchmodSync(path, mode) {\n }\n\n lchown(path: PathLike, uid: number, gid: number, callback: NoParamCallback): void {\n this.#checkProtected(path, false);\n return nodeFS.lchown.call(this, path, uid, gid, callback); // function lchown(path, uid, gid, callback) {\n }\n\n lchownSync(path: PathLike, uid: number, gid: number): void {\n this.#checkProtected(path, false);\n return nodeFS.lchownSync.call(this, path, uid, gid); // function lchownSync(path, uid, gid) {\n }\n\n link(existingPath: PathLike, newPath: PathLike, callback: NoParamCallback): void {\n this.#checkProtected(existingPath, false);\n this.#checkProtected(newPath, false);\n return nodeFS.link.call(this, existingPath, newPath, callback); // function link(existingPath, newPath, callback) {\n }\n\n linkSync(existingPath: PathLike, newPath: PathLike): void {\n this.#checkProtected(existingPath, false);\n this.#checkProtected(newPath, false);\n return nodeFS.linkSync.call(this, existingPath, newPath); // function linkSync(existingPath, newPath) {\n }\n\n lstat(\n path: PathLike,\n options: StatOptions | undefined | ((err: NodeJS.ErrnoException | null, stats: Stats) => void),\n callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void,\n ): void {\n this.#checkProtected(path, true);\n // @ts-expect-error should work\n return nodeFS.lstat.call(this, path, options, callback); // function lstat(path, options = { bigint: false }, callback) {\n }\n\n lstatSync(path: PathLike, options?: StatOptions): Stats {\n this.#checkProtected(path, true);\n return nodeFS.lstatSync.call(this, path, options); // function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) {\n }\n\n lutimes(path: PathLike, atime: TimeLike, mtime: TimeLike, callback: NoParamCallback): void {\n this.#checkProtected(path, false);\n return nodeFS.lutimes.call(this, path, atime, mtime, callback); // function lutimes(path, atime, mtime, callback) {\n }\n\n lutimesSync(path: PathLike, atime: TimeLike, mtime: TimeLike): void {\n this.#checkProtected(path, false);\n return nodeFS.lutimesSync.call(this, path, atime, mtime); // function lutimesSync(path, atime, mtime) {\n }\n\n mkdir(\n path: PathLike,\n options:\n | Mode\n | (MakeDirectoryOptions & {\n recursive: true;\n })\n | null\n | undefined\n | ((err: NodeJS.ErrnoException | null, path?: string) => void),\n callback?: (err: NodeJS.ErrnoException | null, path?: string) => void,\n ): void {\n this.#checkProtected(path, false);\n // @ts-expect-error should work\n return nodeFS.mkdir.call(this, path, options, callback); // function mkdir(path, options, callback) {\n }\n\n mkdirSync(\n path: PathLike,\n options?: MakeDirectoryOptions & {\n recursive: true;\n },\n ): string | undefined {\n this.#checkProtected(path, false);\n return nodeFS.mkdirSync.call(this, path, options); // function mkdirSync(path, options) {\n }\n\n mkdtemp(\n prefix: string,\n options: EncodingOption | ((err: NodeJS.ErrnoException | null, folder: string) => void),\n callback?: (err: NodeJS.ErrnoException | null, folder: string) => void,\n ): void {\n this.#checkProtected(prefix, false);\n // @ts-expect-error should work\n return nodeFS.mkdtemp.call(this, prefix, options, callback); // function mkdtemp(prefix, options, callback) {\n }\n\n mkdtempSync(prefix: string, options?: EncodingOption): string | Buffer {\n this.#checkProtected(prefix, false);\n return nodeFS.mkdtempSync.call(this, prefix, options); // function mkdtempSync(prefix, options) {\n }\n\n rm(path: PathLike, options: RmOptions | NoParamCallback, callback?: NoParamCallback): void {\n this.#checkProtected(path, false);\n // @ts-expect-error should work\n return nodeFS.rm.call(this, path, options, callback); // function rm(path, options, callback) {\n }\n\n rmSync(path: PathLike, options?: RmOptions): void {\n this.#checkProtected(path, false);\n return nodeFS.rmSync.call(this, path, options); // function rmSync(path, options) {\n }\n\n rmdir(path: PathLike, options: RmDirOptions | NoParamCallback, callback?: NoParamCallback): void {\n this.#checkProtected(path, false);\n // @ts-expect-error should work\n return nodeFS.rmdir.call(this, path, options, callback); // function rmdir(path, options, callback) {\n }\n\n rmdirSync(path: PathLike, options?: RmDirOptions): void {\n this.#checkProtected(path, false);\n return nodeFS.rmdirSync.call(this, path, options); // function rmdirSync(path, options) {\n }\n\n watch(filename: PathLike, listener?: WatchListener): FSWatcher {\n this.#checkProtected(filename, true);\n return nodeFS.watch.call(this, filename, listener); // function watch(filename, options, listener) {\n }\n\n watchFile(filename: PathLike, listener: StatsListener): StatWatcher {\n this.#checkProtected(filename, true);\n return nodeFS.watchFile.call(this, filename, listener); // function watchFile(filename, options, listener) {\n }\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/request.js b/build-backend/lib/request.js new file mode 100644 index 00000000..16f67f83 --- /dev/null +++ b/build-backend/lib/request.js @@ -0,0 +1,79 @@ +"use strict"; +// This module monkey-patches request for the sandbox +// so unhandled errors in the callback or forgetting to +// attach the error event handler does not bring down the adapter +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.request = void 0; +const _request = __importStar(require("request")); +let logger = { + error: (e) => console.error(e), +}; +function requestError(error) { + logger.error(`Request error: ${error}`); +} +/** + * Calls a request method which accepts a callback and handles errors in the request and the callback itself + */ +function requestSafe(method, ...args) { + const lastArg = args[args.length - 1]; + if (typeof lastArg === 'function') { + // If a callback was provided, handle errors in the callback + const otherArgs = args.slice(0, args.length - 1); + return method(...otherArgs, (...cbArgs) => { + try { + lastArg(...cbArgs); + } + catch (err) { + logger.error(`Error in request callback: ${err}`); + } + }).on('error', requestError); + } + // otherwise, just pass the call through + return method(...args).on('error', requestError); +} +// and request itself +// @ts-expect-error fix later +const request = (...args) => requestSafe(_request, ...args); +exports.request = request; +exports.request.get = (...args) => requestSafe(_request.get, ...args); +exports.request.post = (...args) => requestSafe(_request.post, ...args); +exports.request.put = (...args) => requestSafe(_request.put, ...args); +exports.request.head = (...args) => requestSafe(_request.head, ...args); +exports.request.patch = (...args) => requestSafe(_request.patch, ...args); +exports.request.del = (...args) => requestSafe(_request.del, ...args); +exports.request.delete = (...args) => requestSafe(_request.delete, ...args); +exports.request.initParams = (...args) => requestSafe(_request.initParams, ...args); +// And copy all other properties and methods +exports.request.defaults = _request.defaults; +exports.request.forever = _request.forever; +exports.request.jar = _request.jar; +exports.request.cookie = _request.cookie; +exports.request.debug = _request.debug; +exports.request.setLogger = function (_logger) { + logger = _logger; +}; +// end of monkeypatching +//# sourceMappingURL=request.js.map \ No newline at end of file diff --git a/build-backend/lib/request.js.map b/build-backend/lib/request.js.map new file mode 100644 index 00000000..37997d93 --- /dev/null +++ b/build-backend/lib/request.js.map @@ -0,0 +1 @@ +{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/lib/request.ts"],"names":[],"mappings":"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","sourcesContent":["// This module monkey-patches request for the sandbox\n// so unhandled errors in the callback or forgetting to\n// attach the error event handler does not bring down the adapter\n\nimport * as _request from 'request';\n\nlet logger: {\n error: (e: string) => void;\n} = {\n error: (e: string): void => console.error(e),\n};\n\nfunction requestError(error: Error | string): void {\n logger.error(`Request error: ${error}`);\n}\n\n/**\n * Calls a request method which accepts a callback and handles errors in the request and the callback itself\n */\nfunction requestSafe(method: (..._args: any[]) => any, ...args: any[]): any {\n const lastArg = args[args.length - 1];\n if (typeof lastArg === 'function') {\n // If a callback was provided, handle errors in the callback\n const otherArgs = args.slice(0, args.length - 1);\n return method(...otherArgs, (...cbArgs: any[]): void => {\n try {\n lastArg(...cbArgs);\n } catch (err: unknown) {\n logger.error(`Error in request callback: ${err as Error}`);\n }\n }).on('error', requestError);\n }\n\n // otherwise, just pass the call through\n return method(...args).on('error', requestError);\n}\n\n// and request itself\n// @ts-expect-error fix later\nexport const request = (...args: any[]): any => requestSafe(_request, ...args);\n\nrequest.get = (...args: any[]): any => requestSafe(_request.get, ...args);\nrequest.post = (...args: any[]): any => requestSafe(_request.post, ...args);\nrequest.put = (...args: any[]): any => requestSafe(_request.put, ...args);\nrequest.head = (...args: any[]): any => requestSafe(_request.head, ...args);\nrequest.patch = (...args: any[]): any => requestSafe(_request.patch, ...args);\nrequest.del = (...args: any[]): any => requestSafe(_request.del, ...args);\nrequest.delete = (...args: any[]): any => requestSafe(_request.delete, ...args);\nrequest.initParams = (...args: any[]): any => requestSafe(_request.initParams, ...args);\n\n// And copy all other properties and methods\nrequest.defaults = _request.defaults;\nrequest.forever = _request.forever;\nrequest.jar = _request.jar;\nrequest.cookie = _request.cookie;\nrequest.debug = _request.debug;\n\nrequest.setLogger = function (_logger: { error: (e: string) => void }): void {\n logger = _logger;\n};\n\n// end of monkeypatching\n"]} \ No newline at end of file diff --git a/build-backend/lib/sandbox.js b/build-backend/lib/sandbox.js new file mode 100644 index 00000000..c6885c01 --- /dev/null +++ b/build-backend/lib/sandbox.js @@ -0,0 +1,4585 @@ +"use strict"; +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.sandBox = sandBox; +const jsonataMod = __importStar(require("jsonata")); +const adapter_core_1 = require("@iobroker/adapter-core"); +const tools_1 = require("./tools"); +const constsMod = __importStar(require("./consts")); +const wordsMod = __importStar(require("./words")); +const eventObjMod = __importStar(require("./eventObj")); +const patternCompareFunctions_1 = require("./patternCompareFunctions"); +const pattern2RegEx = adapter_core_1.commonTools.pattern2RegEx; +function sandBox(script, name, verbose, debug, context) { + const consts = constsMod; + const words = wordsMod; + const eventObj = eventObjMod; + const patternCompareFunctions = patternCompareFunctions_1.patternCompareFunctions; + const jsonata = jsonataMod.default; + const adapter = context.adapter; + const mods = context.mods; + const states = context.states; + const objects = context.objects; + const timers = context.timers; + const enums = context.enums; + const debugMode = context.debugMode; + // eslint-disable-next-line prefer-const + let sandbox; + function errorInCallback(e) { + adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, { + val: true, + ack: true, + c: 'errorInCallback', + }); + context.logError('Error in callback', e); + context.debugMode && console.log(`error$$${name}$$Exception in callback: ${e}`, Date.now()); + } + function subscribePattern(script, pattern) { + if (adapter.config.subscribe) { + if (!script.subscribes[pattern]) { + script.subscribes[pattern] = 1; + } + else { + script.subscribes[pattern]++; + } + if (!context.subscribedPatterns[pattern]) { + context.subscribedPatterns[pattern] = 1; + if (sandbox.verbose) { + sandbox.log(`subscribePattern(pattern=${pattern})`, 'info'); + } + adapter.subscribeForeignStates(pattern); + // request current value to deliver old value on change. + if (typeof pattern === 'string' && !pattern.includes('*')) { + adapter.getForeignState(pattern, (_err, state) => { + if (state) { + states[pattern] = state; + } + }); + } + else { + adapter.getForeignStates(pattern, (_err, _states) => _states && Object.keys(_states).forEach(id => (states[id] = _states[id]))); + } + } + else { + context.subscribedPatterns[pattern]++; + } + } + } + function unsubscribePattern(script, pattern) { + if (adapter.config.subscribe) { + if (script.subscribes[pattern]) { + script.subscribes[pattern]--; + if (!script.subscribes[pattern]) { + delete script.subscribes[pattern]; + } + } + if (context.subscribedPatterns[pattern]) { + context.subscribedPatterns[pattern]--; + if (!context.subscribedPatterns[pattern]) { + adapter.unsubscribeForeignStates(pattern); + delete context.subscribedPatterns[pattern]; + // if the pattern was regex or with * some states will stay in RAM, but it is OK. + if (states[pattern]) { + delete states[pattern]; + } + } + } + } + } + function subscribeFile(script, id, fileNamePattern) { + const key = `${id}$%$${fileNamePattern}`; + if (!script.subscribesFile[key]) { + script.subscribesFile[key] = 1; + } + else { + script.subscribesFile[key]++; + } + if (!context.subscribedPatternsFile[key]) { + context.subscribedPatternsFile[key] = 1; + adapter.subscribeForeignFiles(id, fileNamePattern); + } + else { + context.subscribedPatternsFile[key]++; + } + } + function unsubscribeFile(script, id, fileNamePattern) { + const key = `${id}$%$${fileNamePattern}`; + if (script.subscribesFile[key]) { + script.subscribesFile[key]--; + if (!script.subscribesFile[key]) { + delete script.subscribesFile[key]; + } + } + if (context.subscribedPatternsFile[key]) { + context.subscribedPatternsFile[key]--; + if (!context.subscribedPatternsFile[key]) { + adapter.unsubscribeForeignFiles(id, fileNamePattern); + delete context.subscribedPatternsFile[key]; + } + } + } + function getPatternCompareFunctions(pattern) { + let func; + const functions = []; + functions.logic = pattern.logic || 'and'; + for (const key in pattern) { + if (!Object.prototype.hasOwnProperty.call(pattern, key)) { + continue; + } + if (key === 'logic') { + continue; + } + if (key === 'change' && pattern.change === 'any') { + continue; + } + const _func = patternCompareFunctions[key]; + if (!_func) { + continue; + } + func = _func(pattern); + if (typeof func !== 'function') { + continue; + } + functions.push(func); + } + return functions; + } + /** + * Splits a selector string into attribute and value + * + * @param selector The selector string to split + */ + function splitSelectorString(selector) { + const parts = selector.split('=', 2); + if (parts[1] && parts[1][0] === '"') { + parts[1] = parts[1].substring(1); + const len = parts[1].length; + if (parts[1] && parts[1][len - 1] === '"') { + parts[1] = parts[1].substring(0, len - 1); + } + } + if (parts[1] && parts[1][0] === "'") { + parts[1] = parts[1].substring(1); + const len = parts[1].length; + if (parts[1] && parts[1][len - 1] === "'") { + parts[1] = parts[1].substring(0, len - 1); + } + } + if (parts[1]) { + parts[1] = parts[1].trim(); + } + parts[0] = parts[0].trim(); + return { attr: parts[0], value: parts[1] }; + } + /** + * Transforms a selector string with wildcards into a regular expression + * + * @param str The selector string to transform into a regular expression + */ + function selectorStringToRegExp(str) { + const startsWithWildcard = str[0] === '*'; + const endsWithWildcard = str[str.length - 1] === '*'; + // Sanitize the selector, so it is safe to use in a RegEx + // Taken from https://stackoverflow.com/a/3561711/10179833 but modified + // since * has a special meaning in our selector and should not be escaped + // eslint-disable-next-line no-useless-escape + str = str.replace(/[-\/\\^$+?.()|[\]{}]/g, '\\$&').replace(/\*/g, '.*'); + return new RegExp((startsWithWildcard ? '' : '^') + str + (endsWithWildcard ? '' : '$')); + } + /** + * Adds a regular expression for selectors targeting the state ID + * + * @param selector The selector to apply the transform to + */ + function addRegExpToIdAttrSelectors(selector) { + if ((selector.attr === 'id' || selector.attr === 'state.id') && !selector.idRegExp && selector.value) { + return { + attr: selector.attr, + value: selector.value, + idRegExp: selectorStringToRegExp(selector.value), + }; + } + return selector; + } + /** + * Tests if a value loosely equals (==) the reference string. + * In contrast to the equality operator, this treats true == "true" as well + * so we can test common and native attributes for boolean values + * + * @param value The value to compare with the reference + * @param reference The reference to compare the value to + */ + function looselyEqualsString(value, reference) { + // For booleans, compare the string representation + // For other types do a loose comparison + return typeof value === 'boolean' + ? (value && reference === 'true') || (!value && reference === 'false') + : value == reference; + } + /** + * Returns the `common.type` for a given variable + */ + function getCommonTypeOf(value) { + return (0, tools_1.isArray)(value) ? 'array' : (0, tools_1.isObject)(value) ? 'object' : typeof value; + } + /** + * Returns if an id is in an allowed namespace for automatic object creations + * + * @param id id to check + */ + function validIdForAutomaticFolderCreation(id) { + return id.startsWith('javascript.') || id.startsWith('0_userdata.0.') || id.startsWith('alias.0.'); + } + /** + * Iterate through object structure to create missing folder objects + */ + async function ensureObjectStructure(id) { + if (!validIdForAutomaticFolderCreation(id)) { + return; + } + if (context.folderCreationVerifiedObjects[id] === true) { + return; + } + const idArr = id.split('.'); + idArr.pop(); // the last is created as an object in any way + if (idArr.length < 3) { + return; // Nothing to do + } + // We just create sublevel projects + let idToCheck = idArr.splice(0, 2).join('.'); + context.folderCreationVerifiedObjects[id] = true; + for (const part of idArr) { + idToCheck += `.${part}`; + if (context.folderCreationVerifiedObjects[idToCheck] === true || objects[idToCheck]) { + continue; + } + context.folderCreationVerifiedObjects[idToCheck] = true; + let obj; + try { + obj = await adapter.getForeignObjectAsync(idToCheck); + } + catch { + // ignore + } + if (!obj?.common) { + sandbox.log(`Create folder object for ${idToCheck}`, 'debug'); + try { + await adapter.setForeignObjectAsync(idToCheck, { + _id: idToCheck, + type: 'folder', + common: { + name: part, + }, + native: { + autocreated: 'by automatic ensure logic', + }, + }); + } + catch (err) { + sandbox.log(`Could not automatically create folder object ${idToCheck}: ${err.message}`, 'info'); + } + } + else { + //sandbox.log(` already existing "${idToCheck}": ${JSON.stringify(obj)}`, 'debug'); + } + } + } + function setStateHelper(sandbox, isCreate, isChanged, id, state, isAck, callback) { + if (typeof isAck === 'function') { + callback = isAck; + isAck = undefined; + } + let stateNotNull; + if (isAck === true || isAck === false || isAck === 'true' || isAck === 'false') { + if (state && typeof state === 'object' && state.val !== undefined) { + stateNotNull = state; + // we assume that we were given a state object if + // state is an object that contains a `val` property + if (!Object.prototype.hasOwnProperty.call(state, 'ack')) { + stateNotNull.ack = isAck === true || isAck === 'true'; + } + } + else if (state === null) { + stateNotNull = { val: null, ack: isAck === true || isAck === 'true' }; + } + else { + // otherwise, assume that the given state is the value to be set + stateNotNull = { val: state, ack: isAck === true || isAck === 'true' }; + } + } + else if (state === null) { + stateNotNull = { val: null }; + } + else { + stateNotNull = state; + } + // Check a type of state + if (!objects[id] && objects[`${adapter.namespace}.${id}`]) { + id = `${adapter.namespace}.${id}`; + } + if (isCreate) { + if (id.match(/^javascript\.\d+\.scriptEnabled/)) { + sandbox.log(`Own states (${id}) should not be used in javascript.X.scriptEnabled.*! Please move the states to 0_userdata.0.*`, 'info'); + } + else if (id.match(/^javascript\.\d+\.scriptProblem/)) { + sandbox.log(`Own states (${id}) should not be used in javascript.X.scriptProblem.*! Please move the states to 0_userdata.0.*`, 'info'); + } + } + const common = objects[id] ? objects[id].common : null; + if (common?.type && common.type !== 'mixed' && common.type !== 'json') { + // Find out which type the value has + let actualCommonType; + if (typeof stateNotNull === 'object') { + if (stateNotNull && stateNotNull.val !== undefined && stateNotNull.val !== null) { + actualCommonType = getCommonTypeOf(stateNotNull.val); + } + } + else if (stateNotNull !== null && stateNotNull !== undefined) { + actualCommonType = getCommonTypeOf(stateNotNull); + } + // If this is not the expected one, issue a warning + if (actualCommonType && actualCommonType !== common.type) { + context.logWithLineInfo(`You are assigning a ${actualCommonType} to the state "${id}" which expects a ${common.type}. ` + + `Please fix your code to use a ${common.type} or change the state type to ${actualCommonType}. ` + + `This warning might become an error in future versions.`); + } + if (actualCommonType === 'array' || actualCommonType === 'object') { + try { + if (typeof stateNotNull === 'object' && typeof stateNotNull.val !== 'undefined') { + stateNotNull.val = JSON.stringify(stateNotNull.val); + } + else { + stateNotNull = JSON.stringify(stateNotNull); + } + } + catch (err) { + context.logWithLineInfo(`Could not stringify value for type ${actualCommonType} and id ${id}: ${err.message}`); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(`Could not stringify value for type ${actualCommonType} and id ${id}: ${err.message}`)); + } + catch (err) { + errorInCallback(err); + } + } + } + } + } + // Check min and max of value + if (typeof stateNotNull === 'object') { + if (common && typeof stateNotNull.val === 'number') { + const num = stateNotNull.val; + if (common.min !== undefined && num < common.min) { + stateNotNull.val = common.min; + } + else if (common.max !== undefined && num > common.max) { + stateNotNull.val = common.max; + } + } + } + else if (common && typeof stateNotNull === 'number') { + const num = stateNotNull; + if (common.min !== undefined && num < common.min) { + stateNotNull = common.min; + } + if (common.max !== undefined && num > common.max) { + stateNotNull = common.max; + } + } + let stateAsObject; + // modify state here, to make it available in callback + if (stateNotNull === null || + typeof stateNotNull !== 'object' || + stateNotNull.val === undefined) { + stateAsObject = context.prepareStateObject(id, { + val: stateNotNull, + ack: isAck === true || isAck === 'true', + }); + } + else { + stateAsObject = context.prepareStateObject(id, stateNotNull); + } + // set as comment: from which script this state was set. + stateAsObject.c = sandbox.scriptName; + if (objects[id]) { + script.setStatePerMinuteCounter++; + if (sandbox.verbose) { + sandbox.log(`setForeignState(id=${id}, state=${JSON.stringify(stateAsObject)})`, 'info'); + } + if (debug) { + sandbox.log(`setForeignState(id=${id}, state=${JSON.stringify(stateAsObject)}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + if (typeof callback === 'function') { + setImmediate(() => { + try { + callback.call(sandbox); + } + catch (err) { + errorInCallback(err); + } + }); + } + } + else { + if (!adapter.config.subscribe) { + // store actual state to make possible to process value in callback + // risk that there will be an error on setState is very low, + // but we will not store new state if the setStateChanged is called + if (!isChanged) { + context.interimStateValues[id] = stateAsObject; + } + } + const errHandler = (err, funcId) => { + err && sandbox.log(`${funcId}: ${err}`, 'error'); + // If adapter holds all states + if (err && !adapter.config.subscribe) { + delete context.interimStateValues[id]; + } + if (typeof callback === 'function') { + setImmediate(() => { + try { + callback.call(sandbox); + } + catch (err) { + errorInCallback(err); + } + }); + } + }; + if (isChanged) { + if (!adapter.config.subscribe && context.interimStateValues[id]) { + // if the state is changed, we will compare it with interimStateValues + const oldState = context.interimStateValues[id]; + const attrs = Object.keys(stateAsObject).filter(attr => attr !== 'ts' && stateAsObject[attr] !== undefined); + if (!attrs.every(attr => stateAsObject[attr] === + oldState[attr])) { + // state is changed for sure, and we will call setForeignState + // and store new state to interimStateValues + context.interimStateValues[id] = stateAsObject; + adapter.setForeignState(id, stateAsObject, err => errHandler(err, 'setForeignState')); + } + else { + // otherwise - do nothing as we have cached state, except callback + errHandler(null, 'setForeignStateCached'); + } + } + else { + // adapter doesn't hold all states, or it has not cached then we will simply call setForeignStateChanged + adapter.setForeignStateChanged(id, { ...stateAsObject, ts: undefined }, err => errHandler(err, 'setForeignStateChanged')); + } + } + else { + adapter.setForeignState(id, stateAsObject, err => errHandler(err, 'setForeignState')); + } + } + } + else { + context.logWithLineInfo(`State "${id}" not found`); + if (typeof callback === 'function') { + setImmediate(() => { + try { + callback.call(sandbox, new Error(`State "${id}" not found`)); + } + catch (err) { + errorInCallback(err); + } + }); + } + } + } + sandbox = { + mods, + _id: script._id, + // @deprecated use scriptName + name, + scriptName: name, + instance: adapter.instance || 0, + defaultDataDir: context.getAbsoluteDefaultDataDir(), + verbose, + exports: {}, // Polyfill for the export object in TypeScript modules + require: function (md) { + if (typeof md === 'string' && md.startsWith('node:')) { + md = md.replace(/^node:/, ''); + } + if (md === 'request') { + if (!sandbox.__engine.__deprecatedWarnings.includes(md)) { + sandbox.log(`request package is deprecated - please use httpGet (or a stable lib like axios) instead!`, 'warn'); + sandbox.__engine.__deprecatedWarnings.push(md); + } + } + if (mods[md]) { + return mods[md]; + } + let error; + try { + mods[md] = require(adapter.getAdapterScopedPackageIdentifier ? adapter.getAdapterScopedPackageIdentifier(md) : md); + return mods[md]; + } + catch (e) { + error = e; + } + try { + // the user requires a module which is not specified in the additional node modules + // for backward compatibility we check if the module can simply be required directly before we fail (e.g., direct dependencies of JavaScript adapter) + adapter.log.debug(`Try direct require of "${md}" as not specified in the additional dependencies`); + mods[md] = require(md); + return mods[md]; + } + catch (e) { + context.logError(name, error || e, 6); + adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, { + val: true, + ack: true, + c: 'require', + }); + } + }, + Buffer: Buffer, + __engine: { + __deprecatedWarnings: [], + __subscriptionsObject: 0, + __subscriptions: 0, + __subscriptionsMessage: 0, + __subscriptionsFile: 0, + __subscriptionsLog: 0, + __schedules: 0, + }, + $: function (selector) { + // following is supported + // 'type[commonAttr=something]', 'id[commonAttr=something]', id(enumName="something")', id{nativeName="something"} + // Type can be state, channel or device + // Attr can be any of the common attributes and can have wildcards * + // E.g. "state[id='hm-rpc.0.*]" or "hm-rpc.0.*" returns all states of adapter instance hm-rpc.0 + // channel(room="Living room") => all states in room "Living room" + // channel{TYPE=BLIND}[state.id=*.LEVEL] + // Switch all states with .STATE of channels with role "switch" in "Wohnzimmer" to false + // $('channel[role=switch][state.id=*.STATE](rooms=Wohnzimmer)').setState(false); + // + // Following functions are possible, setValue, getValue (only from first), on, each + // Todo CACHE!!! + const result = {}; + let name = ''; + const commonStrings = []; + const enumStrings = []; + const nativeStrings = []; + let isInsideName = true; + let isInsideCommonString = false; + let isInsideEnumString = false; + let isInsideNativeString = false; + let currentCommonString = ''; + let currentNativeString = ''; + let currentEnumString = ''; + // parse string + let selectorHasInvalidType = false; + if (typeof selector === 'string') { + for (let i = 0; i < selector.length; i++) { + if (selector[i] === '{') { + isInsideName = false; + if (isInsideCommonString || isInsideEnumString || isInsideNativeString) { + // Error + break; + } + isInsideNativeString = true; + } + else if (selector[i] === '}') { + isInsideNativeString = false; + nativeStrings.push(currentNativeString); + currentNativeString = ''; + } + else if (selector[i] === '[') { + isInsideName = false; + if (isInsideCommonString || isInsideEnumString || isInsideNativeString) { + // Error + break; + } + isInsideCommonString = true; + } + else if (selector[i] === ']') { + isInsideCommonString = false; + commonStrings.push(currentCommonString); + currentCommonString = ''; + } + else if (selector[i] === '(') { + isInsideName = false; + if (isInsideCommonString || isInsideEnumString || isInsideNativeString) { + // Error + break; + } + isInsideEnumString = true; + } + else if (selector[i] === ')') { + isInsideEnumString = false; + enumStrings.push(currentEnumString); + currentEnumString = ''; + } + else if (isInsideName) { + name += selector[i]; + } + else if (isInsideCommonString) { + currentCommonString += selector[i]; + } + else if (isInsideEnumString) { + currentEnumString += selector[i]; + } + else if (isInsideNativeString) { + currentNativeString += selector[i]; + } //else { + // some error + //} + } + } + else { + selectorHasInvalidType = true; + } + // If some error in the selector + if (selectorHasInvalidType || isInsideEnumString || isInsideCommonString || isInsideNativeString) { + result.length = 0; + result.toArray = function () { + return []; + }; + result.each = function () { + return this; + }; + result.getState = function () { + return null; + }; + result.setState = function () { + return this; + }; + result.on = function () { + return this; + }; + } + if (isInsideEnumString) { + sandbox.log(`Invalid selector: enum close bracket ")" cannot be found in "${selector}"`, 'warn'); + result.error = 'Invalid selector: enum close bracket ")" cannot be found'; + return result; + } + else if (isInsideCommonString) { + sandbox.log(`Invalid selector: common close bracket "]" cannot be found in "${selector}"`, 'warn'); + result.error = 'Invalid selector: common close bracket "]" cannot be found'; + return result; + } + else if (isInsideNativeString) { + sandbox.log(`Invalid selector: native close bracket "}" cannot be found in "${selector}"`, 'warn'); + result.error = 'Invalid selector: native close bracket "}" cannot be found'; + return result; + } + else if (selectorHasInvalidType) { + const message = `Invalid selector: selector must be a string but is of type ${typeof selector}`; + sandbox.log(message, 'warn'); + result.error = message; + return result; + } + let commonSelectors = commonStrings.map(selector => splitSelectorString(selector)); + let nativeSelectors = nativeStrings.map(selector => splitSelectorString(selector)); + const enumSelectorObjects = enumStrings.map(_enum => splitSelectorString(_enum)); + const allSelectors = commonSelectors.concat(nativeSelectors, enumSelectorObjects); + // These selectors match the state or object ID and don't belong in the common/native selectors + // Also use RegExp for the ID matching + const stateIdSelectors = allSelectors + .filter(selector => selector.attr === 'state.id') + .map(selector => addRegExpToIdAttrSelectors(selector)); + const objectIdSelectors = allSelectors + .filter(selector => selector.attr === 'id') + .map(selector => addRegExpToIdAttrSelectors(selector)); + commonSelectors = commonSelectors.filter(selector => selector.attr !== 'state.id' && selector.attr !== 'id'); + nativeSelectors = nativeSelectors.filter(selector => selector.attr !== 'state.id' && selector.attr !== 'id'); + const enumSelectors = enumSelectorObjects + .filter(selector => selector.attr !== 'state.id' && selector.attr !== 'id') + // enums are filtered by their enum id, so transform the selector into that + .map(selector => `enum.${selector.attr}.${selector.value}`); + name = name.trim(); + if (name === 'channel' || name === 'device') { + // Fill the channels and devices objects with the IDs of all their states, + // so we can loop over them afterward + if (!context.channels || !context.devices) { + context.channels = {}; + context.devices = {}; + for (const _id in objects) { + if (Object.prototype.hasOwnProperty.call(objects, _id) && objects[_id].type === 'state') { + const parts = _id.split('.'); + parts.pop(); + const chn = parts.join('.'); + parts.pop(); + const dev = parts.join('.'); + context.devices[dev] = context.devices[dev] || []; + context.devices[dev].push(_id); + context.channels[chn] = context.channels[chn] || []; + context.channels[chn].push(_id); + } + } + } + } + if (name === 'schedule') { + if (!context.schedules) { + context.schedules = []; + for (const _id in objects) { + if (Object.prototype.hasOwnProperty.call(objects, _id) && objects[_id].type === 'schedule') { + context.schedules.push(_id); + } + } + } + } + /** + * applies all selectors targeting an object or state ID + */ + function applyIDSelectors(objId, selectors) { + // Only keep the ID if it matches every ID selector + return selectors.every(selector => !selector.idRegExp || selector.idRegExp.test(objId)); + } + /** + * Applies all selectors targeting the Object common properties + * + * @param objId - The ID of the object in question + */ + function applyCommonSelectors(objId) { + const obj = objects[objId]; + if (!obj?.common) { + return false; + } + const objCommon = obj.common; + // make sure this object satisfies all selectors + return commonSelectors.every(selector => + // ensure a property exists + (selector.value === undefined && objCommon[selector.attr] !== undefined) || + // or match exact values + looselyEqualsString(objCommon[selector.attr], selector.value)); + } + /** + * Applies all selectors targeting the Object native properties + * + * @param objId - The ID of the object in question + */ + function applyNativeSelectors(objId) { + const obj = objects[objId]; + if (!obj || !obj.native) { + return false; + } + const objNative = obj.native; + // make sure this object satisfies all selectors + return nativeSelectors.every(selector => + // ensure a property exists + (selector.value === undefined && objNative[selector.attr] !== undefined) || + // or match exact values + looselyEqualsString(objNative[selector.attr], selector.value)); + } + /** + * Applies all selectors targeting the Objects enums + * + * @param objId - The ID of the object in question + */ + function applyEnumSelectors(objId) { + const enumIds = []; + eventObj.getObjectEnumsSync(context, objId, enumIds); + // make sure this object satisfies all selectors + return enumSelectors.every(_enum => enumIds.includes(_enum)); + } + let res; + if (name === 'schedule') { + res = context.schedules || []; + if (objectIdSelectors.length) { + res = res.filter(channelId => applyIDSelectors(channelId, objectIdSelectors)); + } + // filter out those that don't match every common selector + if (commonSelectors.length) { + res = res.filter(id => applyCommonSelectors(id)); + } + // filter out those that don't match every native selector + if (nativeSelectors.length) { + res = res.filter(id => applyNativeSelectors(id)); + } + // filter out those that don't match every enum selector + if (enumSelectors.length) { + res = res.filter(channelId => applyEnumSelectors(channelId)); + } + } + else if (name === 'channel') { + if (!context.channels) { + // TODO: fill the channels and maintain them on all places where context.stateIds will be changed + } + const channels = context.channels || {}; + // go through all channels + res = Object.keys(channels); + // filter out those that don't match every ID selector for the channel ID + if (objectIdSelectors.length) { + res = res.filter(channelId => applyIDSelectors(channelId, objectIdSelectors)); + } + // filter out those that don't match every common selector + if (commonSelectors.length) { + res = res.filter(channelId => applyCommonSelectors(channelId)); + } + // filter out those that don't match every native selector + if (nativeSelectors.length) { + res = res.filter(channelId => applyNativeSelectors(channelId)); + } + // filter out those that don't match every enum selector + if (enumSelectors.length) { + res = res.filter(channelId => applyEnumSelectors(channelId)); + } + // retrieve the state ID collection for all remaining channels + res = res + .map(id => channels[id]) + // and flatten the array to get only the state IDs + .reduce((acc, next) => acc.concat(next), []); + // now filter out those that don't match every ID selector for the state ID + if (stateIdSelectors.length) { + res = res.filter(stateId => applyIDSelectors(stateId, stateIdSelectors)); + } + } + else if (name === 'device') { + if (!context.devices) { + // TODO: fill the devices and maintain them on all places where context.stateIds will be changed + } + const devices = context.devices || {}; + // go through all devices + res = Object.keys(devices); + // filter out those that don't match every ID selector for the channel ID + if (objectIdSelectors.length) { + res = res.filter(deviceId => applyIDSelectors(deviceId, objectIdSelectors)); + } + // filter out those that don't match every common selector + if (commonSelectors.length) { + res = res.filter(deviceId => applyCommonSelectors(deviceId)); + } + // filter out those that don't match every native selector + if (nativeSelectors.length) { + res = res.filter(deviceId => applyNativeSelectors(deviceId)); + } + // filter out those that don't match every enum selector + if (enumSelectors.length) { + res = res.filter(deviceId => applyEnumSelectors(deviceId)); + } + // retrieve the state ID collection for all remaining devices + res = res + .map(id => devices[id]) + // and flatten the array to get only the state IDs + .reduce((acc, next) => acc.concat(next), []); + // now filter out those that don't match every ID selector for the state ID + if (stateIdSelectors.length) { + res = res.filter(stateId => applyIDSelectors(stateId, stateIdSelectors)); + } + } + else { + // go through all states + res = context.stateIds; + // if the "name" is not state, then we filter for the ID as well + if (name && name !== 'state') { + const r = new RegExp(`^${name.replace(/\./g, '\\.').replace(/\*/g, '.*')}$`); + res = res.filter(id => r.test(id)); + } + // filter out those that don't match every ID selector for the object ID or the state ID + if (objectIdSelectors.length) { + res = res.filter(id => applyIDSelectors(id, objectIdSelectors)); + } + // filter out those that don't match every ID selector for the state ID + if (stateIdSelectors.length) { + res = res.filter(id => applyIDSelectors(id, stateIdSelectors)); + } + // filter out those that don't match every common selector + if (commonSelectors.length) { + res = res.filter(id => applyCommonSelectors(id)); + } + // filter out those that don't match every native selector + if (nativeSelectors.length) { + res = res.filter(id => applyNativeSelectors(id)); + } + // filter out those that don't match every enum selector + if (enumSelectors.length) { + res = res.filter(id => applyEnumSelectors(id)); + } + } + const resUnique = []; + for (let i = 0; i < res.length; i++) { + if (!resUnique.includes(res[i])) { + resUnique.push(res[i]); + } + } + for (let i = 0; i < resUnique.length; i++) { + result[i] = resUnique[i]; + } + result.length = resUnique.length; + // Implementing the Symbol.iterator contract makes the query result iterable + result[Symbol.iterator] = function* () { + for (let i = 0; i < result.length; i++) { + yield result[i]; + } + }; + result.toArray = function () { + return [...resUnique]; + }; + result.each = function (callback) { + if (typeof callback === 'function') { + let r; + for (let i = 0; i < this.length; i++) { + r = callback(result[i], i); + if (r === false) { + break; + } + } + } + return this; + }; + // @ts-expect-error fix later + result.getState = function (callback) { + if (adapter.config.subscribe) { + if (typeof callback !== 'function') { + sandbox.log('You cannot use this function synchronous', 'error'); + } + else { + adapter.getForeignState(this[0], (err, state) => { + callback(err, context.convertBackStringifiedValues(this[0], state)); + }); + } + } + else { + if (!this[0]) { + return null; + } + if (context.interimStateValues[this[0]] !== undefined) { + return context.convertBackStringifiedValues(this[0], context.interimStateValues[this[0]]); + } + return context.convertBackStringifiedValues(this[0], states[this[0]]); + } + }; + result.getStateAsync = async function () { + if (adapter.config.subscribe) { + const state = await adapter.getForeignStateAsync(this[0]); + return context.convertBackStringifiedValues(this[0], state); + } + if (!this[0]) { + return null; + } + if (context.interimStateValues[this[0]] !== undefined) { + return context.convertBackStringifiedValues(this[0], context.interimStateValues[this[0]]); + } + return context.convertBackStringifiedValues(this[0], states[this[0]]); + }; + result.setState = function (state, isAck, callback) { + if (typeof isAck === 'function') { + callback = isAck; + isAck = undefined; + } + result + .setStateAsync(state, isAck) + .then(() => typeof callback === 'function' && callback()); + return this; + }; + result.setStateAsync = async function (state, isAck) { + for (let i = 0; i < this.length; i++) { + await sandbox.setStateAsync(this[i], state, isAck); + } + }; + result.setStateChanged = function (state, isAck, callback) { + if (typeof isAck === 'function') { + callback = isAck; + isAck = undefined; + } + result.setStateChangedAsync(state, isAck).then(() => typeof callback === 'function' && callback()); + return this; + }; + result.setStateChangedAsync = async function (state, isAck) { + for (let i = 0; i < this.length; i++) { + await sandbox.setStateChangedAsync(this[i], state, isAck); + } + }; + result.setStateDelayed = function (state, isAck, delay, clearRunning, callback) { + if (typeof isAck !== 'boolean') { + callback = clearRunning; + clearRunning = delay; + delay = isAck; + isAck = undefined; + } + if (typeof delay !== 'number') { + callback = clearRunning; + clearRunning = delay; + delay = 0; + } + if (typeof clearRunning !== 'boolean') { + callback = clearRunning; + clearRunning = true; + } + let count = this.length; + for (let i = 0; i < this.length; i++) { + sandbox.setStateDelayed(this[i], state, isAck, delay, clearRunning, () => { + if (!--count && typeof callback === 'function') { + callback(); + } + }); + } + return this; + }; + result.on = function (callbackOrId, value) { + for (let i = 0; i < this.length; i++) { + sandbox.subscribe(this[i], callbackOrId, value); + } + return this; + }; + return result; + }, + log: function (msg, severity) { + severity = severity || 'info'; + // disable log in log handler (prevent endless loops) + if (sandbox.logHandler && (sandbox.logHandler === severity || sandbox.logHandler === '*')) { + return; + } + if (!adapter.log[severity]) { + msg = `Unknown severity level "${severity}" by log of [${msg}]`; + severity = 'warn'; + } + if (msg && typeof msg !== 'string') { + msg = mods.util.format(msg); + } + if (debugMode) { + console.log(`${severity}$$${name}$$${msg}`, Date.now()); + } + else { + adapter.log[severity](`${name}: ${msg}`); + } + }, + onLog: function (severity, callback) { + if (!['info', 'error', 'debug', 'silly', 'warn', '*'].includes(severity)) { + sandbox.log(`Unknown severity "${severity}"`, 'warn'); + return 0; + } + if (typeof callback !== 'function') { + sandbox.log(`Invalid callback for onLog`, 'warn'); + return 0; + } + const handler = { id: Date.now() + Math.floor(Math.random() * 10000), cb: callback, sandbox, severity }; + context.logSubscriptions[sandbox.scriptName] = context.logSubscriptions[sandbox.scriptName] || []; + context.logSubscriptions[sandbox.scriptName].push(handler); + context.updateLogSubscriptions(); + sandbox.__engine.__subscriptionsLog += 1; + sandbox.verbose && + sandbox.log(`onLog(severity=${severity}, id=${handler.id}) - logSubscriptions=${sandbox.__engine.__subscriptionsLog}`, 'info'); + if (sandbox.__engine.__subscriptionsLog % + adapter.config.maxTriggersPerScript === + 0) { + sandbox.log(`More than ${sandbox.__engine.__subscriptionsLog} log subscriptions registered. Check your script!`, 'warn'); + } + return handler.id; + }, + onLogUnregister: function (idOrCallbackOrSeverity) { + let found = false; + if (context.logSubscriptions?.[sandbox.scriptName]) { + sandbox.verbose && + sandbox.log(`onLogUnregister(idOrCallbackOrSeverity=${JSON.stringify(idOrCallbackOrSeverity)}) - logSubscriptions=${sandbox.__engine.__subscriptionsLog}`, 'info'); + for (let i = 0; i < context.logSubscriptions[sandbox.scriptName].length; i++) { + if (context.logSubscriptions[sandbox.scriptName][i].cb === idOrCallbackOrSeverity || + context.logSubscriptions[sandbox.scriptName][i].id === idOrCallbackOrSeverity || + context.logSubscriptions[sandbox.scriptName][i].severity === idOrCallbackOrSeverity) { + sandbox.verbose && + sandbox.log(`onLogUnregister(idOrCallbackOrSeverity=${JSON.stringify(idOrCallbackOrSeverity)}, removing id=${context.logSubscriptions[sandbox.scriptName][i].id})`, 'info'); + context.logSubscriptions[sandbox.scriptName].splice(i, 1); + i--; + sandbox.__engine.__subscriptionsLog--; + found = true; + // if deletion via ID + if (typeof idOrCallbackOrSeverity === 'number') { + break; + } + } + else { + sandbox.verbose && + sandbox.log(`onLogUnregister(idOrCallbackOrSeverity=${JSON.stringify(idOrCallbackOrSeverity)}) NOT = ${JSON.stringify(context.logSubscriptions[sandbox.scriptName][i])}`, 'info'); + } + } + } + context.updateLogSubscriptions(); + return found; + }, + exec: function (cmd, options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + if (!adapter.config.enableExec) { + const error = 'exec is not available. Please enable "Enable Exec" option in instance settings'; + sandbox.log(error, 'error'); + if (typeof callback === 'function') { + setImmediate(callback, error, undefined, undefined); + } + } + else { + if (sandbox.verbose) { + sandbox.log(`exec(cmd=${cmd})`, 'info'); + } + if (debug) { + sandbox.log(words._('Command %s was not executed, while debug mode is active', cmd), 'warn'); + if (typeof callback === 'function') { + setImmediate(function () { + callback(null, '', ''); + }); + } + } + else { + return mods.child_process.exec(cmd, options, (error, stdout, stderr) => { + if (typeof callback === 'function') { + try { + callback.call(sandbox, error, stdout, stderr); + } + catch (err) { + errorInCallback(err); + } + } + }); + } + } + }, + email: function (msg) { + if (sandbox.verbose) { + sandbox.log(`email(msg=${JSON.stringify(msg)})`, 'info'); + } + sandbox.log(`email(msg=${JSON.stringify(msg)}) is deprecated. Please use sendTo instead!`, 'warn'); + adapter.sendTo('email', msg); + }, + pushover: function (msg) { + if (sandbox.verbose) { + sandbox.log(`pushover(msg=${JSON.stringify(msg)})`, 'info'); + } + sandbox.log(`pushover(msg=${JSON.stringify(msg)}) is deprecated. Please use sendTo instead!`, 'warn'); + adapter.sendTo('pushover', msg); + }, + httpGet: function (url, options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + const config = { + ...(0, tools_1.getHttpRequestConfig)(url, options), + method: 'get', + }; + if (sandbox.verbose) { + sandbox.log(`httpGet(config=${JSON.stringify(config)})`, 'info'); + } + const startTime = Date.now(); + mods.axios + .default(config) + .then((response) => { + const responseTime = Date.now() - startTime; + if (sandbox.verbose) { + sandbox.log(`httpGet(url=${url}, responseTime=${responseTime}ms)`, 'info'); + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, null, { + statusCode: response.status, + data: response.data, + headers: response.headers, + responseTime, + }); + } + catch (err) { + errorInCallback(err); + } + } + }) + .catch((error) => { + const responseTime = Date.now() - startTime; + sandbox.log(`httpGet(url=${url}, error=${error.message})`, 'error'); + if (typeof callback === 'function') { + let result = { + statusCode: null, + data: null, + headers: {}, + responseTime, + }; + if (error.response) { + result = { + statusCode: error.response.status, + data: error.response.data, + headers: error.response.headers, + responseTime, + }; + } + try { + callback.call(sandbox, error.message, result); + } + catch (err) { + errorInCallback(err); + } + } + }); + }, + httpPost: function (url, data, options, callback) { + if (typeof options === 'function') { + callback = options; + options = {}; + } + const config = { + ...(0, tools_1.getHttpRequestConfig)(url, options), + method: 'post', + data, + }; + if (sandbox.verbose) { + sandbox.log(`httpPost(config=${JSON.stringify(config)}, data=${data})`, 'info'); + } + const startTime = Date.now(); + mods.axios + .default(config) + .then((response) => { + const responseTime = Date.now() - startTime; + if (sandbox.verbose) { + sandbox.log(`httpPost(url=${url}, responseTime=${responseTime}ms)`, 'info'); + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, null, { + statusCode: response.status, + data: response.data, + headers: response.headers, + responseTime, + }); + } + catch (err) { + errorInCallback(err); + } + } + }) + .catch((error) => { + const responseTime = Date.now() - startTime; + sandbox.log(`httpPost(url=${url}, error=${error.message})`, 'error'); + if (typeof callback === 'function') { + let result = { + statusCode: null, + data: null, + headers: {}, + responseTime, + }; + const response = error.response; + if (response) { + result = { + statusCode: response.status, + data: response.data, + headers: response.headers, + responseTime, + }; + } + try { + callback.call(sandbox, new Error(error.message), result); + } + catch (err) { + errorInCallback(err); + } + } + }); + }, + createTempFile: function (fileName, data) { + const os = mods.os; + const path = mods.path; + const fs = mods.fs; + let tempDirPath = context.tempDirectories?.[sandbox.scriptName]; + if (!tempDirPath) { + // create temp directory + tempDirPath = fs.mkdtempSync(path.join(os.tmpdir(), `${sandbox.scriptName.substring('script.js.'.length)}-`)); + context.tempDirectories[sandbox.scriptName] = tempDirPath; + sandbox.verbose && + sandbox.log(`createTempFile(fileName=${fileName}, tempDirPath=${tempDirPath}) created temp directory in ${os.tmpdir()}`, 'info'); + } + const filePath = path.join(tempDirPath, fileName); + // is sub dir? + const fileDir = path.dirname(filePath); + if (!fs.existsSync(fileDir)) { + fs.mkdirSync(fileDir, { recursive: true }); + } + if (typeof data === 'undefined') { + sandbox.log(`createTempFile(fileName=${fileName}, fileDir=${fileDir}, filePath=${filePath}) data is undefined, file not created!`, 'error'); + return undefined; + } + fs.writeFileSync(filePath, data); + sandbox.verbose && + sandbox.log(`createTempFile(fileName=${fileName}, fileDir=${fileDir}, filePath=${filePath})`, 'info'); + return filePath; + }, + subscribe: function (pattern, + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + callbackOrChangeTypeOrId, value) { + // If a schedule object is given + if ((typeof pattern === 'string' && pattern[0] === '{') || + (typeof pattern === 'object' && pattern.period)) { + return sandbox.schedule(pattern, callbackOrChangeTypeOrId); + } + // If an array of schedules is given + if (pattern && Array.isArray(pattern)) { + const result = []; + for (const p of pattern) { + result.push(sandbox.subscribe(p, callbackOrChangeTypeOrId, value)); + } + return result; + } + // detect subscribe('id', 'any', (obj) => {}) + let oPattern; + if ((typeof pattern === 'string' || pattern instanceof RegExp) && + typeof callbackOrChangeTypeOrId === 'string' && + typeof value === 'function') { + oPattern = { id: pattern, change: callbackOrChangeTypeOrId }; + callbackOrChangeTypeOrId = value; + value = undefined; + } + else { + oPattern = pattern; + } + if (oPattern?.id && Array.isArray(oPattern.id)) { + const result = []; + for (let t = 0; t < oPattern.id.length; t++) { + const pa = JSON.parse(JSON.stringify(oPattern)); + pa.id = oPattern.id[t]; + result.push(sandbox.subscribe(pa, callbackOrChangeTypeOrId, value)); + } + return result; + } + // try to detect astro or cron (by spaces) + if ((0, tools_1.isObject)(pattern) || (typeof pattern === 'string' && pattern.match(/[,/\d*]+\s[,/\d*]+\s[,/\d*]+/))) { + if (pattern.astro) { + return sandbox.schedule(pattern, callbackOrChangeTypeOrId); + } + else if (pattern.time) { + return sandbox.schedule(pattern.time, callbackOrChangeTypeOrId); + } + } + let callback; + // source is set by regexp if defined as /regexp/ + if (!(0, tools_1.isObject)(pattern) || pattern instanceof RegExp || pattern.source) { + oPattern = { id: pattern, change: 'ne' }; + } + if (oPattern.id !== undefined && !oPattern.id) { + sandbox.log(`Error by subscription (trigger): empty ID defined. All states matched.`, 'error'); + return; + } + else if (typeof oPattern.id === 'boolean' || typeof oPattern.id === 'number') { + sandbox.log(`Error by subscription (trigger): Wrong ID of type boolean or number.`, 'error'); + return; + } + sandbox.__engine.__subscriptions += 1; + if (sandbox.__engine.__subscriptions % adapter.config.maxTriggersPerScript === + 0) { + sandbox.log(`More than ${sandbox.__engine.__subscriptions} subscriptions registered. Check your script!`, 'warn'); + } + if (oPattern.q === undefined) { + oPattern.q = 0; + } + // add adapter namespace if nothing given + if (oPattern.id && typeof oPattern.id === 'string' && !oPattern.id.includes('.')) { + oPattern.id = `${adapter.namespace}.${oPattern.id}`; + } + if (typeof callbackOrChangeTypeOrId === 'function') { + callback = callbackOrChangeTypeOrId; + } + else { + if (typeof value === 'undefined') { + callback = function (obj) { + sandbox.setState(callbackOrChangeTypeOrId, obj.newState.val); + }; + } + else { + callback = function ( /* obj */) { + sandbox.setState(callbackOrChangeTypeOrId, value); + }; + } + } + const subs = { + pattern: oPattern, + callback: (obj) => { + if (typeof callback === 'function') { + try { + callback.call(sandbox, obj); + } + catch (err) { + errorInCallback(err); + } + } + }, + name, + }; + // try to extract adapter + if (oPattern.id && typeof oPattern.id === 'string') { + const parts = oPattern.id.split('.'); + const a = `${parts[0]}.${parts[1]}`; + const _adapter = `system.adapter.${a}`; + if (objects[_adapter] && objects[_adapter].common && objects[_adapter].common.subscribable) { + const alive = `system.adapter.${a}.alive`; + context.adapterSubs[alive] = context.adapterSubs[alive] || []; + const subExists = context.adapterSubs[alive].filter(sub => sub === oPattern.id).length > 0; + if (!subExists) { + context.adapterSubs[alive].push(oPattern.id); + adapter.sendTo(a, 'subscribe', oPattern.id); + } + } + } + if (sandbox.verbose) { + sandbox.log(`subscribe: ${JSON.stringify(subs)}`, 'info'); + } + subscribePattern(script, oPattern.id); + subs.patternCompareFunctions = getPatternCompareFunctions(oPattern); + context.subscriptions.push(subs); + if (oPattern.enumName || oPattern.enumId) { + context.isEnums = true; + } + return subs; + }, + getSubscriptions: function () { + const result = {}; + for (let s = 0; s < context.subscriptions.length; s++) { + result[context.subscriptions[s].pattern.id] = + result[context.subscriptions[s].pattern.id] || []; + result[context.subscriptions[s].pattern.id].push({ + name: context.subscriptions[s].name, + pattern: context.subscriptions[s].pattern, + }); + } + if (sandbox.verbose) { + sandbox.log(`getSubscriptions() => ${JSON.stringify(result)}`, 'info'); + } + return result; + }, + getFileSubscriptions: function () { + const result = {}; + for (let s = 0; s < context.subscriptionsFile.length; s++) { + const key = `${context.subscriptionsFile[s].id}$%$${context.subscriptionsFile[s].fileNamePattern}`; + result[key] = result[key] || []; + result[key].push({ + name: context.subscriptionsFile[s].name, + id: context.subscriptionsFile[s].id, + fileNamePattern: context.subscriptionsFile[s].fileNamePattern, + }); + } + if (sandbox.verbose) { + sandbox.log(`getFileSubscriptions() => ${JSON.stringify(result)}`, 'info'); + } + return result; + }, + adapterSubscribe: function (id) { + if (typeof id !== 'string') { + sandbox.log(`adapterSubscribe: invalid type of id ${typeof id}`, 'error'); + return; + } + const parts = id.split('.'); + const _adapter = `system.adapter.${parts[0]}.${parts[1]}`; + if (objects[_adapter]?.common?.subscribable) { + const a = `${parts[0]}.${parts[1]}`; + const alive = `system.adapter.${a}.alive`; + context.adapterSubs[alive] = context.adapterSubs[alive] || []; + context.adapterSubs[alive].push(id); + if (sandbox.verbose) { + sandbox.log(`adapterSubscribe: ${a} - ${id}`, 'info'); + } + adapter.sendTo(a, 'subscribe', id); + } + }, + adapterUnsubscribe: function (idOrObject) { + // todo: BF - it could be an error + return sandbox.unsubscribe(idOrObject); + }, + unsubscribe: function (idOrObject) { + if (idOrObject && Array.isArray(idOrObject)) { + const result = []; + for (let t = 0; t < idOrObject.length; t++) { + result.push(sandbox.unsubscribe(idOrObject[t])); + } + return result; + } + if (sandbox.verbose) { + sandbox.log(`adapterUnsubscribe(id=${JSON.stringify(idOrObject)})`, 'info'); + } + if ((0, tools_1.isObject)(idOrObject)) { + for (let i = context.subscriptions.length - 1; i >= 0; i--) { + if (context.subscriptions[i] === idOrObject) { + unsubscribePattern(script, context.subscriptions[i].pattern.id); + context.subscriptions.splice(i, 1); + sandbox.__engine.__subscriptions--; + return true; + } + } + return false; + } + let deleted = 0; + for (let i = context.subscriptions.length - 1; i >= 0; i--) { + if (context.subscriptions[i].name === name && context.subscriptions[i].pattern.id === idOrObject) { + deleted++; + unsubscribePattern(script, context.subscriptions[i].pattern.id); + context.subscriptions.splice(i, 1); + sandbox.__engine.__subscriptions--; + } + } + return !!deleted; + }, + on: function (pattern, + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + callbackOrChangeTypeOrId, value) { + return sandbox.subscribe(pattern, callbackOrChangeTypeOrId, value); + }, + onEnumMembers: function (enumId, callback) { + if (enums.includes(enumId)) { + const subscriptions = {}; + const init = () => { + const obj = objects[enumId]; + const common = obj?.common ?? {}; + const members = common?.members ?? []; + // Remove old subscriptions + for (const [objId, subscription] of Object.entries(subscriptions)) { + if (!members.includes(objId)) { + sandbox.unsubscribe(subscription); + delete subscriptions[objId]; + } + } + // Subscribe to all members of enum + for (const objId of members) { + if (!Object.keys(subscriptions).includes(objId)) { + if (objects?.[objId]?.type === 'state') { + // Just subscribe to states + subscriptions[objId] = sandbox.subscribe(objId, callback); // TODO: more features + } + } + } + sandbox.verbose && + sandbox.log(`onEnumMembers(id=${enumId}, members=${JSON.stringify(Object.keys(subscriptions))})`, 'info'); + }; + init(); + sandbox.subscribeObject(enumId, obj => obj && init()); + } + else { + sandbox.log(`onEnumMembers: enum with id "${enumId}" doesn't exists`, 'error'); + } + }, + onFile: function (id, fileNamePattern, withFileOrCallback, callback) { + if (typeof withFileOrCallback === 'function') { + callback = withFileOrCallback; + withFileOrCallback = false; + } + if (!adapter.subscribeForeignFiles) { + sandbox.log('onFile: your js-controller does not support yet onFile subscribes. Please update to js-controller@4.1.x or newer', 'warn'); + return; + } + if (!id || !fileNamePattern) { + sandbox.log('onFile: invalid parameters. Usage: onFile("vis.0", "main/*", true, (id, fileName, size, file, mimeType) => {});', 'error'); + return; + } + if (typeof callback !== 'function') { + sandbox.offFile(id, fileNamePattern); + return; + } + if (Array.isArray(fileNamePattern)) { + return fileNamePattern.map(filePattern => sandbox.onFile(id, filePattern, withFileOrCallback, callback)); + } + sandbox.__engine.__subscriptionsFile += 1; + sandbox.verbose && + sandbox.log(`onFile(id=${id}, fileNamePattern=${fileNamePattern}) - fileSubscriptions=${sandbox.__engine.__subscriptionsFile}`, 'info'); + if (sandbox.__engine.__subscriptionsFile % + adapter.config.maxTriggersPerScript === + 0) { + sandbox.log(`More than ${sandbox.__engine.__subscriptionsFile} file subscriptions registered. Check your script!`, 'warn'); + } + let idRegEx; + let fileRegEx; + if (id.includes('*')) { + idRegEx = new RegExp(pattern2RegEx(id)); + } + if (fileNamePattern.includes('*')) { + fileRegEx = new RegExp(pattern2RegEx(fileNamePattern)); + } + const subs = { + id, + fileNamePattern, + withFile: withFileOrCallback, + idRegEx, + fileRegEx, + callback: (id, fileName, size, withFile) => { + try { + sandbox.verbose && + sandbox.log(`onFile changed(id=${id}, fileName=${fileName}, size=${size})`, 'info'); + if (withFile && (size || 0) > 0) { + adapter + .readFileAsync(id, fileName) + .then(data => { + try { + callback.call(sandbox, id, fileName, size, data.file, data.mimeType); + } + catch (err) { + errorInCallback(err); + } + }) + .catch(error => errorInCallback(error)); + } + else { + callback.call(sandbox, id, fileName, size); + } + } + catch (err) { + errorInCallback(err); + } + }, + name, + }; + context.subscriptionsFile.push(subs); + subscribeFile(script, id, fileNamePattern); + return subs; + }, + offFile: function (idOrObject, fileNamePattern) { + if (!adapter.unsubscribeForeignFiles) { + sandbox.log('offFile: your js-controller does not support yet file unsubscribes. Please update to js-controller@4.1.x or newer', 'warn'); + return false; + } + sandbox.verbose && + sandbox.log(`offFile(idOrObject=${JSON.stringify(idOrObject)}, fileNamePattern=${JSON.stringify(fileNamePattern)}) - fileSubscriptions=${sandbox.__engine.__subscriptionsFile}`, 'info'); + if (idOrObject && typeof idOrObject === 'object') { + if (Array.isArray(idOrObject)) { + const result = []; + for (let t = 0; t < idOrObject.length; t++) { + result.push(sandbox.offFile(idOrObject[t])); + } + return result; + } + for (let i = context.subscriptionsFile.length - 1; i >= 0; i--) { + if (context.subscriptionsFile[i] === idOrObject) { + unsubscribeFile(script, context.subscriptionsFile[i].id, context.subscriptionsFile[i].fileNamePattern); + sandbox.verbose && + sandbox.log(`offFile(type=object, fileNamePattern=${JSON.stringify(fileNamePattern)}, removing id=${context.subscriptionsFile[i].id})`, 'info'); + context.subscriptionsFile.splice(i, 1); + sandbox.__engine.__subscriptionsFile--; + return true; + } + } + return false; + } + if (fileNamePattern && Array.isArray(fileNamePattern)) { + const result = []; + for (let t = 0; t < fileNamePattern.length; t++) { + result.push(sandbox.offFile(idOrObject, fileNamePattern[t])); + } + return result; + } + let deleted = 0; + for (let i = context.subscriptionsFile.length - 1; i >= 0; i--) { + if (context.subscriptionsFile[i].id === idOrObject && + context.subscriptionsFile[i].fileNamePattern === fileNamePattern) { + deleted++; + unsubscribeFile(script, context.subscriptionsFile[i].id, context.subscriptionsFile[i].fileNamePattern); + sandbox.verbose && + sandbox.log(`offFile(type=string, fileNamePattern=${fileNamePattern}, removing id=${context.subscriptionsFile[i].id})`, 'info'); + context.subscriptionsFile.splice(i, 1); + sandbox.__engine.__subscriptionsFile--; + } + } + return !!deleted; + }, + /** Registers a one-time subscription which automatically unsubscribes after the first invocation */ + once: function (pattern, callback) { + function _once(cb) { + // eslint-disable-next-line prefer-const + let subscription; + const handler = (obj) => { + subscription && sandbox.unsubscribe(subscription); + typeof cb === 'function' && cb(obj); + }; + subscription = sandbox.subscribe(pattern, handler); + return subscription; + } + if (typeof callback === 'function') { + // Callback-style: once("id", (obj) => { ... }) + return _once(callback); + } + // Promise-style: once("id").then(obj => { ... }) + return new Promise(resolve => _once(resolve)); + }, + schedule: function (pattern, callback) { + if (typeof callback !== 'function') { + sandbox.log(`schedule callback missing`, 'error'); + return null; + } + if ((typeof pattern === 'string' && pattern[0] === '{') || + (typeof pattern === 'object' && pattern.period)) { + sandbox.verbose && + sandbox.log(`schedule(wizard=${typeof pattern === 'object' ? JSON.stringify(pattern) : pattern})`, 'info'); + if (!context.scheduler) { + sandbox.log(`Cannot schedule "${typeof pattern === 'object' ? JSON.stringify(pattern) : pattern}" because scheduler is not available`, 'error'); + return null; + } + const schedule = context.scheduler.add(pattern, sandbox.scriptName, callback); + if (schedule) { + script.wizards.push(schedule); + sandbox.__engine.__schedules += 1; + if (sandbox.__engine.__schedules % + adapter.config.maxTriggersPerScript === + 0) { + sandbox.log(`More than ${sandbox.__engine.__schedules} schedules registered. Check your script!`, 'warn'); + } + } + return schedule; + } + const adapterConfig = adapter.config; + if (typeof pattern === 'object' && pattern.astro) { + const astroPattern = pattern; + const nowDate = new Date(); + if (adapterConfig.latitude === undefined || + adapterConfig.longitude === undefined || + adapterConfig.latitude === null || + adapterConfig.longitude === null) { + sandbox.log('Longitude or latitude does not set. Cannot use astro.', 'error'); + return null; + } + // ensure events are calculated independent of current time + // TODO: use getAstroStartOfDay of adapter? + const todayNoon = new Date(nowDate); + todayNoon.setHours(12, 0, 0, 0); + let ts = mods.suncalc.getTimes(todayNoon, adapterConfig.latitude, adapterConfig.longitude)[astroPattern.astro]; + // event on the next day, correct or force recalculation at midnight + if (todayNoon.getDate() !== ts.getDate()) { + todayNoon.setDate(todayNoon.getDate() - 1); + ts = mods.suncalc.getTimes(todayNoon, adapterConfig.latitude, adapterConfig.longitude)[astroPattern.astro]; + } + if (ts.getTime().toString() === 'NaN') { + sandbox.log(`Cannot calculate "${astroPattern.astro}" for ${adapterConfig.latitude}, ${adapterConfig.longitude}`, 'warn'); + ts = new Date(nowDate.getTime()); + if (astroPattern.astro === 'sunriseEnd' || + astroPattern.astro === 'goldenHourEnd' || + astroPattern.astro === 'sunset' || + astroPattern.astro === 'nightEnd' || + astroPattern.astro === 'nauticalDusk') { + ts.setHours(23); + ts.setMinutes(59); + ts.setSeconds(59); + } + else { + ts.setHours(23); + ts.setMinutes(59); + ts.setSeconds(58); + } + } + if (ts && astroPattern.shift) { + ts = new Date(ts.getTime() + astroPattern.shift * 60000); + } + if (!ts || ts < nowDate) { + const date = new Date(nowDate); + // Event doesn't occur today - try again tomorrow + // Calculate time till 24:00 (local, NOT UTC) and set timeout + date.setDate(date.getDate() + 1); + date.setMinutes(0); // Sometimes timer fires at 23:59:59 + date.setHours(0); + date.setSeconds(1); + date.setMilliseconds(0); + sandbox.__engine.__schedules += 1; + if (sandbox.__engine.__schedules % adapterConfig.maxTriggersPerScript === 0) { + sandbox.log(`More than ${sandbox.__engine.__schedules} schedules registered. Check your script!`, 'warn'); + } + sandbox.verbose && + sandbox.log(`schedule(astro=${astroPattern.astro}, offset=${astroPattern.shift}) is tomorrow, waiting until ${date.toISOString()}`, 'info'); + // Calculate new schedule in the next day + sandbox.setTimeout(() => { + if (sandbox.__engine.__schedules > 0) { + sandbox.__engine.__schedules--; + } + sandbox.schedule(astroPattern, callback); + }, date.getTime() - Date.now()); + return; + } + sandbox.__engine.__schedules += 1; + if (sandbox.__engine.__schedules % adapterConfig.maxTriggersPerScript === 0) { + sandbox.log(`More than ${sandbox.__engine.__schedules} schedules registered. Check your script!`, 'warn'); + } + sandbox.setTimeout(() => { + try { + callback.call(sandbox); + } + catch (err) { + errorInCallback(err); + } + // Reschedule in 2 seconds + sandbox.setTimeout(() => { + if (sandbox.__engine.__schedules > 0) { + sandbox.__engine.__schedules--; + } + sandbox.schedule(astroPattern, callback); + }, 2000); + }, ts.getTime() - Date.now()); + sandbox.verbose && + sandbox.log(`schedule(astro=${astroPattern.astro}, offset=${astroPattern.shift}) is today, waiting until ${ts.toISOString()}`, 'info'); + } + else { + // fix a problem with sunday and 7 + if (typeof pattern === 'string') { + // this could be a CRON + const parts = pattern.replace(/\s+/g, ' ').split(' '); + if (parts.length >= 5 && parseInt(parts[5], 10) >= 7) { + parts[5] = '0'; + } + pattern = parts.join(' '); + } + // created in VM the date object: pattern instanceof Date => false + // so fix it + if (typeof pattern === 'object' && pattern.getDate) { + pattern = new Date(pattern); + } + const schedule = mods.nodeSchedule.scheduleJob(pattern, () => { + try { + callback.call(sandbox); + } + catch (err) { + errorInCallback(err); + } + }); + if (schedule) { + sandbox.__engine.__schedules += 1; + if (sandbox.__engine.__schedules % + adapter.config.maxTriggersPerScript === + 0) { + sandbox.log(`More than ${sandbox.__engine.__schedules} schedules registered. Check your script!`, 'warn'); + } + schedule._ioBroker = { + type: 'cron', + pattern: pattern, + scriptName: sandbox.scriptName, + id: `cron_${Date.now()}_${Math.round(Math.random() * 100000)}`, + }; + script.schedules.push(schedule); + } + else { + sandbox.log(`schedule(cron=${JSON.stringify(pattern)}): cannot create schedule`, 'error'); + } + if (sandbox.verbose) { + sandbox.log(`schedule(cron=${JSON.stringify(pattern)})`, 'info'); + } + return schedule; + } + }, + scheduleById: function (id, ack, callback) { + let scheduleId = null; + let currentExp = null; // current cron expression + if (typeof ack === 'function') { + callback = ack; + ack = undefined; + } + const rhms = /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$/; // hh:mm:ss + const rhm = /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/; // hh:mm + const init = (time) => { + if (typeof time === 'string') { + let h = undefined; + let m = undefined; + let s = undefined; + let isValid = false; + let result = time.match(rhms); + if (result) { + [, h, m, s] = result.map(v => parseInt(v)); + isValid = true; + } + else { + result = time.match(rhm); + if (result) { + [, h, m] = result.map(v => parseInt(v)); + isValid = true; + } + } + if (isValid) { + const cronExp = `${s ?? '0'} ${m ?? '0'} ${h ?? '0'} * * *`; + if (cronExp !== currentExp) { + sandbox.verbose && + sandbox.log(`scheduleById(id=${id}): Init with expression ${cronExp} from ${time}`, 'info'); + currentExp = cronExp; + if (scheduleId) { + sandbox.clearSchedule(scheduleId); + scheduleId = null; + } + scheduleId = sandbox.schedule(cronExp, () => { + if (typeof callback === 'function') { + try { + callback.call(sandbox); + } + catch (err) { + errorInCallback(err); + } + } + }); + } + } + else { + sandbox.log(`scheduleById(id=${id},time=${time}): cannot create schedule - invalid format (HH:MM:SS or H:M:S required)`, 'error'); + } + } + else { + sandbox.log(`scheduleById(id=${id}): cannot create schedule - invalid var type (no string)`, 'error'); + } + }; + sandbox.getState(id, (err, state) => { + if (!err && state?.val) { + if (sandbox.verbose) { + sandbox.log(`scheduleById(id=${id}): Init with value ${state.val}`, 'info'); + } + init(state.val.toString()); + } + }); + const triggerDef = { id, change: 'any' }; + if (ack !== undefined) { + triggerDef.ack = ack; + } + sandbox.on(triggerDef, obj => { + if (obj?.state?.val) { + sandbox.verbose && + sandbox.log(`scheduleById(id=${id}): Update with value ${obj.state.val}`, 'info'); + init(obj.state.val.toString()); + } + }); + }, + getAstroDate: function (pattern, date, offsetMinutes) { + if (date === undefined) { + date = new Date(); + } + if (typeof date === 'number') { + date = new Date(date); + } + else { + date = new Date(date.getTime()); + } + if (!consts.astroList.includes(pattern)) { + const pos = consts.astroListLow.indexOf(pattern.toLowerCase()); + if (pos !== -1) { + pattern = consts.astroList[pos]; + } + } + if ((!adapter.config.latitude && + adapter.config.latitude !== 0) || + (!adapter.config.longitude && + adapter.config.longitude !== 0)) { + sandbox.log('Longitude or latitude does not set. Cannot use astro.', 'error'); + return; + } + // ensure events are calculated independent of current time + date.setHours(12, 0, 0, 0); + let ts = mods.suncalc.getTimes(date, adapter.config.latitude, adapter.config.longitude)[pattern]; + if (ts === undefined || ts.getTime().toString() === 'NaN') { + sandbox.log(`Cannot calculate astro date "${pattern}" for ${adapter.config.latitude}, ${adapter.config.longitude}`, 'warn'); + } + if (sandbox.verbose) { + sandbox.log(`getAstroDate(pattern=${pattern}, date=${date.toString()}) => ${ts}`, 'info'); + } + if (offsetMinutes !== undefined) { + ts = new Date(ts.getTime() + offsetMinutes * 60000); + } + return ts; + }, + isAstroDay: function () { + const nowDate = new Date(); + const dayBegin = sandbox.getAstroDate('sunrise'); + const dayEnd = sandbox.getAstroDate('sunset'); + if (dayBegin === undefined || dayEnd === undefined) { + return; + } + if (sandbox.verbose) { + sandbox.log(`isAstroDay() => ${nowDate >= dayBegin && nowDate <= dayEnd}`, 'info'); + } + return nowDate >= dayBegin && nowDate <= dayEnd; + }, + clearSchedule: function (schedule) { + if (context.scheduler?.get(schedule)) { + if (sandbox.verbose) { + sandbox.log('clearSchedule() => wizard cleared', 'info'); + } + const pos = script.wizards.indexOf(schedule); + if (pos !== -1) { + script.wizards.splice(pos, 1); + if (sandbox.__engine.__schedules > 0) { + sandbox.__engine.__schedules--; + } + } + context.scheduler.remove(schedule); + return true; + } + for (let i = 0; i < script.schedules.length; i++) { + if (schedule && typeof schedule === 'object' && schedule._ioBroker?.type === 'cron') { + if (script.schedules[i]._ioBroker.id === schedule._ioBroker.id) { + if (!mods.nodeSchedule.cancelJob(script.schedules[i])) { + sandbox.log('Error by canceling scheduled job', 'error'); + } + script.schedules.splice(i, 1); + if (sandbox.__engine.__schedules > 0) { + sandbox.__engine.__schedules--; + } + if (sandbox.verbose) { + sandbox.log('clearSchedule() => cleared', 'info'); + } + return true; + } + } + else if (script.schedules[i] === schedule) { + if (!mods.nodeSchedule.cancelJob(script.schedules[i])) { + sandbox.log('Error by canceling scheduled job', 'error'); + } + script.schedules.splice(i, 1); + if (sandbox.__engine.__schedules > 0) { + sandbox.__engine.__schedules--; + } + if (sandbox.verbose) { + sandbox.log('clearSchedule() => cleared', 'info'); + } + return true; + } + } + if (sandbox.verbose) { + sandbox.log('clearSchedule() => invalid handler', 'warn'); + } + return false; + }, + getSchedules: function (allScripts) { + const schedules = context.scheduler?.getList() || []; + if (allScripts) { + Object.keys(context.scripts).forEach(name => context.scripts[name].schedules && + context.scripts[name].schedules.forEach(s => schedules.push(JSON.parse(JSON.stringify(s._ioBroker))))); + } + else { + script.schedules && + script.schedules.forEach(s => schedules.push(JSON.parse(JSON.stringify(s._ioBroker)))); + } + return schedules; + }, + setState: function (id, state, isAck, callback) { + return setStateHelper(sandbox, false, false, id, state, isAck, callback); + }, + setStateChanged: function (id, state, isAck, callback) { + return setStateHelper(sandbox, false, true, id, state, isAck, callback); + }, + setStateDelayed: function (id, state, isAck, delay, clearRunning, callback) { + // find arguments + if (typeof isAck !== 'boolean') { + callback = clearRunning; + clearRunning = delay; + delay = isAck; + isAck = undefined; + } + if (typeof delay !== 'number') { + callback = clearRunning; + clearRunning = delay; + delay = 0; + } + if (typeof clearRunning !== 'boolean') { + callback = clearRunning; + clearRunning = true; + } + // Check a type of state + if (!objects[id] && objects[`${adapter.namespace}.${id}`]) { + id = `${adapter.namespace}.${id}`; + } + sandbox.verbose && + sandbox.log(`setStateDelayed(id=${id}, state=${JSON.stringify(state)}, isAck=${isAck}, delay=${delay}, clearRunning=${clearRunning})`, 'info'); + if (clearRunning) { + if (timers[id]) { + sandbox.verbose && + sandbox.log(`setStateDelayed: clear ${timers[id].length} running timers`, 'info'); + for (let i = 0; i < timers[id].length; i++) { + clearTimeout(timers[id][i].t); + } + delete timers[id]; + } + else { + if (sandbox.verbose) { + sandbox.log('setStateDelayed: no running timers', 'info'); + } + } + } + // If no delay => starts immediately + if (!delay) { + sandbox.setState(id, state, isAck, callback); + return null; + } + // If delay + timers[id] = timers[id] || []; + // calculate timerId + context.timerId++; + if (context.timerId > 0xfffffffe) { + context.timerId = 0; + } + // Start timeout + const timer = setTimeout(function (_timerId, _id, _state, _isAck) { + sandbox.setState(_id, _state, _isAck, callback); + // delete timer handler + if (timers[_id]) { + // optimisation + if (timers[_id].length === 1) { + delete timers[_id]; + } + else { + for (let t = 0; t < timers[_id].length; t++) { + if (timers[_id][t].id === _timerId) { + timers[_id].splice(t, 1); + break; + } + } + if (!timers[_id].length) { + delete timers[_id]; + } + } + } + }, delay, context.timerId, id, state, isAck); + // add timer handler + timers[id].push({ + t: timer, + id: context.timerId, + ts: Date.now(), + delay: delay, + val: (0, tools_1.isObject)(state) && state.val !== undefined + ? state.val + : state, + ack: (0, tools_1.isObject)(state) && + state.val !== undefined && + state.ack !== undefined + ? state.ack + : isAck, + }); + return context.timerId; + }, + clearStateDelayed: function (id, timerId) { + // Check a type of state + if (!objects[id] && objects[`${adapter.namespace}.${id}`]) { + id = `${adapter.namespace}.${id}`; + } + if (sandbox.verbose) { + sandbox.log(`clearStateDelayed(id=${id}, timerId=${timerId})`, 'info'); + } + if (timers[id]) { + for (let i = timers[id].length - 1; i >= 0; i--) { + if (timerId === undefined || timers[id][i].id === timerId) { + clearTimeout(timers[id][i].t); + if (timerId !== undefined) { + timers[id].splice(i, 1); + } + if (sandbox.verbose) { + sandbox.log(`clearStateDelayed: clear timer ${timers[id][i].id}`, 'info'); + } + } + } + if (timerId === undefined) { + delete timers[id]; + } + else { + if (!timers[id].length) { + delete timers[id]; + } + } + return true; + } + return false; + }, + getStateDelayed: function (id) { + const now = Date.now(); + if (id) { + // Check a type of state + if (!objects[id] && objects[`${adapter.namespace}.${id}`]) { + id = `${adapter.namespace}.${id}`; + } + // If timerId given + if (typeof id === 'number') { + for (const _id_ in timers) { + if (Object.prototype.hasOwnProperty.call(timers, _id_)) { + for (let ttt = 0; ttt < timers[_id_].length; ttt++) { + if (timers[_id_][ttt].id === id) { + return { + timerId: id, + left: timers[_id_][ttt].delay - (now - timers[id][ttt].ts), + delay: timers[_id_][ttt].delay, + val: timers[_id_][ttt].val, + ack: timers[_id_][ttt].ack, + }; + } + } + } + } + return null; + } + const result = []; + if (Object.prototype.hasOwnProperty.call(timers, id) && timers[id] && timers[id].length) { + for (let tt = 0; tt < timers[id].length; tt++) { + result.push({ + timerId: timers[id][tt].id, + left: timers[id][tt].delay - (now - timers[id][tt].ts), + delay: timers[id][tt].delay, + val: timers[id][tt].val, + ack: timers[id][tt].ack, + }); + } + } + return result; + } + const result = {}; + for (const _id in timers) { + if (Object.prototype.hasOwnProperty.call(timers, _id) && timers[_id] && timers[_id].length) { + result[_id] = []; + for (let t = 0; t < timers[_id].length; t++) { + result[_id].push({ + timerId: timers[_id][t].id, + left: timers[_id][t].delay - (now - timers[_id][t].ts), + delay: timers[_id][t].delay, + val: timers[_id][t].val, + ack: timers[_id][t].ack, + }); + } + } + } + return result; + }, + getStateAsync: async function (id) { + let state; + if (id.includes('.')) { + state = await adapter.getForeignStateAsync(id); + } + else { + state = await adapter.getStateAsync(id); + } + return context.convertBackStringifiedValues(id, state); + }, + setStateAsync: function (id, state, isAck) { + return new Promise((resolve, reject) => setStateHelper(sandbox, false, false, id, state, isAck, err => (err ? reject(err) : resolve()))); + }, + setStateChangedAsync: function (id, state, isAck) { + return new Promise((resolve, reject) => setStateHelper(sandbox, false, true, id, state, isAck, err => (err ? reject(err) : resolve()))); + }, + getState: function (id, callback) { + if (typeof id !== 'string') { + sandbox.log(`getState has been called with id of type "${typeof id}" but expects a string`, 'error'); + return undefined; + } + if (typeof callback === 'function') { + if (!id.includes('.')) { + adapter.getState(id, (err, state) => callback(err, context.convertBackStringifiedValues(id, state))); + } + else { + adapter.getForeignState(id, (err, state) => callback(err, context.convertBackStringifiedValues(id, state))); + } + } + else { + if (adapter.config.subscribe) { + sandbox.log('The "getState" method cannot be used synchronously, because the adapter setting "Do not subscribe to all states on start" is enabled.', 'error'); + sandbox.log(`Please disable that setting or use "getState" with a callback, e.g.: getState('${id}', (err, state) => { ... });`, 'error'); + } + else { + if (states[id]) { + sandbox.verbose && + sandbox.log(`getState(id=${id}, timerId=${JSON.stringify(timers[id])}) => ${JSON.stringify(states[id])}`, 'info'); + if (context.interimStateValues[id] !== undefined) { + return context.convertBackStringifiedValues(id, context.interimStateValues[id]); + } + return context.convertBackStringifiedValues(id, states[id]); + } + else if (states[`${adapter.namespace}.${id}`]) { + sandbox.verbose && + sandbox.log(`getState(id=${id}, timerId=${JSON.stringify(timers[id])}) => ${JSON.stringify(states[`${adapter.namespace}.${id}`])}`, 'info'); + if (context.interimStateValues[`${adapter.namespace}.${id}`] !== undefined) { + return context.convertBackStringifiedValues(id, context.interimStateValues[`${adapter.namespace}.${id}`]); + } + return context.convertBackStringifiedValues(id, states[`${adapter.namespace}.${id}`]); + } + if (sandbox.verbose) { + sandbox.log(`getState(id=${id}, timerId=${JSON.stringify(timers[id])}) => not found`, 'info'); + } + context.logWithLineInfo(`getState "${id}" not found (3)${states[id] !== undefined ? ` states[id]=${JSON.stringify(states[id])}` : ''}`); ///xxx + return { val: null, notExist: true }; + } + } + }, + existsState: function (id, callback) { + if (typeof id !== 'string') { + sandbox.log(`existsState has been called with id of type "${typeof id}" but expects a string`, 'error'); + return false; + } + if (typeof callback === 'function') { + adapter.getForeignObject(id, (err, obj) => { + if (!obj || obj.type !== 'state') { + callback(err, false); + return; + } + if (adapter.config.subscribe) { + adapter.getForeignState(id, (err, state) => { + callback(err, !!state); + }); + } + else { + callback(err, !!states[id]); + } + }); + } + else { + if (adapter.config.subscribe) { + sandbox.log('The "existsState" method cannot be used synchronously, because the adapter setting "Do not subscribe to all states on start" is enabled.', 'error'); + sandbox.log(`Please disable that setting or use "existsState" with a callback, e.g.: existsState('${id}', (err, stateExists) => { ... });`, 'error'); + } + else { + return !!states[id]; + } + } + }, + existsObject: function (id, callback) { + if (typeof id !== 'string') { + sandbox.log(`existsObject has been called with id of type "${typeof id}" but expects a string`, 'error'); + return false; + } + if (typeof callback === 'function') { + adapter.getForeignObject(id, (err, obj) => callback(err, !!obj)); + } + else { + return !!objects[id]; + } + }, + getIdByName: function (name, alwaysArray) { + sandbox.verbose && + sandbox.log(`getIdByName(name=${name}, alwaysArray=${alwaysArray}) => ${JSON.stringify(context.names[name])}`, 'info'); + if (Object.prototype.hasOwnProperty.call(context.names, name)) { + if (alwaysArray) { + return !Array.isArray(context.names[name]) ? [context.names[name]] : context.names[name]; + } + return context.names[name]; + } + if (alwaysArray) { + return []; + } + return null; + }, + getObject: function (id, enumName, cb) { + if (typeof id !== 'string') { + sandbox.log(`getObject has been called with id of type "${typeof id}" but expects a string`, 'error'); + return null; + } + if (typeof enumName === 'function') { + cb = enumName; + enumName = null; + } + // with callback + if (typeof cb === 'function') { + adapter.getForeignObject(id, (err, obj) => { + if (obj) { + objects[id] = obj; + } + else if (objects[id]) { + delete objects[id]; + } + let result; + try { + result = JSON.parse(JSON.stringify(objects[id])); + } + catch (err) { + adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, { + val: true, + ack: true, + c: 'getObject', + }); + sandbox.log(`Object "${id}" can't be copied: ${JSON.stringify(err)}`, 'error'); + return cb(null, null); + } + sandbox.verbose && + sandbox.log(`getObject(id=${id}, enumName=${enumName}) => ${JSON.stringify(result)}`, 'info'); + cb(err, result); + }); + } + else { + if (!objects[id]) { + sandbox.verbose && + sandbox.log(`getObject(id=${id}, enumName=${enumName}) => does not exist`, 'info'); + sandbox.log(`Object "${id}" does not exist`, 'warn'); + return null; + } + if (enumName) { + const e = eventObj.getObjectEnumsSync(context, id); + const obj = JSON.parse(JSON.stringify(objects[id])); + obj.enumIds = JSON.parse(JSON.stringify(e.enumIds)); + obj.enumNames = JSON.parse(JSON.stringify(e.enumNames)); + if (typeof enumName === 'string') { + const r = new RegExp(`^enum\\.${enumName}\\.`); + for (let i = obj.enumIds.length - 1; i >= 0; i--) { + if (!r.test(obj.enumIds[i])) { + obj.enumIds.splice(i, 1); + obj.enumNames.splice(i, 1); + } + } + } + sandbox.verbose && + sandbox.log(`getObject(id=${id}, enumName=${enumName}) => ${JSON.stringify(obj)}`, 'info'); + return obj; + } + let result; + try { + result = JSON.parse(JSON.stringify(objects[id])); + } + catch (err) { + adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, { + val: true, + ack: true, + c: 'getObject', + }); + sandbox.log(`Object "${id}" can't be copied: ${JSON.stringify(err)}`, 'error'); + return null; + } + sandbox.verbose && + sandbox.log(`getObject(id=${id}, enumName=${enumName}) => ${JSON.stringify(result)}`, 'info'); + return result; + } + }, + // This function will be overloaded later if the modification of objects is allowed + setObject: function (_id, _obj, callback) { + sandbox.log('Function "setObject" is not allowed. Use adapter settings to allow it.', 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error('Function "setObject" is not allowed. Use adapter settings to allow it.')); + } + catch (err) { + errorInCallback(err); + } + } + }, + // This function will be overloaded later if the modification of objects is allowed + extendObject: function (_id, _obj, callback) { + sandbox.log('Function "extendObject" is not allowed. Use adapter settings to allow it.', 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error('Function "extendObject" is not allowed. Use adapter settings to allow it.')); + } + catch (err) { + errorInCallback(err); + } + } + }, + // This function will be overloaded later if the modification of objects is allowed + deleteObject: function (_id, _isRecursive, callback) { + if (typeof _isRecursive === 'function') { + callback = _isRecursive; + } + sandbox.log('Function "deleteObject" is not allowed. Use adapter settings to allow it.', 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error('Function "deleteObject" is not allowed. Use adapter settings to allow it.')); + } + catch (err) { + errorInCallback(err); + } + } + }, + getEnums: function (enumName) { + const result = []; + const r = enumName ? new RegExp(`^enum\\.${enumName}\\.`) : false; + for (let i = 0; i < enums.length; i++) { + if (!r || r.test(enums[i])) { + const common = objects[enums[i]].common || {}; + result.push({ + id: enums[i], + members: common.members || [], + name: common.name || '', + }); + } + } + if (sandbox.verbose) { + sandbox.log(`getEnums(enumName=${enumName}) => ${JSON.stringify(result)}`, 'info'); + } + return JSON.parse(JSON.stringify(result)); + }, + createAlias: function (name, alias, forceCreation, common, native, callback) { + if (typeof native === 'function') { + callback = native; + native = {}; + } + if (typeof common === 'function') { + callback = common; + common = undefined; + } + if (typeof forceCreation === 'function') { + callback = forceCreation; + forceCreation = undefined; + } + if ((0, tools_1.isObject)(forceCreation)) { + native = common; + common = forceCreation; + forceCreation = undefined; + } + if (typeof name !== 'string') { + const err = `Wrong type of name "${typeof name}". Expected "string".`; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + if (!name) { + const err = 'Empty ID is not allowed.'; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + if (!name.startsWith('alias.0.')) { + name = `alias.0.${name}`; + } + const _common = common || {}; + if ((0, tools_1.isObject)(_common.alias)) { + // alias already in common, use this + } + else if ((0, tools_1.isObject)(alias) && + (typeof alias.id === 'string' || (0, tools_1.isObject)(alias.id))) { + _common.alias = alias; + } + else if (typeof alias === 'string') { + _common.alias = { id: alias }; + } + else { + const err = 'Source ID needs to be provided as string or object with id property.'; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + let aliasSourceId = ''; + if (_common.alias) { + aliasSourceId = (0, tools_1.isObject)(_common.alias.id) + ? _common.alias.id.read + : _common.alias.id; + if (!objects[aliasSourceId] && objects[`${adapter.namespace}.${aliasSourceId}`]) { + aliasSourceId = `${adapter.namespace}.${aliasSourceId}`; + if ((0, tools_1.isObject)(_common.alias.id)) { + _common.alias.id.read = aliasSourceId; + } + else { + _common.alias.id = aliasSourceId; + } + } + if ((0, tools_1.isObject)(_common.alias.id) && + _common.alias.id.write && + !objects[_common.alias.id.write] && + objects[`${adapter.namespace}.${_common.alias.id.write}`]) { + _common.alias.id.write = + `${adapter.namespace}.${_common.alias.id.write}`; + } + } + const obj = objects[aliasSourceId]; + if (!obj) { + const err = `Alias source object "${aliasSourceId}" does not exist.`; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + if (obj.type !== 'state') { + const err = `Alias source object "${aliasSourceId}" must be a state object.`; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + if (_common.name === undefined) { + _common.name = obj.common.name || name; + } + if (_common.type === undefined && obj.common.type !== undefined) { + _common.type = obj.common.type; + } + if (_common.role === undefined && obj.common.role !== undefined) { + _common.role = obj.common.role; + } + if (_common.min === undefined && obj.common.min !== undefined) { + _common.min = obj.common.min; + } + if (_common.max === undefined && obj.common.max !== undefined) { + _common.max = obj.common.max; + } + if (_common.step === undefined && obj.common.step !== undefined) { + _common.step = obj.common.step; + } + if (_common.unit === undefined && obj.common.unit !== undefined) { + _common.unit = obj.common.unit; + } + if (_common.desc === undefined && obj.common.desc !== undefined) { + _common.desc = obj.common.desc; + } + return sandbox.createState(name, undefined, forceCreation, _common, native, callback); + }, + createState: async function (name, initValue, forceCreation, common, native, callback) { + if (typeof native === 'function') { + callback = native; + native = {}; + } + if (typeof common === 'function') { + callback = common; + common = undefined; + } + if (typeof initValue === 'function') { + callback = initValue; + initValue = undefined; + } + if (typeof forceCreation === 'function') { + callback = forceCreation; + forceCreation = undefined; + } + if ((0, tools_1.isObject)(initValue)) { + common = initValue; + native = forceCreation; + forceCreation = undefined; + initValue = undefined; + } + if ((0, tools_1.isObject)(forceCreation)) { + native = common; + common = forceCreation; + forceCreation = undefined; + } + if (typeof name !== 'string') { + const err = `Wrong type of name "${typeof name}". Expected "string".`; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + if (!name) { + const err = 'Empty ID is not allowed.'; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + const isAlias = name.startsWith('alias.0.'); + const _common = (common || {}); + _common.name = _common.name || name; + _common.role = _common.role || 'state'; + _common.type = _common.type || 'mixed'; + if (!isAlias && initValue === undefined) { + initValue = _common.def; + } + native = native || {}; + // Check min, max and def values for number + if (_common.type !== undefined && _common.type === 'number') { + let min = 0; + let max = 0; + let def = 0; + let err; + if (_common.min !== undefined) { + min = _common.min; + if (typeof min !== 'number') { + min = parseFloat(min); + if (isNaN(min)) { + err = `Wrong type of ${name}.common.min`; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + _common.min = min; + } + } + if (_common.max !== undefined) { + max = _common.max; + if (typeof max !== 'number') { + max = parseFloat(max); + if (isNaN(max)) { + err = `Wrong type of ${name}.common.max`; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + _common.max = max; + } + } + if (_common.def !== undefined) { + if (isAlias) { + delete _common.def; + } + else { + def = _common.def; + if (typeof def !== 'number') { + def = parseFloat(def); + if (isNaN(def)) { + err = `Wrong type of ${name}.common.def`; + sandbox.log(err, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err)); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + _common.def = def; + } + } + } + if (_common.min !== undefined && _common.max !== undefined && min > max) { + _common.max = min; + _common.min = max; + } + if (_common.def !== undefined && _common.min !== undefined && def < min) { + _common.def = min; + } + if (_common.def !== undefined && _common.max !== undefined && def > max) { + _common.def = max; + } + } + if (sandbox.verbose) { + sandbox.log(`createState(name=${name}, initValue=${JSON.stringify(initValue)}, forceCreation=${JSON.stringify(forceCreation)}, common=${JSON.stringify(common)}, native=${JSON.stringify(native)}, isAlias=${isAlias})`, 'debug'); + } + let id = `${adapter.namespace}.${name}`; + if (name.match(/^javascript\.\d+\./) || name.startsWith('0_userdata.0.') || isAlias) { + id = name; + } + if (id.match(/^javascript\.\d+\.scriptEnabled/)) { + sandbox.log(`Own states (${id}) should not be created in javascript.X.scriptEnabled.*! Please move the states to 0_userdata.0.*`, 'info'); + } + else if (id.match(/^javascript\.\d+\.scriptProblem/)) { + sandbox.log(`Own states (${id}) should not be created in javascript.X.scriptProblem.*! Please move the states to 0_userdata.0.*`, 'info'); + } + // User can create aliases by two ways: + // - id is starting with "alias.0." and common.alias.id is set, so the state defined in common.alias.id will be created automatically if not exists + // - id is not starting with "alias.0.", but common.alias is set, so the state defined in common.alias will be created automatically if not exists + if (!isAlias && _common.alias) { + // check and create if not exists the alias + let alias; + if (typeof _common.alias === 'string') { + alias = { + id: _common.alias, + }; + } + else if (typeof _common.alias === 'boolean') { + const parts = id.split('.'); + parts[0] = 'alias'; + parts[1] = '0'; + alias = { + id: parts.join('.'), + }; + } + else { + alias = _common.alias; + } + delete _common.alias; + if (!alias.id.startsWith('alias.0.')) { + alias.id = `alias.0.${alias.id}`; + } + let aObj; + try { + aObj = (await adapter.getForeignObjectAsync(alias.id)); + } + catch { + // ignore + } + if (!aObj) { + try { + const _obj = { + _id: alias.id, + type: 'state', + common: { + name: `Alias to ${id}`, + role: 'state', + type: _common.type, + read: _common.read, + write: _common.write, + unit: _common.unit, + alias: { + id, + read: alias.read, + write: alias.write, + }, + }, + native: {}, + }; + await adapter.setForeignObjectAsync(alias.id, _obj); + } + catch (err) { + sandbox.log(`Cannot create alias "${alias.id}": ${err}`, 'error'); + } + } + } + else if (isAlias && _common.alias) { + if (typeof _common.alias === 'string') { + _common.alias = { + id: _common.alias, + }; + } + const readId = typeof _common.alias.id === 'string' ? _common.alias.id : _common.alias.id.read; + let writeId = typeof _common.alias.id === 'string' ? _common.alias.id : _common.alias.id.write; + if (writeId === readId) { + writeId = undefined; + } + // try to create the linked states + let aObj; + try { + aObj = (await adapter.getForeignObjectAsync(readId)); + } + catch { + // ignore + } + if (!aObj) { + try { + await adapter.setForeignObjectAsync(readId, { + type: 'state', + common: { + name: `State for ${id}`, + role: 'state', + type: _common.type, + read: _common.read, + write: _common.write, + unit: _common.unit, + }, + native: {}, + }); + } + catch (err) { + sandbox.log(`Cannot create alias "${readId}": ${err}`, 'error'); + } + } + if (writeId && _common.write !== false) { + try { + aObj = (await adapter.getForeignObjectAsync(writeId)); + } + catch { + // ignore + } + if (!aObj) { + try { + await adapter.setForeignObjectAsync(writeId, { + type: 'state', + common: { + name: `Write state for ${id}`, + role: 'state', + type: _common.type, + read: _common.read, + write: _common.write, + unit: _common.unit, + }, + native: {}, + }); + } + catch (err) { + sandbox.log(`Cannot create alias "${writeId}": ${err}`, 'error'); + } + } + } + } + let obj; + try { + obj = await adapter.getForeignObjectAsync(id); + } + catch { + // ignore + } + if (obj?._id && + validIdForAutomaticFolderCreation(obj._id) && + obj.type === 'folder' && + obj.native && + obj.native.autocreated === 'by automatic ensure logic') { + // ignore a default created object because we now have a better defined one + obj = null; + } + if (!obj || forceCreation) { + // create new one + const newObj = { + _id: id, + common: _common, + native, + type: 'state', + }; + try { + await adapter.setForeignObjectAsync(id, newObj); + } + catch (err) { + sandbox.log(`Cannot set object "${id}": ${err}`, 'warn'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, err); + } + catch (err) { + errorInCallback(err); + } + } + return; + } + // Update meta objects + context.updateObjectContext(id, newObj); + if (!isAlias && initValue !== undefined) { + if ((0, tools_1.isObject)(initValue) && initValue.ack !== undefined) { + setStateHelper(sandbox, true, false, id, initValue, callback); + } + else { + setStateHelper(sandbox, true, false, id, initValue, true, callback); + } + } + else if (!isAlias && !forceCreation) { + setStateHelper(sandbox, true, false, id, null, callback); + } + else if (isAlias) { + try { + const state = await adapter.getForeignStateAsync(id); + if (state) { + states[id] = state; + } + } + catch { + // ignore + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, null, id); + } + catch (err) { + errorInCallback(err); + } + } + } + else if (typeof callback === 'function') { + try { + callback.call(sandbox, null, id); + } + catch (err) { + errorInCallback(err); + } + } + await ensureObjectStructure(id); + } + else { + // state yet exists + if (!adapter.config.subscribe && + !states[id] && + states[`${adapter.namespace}.${id}`] === undefined) { + states[id] = { + val: null, + ack: true, + lc: Date.now(), + ts: Date.now(), + q: 0, + from: `system.adapter.${adapter.namespace}`, + }; + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, null, id); + } + catch (err) { + errorInCallback(err); + } + } + await ensureObjectStructure(id); + } + }, + deleteState: function (id, callback) { + // todo: check rights + // todo: also remove from "names" + if (sandbox.verbose) { + sandbox.log(`deleteState(id=${id})`, 'debug'); + } + let found = false; + if ((id.startsWith('0_userdata.0.') || id.startsWith(adapter.namespace)) && objects[id]) { + found = true; + delete objects[id]; + if (states[id]) { + delete states[id]; + } + adapter.delForeignObject(id, function (err) { + err && sandbox.log(`Object for state "${id}" does not exist: ${err}`, 'warn'); + adapter.delForeignState(id, function (err) { + err && sandbox.log(`Cannot delete state "${id}": ${err}`, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, err, found); + } + catch (err) { + errorInCallback(err); + } + } + }); + }); + } + else if (objects[`${adapter.namespace}.${id}`]) { + delete objects[`${adapter.namespace}.${id}`]; + found = true; + if (states[`${adapter.namespace}.${id}`]) { + delete states[`${adapter.namespace}.${id}`]; + } + adapter.delObject(id, function (err) { + err && sandbox.log(`Object for state "${id}" does not exist: ${err}`, 'warn'); + adapter.delState(id, function (err) { + err && sandbox.log(`Cannot delete state "${id}": ${err}`, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, err, found); + } + catch (err) { + errorInCallback(err); + } + } + }); + }); + } + else { + const err = 'Not found'; + sandbox.log(`Cannot delete state "${id}": ${err}`, 'error'); + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error(err), found); + } + catch (err) { + errorInCallback(err); + } + } + } + }, + sendTo: function (_adapter, cmd, msg, options, callback) { + const defaultTimeout = 20000; + if (typeof options === 'function') { + callback = options; + options = { timeout: defaultTimeout }; + } + let timeout = null; + if (typeof callback === 'function') { + const timeoutDuration = parseInt(options?.timeout, 10) || defaultTimeout; + timeout = setTimeout(() => { + timeout = null; + if (sandbox.verbose) { + sandbox.log(`sendTo => timeout: ${timeoutDuration}`, 'debug'); + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, { error: 'timeout' }, options, _adapter); + } + catch (err) { + errorInCallback(err); + } + callback = undefined; + } + }, timeoutDuration); + } + let cbFunc; + if (timeout) { + cbFunc = function (result) { + if (timeout) { + clearTimeout(timeout); + timeout = null; + } + if (sandbox.verbose && result) { + sandbox.log(`sendTo => ${JSON.stringify(result)}`, 'debug'); + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, result, options, _adapter); + } + catch (err) { + errorInCallback(err); + } + callback = undefined; + } + }; + } + // If specific instance + if (_adapter.match(/\.[0-9]+$/)) { + sandbox.verbose && + sandbox.log(`sendTo(instance=${_adapter}, cmd=${cmd}, msg=${JSON.stringify(msg)}, hasCallback=${typeof callback === 'function'})`, 'info'); + adapter.sendTo(_adapter, cmd, msg, cbFunc, options); + } + else { + // Send it to all instances + context.adapter.getObjectView('system', 'instance', { startkey: `system.adapter.${_adapter}.`, endkey: `system.adapter.${_adapter}.\u9999` }, options, (err, res) => { + if (err || !res) { + sandbox.log(`sendTo failed: ${err?.message}`, 'error'); + return; + } + const instances = res.rows.map(item => item.id.substring('system.adapter.'.length)); + instances.forEach(instance => { + sandbox.verbose && + sandbox.log(`sendTo(instance=${instance}, cmd=${cmd}, msg=${JSON.stringify(msg)}, hasCallback=${typeof callback === 'function'})`, 'info'); + adapter.sendTo(instance, cmd, msg, cbFunc, options); + }); + }); + } + }, + sendto: function (_adapter, cmd, msg, callback) { + return sandbox.sendTo(_adapter, cmd, msg, callback); + }, + sendToAsync: function (_adapter, cmd, msg, options) { + return new Promise((resolve, reject) => { + sandbox.sendTo(_adapter, cmd, msg, options, res => { + if (!res || res.error) { + reject(res ? new Error(res.error) : new Error('Unknown error')); + } + else { + resolve(res); + } + }); + }); + }, + sendToHost: function (host, cmd, msg, callback) { + if (!adapter.config.enableSendToHost) { + const error = 'sendToHost is not available. Please enable "Enable SendToHost" option in instance settings'; + sandbox.log(error, 'error'); + if (typeof callback === 'function') { + // leave it as a normal function and not as a lambda, to hide the "this" object + setImmediate(function () { + callback(error); + }); + } + } + else { + sandbox.verbose && + sandbox.log(`sendToHost(adapter=${host}, cmd=${cmd}, msg=${JSON.stringify(msg)})`, 'info'); + adapter.sendToHost(host, cmd, msg, callback); + } + }, + sendToHostAsync: function (host, cmd, msg) { + return new Promise((resolve, reject) => { + sandbox.sendToHost(host, cmd, msg, res => { + if (!res || res.error) { + reject(res ? new Error(res.error) : new Error('Unknown error')); + } + else { + resolve(res); + } + }); + }); + }, + registerNotification: function (msg, isAlert) { + const category = !isAlert ? 'scriptMessage' : 'scriptAlert'; + if (sandbox.verbose) { + sandbox.log(`registerNotification(msg=${msg}, category=${category})`, 'info'); + } + adapter.registerNotification('javascript', category, msg); + }, + setInterval: function (callback, ms, ...args) { + if (typeof callback === 'function') { + const int = setInterval(() => { + try { + callback.call(sandbox, ...args); + } + catch (err) { + errorInCallback(err); + } + }, ms); + script.intervals.push(int); + if (sandbox.verbose) { + sandbox.log(`setInterval(ms=${ms})`, 'info'); + } + return int; + } + sandbox.log(`Invalid callback for setInterval! - ${typeof callback}`, 'error'); + return null; + }, + clearInterval: function (id) { + const pos = script.intervals.indexOf(id); + if (pos !== -1) { + if (sandbox.verbose) { + sandbox.log('clearInterval() => cleared', 'info'); + } + clearInterval(id); + script.intervals.splice(pos, 1); + } + else { + if (sandbox.verbose) { + sandbox.log('clearInterval() => not found', 'warn'); + } + } + }, + setTimeout: function (callback, ms, ...args) { + if (typeof callback === 'function') { + const to = setTimeout(() => { + // Remove timeout from the list + const pos = script.timeouts.indexOf(to); + if (pos !== -1) { + script.timeouts.splice(pos, 1); + } + try { + callback.call(sandbox, ...args); + } + catch (err) { + errorInCallback(err); + } + }, ms); + if (sandbox.verbose) { + sandbox.log(`setTimeout(ms=${ms})`, 'info'); + } + script.timeouts.push(to); + return to; + } + sandbox.log(`Invalid callback for setTimeout! - ${typeof callback}`, 'error'); + return null; + }, + clearTimeout: function (id) { + const pos = script.timeouts.indexOf(id); + if (pos !== -1) { + if (sandbox.verbose) { + sandbox.log('clearTimeout() => cleared', 'info'); + } + clearTimeout(id); + script.timeouts.splice(pos, 1); + } + else { + if (sandbox.verbose) { + sandbox.log('clearTimeout() => not found', 'warn'); + } + } + }, + setImmediate: function (callback, ...args) { + if (typeof callback === 'function') { + setImmediate(() => { + try { + callback.apply(sandbox, args); + } + catch (err) { + errorInCallback(err); + } + }); + if (sandbox.verbose) { + sandbox.log('setImmediate()', 'info'); + } + } + else { + sandbox.log(`Invalid callback for setImmediate! - ${typeof callback}`, 'error'); + } + }, + cb: function (callback) { + return function (args) { + if (context.scripts[name]?._id === sandbox._id) { + if (typeof callback === 'function') { + try { + callback.apply(sandbox, args); + } + catch (err) { + errorInCallback(err); + } + } + } + else { + sandbox.log(`Callback for old version of script: ${name}`, 'warn'); + } + }; + }, + compareTime: function (startTime, endTime, operation, time) { + if (startTime && typeof startTime === 'string') { + const pos = consts.astroListLow.indexOf(startTime.toLowerCase()); + if (pos !== -1) { + const aTime = sandbox.getAstroDate(consts.astroList[pos]); + if (aTime) { + startTime = aTime.toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + hour12: false, + }); + } + else { + startTime = 0; + } + } + } + else if (startTime && (0, tools_1.isObject)(startTime) && startTime.astro) { + const aTime = sandbox.getAstroDate(startTime.astro, startTime.date || new Date(), startTime.offset || 0); + if (aTime) { + startTime = aTime.toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + hour12: false, + }); + } + else { + startTime = 0; + } + } + if (endTime && typeof endTime === 'string') { + const pos = consts.astroListLow.indexOf(endTime.toLowerCase()); + if (pos !== -1) { + const aTime = sandbox.getAstroDate(consts.astroList[pos]); + endTime = + aTime?.toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + hour12: false, + }) || 0; + } + } + else if (endTime && (0, tools_1.isObject)(endTime) && endTime.astro) { + const aTime = sandbox.getAstroDate(endTime.astro, endTime.date || new Date(), endTime.offset || 0); + endTime = + aTime?.toLocaleTimeString([], { + hour: '2-digit', + minute: '2-digit', + hour12: false, + }) || 0; + } + // --- Convert "time" to number + let nTime; + // maybe it is astro date like 'sunrise' or 'sunset' + if (time && typeof time === 'string') { + const pos = consts.astroListLow.indexOf(time.toLowerCase()); + if (pos !== -1) { + nTime = sandbox.getAstroDate(consts.astroList[pos])?.getTime() || 0; + } + } + else if (time && (0, tools_1.isObject)(time) && time.astro) { + nTime = + sandbox + .getAstroDate(time.astro, time.date || new Date(), time.offset || 0) + ?.getTime() || 0; + } + let daily = true; + if (time) { + daily = false; + } + // if not astro date + if (!nTime) { + if (time && !(0, tools_1.isObject)(time)) { + if (typeof time === 'string' && !time.includes(' ') && !time.includes('T')) { + const parts = time.split(':'); + const oTime = new Date(); + oTime.setHours(parseInt(parts[0], 10)); + oTime.setMinutes(parseInt(parts[1], 10)); + oTime.setMilliseconds(0); + if (parts.length === 3) { + oTime.setSeconds(parseInt(parts[2], 10)); + } + else { + oTime.setSeconds(0); + } + nTime = oTime.getTime(); + } + else { + nTime = new Date(time).getTime(); + } + } + else if (!time) { + const oTime = new Date(); + oTime.setMilliseconds(0); + nTime = oTime.getTime(); + } + else { + // If Date + nTime = time.getTime(); + } + } + // --- End of conversion "time" to number + if (typeof startTime === 'string') { + if (!startTime.includes(' ') && !startTime.includes('T')) { + const parts = startTime.split(':'); + startTime = new Date(); + startTime.setHours(parseInt(parts[0], 10)); + startTime.setMinutes(parseInt(parts[1], 10)); + startTime.setMilliseconds(0); + if (parts.length === 3) { + startTime.setSeconds(parseInt(parts[2], 10)); + } + else { + startTime.setSeconds(0); + } + } + else { + daily = false; + startTime = new Date(startTime); + } + } + else { + daily = false; + startTime = new Date(startTime); + } + const nStartTime = startTime.getTime(); + let nEndTime; + if (endTime && typeof endTime === 'string') { + if (!endTime.includes(' ') && !endTime.includes('T')) { + const parts = endTime.split(':'); + endTime = new Date(); + endTime.setHours(parseInt(parts[0], 10)); + endTime.setMinutes(parseInt(parts[1], 10)); + endTime.setMilliseconds(0); + if (parts.length === 3) { + endTime.setSeconds(parseInt(parts[2], 10)); + } + else { + endTime.setSeconds(0); + } + } + else { + daily = false; + endTime = new Date(endTime); + } + } + else if (endTime) { + daily = false; + endTime = new Date(endTime); + } + else { + endTime = null; + } + if (endTime) { + nEndTime = endTime.getTime(); + } + else { + nEndTime = null; + } + if (operation === 'between') { + if (nEndTime) { + if (nStartTime > nEndTime && daily) { + return !(nTime >= nEndTime && nTime < nStartTime); + } + return nTime >= nStartTime && nTime < nEndTime; + } + sandbox.log(`missing or unrecognized endTime expression: ${JSON.stringify(endTime)}`, 'warn'); + return false; + } + if (operation === 'not between') { + if (nEndTime) { + if (nStartTime > nEndTime && daily) { + return nTime >= nEndTime && nTime < nStartTime; + } + return !(nTime >= nStartTime && nTime < nEndTime); + } + sandbox.log(`missing or unrecognized endTime expression: ${JSON.stringify(endTime)}`, 'warn'); + return false; + } + if (operation === '>') { + return nTime > nStartTime; + } + if (operation === '>=') { + return nTime >= nStartTime; + } + if (operation === '<') { + return nTime < nStartTime; + } + if (operation === '<=') { + return nTime <= nStartTime; + } + if (operation === '==') { + return nTime === nStartTime; + } + if (operation === '<>' || operation === '!=') { + return nTime !== nStartTime; + } + sandbox.log(`Invalid operator: ${operation}`, 'warn'); + return false; + }, + onStop: function (cb, timeout) { + if (sandbox.verbose) { + sandbox.log(`onStop(timeout=${timeout})`, 'info'); + } + script.onStopCb = cb; + script.onStopTimeout = timeout || 1000; + }, + formatValue: function (value, decimals, format) { + if (typeof decimals === 'string') { + format = decimals; + decimals = 0; + } + if (!format) { + if (adapter.isFloatComma !== undefined) { + format = adapter.isFloatComma ? '.,' : ',.'; + } + else if (objects['system.config'] && objects['system.config'].common) { + format = objects['system.config'].common.isFloatComma ? '.,' : ',.'; + } + } + return adapter.formatValue(value, decimals, format); + }, + formatDate: function (date, format, language) { + if (!format) { + if (adapter.dateFormat) { + format = adapter.dateFormat; + } + else { + format = + objects['system.config'] && objects['system.config'].common + ? objects['system.config'].common.dateFormat || 'DD.MM.YYYY' + : 'DD.MM.YYYY'; + } + format = format || 'DD.MM.YYYY'; + } + // maybe it is astro date like 'sunrise' or 'sunset' + if (date && typeof date === 'string') { + const pos = consts.astroListLow.indexOf(date.toLowerCase()); + if (pos !== -1) { + date = sandbox.getAstroDate(consts.astroList[pos])?.getTime() || 0; + } + } + else if (date && (0, tools_1.isObject)(date) && date.astro) { + date = + sandbox + .getAstroDate(date.astro, date.date || new Date(), date.offset || 0) + ?.getTime() || 0; + } + if (format.match(/[WНOО]+/)) { + let text = adapter.formatDate(date, format); + if (!language || !consts.dayOfWeeksFull[language]) { + language = + adapter.language || + (objects['system.config'] && + objects['system.config'].common && + objects['system.config'].common.language) || + 'en'; + if (!consts.dayOfWeeksFull[language]) { + language = 'en'; + } + } + if (typeof date === 'number' || typeof date === 'string') { + date = new Date(date); + } + else if (typeof date.getMonth !== 'function') { + sandbox.log(`Invalid date object provided: ${JSON.stringify(date)}`, 'error'); + return 'Invalid date'; + } + const d = date.getDay(); + text = text.replace('НН', consts.dayOfWeeksFull[language][d]); + let initialText = text; + text = text.replace('WW', consts.dayOfWeeksFull[language][d]); + if (initialText === text) { + text = text.replace('W', consts.dayOfWeeksShort[language][d]); + } + text = text.replace('Н', consts.dayOfWeeksShort[language][d]); + text = text.replace('Н', consts.dayOfWeeksShort[language][d]); + const m = date.getMonth(); + initialText = text; + text = text.replace('OOO', consts.monthFullGen[language][m]); + text = text.replace('ООО', consts.monthFullGen[language][m]); + text = text.replace('OO', consts.monthFull[language][m]); + text = text.replace('ОО', consts.monthFull[language][m]); + if (initialText === text) { + text = text.replace('O', consts.monthShort[language][m]); + } + return text; + } + return adapter.formatDate(date, format); + }, + formatTimeDiff: function (diff, format) { + if (!format) { + format = 'hh:mm:ss'; + } + let text = format; + if (sandbox.verbose) { + sandbox.log(`formatTimeDiff(format=${format}, diff=${diff})`, 'debug'); + } + const second = 1000; + const minute = 60 * second; + const hour = 60 * minute; + const day = 24 * hour; + const neg = diff < 0; + diff = Math.abs(diff); + if (/DD|TT|ДД|D|T|Д/.test(text)) { + const days = Math.floor(diff / day); + text = text.replace(/DD|TT|ДД/, days < 10 ? `0${days}` : days.toString()); + text = text.replace(/[DTД]/, days.toString()); + if (sandbox.verbose) { + sandbox.log(`formatTimeDiff(format=${format}, text=${text}, days=${days})`, 'debug'); + } + diff -= days * day; + } + if (/hh|SS|чч|h|S|ч/.test(text)) { + const hours = Math.floor(diff / hour); + text = text.replace(/hh|SS|чч/, hours < 10 ? `0${hours}` : hours.toString()); + text = text.replace(/[hSч]/, hours.toString()); + sandbox.verbose && + sandbox.log(`formatTimeDiff(format=${format}, text=${text}, hours=${hours})`, 'debug'); + diff -= hours * hour; + } + if (/mm|мм|m|м/.test(text)) { + const minutes = Math.floor(diff / minute); + text = text.replace(/mm|мм/, minutes < 10 ? `0${minutes}` : minutes.toString()); + text = text.replace(/[mм]/, minutes.toString()); + sandbox.verbose && + sandbox.log(`formatTimeDiff(format=${format}, text=${text}, minutes=${minutes})`, 'debug'); + diff -= minutes * minute; + } + if (/ss|сс|мм|s|с/.test(text)) { + const seconds = Math.floor(diff / second); + text = text.replace(/ss|сс/, seconds < 10 ? `0${seconds}` : seconds.toString()); + text = text.replace(/[sс]/, seconds.toString()); + sandbox.verbose && + sandbox.log(`formatTimeDiff(format=${format}, text=${text}, seconds=${seconds})`, 'debug'); + // diff -= seconds * second; // no milliseconds + } + if (sandbox.verbose) { + sandbox.log(`formatTimeDiff(format=${format}, text=${text})`, 'debug'); + } + return neg ? `-${text}` : text; + }, + getDateObject: function (date) { + if ((0, tools_1.isObject)(date)) { + return date; + } + if (typeof date === 'undefined') { + return new Date(); + } + if (typeof date !== 'string') { + return new Date(date); + } + // If only hours: 20, 2 + if (date.match(/^\d?\d$/)) { + const _now = new Date(); + date = `${_now.getFullYear()}-${_now.getMonth() + 1}-${_now.getDate()} ${date}:00`; + } + else if (date.match(/^\d?\d:\d\d(:\d\d)?$/)) { + // 20:00, 2:00, 20:00:00, 2:00:00 + const now = new Date(); + date = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()} ${date}`; + } + return new Date(date); + }, + writeFile: function (_adapter, fileName, data, callback) { + if (typeof data === 'function' || !data) { + callback = data; + data = fileName; + fileName = _adapter; + _adapter = '0_userdata.0'; + } + _adapter = _adapter || '0_userdata.0'; + if (debug) { + sandbox.log(`writeFile(adapter=${_adapter}, fileName=${fileName}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + if (typeof callback === 'function') { + setTimeout(function () { + try { + callback.call(sandbox); + } + catch (err) { + errorInCallback(err); + } + }, 0); + } + } + else { + if (sandbox.verbose) { + sandbox.log(`writeFile(adapter=${_adapter}, fileName=${fileName})`, 'info'); + } + if (callback) { + adapter.writeFile(_adapter, fileName, data, callback); + } + else { + // @ts-expect-error should be fixed in js-controller + adapter.writeFile(_adapter, fileName, data); + } + } + }, + readFile: function (_adapter, fileName, callback) { + if (typeof fileName === 'function') { + callback = fileName; + fileName = _adapter; + _adapter = '0_userdata.0'; + } + if (typeof callback !== 'function') { + sandbox.log(`readFile(adapter=${_adapter}, fileName=${fileName}): no callback`, 'error'); + return; + } + _adapter = _adapter || '0_userdata.0'; + if (sandbox.verbose) { + sandbox.log(`readFile(adapter=${_adapter}, fileName=${fileName})`, 'info'); + } + adapter.fileExists(_adapter, fileName, (error, result) => { + if (error) { + callback(error); + } + else if (!result) { + callback(new Error('Not exists')); + } + else { + adapter.readFile(_adapter, fileName, callback); + } + }); + }, + unlink: function (_adapter, fileName, callback) { + if (typeof fileName === 'function') { + callback = fileName; + fileName = _adapter; + _adapter = '0_userdata.0'; + } + _adapter = _adapter || '0_userdata.0'; + if (debug) { + sandbox.log(`unlink(adapter=${_adapter}, fileName=${fileName}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + if (typeof callback === 'function') { + setTimeout(function () { + try { + callback.call(sandbox); + } + catch (err) { + errorInCallback(err); + } + }, 0); + } + } + else { + if (sandbox.verbose) { + sandbox.log(`unlink(adapter=${_adapter}, fileName=${fileName})`, 'info'); + } + if (callback) { + adapter.unlink(_adapter, fileName, callback); + } + else { + // @ts-expect-error should be fixed in js-controller + adapter.unlink(_adapter, fileName); + } + } + }, + delFile: function (_adapter, fileName, callback) { + return sandbox.unlink(_adapter, fileName, callback); + }, + rename: function (_adapter, oldName, newName, callback) { + _adapter = _adapter || '0_userdata.0'; + if (debug) { + sandbox.log(`rename(adapter=${_adapter}, oldName=${oldName}, newName=${newName}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + if (typeof callback === 'function') { + setTimeout(function () { + try { + callback.call(sandbox); + } + catch (err) { + errorInCallback(err); + } + }, 0); + } + } + else { + sandbox.verbose && + sandbox.log(`rename(adapter=${_adapter}, oldName=${oldName}, newName=${newName})`, 'info'); + if (callback) { + adapter.rename(_adapter, oldName, newName, callback); + } + else { + // @ts-expect-error should be fixed in js-controller + adapter.rename(_adapter, oldName, newName); + } + } + }, + renameFile: function (_adapter, oldName, newName, callback) { + return sandbox.rename(_adapter, oldName, newName, callback); + }, + getHistory: function (instance, options, callback) { + if ((0, tools_1.isObject)(instance)) { + callback = options; + options = instance; + instance = ''; + } + if (typeof callback !== 'function') { + return sandbox.log('No callback found!', 'error'); + } + if (!(0, tools_1.isObject)(options)) { + return sandbox.log('No options found!', 'error'); + } + if (!options.id) { + return sandbox.log('No ID found!', 'error'); + } + const timeoutMs = parseInt(options + ?.timeout, 10) || 20000; + if (!instance) { + // @ts-expect-error defaultHistory is private attribute of adapter. Fix later + if (adapter.defaultHistory) { + // @ts-expect-error defaultHistory is private attribute of adapter. Fix later + instance = adapter.defaultHistory; + } + else { + instance = objects['system.config']?.common?.defaultHistory || null; + } + } + if (sandbox.verbose) { + sandbox.log(`getHistory(instance=${instance}, options=${JSON.stringify(options)})`, 'info'); + } + if (!instance) { + sandbox.log('No default history instance found!', 'error'); + try { + callback.call(sandbox, new Error('No default history instance found!')); + } + catch (err) { + errorInCallback(err); + } + return; + } + if (instance.startsWith('system.adapter.')) { + instance = instance.substring('system.adapter.'.length); + } + if (!objects[`system.adapter.${instance}`]) { + sandbox.log(`Instance "${instance}" not found!`, 'error'); + try { + callback.call(sandbox, new Error(`Instance "${instance}" not found!`)); + } + catch (err) { + errorInCallback(err); + } + return; + } + let _timeout = setTimeout(() => { + _timeout = null; + if (sandbox.verbose) { + sandbox.log('getHistory => timeout', 'debug'); + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, new Error('Timeout'), null, options, instance); + } + catch (err) { + errorInCallback(err); + } + callback = undefined; + } + }, timeoutMs); + adapter.sendTo(instance, 'getHistory', { + id: options.id, + options, + }, (res) => { + if (_timeout) { + clearTimeout(_timeout); + _timeout = null; + } + const result = res; + if (sandbox.verbose && result?.error) { + sandbox.log(`getHistory => ${result.error}`, 'error'); + } + if (sandbox.verbose && result?.result) { + sandbox.log(`getHistory => ${result.result.length} items`, 'debug'); + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, result.error ? new Error(result.error) : null, result.result, options, instance); + } + catch (err) { + errorInCallback(err); + } + callback = undefined; + } + }); + }, + runScript: function (scriptName, callback) { + scriptName = scriptName || name; + if (!scriptName.match(/^script\.js\./)) { + scriptName = `script.js.${scriptName}`; + } + // start another script + if (!objects[scriptName] || !objects[scriptName].common) { + sandbox.log(`Cannot start "${scriptName}", because not found`, 'error'); + return false; + } + if (debug) { + sandbox.log(`runScript(scriptName=${scriptName}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + typeof callback === 'function' && callback(); + return true; + } + if (objects[scriptName].common.enabled) { + objects[scriptName].common.enabled = false; + adapter.extendForeignObject(scriptName, { common: { enabled: false } }, ( /* err, obj */) => { + adapter.extendForeignObject(scriptName, { common: { enabled: true } }, err => typeof callback === 'function' && callback(err)); + }); + return true; + } + adapter.extendForeignObject(scriptName, { common: { enabled: true } }, err => typeof callback === 'function' && callback(err)); + return true; + }, + runScriptAsync: function (scriptName) { + let done = false; + return new Promise((resolve, reject) => { + const result = sandbox.runScript(scriptName, err => { + if (err) { + reject(err); + done = true; + } + else { + resolve(); + } + }); + if (result === false && !done) { + reject(new Error(`Script ${scriptName} was not found!`)); + } + }); + }, + startScript: function (scriptName, ignoreIfStarted, callback) { + if (typeof ignoreIfStarted === 'function') { + callback = ignoreIfStarted; + ignoreIfStarted = false; + } + scriptName = scriptName || name; + if (!scriptName.match(/^script\.js\./)) { + scriptName = `script.js.${scriptName}`; + } + // start another script + if (!objects[scriptName] || !objects[scriptName].common) { + sandbox.log(`Cannot start "${scriptName}", because not found`, 'error'); + return false; + } + if (debug) { + sandbox.log(`startScript(scriptName=${scriptName}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + typeof callback === 'function' && callback(null, false); + return true; + } + if (objects[scriptName].common.enabled) { + if (!ignoreIfStarted) { + objects[scriptName].common.enabled = false; + adapter.extendForeignObject(scriptName, { common: { enabled: false } }, () => { + adapter.extendForeignObject(scriptName, { common: { enabled: true } }, err => typeof callback === 'function' && callback(err, true)); + }); + } + else if (typeof callback === 'function') { + callback(null, false); + } + return true; + } + adapter.extendForeignObject(scriptName, { common: { enabled: true } }, err => { + typeof callback === 'function' && callback(err, true); + }); + return true; + }, + startScriptAsync: function (scriptName, ignoreIfStarted) { + return new Promise((resolve, reject) => { + const result = sandbox.startScript(scriptName, !!ignoreIfStarted, (err, started) => { + if (err) { + reject(err); + } + else { + resolve(started); + } + }); + if (result === false) { + reject(new Error(`Script ${scriptName} was not found!`)); + } + }); + }, + stopScript: function (scriptName, callback) { + scriptName = scriptName || name; + if (!scriptName.match(/^script\.js\./)) { + scriptName = `script.js.${scriptName}`; + } + // stop another script + if (!objects[scriptName] || !objects[scriptName].common) { + sandbox.log(`Cannot stop "${scriptName}", because not found`, 'error'); + return false; + } + if (debug) { + sandbox.log(`stopScript(scriptName=${scriptName}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + if (typeof callback === 'function') { + callback(null, false); + } + return true; + } + if (objects[scriptName].common.enabled) { + objects[scriptName].common.enabled = false; + adapter.extendForeignObject(scriptName, { common: { enabled: false } }, err => { + if (typeof callback === 'function') { + callback(err, true); + } + }); + } + else if (typeof callback === 'function') { + callback(null, false); + } + return true; + }, + stopScriptAsync: function (scriptName) { + return new Promise((resolve, reject) => { + const result = sandbox.stopScript(scriptName, (err, stopped) => { + if (err) { + reject(err); + } + else { + resolve(stopped); + } + }); + if (result === false) { + reject(new Error(`Script ${scriptName} was not found!`)); + } + }); + }, + isScriptActive: function (scriptName) { + if (!scriptName.match(/^script\.js\./)) { + scriptName = `script.js.${scriptName}`; + } + if (!objects[scriptName] || !objects[scriptName].common) { + sandbox.log('Script does not exist', 'error'); + return false; + } + return objects[scriptName].common.enabled; + }, + startInstanceAsync: async function (instanceName) { + const objInstanceId = `system.adapter.${instanceName}`; + const exists = await adapter.foreignObjectExists(objInstanceId); + if (exists) { + const instanceObj = await adapter.getForeignObjectAsync(objInstanceId); + if (instanceObj?.type === 'instance' && !instanceObj.common.enabled) { + await adapter.extendForeignObjectAsync(objInstanceId, { common: { enabled: true } }); + if (sandbox.verbose) { + sandbox.log(`startInstanceAsync (instanceName=${instanceName})`, 'info'); + } + return true; + } + sandbox.log(`Cannot start instance "${instanceName}", because already running`, 'warn'); + } + else { + sandbox.log(`Cannot start instance "${instanceName}", because not found`, 'error'); + } + return false; + }, + restartInstanceAsync: async function (instanceName) { + const objInstanceId = `system.adapter.${instanceName}`; + const exists = await adapter.foreignObjectExists(objInstanceId); + if (exists) { + const instanceObj = await adapter.getForeignObjectAsync(objInstanceId); + if (instanceObj?.type === 'instance' && instanceObj.common.enabled) { + await adapter.extendForeignObjectAsync(objInstanceId, {}); + if (sandbox.verbose) { + sandbox.log(`restartInstanceAsync (instanceName=${instanceName})`, 'info'); + } + return true; + } + sandbox.log(`Cannot restart instance "${instanceName}", because not running`, 'warn'); + } + else { + sandbox.log(`Cannot restart instance "${instanceName}", because not found`, 'error'); + } + return false; + }, + stopInstanceAsync: async function (instanceName) { + const objInstanceId = `system.adapter.${instanceName}`; + const exists = await adapter.foreignObjectExists(objInstanceId); + if (exists) { + const instanceObj = await adapter.getForeignObjectAsync(objInstanceId); + if (instanceObj?.type === 'instance' && instanceObj.common.enabled) { + await adapter.extendForeignObjectAsync(objInstanceId, { common: { enabled: false } }); + if (sandbox.verbose) { + sandbox.log(`stopInstanceAsync (instanceName=${instanceName})`, 'info'); + } + return true; + } + sandbox.log(`Cannot stop instance "${instanceName}", because not running`, 'warn'); + } + else { + sandbox.log(`Cannot stop instance "${instanceName}", because not found`, 'error'); + } + return false; + }, + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + toInt: function (val) { + if (val === true || val === 'true') { + val = 1; + } + if (val === false || val === 'false') { + val = 0; + } + val = parseInt(val) || 0; + return val; + }, + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + toFloat: function (val) { + if (val === true || val === 'true') { + val = 1; + } + if (val === false || val === 'false') { + val = 0; + } + val = parseFloat(val) || 0; + return val; + }, + // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents + toBoolean: function (val) { + if (val === '1' || val === 'true') { + val = true; + } + if (val === '0' || val === 'false') { + val = false; + } + return !!val; + }, + getAttr: function (obj, path) { + if (typeof path === 'string') { + path = path.split('.'); + } + if (typeof obj === 'string') { + try { + obj = JSON.parse(obj); + } + catch (err) { + adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, { + val: true, + ack: true, + c: 'getAttr', + }); + sandbox.log(`Cannot parse "${obj.substring(0, 30)}": ${err}`, 'error'); + return null; + } + } + const attr = path.shift() || ''; + try { + obj = obj[attr]; + } + catch (err) { + adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, { + val: true, + ack: true, + c: 'getAttr', + }); + sandbox.log(`Cannot get ${attr} of "${JSON.stringify(obj)}": ${err}`, 'error'); + return null; + } + if (!path.length) { + return obj; + } + const type = typeof obj; + if (obj === null || obj === undefined || type === 'boolean' || type === 'number') { + return null; + } + return sandbox.getAttr(obj, path); + }, + messageTo: function (target, data, options, callback) { + const defaultTimeout = 5000; + if (typeof target !== 'object') { + target = { instance: null, script: null, message: target }; + } + if (typeof options === 'function') { + callback = options; + options = { timeout: defaultTimeout }; + } + let timeout = null; + if (typeof callback === 'function') { + const timeoutDuration = parseInt(options?.timeout, 10) || defaultTimeout; + timeout = setTimeout(() => { + timeout = null; + if (sandbox.verbose) { + sandbox.log(`messageTo => timeout: ${timeoutDuration}`, 'debug'); + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, { error: 'timeout' }, options, target.instance); + } + catch (err) { + errorInCallback(err); + } + callback = undefined; + } + }, timeoutDuration); + } + let cbFunc; + if (timeout) { + cbFunc = function (res) { + timeout && clearTimeout(timeout); + const result = res; + if (sandbox.verbose && result?.result) { + sandbox.log(`messageTo => ${JSON.stringify(result)}`, 'debug'); + } + if (sandbox.verbose && result?.error) { + sandbox.log(`messageTo => ${result.error}`, 'error'); + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, result, options, target.instance); + } + catch (err) { + errorInCallback(err); + } + callback = undefined; + } + }; + } + if (target.instance || target.instance === 0) { + if (typeof target.instance === 'string' && + target.instance && + target.instance.startsWith('system.adapter.')) { + target.instance = target.instance.substring('system.adapter.'.length); + } + else if (typeof target.instance === 'number') { + target.instance = `javascript.${target.instance}`; + } + adapter.sendTo(target.instance, 'jsMessageBus', { message: target.message, script: target.script, data }, cbFunc); + } + else { + // Send it to all instances + context.adapter.getObjectView('system', 'instance', { startkey: 'system.adapter.javascript.', endkey: 'system.adapter.javascript.\u9999' }, options, (err, res) => { + if (err || !res) { + sandbox.log(`messageTo failed: ${err?.message}`, 'error'); + return; + } + const len = 'system.adapter.'.length; + const instances = res.rows.map(item => item.id.substring(len)); + instances.forEach(instance => { + adapter.sendTo(instance, 'jsMessageBus', { message: target.message, script: target.script, data }, cbFunc); + }); + }); + } + }, + messageToAsync: function (target, data, options) { + return new Promise((resolve, reject) => { + sandbox.messageTo(target, data, options, (res) => { + const result = res; + if (sandbox.verbose) { + sandbox.log(`messageTo result => ${JSON.stringify(res)}`, 'debug'); + } + if (!res || result.error) { + reject(result ? new Error(result.error) : new Error('Unknown error')); + } + else { + resolve(result); + } + }); + }); + }, + onMessage: function (messageName, callback) { + if (typeof callback !== 'function') { + sandbox.log('onMessage callback is not a function', 'error'); + return null; + } + context.messageBusHandlers[sandbox.scriptName] = context.messageBusHandlers[sandbox.scriptName] || {}; + context.messageBusHandlers[sandbox.scriptName][messageName] = + context.messageBusHandlers[sandbox.scriptName][messageName] || []; + const handler = { id: Date.now() + Math.floor(Math.random() * 10000), cb: callback, sandbox }; + context.messageBusHandlers[sandbox.scriptName][messageName].push(handler); + sandbox.__engine.__subscriptionsMessage += 1; + if (sandbox.__engine.__subscriptionsMessage % + adapter.config.maxTriggersPerScript === + 0) { + sandbox.log(`More than ${sandbox.__engine.__subscriptionsMessage} message subscriptions registered. Check your script!`, 'warn'); + } + return handler.id; + }, + onMessageUnregister: function (idOrName) { + const ctx = context.messageBusHandlers[sandbox.scriptName]; + let found = false; + if (ctx) { + if (typeof idOrName === 'number') { + for (const messageName in ctx) { + if (Object.prototype.hasOwnProperty.call(ctx, messageName)) { + for (let i = 0; i < ctx[messageName].length; i++) { + if (ctx[messageName][i].id === idOrName) { + ctx[messageName].splice(i, 1); + if (!ctx[messageName].length) { + delete ctx[messageName]; + sandbox.__engine.__subscriptionsMessage--; + } + found = true; + break; + } + } + } + if (found) { + break; + } + } + } + else if (idOrName && ctx[idOrName]) { + delete ctx[idOrName]; + sandbox.__engine.__subscriptionsMessage--; + found = true; + } + } + return found; + }, + console: { + log: function (msg) { + sandbox.log(msg, 'info'); + }, + error: function (msg) { + sandbox.log(msg, 'error'); + }, + warn: function (msg) { + sandbox.log(msg, 'warn'); + }, + info: function (msg) { + sandbox.log(msg, 'info'); + }, + debug: function (msg) { + sandbox.log(msg, 'debug'); + }, + }, + jsonataExpression: function (data, expression) { + return jsonata(expression).evaluate(data); + }, + wait: function (ms) { + return new Promise((resolve) => { + sandbox.setTimeout(resolve, ms); + }); + }, + sleep: function (ms) { + return sandbox.wait(ms); + }, + onObject: function (pattern, callback) { + return sandbox.subscribeObject(pattern, callback); + }, + subscribeObject: function (pattern, callback) { + if (Array.isArray(pattern)) { + const result = []; + for (let p = 0; p < pattern.length; p++) { + result.push(sandbox.subscribeObject(pattern[p], callback)); + } + return result; + } + sandbox.__engine.__subscriptionsObject += 1; + if (sandbox.__engine.__subscriptionsObject % + adapter.config.maxTriggersPerScript === + 0) { + sandbox.log(`More than ${sandbox.__engine.__subscriptionsObject} object subscriptions registered. Check your script!`, 'warn'); + } + // source is set by regexp if defined as /regexp/ + if (!pattern || typeof pattern !== 'string') { + sandbox.log('Error by subscribeObject: pattern can be only string or array of strings.', 'error'); + return null; + } + if (typeof callback !== 'function') { + sandbox.log('Error by subscribeObject: callback is not a function', 'error'); + return null; + } + const subs = { pattern, callback, name }; + if (sandbox.verbose) { + sandbox.log(`subscribeObject: ${JSON.stringify(subs)}`, 'info'); + } + adapter.subscribeForeignObjects(pattern); + context.subscriptionsObject.push(subs); + return subs; + }, + unsubscribeObject: function (subObject) { + if (subObject && Array.isArray(subObject)) { + const result = []; + for (let t = 0; t < subObject.length; t++) { + result.push(sandbox.unsubscribeObject(subObject[t])); + } + return result; + } + if (sandbox.verbose) { + sandbox.log(`adapterUnsubscribeObject(id=${JSON.stringify(subObject)})`, 'info'); + } + for (let i = context.subscriptionsObject.length - 1; i >= 0; i--) { + if (context.subscriptionsObject[i] === subObject) { + adapter.unsubscribeForeignObjects(subObject.pattern); + context.subscriptionsObject.splice(i, 1); + sandbox.__engine.__subscriptionsObject--; + return true; + } + } + let deleted = 0; + for (let i = context.subscriptionsObject.length - 1; i >= 0; i--) { + if (context.subscriptionsObject[i].name && + context.subscriptionsObject[i].pattern === subObject.pattern) { + deleted++; + adapter.unsubscribeForeignObjects(subObject.pattern); + context.subscriptionsObject.splice(i, 1); + sandbox.__engine.__subscriptionsObject--; + } + } + return !!deleted; + }, + // internal function to send the block debugging info to the front-end + _sendToFrontEnd: function (blockId, data) { + if (context.rulesOpened === sandbox.scriptName) { + adapter.setState('debug.rules', JSON.stringify({ ruleId: sandbox.scriptName, blockId, data, ts: Date.now() }), true); + } + }, + existsStateAsync: function (_id) { + return Promise.reject(new Error('Not implemented')); + }, + existsObjectAsync: function (_id) { + return Promise.reject(new Error('Not implemented')); + }, + getObjectAsync: function (_id, _enumName) { + return Promise.reject(new Error('Not implemented')); + }, + setObjectAsync: function (_id, _obj) { + return Promise.reject(new Error('Not implemented')); + }, + extendObjectAsync: function (_id, _obj) { + return Promise.reject(new Error('Not implemented')); + }, + deleteObjectAsync: function (_id, _isRecursive) { + return Promise.reject(new Error('Not implemented')); + }, + createStateAsync: function (_name, _initValue, _forceCreation, _common, _native) { + return Promise.reject(new Error('Not implemented')); + }, + createAliasAsync: function (_name, _alias, _forceCreation, _common, _native) { + return Promise.reject(new Error('Not implemented')); + }, + deleteStateAsync: function (_id) { + return Promise.reject(new Error('Not implemented')); + }, + writeFileAsync: function (_adapter, _fileName, _data) { + return Promise.reject(new Error('Not implemented')); + }, + readFileAsync: function (_adapter, _fileName) { + return Promise.reject(new Error('Not implemented')); + }, + unlinkAsync: function (_adapter, _fileName) { + return Promise.reject(new Error('Not implemented')); + }, + delFileAsync: function (_adapter, _fileName) { + return Promise.reject(new Error('Not implemented')); + }, + renameAsync: function (_adapter, _oldName, _newName) { + return Promise.reject(new Error('Not implemented')); + }, + renameFileAsync: function (_adapter, _oldName, _newName) { + return Promise.reject(new Error('Not implemented')); + }, + getHistoryAsync: function (_instance, _options) { + return Promise.reject(new Error('Not implemented')); + }, + httpGetAsync: function (_url, _options) { + return Promise.reject(new Error('Not implemented')); + }, + httpPostAsync: function (_url, _data, _options) { + return Promise.reject(new Error('Not implemented')); + }, + }; + // Create advanced functions that can modify objects + if (adapter.config.enableSetObject) { + sandbox.setObject = function (id, obj, callback) { + if (id && typeof id === 'string' && id.startsWith('system.adapter.')) { + sandbox.log(`Using setObject on system object ${id} can be dangerous (protected instance attributes may be lost)`, 'info'); + } + if (debug) { + sandbox.log(`setObject(id=${id}, obj=${JSON.stringify(obj)}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + if (typeof callback === 'function') { + setImmediate(function () { + try { + callback.call(sandbox, null, { id }); + } + catch (err) { + errorInCallback(err); + } + }); + } + } + else { + if (sandbox.verbose) { + sandbox.log(`setObject(id=${id}, obj=${JSON.stringify(obj)})`, 'info'); + } + adapter.setForeignObject(id, obj, (err, res) => { + if (!err) { + // Update meta object data + context.updateObjectContext(id, obj); + } + if (typeof callback === 'function') { + try { + callback.call(sandbox, err, res); + } + catch (err) { + errorInCallback(err); + } + } + }); + } + }; + sandbox.extendObject = function (id, obj, callback) { + if (debug) { + sandbox.log(`extendObject(id=${id}, obj=${JSON.stringify(obj)}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + if (typeof callback === 'function') { + setTimeout(function () { + try { + callback.call(sandbox, null, { id }); + } + catch (err) { + errorInCallback(err); + } + }, 0); + } + } + else { + if (sandbox.verbose) { + sandbox.log(`extendObject(id=${id}, obj=${JSON.stringify(obj)})`, 'info'); + } + adapter.extendForeignObject(id, JSON.parse(JSON.stringify(obj)), callback); + } + }; + sandbox.deleteObject = function (id, isRecursive, callback) { + if (typeof isRecursive === 'function') { + callback = isRecursive; + isRecursive = false; + } + if (debug) { + sandbox.log(`deleteObject(id=${id}) - ${words._('was not executed, while debug mode is active')}`, 'warn'); + if (typeof callback === 'function') { + setTimeout(function () { + try { + callback.call(sandbox); + } + catch (err) { + errorInCallback(err); + } + }, 0); + } + } + else { + if (sandbox.verbose) { + sandbox.log(`deleteObject(id=${id})`, 'info'); + } + adapter.delForeignObject(id, { recursive: isRecursive }, callback); + } + }; + } + // promisify methods on the sandbox + sandbox.existsStateAsync = (0, tools_1.promisify)(sandbox.existsState); + sandbox.existsObjectAsync = (0, tools_1.promisify)(sandbox.existsObject); + sandbox.getObjectAsync = (0, tools_1.promisify)(sandbox.getObject); + sandbox.setObjectAsync = (0, tools_1.promisify)(sandbox.setObject); + sandbox.extendObjectAsync = (0, tools_1.promisify)(sandbox.extendObject); + sandbox.deleteObjectAsync = (0, tools_1.promisify)(sandbox.deleteObject); + sandbox.createStateAsync = (0, tools_1.promisify)(sandbox.createState); + sandbox.createAliasAsync = (0, tools_1.promisify)(sandbox.createAlias); + sandbox.deleteStateAsync = (0, tools_1.promisify)(sandbox.deleteState); + sandbox.writeFileAsync = (0, tools_1.promisify)(sandbox.writeFile); + sandbox.readFileAsync = (0, tools_1.promisify)(sandbox.readFile); + sandbox.unlinkAsync = (0, tools_1.promisify)(sandbox.unlink); + sandbox.delFileAsync = (0, tools_1.promisify)(sandbox.delFile); + sandbox.renameAsync = (0, tools_1.promisify)(sandbox.rename); + sandbox.renameFileAsync = (0, tools_1.promisify)(sandbox.renameFile); + sandbox.getHistoryAsync = (0, tools_1.promisify)(sandbox.getHistory); + sandbox.httpGetAsync = (0, tools_1.promisify)(sandbox.httpGet); + sandbox.httpPostAsync = (0, tools_1.promisify)(sandbox.httpPost); + // Make all predefined properties and methods readonly so scripts cannot overwrite them + for (const prop of Object.keys(sandbox)) { + Object.defineProperty(sandbox, prop, { + configurable: false, + writable: false, + }); + } + return sandbox; +} +//# sourceMappingURL=sandbox.js.map \ No newline at end of file diff --git a/build-backend/lib/sandbox.js.map b/build-backend/lib/sandbox.js.map new file mode 100644 index 00000000..78112a3b --- /dev/null +++ b/build-backend/lib/sandbox.js.map @@ -0,0 +1 @@ +{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../src/lib/sandbox.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,0BA0hLC;AA9jLD,oDAAsC;AAItC,yDAAqD;AAErD,mCAA6E;AAmB7E,oDAAsC;AACtC,kDAAoC;AACpC,wDAA0C;AAC1C,uEAAkG;AAMlG,MAAM,aAAa,GAAG,0BAAW,CAAC,aAAa,CAAC;AAEhD,SAAgB,OAAO,CACnB,MAAgB,EAChB,IAAY,EACZ,OAA4B,EAC5B,KAA0B,EAC1B,OAA0B;IAE1B,MAAM,MAAM,GAAG,SAAS,CAAC;IACzB,MAAM,KAAK,GAAG,QAAQ,CAAC;IACvB,MAAM,QAAQ,GAAG,WAAW,CAAC;IAC7B,MAAM,uBAAuB,GAAG,iDAA0B,CAAC;IAC3D,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;IAEnC,MAAM,OAAO,GAAqB,OAAO,CAAC,OAAO,CAAC;IAClD,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC;IAC1B,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;IAChC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAC9B,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAEpC,wCAAwC;IACxC,IAAI,OAAoB,CAAC;IAEzB,SAAS,eAAe,CAAC,CAAQ;QAC7B,OAAO,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE;YACrE,GAAG,EAAE,IAAI;YACT,GAAG,EAAE,IAAI;YACT,CAAC,EAAE,iBAAiB;SACvB,CAAC,CAAC;QACH,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC,CAAC,CAAC;QACzC,OAAO,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,UAAU,IAAI,4BAA4B,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAChG,CAAC;IAED,SAAS,gBAAgB,CAAC,MAAgB,EAAE,OAAe;QACvD,IAAK,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,CAAC;YACxD,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC9B,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACjC,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACvC,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;gBAExC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,4BAA4B,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC;gBAChE,CAAC;gBACD,OAAO,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;gBAExC,wDAAwD;gBACxD,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxD,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;wBAC7C,IAAI,KAAK,EAAE,CAAC;4BACR,MAAM,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;wBAC5B,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,gBAAgB,CACpB,OAAO,EACP,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,CAAC,OAAO,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAC/F,CAAC;gBACN,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,CAAC;QACL,CAAC;IACL,CAAC;IAED,SAAS,kBAAkB,CAAC,MAAgB,EAAE,OAAe;QACzD,IAAK,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,CAAC;YACxD,IAAI,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7B,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC7B,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;oBAC9B,OAAO,MAAM,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;gBACtC,CAAC;YACL,CAAC;YAED,IAAI,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,CAAC;oBACvC,OAAO,CAAC,wBAAwB,CAAC,OAAO,CAAC,CAAC;oBAC1C,OAAO,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;oBAE3C,iFAAiF;oBACjF,IAAI,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC;wBAClB,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC;oBAC3B,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED,SAAS,aAAa,CAAC,MAAgB,EAAE,EAAU,EAAE,eAAuB;QACxE,MAAM,GAAG,GAAG,GAAG,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;aAAM,CAAC;YACJ,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;QACjC,CAAC;QAED,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;YACvC,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACxC,OAAO,CAAC,qBAAqB,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;QACvD,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,CAAC;IACL,CAAC;IAED,SAAS,eAAe,CAAC,MAAgB,EAAE,EAAU,EAAE,eAAuB;QAC1E,MAAM,GAAG,GAAG,GAAG,EAAE,MAAM,eAAe,EAAE,CAAC;QACzC,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC9B,OAAO,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YACtC,CAAC;QACL,CAAC;QAED,IAAI,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;YACtC,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;YACtC,IAAI,CAAC,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;gBACvC,OAAO,CAAC,uBAAuB,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;gBACrD,OAAO,OAAO,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;YAC/C,CAAC;QACL,CAAC;IACL,CAAC;IAED,SAAS,0BAA0B,CAAC,OAAgB;QAChD,IAAI,IAAiC,CAAC;QACtC,MAAM,SAAS,GAA6D,EAAE,CAAC;QAC/E,SAAS,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,KAAK,CAAC;QAEzC,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;YACxB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;gBACtD,SAAS;YACb,CAAC;YACD,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;gBAClB,SAAS;YACb,CAAC;YACD,IAAI,GAAG,KAAK,QAAQ,IAAI,OAAO,CAAC,MAAM,KAAK,KAAK,EAAE,CAAC;gBAC/C,SAAS;YACb,CAAC;YACD,MAAM,KAAK,GACP,uBACH,CAAC,GAAG,CAAC,CAAC;YACP,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,SAAS;YACb,CAAC;YACD,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC;YACtB,IAAI,OAAO,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC7B,SAAS;YACb,CAAC;YACD,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAED;;;;OAIG;IACH,SAAS,mBAAmB,CAAC,QAAgB;QACzC,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QACrC,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAClC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5B,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;YAC9C,CAAC;QACL,CAAC;QACD,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;YAClC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;YACjC,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC5B,IAAI,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACxC,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,CAAC;YAC9C,CAAC;QACL,CAAC;QAED,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACX,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/B,CAAC;QACD,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAE3B,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;IAC/C,CAAC;IAED;;;;OAIG;IACH,SAAS,sBAAsB,CAAC,GAAW;QACvC,MAAM,kBAAkB,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;QAC1C,MAAM,gBAAgB,GAAG,GAAG,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC;QAErD,yDAAyD;QACzD,uEAAuE;QACvE,0EAA0E;QAC1E,6CAA6C;QAC7C,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,uBAAuB,EAAE,MAAM,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;QAExE,OAAO,IAAI,MAAM,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,GAAG,GAAG,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7F,CAAC;IAED;;;;OAIG;IACH,SAAS,0BAA0B,CAAC,QAAkB;QAClD,IAAI,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC;YACnG,OAAO;gBACH,IAAI,EAAE,QAAQ,CAAC,IAAI;gBACnB,KAAK,EAAE,QAAQ,CAAC,KAAK;gBACrB,QAAQ,EAAE,sBAAsB,CAAC,QAAQ,CAAC,KAAK,CAAC;aACnD,CAAC;QACN,CAAC;QACD,OAAO,QAAQ,CAAC;IACpB,CAAC;IAED;;;;;;;OAOG;IACH,SAAS,mBAAmB,CAAC,KAA4C,EAAE,SAAiB;QACxF,kDAAkD;QAClD,wCAAwC;QACxC,OAAO,OAAO,KAAK,KAAK,SAAS;YAC7B,CAAC,CAAC,CAAC,KAAK,IAAI,SAAS,KAAK,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,SAAS,KAAK,OAAO,CAAC;YACtE,CAAC,CAAC,KAAK,IAAI,SAAS,CAAC;IAC7B,CAAC;IAED;;OAEG;IACH,SAAS,eAAe,CAAC,KAAU;QAC/B,OAAO,IAAA,eAAO,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAE,OAAO,KAA6B,CAAC;IACzG,CAAC;IAED;;;;OAIG;IACH,SAAS,iCAAiC,CAAC,EAAU;QACjD,OAAO,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;IACvG,CAAC;IAED;;OAEG;IACH,KAAK,UAAU,qBAAqB,CAAC,EAAU;QAC3C,IAAI,CAAC,iCAAiC,CAAC,EAAE,CAAC,EAAE,CAAC;YACzC,OAAO;QACX,CAAC;QACD,IAAI,OAAO,CAAC,6BAA6B,CAAC,EAAE,CAAC,KAAK,IAAI,EAAE,CAAC;YACrD,OAAO;QACX,CAAC;QACD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5B,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,8CAA8C;QAC3D,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACnB,OAAO,CAAC,gBAAgB;QAC5B,CAAC;QACD,mCAAmC;QACnC,IAAI,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE7C,OAAO,CAAC,6BAA6B,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QACjD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACvB,SAAS,IAAI,IAAI,IAAI,EAAE,CAAC;YACxB,IAAI,OAAO,CAAC,6BAA6B,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBAClF,SAAS;YACb,CAAC;YACD,OAAO,CAAC,6BAA6B,CAAC,SAAS,CAAC,GAAG,IAAI,CAAC;YACxD,IAAI,GAAuC,CAAC;YAC5C,IAAI,CAAC;gBACD,GAAG,GAAG,MAAM,OAAO,CAAC,qBAAqB,CAAC,SAAS,CAAC,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC;gBACL,SAAS;YACb,CAAC;YACD,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC;gBACf,OAAO,CAAC,GAAG,CAAC,4BAA4B,SAAS,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC9D,IAAI,CAAC;oBACD,MAAM,OAAO,CAAC,qBAAqB,CAAC,SAAS,EAAE;wBAC3C,GAAG,EAAE,SAAS;wBACd,IAAI,EAAE,QAAQ;wBACd,MAAM,EAAE;4BACJ,IAAI,EAAE,IAAI;yBACb;wBACD,MAAM,EAAE;4BACJ,WAAW,EAAE,2BAA2B;yBAC3C;qBACqB,CAAC,CAAC;gBAChC,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAChB,OAAO,CAAC,GAAG,CAAC,gDAAgD,SAAS,KAAK,GAAG,CAAC,OAAO,EAAE,EAAE,MAAM,CAAC,CAAC;gBACrG,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,sFAAsF;YAC1F,CAAC;QACL,CAAC;IACL,CAAC;IAED,SAAS,cAAc,CACnB,OAAoB,EACpB,QAAiB,EACjB,SAAkB,EAClB,EAAU,EACV,KAA0D,EAC1D,KAAgF,EAChF,QAAyC;QAEzC,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;YAC9B,QAAQ,GAAG,KAAK,CAAC;YACjB,KAAK,GAAG,SAAS,CAAC;QACtB,CAAC;QAED,IAAI,YAA0D,CAAC;QAE/D,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,KAAK,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YAC7E,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;gBAChE,YAAY,GAAG,KAAK,CAAC;gBACrB,iDAAiD;gBACjD,oDAAoD;gBACpD,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC;oBACtD,YAAY,CAAC,GAAG,GAAG,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,CAAC;gBAC1D,CAAC;YACL,CAAC;iBAAM,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACxB,YAAY,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,EAAE,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1E,CAAC;iBAAM,CAAC;gBACJ,gEAAgE;gBAChE,YAAY,GAAG,EAAE,GAAG,EAAE,KAA4B,EAAE,GAAG,EAAE,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,EAAE,CAAC;YAClG,CAAC;QACL,CAAC;aAAM,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;YACxB,YAAY,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QACjC,CAAC;aAAM,CAAC;YACJ,YAAY,GAAG,KAAK,CAAC;QACzB,CAAC;QAED,wBAAwB;QACxB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;YACxD,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;QACtC,CAAC;QAED,IAAI,QAAQ,EAAE,CAAC;YACX,IAAI,EAAE,CAAC,KAAK,CAAC,iCAAiC,CAAC,EAAE,CAAC;gBAC9C,OAAO,CAAC,GAAG,CACP,eAAe,EAAE,gGAAgG,EACjH,MAAM,CACT,CAAC;YACN,CAAC;iBAAM,IAAI,EAAE,CAAC,KAAK,CAAC,iCAAiC,CAAC,EAAE,CAAC;gBACrD,OAAO,CAAC,GAAG,CACP,eAAe,EAAE,gGAAgG,EACjH,MAAM,CACT,CAAC;YACN,CAAC;QACL,CAAC;QAED,MAAM,MAAM,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC;QACvD,IAAI,MAAM,EAAE,IAAI,IAAI,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,MAAM,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACpE,oCAAoC;YACpC,IAAI,gBAAiD,CAAC;YACtD,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;gBACnC,IAAI,YAAY,IAAI,YAAY,CAAC,GAAG,KAAK,SAAS,IAAI,YAAY,CAAC,GAAG,KAAK,IAAI,EAAE,CAAC;oBAC9E,gBAAgB,GAAG,eAAe,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;gBACzD,CAAC;YACL,CAAC;iBAAM,IAAI,YAAY,KAAK,IAAI,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAC7D,gBAAgB,GAAG,eAAe,CAAC,YAAY,CAAC,CAAC;YACrD,CAAC;YACD,mDAAmD;YACnD,IAAI,gBAAgB,IAAI,gBAAgB,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;gBACvD,OAAO,CAAC,eAAe,CACnB,uBAAuB,gBAAgB,kBAAkB,EAAE,qBAAqB,MAAM,CAAC,IAAI,IAAI;oBAC3F,iCAAiC,MAAM,CAAC,IAAI,gCAAgC,gBAAgB,IAAI;oBAChG,wDAAwD,CAC/D,CAAC;YACN,CAAC;YAED,IAAI,gBAAgB,KAAK,OAAO,IAAI,gBAAgB,KAAK,QAAQ,EAAE,CAAC;gBAChE,IAAI,CAAC;oBACD,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,OAAO,YAAY,CAAC,GAAG,KAAK,WAAW,EAAE,CAAC;wBAC9E,YAAY,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;oBACxD,CAAC;yBAAM,CAAC;wBACJ,YAAY,GAAG,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;oBAChD,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAChB,OAAO,CAAC,eAAe,CACnB,sCAAsC,gBAAgB,WAAW,EAAE,KAAK,GAAG,CAAC,OAAO,EAAE,CACxF,CAAC;oBACF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CACT,OAAO,EACP,IAAI,KAAK,CACL,sCAAsC,gBAAgB,WAAW,EAAE,KAAK,GAAG,CAAC,OAAO,EAAE,CACxF,CACJ,CAAC;wBACN,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QACD,6BAA6B;QAC7B,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACnC,IAAI,MAAM,IAAI,OAAO,YAAY,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACjD,MAAM,GAAG,GAAW,YAAY,CAAC,GAAG,CAAC;gBACrC,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;oBAC/C,YAAY,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;gBAClC,CAAC;qBAAM,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;oBACtD,YAAY,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;gBAClC,CAAC;YACL,CAAC;QACL,CAAC;aAAM,IAAI,MAAM,IAAI,OAAO,YAAY,KAAK,QAAQ,EAAE,CAAC;YACpD,MAAM,GAAG,GAAW,YAAY,CAAC;YACjC,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;gBAC/C,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC;YAC9B,CAAC;YACD,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,MAAM,CAAC,GAAG,EAAE,CAAC;gBAC/C,YAAY,GAAG,MAAM,CAAC,GAAG,CAAC;YAC9B,CAAC;QACL,CAAC;QAED,IAAI,aAA6B,CAAC;QAClC,sDAAsD;QACtD,IACI,YAAY,KAAK,IAAI;YACrB,OAAO,YAAY,KAAK,QAAQ;YAC/B,YAAuC,CAAC,GAAG,KAAK,SAAS,EAC5D,CAAC;YACC,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,EAAE,EAAE;gBAC3C,GAAG,EAAE,YAAmC;gBACxC,GAAG,EAAE,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM;aAC1C,CAAC,CAAC;QACP,CAAC;aAAM,CAAC;YACJ,aAAa,GAAG,OAAO,CAAC,kBAAkB,CAAC,EAAE,EAAE,YAAsC,CAAC,CAAC;QAC3F,CAAC;QAED,wDAAwD;QACxD,aAAa,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,CAAC;QAErC,IAAI,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YACd,MAAM,CAAC,wBAAwB,EAAE,CAAC;YAClC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,WAAW,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC7F,CAAC;YAED,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,sBAAsB,EAAE,WAAW,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EAChI,MAAM,CACT,CAAC;gBAEF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,YAAY,CAAC,GAAG,EAAE;wBACd,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBAC3B,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAE,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,CAAC;oBACzD,mEAAmE;oBACnE,4DAA4D;oBAC5D,mEAAmE;oBACnE,IAAI,CAAC,SAAS,EAAE,CAAC;wBACb,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC;oBACnD,CAAC;gBACL,CAAC;gBACD,MAAM,UAAU,GAAG,CAAC,GAA6B,EAAE,MAAc,EAAQ,EAAE;oBACvE,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,MAAM,KAAK,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;oBACjD,8BAA8B;oBAC9B,IAAI,GAAG,IAAI,CAAE,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,CAAC;wBAChE,OAAO,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;oBAC1C,CAAC;oBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,YAAY,CAAC,GAAG,EAAE;4BACd,IAAI,CAAC;gCACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;4BAC3B,CAAC;4BAAC,OAAO,GAAY,EAAE,CAAC;gCACpB,eAAe,CAAC,GAAY,CAAC,CAAC;4BAClC,CAAC;wBACL,CAAC,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC,CAAC;gBACF,IAAI,SAAS,EAAE,CAAC;oBACZ,IAAI,CAAE,OAAO,CAAC,MAAkC,CAAC,SAAS,IAAI,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;wBAC3F,sEAAsE;wBACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;wBAChD,MAAM,KAAK,GAAa,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,CACrD,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,IAAI,IAAK,aAAqC,CAAC,IAAI,CAAC,KAAK,SAAS,CACtF,CAAC;wBACF,IACI,CAAC,KAAK,CAAC,KAAK,CACR,IAAI,CAAC,EAAE,CACF,aAAqC,CAAC,IAAI,CAAC;4BAC3C,QAAgC,CAAC,IAAI,CAAC,CAC9C,EACH,CAAC;4BACC,8DAA8D;4BAC9D,4CAA4C;4BAC5C,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC;4BAC/C,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC;wBAC1F,CAAC;6BAAM,CAAC;4BACJ,kEAAkE;4BAClE,UAAU,CAAC,IAAI,EAAE,uBAAuB,CAAC,CAAC;wBAC9C,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACJ,wGAAwG;wBACxG,OAAO,CAAC,sBAAsB,CAAC,EAAE,EAAE,EAAE,GAAG,aAAa,EAAE,EAAE,EAAE,SAAS,EAAE,EAAE,GAAG,CAAC,EAAE,CAC1E,UAAU,CAAC,GAAG,EAAE,wBAAwB,CAAC,CAC5C,CAAC;oBACN,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,aAAa,EAAE,GAAG,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,EAAE,iBAAiB,CAAC,CAAC,CAAC;gBAC1F,CAAC;YACL,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,eAAe,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC;YACnD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,YAAY,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,UAAU,EAAE,aAAa,CAAC,CAAC,CAAC;oBACjE,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,GAAG;QACN,IAAI;QACJ,GAAG,EAAE,MAAM,CAAC,GAAG;QACf,6BAA6B;QAC7B,IAAI;QACJ,UAAU,EAAE,IAAI;QAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ,IAAI,CAAC;QAC/B,cAAc,EAAE,OAAO,CAAC,yBAAyB,EAAE;QACnD,OAAO;QACP,OAAO,EAAE,EAAE,EAAE,uDAAuD;QACpE,OAAO,EAAE,UAAU,EAAU;YACzB,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBACnD,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAClC,CAAC;YAED,IAAI,EAAE,KAAK,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBACtD,OAAO,CAAC,GAAG,CACP,0FAA0F,EAC1F,MAAM,CACT,CAAC;oBACF,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACnD,CAAC;YACL,CAAC;YAED,IAAI,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;gBACX,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC;YAED,IAAI,KAAwB,CAAC;YAE7B,IAAI,CAAC;gBACD,IAAI,CAAC,EAAE,CAAC,GAAG,OAAO,CACd,OAAO,CAAC,iCAAiC,CAAC,CAAC,CAAC,OAAO,CAAC,iCAAiC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CACjG,CAAC;gBACF,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBACd,KAAK,GAAG,CAAU,CAAC;YACvB,CAAC;YAED,IAAI,CAAC;gBACD,mFAAmF;gBACnF,qJAAqJ;gBACrJ,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,0BAA0B,EAAE,mDAAmD,CAAC,CAAC;gBACnG,IAAI,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC;gBAEvB,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC;YAAC,OAAO,CAAM,EAAE,CAAC;gBACd,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACtC,OAAO,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE;oBACrE,GAAG,EAAE,IAAI;oBACT,GAAG,EAAE,IAAI;oBACT,CAAC,EAAE,SAAS;iBACf,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QACD,MAAM,EAAE,MAAM;QACd,QAAQ,EAAE;YACN,oBAAoB,EAAE,EAAE;YACxB,qBAAqB,EAAE,CAAC;YACxB,eAAe,EAAE,CAAC;YAClB,sBAAsB,EAAE,CAAC;YACzB,mBAAmB,EAAE,CAAC;YACtB,kBAAkB,EAAE,CAAC;YACrB,WAAW,EAAE,CAAC;SACjB;QAED,CAAC,EAAE,UAAU,QAAgB;YACzB,yBAAyB;YACzB,kHAAkH;YAClH,uCAAuC;YACvC,oEAAoE;YACpE,+FAA+F;YAC/F,kEAAkE;YAClE,wCAAwC;YACxC,wFAAwF;YACxF,iFAAiF;YACjF,EAAE;YACF,mFAAmF;YAEnF,gBAAgB;YAEhB,MAAM,MAAM,GAAsB,EAAuB,CAAC;YAE1D,IAAI,IAAI,GAAG,EAAE,CAAC;YACd,MAAM,aAAa,GAAa,EAAE,CAAC;YACnC,MAAM,WAAW,GAAa,EAAE,CAAC;YACjC,MAAM,aAAa,GAAa,EAAE,CAAC;YACnC,IAAI,YAAY,GAAG,IAAI,CAAC;YACxB,IAAI,oBAAoB,GAAG,KAAK,CAAC;YACjC,IAAI,kBAAkB,GAAG,KAAK,CAAC;YAC/B,IAAI,oBAAoB,GAAG,KAAK,CAAC;YACjC,IAAI,mBAAmB,GAAG,EAAE,CAAC;YAC7B,IAAI,mBAAmB,GAAG,EAAE,CAAC;YAC7B,IAAI,iBAAiB,GAAG,EAAE,CAAC;YAE3B,eAAe;YACf,IAAI,sBAAsB,GAAG,KAAK,CAAC;YACnC,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACvC,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;wBACtB,YAAY,GAAG,KAAK,CAAC;wBACrB,IAAI,oBAAoB,IAAI,kBAAkB,IAAI,oBAAoB,EAAE,CAAC;4BACrE,QAAQ;4BACR,MAAM;wBACV,CAAC;wBACD,oBAAoB,GAAG,IAAI,CAAC;oBAChC,CAAC;yBAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;wBAC7B,oBAAoB,GAAG,KAAK,CAAC;wBAC7B,aAAa,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;wBACxC,mBAAmB,GAAG,EAAE,CAAC;oBAC7B,CAAC;yBAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;wBAC7B,YAAY,GAAG,KAAK,CAAC;wBACrB,IAAI,oBAAoB,IAAI,kBAAkB,IAAI,oBAAoB,EAAE,CAAC;4BACrE,QAAQ;4BACR,MAAM;wBACV,CAAC;wBACD,oBAAoB,GAAG,IAAI,CAAC;oBAChC,CAAC;yBAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;wBAC7B,oBAAoB,GAAG,KAAK,CAAC;wBAC7B,aAAa,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;wBACxC,mBAAmB,GAAG,EAAE,CAAC;oBAC7B,CAAC;yBAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;wBAC7B,YAAY,GAAG,KAAK,CAAC;wBACrB,IAAI,oBAAoB,IAAI,kBAAkB,IAAI,oBAAoB,EAAE,CAAC;4BACrE,QAAQ;4BACR,MAAM;wBACV,CAAC;wBACD,kBAAkB,GAAG,IAAI,CAAC;oBAC9B,CAAC;yBAAM,IAAI,QAAQ,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;wBAC7B,kBAAkB,GAAG,KAAK,CAAC;wBAC3B,WAAW,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;wBACpC,iBAAiB,GAAG,EAAE,CAAC;oBAC3B,CAAC;yBAAM,IAAI,YAAY,EAAE,CAAC;wBACtB,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;oBACxB,CAAC;yBAAM,IAAI,oBAAoB,EAAE,CAAC;wBAC9B,mBAAmB,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;oBACvC,CAAC;yBAAM,IAAI,kBAAkB,EAAE,CAAC;wBAC5B,iBAAiB,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;oBACrC,CAAC;yBAAM,IAAI,oBAAoB,EAAE,CAAC;wBAC9B,mBAAmB,IAAI,QAAQ,CAAC,CAAC,CAAC,CAAC;oBACvC,CAAC,CAAC,QAAQ;oBACV,aAAa;oBACb,GAAG;gBACP,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,sBAAsB,GAAG,IAAI,CAAC;YAClC,CAAC;YAED,gCAAgC;YAChC,IAAI,sBAAsB,IAAI,kBAAkB,IAAI,oBAAoB,IAAI,oBAAoB,EAAE,CAAC;gBAC/F,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;gBAClB,MAAM,CAAC,OAAO,GAAG;oBACb,OAAO,EAAE,CAAC;gBACd,CAAC,CAAC;gBACF,MAAM,CAAC,IAAI,GAAG;oBACV,OAAO,IAAI,CAAC;gBAChB,CAAC,CAAC;gBACF,MAAM,CAAC,QAAQ,GAAG;oBACd,OAAO,IAAI,CAAC;gBAChB,CAAC,CAAC;gBACF,MAAM,CAAC,QAAQ,GAAG;oBACd,OAAO,IAAI,CAAC;gBAChB,CAAC,CAAC;gBACF,MAAM,CAAC,EAAE,GAAG;oBACR,OAAO,IAAI,CAAC;gBAChB,CAAC,CAAC;YACN,CAAC;YAED,IAAI,kBAAkB,EAAE,CAAC;gBACrB,OAAO,CAAC,GAAG,CAAC,gEAAgE,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;gBACjG,MAAM,CAAC,KAAK,GAAG,0DAA0D,CAAC;gBAC1E,OAAO,MAAM,CAAC;YAClB,CAAC;iBAAM,IAAI,oBAAoB,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,kEAAkE,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;gBACnG,MAAM,CAAC,KAAK,GAAG,4DAA4D,CAAC;gBAC5E,OAAO,MAAM,CAAC;YAClB,CAAC;iBAAM,IAAI,oBAAoB,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CAAC,kEAAkE,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;gBACnG,MAAM,CAAC,KAAK,GAAG,4DAA4D,CAAC;gBAC5E,OAAO,MAAM,CAAC;YAClB,CAAC;iBAAM,IAAI,sBAAsB,EAAE,CAAC;gBAChC,MAAM,OAAO,GAAG,8DAA8D,OAAO,QAAQ,EAAE,CAAC;gBAChG,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAC7B,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC;gBACvB,OAAO,MAAM,CAAC;YAClB,CAAC;YAED,IAAI,eAAe,GAAe,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC/F,IAAI,eAAe,GAAe,aAAa,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,mBAAmB,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC/F,MAAM,mBAAmB,GAAe,WAAW,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7F,MAAM,YAAY,GAAe,eAAe,CAAC,MAAM,CAAC,eAAe,EAAE,mBAAmB,CAAC,CAAC;YAE9F,+FAA+F;YAC/F,sCAAsC;YACtC,MAAM,gBAAgB,GAAe,YAAY;iBAC5C,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,CAAC;iBAChD,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3D,MAAM,iBAAiB,GAAe,YAAY;iBAC7C,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC;iBAC1C,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,0BAA0B,CAAC,QAAQ,CAAC,CAAC,CAAC;YAC3D,eAAe,GAAG,eAAe,CAAC,MAAM,CACpC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,CACrE,CAAC;YACF,eAAe,GAAG,eAAe,CAAC,MAAM,CACpC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,CACrE,CAAC;YACF,MAAM,aAAa,GAAa,mBAAmB;iBAC9C,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,KAAK,UAAU,IAAI,QAAQ,CAAC,IAAI,KAAK,IAAI,CAAC;gBAC3E,2EAA2E;iBAC1E,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,QAAQ,CAAC,IAAI,IAAI,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC;YAEhE,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAEnB,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1C,0EAA0E;gBAC1E,qCAAqC;gBACrC,IAAI,CAAC,OAAO,CAAC,QAAQ,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;oBACxC,OAAO,CAAC,QAAQ,GAAG,EAAE,CAAC;oBACtB,OAAO,CAAC,OAAO,GAAG,EAAE,CAAC;oBACrB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;wBACxB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;4BACtF,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;4BAC7B,KAAK,CAAC,GAAG,EAAE,CAAC;4BACZ,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;4BAE5B,KAAK,CAAC,GAAG,EAAE,CAAC;4BACZ,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;4BAE5B,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;4BAClD,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;4BAE/B,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;4BACpD,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBACpC,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;YAED,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBACtB,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;oBACrB,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC;oBACvB,KAAK,MAAM,GAAG,IAAI,OAAO,EAAE,CAAC;wBACxB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;4BACzF,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;wBAChC,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;YAED;;eAEG;YACH,SAAS,gBAAgB,CAAC,KAAa,EAAE,SAAqB;gBAC1D,mDAAmD;gBACnD,OAAO,SAAS,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;YAC5F,CAAC;YAED;;;;eAIG;YACH,SAAS,oBAAoB,CAAC,KAAa;gBACvC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC3B,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC;oBACf,OAAO,KAAK,CAAC;gBACjB,CAAC;gBACD,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC;gBAE7B,gDAAgD;gBAChD,OAAO,eAAe,CAAC,KAAK,CACxB,QAAQ,CAAC,EAAE;gBACP,2BAA2B;gBAC3B,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC;oBACxE,wBAAwB;oBACxB,mBAAmB,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CACpE,CAAC;YACN,CAAC;YAED;;;;eAIG;YACH,SAAS,oBAAoB,CAAC,KAAa;gBACvC,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;gBAC3B,IAAI,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;oBACtB,OAAO,KAAK,CAAC;gBACjB,CAAC;gBACD,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAAC;gBAC7B,gDAAgD;gBAChD,OAAO,eAAe,CAAC,KAAK,CACxB,QAAQ,CAAC,EAAE;gBACP,2BAA2B;gBAC3B,CAAC,QAAQ,CAAC,KAAK,KAAK,SAAS,IAAI,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,SAAS,CAAC;oBACxE,wBAAwB;oBACxB,mBAAmB,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,QAAQ,CAAC,KAAK,CAAC,CACpE,CAAC;YACN,CAAC;YAED;;;;eAIG;YACH,SAAS,kBAAkB,CAAC,KAAa;gBACrC,MAAM,OAAO,GAAa,EAAE,CAAC;gBAC7B,QAAQ,CAAC,kBAAkB,CAAC,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;gBACrD,gDAAgD;gBAChD,OAAO,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;YACjE,CAAC;YAED,IAAI,GAAa,CAAC;YAElB,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;gBACtB,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,CAAC;gBAC9B,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;oBAC3B,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC;gBAClF,CAAC;gBAED,0DAA0D;gBAC1D,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrD,CAAC;gBAED,0DAA0D;gBAC1D,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrD,CAAC;gBAED,wDAAwD;gBACxD,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;oBACvB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;gBACjE,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC5B,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;oBACpB,iGAAiG;gBACrG,CAAC;gBACD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;gBAExC,0BAA0B;gBAC1B,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC5B,yEAAyE;gBACzE,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;oBAC3B,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,gBAAgB,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC,CAAC;gBAClF,CAAC;gBACD,0DAA0D;gBAC1D,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC;gBACnE,CAAC;gBACD,0DAA0D;gBAC1D,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC,CAAC;gBACnE,CAAC;gBACD,wDAAwD;gBACxD,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;oBACvB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC,kBAAkB,CAAC,SAAS,CAAC,CAAC,CAAC;gBACjE,CAAC;gBAED,8DAA8D;gBAC9D,GAAG,GAAG,GAAG;qBACJ,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;oBACxB,kDAAkD;qBACjD,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;gBAEjD,2EAA2E;gBAC3E,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC;oBAC1B,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;gBAC7E,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;oBACnB,gGAAgG;gBACpG,CAAC;gBAED,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,EAAE,CAAC;gBAEtC,yBAAyB;gBACzB,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;gBAC3B,yEAAyE;gBACzE,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;oBAC3B,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,gBAAgB,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC,CAAC;gBAChF,CAAC;gBAED,0DAA0D;gBAC1D,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACjE,CAAC;gBAED,0DAA0D;gBAC1D,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC,CAAC;gBACjE,CAAC;gBAED,wDAAwD;gBACxD,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;oBACvB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,kBAAkB,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC/D,CAAC;gBAED,6DAA6D;gBAC7D,GAAG,GAAG,GAAG;qBACJ,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBACvB,kDAAkD;qBACjD,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;gBAEjD,2EAA2E;gBAC3E,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC;oBAC1B,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,gBAAgB,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC;gBAC7E,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,wBAAwB;gBACxB,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC;gBACvB,gEAAgE;gBAChE,IAAI,IAAI,IAAI,IAAI,KAAK,OAAO,EAAE,CAAC;oBAC3B,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC7E,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACvC,CAAC;gBAED,wFAAwF;gBACxF,IAAI,iBAAiB,CAAC,MAAM,EAAE,CAAC;oBAC3B,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,iBAAiB,CAAC,CAAC,CAAC;gBACpE,CAAC;gBAED,uEAAuE;gBACvE,IAAI,gBAAgB,CAAC,MAAM,EAAE,CAAC;oBAC1B,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC;gBACnE,CAAC;gBAED,0DAA0D;gBAC1D,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrD,CAAC;gBAED,0DAA0D;gBAC1D,IAAI,eAAe,CAAC,MAAM,EAAE,CAAC;oBACzB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrD,CAAC;gBAED,wDAAwD;gBACxD,IAAI,aAAa,CAAC,MAAM,EAAE,CAAC;oBACvB,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;gBACnD,CAAC;YACL,CAAC;YAED,MAAM,SAAS,GAAa,EAAE,CAAC;YAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAClC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC9B,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC3B,CAAC;YACL,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxC,MAAM,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC7B,CAAC;YACD,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC;YAEjC,4EAA4E;YAC5E,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;gBAC/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACrC,MAAM,MAAM,CAAC,CAAC,CAAC,CAAC;gBACpB,CAAC;YACL,CAAC,CAAC;YACF,MAAM,CAAC,OAAO,GAAG;gBACb,OAAO,CAAC,GAAG,SAAS,CAAC,CAAC;YAC1B,CAAC,CAAC;YACF,MAAM,CAAC,IAAI,GAAG,UAAU,QAAqD;gBACzE,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAiB,CAAC;oBACtB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACnC,CAAC,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBAC3B,IAAI,CAAC,KAAK,KAAK,EAAE,CAAC;4BACd,MAAM;wBACV,CAAC;oBACL,CAAC;gBACL,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC,CAAC;YACF,6BAA6B;YAC7B,MAAM,CAAC,QAAQ,GAAG,UACd,QAAoC;gBAEpC,IAAK,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,CAAC;oBACxD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,OAAO,CAAC,GAAG,CAAC,0CAA0C,EAAE,OAAO,CAAC,CAAC;oBACrE,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,eAAe,CACnB,IAAI,CAAC,CAAC,CAAC,EACP,CAAC,GAA6B,EAAE,KAA6B,EAAQ,EAAE;4BACnE,QAAQ,CACJ,GAAG,EACH,OAAO,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAE5B,CAC1B,CAAC;wBACN,CAAC,CACJ,CAAC;oBACN,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;wBACX,OAAO,IAAI,CAAC;oBAChB,CAAC;oBACD,IAAI,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;wBACpD,OAAO,OAAO,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAEjE,CAAC;oBAC5B,CAAC;oBACD,OAAO,OAAO,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAE7C,CAAC;gBAC5B,CAAC;YACL,CAAC,CAAC;YACF,MAAM,CAAC,aAAa,GAAG,KAAK;gBAGxB,IAAK,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,CAAC;oBACxD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC1D,OAAO,OAAO,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,CAGhD,CAAC;gBACf,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACX,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,IAAI,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;oBACpD,OAAO,OAAO,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAG9E,CAAC;gBACf,CAAC;gBACD,OAAO,OAAO,CAAC,4BAA4B,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAG1D,CAAC;YACf,CAAC,CAAC;YACF,MAAM,CAAC,QAAQ,GAAG,UACd,KAAmD,EACnD,KAAkE,EAClE,QAAiC;gBAEjC,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;oBAC9B,QAAQ,GAAG,KAAK,CAAC;oBACjB,KAAK,GAAG,SAAS,CAAC;gBACtB,CAAC;gBACD,MAAM;qBACD,aAAa,CAAC,KAAK,EAAE,KAAmC,CAAC;qBACzD,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,EAAE,CAAC,CAAC;gBAC9D,OAAO,IAAI,CAAC;YAChB,CAAC,CAAC;YACF,MAAM,CAAC,aAAa,GAAG,KAAK,WACxB,KAAmD,EACnD,KAAe;gBAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACnC,MAAM,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;gBACvD,CAAC;YACL,CAAC,CAAC;YACF,MAAM,CAAC,eAAe,GAAG,UACrB,KAAmD,EACnD,KAAe,EACf,QAAqB;gBAErB,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;oBAC9B,QAAQ,GAAG,KAAK,CAAC;oBACjB,KAAK,GAAG,SAAS,CAAC;gBACtB,CAAC;gBACD,MAAM,CAAC,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,EAAE,CAAC,CAAC;gBACnG,OAAO,IAAI,CAAC;YAChB,CAAC,CAAC;YACF,MAAM,CAAC,oBAAoB,GAAG,KAAK,WAC/B,KAAmD,EACnD,KAAe;gBAEf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACnC,MAAM,OAAO,CAAC,oBAAoB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;gBAC9D,CAAC;YACL,CAAC,CAAC;YACF,MAAM,CAAC,eAAe,GAAG,UACrB,KAAmD,EACnD,KAAmC,EACnC,KAAwB,EACxB,YAAqC,EACrC,QAAqB;gBAErB,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC7B,QAAQ,GAAG,YAA0B,CAAC;oBACtC,YAAY,GAAG,KAAgB,CAAC;oBAChC,KAAK,GAAG,KAAe,CAAC;oBACxB,KAAK,GAAG,SAAS,CAAC;gBACtB,CAAC;gBACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;oBAC5B,QAAQ,GAAG,YAA0B,CAAC;oBACtC,YAAY,GAAG,KAAK,CAAC;oBACrB,KAAK,GAAG,CAAC,CAAC;gBACd,CAAC;gBACD,IAAI,OAAO,YAAY,KAAK,SAAS,EAAE,CAAC;oBACpC,QAAQ,GAAG,YAAY,CAAC;oBACxB,YAAY,GAAG,IAAI,CAAC;gBACxB,CAAC;gBACD,IAAI,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC;gBACxB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACnC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAgB,EAAE,KAAK,EAAE,YAAY,EAAE,GAAG,EAAE;wBAChF,IAAI,CAAC,EAAE,KAAK,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;4BAC7C,QAAQ,EAAE,CAAC;wBACf,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC,CAAC;YACF,MAAM,CAAC,EAAE,GAAG,UAAU,YAA4C,EAAE,KAAW;gBAC3E,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACnC,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;gBACpD,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC,CAAC;YACF,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,GAAG,EAAE,UAAU,GAAW,EAAE,QAA4B;YACpD,QAAQ,GAAG,QAAQ,IAAI,MAAM,CAAC;YAE9B,qDAAqD;YACrD,IAAI,OAAO,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,QAAQ,IAAI,OAAO,CAAC,UAAU,KAAK,GAAG,CAAC,EAAE,CAAC;gBACxF,OAAO;YACX,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,GAAG,GAAG,2BAA2B,QAAQ,gBAAgB,GAAG,GAAG,CAAC;gBAChE,QAAQ,GAAG,MAAM,CAAC;YACtB,CAAC;YAED,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBACjC,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YAChC,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACZ,OAAO,CAAC,GAAG,CAAC,GAAG,QAAQ,KAAK,IAAI,KAAK,GAAG,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YAC5D,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,GAAG,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;YAC7C,CAAC;QACL,CAAC;QACD,KAAK,EAAE,UAAU,QAA2B,EAAE,QAAoC;YAC9E,IAAI,CAAC,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACvE,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;gBACtD,OAAO,CAAC,CAAC;YACb,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,MAAM,CAAC,CAAC;gBAClD,OAAO,CAAC,CAAC;YACb,CAAC;YAED,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;YACxG,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YAClG,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAC3D,OAAO,CAAC,sBAAsB,EAAE,CAAC;YAEjC,OAAO,CAAC,QAAQ,CAAC,kBAAkB,IAAI,CAAC,CAAC;YAEzC,OAAO,CAAC,OAAO;gBACX,OAAO,CAAC,GAAG,CACP,kBAAkB,QAAQ,QAAQ,OAAO,CAAC,EAAE,wBAAwB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EACzG,MAAM,CACT,CAAC;YAEN,IACI,OAAO,CAAC,QAAQ,CAAC,kBAAkB;gBAC9B,OAAO,CAAC,MAAkC,CAAC,oBAAoB;gBACpE,CAAC,EACH,CAAC;gBACC,OAAO,CAAC,GAAG,CACP,aAAa,OAAO,CAAC,QAAQ,CAAC,kBAAkB,mDAAmD,EACnG,MAAM,CACT,CAAC;YACN,CAAC;YAED,OAAO,OAAO,CAAC,EAAE,CAAC;QACtB,CAAC;QACD,eAAe,EAAE,UACb,sBAAiF;YAEjF,IAAI,KAAK,GAAG,KAAK,CAAC;YAElB,IAAI,OAAO,CAAC,gBAAgB,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBACjD,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CACP,0CAA0C,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,wBAAwB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,EAAE,EAC7I,MAAM,CACT,CAAC;gBAEN,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC3E,IACI,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,sBAAsB;wBAC7E,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,sBAAsB;wBAC7E,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,KAAK,sBAAsB,EACrF,CAAC;wBACC,OAAO,CAAC,OAAO;4BACX,OAAO,CAAC,GAAG,CACP,0CAA0C,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,iBAAiB,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EACtJ,MAAM,CACT,CAAC;wBAEN,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBAC1D,CAAC,EAAE,CAAC;wBACJ,OAAO,CAAC,QAAQ,CAAC,kBAAkB,EAAE,CAAC;wBAEtC,KAAK,GAAG,IAAI,CAAC;wBAEb,qBAAqB;wBACrB,IAAI,OAAO,sBAAsB,KAAK,QAAQ,EAAE,CAAC;4BAC7C,MAAM;wBACV,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,OAAO;4BACX,OAAO,CAAC,GAAG,CACP,0CAA0C,IAAI,CAAC,SAAS,CAAC,sBAAsB,CAAC,WAAW,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,gBAAgB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAC5J,MAAM,CACT,CAAC;oBACV,CAAC;gBACL,CAAC;YACL,CAAC;YAED,OAAO,CAAC,sBAAsB,EAAE,CAAC;YAEjC,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,IAAI,EAAE,UACF,GAAW,EACX,OAAkG,EAClG,QAAmF;YAEnF,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,QAAQ,GAAG,OAAmF,CAAC;gBAC/F,OAAO,GAAG,EAAE,CAAC;YACjB,CAAC;YACD,IAAI,CAAE,OAAO,CAAC,MAAkC,CAAC,UAAU,EAAE,CAAC;gBAC1D,MAAM,KAAK,GAAG,gFAAgF,CAAC;gBAC/F,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBAE5B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,YAAY,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;gBACxD,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,YAAY,GAAG,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC5C,CAAC;gBAED,IAAI,KAAK,EAAE,CAAC;oBACR,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,yDAAyD,EAAE,GAAG,CAAC,EAAE,MAAM,CAAC,CAAC;oBAC7F,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,YAAY,CAAC;4BACT,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;wBAC3B,CAAC,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,OAAO,IAAI,CAAC,aAAa,CAAC,IAAI,CAC1B,GAAG,EACH,OAAO,EACP,CAAC,KAAmB,EAAE,MAAc,EAAE,MAAc,EAAQ,EAAE;wBAC1D,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;4BACjC,IAAI,CAAC;gCACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;4BAClD,CAAC;4BAAC,OAAO,GAAY,EAAE,CAAC;gCACpB,eAAe,CAAC,GAAY,CAAC,CAAC;4BAClC,CAAC;wBACL,CAAC;oBACL,CAAC,CACJ,CAAC;gBACN,CAAC;YACL,CAAC;QACL,CAAC;QACD,KAAK,EAAE,UAAU,GAA6B;YAC1C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC7D,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,6CAA6C,EAAE,MAAM,CAAC,CAAC;YACnG,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjC,CAAC;QACD,QAAQ,EAAE,UAAU,GAA6B;YAC7C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAChE,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,6CAA6C,EAAE,MAAM,CAAC,CAAC;YACtG,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;QACpC,CAAC;QACD,OAAO,EAAE,UACL,GAAW,EACX,OAiBgB,EAChB,QAQS;YAET,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,QAAQ,GAAG,OAQF,CAAC;gBACV,OAAO,GAAG,EAAE,CAAC;YACjB,CAAC;YAED,MAAM,MAAM,GAAG;gBACX,GAAG,IAAA,4BAAoB,EAAC,GAAG,EAAE,OAAO,CAAC;gBACrC,MAAM,EAAE,KAAK;aAChB,CAAC;YAEF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACrE,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE7B,IAAI,CAAC,KAAK;iBACL,OAAO,CAAC,MAAM,CAAC;iBACf,IAAI,CAAC,CAAC,QAAuB,EAAE,EAAE;gBAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAE5C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,kBAAkB,YAAY,KAAK,EAAE,MAAM,CAAC,CAAC;gBAC/E,CAAC;gBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE;4BACzB,UAAU,EAAE,QAAQ,CAAC,MAAM;4BAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI;4BACnB,OAAO,EAAE,QAAQ,CAAC,OAAiC;4BACnD,YAAY;yBACf,CAAC,CAAC;oBACP,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;YACL,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAU,EAAE,EAAE;gBAClB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAE5C,OAAO,CAAC,GAAG,CAAC,eAAe,GAAG,WAAW,KAAK,CAAC,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;gBAEpE,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,MAAM,GAKN;wBACA,UAAU,EAAE,IAAI;wBAChB,IAAI,EAAE,IAAI;wBACV,OAAO,EAAE,EAAE;wBACX,YAAY;qBACf,CAAC;oBAEF,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;wBACjB,MAAM,GAAG;4BACL,UAAU,EAAE,KAAK,CAAC,QAAQ,CAAC,MAAM;4BACjC,IAAI,EAAE,KAAK,CAAC,QAAQ,CAAC,IAAI;4BACzB,OAAO,EAAE,KAAK,CAAC,QAAQ,CAAC,OAAO;4BAC/B,YAAY;yBACf,CAAC;oBACN,CAAC;oBAED,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;oBAClD,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;YACL,CAAC,CAAC,CAAC;QACX,CAAC;QACD,QAAQ,EAAE,UACN,GAAW,EACX,IAAS,EACT,OAiBgB,EAChB,QAQS;YAET,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,QAAQ,GAAG,OAAO,CAAC;gBACnB,OAAO,GAAG,EAAE,CAAC;YACjB,CAAC;YAED,MAAM,MAAM,GAAG;gBACX,GAAG,IAAA,4BAAoB,EACnB,GAAG,EACH,OAOC,CACJ;gBACD,MAAM,EAAE,MAAM;gBACd,IAAI;aACP,CAAC;YAEF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,UAAU,IAAI,GAAG,EAAE,MAAM,CAAC,CAAC;YACpF,CAAC;YAED,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YAE7B,IAAI,CAAC,KAAK;iBACL,OAAO,CAAC,MAAM,CAAC;iBACf,IAAI,CAAC,CAAC,QAAuB,EAAE,EAAE;gBAC9B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAE5C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,kBAAkB,YAAY,KAAK,EAAE,MAAM,CAAC,CAAC;gBAChF,CAAC;gBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE;4BACzB,UAAU,EAAE,QAAQ,CAAC,MAAM;4BAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI;4BACnB,OAAO,EAAE,QAAQ,CAAC,OAAO;4BACzB,YAAY;yBACf,CAAC,CAAC;oBACP,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;YACL,CAAC,CAAC;iBACD,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE;gBACtB,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;gBAE5C,OAAO,CAAC,GAAG,CAAC,gBAAgB,GAAG,WAAY,KAAe,CAAC,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;gBAEhF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,MAAM,GAKN;wBACA,UAAU,EAAE,IAAI;wBAChB,IAAI,EAAE,IAAI;wBACV,OAAO,EAAE,EAAE;wBACX,YAAY;qBACf,CAAC;oBACF,MAAM,QAAQ,GAA6C,KAAoB,CAAC,QAAQ,CAAC;oBAEzF,IAAI,QAAQ,EAAE,CAAC;wBACX,MAAM,GAAG;4BACL,UAAU,EAAE,QAAQ,CAAC,MAAM;4BAC3B,IAAI,EAAE,QAAQ,CAAC,IAAI;4BACnB,OAAO,EAAE,QAAQ,CAAC,OAAO;4BACzB,YAAY;yBACf,CAAC;oBACN,CAAC;oBAED,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAE,KAAoB,CAAC,OAAO,CAAC,EAAE,MAAM,CAAC,CAAC;oBAC7E,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;YACL,CAAC,CAAC,CAAC;QACX,CAAC;QACD,cAAc,EAAE,UAAU,QAAgB,EAAE,IAAqB;YAC7D,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;YACnB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;YACvB,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;YAEnB,IAAI,WAAW,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAEhE,IAAI,CAAC,WAAW,EAAE,CAAC;gBACf,wBAAwB;gBACxB,WAAW,GAAG,EAAE,CAAC,WAAW,CACxB,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,EAAE,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,CAAC,CAClF,CAAC;gBACF,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,WAAW,CAAC;gBAE1D,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CACP,2BAA2B,QAAQ,iBAAiB,WAAW,+BAA+B,EAAE,CAAC,MAAM,EAAE,EAAE,EAC3G,MAAM,CACT,CAAC;YACV,CAAC;YAED,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;YAElD,cAAc;YACd,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;YACvC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1B,EAAE,CAAC,SAAS,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/C,CAAC;YAED,IAAI,OAAO,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC9B,OAAO,CAAC,GAAG,CACP,2BAA2B,QAAQ,aAAa,OAAO,cAAc,QAAQ,wCAAwC,EACrH,OAAO,CACV,CAAC;gBAEF,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YACjC,OAAO,CAAC,OAAO;gBACX,OAAO,CAAC,GAAG,CAAC,2BAA2B,QAAQ,aAAa,OAAO,cAAc,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;YAE1G,OAAO,QAAQ,CAAC;QACpB,CAAC;QACD,SAAS,EAAE,UACP,OAMiE;QACjE,6EAA6E;QAC7E,wBAA4E,EAC5E,KAAW;YAQX,gCAAgC;YAChC,IACI,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;gBACnD,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAK,OAAyB,CAAC,MAAM,CAAC,EACpE,CAAC;gBACC,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAwB,EAAE,wBAAsC,CAAC,CAAC;YAC9F,CAAC;YACD,oCAAoC;YACpC,IAAI,OAAO,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACpC,MAAM,MAAM,GAAgD,EAAE,CAAC;gBAC/D,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;oBACtB,MAAM,CAAC,IAAI,CACP,OAAO,CAAC,SAAS,CAAC,CAA2B,EAAE,wBAAwB,EAAE,KAAK,CAI/D,CAClB,CAAC;gBACN,CAAC;gBACD,OAAO,MAAM,CAAC;YAClB,CAAC;YAED,6CAA6C;YAC7C,IAAI,QAAiB,CAAC;YACtB,IACI,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,YAAY,MAAM,CAAC;gBAC1D,OAAO,wBAAwB,KAAK,QAAQ;gBAC5C,OAAO,KAAK,KAAK,UAAU,EAC7B,CAAC;gBACC,QAAQ,GAAG,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,wBAAsC,EAAE,CAAC;gBAC3E,wBAAwB,GAAG,KAAK,CAAC;gBACjC,KAAK,GAAG,SAAS,CAAC;YACtB,CAAC;iBAAM,CAAC;gBACJ,QAAQ,GAAG,OAAkB,CAAC;YAClC,CAAC;YAED,IAAI,QAAQ,EAAE,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;gBAC7C,MAAM,MAAM,GAAgD,EAAE,CAAC;gBAC/D,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC1C,MAAM,EAAE,GAAY,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;oBACzD,EAAE,CAAC,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;oBACvB,MAAM,CAAC,IAAI,CACP,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,wBAAwB,EAAE,KAAK,CAItC,CAClB,CAAC;gBACN,CAAC;gBACD,OAAO,MAAM,CAAC;YAClB,CAAC;YAED,0CAA0C;YAC1C,IAAI,IAAA,gBAAQ,EAAC,OAAO,CAAC,IAAI,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC,EAAE,CAAC;gBACtG,IAAK,OAAqB,CAAC,KAAK,EAAE,CAAC;oBAC/B,OAAO,OAAO,CAAC,QAAQ,CAAC,OAAoB,EAAE,wBAAsC,CAAC,CAAC;gBAC1F,CAAC;qBAAM,IAAK,OAAoB,CAAC,IAAI,EAAE,CAAC;oBACpC,OAAO,OAAO,CAAC,QAAQ,CAClB,OAAoB,CAAC,IAAc,EACpC,wBAAsC,CACzC,CAAC;gBACN,CAAC;YACL,CAAC;YAED,IAAI,QAA+C,CAAC;YAEpD,iDAAiD;YACjD,IAAI,CAAC,IAAA,gBAAQ,EAAC,OAAO,CAAC,IAAI,OAAO,YAAY,MAAM,IAAK,OAAkB,CAAC,MAAM,EAAE,CAAC;gBAChF,QAAQ,GAAG,EAAE,EAAE,EAAE,OAA0B,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;YAChE,CAAC;YAED,IAAI,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAC5C,OAAO,CAAC,GAAG,CAAC,wEAAwE,EAAE,OAAO,CAAC,CAAC;gBAC/F,OAAO;YACX,CAAC;iBAAM,IAAI,OAAO,QAAQ,CAAC,EAAE,KAAK,SAAS,IAAI,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;gBAC7E,OAAO,CAAC,GAAG,CAAC,sEAAsE,EAAE,OAAO,CAAC,CAAC;gBAC7F,OAAO;YACX,CAAC;YAED,OAAO,CAAC,QAAQ,CAAC,eAAe,IAAI,CAAC,CAAC;YAEtC,IACI,OAAO,CAAC,QAAQ,CAAC,eAAe,GAAI,OAAO,CAAC,MAAkC,CAAC,oBAAoB;gBACnG,CAAC,EACH,CAAC;gBACC,OAAO,CAAC,GAAG,CACP,aAAa,OAAO,CAAC,QAAQ,CAAC,eAAe,+CAA+C,EAC5F,MAAM,CACT,CAAC;YACN,CAAC;YAED,IAAI,QAAQ,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;gBAC3B,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;YAED,yCAAyC;YACzC,IAAI,QAAQ,CAAC,EAAE,IAAI,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAC/E,QAAQ,CAAC,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;YACxD,CAAC;YAED,IAAI,OAAO,wBAAwB,KAAK,UAAU,EAAE,CAAC;gBACjD,QAAQ,GAAG,wBAAwB,CAAC;YACxC,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,KAAK,KAAK,WAAW,EAAE,CAAC;oBAC/B,QAAQ,GAAG,UAAU,GAAa;wBAC9B,OAAO,CAAC,QAAQ,CAAC,wBAAwB,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;oBACjE,CAAC,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,QAAQ,GAAG,WAAU,SAAS;wBAC1B,OAAO,CAAC,QAAQ,CAAC,wBAAwB,EAAE,KAAK,CAAC,CAAC;oBACtD,CAAC,CAAC;gBACN,CAAC;YACL,CAAC;YAED,MAAM,IAAI,GAAuB;gBAC7B,OAAO,EAAE,QAAQ;gBACjB,QAAQ,EAAE,CAAC,GAAa,EAAE,EAAE;oBACxB,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;wBAChC,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC;gBACL,CAAC;gBACD,IAAI;aACP,CAAC;YAEF,yBAAyB;YACzB,IAAI,QAAQ,CAAC,EAAE,IAAI,OAAO,QAAQ,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;gBACjD,MAAM,KAAK,GAAG,QAAQ,CAAC,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACrC,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpC,MAAM,QAAQ,GAAG,kBAAkB,CAAC,EAAE,CAAC;gBAEvC,IAAI,OAAO,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;oBACzF,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,CAAC;oBAC1C,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;oBAE9D,MAAM,SAAS,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;oBAE3F,IAAI,CAAC,SAAS,EAAE,CAAC;wBACb,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;wBAC7C,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;oBAChD,CAAC;gBACL,CAAC;YACL,CAAC;YACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC9D,CAAC;YAED,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAY,CAAC,CAAC;YAEhD,IAAI,CAAC,uBAAuB,GAAG,0BAA0B,CAAC,QAAQ,CAAC,CAAC;YACpE,OAAO,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEjC,IAAI,QAAQ,CAAC,QAAQ,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;gBACvC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;YAC3B,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,gBAAgB,EAAE;YACd,MAAM,MAAM,GAAyD,EAAE,CAAC;YACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpD,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAY,CAAC;oBACjD,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAY,CAAC,IAAI,EAAE,CAAC;gBAChE,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAY,CAAC,CAAC,IAAI,CAAC;oBACvD,IAAI,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI;oBACnC,OAAO,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO;iBAC5C,CAAC,CAAC;YACP,CAAC;YACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC3E,CAAC;YACD,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,oBAAoB,EAAE;YAClB,MAAM,MAAM,GAA4E,EAAE,CAAC;YAC3F,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACxD,MAAM,GAAG,GAAG,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,eAAe,EAAE,CAAC;gBACnG,MAAM,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;gBAChC,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;oBACb,IAAI,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI;oBACvC,EAAE,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE;oBACnC,eAAe,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,eAAe;iBAChE,CAAC,CAAC;YACP,CAAC;YACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,6BAA6B,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YAC/E,CAAC;YACD,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,gBAAgB,EAAE,UAAU,EAAU;YAClC,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,wCAAwC,OAAO,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC1E,OAAO;YACX,CAAC;YACD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC5B,MAAM,QAAQ,GAAG,kBAAkB,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YAC1D,IAAI,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;gBAC1C,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACpC,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,CAAC;gBAC1C,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBAC9D,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACpC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,MAAM,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;gBAC1D,CAAC;gBACD,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,EAAE,CAAC,CAAC;YACvC,CAAC;QACL,CAAC;QACD,kBAAkB,EAAE,UAChB,UAAyE;YAEzE,kCAAkC;YAClC,OAAO,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;QAC3C,CAAC;QACD,WAAW,EAAE,UACT,UAAyE;YAEzE,IAAI,UAAU,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC1C,MAAM,MAAM,GAAc,EAAE,CAAC;gBAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACzC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,CAAC,CAAY,CAAC,CAAC;gBAC/D,CAAC;gBACD,OAAO,MAAM,CAAC;YAClB,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAChF,CAAC;YAED,IAAI,IAAA,gBAAQ,EAAC,UAAU,CAAC,EAAE,CAAC;gBACvB,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBACzD,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;wBAC1C,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAY,CAAC,CAAC;wBAC1E,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;wBACnC,OAAO,IAAI,CAAC;oBAChB,CAAC;gBACL,CAAC;gBACD,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACzD,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,KAAK,UAAU,EAAE,CAAC;oBAC/F,OAAO,EAAE,CAAC;oBACV,kBAAkB,CAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAY,CAAC,CAAC;oBAC1E,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACnC,OAAO,CAAC,QAAQ,CAAC,eAAe,EAAE,CAAC;gBACvC,CAAC;YACL,CAAC;YACD,OAAO,CAAC,CAAC,OAAO,CAAC;QACrB,CAAC;QACD,EAAE,EAAE,UACA,OAMiE;QACjE,6EAA6E;QAC7E,wBAA4E,EAC5E,KAAW;YAQX,OAAO,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,wBAAwB,EAAE,KAAK,CAAC,CAAC;QACvE,CAAC;QACD,aAAa,EAAE,UAAU,MAAc,EAAE,QAAoC;YACzE,IAAI,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzB,MAAM,aAAa,GAAgD,EAAE,CAAC;gBAEtE,MAAM,IAAI,GAAG,GAAS,EAAE;oBACpB,MAAM,GAAG,GAAwB,OAAO,CAAC,MAAM,CAAwB,CAAC;oBACxE,MAAM,MAAM,GAAwB,GAAG,EAAE,MAAM,IAAI,EAAE,CAAC;oBACtD,MAAM,OAAO,GAAa,MAAM,EAAE,OAAO,IAAI,EAAE,CAAC;oBAEhD,2BAA2B;oBAC3B,KAAK,MAAM,CAAC,KAAK,EAAE,YAAY,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC;wBAChE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;4BAC3B,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;4BAClC,OAAO,aAAa,CAAC,KAAK,CAAC,CAAC;wBAChC,CAAC;oBACL,CAAC;oBAED,mCAAmC;oBACnC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;wBAC1B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;4BAC9C,IAAI,OAAO,EAAE,CAAC,KAAK,CAAC,EAAE,IAAI,KAAK,OAAO,EAAE,CAAC;gCACrC,2BAA2B;gCAC3B,aAAa,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAEhC,CAAC,CAAC,sBAAsB;4BACpD,CAAC;wBACL,CAAC;oBACL,CAAC;oBAED,OAAO,CAAC,OAAO;wBACX,OAAO,CAAC,GAAG,CACP,oBAAoB,MAAM,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,GAAG,EACpF,MAAM,CACT,CAAC;gBACV,CAAC,CAAC;gBAEF,IAAI,EAAE,CAAC;gBAEP,OAAO,CAAC,eAAe,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,CAAC;YAC1D,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,GAAG,CAAC,gCAAgC,MAAM,kBAAkB,EAAE,OAAO,CAAC,CAAC;YACnF,CAAC;QACL,CAAC;QACD,MAAM,EAAE,UACJ,EAAU,EACV,eAAkC,EAClC,kBAEuG,EACvG,QAMS;YAET,IAAI,OAAO,kBAAkB,KAAK,UAAU,EAAE,CAAC;gBAC3C,QAAQ,GAAG,kBAMF,CAAC;gBACV,kBAAkB,GAAG,KAAK,CAAC;YAC/B,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CACP,kHAAkH,EAClH,MAAM,CACT,CAAC;gBACF,OAAO;YACX,CAAC;YACD,IAAI,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;gBAC1B,OAAO,CAAC,GAAG,CACP,iHAAiH,EACjH,OAAO,CACV,CAAC;gBACF,OAAO;YACX,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,eAAe,CAAC,CAAC;gBACrC,OAAO;YACX,CAAC;YAED,IAAI,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;gBACjC,OAAO,eAAe,CAAC,GAAG,CACtB,WAAW,CAAC,EAAE,CACV,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,WAAW,EAAE,kBAAkB,EAAE,QAAQ,CAEhC,CACnC,CAAC;YACN,CAAC;YAED,OAAO,CAAC,QAAQ,CAAC,mBAAmB,IAAI,CAAC,CAAC;YAE1C,OAAO,CAAC,OAAO;gBACX,OAAO,CAAC,GAAG,CACP,aAAa,EAAE,qBAAqB,eAAe,yBAAyB,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE,EAClH,MAAM,CACT,CAAC;YAEN,IACI,OAAO,CAAC,QAAQ,CAAC,mBAAmB;gBAC/B,OAAO,CAAC,MAAkC,CAAC,oBAAoB;gBACpE,CAAC,EACH,CAAC;gBACC,OAAO,CAAC,GAAG,CACP,aAAa,OAAO,CAAC,QAAQ,CAAC,mBAAmB,oDAAoD,EACrG,MAAM,CACT,CAAC;YACN,CAAC;YAED,IAAI,OAA2B,CAAC;YAChC,IAAI,SAA6B,CAAC;YAClC,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,OAAO,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC,CAAC;YAC5C,CAAC;YACD,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBAChC,SAAS,GAAG,IAAI,MAAM,CAAC,aAAa,CAAC,eAAe,CAAC,CAAC,CAAC;YAC3D,CAAC;YAED,MAAM,IAAI,GAA2B;gBACjC,EAAE;gBACF,eAAe;gBACf,QAAQ,EAAE,kBAAkB;gBAC5B,OAAO;gBACP,SAAS;gBACT,QAAQ,EAAE,CAAC,EAAU,EAAE,QAAgB,EAAE,IAAmB,EAAE,QAAiB,EAAQ,EAAE;oBACrF,IAAI,CAAC;wBACD,OAAO,CAAC,OAAO;4BACX,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,cAAc,QAAQ,UAAU,IAAI,GAAG,EAAE,MAAM,CAAC,CAAC;wBAExF,IAAI,QAAQ,IAAI,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;4BAC9B,OAAO;iCACF,aAAa,CAAC,EAAE,EAAE,QAAQ,CAAC;iCAC3B,IAAI,CAAC,IAAI,CAAC,EAAE;gCACT,IAAI,CAAC;oCACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;gCACzE,CAAC;gCAAC,OAAO,GAAY,EAAE,CAAC;oCACpB,eAAe,CAAC,GAAY,CAAC,CAAC;gCAClC,CAAC;4BACL,CAAC,CAAC;iCACD,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC,CAAC;wBAChD,CAAC;6BAAM,CAAC;4BACJ,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;wBAC/C,CAAC;oBACL,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,IAAI;aACP,CAAC;YAEF,OAAO,CAAC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrC,aAAa,CAAC,MAAM,EAAE,EAAE,EAAE,eAAe,CAAC,CAAC;YAC3C,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,EAAE,UACL,UAAiF,EACjF,eAAmC;YAEnC,IAAI,CAAC,OAAO,CAAC,uBAAuB,EAAE,CAAC;gBACnC,OAAO,CAAC,GAAG,CACP,mHAAmH,EACnH,MAAM,CACT,CAAC;gBACF,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,OAAO,CAAC,OAAO;gBACX,OAAO,CAAC,GAAG,CACP,sBAAsB,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,yBAAyB,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE,EACnK,MAAM,CACT,CAAC;YAEN,IAAI,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;gBAC/C,IAAI,KAAK,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC5B,MAAM,MAAM,GAAc,EAAE,CAAC;oBAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACzC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAY,CAAC,CAAC;oBAC3D,CAAC;oBACD,OAAO,MAAM,CAAC;gBAClB,CAAC;gBACD,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC7D,IAAI,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,KAAK,UAAU,EAAE,CAAC;wBAC9C,eAAe,CACX,MAAM,EACN,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,EAC/B,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,eAAe,CAC/C,CAAC;wBAEF,OAAO,CAAC,OAAO;4BACX,OAAO,CAAC,GAAG,CACP,wCAAwC,IAAI,CAAC,SAAS,CAAC,eAAe,CAAC,iBAAiB,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAC1H,MAAM,CACT,CAAC;wBAEN,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBACvC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC;wBACvC,OAAO,IAAI,CAAC;oBAChB,CAAC;gBACL,CAAC;gBACD,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,IAAI,eAAe,IAAI,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;gBACpD,MAAM,MAAM,GAAc,EAAE,CAAC;gBAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC9C,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,CAAY,CAAC,CAAC;gBAC5E,CAAC;gBACD,OAAO,MAAM,CAAC;YAClB,CAAC;YAED,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC7D,IACI,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,UAAU;oBAC9C,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,eAAe,KAAK,eAAe,EAClE,CAAC;oBACC,OAAO,EAAE,CAAC;oBACV,eAAe,CACX,MAAM,EACN,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,EAC/B,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,eAAe,CAC/C,CAAC;oBAEF,OAAO,CAAC,OAAO;wBACX,OAAO,CAAC,GAAG,CACP,wCAAwC,eAAe,iBAAiB,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,EAC1G,MAAM,CACT,CAAC;oBAEN,OAAO,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACvC,OAAO,CAAC,QAAQ,CAAC,mBAAmB,EAAE,CAAC;gBAC3C,CAAC;YACL,CAAC;YACD,OAAO,CAAC,CAAC,OAAO,CAAC;QACrB,CAAC;QACD,oGAAoG;QACpG,IAAI,EAAE,UACF,OAMiE,EACjE,QAAqC;YAErC,SAAS,KAAK,CAAC,EAA4B;gBACvC,wCAAwC;gBACxC,IAAI,YAAyC,CAAC;gBAC9C,MAAM,OAAO,GAAG,CAAC,GAAc,EAAQ,EAAE;oBACrC,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;oBAClD,OAAO,EAAE,KAAK,UAAU,IAAI,EAAE,CAAC,GAAG,CAAC,CAAC;gBACxC,CAAC,CAAC;gBACF,YAAY,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,OAAO,CAAgC,CAAC;gBAClF,OAAO,YAAY,CAAC;YACxB,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,+CAA+C;gBAC/C,OAAO,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC3B,CAAC;YAED,iDAAiD;YACjD,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;QAClD,CAAC;QACD,QAAQ,EAAE,UACN,OAAkD,EAClD,QAAoB;YAEpB,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAC;gBAClD,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,IACI,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC;gBACnD,CAAC,OAAO,OAAO,KAAK,QAAQ,IAAK,OAAyB,CAAC,MAAM,CAAC,EACpE,CAAC;gBACC,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CACP,mBAAmB,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,GAAG,EACrF,MAAM,CACT,CAAC;gBAEN,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;oBACrB,OAAO,CAAC,GAAG,CACP,oBAAoB,OAAO,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,sCAAsC,EACzH,OAAO,CACV,CAAC;oBACF,OAAO,IAAI,CAAC;gBAChB,CAAC;gBAED,MAAM,QAAQ,GAAkB,OAAO,CAAC,SAAS,CAAC,GAAG,CACjD,OAAiC,EACjC,OAAO,CAAC,UAAU,EAClB,QAAQ,CACX,CAAC;gBACF,IAAI,QAAQ,EAAE,CAAC;oBACX,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;oBAC9B,OAAO,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC;oBAElC,IACI,OAAO,CAAC,QAAQ,CAAC,WAAW;wBACvB,OAAO,CAAC,MAAkC,CAAC,oBAAoB;wBACpE,CAAC,EACH,CAAC;wBACC,OAAO,CAAC,GAAG,CACP,aAAa,OAAO,CAAC,QAAQ,CAAC,WAAW,2CAA2C,EACpF,MAAM,CACT,CAAC;oBACN,CAAC;gBACL,CAAC;gBAED,OAAO,QAAQ,CAAC;YACpB,CAAC;YAED,MAAM,aAAa,GAA4B,OAAO,CAAC,MAAiC,CAAC;YAEzF,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAK,OAAqB,CAAC,KAAK,EAAE,CAAC;gBAC9D,MAAM,YAAY,GAAG,OAAoB,CAAC;gBAC1C,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;gBAE3B,IACI,aAAa,CAAC,QAAQ,KAAK,SAAS;oBACpC,aAAa,CAAC,SAAS,KAAK,SAAS;oBACrC,aAAa,CAAC,QAAQ,KAAK,IAAI;oBAC/B,aAAa,CAAC,SAAS,KAAK,IAAI,EAClC,CAAC;oBACC,OAAO,CAAC,GAAG,CAAC,uDAAuD,EAAE,OAAO,CAAC,CAAC;oBAC9E,OAAO,IAAI,CAAC;gBAChB,CAAC;gBAED,2DAA2D;gBAC3D,2CAA2C;gBAC3C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;gBACpC,SAAS,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAChC,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,SAAS,CAAC,CACtF,YAAY,CAAC,KAAK,CACrB,CAAC;gBAEF,oEAAoE;gBACpE,IAAI,SAAS,CAAC,OAAO,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC;oBACvC,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;oBAC3C,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,SAAS,EAAE,aAAa,CAAC,QAAQ,EAAE,aAAa,CAAC,SAAS,CAAC,CAClF,YAAY,CAAC,KAAK,CACrB,CAAC;gBACN,CAAC;gBAED,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,KAAK,KAAK,EAAE,CAAC;oBACpC,OAAO,CAAC,GAAG,CACP,qBAAqB,YAAY,CAAC,KAAK,SAAS,aAAa,CAAC,QAAQ,KAAK,aAAa,CAAC,SAAS,EAAE,EACpG,MAAM,CACT,CAAC;oBACF,EAAE,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;oBAEjC,IACI,YAAY,CAAC,KAAK,KAAK,YAAY;wBACnC,YAAY,CAAC,KAAK,KAAK,eAAe;wBACtC,YAAY,CAAC,KAAK,KAAK,QAAQ;wBAC/B,YAAY,CAAC,KAAK,KAAK,UAAU;wBACjC,YAAY,CAAC,KAAK,KAAK,cAAc,EACvC,CAAC;wBACC,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;wBAChB,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;wBAClB,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACtB,CAAC;yBAAM,CAAC;wBACJ,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;wBAChB,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;wBAClB,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACtB,CAAC;gBACL,CAAC;gBAED,IAAI,EAAE,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC;oBAC3B,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,YAAY,CAAC,KAAK,GAAG,KAAK,CAAC,CAAC;gBAC7D,CAAC;gBAED,IAAI,CAAC,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,CAAC;oBACtB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC/B,iDAAiD;oBACjD,6DAA6D;oBAC7D,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;oBACjC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,oCAAoC;oBACxD,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;oBACjB,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;oBACnB,IAAI,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;oBAExB,OAAO,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC;oBAElC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,GAAG,aAAa,CAAC,oBAAoB,KAAK,CAAC,EAAE,CAAC;wBAC1E,OAAO,CAAC,GAAG,CACP,aAAa,OAAO,CAAC,QAAQ,CAAC,WAAW,2CAA2C,EACpF,MAAM,CACT,CAAC;oBACN,CAAC;oBAED,OAAO,CAAC,OAAO;wBACX,OAAO,CAAC,GAAG,CACP,kBAAkB,YAAY,CAAC,KAAK,YAAY,YAAY,CAAC,KAAK,gCAAgC,IAAI,CAAC,WAAW,EAAE,EAAE,EACtH,MAAM,CACT,CAAC;oBAEN,yCAAyC;oBACzC,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE;wBACpB,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;4BACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;wBACnC,CAAC;wBACD,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;oBAC7C,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;oBAEhC,OAAO;gBACX,CAAC;gBAED,OAAO,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC;gBAElC,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,GAAG,aAAa,CAAC,oBAAoB,KAAK,CAAC,EAAE,CAAC;oBAC1E,OAAO,CAAC,GAAG,CACP,aAAa,OAAO,CAAC,QAAQ,CAAC,WAAW,2CAA2C,EACpF,MAAM,CACT,CAAC;gBACN,CAAC;gBAED,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE;oBACpB,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC3B,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;oBACD,0BAA0B;oBAC1B,OAAO,CAAC,UAAU,CAAC,GAAG,EAAE;wBACpB,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;4BACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;wBACnC,CAAC;wBACD,OAAO,CAAC,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;oBAC7C,CAAC,EAAE,IAAI,CAAC,CAAC;gBACb,CAAC,EAAE,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBAE9B,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CACP,kBAAkB,YAAY,CAAC,KAAK,YAAY,YAAY,CAAC,KAAK,6BAA6B,EAAE,CAAC,WAAW,EAAE,EAAE,EACjH,MAAM,CACT,CAAC;YACV,CAAC;iBAAM,CAAC;gBACJ,kCAAkC;gBAClC,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;oBAC9B,uBAAuB;oBACvB,MAAM,KAAK,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACtD,IAAI,KAAK,CAAC,MAAM,IAAI,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;wBACnD,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;oBACnB,CAAC;oBACD,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC9B,CAAC;gBACD,kEAAkE;gBAClE,YAAY;gBACZ,IAAI,OAAO,OAAO,KAAK,QAAQ,IAAK,OAAgB,CAAC,OAAO,EAAE,CAAC;oBAC3D,OAAO,GAAG,IAAI,IAAI,CAAC,OAAe,CAAC,CAAC;gBACxC,CAAC;gBAED,MAAM,QAAQ,GAAgB,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE,GAAS,EAAE;oBAC5E,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oBAC3B,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,IAAI,QAAQ,EAAE,CAAC;oBACX,OAAO,CAAC,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC;oBAElC,IACI,OAAO,CAAC,QAAQ,CAAC,WAAW;wBACvB,OAAO,CAAC,MAAkC,CAAC,oBAAoB;wBACpE,CAAC,EACH,CAAC;wBACC,OAAO,CAAC,GAAG,CACP,aAAa,OAAO,CAAC,QAAQ,CAAC,WAAW,2CAA2C,EACpF,MAAM,CACT,CAAC;oBACN,CAAC;oBAED,QAAQ,CAAC,SAAS,GAAG;wBACjB,IAAI,EAAE,MAAM;wBACZ,OAAO,EAAE,OAAwB;wBACjC,UAAU,EAAE,OAAO,CAAC,UAAU;wBAC9B,EAAE,EAAE,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE;qBACjE,CAAC;oBAEF,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBACpC,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,2BAA2B,EAAE,OAAO,CAAC,CAAC;gBAC9F,CAAC;gBAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBACrE,CAAC;gBAED,OAAO,QAAQ,CAAC;YACpB,CAAC;QACL,CAAC;QACD,YAAY,EAAE,UAAU,EAAU,EAAE,GAAuC,EAAE,QAAqB;YAC9F,IAAI,UAAU,GAA4C,IAAI,CAAC;YAC/D,IAAI,UAAU,GAAkB,IAAI,CAAC,CAAC,0BAA0B;YAEhE,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE,CAAC;gBAC5B,QAAQ,GAAG,GAAG,CAAC;gBACf,GAAG,GAAG,SAAS,CAAC;YACpB,CAAC;YAED,MAAM,IAAI,GAAG,mDAAmD,CAAC,CAAC,WAAW;YAC7E,MAAM,GAAG,GAAG,qCAAqC,CAAC,CAAC,QAAQ;YAE3D,MAAM,IAAI,GAAG,CAAC,IAAY,EAAQ,EAAE;gBAChC,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC3B,IAAI,CAAC,GAAuB,SAAS,CAAC;oBACtC,IAAI,CAAC,GAAuB,SAAS,CAAC;oBACtC,IAAI,CAAC,GAAuB,SAAS,CAAC;oBAEtC,IAAI,OAAO,GAAG,KAAK,CAAC;oBAEpB,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;oBAC9B,IAAI,MAAM,EAAE,CAAC;wBACT,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC3C,OAAO,GAAG,IAAI,CAAC;oBACnB,CAAC;yBAAM,CAAC;wBACJ,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;wBACzB,IAAI,MAAM,EAAE,CAAC;4BACT,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;4BACxC,OAAO,GAAG,IAAI,CAAC;wBACnB,CAAC;oBACL,CAAC;oBAED,IAAI,OAAO,EAAE,CAAC;wBACV,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;wBAE5D,IAAI,OAAO,KAAK,UAAU,EAAE,CAAC;4BACzB,OAAO,CAAC,OAAO;gCACX,OAAO,CAAC,GAAG,CACP,mBAAmB,EAAE,2BAA2B,OAAO,SAAS,IAAI,EAAE,EACtE,MAAM,CACT,CAAC;4BACN,UAAU,GAAG,OAAO,CAAC;4BAErB,IAAI,UAAU,EAAE,CAAC;gCACb,OAAO,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;gCAClC,UAAU,GAAG,IAAI,CAAC;4BACtB,CAAC;4BAED,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,OAAO,EAAE,GAAG,EAAE;gCACxC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oCACjC,IAAI,CAAC;wCACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;oCAC3B,CAAC;oCAAC,OAAO,GAAY,EAAE,CAAC;wCACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oCAClC,CAAC;gCACL,CAAC;4BACL,CAAC,CAAC,CAAC;wBACP,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,GAAG,CACP,mBAAmB,EAAE,SAAS,IAAI,yEAAyE,EAC3G,OAAO,CACV,CAAC;oBACN,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,GAAG,CACP,mBAAmB,EAAE,0DAA0D,EAC/E,OAAO,CACV,CAAC;gBACN,CAAC;YACL,CAAC,CAAC;YAEF,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;gBAChC,IAAI,CAAC,GAAG,IAAI,KAAK,EAAE,GAAG,EAAE,CAAC;oBACrB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,sBAAsB,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;oBAChF,CAAC;oBACD,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC/B,CAAC;YACL,CAAC,CAAC,CAAC;YAEH,MAAM,UAAU,GAAY,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;YAClD,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;gBACpB,UAAU,CAAC,GAAG,GAAG,GAAG,CAAC;YACzB,CAAC;YAED,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE;gBACzB,IAAI,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;oBAClB,OAAO,CAAC,OAAO;wBACX,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,wBAAwB,GAAG,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;oBACtF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;gBACnC,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC;QACD,YAAY,EAAE,UAAU,OAAmB,EAAE,IAAoB,EAAE,aAAsB;YACrF,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;gBACrB,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;YACtB,CAAC;YACD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACJ,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;YACpC,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC/D,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACb,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACpC,CAAC;YACL,CAAC;YAED,IACI,CAAC,CAAE,OAAO,CAAC,MAAkC,CAAC,QAAQ;gBAChD,OAAO,CAAC,MAAkC,CAAC,QAA8B,KAAK,CAAC,CAAC;gBACtF,CAAC,CAAE,OAAO,CAAC,MAAkC,CAAC,SAAS;oBACjD,OAAO,CAAC,MAAkC,CAAC,SAA+B,KAAK,CAAC,CAAC,EACzF,CAAC;gBACC,OAAO,CAAC,GAAG,CAAC,uDAAuD,EAAE,OAAO,CAAC,CAAC;gBAC9E,OAAO;YACX,CAAC;YAED,2DAA2D;YAC3D,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;YAC3B,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAC1B,IAAI,EACH,OAAO,CAAC,MAAkC,CAAC,QAAQ,EACnD,OAAO,CAAC,MAAkC,CAAC,SAAS,CACxD,CAAC,OAAO,CAAC,CAAC;YAEX,IAAI,EAAE,KAAK,SAAS,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,KAAK,KAAK,EAAE,CAAC;gBACxD,OAAO,CAAC,GAAG,CACP,gCAAgC,OAAO,SAAU,OAAO,CAAC,MAAkC,CAAC,QAAQ,KAAM,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,EAChK,MAAM,CACT,CAAC;YACN,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,UAAU,IAAI,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;YAC9F,CAAC;YAED,IAAI,aAAa,KAAK,SAAS,EAAE,CAAC;gBAC9B,EAAE,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,aAAa,GAAG,KAAK,CAAC,CAAC;YACxD,CAAC;YACD,OAAO,EAAE,CAAC;QACd,CAAC;QACD,UAAU,EAAE;YACR,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;YAC3B,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,SAAS,CAAC,CAAC;YACjD,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;YAE9C,IAAI,QAAQ,KAAK,SAAS,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;gBACjD,OAAO;YACX,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,mBAAmB,OAAO,IAAI,QAAQ,IAAI,OAAO,IAAI,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC;YACvF,CAAC;YAED,OAAO,OAAO,IAAI,QAAQ,IAAI,OAAO,IAAI,MAAM,CAAC;QACpD,CAAC;QACD,aAAa,EAAE,UAAU,QAA6C;YAClE,IAAI,OAAO,CAAC,SAAS,EAAE,GAAG,CAAC,QAAiC,CAAC,EAAE,CAAC;gBAC5D,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,MAAM,CAAC,CAAC;gBAC7D,CAAC;gBACD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,QAAkB,CAAC,CAAC;gBACvD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACb,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;oBAC9B,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;wBACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;oBACnC,CAAC;gBACL,CAAC;gBACD,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,QAAiC,CAAC,CAAC;gBAC5D,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/C,IAAI,QAAQ,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAK,QAAwB,CAAC,SAAS,EAAE,IAAI,KAAK,MAAM,EAAE,CAAC;oBACnG,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,EAAE,KAAM,QAAwB,CAAC,SAAS,CAAC,EAAE,EAAE,CAAC;wBAC9E,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;4BACpD,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,OAAO,CAAC,CAAC;wBAC7D,CAAC;wBACD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBAC9B,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;4BACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;wBACnC,CAAC;wBAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;4BAClB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,MAAM,CAAC,CAAC;wBACtD,CAAC;wBACD,OAAO,IAAI,CAAC;oBAChB,CAAC;gBACL,CAAC;qBAAM,IAAI,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,QAAQ,EAAE,CAAC;oBAC1C,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;wBACpD,OAAO,CAAC,GAAG,CAAC,kCAAkC,EAAE,OAAO,CAAC,CAAC;oBAC7D,CAAC;oBACD,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC9B,IAAI,OAAO,CAAC,QAAQ,CAAC,WAAW,GAAG,CAAC,EAAE,CAAC;wBACnC,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC;oBACnC,CAAC;oBAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,MAAM,CAAC,CAAC;oBACtD,CAAC;oBACD,OAAO,IAAI,CAAC;gBAChB,CAAC;YACL,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,oCAAoC,EAAE,MAAM,CAAC,CAAC;YAC9D,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,YAAY,EAAE,UAAU,UAAoB;YACxC,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;YACrD,IAAI,UAAU,EAAE,CAAC;gBACb,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAChC,IAAI,CAAC,EAAE,CACH,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS;oBAC/B,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CACxC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAC1D,CACR,CAAC;YACN,CAAC;iBAAM,CAAC;gBACJ,MAAM,CAAC,SAAS;oBACZ,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YAC/F,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,QAAQ,EAAE,UACN,EAAU,EACV,KAAmD,EACnD,KAAmE,EACnE,QAAuC;YAEvC,OAAO,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC7E,CAAC;QACD,eAAe,EAAE,UACb,EAAU,EACV,KAAmD,EACnD,KAAgD,EAChD,QAAuC;YAEvC,OAAO,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC5E,CAAC;QACD,eAAe,EAAE,UACb,EAAU,EACV,KAAmD,EACnD,KAAmC,EACnC,KAAwB,EACxB,YAAuD,EACvD,QAAuC;YAEvC,iBAAiB;YACjB,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;gBAC7B,QAAQ,GAAG,YAA4C,CAAC;gBACxD,YAAY,GAAG,KAAgB,CAAC;gBAChC,KAAK,GAAG,KAAe,CAAC;gBACxB,KAAK,GAAG,SAAS,CAAC;YACtB,CAAC;YACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC5B,QAAQ,GAAG,YAA4C,CAAC;gBACxD,YAAY,GAAG,KAAgB,CAAC;gBAChC,KAAK,GAAG,CAAC,CAAC;YACd,CAAC;YACD,IAAI,OAAO,YAAY,KAAK,SAAS,EAAE,CAAC;gBACpC,QAAQ,GAAG,YAAY,CAAC;gBACxB,YAAY,GAAG,IAAI,CAAC;YACxB,CAAC;YAED,wBAAwB;YACxB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;gBACxD,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YACtC,CAAC;YAED,OAAO,CAAC,OAAO;gBACX,OAAO,CAAC,GAAG,CACP,sBAAsB,EAAE,WAAW,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,WAAW,KAAK,WAAW,KAAK,kBAAkB,YAAY,GAAG,EACzH,MAAM,CACT,CAAC;YAEN,IAAI,YAAY,EAAE,CAAC;gBACf,IAAI,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;oBACb,OAAO,CAAC,OAAO;wBACX,OAAO,CAAC,GAAG,CAAC,0BAA0B,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,iBAAiB,EAAE,MAAM,CAAC,CAAC;oBAEtF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBACzC,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAClC,CAAC;oBACD,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACJ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,oCAAoC,EAAE,MAAM,CAAC,CAAC;oBAC9D,CAAC;gBACL,CAAC;YACL,CAAC;YACD,oCAAoC;YACpC,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC;gBAC7C,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,WAAW;YACX,MAAM,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE,CAAC;YAE9B,oBAAoB;YACpB,OAAO,CAAC,OAAO,EAAE,CAAC;YAClB,IAAI,OAAO,CAAC,OAAO,GAAG,UAAU,EAAE,CAAC;gBAC/B,OAAO,CAAC,OAAO,GAAG,CAAC,CAAC;YACxB,CAAC;YAED,gBAAgB;YAChB,MAAM,KAAK,GAAG,UAAU,CACpB,UAAU,QAAQ,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM;gBACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;gBAChD,uBAAuB;gBACvB,IAAI,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC;oBACd,eAAe;oBACf,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC3B,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;oBACvB,CAAC;yBAAM,CAAC;wBACJ,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;4BAC1C,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;gCACjC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gCACzB,MAAM;4BACV,CAAC;wBACL,CAAC;wBACD,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;4BACtB,OAAO,MAAM,CAAC,GAAG,CAAC,CAAC;wBACvB,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC,EACD,KAAK,EACL,OAAO,CAAC,OAAO,EACf,EAAE,EACF,KAAK,EACL,KAAK,CACR,CAAC;YAEF,oBAAoB;YACpB,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC;gBACZ,CAAC,EAAE,KAAK;gBACR,EAAE,EAAE,OAAO,CAAC,OAAO;gBACnB,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;gBACd,KAAK,EAAE,KAAK;gBACZ,GAAG,EACC,IAAA,gBAAQ,EAAC,KAAK,CAAC,IAAK,KAAgC,CAAC,GAAG,KAAK,SAAS;oBAClE,CAAC,CAAG,KAAgC,CAAC,GAA2B;oBAChE,CAAC,CAAE,KAA6B;gBACxC,GAAG,EACC,IAAA,gBAAQ,EAAC,KAAK,CAAC;oBACd,KAAgC,CAAC,GAAG,KAAK,SAAS;oBAClD,KAAgC,CAAC,GAAG,KAAK,SAAS;oBAC/C,CAAC,CAAE,KAAgC,CAAC,GAAG;oBACvC,CAAC,CAAC,KAAK;aAClB,CAAC,CAAC;YAEH,OAAO,OAAO,CAAC,OAAO,CAAC;QAC3B,CAAC;QACD,iBAAiB,EAAE,UAAU,EAAU,EAAE,OAAe;YACpD,wBAAwB;YACxB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;gBACxD,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;YACtC,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,aAAa,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC;YAC3E,CAAC;YAED,IAAI,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;gBACb,KAAK,IAAI,CAAC,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC9C,IAAI,OAAO,KAAK,SAAS,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,OAAO,EAAE,CAAC;wBACxD,YAAY,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBAC9B,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;4BACxB,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;wBAC5B,CAAC;wBACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;4BAClB,OAAO,CAAC,GAAG,CAAC,kCAAkC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,CAAC;wBAC9E,CAAC;oBACL,CAAC;gBACL,CAAC;gBACD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;oBACxB,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC;gBACtB,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;wBACrB,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC;oBACtB,CAAC;gBACL,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,eAAe,EAAE,UACb,EAAmB;YASnB,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACvB,IAAI,EAAE,EAAE,CAAC;gBACL,wBAAwB;gBACxB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;oBACxD,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC;gBACtC,CAAC;gBACD,mBAAmB;gBACnB,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;oBACzB,KAAK,MAAM,IAAI,IAAI,MAAM,EAAE,CAAC;wBACxB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE,CAAC;4BACrD,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;gCACjD,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;oCAC9B,OAAO;wCACH,OAAO,EAAE,EAAE;wCACX,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;wCAC1D,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK;wCAC9B,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG;wCAC1B,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG;qCAC7B,CAAC;gCACN,CAAC;4BACL,CAAC;wBACL,CAAC;oBACL,CAAC;oBACD,OAAO,IAAI,CAAC;gBAChB,CAAC;gBAED,MAAM,MAAM,GAMN,EAAE,CAAC;gBACT,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;oBACtF,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,EAAE,EAAE,EAAE,CAAC;wBAC5C,MAAM,CAAC,IAAI,CAAC;4BACR,OAAO,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;4BAC1B,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;4BACtD,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK;4BAC3B,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;4BACvB,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG;yBAC1B,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC;gBACD,OAAO,MAAM,CAAC;YAClB,CAAC;YACD,MAAM,MAAM,GAGR,EAAE,CAAC;YACP,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;oBACzF,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC;oBACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC1C,MAAM,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC;4BACb,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE;4BAC1B,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;4BACtD,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK;4BAC3B,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;4BACvB,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG;yBAC1B,CAAC,CAAC;oBACP,CAAC;gBACL,CAAC;YACL,CAAC;YACD,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,aAAa,EAAE,KAAK,WAAW,EAAU;YACrC,IAAI,KAAwC,CAAC;YAC7C,IAAI,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnB,KAAK,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;YACnD,CAAC;iBAAM,CAAC;gBACJ,KAAK,GAAG,MAAM,OAAO,CAAC,aAAa,CAAC,EAAE,CAAC,CAAC;YAC5C,CAAC;YACD,OAAO,OAAO,CAAC,4BAA4B,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;QAC3D,CAAC;QACD,aAAa,EAAE,UACX,EAAU,EACV,KAAmD,EACnD,KAAe;YAEf,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACnC,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAClG,CAAC;QACN,CAAC;QACD,oBAAoB,EAAE,UAClB,EAAU,EACV,KAAmD,EACnD,KAAe;YAEf,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE,CACnC,cAAc,CAAC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CACjG,CAAC;QACN,CAAC;QACD,QAAQ,EAAE,UACN,EAAU,EACV,QAAiF;YAEjF,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,6CAA6C,OAAO,EAAE,wBAAwB,EAAE,OAAO,CAAC,CAAC;gBACrG,OAAO,SAAS,CAAC;YACrB,CAAC;YAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACpB,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CAChC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,4BAA4B,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CACjE,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE,CACvC,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,4BAA4B,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC,CACjE,CAAC;gBACN,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAK,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,CAAC;oBACxD,OAAO,CAAC,GAAG,CACP,uIAAuI,EACvI,OAAO,CACV,CAAC;oBACF,OAAO,CAAC,GAAG,CACP,kFAAkF,EAAE,8BAA8B,EAClH,OAAO,CACV,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,IAAI,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;wBACb,OAAO,CAAC,OAAO;4BACX,OAAO,CAAC,GAAG,CACP,eAAe,EAAE,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,EAC5F,MAAM,CACT,CAAC;wBACN,IAAI,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;4BAC/C,OAAO,OAAO,CAAC,4BAA4B,CAAC,EAAE,EAAE,OAAO,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC,CAAC;wBACpF,CAAC;wBACD,OAAO,OAAO,CAAC,4BAA4B,CAAC,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;oBAChE,CAAC;yBAAM,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;wBAC9C,OAAO,CAAC,OAAO;4BACX,OAAO,CAAC,GAAG,CACP,eAAe,EAAE,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,QAAQ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,EACtH,MAAM,CACT,CAAC;wBACN,IAAI,OAAO,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;4BACzE,OAAO,OAAO,CAAC,4BAA4B,CACvC,EAAE,EACF,OAAO,CAAC,kBAAkB,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAC3D,CAAC;wBACN,CAAC;wBACD,OAAO,OAAO,CAAC,4BAA4B,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;oBAC1F,CAAC;oBAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;oBAClG,CAAC;oBAED,OAAO,CAAC,eAAe,CACnB,aAAa,EAAE,kBAAkB,MAAM,CAAC,EAAE,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,eAAe,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CACjH,CAAC,CAAC,MAAM;oBACT,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAA0C,CAAC;gBACjF,CAAC;YACL,CAAC;QACL,CAAC;QACD,WAAW,EAAE,UACT,EAAU,EACV,QAAyE;YAEzE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,gDAAgD,OAAO,EAAE,wBAAwB,EAAE,OAAO,CAAC,CAAC;gBACxG,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;oBACtC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;wBAC/B,QAAQ,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;wBACrB,OAAO;oBACX,CAAC;oBAED,IAAK,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,CAAC;wBACxD,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,KAAK,EAAE,EAAE;4BACvC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC;wBAC3B,CAAC,CAAC,CAAC;oBACP,CAAC;yBAAM,CAAC;wBACJ,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;oBAChC,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC;iBAAM,CAAC;gBACJ,IAAK,OAAO,CAAC,MAAkC,CAAC,SAAS,EAAE,CAAC;oBACxD,OAAO,CAAC,GAAG,CACP,0IAA0I,EAC1I,OAAO,CACV,CAAC;oBACF,OAAO,CAAC,GAAG,CACP,wFAAwF,EAAE,oCAAoC,EAC9H,OAAO,CACV,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACxB,CAAC;YACL,CAAC;QACL,CAAC;QACD,YAAY,EAAE,UACV,EAAU,EACV,QAA0E;YAE1E,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CACP,iDAAiD,OAAO,EAAE,wBAAwB,EAClF,OAAO,CACV,CAAC;gBACF,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YACrE,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;QACD,WAAW,EAAE,UAAU,IAAY,EAAE,WAAqB;YACtD,OAAO,CAAC,OAAO;gBACX,OAAO,CAAC,GAAG,CACP,oBAAoB,IAAI,iBAAiB,WAAW,QAAQ,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,EACjG,MAAM,CACT,CAAC;YACN,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,EAAE,CAAC;gBAC5D,IAAI,WAAW,EAAE,CAAC;oBACd,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC7F,CAAC;gBACD,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YAC/B,CAAC;YACD,IAAI,WAAW,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;YACd,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,SAAS,EAAE,UACP,EAAU,EACV,QAAiG,EACjG,EAA0E;YAE1E,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;gBACzB,OAAO,CAAC,GAAG,CAAC,8CAA8C,OAAO,EAAE,wBAAwB,EAAE,OAAO,CAAC,CAAC;gBACtG,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,EAAE,GAAG,QAAQ,CAAC;gBACd,QAAQ,GAAG,IAAI,CAAC;YACpB,CAAC;YACD,gBAAgB;YAChB,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;gBAC3B,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;oBACtC,IAAI,GAAG,EAAE,CAAC;wBACN,OAAO,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;oBACtB,CAAC;yBAAM,IAAI,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;wBACrB,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;oBACvB,CAAC;oBACD,IAAI,MAA0C,CAAC;oBAC/C,IAAI,CAAC;wBACD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;oBACrD,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE;4BACrE,GAAG,EAAE,IAAI;4BACT,GAAG,EAAE,IAAI;4BACT,CAAC,EAAE,WAAW;yBACjB,CAAC,CAAC;wBACH,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,sBAAsB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;wBAC/E,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;oBAC1B,CAAC;oBACD,OAAO,CAAC,OAAO;wBACX,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAc,QAAQ,QAAQ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;oBAClG,EAAE,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBACpB,CAAC,CAAC,CAAC;YACP,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;oBACf,OAAO,CAAC,OAAO;wBACX,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAc,QAAQ,qBAAqB,EAAE,MAAM,CAAC,CAAC;oBACvF,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,kBAAkB,EAAE,MAAM,CAAC,CAAC;oBACrD,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,IAAI,QAAQ,EAAE,CAAC;oBACX,MAAM,CAAC,GAAG,QAAQ,CAAC,kBAAkB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;oBACnD,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;oBACpD,GAAG,CAAC,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;oBACpD,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;oBACxD,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;wBAC/B,MAAM,CAAC,GAAG,IAAI,MAAM,CAAC,WAAW,QAAQ,KAAK,CAAC,CAAC;wBAC/C,KAAK,IAAI,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;4BAC/C,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gCAC1B,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gCACzB,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;4BAC/B,CAAC;wBACL,CAAC;oBACL,CAAC;oBACD,OAAO,CAAC,OAAO;wBACX,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAc,QAAQ,QAAQ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;oBAE/F,OAAO,GAAG,CAAC;gBACf,CAAC;gBACD,IAAI,MAA0C,CAAC;gBAC/C,IAAI,CAAC;oBACD,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;gBACrD,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACpB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE;wBACrE,GAAG,EAAE,IAAI;wBACT,GAAG,EAAE,IAAI;wBACT,CAAC,EAAE,WAAW;qBACjB,CAAC,CAAC;oBACH,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,sBAAsB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;oBAC/E,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,cAAc,QAAQ,QAAQ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gBAClG,OAAO,MAAM,CAAC;YAClB,CAAC;QACL,CAAC;QACD,mFAAmF;QACnF,SAAS,EAAE,UACP,GAAW,EACX,IAAqB,EACrB,QAA6D;YAE7D,OAAO,CAAC,GAAG,CAAC,wEAAwE,EAAE,OAAO,CAAC,CAAC;YAC/F,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC;oBACD,QAAQ,CAAC,IAAI,CACT,OAAO,EACP,IAAI,KAAK,CAAC,wEAAwE,CAAC,CACtF,CAAC;gBACN,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;QACL,CAAC;QACD,mFAAmF;QACnF,YAAY,EAAE,UACV,GAAW,EACX,IAA8B,EAC9B,QAA6D;YAE7D,OAAO,CAAC,GAAG,CAAC,2EAA2E,EAAE,OAAO,CAAC,CAAC;YAClG,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC;oBACD,QAAQ,CAAC,IAAI,CACT,OAAO,EACP,IAAI,KAAK,CAAC,2EAA2E,CAAC,CACzF,CAAC;gBACN,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;QACL,CAAC;QACD,mFAAmF;QACnF,YAAY,EAAE,UACV,GAAW,EACX,YAA+C,EAC/C,QAAiC;YAEjC,IAAI,OAAO,YAAY,KAAK,UAAU,EAAE,CAAC;gBACrC,QAAQ,GAAG,YAAY,CAAC;YAC5B,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,2EAA2E,EAAE,OAAO,CAAC,CAAC;YAClG,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,IAAI,CAAC;oBACD,QAAQ,CAAC,IAAI,CACT,OAAO,EACP,IAAI,KAAK,CAAC,2EAA2E,CAAC,CACzF,CAAC;gBACN,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;QACL,CAAC;QACD,QAAQ,EAAE,UAAU,QAAiB;YACjC,MAAM,MAAM,GAA2E,EAAE,CAAC;YAC1F,MAAM,CAAC,GAAG,QAAQ,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,WAAW,QAAQ,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;YAClE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;oBACzB,MAAM,MAAM,GACP,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAyB,CAAC,MAAM,IAAK,EAA0B,CAAC;oBACrF,MAAM,CAAC,IAAI,CAAC;wBACR,EAAE,EAAE,KAAK,CAAC,CAAC,CAAC;wBACZ,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,EAAE;wBAC7B,IAAI,EAAE,MAAM,CAAC,IAAI,IAAI,EAAE;qBAC1B,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;YACD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,QAAQ,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACvF,CAAC;YACD,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;QAC9C,CAAC;QACD,WAAW,EAAE,UACT,IAAY,EACZ,KAA2B,EAC3B,aAAkG,EAClG,MAA4F,EAC5F,MAA4D,EAC5D,QAAsC;YAEtC,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC/B,QAAQ,GAAG,MAAqC,CAAC;gBACjD,MAAM,GAAG,EAAE,CAAC;YAChB,CAAC;YACD,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC/B,QAAQ,GAAG,MAAqC,CAAC;gBACjD,MAAM,GAAG,SAAS,CAAC;YACvB,CAAC;YACD,IAAI,OAAO,aAAa,KAAK,UAAU,EAAE,CAAC;gBACtC,QAAQ,GAAG,aAA4C,CAAC;gBACxD,aAAa,GAAG,SAAS,CAAC;YAC9B,CAAC;YACD,IAAI,IAAA,gBAAQ,EAAC,aAAa,CAAC,EAAE,CAAC;gBAC1B,MAAM,GAAG,MAAM,CAAC;gBAChB,MAAM,GAAG,aAA+C,CAAC;gBACzD,aAAa,GAAG,SAAS,CAAC;YAC9B,CAAC;YAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,uBAAuB,OAAO,IAAI,uBAAuB,CAAC;gBACtE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC3C,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,OAAO;YACX,CAAC;YAED,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,MAAM,GAAG,GAAG,0BAA0B,CAAC;gBACvC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC3C,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,OAAO;YACX,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC/B,IAAI,GAAG,WAAW,IAAI,EAAE,CAAC;YAC7B,CAAC;YAED,MAAM,OAAO,GAAmC,MAAwC,IAAI,EAAE,CAAC;YAC/F,IAAI,IAAA,gBAAQ,EAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,oCAAoC;YACxC,CAAC;iBAAM,IACH,IAAA,gBAAQ,EAAC,KAAK,CAAC;gBACf,CAAC,OAAQ,KAAqB,CAAC,EAAE,KAAK,QAAQ,IAAI,IAAA,gBAAQ,EAAE,KAAqB,CAAC,EAAE,CAAC,CAAC,EACxF,CAAC;gBACC,OAAO,CAAC,KAAK,GAAG,KAAoB,CAAC;YACzC,CAAC;iBAAM,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;gBACnC,OAAO,CAAC,KAAK,GAAG,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;YAClC,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,GAAG,sEAAsE,CAAC;gBACnF,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC3C,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,OAAO;YACX,CAAC;YAED,IAAI,aAAa,GAAG,EAAE,CAAC;YACvB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAChB,aAAa,GAAG,IAAA,gBAAQ,EAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACtC,CAAC,CAAE,OAAO,CAAC,KAAK,CAAC,EAAsC,CAAC,IAAI;oBAC5D,CAAC,CAAE,OAAO,CAAC,KAAK,CAAC,EAAa,CAAC;gBACnC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,aAAa,EAAE,CAAC,EAAE,CAAC;oBAC9E,aAAa,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,aAAa,EAAE,CAAC;oBACxD,IAAI,IAAA,gBAAQ,EAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;wBAC5B,OAAO,CAAC,KAAK,CAAC,EAAsC,CAAC,IAAI,GAAG,aAAa,CAAC;oBAC/E,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,KAAK,CAAC,EAAE,GAAG,aAAa,CAAC;oBACrC,CAAC;gBACL,CAAC;gBACD,IACI,IAAA,gBAAQ,EAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;oBACzB,OAAO,CAAC,KAAK,CAAC,EAAsC,CAAC,KAAK;oBAC3D,CAAC,OAAO,CAAE,OAAO,CAAC,KAAK,CAAC,EAAsC,CAAC,KAAK,CAAC;oBACrE,OAAO,CAAC,GAAG,OAAO,CAAC,SAAS,IAAK,OAAO,CAAC,KAAK,CAAC,EAAsC,CAAC,KAAK,EAAE,CAAC,EAChG,CAAC;oBACE,OAAO,CAAC,KAAK,CAAC,EAAsC,CAAC,KAAK;wBACvD,GAAG,OAAO,CAAC,SAAS,IAAK,OAAO,CAAC,KAAK,CAAC,EAAsC,CAAC,KAAK,EAAE,CAAC;gBAC9F,CAAC;YACL,CAAC;YACD,MAAM,GAAG,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC;YACnC,IAAI,CAAC,GAAG,EAAE,CAAC;gBACP,MAAM,GAAG,GAAG,wBAAwB,aAAa,mBAAmB,CAAC;gBACrE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC3C,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,OAAO;YACX,CAAC;YACD,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACvB,MAAM,GAAG,GAAG,wBAAwB,aAAa,2BAA2B,CAAC;gBAC7E,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC3C,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,OAAO;YACX,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC7B,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,IAAI,CAAC;YAC3C,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9D,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YACnC,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9D,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YACnC,CAAC;YACD,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;gBAC5D,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;YACjC,CAAC;YACD,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;gBAC5D,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC;YACjC,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9D,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YACnC,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9D,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YACnC,CAAC;YACD,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;gBAC9D,OAAO,CAAC,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YACnC,CAAC;YAED,OAAO,OAAO,CAAC,WAAW,CACtB,IAAI,EACJ,SAAS,EACT,aAAwB,EACxB,OAAO,EACP,MAAM,EACN,QAAwC,CAC3C,CAAC;QACN,CAAC;QACD,WAAW,EAAE,KAAK,WACd,IAAY,EACZ,SAA2D,EAC3D,aAKmC,EACnC,MAAsE,EACtE,MAA4D,EAC5D,QAAiE;YAEjE,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC/B,QAAQ,GAAG,MAAsC,CAAC;gBAClD,MAAM,GAAG,EAAE,CAAC;YAChB,CAAC;YACD,IAAI,OAAO,MAAM,KAAK,UAAU,EAAE,CAAC;gBAC/B,QAAQ,GAAG,MAAsC,CAAC;gBAClD,MAAM,GAAG,SAAS,CAAC;YACvB,CAAC;YACD,IAAI,OAAO,SAAS,KAAK,UAAU,EAAE,CAAC;gBAClC,QAAQ,GAAG,SAAyC,CAAC;gBACrD,SAAS,GAAG,SAAS,CAAC;YAC1B,CAAC;YACD,IAAI,OAAO,aAAa,KAAK,UAAU,EAAE,CAAC;gBACtC,QAAQ,GAAG,aAA6C,CAAC;gBACzD,aAAa,GAAG,SAAS,CAAC;YAC9B,CAAC;YACD,IAAI,IAAA,gBAAQ,EAAC,SAAS,CAAC,EAAE,CAAC;gBACtB,MAAM,GAAG,SAA0C,CAAC;gBACpD,MAAM,GAAG,aAAoC,CAAC;gBAC9C,aAAa,GAAG,SAAS,CAAC;gBAC1B,SAAS,GAAG,SAAS,CAAC;YAC1B,CAAC;YACD,IAAI,IAAA,gBAAQ,EAAC,aAAa,CAAC,EAAE,CAAC;gBAC1B,MAAM,GAAG,MAA6B,CAAC;gBACvC,MAAM,GAAG,aAA8C,CAAC;gBACxD,aAAa,GAAG,SAAS,CAAC;YAC9B,CAAC;YAED,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,MAAM,GAAG,GAAG,uBAAuB,OAAO,IAAI,uBAAuB,CAAC;gBACtE,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC3C,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,OAAO;YACX,CAAC;YAED,IAAI,CAAC,IAAI,EAAE,CAAC;gBACR,MAAM,GAAG,GAAG,0BAA0B,CAAC;gBACvC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC3C,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,OAAO;YACX,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YAE5C,MAAM,OAAO,GAAyB,CAAC,MAAM,IAAI,EAAE,CAAyB,CAAC;YAC7E,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,IAAI,CAAC;YACpC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC;YACvC,OAAO,CAAC,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC;YACvC,IAAI,CAAC,OAAO,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBACtC,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC;YAC5B,CAAC;YAED,MAAM,GAAG,MAAM,IAAI,EAAE,CAAC;YAEtB,2CAA2C;YAC3C,IAAI,OAAO,CAAC,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC1D,IAAI,GAAG,GAAG,CAAC,CAAC;gBACZ,IAAI,GAAG,GAAG,CAAC,CAAC;gBACZ,IAAI,GAAG,GAAG,CAAC,CAAC;gBACZ,IAAI,GAAuB,CAAC;gBAC5B,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;oBAC5B,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;oBAClB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;wBAC1B,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;wBACtB,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;4BACb,GAAG,GAAG,iBAAiB,IAAI,aAAa,CAAC;4BACzC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;4BAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gCACjC,IAAI,CAAC;oCACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;gCAC3C,CAAC;gCAAC,OAAO,GAAY,EAAE,CAAC;oCACpB,eAAe,CAAC,GAAY,CAAC,CAAC;gCAClC,CAAC;4BACL,CAAC;4BACD,OAAO;wBACX,CAAC;wBACD,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;oBACtB,CAAC;gBACL,CAAC;gBACD,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;oBAC5B,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;oBAClB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;wBAC1B,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;wBACtB,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;4BACb,GAAG,GAAG,iBAAiB,IAAI,aAAa,CAAC;4BACzC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;4BAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gCACjC,IAAI,CAAC;oCACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;gCAC3C,CAAC;gCAAC,OAAO,GAAY,EAAE,CAAC;oCACpB,eAAe,CAAC,GAAY,CAAC,CAAC;gCAClC,CAAC;4BACL,CAAC;4BACD,OAAO;wBACX,CAAC;wBACD,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;oBACtB,CAAC;gBACL,CAAC;gBAED,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;oBAC5B,IAAI,OAAO,EAAE,CAAC;wBACV,OAAO,OAAO,CAAC,GAAG,CAAC;oBACvB,CAAC;yBAAM,CAAC;wBACJ,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;wBAClB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;4BAC1B,GAAG,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;4BACtB,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;gCACb,GAAG,GAAG,iBAAiB,IAAI,aAAa,CAAC;gCACzC,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;gCAC1B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oCACjC,IAAI,CAAC;wCACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;oCAC3C,CAAC;oCAAC,OAAO,GAAY,EAAE,CAAC;wCACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oCAClC,CAAC;gCACL,CAAC;gCACD,OAAO;4BACX,CAAC;4BACD,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;wBACtB,CAAC;oBACL,CAAC;gBACL,CAAC;gBAED,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;oBACtE,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;oBAClB,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;gBACtB,CAAC;gBACD,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;oBACtE,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;gBACtB,CAAC;gBACD,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS,IAAI,GAAG,GAAG,GAAG,EAAE,CAAC;oBACtE,OAAO,CAAC,GAAG,GAAG,GAAG,CAAC;gBACtB,CAAC;YACL,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CACP,oBAAoB,IAAI,eAAe,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,mBAAmB,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,aAAa,OAAO,GAAG,EAC3M,OAAO,CACV,CAAC;YACN,CAAC;YAED,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,SAAS,IAAI,IAAI,EAAE,CAAC;YACxC,IAAI,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,OAAO,EAAE,CAAC;gBAClF,EAAE,GAAG,IAAI,CAAC;YACd,CAAC;YACD,IAAI,EAAE,CAAC,KAAK,CAAC,iCAAiC,CAAC,EAAE,CAAC;gBAC9C,OAAO,CAAC,GAAG,CACP,eAAe,EAAE,mGAAmG,EACpH,MAAM,CACT,CAAC;YACN,CAAC;iBAAM,IAAI,EAAE,CAAC,KAAK,CAAC,iCAAiC,CAAC,EAAE,CAAC;gBACrD,OAAO,CAAC,GAAG,CACP,eAAe,EAAE,mGAAmG,EACpH,MAAM,CACT,CAAC;YACN,CAAC;YAED,uCAAuC;YACvC,mJAAmJ;YACnJ,kJAAkJ;YAClJ,IAAI,CAAC,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAC5B,2CAA2C;gBAC3C,IAAI,KAAkB,CAAC;gBACvB,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACpC,KAAK,GAAG;wBACJ,EAAE,EAAE,OAAO,CAAC,KAAK;qBACpB,CAAC;gBACN,CAAC;qBAAM,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;oBAC5C,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAC5B,KAAK,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC;oBACnB,KAAK,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;oBAEf,KAAK,GAAG;wBACJ,EAAE,EAAE,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC;qBACtB,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;gBAC1B,CAAC;gBACD,OAAO,OAAO,CAAC,KAAK,CAAC;gBAErB,IAAI,CAAE,KAAK,CAAC,EAAa,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;oBAC/C,KAAK,CAAC,EAAE,GAAG,WAAW,KAAK,CAAC,EAAY,EAAE,CAAC;gBAC/C,CAAC;gBAED,IAAI,IAA6C,CAAC;gBAClD,IAAI,CAAC;oBACD,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAY,CAAC,CAGhD,CAAC;gBACpB,CAAC;gBAAC,MAAM,CAAC;oBACL,SAAS;gBACb,CAAC;gBACD,IAAI,CAAC,IAAI,EAAE,CAAC;oBACR,IAAI,CAAC;wBACD,MAAM,IAAI,GAAyB;4BAC/B,GAAG,EAAE,KAAK,CAAC,EAAY;4BACvB,IAAI,EAAE,OAAO;4BACb,MAAM,EAAE;gCACJ,IAAI,EAAE,YAAY,EAAE,EAAE;gCACtB,IAAI,EAAE,OAAO;gCACb,IAAI,EAAE,OAAO,CAAC,IAAI;gCAClB,IAAI,EAAE,OAAO,CAAC,IAAI;gCAClB,KAAK,EAAE,OAAO,CAAC,KAAK;gCACpB,IAAI,EAAE,OAAO,CAAC,IAAI;gCAClB,KAAK,EAAE;oCACH,EAAE;oCACF,IAAI,EAAE,KAAK,CAAC,IAAI;oCAChB,KAAK,EAAE,KAAK,CAAC,KAAK;iCACrB;6BACJ;4BACD,MAAM,EAAE,EAAE;yBACb,CAAC;wBAEF,MAAM,OAAO,CAAC,qBAAqB,CAAC,KAAK,CAAC,EAAY,EAAE,IAAI,CAAC,CAAC;oBAClE,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,OAAO,CAAC,GAAG,CAAC,wBAAwB,KAAK,CAAC,EAAY,MAAM,GAAY,EAAE,EAAE,OAAO,CAAC,CAAC;oBACzF,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;gBAClC,IAAI,OAAO,OAAO,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACpC,OAAO,CAAC,KAAK,GAAG;wBACZ,EAAE,EAAE,OAAO,CAAC,KAAK;qBACpB,CAAC;gBACN,CAAC;gBACD,MAAM,MAAM,GAAG,OAAO,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC;gBAC/F,IAAI,OAAO,GACP,OAAO,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC;gBACrF,IAAI,OAAO,KAAK,MAAM,EAAE,CAAC;oBACrB,OAAO,GAAG,SAAS,CAAC;gBACxB,CAAC;gBACD,kCAAkC;gBAClC,IAAI,IAA6C,CAAC;gBAClD,IAAI,CAAC;oBACD,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,qBAAqB,CAAC,MAAM,CAAC,CAA4C,CAAC;gBACpG,CAAC;gBAAC,MAAM,CAAC;oBACL,SAAS;gBACb,CAAC;gBACD,IAAI,CAAC,IAAI,EAAE,CAAC;oBACR,IAAI,CAAC;wBACD,MAAM,OAAO,CAAC,qBAAqB,CAAC,MAAM,EAAE;4BACxC,IAAI,EAAE,OAAO;4BACb,MAAM,EAAE;gCACJ,IAAI,EAAE,aAAa,EAAE,EAAE;gCACvB,IAAI,EAAE,OAAO;gCACb,IAAI,EAAE,OAAO,CAAC,IAAI;gCAClB,IAAI,EAAE,OAAO,CAAC,IAAI;gCAClB,KAAK,EAAE,OAAO,CAAC,KAAK;gCACpB,IAAI,EAAE,OAAO,CAAC,IAAI;6BACrB;4BACD,MAAM,EAAE,EAAE;yBACb,CAAC,CAAC;oBACP,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,OAAO,CAAC,GAAG,CAAC,wBAAwB,MAAM,MAAM,GAAY,EAAE,EAAE,OAAO,CAAC,CAAC;oBAC7E,CAAC;gBACL,CAAC;gBACD,IAAI,OAAO,IAAI,OAAO,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;oBACrC,IAAI,CAAC;wBACD,IAAI,GAAG,CAAC,MAAM,OAAO,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAGrC,CAAC;oBACpB,CAAC;oBAAC,MAAM,CAAC;wBACL,SAAS;oBACb,CAAC;oBACD,IAAI,CAAC,IAAI,EAAE,CAAC;wBACR,IAAI,CAAC;4BACD,MAAM,OAAO,CAAC,qBAAqB,CAAC,OAAO,EAAE;gCACzC,IAAI,EAAE,OAAO;gCACb,MAAM,EAAE;oCACJ,IAAI,EAAE,mBAAmB,EAAE,EAAE;oCAC7B,IAAI,EAAE,OAAO;oCACb,IAAI,EAAE,OAAO,CAAC,IAAI;oCAClB,IAAI,EAAE,OAAO,CAAC,IAAI;oCAClB,KAAK,EAAE,OAAO,CAAC,KAAK;oCACpB,IAAI,EAAE,OAAO,CAAC,IAAI;iCACrB;gCACD,MAAM,EAAE,EAAE;6BACb,CAAC,CAAC;wBACP,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,OAAO,CAAC,GAAG,CAAC,wBAAwB,OAAO,MAAM,GAAY,EAAE,EAAE,OAAO,CAAC,CAAC;wBAC9E,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;YAED,IAAI,GAAuC,CAAC;YAC5C,IAAI,CAAC;gBACD,GAAG,GAAG,MAAM,OAAO,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAAC;YAClD,CAAC;YAAC,MAAM,CAAC;gBACL,SAAS;YACb,CAAC;YAED,IACI,GAAG,EAAE,GAAG;gBACR,iCAAiC,CAAC,GAAG,CAAC,GAAG,CAAC;gBAC1C,GAAG,CAAC,IAAI,KAAK,QAAQ;gBACrB,GAAG,CAAC,MAAM;gBACV,GAAG,CAAC,MAAM,CAAC,WAAW,KAAK,2BAA2B,EACxD,CAAC;gBACC,2EAA2E;gBAC3E,GAAG,GAAG,IAAI,CAAC;YACf,CAAC;YAED,IAAI,CAAC,GAAG,IAAI,aAAa,EAAE,CAAC;gBACxB,iBAAiB;gBACjB,MAAM,MAAM,GAAyB;oBACjC,GAAG,EAAE,EAAE;oBACP,MAAM,EAAE,OAAO;oBACf,MAAM;oBACN,IAAI,EAAE,OAAO;iBAChB,CAAC;gBACF,IAAI,CAAC;oBACD,MAAM,OAAO,CAAC,qBAAqB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gBACpD,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACpB,OAAO,CAAC,GAAG,CAAC,sBAAsB,EAAE,MAAM,GAAY,EAAE,EAAE,MAAM,CAAC,CAAC;oBAClE,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,GAAY,CAAC,CAAC;wBACzC,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC;oBACD,OAAO;gBACX,CAAC;gBAED,sBAAsB;gBACtB,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gBAExC,IAAI,CAAC,OAAO,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;oBACtC,IAAI,IAAA,gBAAQ,EAAC,SAAS,CAAC,IAAK,SAA4B,CAAC,GAAG,KAAK,SAAS,EAAE,CAAC;wBACzE,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;oBAClE,CAAC;yBAAM,CAAC;wBACJ,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;oBACxE,CAAC;gBACL,CAAC;qBAAM,IAAI,CAAC,OAAO,IAAI,CAAC,aAAa,EAAE,CAAC;oBACpC,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;gBAC7D,CAAC;qBAAM,IAAI,OAAO,EAAE,CAAC;oBACjB,IAAI,CAAC;wBACD,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;wBACrD,IAAI,KAAK,EAAE,CAAC;4BACR,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;wBACvB,CAAC;oBACL,CAAC;oBAAC,MAAM,CAAC;wBACL,SAAS;oBACb,CAAC;oBACD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;wBACrC,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC;gBACL,CAAC;qBAAM,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACxC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;oBACrC,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBACD,MAAM,qBAAqB,CAAC,EAAE,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACJ,mBAAmB;gBACnB,IACI,CAAE,OAAO,CAAC,MAAkC,CAAC,SAAS;oBACtD,CAAC,MAAM,CAAC,EAAE,CAAC;oBACX,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,KAAK,SAAS,EACpD,CAAC;oBACC,MAAM,CAAC,EAAE,CAAC,GAAG;wBACT,GAAG,EAAE,IAAI;wBACT,GAAG,EAAE,IAAI;wBACT,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;wBACd,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE;wBACd,CAAC,EAAE,CAAC;wBACJ,IAAI,EAAE,kBAAkB,OAAO,CAAC,SAAS,EAAE;qBAC9C,CAAC;gBACN,CAAC;gBACD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;oBACrC,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;gBAED,MAAM,qBAAqB,CAAC,EAAE,CAAC,CAAC;YACpC,CAAC;QACL,CAAC;QACD,WAAW,EAAE,UAAU,EAAU,EAAE,QAAmE;YAClG,qBAAqB;YACrB,iCAAiC;YAEjC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,GAAG,EAAE,OAAO,CAAC,CAAC;YAClD,CAAC;YAED,IAAI,KAAK,GAAG,KAAK,CAAC;YAClB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,IAAI,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;gBACtF,KAAK,GAAG,IAAI,CAAC;gBACb,OAAO,OAAO,CAAC,EAAE,CAAC,CAAC;gBACnB,IAAI,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;oBACb,OAAO,MAAM,CAAC,EAAE,CAAC,CAAC;gBACtB,CAAC;gBAED,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,UAAU,GAAG;oBACtC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,qBAAqB,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;oBAE9E,OAAO,CAAC,eAAe,CAAC,EAAE,EAAE,UAAU,GAAG;wBACrC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;wBACnE,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;4BACjC,IAAI,CAAC;gCACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;4BACvC,CAAC;4BAAC,OAAO,GAAY,EAAE,CAAC;gCACpB,eAAe,CAAC,GAAY,CAAC,CAAC;4BAClC,CAAC;wBACL,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC,CAAC,CAAC;YACP,CAAC;iBAAM,IAAI,OAAO,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;gBAC/C,OAAO,OAAO,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC;gBAC7C,KAAK,GAAG,IAAI,CAAC;gBACb,IAAI,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC;oBACvC,OAAO,MAAM,CAAC,GAAG,OAAO,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC;gBAChD,CAAC;gBAED,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,UAAU,GAAG;oBAC/B,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,qBAAqB,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC;oBAE9E,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,UAAU,GAAG;wBAC9B,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;wBACnE,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;4BACjC,IAAI,CAAC;gCACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;4BACvC,CAAC;4BAAC,OAAO,GAAY,EAAE,CAAC;gCACpB,eAAe,CAAC,GAAY,CAAC,CAAC;4BAClC,CAAC;wBACL,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC,CAAC,CAAC;YACP,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,GAAG,WAAW,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,wBAAwB,EAAE,MAAM,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC5D,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,GAAG,CAAC,EAAE,KAAK,CAAC,CAAC;oBAClD,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QACD,MAAM,EAAE,UACJ,QAAgB,EAChB,GAAW,EACX,GAAS,EACT,OAAuG,EACvG,QAAgF;YAEhF,MAAM,cAAc,GAAG,KAAK,CAAC;YAE7B,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,QAAQ,GAAG,OAAgF,CAAC;gBAC5F,OAAO,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;YAC1C,CAAC;YAED,IAAI,OAAO,GAA0B,IAAI,CAAC;YAC1C,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC;gBAEzE,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;oBACtB,OAAO,GAAG,IAAI,CAAC;oBAEf,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,sBAAsB,eAAe,EAAE,EAAE,OAAO,CAAC,CAAC;oBAClE,CAAC;oBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,OAA8B,EAAE,QAAQ,CAAC,CAAC;wBAC3F,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;wBACD,QAAQ,GAAG,SAAS,CAAC;oBACzB,CAAC;gBACL,CAAC,EAAE,eAAe,CAAC,CAAC;YACxB,CAAC;YAED,IAAI,MAA2C,CAAC;YAChD,IAAI,OAAO,EAAE,CAAC;gBACV,MAAM,GAAG,UAAU,MAAW;oBAC1B,IAAI,OAAO,EAAE,CAAC;wBACV,YAAY,CAAC,OAAO,CAAC,CAAC;wBACtB,OAAO,GAAG,IAAI,CAAC;oBACnB,CAAC;oBAED,IAAI,OAAO,CAAC,OAAO,IAAI,MAAM,EAAE,CAAC;wBAC5B,OAAO,CAAC,GAAG,CAAC,aAAa,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;oBAChE,CAAC;oBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAA8B,EAAE,QAAQ,CAAC,CAAC;wBAC7E,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;wBACD,QAAQ,GAAG,SAAS,CAAC;oBACzB,CAAC;gBACL,CAAC,CAAC;YACN,CAAC;YAED,uBAAuB;YACvB,IAAI,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC9B,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CACP,mBAAmB,QAAQ,SAAS,GAAG,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,OAAO,QAAQ,KAAK,UAAU,GAAG,EACrH,MAAM,CACT,CAAC;gBAEN,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;YACxD,CAAC;iBAAM,CAAC;gBACJ,2BAA2B;gBAC3B,OAAO,CAAC,OAAO,CAAC,aAAa,CACzB,QAAQ,EACR,UAAU,EACV,EAAE,QAAQ,EAAE,kBAAkB,QAAQ,GAAG,EAAE,MAAM,EAAE,kBAAkB,QAAQ,SAAS,EAAE,EACxF,OAAO,EACP,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;oBACT,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;wBACd,OAAO,CAAC,GAAG,CAAC,kBAAkB,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;wBACvD,OAAO;oBACX,CAAC;oBAED,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,CAAC;oBAEpF,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;wBACzB,OAAO,CAAC,OAAO;4BACX,OAAO,CAAC,GAAG,CACP,mBAAmB,QAAQ,SAAS,GAAG,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,iBAAiB,OAAO,QAAQ,KAAK,UAAU,GAAG,EACrH,MAAM,CACT,CAAC;wBACN,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;oBACxD,CAAC,CAAC,CAAC;gBACP,CAAC,CACJ,CAAC;YACN,CAAC;QACL,CAAC;QACD,MAAM,EAAE,UACJ,QAAgB,EAChB,GAAW,EACX,GAAQ,EACR,QAAgF;YAEhF,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;QACxD,CAAC;QACD,WAAW,EAAE,UAAU,QAAgB,EAAE,GAAW,EAAE,GAAS,EAAE,OAA6B;YAC1F,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACnC,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,GAAG,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE;oBAC9C,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;wBACpB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;oBACpE,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,GAAG,CAAC,CAAC;oBACjB,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC;QACD,UAAU,EAAE,UAAU,IAAY,EAAE,GAAW,EAAE,GAAS,EAAE,QAAgC;YACxF,IAAI,CAAE,OAAO,CAAC,MAAkC,CAAC,gBAAgB,EAAE,CAAC;gBAChE,MAAM,KAAK,GACP,4FAA4F,CAAC;gBACjG,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBAE5B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,+EAA+E;oBAC/E,YAAY,CAAC;wBACT,QAAQ,CAAC,KAAK,CAAC,CAAC;oBACpB,CAAC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,SAAS,GAAG,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC/F,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,CAAC,CAAC;YACjD,CAAC;QACL,CAAC;QACD,eAAe,EAAE,UAAU,IAAY,EAAE,GAAW,EAAE,GAAS;YAC3D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACnC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,EAAE;oBACrC,IAAI,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,EAAE,CAAC;wBACpB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;oBACpE,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,GAAG,CAAC,CAAC;oBACjB,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC;QACD,oBAAoB,EAAE,UAAU,GAAW,EAAE,OAAiB;YAC1D,MAAM,QAAQ,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,aAAa,CAAC;YAE5D,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,cAAc,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;YAClF,CAAC;YAED,OAAO,CAAC,oBAAoB,CAAC,YAAY,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC9D,CAAC;QACD,WAAW,EAAE,UAAU,QAAkC,EAAE,EAAU,EAAE,GAAG,IAAW;YACjF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,MAAM,GAAG,GAAmB,WAAW,CAAC,GAAG,EAAE;oBACzC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;oBACpC,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC,EAAE,EAAE,CAAC,CAAC;gBACP,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAE3B,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;gBACjD,CAAC;gBACD,OAAO,GAAG,CAAC;YACf,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,uCAAuC,OAAO,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;YAC/E,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,aAAa,EAAE,UAAU,EAAkB;YACvC,MAAM,GAAG,GAAG,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACzC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACb,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,MAAM,CAAC,CAAC;gBACtD,CAAC;gBACD,aAAa,CAAC,EAAE,CAAC,CAAC;gBAClB,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,8BAA8B,EAAE,MAAM,CAAC,CAAC;gBACxD,CAAC;YACL,CAAC;QACL,CAAC;QACD,UAAU,EAAE,UAAU,QAAgC,EAAE,EAAU,EAAE,GAAG,IAAW;YAC9E,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,MAAM,EAAE,GAAG,UAAU,CAAC,GAAG,EAAE;oBACvB,+BAA+B;oBAC/B,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBACxC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;wBACb,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;oBACnC,CAAC;oBAED,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,CAAC;oBACpC,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC,EAAE,EAAE,CAAC,CAAC;gBACP,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;gBAChD,CAAC;gBAED,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACzB,OAAO,EAAE,CAAC;YACd,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,sCAAsC,OAAO,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;YAC9E,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,YAAY,EAAE,UAAU,EAAkB;YACtC,MAAM,GAAG,GAAG,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACxC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACb,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,MAAM,CAAC,CAAC;gBACrD,CAAC;gBACD,YAAY,CAAC,EAAE,CAAC,CAAC;gBACjB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACnC,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,6BAA6B,EAAE,MAAM,CAAC,CAAC;gBACvD,CAAC;YACL,CAAC;QACL,CAAC;QACD,YAAY,EAAE,UAAU,QAAmC,EAAE,GAAG,IAAW;YACvE,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,YAAY,CAAC,GAAG,EAAE;oBACd,IAAI,CAAC;wBACD,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;oBAClC,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;gBAC1C,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,GAAG,CAAC,wCAAwC,OAAO,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAC;YACpF,CAAC;QACL,CAAC;QACD,EAAE,EAAE,UAAU,QAAmC;YAC7C,OAAO,UAAU,IAAW;gBACxB,IAAI,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;oBAC7C,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;wBAClC,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,GAAG,CAAC,uCAAuC,IAAI,EAAE,EAAE,MAAM,CAAC,CAAC;gBACvE,CAAC;YACL,CAAC,CAAC;QACN,CAAC;QACD,WAAW,EAAE,UACT,SAAmD,EACnD,OAAwD,EACxD,SAAmF,EACnF,IAA+C;YAE/C,IAAI,SAAS,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAC7C,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;gBACjE,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACb,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC1D,IAAI,KAAK,EAAE,CAAC;wBACR,SAAS,GAAG,KAAK,CAAC,kBAAkB,CAAC,EAAE,EAAE;4BACrC,IAAI,EAAE,SAAS;4BACf,MAAM,EAAE,SAAS;4BACjB,MAAM,EAAE,KAAK;yBAChB,CAAC,CAAC;oBACP,CAAC;yBAAM,CAAC;wBACJ,SAAS,GAAG,CAAC,CAAC;oBAClB,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,IAAI,SAAS,IAAI,IAAA,gBAAQ,EAAC,SAAS,CAAC,IAAK,SAA6B,CAAC,KAAK,EAAE,CAAC;gBAClF,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAC7B,SAA6B,CAAC,KAAK,EACnC,SAA6B,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,EAChD,SAA6B,CAAC,MAAM,IAAI,CAAC,CAC7C,CAAC;gBACF,IAAI,KAAK,EAAE,CAAC;oBACR,SAAS,GAAG,KAAK,CAAC,kBAAkB,CAAC,EAAE,EAAE;wBACrC,IAAI,EAAE,SAAS;wBACf,MAAM,EAAE,SAAS;wBACjB,MAAM,EAAE,KAAK;qBAChB,CAAC,CAAC;gBACP,CAAC;qBAAM,CAAC;oBACJ,SAAS,GAAG,CAAC,CAAC;gBAClB,CAAC;YACL,CAAC;YAED,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACzC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC/D,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACb,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;oBAC1D,OAAO;wBACH,KAAK,EAAE,kBAAkB,CAAC,EAAE,EAAE;4BAC1B,IAAI,EAAE,SAAS;4BACf,MAAM,EAAE,SAAS;4BACjB,MAAM,EAAE,KAAK;yBAChB,CAAC,IAAI,CAAC,CAAC;gBAChB,CAAC;YACL,CAAC;iBAAM,IAAI,OAAO,IAAI,IAAA,gBAAQ,EAAC,OAAO,CAAC,IAAK,OAA2B,CAAC,KAAK,EAAE,CAAC;gBAC5E,MAAM,KAAK,GAAG,OAAO,CAAC,YAAY,CAC7B,OAA2B,CAAC,KAAK,EACjC,OAA2B,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,EAC9C,OAA2B,CAAC,MAAM,IAAI,CAAC,CAC3C,CAAC;gBACF,OAAO;oBACH,KAAK,EAAE,kBAAkB,CAAC,EAAE,EAAE;wBAC1B,IAAI,EAAE,SAAS;wBACf,MAAM,EAAE,SAAS;wBACjB,MAAM,EAAE,KAAK;qBAChB,CAAC,IAAI,CAAC,CAAC;YAChB,CAAC;YAED,+BAA+B;YAC/B,IAAI,KAAyB,CAAC;YAC9B,oDAAoD;YACpD,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC5D,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACb,KAAK,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;gBACxE,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,IAAI,IAAA,gBAAQ,EAAC,IAAI,CAAC,IAAK,IAAwB,CAAC,KAAK,EAAE,CAAC;gBACnE,KAAK;oBACD,OAAO;yBACF,YAAY,CACR,IAAwB,CAAC,KAAK,EAC9B,IAAwB,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,EAC3C,IAAwB,CAAC,MAAM,IAAI,CAAC,CACxC;wBACD,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAC7B,CAAC;YAED,IAAI,KAAK,GAAG,IAAI,CAAC;YACjB,IAAI,IAAI,EAAE,CAAC;gBACP,KAAK,GAAG,KAAK,CAAC;YAClB,CAAC;YACD,oBAAoB;YACpB,IAAI,CAAC,KAAK,EAAE,CAAC;gBACT,IAAI,IAAI,IAAI,CAAC,IAAA,gBAAQ,EAAC,IAAI,CAAC,EAAE,CAAC;oBAC1B,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;wBACzE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;wBAC9B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;wBACzB,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;wBACvC,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;wBACzC,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;wBAEzB,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;4BACrB,KAAK,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;wBAC7C,CAAC;6BAAM,CAAC;4BACJ,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;wBACxB,CAAC;wBACD,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;oBAC5B,CAAC;yBAAM,CAAC;wBACJ,KAAK,GAAG,IAAI,IAAI,CAAC,IAAuB,CAAC,CAAC,OAAO,EAAE,CAAC;oBACxD,CAAC;gBACL,CAAC;qBAAM,IAAI,CAAC,IAAI,EAAE,CAAC;oBACf,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC;oBACzB,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;oBACzB,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,CAAC;gBAC5B,CAAC;qBAAM,CAAC;oBACJ,UAAU;oBACV,KAAK,GAAI,IAAa,CAAC,OAAO,EAAE,CAAC;gBACrC,CAAC;YACL,CAAC;YACD,yCAAyC;YACzC,IAAI,OAAO,SAAS,KAAK,QAAQ,EAAE,CAAC;gBAChC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACvD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACnC,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;oBACvB,SAAS,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;oBAC3C,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;oBAC7C,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;oBAE7B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACrB,SAAS,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;oBACjD,CAAC;yBAAM,CAAC;wBACJ,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;oBAC5B,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,KAAK,GAAG,KAAK,CAAC;oBACd,SAAS,GAAG,IAAI,IAAI,CAAC,SAAS,CAAC,CAAC;gBACpC,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,KAAK,GAAG,KAAK,CAAC;gBACd,SAAS,GAAG,IAAI,IAAI,CAAC,SAA0B,CAAC,CAAC;YACrD,CAAC;YACD,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC;YAEvC,IAAI,QAAuB,CAAC;YAC5B,IAAI,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBACzC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBACjC,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;oBACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;oBACzC,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;oBAC3C,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;oBAE3B,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBACrB,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;oBAC/C,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;oBAC1B,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,KAAK,GAAG,KAAK,CAAC;oBACd,OAAO,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,CAAC;gBAChC,CAAC;YACL,CAAC;iBAAM,IAAI,OAAO,EAAE,CAAC;gBACjB,KAAK,GAAG,KAAK,CAAC;gBACd,OAAO,GAAG,IAAI,IAAI,CAAC,OAAwB,CAAC,CAAC;YACjD,CAAC;iBAAM,CAAC;gBACJ,OAAO,GAAG,IAAI,CAAC;YACnB,CAAC;YAED,IAAI,OAAO,EAAE,CAAC;gBACV,QAAQ,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;YACjC,CAAC;iBAAM,CAAC;gBACJ,QAAQ,GAAG,IAAI,CAAC;YACpB,CAAC;YAED,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;gBAC1B,IAAI,QAAQ,EAAE,CAAC;oBACX,IAAI,UAAU,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;wBACjC,OAAO,CAAC,CAAC,KAAK,IAAI,QAAQ,IAAI,KAAK,GAAG,UAAU,CAAC,CAAC;oBACtD,CAAC;oBACD,OAAO,KAAK,IAAI,UAAU,IAAI,KAAK,GAAG,QAAQ,CAAC;gBACnD,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,+CAA+C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gBAC9F,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,IAAI,SAAS,KAAK,aAAa,EAAE,CAAC;gBAC9B,IAAI,QAAQ,EAAE,CAAC;oBACX,IAAI,UAAU,GAAG,QAAQ,IAAI,KAAK,EAAE,CAAC;wBACjC,OAAO,KAAK,IAAI,QAAQ,IAAI,KAAK,GAAG,UAAU,CAAC;oBACnD,CAAC;oBACD,OAAO,CAAC,CAAC,KAAK,IAAI,UAAU,IAAI,KAAK,GAAG,QAAQ,CAAC,CAAC;gBACtD,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,+CAA+C,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gBAC9F,OAAO,KAAK,CAAC;YACjB,CAAC;YAED,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;gBACpB,OAAO,KAAK,GAAG,UAAU,CAAC;YAC9B,CAAC;YACD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,KAAK,IAAI,UAAU,CAAC;YAC/B,CAAC;YACD,IAAI,SAAS,KAAK,GAAG,EAAE,CAAC;gBACpB,OAAO,KAAK,GAAG,UAAU,CAAC;YAC9B,CAAC;YACD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,KAAK,IAAI,UAAU,CAAC;YAC/B,CAAC;YACD,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBACrB,OAAO,KAAK,KAAK,UAAU,CAAC;YAChC,CAAC;YACD,IAAI,SAAS,KAAK,IAAI,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;gBAC3C,OAAO,KAAK,KAAK,UAAU,CAAC;YAChC,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,qBAAqB,SAAmB,EAAE,EAAE,MAAM,CAAC,CAAC;YAChE,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,MAAM,EAAE,UAAU,EAAc,EAAE,OAAgB;YAC9C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,kBAAkB,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC;YACtD,CAAC;YAED,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;YACrB,MAAM,CAAC,aAAa,GAAG,OAAO,IAAI,IAAI,CAAC;QAC3C,CAAC;QACD,WAAW,EAAE,UAAU,KAAsB,EAAE,QAAyB,EAAE,MAAe;YACrF,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;gBAC/B,MAAM,GAAG,QAAQ,CAAC;gBAClB,QAAQ,GAAG,CAAC,CAAC;YACjB,CAAC;YACD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,IAAI,OAAO,CAAC,YAAY,KAAK,SAAS,EAAE,CAAC;oBACrC,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAChD,CAAC;qBAAM,IAAI,OAAO,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,EAAE,CAAC;oBACrE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBACxE,CAAC;YACL,CAAC;YACD,OAAO,OAAO,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC;QACxD,CAAC;QACD,UAAU,EAAE,UACR,IAA8C,EAC9C,MAAe,EACf,QAA6B;YAE7B,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;oBACrB,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;gBAChC,CAAC;qBAAM,CAAC;oBACJ,MAAM;wBACF,OAAO,CAAC,eAAe,CAAC,IAAI,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM;4BACvD,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,UAAU,IAAI,YAAY;4BAC5D,CAAC,CAAC,YAAY,CAAC;gBAC3B,CAAC;gBACD,MAAM,GAAG,MAAM,IAAI,YAAY,CAAC;YACpC,CAAC;YACD,oDAAoD;YACpD,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,MAAM,GAAG,GAAG,MAAM,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC5D,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACb,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;gBACvE,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,IAAI,IAAA,gBAAQ,EAAC,IAAI,CAAC,IAAK,IAAwB,CAAC,KAAK,EAAE,CAAC;gBACnE,IAAI;oBACA,OAAO;yBACF,YAAY,CACR,IAAwB,CAAC,KAAK,EAC9B,IAAwB,CAAC,IAAI,IAAI,IAAI,IAAI,EAAE,EAC3C,IAAwB,CAAC,MAAM,IAAI,CAAC,CACxC;wBACD,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;YAC7B,CAAC;YAED,IAAI,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1B,IAAI,IAAI,GAAW,OAAO,CAAC,UAAU,CAAC,IAA8B,EAAE,MAAM,CAAC,CAAC;gBAC9E,IAAI,CAAC,QAAQ,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChD,QAAQ;wBACJ,OAAO,CAAC,QAAQ;4BAChB,CAAC,OAAO,CAAC,eAAe,CAAC;gCACrB,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM;gCAC/B,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC;4BAC7C,IAAI,CAAC;oBACT,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC,QAA8B,CAAC,EAAE,CAAC;wBACzD,QAAQ,GAAG,IAAI,CAAC;oBACpB,CAAC;gBACL,CAAC;gBACD,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;oBACvD,IAAI,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC;qBAAM,IAAI,OAAQ,IAAa,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACvD,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;oBAC9E,OAAO,cAAc,CAAC;gBAC1B,CAAC;gBACD,MAAM,CAAC,GAAY,IAAa,CAAC,MAAM,EAAE,CAAC;gBAC1C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,cAAc,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpF,IAAI,WAAW,GAAG,IAAI,CAAC;gBACvB,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,cAAc,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAEpF,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;oBACvB,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,eAAe,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACxF,CAAC;gBAED,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,eAAe,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,eAAe,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACpF,MAAM,CAAC,GAAY,IAAa,CAAC,QAAQ,EAAE,CAAC;gBAC5C,WAAW,GAAG,IAAI,CAAC;gBACnB,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAC/E,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,MAAM,CAAC,SAAS,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBAE/E,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;oBACvB,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,QAA8B,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACnF,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,OAAO,CAAC,UAAU,CAAC,IAA8B,EAAE,MAAM,CAAC,CAAC;QACtE,CAAC;QACD,cAAc,EAAE,UAAU,IAAY,EAAE,MAAe;YACnD,IAAI,CAAC,MAAM,EAAE,CAAC;gBACV,MAAM,GAAG,UAAU,CAAC;YACxB,CAAC;YAED,IAAI,IAAI,GAAG,MAAM,CAAC;YAElB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,UAAU,IAAI,GAAG,EAAE,OAAO,CAAC,CAAC;YAC3E,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,CAAC;YACpB,MAAM,MAAM,GAAG,EAAE,GAAG,MAAM,CAAC;YAC3B,MAAM,IAAI,GAAG,EAAE,GAAG,MAAM,CAAC;YACzB,MAAM,GAAG,GAAG,EAAE,GAAG,IAAI,CAAC;YACtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,CAAC;YACrB,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAEtB,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC;gBAEpC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC1E,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAE9C,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,UAAU,IAAI,UAAU,IAAI,GAAG,EAAE,OAAO,CAAC,CAAC;gBACzF,CAAC;gBAED,IAAI,IAAI,IAAI,GAAG,GAAG,CAAC;YACvB,CAAC;YAED,IAAI,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;gBAEtC,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAC7E,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAE/C,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,UAAU,IAAI,WAAW,KAAK,GAAG,EAAE,OAAO,CAAC,CAAC;gBAE3F,IAAI,IAAI,KAAK,GAAG,IAAI,CAAC;YACzB,CAAC;YAED,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;gBAE1C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAChF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEhD,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,UAAU,IAAI,aAAa,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;gBAE/F,IAAI,IAAI,OAAO,GAAG,MAAM,CAAC;YAC7B,CAAC;YAED,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,MAAM,CAAC,CAAC;gBAE1C,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,OAAO,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAChF,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAC;gBAEhD,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,UAAU,IAAI,aAAa,OAAO,GAAG,EAAE,OAAO,CAAC,CAAC;gBAC/F,+CAA+C;YACnD,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,yBAAyB,MAAM,UAAU,IAAI,GAAG,EAAE,OAAO,CAAC,CAAC;YAC3E,CAAC;YAED,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACnC,CAAC;QACD,aAAa,EAAE,UAAU,IAA4B;YACjD,IAAI,IAAA,gBAAQ,EAAC,IAAI,CAAC,EAAE,CAAC;gBACjB,OAAO,IAAY,CAAC;YACxB,CAAC;YACD,IAAI,OAAO,IAAI,KAAK,WAAW,EAAE,CAAC;gBAC9B,OAAO,IAAI,IAAI,EAAE,CAAC;YACtB,CAAC;YACD,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;YAC1B,CAAC;YAED,uBAAuB;YACvB,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC;gBACxB,IAAI,GAAG,GAAG,IAAI,CAAC,WAAW,EAAE,IAAI,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,IAAI,KAAK,CAAC;YACvF,CAAC;iBAAM,IAAI,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,EAAE,CAAC;gBAC5C,iCAAiC;gBACjC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;gBACvB,IAAI,GAAG,GAAG,GAAG,CAAC,WAAW,EAAE,IAAI,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,IAAI,GAAG,CAAC,OAAO,EAAE,IAAI,IAAI,EAAE,CAAC;YACjF,CAAC;YAED,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;QACD,SAAS,EAAE,UACP,QAAgB,EAChB,QAAgB,EAChB,IAA8C,EAC9C,QAAuC;YAEvC,IAAI,OAAO,IAAI,KAAK,UAAU,IAAI,CAAC,IAAI,EAAE,CAAC;gBACtC,QAAQ,GAAG,IAAoC,CAAC;gBAChD,IAAI,GAAG,QAAQ,CAAC;gBAChB,QAAQ,GAAG,QAAQ,CAAC;gBACpB,QAAQ,GAAG,cAAc,CAAC;YAC9B,CAAC;YACD,QAAQ,GAAG,QAAQ,IAAI,cAAc,CAAC;YAEtC,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,qBAAqB,QAAQ,cAAc,QAAQ,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EACnH,MAAM,CACT,CAAC;gBACF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,UAAU,CAAC;wBACP,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBAC3B,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC,EAAE,CAAC,CAAC,CAAC;gBACV,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,qBAAqB,QAAQ,cAAc,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;gBAChF,CAAC;gBACD,IAAI,QAAQ,EAAE,CAAC;oBACX,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;gBAC1D,CAAC;qBAAM,CAAC;oBACJ,oDAAoD;oBACpD,OAAO,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAChD,CAAC;YACL,CAAC;QACL,CAAC;QACD,QAAQ,EAAE,UACN,QAAgB,EAChB,QAAuG,EACvG,QAA6F;YAE7F,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,QAAQ,GAAG,QAIF,CAAC;gBACV,QAAQ,GAAG,QAAQ,CAAC;gBACpB,QAAQ,GAAG,cAAc,CAAC;YAC9B,CAAC;YACD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,cAAc,QAAQ,gBAAgB,EAAE,OAAO,CAAC,CAAC;gBACzF,OAAO;YACX,CAAC;YACD,QAAQ,GAAG,QAAQ,IAAI,cAAc,CAAC;YACtC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,cAAc,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;YAC/E,CAAC;YAED,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,KAA+B,EAAE,MAAgB,EAAQ,EAAE;gBAC/F,IAAI,KAAK,EAAE,CAAC;oBACR,QAAQ,CAAC,KAAK,CAAC,CAAC;gBACpB,CAAC;qBAAM,IAAI,CAAC,MAAM,EAAE,CAAC;oBACjB,QAAQ,CAAC,IAAI,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC;gBACtC,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBACnD,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC;QACD,MAAM,EAAE,UACJ,QAAgB,EAChB,QAAiD,EACjD,QAAuC;YAEvC,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,QAAQ,GAAG,QAAQ,CAAC;gBACpB,QAAQ,GAAG,QAAQ,CAAC;gBACpB,QAAQ,GAAG,cAAc,CAAC;YAC9B,CAAC;YACD,QAAQ,GAAG,QAAQ,IAAI,cAAc,CAAC;YAEtC,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,kBAAkB,QAAQ,cAAc,QAAQ,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EAChH,MAAM,CACT,CAAC;gBACF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,UAAU,CAAC;wBACP,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBAC3B,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC,EAAE,CAAC,CAAC,CAAC;gBACV,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,kBAAkB,QAAQ,cAAc,QAAQ,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC7E,CAAC;gBACD,IAAI,QAAQ,EAAE,CAAC;oBACX,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBACjD,CAAC;qBAAM,CAAC;oBACJ,oDAAoD;oBACpD,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;gBACvC,CAAC;YACL,CAAC;QACL,CAAC;QACD,OAAO,EAAE,UACL,QAAgB,EAChB,QAAiD,EACjD,QAAuC;YAEvC,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAkB,EAAE,QAAQ,CAAC,CAAC;QAClE,CAAC;QACD,MAAM,EAAE,UAAU,QAAgB,EAAE,OAAe,EAAE,OAAe,EAAE,QAAuC;YACzG,QAAQ,GAAG,QAAQ,IAAI,cAAc,CAAC;YAEtC,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,kBAAkB,QAAQ,aAAa,OAAO,aAAa,OAAO,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EAClI,MAAM,CACT,CAAC;gBACF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,UAAU,CAAC;wBACP,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBAC3B,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC,EAAE,CAAC,CAAC,CAAC;gBACV,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,OAAO;oBACX,OAAO,CAAC,GAAG,CAAC,kBAAkB,QAAQ,aAAa,OAAO,aAAa,OAAO,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC/F,IAAI,QAAQ,EAAE,CAAC;oBACX,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;gBACzD,CAAC;qBAAM,CAAC;oBACJ,oDAAoD;oBACpD,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC/C,CAAC;YACL,CAAC;QACL,CAAC;QACD,UAAU,EAAE,UACR,QAAgB,EAChB,OAAe,EACf,OAAe,EACf,QAAuC;YAEvC,OAAO,OAAO,CAAC,MAAM,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QAChE,CAAC;QACD,UAAU,EAAE,UACR,QAA2F,EAC3F,OAOgB,EAChB,QAKS;YAET,IAAI,IAAA,gBAAQ,EAAC,QAAQ,CAAC,EAAE,CAAC;gBACrB,QAAQ,GAAG,OAKF,CAAC;gBACV,OAAO,GAAG,QAAmF,CAAC;gBAC9F,QAAQ,GAAG,EAAE,CAAC;YAClB,CAAC;YAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,OAAO,CAAC,GAAG,CAAC,oBAAoB,EAAE,OAAO,CAAC,CAAC;YACtD,CAAC;YACD,IAAI,CAAC,IAAA,gBAAQ,EAAC,OAAO,CAAC,EAAE,CAAC;gBACrB,OAAO,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;YACrD,CAAC;YACD,IAAI,CAAE,OAAmF,CAAC,EAAE,EAAE,CAAC;gBAC3F,OAAO,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;YAChD,CAAC;YACD,MAAM,SAAS,GACX,QAAQ,CACH,OAA0E;gBACvE,EAAE,OAA4B,EAClC,EAAE,CACL,IAAI,KAAK,CAAC;YAEf,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,6EAA6E;gBAC7E,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC;oBACzB,6EAA6E;oBAC7E,QAAQ,GAAG,OAAO,CAAC,cAAc,CAAC;gBACtC,CAAC;qBAAM,CAAC;oBACJ,QAAQ,GAAG,OAAO,CAAC,eAAe,CAAC,EAAE,MAAM,EAAE,cAAc,IAAI,IAAI,CAAC;gBACxE,CAAC;YACL,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,uBAAuB,QAAkB,aAAa,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC1G,CAAC;YAED,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,OAAO,CAAC,GAAG,CAAC,oCAAoC,EAAE,OAAO,CAAC,CAAC;gBAC3D,IAAI,CAAC;oBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,oCAAoC,CAAC,CAAC,CAAC;gBAC5E,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;gBAClC,CAAC;gBACD,OAAO;YACX,CAAC;YACD,IAAK,QAAmB,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACrD,QAAQ,GAAI,QAAmB,CAAC,SAAS,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;YACxE,CAAC;YAED,IAAI,CAAC,OAAO,CAAC,kBAAkB,QAAkB,EAAE,CAAC,EAAE,CAAC;gBACnD,OAAO,CAAC,GAAG,CAAC,aAAa,QAAkB,cAAc,EAAE,OAAO,CAAC,CAAC;gBACpE,IAAI,CAAC;oBACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,CAAC,aAAa,QAAkB,cAAc,CAAC,CAAC,CAAC;gBACrF,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;gBAClC,CAAC;gBACD,OAAO;YACX,CAAC;YAED,IAAI,QAAQ,GAA0B,UAAU,CAAC,GAAG,EAAE;gBAClD,QAAQ,GAAG,IAAI,CAAC;gBAChB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;gBAClD,CAAC;gBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CACT,OAAO,EACP,IAAI,KAAK,CAAC,SAAS,CAAC,EACpB,IAAI,EACJ,OAAiF,EACjF,QAAkB,CACrB,CAAC;oBACN,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;oBACD,QAAQ,GAAG,SAAS,CAAC;gBACzB,CAAC;YACL,CAAC,EAAE,SAAS,CAAC,CAAC;YAEd,OAAO,CAAC,MAAM,CACV,QAAkB,EAClB,YAAY,EACZ;gBACI,EAAE,EAAG,OAAkF,CAAC,EAAE;gBAC1F,OAAO;aACV,EACD,CAAC,GAAQ,EAAQ,EAAE;gBACf,IAAI,QAAQ,EAAE,CAAC;oBACX,YAAY,CAAC,QAAQ,CAAC,CAAC;oBACvB,QAAQ,GAAG,IAAI,CAAC;gBACpB,CAAC;gBACD,MAAM,MAAM,GAKR,GAAG,CAAC;gBAER,IAAI,OAAO,CAAC,OAAO,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;oBACnC,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;gBAC1D,CAAC;gBACD,IAAI,OAAO,CAAC,OAAO,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC;oBACpC,OAAO,CAAC,GAAG,CAAC,iBAAiB,MAAM,CAAC,MAAM,CAAC,MAAM,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACxE,CAAC;gBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,IAAI,CAAC;wBACD,QAAQ,CAAC,IAAI,CACT,OAAO,EACP,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAC7C,MAAM,CAAC,MAAM,EACb,OAAiF,EACjF,QAAkB,CACrB,CAAC;oBACN,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,eAAe,CAAC,GAAY,CAAC,CAAC;oBAClC,CAAC;oBACD,QAAQ,GAAG,SAAS,CAAC;gBACzB,CAAC;YACL,CAAC,CACJ,CAAC;QACN,CAAC;QACD,SAAS,EAAE,UAAU,UAAkB,EAAE,QAAuC;YAC5E,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC;YAChC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;gBACrC,UAAU,GAAG,aAAa,UAAU,EAAE,CAAC;YAC3C,CAAC;YACD,uBAAuB;YACvB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC;gBACtD,OAAO,CAAC,GAAG,CAAC,iBAAiB,UAAU,sBAAsB,EAAE,OAAO,CAAC,CAAC;gBACxE,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,wBAAwB,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EAClG,MAAM,CACT,CAAC;gBACF,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,EAAE,CAAC;gBAC7C,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;gBAC3C,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAC,cAAc,EAAE,EAAE;oBACvF,OAAO,CAAC,mBAAmB,CACvB,UAAU,EACV,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAC7B,GAAG,CAAC,EAAE,CAAC,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,GAAG,CAAC,CACzD,CAAC;gBACN,CAAC,CAAC,CAAC;gBACH,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,CAAC,mBAAmB,CACvB,UAAU,EACV,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAC7B,GAAG,CAAC,EAAE,CAAC,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,GAAG,CAAC,CACzD,CAAC;YACF,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,cAAc,EAAE,UAAU,UAAkB;YACxC,IAAI,IAAI,GAAG,KAAK,CAAC;YACjB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,CAAC,EAAE;oBAC/C,IAAI,GAAG,EAAE,CAAC;wBACN,MAAM,CAAC,GAAG,CAAC,CAAC;wBACZ,IAAI,GAAG,IAAI,CAAC;oBAChB,CAAC;yBAAM,CAAC;wBACJ,OAAO,EAAE,CAAC;oBACd,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,IAAI,MAAM,KAAK,KAAK,IAAI,CAAC,IAAI,EAAE,CAAC;oBAC5B,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,UAAU,iBAAiB,CAAC,CAAC,CAAC;gBAC7D,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC;QACD,WAAW,EAAE,UACT,UAAkB,EAClB,eAAuF,EACvF,QAAoE;YAEpE,IAAI,OAAO,eAAe,KAAK,UAAU,EAAE,CAAC;gBACxC,QAAQ,GAAG,eAA4E,CAAC;gBACxF,eAAe,GAAG,KAAK,CAAC;YAC5B,CAAC;YACD,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC;YAChC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;gBACrC,UAAU,GAAG,aAAa,UAAU,EAAE,CAAC;YAC3C,CAAC;YACD,uBAAuB;YACvB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC;gBACtD,OAAO,CAAC,GAAG,CAAC,iBAAiB,UAAU,sBAAsB,EAAE,OAAO,CAAC,CAAC;gBACxE,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,0BAA0B,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EACpG,MAAM,CACT,CAAC;gBACF,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBACxD,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrC,IAAI,CAAC,eAAe,EAAE,CAAC;oBACnB,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;oBAC3C,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,EAAE;wBACzE,OAAO,CAAC,mBAAmB,CACvB,UAAU,EACV,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAC7B,GAAG,CAAC,EAAE,CAAC,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAC/D,CAAC;oBACN,CAAC,CAAC,CAAC;gBACP,CAAC;qBAAM,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACxC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAC1B,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE;gBACzE,OAAO,QAAQ,KAAK,UAAU,IAAI,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;YACH,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,gBAAgB,EAAE,UAAU,UAAkB,EAAE,eAAyB;YACrE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,OAAO,CAAC,WAAW,CAC9B,UAAU,EACV,CAAC,CAAC,eAAe,EACjB,CAAC,GAA6B,EAAE,OAAgB,EAAQ,EAAE;oBACtD,IAAI,GAAG,EAAE,CAAC;wBACN,MAAM,CAAC,GAAG,CAAC,CAAC;oBAChB,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,OAAO,CAAC,CAAC;oBACrB,CAAC;gBACL,CAAC,CACJ,CAAC;gBACF,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;oBACnB,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,UAAU,iBAAiB,CAAC,CAAC,CAAC;gBAC7D,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC;QACD,UAAU,EAAE,UACR,UAAkB,EAClB,QAAoE;YAEpE,UAAU,GAAG,UAAU,IAAI,IAAI,CAAC;YAEhC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;gBACrC,UAAU,GAAG,aAAa,UAAU,EAAE,CAAC;YAC3C,CAAC;YAED,sBAAsB;YACtB,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC;gBACtD,OAAO,CAAC,GAAG,CAAC,gBAAgB,UAAU,sBAAsB,EAAE,OAAO,CAAC,CAAC;gBACvE,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,yBAAyB,UAAU,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EACnG,MAAM,CACT,CAAC;gBACF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;gBAC1B,CAAC;gBACD,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,IAAI,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;gBACrC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,GAAG,KAAK,CAAC;gBAC3C,OAAO,CAAC,mBAAmB,CAAC,UAAU,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE;oBAC1E,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,QAAQ,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;oBACxB,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC;iBAAM,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACxC,QAAQ,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;YAC1B,CAAC;YACD,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,eAAe,EAAE,UAAU,UAAkB;YACzC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACnC,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,CAC7B,UAAU,EACV,CAAC,GAA6B,EAAE,OAAgB,EAAQ,EAAE;oBACtD,IAAI,GAAG,EAAE,CAAC;wBACN,MAAM,CAAC,GAAG,CAAC,CAAC;oBAChB,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,OAAO,CAAC,CAAC;oBACrB,CAAC;gBACL,CAAC,CACJ,CAAC;gBACF,IAAI,MAAM,KAAK,KAAK,EAAE,CAAC;oBACnB,MAAM,CAAC,IAAI,KAAK,CAAC,UAAU,UAAU,iBAAiB,CAAC,CAAC,CAAC;gBAC7D,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC;QACD,cAAc,EAAE,UAAU,UAAkB;YACxC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,eAAe,CAAC,EAAE,CAAC;gBACrC,UAAU,GAAG,aAAa,UAAU,EAAE,CAAC;YAC3C,CAAC;YACD,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC;gBACtD,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,OAAO,CAAC,CAAC;gBAC9C,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;QAC9C,CAAC;QACD,kBAAkB,EAAE,KAAK,WAAW,YAAoB;YACpD,MAAM,aAAa,GAAG,kBAAkB,YAAY,EAAE,CAAC;YACvD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;YAEhE,IAAI,MAAM,EAAE,CAAC;gBACT,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;gBAEvE,IAAI,WAAW,EAAE,IAAI,KAAK,UAAU,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBAClE,MAAM,OAAO,CAAC,wBAAwB,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;oBAErF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,oCAAoC,YAAY,GAAG,EAAE,MAAM,CAAC,CAAC;oBAC7E,CAAC;oBAED,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,0BAA0B,YAAY,4BAA4B,EAAE,MAAM,CAAC,CAAC;YAC5F,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,GAAG,CAAC,0BAA0B,YAAY,sBAAsB,EAAE,OAAO,CAAC,CAAC;YACvF,CAAC;YAED,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,oBAAoB,EAAE,KAAK,WAAW,YAAoB;YACtD,MAAM,aAAa,GAAG,kBAAkB,YAAY,EAAE,CAAC;YACvD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;YAEhE,IAAI,MAAM,EAAE,CAAC;gBACT,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;gBAEvE,IAAI,WAAW,EAAE,IAAI,KAAK,UAAU,IAAI,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjE,MAAM,OAAO,CAAC,wBAAwB,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;oBAE1D,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,sCAAsC,YAAY,GAAG,EAAE,MAAM,CAAC,CAAC;oBAC/E,CAAC;oBAED,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,4BAA4B,YAAY,wBAAwB,EAAE,MAAM,CAAC,CAAC;YAC1F,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,GAAG,CAAC,4BAA4B,YAAY,sBAAsB,EAAE,OAAO,CAAC,CAAC;YACzF,CAAC;YAED,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,iBAAiB,EAAE,KAAK,WAAW,YAAoB;YACnD,MAAM,aAAa,GAAG,kBAAkB,YAAY,EAAE,CAAC;YACvD,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC,mBAAmB,CAAC,aAAa,CAAC,CAAC;YAEhE,IAAI,MAAM,EAAE,CAAC;gBACT,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,qBAAqB,CAAC,aAAa,CAAC,CAAC;gBAEvE,IAAI,WAAW,EAAE,IAAI,KAAK,UAAU,IAAI,WAAW,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjE,MAAM,OAAO,CAAC,wBAAwB,CAAC,aAAa,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;oBAEtF,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,mCAAmC,YAAY,GAAG,EAAE,MAAM,CAAC,CAAC;oBAC5E,CAAC;oBAED,OAAO,IAAI,CAAC;gBAChB,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,yBAAyB,YAAY,wBAAwB,EAAE,MAAM,CAAC,CAAC;YACvF,CAAC;iBAAM,CAAC;gBACJ,OAAO,CAAC,GAAG,CAAC,yBAAyB,YAAY,sBAAsB,EAAE,OAAO,CAAC,CAAC;YACtF,CAAC;YAED,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,6EAA6E;QAC7E,KAAK,EAAE,UAAU,GAAiD;YAC9D,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;gBACjC,GAAG,GAAG,CAAC,CAAC;YACZ,CAAC;YACD,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;gBACnC,GAAG,GAAG,CAAC,CAAC;YACZ,CAAC;YACD,GAAG,GAAG,QAAQ,CAAC,GAAwB,CAAC,IAAI,CAAC,CAAC;YAC9C,OAAO,GAAG,CAAC;QACf,CAAC;QACD,6EAA6E;QAC7E,OAAO,EAAE,UAAU,GAAiD;YAChE,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;gBACjC,GAAG,GAAG,CAAC,CAAC;YACZ,CAAC;YACD,IAAI,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;gBACnC,GAAG,GAAG,CAAC,CAAC;YACZ,CAAC;YACD,GAAG,GAAG,UAAU,CAAC,GAAwB,CAAC,IAAI,CAAC,CAAC;YAChD,OAAO,GAAG,CAAC;QACf,CAAC;QACD,6EAA6E;QAC7E,SAAS,EAAE,UAAU,GAAiD;YAClE,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,MAAM,EAAE,CAAC;gBAChC,GAAG,GAAG,IAAI,CAAC;YACf,CAAC;YACD,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,OAAO,EAAE,CAAC;gBACjC,GAAG,GAAG,KAAK,CAAC;YAChB,CAAC;YACD,OAAO,CAAC,CAAC,GAAG,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,UAAU,GAAiC,EAAE,IAAuB;YACzE,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC3B,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC3B,CAAC;YACD,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;gBAC1B,IAAI,CAAC;oBACD,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC1B,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACpB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE;wBACrE,GAAG,EAAE,IAAI;wBACT,GAAG,EAAE,IAAI;wBACT,CAAC,EAAE,SAAS;qBACf,CAAC,CAAC;oBACH,OAAO,CAAC,GAAG,CAAC,iBAAiB,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,GAAY,EAAE,EAAE,OAAO,CAAC,CAAC;oBAEhF,OAAO,IAAI,CAAC;gBAChB,CAAC;YACL,CAAC;YAED,MAAM,IAAI,GAAW,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC;YACxC,IAAI,CAAC;gBACD,GAAG,GAAI,GAA2B,CAAC,IAAI,CAAC,CAAC;YAC7C,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACpB,OAAO,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,MAAM,CAAC,EAAE,EAAE;oBACrE,GAAG,EAAE,IAAI;oBACT,GAAG,EAAE,IAAI;oBACT,CAAC,EAAE,SAAS;iBACf,CAAC,CAAC;gBACH,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,QAAQ,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,MAAM,GAAY,EAAE,EAAE,OAAO,CAAC,CAAC;gBAExF,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;gBACf,OAAO,GAAG,CAAC;YACf,CAAC;YACD,MAAM,IAAI,GAAG,OAAO,GAAG,CAAC;YACxB,IAAI,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;gBAC/E,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;QACD,SAAS,EAAE,UACP,MAA6F,EAC7F,IAAS,EACT,OAAwG,EACxG,QAA0G;YAE1G,MAAM,cAAc,GAAG,IAAI,CAAC;YAE5B,IAAI,OAAO,MAAM,KAAK,QAAQ,EAAE,CAAC;gBAC7B,MAAM,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;YAC/D,CAAC;YACD,IAAI,OAAO,OAAO,KAAK,UAAU,EAAE,CAAC;gBAChC,QAAQ,GAAG,OAAO,CAAC;gBACnB,OAAO,GAAG,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;YAC1C,CAAC;YAED,IAAI,OAAO,GAA0B,IAAI,CAAC;YAC1C,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,MAAM,eAAe,GAAG,QAAQ,CAAC,OAAO,EAAE,OAA4B,EAAE,EAAE,CAAC,IAAI,cAAc,CAAC;gBAE9F,OAAO,GAAG,UAAU,CAAC,GAAG,EAAE;oBACtB,OAAO,GAAG,IAAI,CAAC;oBAEf,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,yBAAyB,eAAe,EAAE,EAAE,OAAO,CAAC,CAAC;oBACrE,CAAC;oBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;wBAC3E,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;wBACD,QAAQ,GAAG,SAAS,CAAC;oBACzB,CAAC;gBACL,CAAC,EAAE,eAAe,CAAC,CAAC;YACxB,CAAC;YACD,IAAI,MAA2C,CAAC;YAChD,IAAI,OAAO,EAAE,CAAC;gBACV,MAAM,GAAG,UAAU,GAAQ;oBACvB,OAAO,IAAI,YAAY,CAAC,OAAO,CAAC,CAAC;oBACjC,MAAM,MAAM,GAA4C,GAAG,CAAC;oBAE5D,IAAI,OAAO,CAAC,OAAO,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC;wBACpC,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;oBACnE,CAAC;oBACD,IAAI,OAAO,CAAC,OAAO,IAAI,MAAM,EAAE,KAAK,EAAE,CAAC;wBACnC,OAAO,CAAC,GAAG,CAAC,gBAAgB,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;oBACzD,CAAC;oBAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;wBAC7D,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;wBACD,QAAQ,GAAG,SAAS,CAAC;oBACzB,CAAC;gBACL,CAAC,CAAC;YACN,CAAC;YAED,IAAI,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,QAAQ,KAAK,CAAC,EAAE,CAAC;gBAC3C,IACI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ;oBACnC,MAAM,CAAC,QAAQ;oBACf,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAC/C,CAAC;oBACC,MAAM,CAAC,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC;gBAC1E,CAAC;qBAAM,IAAI,OAAO,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAC7C,MAAM,CAAC,QAAQ,GAAG,cAAc,MAAM,CAAC,QAAQ,EAAE,CAAC;gBACtD,CAAC;gBAED,OAAO,CAAC,MAAM,CACV,MAAM,CAAC,QAAQ,EACf,cAAc,EACd,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,EACxD,MAAM,CACT,CAAC;YACN,CAAC;iBAAM,CAAC;gBACJ,2BAA2B;gBAC3B,OAAO,CAAC,OAAO,CAAC,aAAa,CACzB,QAAQ,EACR,UAAU,EACV,EAAE,QAAQ,EAAE,4BAA4B,EAAE,MAAM,EAAE,kCAAkC,EAAE,EACtF,OAAO,EACP,CAAC,GAA6B,EAAE,GAAG,EAAQ,EAAE;oBACzC,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;wBACd,OAAO,CAAC,GAAG,CAAC,qBAAqB,GAAG,EAAE,OAAO,EAAE,EAAE,OAAO,CAAC,CAAC;wBAC1D,OAAO;oBACX,CAAC;oBACD,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,CAAC;oBACrC,MAAM,SAAS,GAAG,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;oBAE/D,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE;wBACzB,OAAO,CAAC,MAAM,CACV,QAAQ,EACR,cAAc,EACd,EAAE,OAAO,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,EACxD,MAAM,CACT,CAAC;oBACN,CAAC,CAAC,CAAC;gBACP,CAAC,CACJ,CAAC;YACN,CAAC;QACL,CAAC;QACD,cAAc,EAAE,UACZ,MAA6F,EAC7F,IAAS,EACT,OAAuC;YAEvC,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;gBACnC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,GAAQ,EAAQ,EAAE;oBACxD,MAAM,MAAM,GAAuB,GAAG,CAAC;oBACvC,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;wBAClB,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;oBACvE,CAAC;oBACD,IAAI,CAAC,GAAG,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;wBACvB,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,eAAe,CAAC,CAAC,CAAC;oBAC1E,CAAC;yBAAM,CAAC;wBACJ,OAAO,CAAC,MAAM,CAAC,CAAC;oBACpB,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC;QACD,SAAS,EAAE,UACP,WAAmB,EACnB,QAAwD;YAExD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,sCAAsC,EAAE,OAAO,CAAC,CAAC;gBAE7D,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC;YACtG,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC;gBACvD,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,IAAI,EAAE,CAAC;YAEtE,MAAM,OAAO,GAAG,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,EAAE,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,CAAC;YAC9F,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,WAAW,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAE1E,OAAO,CAAC,QAAQ,CAAC,sBAAsB,IAAI,CAAC,CAAC;YAE7C,IACI,OAAO,CAAC,QAAQ,CAAC,sBAAsB;gBAClC,OAAO,CAAC,MAAkC,CAAC,oBAAoB;gBACpE,CAAC,EACH,CAAC;gBACC,OAAO,CAAC,GAAG,CACP,aAAa,OAAO,CAAC,QAAQ,CAAC,sBAAsB,uDAAuD,EAC3G,MAAM,CACT,CAAC;YACN,CAAC;YAED,OAAO,OAAO,CAAC,EAAE,CAAC;QACtB,CAAC;QACD,mBAAmB,EAAE,UAAU,QAAyB;YACpD,MAAM,GAAG,GAAG,OAAO,CAAC,kBAAkB,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YAC3D,IAAI,KAAK,GAAG,KAAK,CAAC;YAClB,IAAI,GAAG,EAAE,CAAC;gBACN,IAAI,OAAO,QAAQ,KAAK,QAAQ,EAAE,CAAC;oBAC/B,KAAK,MAAM,WAAW,IAAI,GAAG,EAAE,CAAC;wBAC5B,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,WAAW,CAAC,EAAE,CAAC;4BACzD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gCAC/C,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,KAAK,QAAQ,EAAE,CAAC;oCACtC,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oCAC9B,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,MAAM,EAAE,CAAC;wCAC3B,OAAO,GAAG,CAAC,WAAW,CAAC,CAAC;wCACxB,OAAO,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC;oCAC9C,CAAC;oCACD,KAAK,GAAG,IAAI,CAAC;oCACb,MAAM;gCACV,CAAC;4BACL,CAAC;wBACL,CAAC;wBACD,IAAI,KAAK,EAAE,CAAC;4BACR,MAAM;wBACV,CAAC;oBACL,CAAC;gBACL,CAAC;qBAAM,IAAI,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;oBACnC,OAAO,GAAG,CAAC,QAAQ,CAAC,CAAC;oBACrB,OAAO,CAAC,QAAQ,CAAC,sBAAsB,EAAE,CAAC;oBAC1C,KAAK,GAAG,IAAI,CAAC;gBACjB,CAAC;YACL,CAAC;YACD,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,EAAE;YACL,GAAG,EAAE,UAAU,GAAW;gBACtB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC7B,CAAC;YACD,KAAK,EAAE,UAAU,GAAW;gBACxB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC9B,CAAC;YACD,IAAI,EAAE,UAAU,GAAW;gBACvB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC7B,CAAC;YACD,IAAI,EAAE,UAAU,GAAW;gBACvB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YAC7B,CAAC;YACD,KAAK,EAAE,UAAU,GAAW;gBACxB,OAAO,CAAC,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC9B,CAAC;SACJ;QACD,iBAAiB,EAAE,UAAU,IAAS,EAAE,UAAkB;YACtD,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,EAAE,UAAU,EAAU;YACtB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAmB,EAAQ,EAAE;gBAC7C,OAAO,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;YACpC,CAAC,CAAC,CAAC;QACP,CAAC;QACD,KAAK,EAAE,UAAU,EAAU;YACvB,OAAO,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;QACD,QAAQ,EAAE,UACN,OAA0B,EAC1B,QAA4D;YAE5D,OAAO,OAAO,CAAC,eAAe,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtD,CAAC;QACD,eAAe,EAAE,UACb,OAA0B,EAC1B,QAA4D;YAE5D,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;gBACzB,MAAM,MAAM,GAIN,EAAE,CAAC;gBACT,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACtC,MAAM,CAAC,IAAI,CACP,OAAO,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,QAAQ,CAI3C,CACJ,CAAC;gBACN,CAAC;gBACD,OAAO,MAAM,CAAC;YAClB,CAAC;YAED,OAAO,CAAC,QAAQ,CAAC,qBAAqB,IAAI,CAAC,CAAC;YAE5C,IACI,OAAO,CAAC,QAAQ,CAAC,qBAAqB;gBACjC,OAAO,CAAC,MAAkC,CAAC,oBAAoB;gBACpE,CAAC,EACH,CAAC;gBACC,OAAO,CAAC,GAAG,CACP,aAAa,OAAO,CAAC,QAAQ,CAAC,qBAAqB,sDAAsD,EACzG,MAAM,CACT,CAAC;YACN,CAAC;YAED,iDAAiD;YACjD,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;gBAC1C,OAAO,CAAC,GAAG,CAAC,2EAA2E,EAAE,OAAO,CAAC,CAAC;gBAClG,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,sDAAsD,EAAE,OAAO,CAAC,CAAC;gBAC7E,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,MAAM,IAAI,GAAoB,EAAE,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC;YAC1D,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;YACpE,CAAC;YAED,OAAO,CAAC,uBAAuB,CAAC,OAAO,CAAC,CAAC;YAEzC,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YAEvC,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,iBAAiB,EAAE,UAAU,SAA8C;YACvE,IAAI,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxC,MAAM,MAAM,GAAc,EAAE,CAAC;gBAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACxC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,iBAAiB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAY,CAAC,CAAC;gBACpE,CAAC;gBACD,OAAO,MAAM,CAAC;YAClB,CAAC;YAED,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBAClB,OAAO,CAAC,GAAG,CAAC,+BAA+B,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;YACrF,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/D,IAAI,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;oBAC/C,OAAO,CAAC,yBAAyB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;oBACrD,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACzC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;oBACzC,OAAO,IAAI,CAAC;gBAChB,CAAC;YACL,CAAC;YACD,IAAI,OAAO,GAAG,CAAC,CAAC;YAChB,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC/D,IACI,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI;oBACnC,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,SAAS,CAAC,OAAO,EAC9D,CAAC;oBACC,OAAO,EAAE,CAAC;oBACV,OAAO,CAAC,yBAAyB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;oBACrD,OAAO,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBACzC,OAAO,CAAC,QAAQ,CAAC,qBAAqB,EAAE,CAAC;gBAC7C,CAAC;YACL,CAAC;YACD,OAAO,CAAC,CAAC,OAAO,CAAC;QACrB,CAAC;QACD,sEAAsE;QACtE,eAAe,EAAE,UAAU,OAAe,EAAE,IAAS;YACjD,IAAI,OAAO,CAAC,WAAW,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;gBAC7C,OAAO,CAAC,QAAQ,CACZ,aAAa,EACb,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,EAC7E,IAAI,CACP,CAAC;YACN,CAAC;QACL,CAAC;QACD,gBAAgB,EAAE,UAAU,GAAW;YACnC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,iBAAiB,EAAE,UAAU,GAAW;YACpC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,cAAc,EAAE,UAAU,GAAW,EAAE,SAAwB;YAC3D,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,cAAc,EAAE,UAAU,GAAW,EAAE,IAAqB;YACxD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,iBAAiB,EAAE,UAAU,GAAW,EAAE,IAA8B;YACpE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,iBAAiB,EAAE,UAAU,GAAW,EAAE,YAAsB;YAC5D,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,gBAAgB,EAAE,UACd,KAAa,EACb,UAA4D,EAC5D,cAKmC,EACnC,OAAuE,EACvE,OAA6D;YAE7D,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,gBAAgB,EAAE,UACd,KAAa,EACb,MAA4B,EAC5B,cAAmE,EACnE,OAA6D,EAC7D,OAA6B;YAE7B,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,gBAAgB,EAAE,UAAU,GAAW;YACnC,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,cAAc,EAAE,UACZ,QAAgB,EAChB,SAA0B,EAC1B,KAAuB;YAEvB,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,aAAa,EAAE,UAAU,QAAgB,EAAE,SAAkB;YACzD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,WAAW,EAAE,UAAU,QAAgB,EAAE,SAAkB;YACvD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,YAAY,EAAE,UAAU,QAAgB,EAAE,SAAkB;YACxD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,WAAW,EAAE,UAAU,QAAgB,EAAE,QAAgB,EAAE,QAAiB;YACxE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,eAAe,EAAE,UAAU,QAAgB,EAAE,QAAgB,EAAE,QAAiB;YAC5E,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,eAAe,EAAE,UACb,SAA4F,EAC5F,QAAkF;YAElF,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,YAAY,EAAE,UACV,IAAY,EACZ,QAOC;YAOD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,aAAa,EAAE,UACX,IAAY,EACZ,KAAU,EACV,QAOC;YAOD,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,iBAAiB,CAAC,CAAC,CAAC;QACxD,CAAC;KACJ,CAAC;IAEF,oDAAoD;IACpD,IAAK,OAAO,CAAC,MAAkC,CAAC,eAAe,EAAE,CAAC;QAC9D,OAAO,CAAC,SAAS,GAAG,UAChB,EAAU,EACV,GAAoB,EACpB,QAA6D;YAE7D,IAAI,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,IAAI,EAAE,CAAC,UAAU,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBACnE,OAAO,CAAC,GAAG,CACP,oCAAoC,EAAE,+DAA+D,EACrG,MAAM,CACT,CAAC;YACN,CAAC;YACD,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,gBAAgB,EAAE,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EAC9G,MAAM,CACT,CAAC;gBACF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,YAAY,CAAC;wBACT,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;wBACzC,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,gBAAgB,EAAE,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC3E,CAAC;gBACD,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE;oBAC3C,IAAI,CAAC,GAAG,EAAE,CAAC;wBACP,0BAA0B;wBAC1B,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;oBACzC,CAAC;oBACD,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;wBACjC,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;wBACrC,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC;QACL,CAAC,CAAC;QACF,OAAO,CAAC,YAAY,GAAG,UACnB,EAAU,EACV,GAA6B,EAC7B,QAAwE;YAExE,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,mBAAmB,EAAE,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EACjH,MAAM,CACT,CAAC;gBACF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,UAAU,CAAC;wBACP,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;wBACzC,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC,EAAE,CAAC,CAAC,CAAC;gBACV,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,SAAS,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC;gBAC9E,CAAC;gBACD,OAAO,CAAC,mBAAmB,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;YAC/E,CAAC;QACL,CAAC,CAAC;QACF,OAAO,CAAC,YAAY,GAAG,UAAU,EAAU,EAAE,WAAqB,EAAE,QAAiC;YACjG,IAAI,OAAO,WAAW,KAAK,UAAU,EAAE,CAAC;gBACpC,QAAQ,GAAG,WAAW,CAAC;gBACvB,WAAW,GAAG,KAAK,CAAC;YACxB,CAAC;YACD,IAAI,KAAK,EAAE,CAAC;gBACR,OAAO,CAAC,GAAG,CACP,mBAAmB,EAAE,OAAO,KAAK,CAAC,CAAC,CAAC,8CAA8C,CAAC,EAAE,EACrF,MAAM,CACT,CAAC;gBACF,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;oBACjC,UAAU,CAAC;wBACP,IAAI,CAAC;4BACD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;wBAC3B,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,eAAe,CAAC,GAAY,CAAC,CAAC;wBAClC,CAAC;oBACL,CAAC,EAAE,CAAC,CAAC,CAAC;gBACV,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;oBAClB,OAAO,CAAC,GAAG,CAAC,mBAAmB,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;gBAClD,CAAC;gBACD,OAAO,CAAC,gBAAgB,CAAC,EAAE,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,QAAQ,CAAC,CAAC;YACvE,CAAC;QACL,CAAC,CAAC;IACN,CAAC;IAED,mCAAmC;IACnC,OAAO,CAAC,gBAAgB,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,CAAC,iBAAiB,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5D,OAAO,CAAC,cAAc,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACtD,OAAO,CAAC,cAAc,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACtD,OAAO,CAAC,iBAAiB,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5D,OAAO,CAAC,iBAAiB,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IAC5D,OAAO,CAAC,gBAAgB,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,CAAC,gBAAgB,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,CAAC,gBAAgB,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,WAAW,CAAC,CAAC;IAC1D,OAAO,CAAC,cAAc,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACtD,OAAO,CAAC,aAAa,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACpD,OAAO,CAAC,WAAW,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,OAAO,CAAC,YAAY,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,OAAO,CAAC,WAAW,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAChD,OAAO,CAAC,eAAe,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxD,OAAO,CAAC,eAAe,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxD,OAAO,CAAC,YAAY,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAClD,OAAO,CAAC,aAAa,GAAG,IAAA,iBAAS,EAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAEpD,uFAAuF;IACvF,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;QACtC,MAAM,CAAC,cAAc,CAAC,OAAO,EAAE,IAAI,EAAE;YACjC,YAAY,EAAE,KAAK;YACnB,QAAQ,EAAE,KAAK;SAClB,CAAC,CAAC;IACP,CAAC;IAED,OAAO,OAAO,CAAC;AACnB,CAAC","sourcesContent":["import type { ChildProcess, ExecOptions } from 'node:child_process';\nimport * as jsonataMod from 'jsonata';\nimport type { SendMailOptions } from 'nodemailer';\nimport type { AxiosError, AxiosHeaderValue, AxiosResponse, ResponseType } from 'axios';\n\nimport { commonTools } from '@iobroker/adapter-core';\n\nimport { isObject, isArray, promisify, getHttpRequestConfig } from './tools';\nimport type {\n JavaScriptAdapterConfig,\n AstroRule,\n ChangeType,\n CommonAlias,\n FileSubscriptionResult,\n IobSchedule,\n JavascriptContext,\n JsScript,\n LogMessage,\n Pattern,\n PushoverOptions,\n SandboxType,\n Selector,\n SubscribeObject,\n SubscriptionResult,\n TimeRule,\n} from '../types';\nimport * as constsMod from './consts';\nimport * as wordsMod from './words';\nimport * as eventObjMod from './eventObj';\nimport { patternCompareFunctions as patternCompareFunctionsMod } from './patternCompareFunctions';\nimport type { PatternEventCompareFunction } from './patternCompareFunctions';\nimport type { ScheduleName, SchedulerRule } from './scheduler';\nimport type { EventObj } from './eventObj';\nimport type { AstroEvent } from './consts';\n\nconst pattern2RegEx = commonTools.pattern2RegEx;\n\nexport function sandBox(\n script: JsScript,\n name: string,\n verbose: boolean | undefined,\n debug: boolean | undefined,\n context: JavascriptContext,\n): SandboxType {\n const consts = constsMod;\n const words = wordsMod;\n const eventObj = eventObjMod;\n const patternCompareFunctions = patternCompareFunctionsMod;\n const jsonata = jsonataMod.default;\n\n const adapter: ioBroker.Adapter = context.adapter;\n const mods = context.mods;\n const states = context.states;\n const objects = context.objects;\n const timers = context.timers;\n const enums = context.enums;\n const debugMode = context.debugMode;\n\n // eslint-disable-next-line prefer-const\n let sandbox: SandboxType;\n\n function errorInCallback(e: Error): void {\n adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, {\n val: true,\n ack: true,\n c: 'errorInCallback',\n });\n context.logError('Error in callback', e);\n context.debugMode && console.log(`error$$${name}$$Exception in callback: ${e}`, Date.now());\n }\n\n function subscribePattern(script: JsScript, pattern: string): void {\n if ((adapter.config as JavaScriptAdapterConfig).subscribe) {\n if (!script.subscribes[pattern]) {\n script.subscribes[pattern] = 1;\n } else {\n script.subscribes[pattern]++;\n }\n\n if (!context.subscribedPatterns[pattern]) {\n context.subscribedPatterns[pattern] = 1;\n\n if (sandbox.verbose) {\n sandbox.log(`subscribePattern(pattern=${pattern})`, 'info');\n }\n adapter.subscribeForeignStates(pattern);\n\n // request current value to deliver old value on change.\n if (typeof pattern === 'string' && !pattern.includes('*')) {\n adapter.getForeignState(pattern, (_err, state) => {\n if (state) {\n states[pattern] = state;\n }\n });\n } else {\n adapter.getForeignStates(\n pattern,\n (_err, _states) => _states && Object.keys(_states).forEach(id => (states[id] = _states[id])),\n );\n }\n } else {\n context.subscribedPatterns[pattern]++;\n }\n }\n }\n\n function unsubscribePattern(script: JsScript, pattern: string): void {\n if ((adapter.config as JavaScriptAdapterConfig).subscribe) {\n if (script.subscribes[pattern]) {\n script.subscribes[pattern]--;\n if (!script.subscribes[pattern]) {\n delete script.subscribes[pattern];\n }\n }\n\n if (context.subscribedPatterns[pattern]) {\n context.subscribedPatterns[pattern]--;\n if (!context.subscribedPatterns[pattern]) {\n adapter.unsubscribeForeignStates(pattern);\n delete context.subscribedPatterns[pattern];\n\n // if the pattern was regex or with * some states will stay in RAM, but it is OK.\n if (states[pattern]) {\n delete states[pattern];\n }\n }\n }\n }\n }\n\n function subscribeFile(script: JsScript, id: string, fileNamePattern: string): void {\n const key = `${id}$%$${fileNamePattern}`;\n if (!script.subscribesFile[key]) {\n script.subscribesFile[key] = 1;\n } else {\n script.subscribesFile[key]++;\n }\n\n if (!context.subscribedPatternsFile[key]) {\n context.subscribedPatternsFile[key] = 1;\n adapter.subscribeForeignFiles(id, fileNamePattern);\n } else {\n context.subscribedPatternsFile[key]++;\n }\n }\n\n function unsubscribeFile(script: JsScript, id: string, fileNamePattern: string): void {\n const key = `${id}$%$${fileNamePattern}`;\n if (script.subscribesFile[key]) {\n script.subscribesFile[key]--;\n if (!script.subscribesFile[key]) {\n delete script.subscribesFile[key];\n }\n }\n\n if (context.subscribedPatternsFile[key]) {\n context.subscribedPatternsFile[key]--;\n if (!context.subscribedPatternsFile[key]) {\n adapter.unsubscribeForeignFiles(id, fileNamePattern);\n delete context.subscribedPatternsFile[key];\n }\n }\n }\n\n function getPatternCompareFunctions(pattern: Pattern): PatternEventCompareFunction[] & { logic?: 'and' | 'or' } {\n let func: PatternEventCompareFunction;\n const functions: PatternEventCompareFunction[] & { logic?: 'and' | 'or' } = [];\n functions.logic = pattern.logic || 'and';\n\n for (const key in pattern) {\n if (!Object.prototype.hasOwnProperty.call(pattern, key)) {\n continue;\n }\n if (key === 'logic') {\n continue;\n }\n if (key === 'change' && pattern.change === 'any') {\n continue;\n }\n const _func: (pattern: Pattern) => PatternEventCompareFunction = (\n patternCompareFunctions as unknown as Record PatternEventCompareFunction>\n )[key];\n if (!_func) {\n continue;\n }\n func = _func(pattern);\n if (typeof func !== 'function') {\n continue;\n }\n functions.push(func);\n }\n return functions;\n }\n\n /**\n * Splits a selector string into attribute and value\n *\n * @param selector The selector string to split\n */\n function splitSelectorString(selector: string): Selector {\n const parts = selector.split('=', 2);\n if (parts[1] && parts[1][0] === '\"') {\n parts[1] = parts[1].substring(1);\n const len = parts[1].length;\n if (parts[1] && parts[1][len - 1] === '\"') {\n parts[1] = parts[1].substring(0, len - 1);\n }\n }\n if (parts[1] && parts[1][0] === \"'\") {\n parts[1] = parts[1].substring(1);\n const len = parts[1].length;\n if (parts[1] && parts[1][len - 1] === \"'\") {\n parts[1] = parts[1].substring(0, len - 1);\n }\n }\n\n if (parts[1]) {\n parts[1] = parts[1].trim();\n }\n parts[0] = parts[0].trim();\n\n return { attr: parts[0], value: parts[1] };\n }\n\n /**\n * Transforms a selector string with wildcards into a regular expression\n *\n * @param str The selector string to transform into a regular expression\n */\n function selectorStringToRegExp(str: string): RegExp {\n const startsWithWildcard = str[0] === '*';\n const endsWithWildcard = str[str.length - 1] === '*';\n\n // Sanitize the selector, so it is safe to use in a RegEx\n // Taken from https://stackoverflow.com/a/3561711/10179833 but modified\n // since * has a special meaning in our selector and should not be escaped\n // eslint-disable-next-line no-useless-escape\n str = str.replace(/[-\\/\\\\^$+?.()|[\\]{}]/g, '\\\\$&').replace(/\\*/g, '.*');\n\n return new RegExp((startsWithWildcard ? '' : '^') + str + (endsWithWildcard ? '' : '$'));\n }\n\n /**\n * Adds a regular expression for selectors targeting the state ID\n *\n * @param selector The selector to apply the transform to\n */\n function addRegExpToIdAttrSelectors(selector: Selector): Selector {\n if ((selector.attr === 'id' || selector.attr === 'state.id') && !selector.idRegExp && selector.value) {\n return {\n attr: selector.attr,\n value: selector.value,\n idRegExp: selectorStringToRegExp(selector.value),\n };\n }\n return selector;\n }\n\n /**\n * Tests if a value loosely equals (==) the reference string.\n * In contrast to the equality operator, this treats true == \"true\" as well\n * so we can test common and native attributes for boolean values\n *\n * @param value The value to compare with the reference\n * @param reference The reference to compare the value to\n */\n function looselyEqualsString(value: string | number | boolean | undefined, reference: string): boolean {\n // For booleans, compare the string representation\n // For other types do a loose comparison\n return typeof value === 'boolean'\n ? (value && reference === 'true') || (!value && reference === 'false')\n : value == reference;\n }\n\n /**\n * Returns the `common.type` for a given variable\n */\n function getCommonTypeOf(value: any): ioBroker.CommonType {\n return isArray(value) ? 'array' : isObject(value) ? 'object' : (typeof value as ioBroker.CommonType);\n }\n\n /**\n * Returns if an id is in an allowed namespace for automatic object creations\n *\n * @param id id to check\n */\n function validIdForAutomaticFolderCreation(id: string): boolean {\n return id.startsWith('javascript.') || id.startsWith('0_userdata.0.') || id.startsWith('alias.0.');\n }\n\n /**\n * Iterate through object structure to create missing folder objects\n */\n async function ensureObjectStructure(id: string): Promise {\n if (!validIdForAutomaticFolderCreation(id)) {\n return;\n }\n if (context.folderCreationVerifiedObjects[id] === true) {\n return;\n }\n const idArr = id.split('.');\n idArr.pop(); // the last is created as an object in any way\n if (idArr.length < 3) {\n return; // Nothing to do\n }\n // We just create sublevel projects\n let idToCheck = idArr.splice(0, 2).join('.');\n\n context.folderCreationVerifiedObjects[id] = true;\n for (const part of idArr) {\n idToCheck += `.${part}`;\n if (context.folderCreationVerifiedObjects[idToCheck] === true || objects[idToCheck]) {\n continue;\n }\n context.folderCreationVerifiedObjects[idToCheck] = true;\n let obj: ioBroker.Object | null | undefined;\n try {\n obj = await adapter.getForeignObjectAsync(idToCheck);\n } catch {\n // ignore\n }\n if (!obj?.common) {\n sandbox.log(`Create folder object for ${idToCheck}`, 'debug');\n try {\n await adapter.setForeignObjectAsync(idToCheck, {\n _id: idToCheck,\n type: 'folder',\n common: {\n name: part,\n },\n native: {\n autocreated: 'by automatic ensure logic',\n },\n } as ioBroker.FolderObject);\n } catch (err: any) {\n sandbox.log(`Could not automatically create folder object ${idToCheck}: ${err.message}`, 'info');\n }\n } else {\n //sandbox.log(` already existing \"${idToCheck}\": ${JSON.stringify(obj)}`, 'debug');\n }\n }\n }\n\n function setStateHelper(\n sandbox: SandboxType,\n isCreate: boolean,\n isChanged: boolean,\n id: string,\n state: null | ioBroker.SettableState | ioBroker.StateValue,\n isAck: boolean | 'true' | 'false' | undefined | ((error?: Error | null) => void),\n callback?: (error?: Error | null) => void,\n ): void {\n if (typeof isAck === 'function') {\n callback = isAck;\n isAck = undefined;\n }\n\n let stateNotNull: ioBroker.SettableState | ioBroker.StateValue;\n\n if (isAck === true || isAck === false || isAck === 'true' || isAck === 'false') {\n if (state && typeof state === 'object' && state.val !== undefined) {\n stateNotNull = state;\n // we assume that we were given a state object if\n // state is an object that contains a `val` property\n if (!Object.prototype.hasOwnProperty.call(state, 'ack')) {\n stateNotNull.ack = isAck === true || isAck === 'true';\n }\n } else if (state === null) {\n stateNotNull = { val: null, ack: isAck === true || isAck === 'true' };\n } else {\n // otherwise, assume that the given state is the value to be set\n stateNotNull = { val: state as ioBroker.StateValue, ack: isAck === true || isAck === 'true' };\n }\n } else if (state === null) {\n stateNotNull = { val: null };\n } else {\n stateNotNull = state;\n }\n\n // Check a type of state\n if (!objects[id] && objects[`${adapter.namespace}.${id}`]) {\n id = `${adapter.namespace}.${id}`;\n }\n\n if (isCreate) {\n if (id.match(/^javascript\\.\\d+\\.scriptEnabled/)) {\n sandbox.log(\n `Own states (${id}) should not be used in javascript.X.scriptEnabled.*! Please move the states to 0_userdata.0.*`,\n 'info',\n );\n } else if (id.match(/^javascript\\.\\d+\\.scriptProblem/)) {\n sandbox.log(\n `Own states (${id}) should not be used in javascript.X.scriptProblem.*! Please move the states to 0_userdata.0.*`,\n 'info',\n );\n }\n }\n\n const common = objects[id] ? objects[id].common : null;\n if (common?.type && common.type !== 'mixed' && common.type !== 'json') {\n // Find out which type the value has\n let actualCommonType: ioBroker.CommonType | undefined;\n if (typeof stateNotNull === 'object') {\n if (stateNotNull && stateNotNull.val !== undefined && stateNotNull.val !== null) {\n actualCommonType = getCommonTypeOf(stateNotNull.val);\n }\n } else if (stateNotNull !== null && stateNotNull !== undefined) {\n actualCommonType = getCommonTypeOf(stateNotNull);\n }\n // If this is not the expected one, issue a warning\n if (actualCommonType && actualCommonType !== common.type) {\n context.logWithLineInfo(\n `You are assigning a ${actualCommonType} to the state \"${id}\" which expects a ${common.type}. ` +\n `Please fix your code to use a ${common.type} or change the state type to ${actualCommonType}. ` +\n `This warning might become an error in future versions.`,\n );\n }\n\n if (actualCommonType === 'array' || actualCommonType === 'object') {\n try {\n if (typeof stateNotNull === 'object' && typeof stateNotNull.val !== 'undefined') {\n stateNotNull.val = JSON.stringify(stateNotNull.val);\n } else {\n stateNotNull = JSON.stringify(stateNotNull);\n }\n } catch (err: any) {\n context.logWithLineInfo(\n `Could not stringify value for type ${actualCommonType} and id ${id}: ${err.message}`,\n );\n if (typeof callback === 'function') {\n try {\n callback.call(\n sandbox,\n new Error(\n `Could not stringify value for type ${actualCommonType} and id ${id}: ${err.message}`,\n ),\n );\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n }\n }\n }\n // Check min and max of value\n if (typeof stateNotNull === 'object') {\n if (common && typeof stateNotNull.val === 'number') {\n const num: number = stateNotNull.val;\n if (common.min !== undefined && num < common.min) {\n stateNotNull.val = common.min;\n } else if (common.max !== undefined && num > common.max) {\n stateNotNull.val = common.max;\n }\n }\n } else if (common && typeof stateNotNull === 'number') {\n const num: number = stateNotNull;\n if (common.min !== undefined && num < common.min) {\n stateNotNull = common.min;\n }\n if (common.max !== undefined && num > common.max) {\n stateNotNull = common.max;\n }\n }\n\n let stateAsObject: ioBroker.State;\n // modify state here, to make it available in callback\n if (\n stateNotNull === null ||\n typeof stateNotNull !== 'object' ||\n (stateNotNull as ioBroker.SettableState).val === undefined\n ) {\n stateAsObject = context.prepareStateObject(id, {\n val: stateNotNull as ioBroker.StateValue,\n ack: isAck === true || isAck === 'true',\n });\n } else {\n stateAsObject = context.prepareStateObject(id, stateNotNull as ioBroker.SettableState);\n }\n\n // set as comment: from which script this state was set.\n stateAsObject.c = sandbox.scriptName;\n\n if (objects[id]) {\n script.setStatePerMinuteCounter++;\n if (sandbox.verbose) {\n sandbox.log(`setForeignState(id=${id}, state=${JSON.stringify(stateAsObject)})`, 'info');\n }\n\n if (debug) {\n sandbox.log(\n `setForeignState(id=${id}, state=${JSON.stringify(stateAsObject)}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n\n if (typeof callback === 'function') {\n setImmediate(() => {\n try {\n callback.call(sandbox);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n });\n }\n } else {\n if (!(adapter.config as JavaScriptAdapterConfig).subscribe) {\n // store actual state to make possible to process value in callback\n // risk that there will be an error on setState is very low,\n // but we will not store new state if the setStateChanged is called\n if (!isChanged) {\n context.interimStateValues[id] = stateAsObject;\n }\n }\n const errHandler = (err: Error | null | undefined, funcId: string): void => {\n err && sandbox.log(`${funcId}: ${err}`, 'error');\n // If adapter holds all states\n if (err && !(adapter.config as JavaScriptAdapterConfig).subscribe) {\n delete context.interimStateValues[id];\n }\n\n if (typeof callback === 'function') {\n setImmediate(() => {\n try {\n callback.call(sandbox);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n });\n }\n };\n if (isChanged) {\n if (!(adapter.config as JavaScriptAdapterConfig).subscribe && context.interimStateValues[id]) {\n // if the state is changed, we will compare it with interimStateValues\n const oldState = context.interimStateValues[id];\n const attrs: string[] = Object.keys(stateAsObject).filter(\n attr => attr !== 'ts' && (stateAsObject as Record)[attr] !== undefined,\n );\n if (\n !attrs.every(\n attr =>\n (stateAsObject as Record)[attr] ===\n (oldState as Record)[attr],\n )\n ) {\n // state is changed for sure, and we will call setForeignState\n // and store new state to interimStateValues\n context.interimStateValues[id] = stateAsObject;\n adapter.setForeignState(id, stateAsObject, err => errHandler(err, 'setForeignState'));\n } else {\n // otherwise - do nothing as we have cached state, except callback\n errHandler(null, 'setForeignStateCached');\n }\n } else {\n // adapter doesn't hold all states, or it has not cached then we will simply call setForeignStateChanged\n adapter.setForeignStateChanged(id, { ...stateAsObject, ts: undefined }, err =>\n errHandler(err, 'setForeignStateChanged'),\n );\n }\n } else {\n adapter.setForeignState(id, stateAsObject, err => errHandler(err, 'setForeignState'));\n }\n }\n } else {\n context.logWithLineInfo(`State \"${id}\" not found`);\n if (typeof callback === 'function') {\n setImmediate(() => {\n try {\n callback.call(sandbox, new Error(`State \"${id}\" not found`));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n });\n }\n }\n }\n\n sandbox = {\n mods,\n _id: script._id,\n // @deprecated use scriptName\n name,\n scriptName: name,\n instance: adapter.instance || 0,\n defaultDataDir: context.getAbsoluteDefaultDataDir(),\n verbose,\n exports: {}, // Polyfill for the export object in TypeScript modules\n require: function (md: string): any {\n if (typeof md === 'string' && md.startsWith('node:')) {\n md = md.replace(/^node:/, '');\n }\n\n if (md === 'request') {\n if (!sandbox.__engine.__deprecatedWarnings.includes(md)) {\n sandbox.log(\n `request package is deprecated - please use httpGet (or a stable lib like axios) instead!`,\n 'warn',\n );\n sandbox.__engine.__deprecatedWarnings.push(md);\n }\n }\n\n if (mods[md]) {\n return mods[md];\n }\n\n let error: Error | undefined;\n\n try {\n mods[md] = require(\n adapter.getAdapterScopedPackageIdentifier ? adapter.getAdapterScopedPackageIdentifier(md) : md,\n );\n return mods[md];\n } catch (e: any) {\n error = e as Error;\n }\n\n try {\n // the user requires a module which is not specified in the additional node modules\n // for backward compatibility we check if the module can simply be required directly before we fail (e.g., direct dependencies of JavaScript adapter)\n adapter.log.debug(`Try direct require of \"${md}\" as not specified in the additional dependencies`);\n mods[md] = require(md);\n\n return mods[md];\n } catch (e: any) {\n context.logError(name, error || e, 6);\n adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, {\n val: true,\n ack: true,\n c: 'require',\n });\n }\n },\n Buffer: Buffer,\n __engine: {\n __deprecatedWarnings: [],\n __subscriptionsObject: 0,\n __subscriptions: 0,\n __subscriptionsMessage: 0,\n __subscriptionsFile: 0,\n __subscriptionsLog: 0,\n __schedules: 0,\n },\n\n $: function (selector: string): iobJS.QueryResult {\n // following is supported\n // 'type[commonAttr=something]', 'id[commonAttr=something]', id(enumName=\"something\")', id{nativeName=\"something\"}\n // Type can be state, channel or device\n // Attr can be any of the common attributes and can have wildcards *\n // E.g. \"state[id='hm-rpc.0.*]\" or \"hm-rpc.0.*\" returns all states of adapter instance hm-rpc.0\n // channel(room=\"Living room\") => all states in room \"Living room\"\n // channel{TYPE=BLIND}[state.id=*.LEVEL]\n // Switch all states with .STATE of channels with role \"switch\" in \"Wohnzimmer\" to false\n // $('channel[role=switch][state.id=*.STATE](rooms=Wohnzimmer)').setState(false);\n //\n // Following functions are possible, setValue, getValue (only from first), on, each\n\n // Todo CACHE!!!\n\n const result: iobJS.QueryResult = {} as iobJS.QueryResult;\n\n let name = '';\n const commonStrings: string[] = [];\n const enumStrings: string[] = [];\n const nativeStrings: string[] = [];\n let isInsideName = true;\n let isInsideCommonString = false;\n let isInsideEnumString = false;\n let isInsideNativeString = false;\n let currentCommonString = '';\n let currentNativeString = '';\n let currentEnumString = '';\n\n // parse string\n let selectorHasInvalidType = false;\n if (typeof selector === 'string') {\n for (let i = 0; i < selector.length; i++) {\n if (selector[i] === '{') {\n isInsideName = false;\n if (isInsideCommonString || isInsideEnumString || isInsideNativeString) {\n // Error\n break;\n }\n isInsideNativeString = true;\n } else if (selector[i] === '}') {\n isInsideNativeString = false;\n nativeStrings.push(currentNativeString);\n currentNativeString = '';\n } else if (selector[i] === '[') {\n isInsideName = false;\n if (isInsideCommonString || isInsideEnumString || isInsideNativeString) {\n // Error\n break;\n }\n isInsideCommonString = true;\n } else if (selector[i] === ']') {\n isInsideCommonString = false;\n commonStrings.push(currentCommonString);\n currentCommonString = '';\n } else if (selector[i] === '(') {\n isInsideName = false;\n if (isInsideCommonString || isInsideEnumString || isInsideNativeString) {\n // Error\n break;\n }\n isInsideEnumString = true;\n } else if (selector[i] === ')') {\n isInsideEnumString = false;\n enumStrings.push(currentEnumString);\n currentEnumString = '';\n } else if (isInsideName) {\n name += selector[i];\n } else if (isInsideCommonString) {\n currentCommonString += selector[i];\n } else if (isInsideEnumString) {\n currentEnumString += selector[i];\n } else if (isInsideNativeString) {\n currentNativeString += selector[i];\n } //else {\n // some error\n //}\n }\n } else {\n selectorHasInvalidType = true;\n }\n\n // If some error in the selector\n if (selectorHasInvalidType || isInsideEnumString || isInsideCommonString || isInsideNativeString) {\n result.length = 0;\n result.toArray = function () {\n return [];\n };\n result.each = function () {\n return this;\n };\n result.getState = function () {\n return null;\n };\n result.setState = function () {\n return this;\n };\n result.on = function () {\n return this;\n };\n }\n\n if (isInsideEnumString) {\n sandbox.log(`Invalid selector: enum close bracket \")\" cannot be found in \"${selector}\"`, 'warn');\n result.error = 'Invalid selector: enum close bracket \")\" cannot be found';\n return result;\n } else if (isInsideCommonString) {\n sandbox.log(`Invalid selector: common close bracket \"]\" cannot be found in \"${selector}\"`, 'warn');\n result.error = 'Invalid selector: common close bracket \"]\" cannot be found';\n return result;\n } else if (isInsideNativeString) {\n sandbox.log(`Invalid selector: native close bracket \"}\" cannot be found in \"${selector}\"`, 'warn');\n result.error = 'Invalid selector: native close bracket \"}\" cannot be found';\n return result;\n } else if (selectorHasInvalidType) {\n const message = `Invalid selector: selector must be a string but is of type ${typeof selector}`;\n sandbox.log(message, 'warn');\n result.error = message;\n return result;\n }\n\n let commonSelectors: Selector[] = commonStrings.map(selector => splitSelectorString(selector));\n let nativeSelectors: Selector[] = nativeStrings.map(selector => splitSelectorString(selector));\n const enumSelectorObjects: Selector[] = enumStrings.map(_enum => splitSelectorString(_enum));\n const allSelectors: Selector[] = commonSelectors.concat(nativeSelectors, enumSelectorObjects);\n\n // These selectors match the state or object ID and don't belong in the common/native selectors\n // Also use RegExp for the ID matching\n const stateIdSelectors: Selector[] = allSelectors\n .filter(selector => selector.attr === 'state.id')\n .map(selector => addRegExpToIdAttrSelectors(selector));\n const objectIdSelectors: Selector[] = allSelectors\n .filter(selector => selector.attr === 'id')\n .map(selector => addRegExpToIdAttrSelectors(selector));\n commonSelectors = commonSelectors.filter(\n selector => selector.attr !== 'state.id' && selector.attr !== 'id',\n );\n nativeSelectors = nativeSelectors.filter(\n selector => selector.attr !== 'state.id' && selector.attr !== 'id',\n );\n const enumSelectors: string[] = enumSelectorObjects\n .filter(selector => selector.attr !== 'state.id' && selector.attr !== 'id')\n // enums are filtered by their enum id, so transform the selector into that\n .map(selector => `enum.${selector.attr}.${selector.value}`);\n\n name = name.trim();\n\n if (name === 'channel' || name === 'device') {\n // Fill the channels and devices objects with the IDs of all their states,\n // so we can loop over them afterward\n if (!context.channels || !context.devices) {\n context.channels = {};\n context.devices = {};\n for (const _id in objects) {\n if (Object.prototype.hasOwnProperty.call(objects, _id) && objects[_id].type === 'state') {\n const parts = _id.split('.');\n parts.pop();\n const chn = parts.join('.');\n\n parts.pop();\n const dev = parts.join('.');\n\n context.devices[dev] = context.devices[dev] || [];\n context.devices[dev].push(_id);\n\n context.channels[chn] = context.channels[chn] || [];\n context.channels[chn].push(_id);\n }\n }\n }\n }\n\n if (name === 'schedule') {\n if (!context.schedules) {\n context.schedules = [];\n for (const _id in objects) {\n if (Object.prototype.hasOwnProperty.call(objects, _id) && objects[_id].type === 'schedule') {\n context.schedules.push(_id);\n }\n }\n }\n }\n\n /**\n * applies all selectors targeting an object or state ID\n */\n function applyIDSelectors(objId: string, selectors: Selector[]): boolean {\n // Only keep the ID if it matches every ID selector\n return selectors.every(selector => !selector.idRegExp || selector.idRegExp.test(objId));\n }\n\n /**\n * Applies all selectors targeting the Object common properties\n *\n * @param objId - The ID of the object in question\n */\n function applyCommonSelectors(objId: string): boolean {\n const obj = objects[objId];\n if (!obj?.common) {\n return false;\n }\n const objCommon = obj.common;\n\n // make sure this object satisfies all selectors\n return commonSelectors.every(\n selector =>\n // ensure a property exists\n (selector.value === undefined && objCommon[selector.attr] !== undefined) ||\n // or match exact values\n looselyEqualsString(objCommon[selector.attr], selector.value),\n );\n }\n\n /**\n * Applies all selectors targeting the Object native properties\n *\n * @param objId - The ID of the object in question\n */\n function applyNativeSelectors(objId: string): boolean {\n const obj = objects[objId];\n if (!obj || !obj.native) {\n return false;\n }\n const objNative = obj.native;\n // make sure this object satisfies all selectors\n return nativeSelectors.every(\n selector =>\n // ensure a property exists\n (selector.value === undefined && objNative[selector.attr] !== undefined) ||\n // or match exact values\n looselyEqualsString(objNative[selector.attr], selector.value),\n );\n }\n\n /**\n * Applies all selectors targeting the Objects enums\n *\n * @param objId - The ID of the object in question\n */\n function applyEnumSelectors(objId: string): boolean {\n const enumIds: string[] = [];\n eventObj.getObjectEnumsSync(context, objId, enumIds);\n // make sure this object satisfies all selectors\n return enumSelectors.every(_enum => enumIds.includes(_enum));\n }\n\n let res: string[];\n\n if (name === 'schedule') {\n res = context.schedules || [];\n if (objectIdSelectors.length) {\n res = res.filter(channelId => applyIDSelectors(channelId, objectIdSelectors));\n }\n\n // filter out those that don't match every common selector\n if (commonSelectors.length) {\n res = res.filter(id => applyCommonSelectors(id));\n }\n\n // filter out those that don't match every native selector\n if (nativeSelectors.length) {\n res = res.filter(id => applyNativeSelectors(id));\n }\n\n // filter out those that don't match every enum selector\n if (enumSelectors.length) {\n res = res.filter(channelId => applyEnumSelectors(channelId));\n }\n } else if (name === 'channel') {\n if (!context.channels) {\n // TODO: fill the channels and maintain them on all places where context.stateIds will be changed\n }\n const channels = context.channels || {};\n\n // go through all channels\n res = Object.keys(channels);\n // filter out those that don't match every ID selector for the channel ID\n if (objectIdSelectors.length) {\n res = res.filter(channelId => applyIDSelectors(channelId, objectIdSelectors));\n }\n // filter out those that don't match every common selector\n if (commonSelectors.length) {\n res = res.filter(channelId => applyCommonSelectors(channelId));\n }\n // filter out those that don't match every native selector\n if (nativeSelectors.length) {\n res = res.filter(channelId => applyNativeSelectors(channelId));\n }\n // filter out those that don't match every enum selector\n if (enumSelectors.length) {\n res = res.filter(channelId => applyEnumSelectors(channelId));\n }\n\n // retrieve the state ID collection for all remaining channels\n res = res\n .map(id => channels[id])\n // and flatten the array to get only the state IDs\n .reduce((acc, next) => acc.concat(next), []);\n\n // now filter out those that don't match every ID selector for the state ID\n if (stateIdSelectors.length) {\n res = res.filter(stateId => applyIDSelectors(stateId, stateIdSelectors));\n }\n } else if (name === 'device') {\n if (!context.devices) {\n // TODO: fill the devices and maintain them on all places where context.stateIds will be changed\n }\n\n const devices = context.devices || {};\n\n // go through all devices\n res = Object.keys(devices);\n // filter out those that don't match every ID selector for the channel ID\n if (objectIdSelectors.length) {\n res = res.filter(deviceId => applyIDSelectors(deviceId, objectIdSelectors));\n }\n\n // filter out those that don't match every common selector\n if (commonSelectors.length) {\n res = res.filter(deviceId => applyCommonSelectors(deviceId));\n }\n\n // filter out those that don't match every native selector\n if (nativeSelectors.length) {\n res = res.filter(deviceId => applyNativeSelectors(deviceId));\n }\n\n // filter out those that don't match every enum selector\n if (enumSelectors.length) {\n res = res.filter(deviceId => applyEnumSelectors(deviceId));\n }\n\n // retrieve the state ID collection for all remaining devices\n res = res\n .map(id => devices[id])\n // and flatten the array to get only the state IDs\n .reduce((acc, next) => acc.concat(next), []);\n\n // now filter out those that don't match every ID selector for the state ID\n if (stateIdSelectors.length) {\n res = res.filter(stateId => applyIDSelectors(stateId, stateIdSelectors));\n }\n } else {\n // go through all states\n res = context.stateIds;\n // if the \"name\" is not state, then we filter for the ID as well\n if (name && name !== 'state') {\n const r = new RegExp(`^${name.replace(/\\./g, '\\\\.').replace(/\\*/g, '.*')}$`);\n res = res.filter(id => r.test(id));\n }\n\n // filter out those that don't match every ID selector for the object ID or the state ID\n if (objectIdSelectors.length) {\n res = res.filter(id => applyIDSelectors(id, objectIdSelectors));\n }\n\n // filter out those that don't match every ID selector for the state ID\n if (stateIdSelectors.length) {\n res = res.filter(id => applyIDSelectors(id, stateIdSelectors));\n }\n\n // filter out those that don't match every common selector\n if (commonSelectors.length) {\n res = res.filter(id => applyCommonSelectors(id));\n }\n\n // filter out those that don't match every native selector\n if (nativeSelectors.length) {\n res = res.filter(id => applyNativeSelectors(id));\n }\n\n // filter out those that don't match every enum selector\n if (enumSelectors.length) {\n res = res.filter(id => applyEnumSelectors(id));\n }\n }\n\n const resUnique: string[] = [];\n for (let i = 0; i < res.length; i++) {\n if (!resUnique.includes(res[i])) {\n resUnique.push(res[i]);\n }\n }\n\n for (let i = 0; i < resUnique.length; i++) {\n result[i] = resUnique[i];\n }\n result.length = resUnique.length;\n\n // Implementing the Symbol.iterator contract makes the query result iterable\n result[Symbol.iterator] = function* () {\n for (let i = 0; i < result.length; i++) {\n yield result[i];\n }\n };\n result.toArray = function (): string[] {\n return [...resUnique];\n };\n result.each = function (callback: (id: string, index: number) => void | false): iobJS.QueryResult {\n if (typeof callback === 'function') {\n let r: boolean | void;\n for (let i = 0; i < this.length; i++) {\n r = callback(result[i], i);\n if (r === false) {\n break;\n }\n }\n }\n return this;\n };\n // @ts-expect-error fix later\n result.getState = function (\n callback?: iobJS.GetStateCallback,\n ): void | null | undefined | iobJS.TypedState | iobJS.AbsentState {\n if ((adapter.config as JavaScriptAdapterConfig).subscribe) {\n if (typeof callback !== 'function') {\n sandbox.log('You cannot use this function synchronous', 'error');\n } else {\n adapter.getForeignState(\n this[0],\n (err: Error | null | undefined, state?: ioBroker.State | null): void => {\n callback(\n err,\n context.convertBackStringifiedValues(this[0], state) as\n | iobJS.TypedState\n | iobJS.AbsentState,\n );\n },\n );\n }\n } else {\n if (!this[0]) {\n return null;\n }\n if (context.interimStateValues[this[0]] !== undefined) {\n return context.convertBackStringifiedValues(this[0], context.interimStateValues[this[0]]) as\n | iobJS.TypedState\n | iobJS.AbsentState;\n }\n return context.convertBackStringifiedValues(this[0], states[this[0]]) as\n | iobJS.TypedState\n | iobJS.AbsentState;\n }\n };\n result.getStateAsync = async function (): Promise<\n iobJS.TypedState | iobJS.AbsentState | null | undefined\n > {\n if ((adapter.config as JavaScriptAdapterConfig).subscribe) {\n const state = await adapter.getForeignStateAsync(this[0]);\n return context.convertBackStringifiedValues(this[0], state) as\n | iobJS.TypedState\n | iobJS.AbsentState\n | null;\n }\n if (!this[0]) {\n return null;\n }\n if (context.interimStateValues[this[0]] !== undefined) {\n return context.convertBackStringifiedValues(this[0], context.interimStateValues[this[0]]) as\n | iobJS.TypedState\n | iobJS.AbsentState\n | null;\n }\n return context.convertBackStringifiedValues(this[0], states[this[0]]) as\n | iobJS.TypedState\n | iobJS.AbsentState\n | null;\n };\n result.setState = function (\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck?: boolean | 'false' | 'true' | null | iobJS.SetStateCallback,\n callback?: iobJS.SetStateCallback,\n ) {\n if (typeof isAck === 'function') {\n callback = isAck;\n isAck = undefined;\n }\n result\n .setStateAsync(state, isAck as boolean | 'false' | 'true')\n .then(() => typeof callback === 'function' && callback());\n return this;\n };\n result.setStateAsync = async function (\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck?: boolean,\n ): Promise {\n for (let i = 0; i < this.length; i++) {\n await sandbox.setStateAsync(this[i], state, isAck);\n }\n };\n result.setStateChanged = function (\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck?: boolean,\n callback?: () => void,\n ) {\n if (typeof isAck === 'function') {\n callback = isAck;\n isAck = undefined;\n }\n result.setStateChangedAsync(state, isAck).then(() => typeof callback === 'function' && callback());\n return this;\n };\n result.setStateChangedAsync = async function (\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck?: boolean,\n ): Promise {\n for (let i = 0; i < this.length; i++) {\n await sandbox.setStateChangedAsync(this[i], state, isAck);\n }\n };\n result.setStateDelayed = function (\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck: boolean | number | undefined,\n delay?: number | boolean,\n clearRunning?: boolean | (() => void),\n callback?: () => void,\n ) {\n if (typeof isAck !== 'boolean') {\n callback = clearRunning as () => void;\n clearRunning = delay as boolean;\n delay = isAck as number;\n isAck = undefined;\n }\n if (typeof delay !== 'number') {\n callback = clearRunning as () => void;\n clearRunning = delay;\n delay = 0;\n }\n if (typeof clearRunning !== 'boolean') {\n callback = clearRunning;\n clearRunning = true;\n }\n let count = this.length;\n for (let i = 0; i < this.length; i++) {\n sandbox.setStateDelayed(this[i], state, isAck as boolean, delay, clearRunning, () => {\n if (!--count && typeof callback === 'function') {\n callback();\n }\n });\n }\n return this;\n };\n result.on = function (callbackOrId: string | ((data: any) => void), value?: any) {\n for (let i = 0; i < this.length; i++) {\n sandbox.subscribe(this[i], callbackOrId, value);\n }\n return this;\n };\n return result;\n },\n log: function (msg: string, severity?: ioBroker.LogLevel): void {\n severity = severity || 'info';\n\n // disable log in log handler (prevent endless loops)\n if (sandbox.logHandler && (sandbox.logHandler === severity || sandbox.logHandler === '*')) {\n return;\n }\n\n if (!adapter.log[severity]) {\n msg = `Unknown severity level \"${severity}\" by log of [${msg}]`;\n severity = 'warn';\n }\n\n if (msg && typeof msg !== 'string') {\n msg = mods.util.format(msg);\n }\n\n if (debugMode) {\n console.log(`${severity}$$${name}$$${msg}`, Date.now());\n } else {\n adapter.log[severity](`${name}: ${msg}`);\n }\n },\n onLog: function (severity: ioBroker.LogLevel, callback: (info: LogMessage) => void): number {\n if (!['info', 'error', 'debug', 'silly', 'warn', '*'].includes(severity)) {\n sandbox.log(`Unknown severity \"${severity}\"`, 'warn');\n return 0;\n }\n if (typeof callback !== 'function') {\n sandbox.log(`Invalid callback for onLog`, 'warn');\n return 0;\n }\n\n const handler = { id: Date.now() + Math.floor(Math.random() * 10000), cb: callback, sandbox, severity };\n context.logSubscriptions[sandbox.scriptName] = context.logSubscriptions[sandbox.scriptName] || [];\n context.logSubscriptions[sandbox.scriptName].push(handler);\n context.updateLogSubscriptions();\n\n sandbox.__engine.__subscriptionsLog += 1;\n\n sandbox.verbose &&\n sandbox.log(\n `onLog(severity=${severity}, id=${handler.id}) - logSubscriptions=${sandbox.__engine.__subscriptionsLog}`,\n 'info',\n );\n\n if (\n sandbox.__engine.__subscriptionsLog %\n (adapter.config as JavaScriptAdapterConfig).maxTriggersPerScript ===\n 0\n ) {\n sandbox.log(\n `More than ${sandbox.__engine.__subscriptionsLog} log subscriptions registered. Check your script!`,\n 'warn',\n );\n }\n\n return handler.id;\n },\n onLogUnregister: function (\n idOrCallbackOrSeverity: number | ioBroker.LogLevel | ((info: LogMessage) => void),\n ): boolean {\n let found = false;\n\n if (context.logSubscriptions?.[sandbox.scriptName]) {\n sandbox.verbose &&\n sandbox.log(\n `onLogUnregister(idOrCallbackOrSeverity=${JSON.stringify(idOrCallbackOrSeverity)}) - logSubscriptions=${sandbox.__engine.__subscriptionsLog}`,\n 'info',\n );\n\n for (let i = 0; i < context.logSubscriptions[sandbox.scriptName].length; i++) {\n if (\n context.logSubscriptions[sandbox.scriptName][i].cb === idOrCallbackOrSeverity ||\n context.logSubscriptions[sandbox.scriptName][i].id === idOrCallbackOrSeverity ||\n context.logSubscriptions[sandbox.scriptName][i].severity === idOrCallbackOrSeverity\n ) {\n sandbox.verbose &&\n sandbox.log(\n `onLogUnregister(idOrCallbackOrSeverity=${JSON.stringify(idOrCallbackOrSeverity)}, removing id=${context.logSubscriptions[sandbox.scriptName][i].id})`,\n 'info',\n );\n\n context.logSubscriptions[sandbox.scriptName].splice(i, 1);\n i--;\n sandbox.__engine.__subscriptionsLog--;\n\n found = true;\n\n // if deletion via ID\n if (typeof idOrCallbackOrSeverity === 'number') {\n break;\n }\n } else {\n sandbox.verbose &&\n sandbox.log(\n `onLogUnregister(idOrCallbackOrSeverity=${JSON.stringify(idOrCallbackOrSeverity)}) NOT = ${JSON.stringify(context.logSubscriptions[sandbox.scriptName][i])}`,\n 'info',\n );\n }\n }\n }\n\n context.updateLogSubscriptions();\n\n return found;\n },\n exec: function (\n cmd: string,\n options?: ExecOptions | ((error: Error | null | string, stdout?: string, stderr?: string) => void),\n callback?: (error: Error | null | string, stdout?: string, stderr?: string) => void,\n ): undefined | ChildProcess {\n if (typeof options === 'function') {\n callback = options as (error: Error | null | string, stdout?: string, stderr?: string) => void;\n options = {};\n }\n if (!(adapter.config as JavaScriptAdapterConfig).enableExec) {\n const error = 'exec is not available. Please enable \"Enable Exec\" option in instance settings';\n sandbox.log(error, 'error');\n\n if (typeof callback === 'function') {\n setImmediate(callback, error, undefined, undefined);\n }\n } else {\n if (sandbox.verbose) {\n sandbox.log(`exec(cmd=${cmd})`, 'info');\n }\n\n if (debug) {\n sandbox.log(words._('Command %s was not executed, while debug mode is active', cmd), 'warn');\n if (typeof callback === 'function') {\n setImmediate(function () {\n callback(null, '', '');\n });\n }\n } else {\n return mods.child_process.exec(\n cmd,\n options,\n (error: Error | null, stdout: string, stderr: string): void => {\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, error, stdout, stderr);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n },\n );\n }\n }\n },\n email: function (msg: string | SendMailOptions): void {\n if (sandbox.verbose) {\n sandbox.log(`email(msg=${JSON.stringify(msg)})`, 'info');\n }\n sandbox.log(`email(msg=${JSON.stringify(msg)}) is deprecated. Please use sendTo instead!`, 'warn');\n adapter.sendTo('email', msg);\n },\n pushover: function (msg: string | PushoverOptions): void {\n if (sandbox.verbose) {\n sandbox.log(`pushover(msg=${JSON.stringify(msg)})`, 'info');\n }\n sandbox.log(`pushover(msg=${JSON.stringify(msg)}) is deprecated. Please use sendTo instead!`, 'warn');\n adapter.sendTo('pushover', msg);\n },\n httpGet: function (\n url: string,\n options:\n | {\n timeout?: number;\n responseType?: ResponseType;\n headers?: Record;\n basicAuth?: { user: string; password: string } | null;\n bearerAuth?: string;\n validateCertificate?: boolean;\n }\n | ((\n error: Error | null,\n result: {\n statusCode: number | null;\n data: any;\n headers: Record;\n responseTime: number;\n },\n ) => void),\n callback?: (\n error: Error | null,\n result: {\n statusCode: number | null;\n data: any;\n headers: Record;\n responseTime: number;\n },\n ) => void,\n ): void {\n if (typeof options === 'function') {\n callback = options as (\n error: Error | null,\n result: {\n statusCode: number | null;\n data: any;\n headers: Record;\n responseTime: number;\n },\n ) => void;\n options = {};\n }\n\n const config = {\n ...getHttpRequestConfig(url, options),\n method: 'get',\n };\n\n if (sandbox.verbose) {\n sandbox.log(`httpGet(config=${JSON.stringify(config)})`, 'info');\n }\n\n const startTime = Date.now();\n\n mods.axios\n .default(config)\n .then((response: AxiosResponse) => {\n const responseTime = Date.now() - startTime;\n\n if (sandbox.verbose) {\n sandbox.log(`httpGet(url=${url}, responseTime=${responseTime}ms)`, 'info');\n }\n\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, null, {\n statusCode: response.status,\n data: response.data,\n headers: response.headers as Record,\n responseTime,\n });\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n })\n .catch((error: any) => {\n const responseTime = Date.now() - startTime;\n\n sandbox.log(`httpGet(url=${url}, error=${error.message})`, 'error');\n\n if (typeof callback === 'function') {\n let result: {\n statusCode: number | null;\n data: any;\n headers: Record;\n responseTime: number;\n } = {\n statusCode: null,\n data: null,\n headers: {},\n responseTime,\n };\n\n if (error.response) {\n result = {\n statusCode: error.response.status,\n data: error.response.data,\n headers: error.response.headers,\n responseTime,\n };\n }\n\n try {\n callback.call(sandbox, error.message, result);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n });\n },\n httpPost: function (\n url: string,\n data: any,\n options:\n | {\n timeout?: number;\n responseType?: ResponseType;\n headers?: Record;\n basicAuth?: { user: string; password: string } | null;\n bearerAuth?: string;\n validateCertificate?: boolean;\n }\n | ((\n error: Error | null,\n result: {\n statusCode: number | null;\n data: any;\n headers: Record;\n responseTime: number;\n },\n ) => void),\n callback?: (\n error: Error | null,\n result: {\n statusCode: number | null;\n data: any;\n headers: Record;\n responseTime: number;\n },\n ) => void,\n ): void {\n if (typeof options === 'function') {\n callback = options;\n options = {};\n }\n\n const config = {\n ...getHttpRequestConfig(\n url,\n options as {\n timeout?: number;\n responseType?: ResponseType;\n headers?: Record;\n basicAuth?: { user: string; password: string } | null;\n bearerAuth?: string;\n validateCertificate?: boolean;\n },\n ),\n method: 'post',\n data,\n };\n\n if (sandbox.verbose) {\n sandbox.log(`httpPost(config=${JSON.stringify(config)}, data=${data})`, 'info');\n }\n\n const startTime = Date.now();\n\n mods.axios\n .default(config)\n .then((response: AxiosResponse) => {\n const responseTime = Date.now() - startTime;\n\n if (sandbox.verbose) {\n sandbox.log(`httpPost(url=${url}, responseTime=${responseTime}ms)`, 'info');\n }\n\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, null, {\n statusCode: response.status,\n data: response.data,\n headers: response.headers,\n responseTime,\n });\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n })\n .catch((error: unknown) => {\n const responseTime = Date.now() - startTime;\n\n sandbox.log(`httpPost(url=${url}, error=${(error as Error).message})`, 'error');\n\n if (typeof callback === 'function') {\n let result: {\n statusCode: number | null;\n data: any;\n headers: Record;\n responseTime: number;\n } = {\n statusCode: null,\n data: null,\n headers: {},\n responseTime,\n };\n const response: AxiosResponse | undefined = (error as AxiosError).response;\n\n if (response) {\n result = {\n statusCode: response.status,\n data: response.data,\n headers: response.headers,\n responseTime,\n };\n }\n\n try {\n callback.call(sandbox, new Error((error as AxiosError).message), result);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n });\n },\n createTempFile: function (fileName: string, data: Buffer | string): undefined | string {\n const os = mods.os;\n const path = mods.path;\n const fs = mods.fs;\n\n let tempDirPath = context.tempDirectories?.[sandbox.scriptName];\n\n if (!tempDirPath) {\n // create temp directory\n tempDirPath = fs.mkdtempSync(\n path.join(os.tmpdir(), `${sandbox.scriptName.substring('script.js.'.length)}-`),\n );\n context.tempDirectories[sandbox.scriptName] = tempDirPath;\n\n sandbox.verbose &&\n sandbox.log(\n `createTempFile(fileName=${fileName}, tempDirPath=${tempDirPath}) created temp directory in ${os.tmpdir()}`,\n 'info',\n );\n }\n\n const filePath = path.join(tempDirPath, fileName);\n\n // is sub dir?\n const fileDir = path.dirname(filePath);\n if (!fs.existsSync(fileDir)) {\n fs.mkdirSync(fileDir, { recursive: true });\n }\n\n if (typeof data === 'undefined') {\n sandbox.log(\n `createTempFile(fileName=${fileName}, fileDir=${fileDir}, filePath=${filePath}) data is undefined, file not created!`,\n 'error',\n );\n\n return undefined;\n }\n\n fs.writeFileSync(filePath, data);\n sandbox.verbose &&\n sandbox.log(`createTempFile(fileName=${fileName}, fileDir=${fileDir}, filePath=${filePath})`, 'info');\n\n return filePath;\n },\n subscribe: function (\n pattern:\n | TimeRule\n | AstroRule\n | Pattern\n | SchedulerRule\n | string\n | (TimeRule | AstroRule | Pattern | SchedulerRule | string)[],\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n callbackOrChangeTypeOrId: string | ChangeType | ((event?: EventObj) => void),\n value?: any,\n ):\n | SubscriptionResult\n | IobSchedule\n | string\n | null\n | undefined\n | (SubscriptionResult | IobSchedule | string | null | undefined)[] {\n // If a schedule object is given\n if (\n (typeof pattern === 'string' && pattern[0] === '{') ||\n (typeof pattern === 'object' && (pattern as SchedulerRule).period)\n ) {\n return sandbox.schedule(pattern as SchedulerRule, callbackOrChangeTypeOrId as () => void);\n }\n // If an array of schedules is given\n if (pattern && Array.isArray(pattern)) {\n const result: (IobSchedule | string | null | undefined)[] = [];\n for (const p of pattern) {\n result.push(\n sandbox.subscribe(p as SchedulerRule | string, callbackOrChangeTypeOrId, value) as\n | IobSchedule\n | string\n | null\n | undefined,\n );\n }\n return result;\n }\n\n // detect subscribe('id', 'any', (obj) => {})\n let oPattern: Pattern;\n if (\n (typeof pattern === 'string' || pattern instanceof RegExp) &&\n typeof callbackOrChangeTypeOrId === 'string' &&\n typeof value === 'function'\n ) {\n oPattern = { id: pattern, change: callbackOrChangeTypeOrId as ChangeType };\n callbackOrChangeTypeOrId = value;\n value = undefined;\n } else {\n oPattern = pattern as Pattern;\n }\n\n if (oPattern?.id && Array.isArray(oPattern.id)) {\n const result: (IobSchedule | string | null | undefined)[] = [];\n for (let t = 0; t < oPattern.id.length; t++) {\n const pa: Pattern = JSON.parse(JSON.stringify(oPattern));\n pa.id = oPattern.id[t];\n result.push(\n sandbox.subscribe(pa, callbackOrChangeTypeOrId, value) as\n | IobSchedule\n | string\n | null\n | undefined,\n );\n }\n return result;\n }\n\n // try to detect astro or cron (by spaces)\n if (isObject(pattern) || (typeof pattern === 'string' && pattern.match(/[,/\\d*]+\\s[,/\\d*]+\\s[,/\\d*]+/))) {\n if ((pattern as AstroRule).astro) {\n return sandbox.schedule(pattern as AstroRule, callbackOrChangeTypeOrId as () => void);\n } else if ((pattern as TimeRule).time) {\n return sandbox.schedule(\n (pattern as TimeRule).time as string,\n callbackOrChangeTypeOrId as () => void,\n );\n }\n }\n\n let callback: undefined | ((obj: EventObj) => void);\n\n // source is set by regexp if defined as /regexp/\n if (!isObject(pattern) || pattern instanceof RegExp || (pattern as RegExp).source) {\n oPattern = { id: pattern as string | RegExp, change: 'ne' };\n }\n\n if (oPattern.id !== undefined && !oPattern.id) {\n sandbox.log(`Error by subscription (trigger): empty ID defined. All states matched.`, 'error');\n return;\n } else if (typeof oPattern.id === 'boolean' || typeof oPattern.id === 'number') {\n sandbox.log(`Error by subscription (trigger): Wrong ID of type boolean or number.`, 'error');\n return;\n }\n\n sandbox.__engine.__subscriptions += 1;\n\n if (\n sandbox.__engine.__subscriptions % (adapter.config as JavaScriptAdapterConfig).maxTriggersPerScript ===\n 0\n ) {\n sandbox.log(\n `More than ${sandbox.__engine.__subscriptions} subscriptions registered. Check your script!`,\n 'warn',\n );\n }\n\n if (oPattern.q === undefined) {\n oPattern.q = 0;\n }\n\n // add adapter namespace if nothing given\n if (oPattern.id && typeof oPattern.id === 'string' && !oPattern.id.includes('.')) {\n oPattern.id = `${adapter.namespace}.${oPattern.id}`;\n }\n\n if (typeof callbackOrChangeTypeOrId === 'function') {\n callback = callbackOrChangeTypeOrId;\n } else {\n if (typeof value === 'undefined') {\n callback = function (obj: EventObj) {\n sandbox.setState(callbackOrChangeTypeOrId, obj.newState.val);\n };\n } else {\n callback = function (/* obj */) {\n sandbox.setState(callbackOrChangeTypeOrId, value);\n };\n }\n }\n\n const subs: SubscriptionResult = {\n pattern: oPattern,\n callback: (obj: EventObj) => {\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, obj);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n },\n name,\n };\n\n // try to extract adapter\n if (oPattern.id && typeof oPattern.id === 'string') {\n const parts = oPattern.id.split('.');\n const a = `${parts[0]}.${parts[1]}`;\n const _adapter = `system.adapter.${a}`;\n\n if (objects[_adapter] && objects[_adapter].common && objects[_adapter].common.subscribable) {\n const alive = `system.adapter.${a}.alive`;\n context.adapterSubs[alive] = context.adapterSubs[alive] || [];\n\n const subExists = context.adapterSubs[alive].filter(sub => sub === oPattern.id).length > 0;\n\n if (!subExists) {\n context.adapterSubs[alive].push(oPattern.id);\n adapter.sendTo(a, 'subscribe', oPattern.id);\n }\n }\n }\n if (sandbox.verbose) {\n sandbox.log(`subscribe: ${JSON.stringify(subs)}`, 'info');\n }\n\n subscribePattern(script, oPattern.id as string);\n\n subs.patternCompareFunctions = getPatternCompareFunctions(oPattern);\n context.subscriptions.push(subs);\n\n if (oPattern.enumName || oPattern.enumId) {\n context.isEnums = true;\n }\n return subs;\n },\n getSubscriptions: function (): Record {\n const result: Record = {};\n for (let s = 0; s < context.subscriptions.length; s++) {\n result[context.subscriptions[s].pattern.id as string] =\n result[context.subscriptions[s].pattern.id as string] || [];\n result[context.subscriptions[s].pattern.id as string].push({\n name: context.subscriptions[s].name,\n pattern: context.subscriptions[s].pattern,\n });\n }\n if (sandbox.verbose) {\n sandbox.log(`getSubscriptions() => ${JSON.stringify(result)}`, 'info');\n }\n return result;\n },\n getFileSubscriptions: function (): Record {\n const result: Record = {};\n for (let s = 0; s < context.subscriptionsFile.length; s++) {\n const key = `${context.subscriptionsFile[s].id}$%$${context.subscriptionsFile[s].fileNamePattern}`;\n result[key] = result[key] || [];\n result[key].push({\n name: context.subscriptionsFile[s].name,\n id: context.subscriptionsFile[s].id,\n fileNamePattern: context.subscriptionsFile[s].fileNamePattern,\n });\n }\n if (sandbox.verbose) {\n sandbox.log(`getFileSubscriptions() => ${JSON.stringify(result)}`, 'info');\n }\n return result;\n },\n adapterSubscribe: function (id: string): void {\n if (typeof id !== 'string') {\n sandbox.log(`adapterSubscribe: invalid type of id ${typeof id}`, 'error');\n return;\n }\n const parts = id.split('.');\n const _adapter = `system.adapter.${parts[0]}.${parts[1]}`;\n if (objects[_adapter]?.common?.subscribable) {\n const a = `${parts[0]}.${parts[1]}`;\n const alive = `system.adapter.${a}.alive`;\n context.adapterSubs[alive] = context.adapterSubs[alive] || [];\n context.adapterSubs[alive].push(id);\n if (sandbox.verbose) {\n sandbox.log(`adapterSubscribe: ${a} - ${id}`, 'info');\n }\n adapter.sendTo(a, 'subscribe', id);\n }\n },\n adapterUnsubscribe: function (\n idOrObject: string | SubscriptionResult | (string | SubscriptionResult)[],\n ): boolean | boolean[] {\n // todo: BF - it could be an error\n return sandbox.unsubscribe(idOrObject);\n },\n unsubscribe: function (\n idOrObject: string | SubscriptionResult | (string | SubscriptionResult)[],\n ): boolean | boolean[] {\n if (idOrObject && Array.isArray(idOrObject)) {\n const result: boolean[] = [];\n for (let t = 0; t < idOrObject.length; t++) {\n result.push(sandbox.unsubscribe(idOrObject[t]) as boolean);\n }\n return result;\n }\n\n if (sandbox.verbose) {\n sandbox.log(`adapterUnsubscribe(id=${JSON.stringify(idOrObject)})`, 'info');\n }\n\n if (isObject(idOrObject)) {\n for (let i = context.subscriptions.length - 1; i >= 0; i--) {\n if (context.subscriptions[i] === idOrObject) {\n unsubscribePattern(script, context.subscriptions[i].pattern.id as string);\n context.subscriptions.splice(i, 1);\n sandbox.__engine.__subscriptions--;\n return true;\n }\n }\n return false;\n }\n let deleted = 0;\n for (let i = context.subscriptions.length - 1; i >= 0; i--) {\n if (context.subscriptions[i].name === name && context.subscriptions[i].pattern.id === idOrObject) {\n deleted++;\n unsubscribePattern(script, context.subscriptions[i].pattern.id as string);\n context.subscriptions.splice(i, 1);\n sandbox.__engine.__subscriptions--;\n }\n }\n return !!deleted;\n },\n on: function (\n pattern:\n | TimeRule\n | AstroRule\n | Pattern\n | SchedulerRule\n | string\n | (TimeRule | AstroRule | Pattern | SchedulerRule | string)[],\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n callbackOrChangeTypeOrId: string | ChangeType | ((event?: EventObj) => void),\n value?: any,\n ):\n | SubscriptionResult\n | IobSchedule\n | string\n | null\n | undefined\n | (SubscriptionResult | IobSchedule | string | null | undefined)[] {\n return sandbox.subscribe(pattern, callbackOrChangeTypeOrId, value);\n },\n onEnumMembers: function (enumId: string, callback: (event?: EventObj) => void): void {\n if (enums.includes(enumId)) {\n const subscriptions: Record = {};\n\n const init = (): void => {\n const obj: ioBroker.EnumObject = objects[enumId] as ioBroker.EnumObject;\n const common: ioBroker.EnumCommon = obj?.common ?? {};\n const members: string[] = common?.members ?? [];\n\n // Remove old subscriptions\n for (const [objId, subscription] of Object.entries(subscriptions)) {\n if (!members.includes(objId)) {\n sandbox.unsubscribe(subscription);\n delete subscriptions[objId];\n }\n }\n\n // Subscribe to all members of enum\n for (const objId of members) {\n if (!Object.keys(subscriptions).includes(objId)) {\n if (objects?.[objId]?.type === 'state') {\n // Just subscribe to states\n subscriptions[objId] = sandbox.subscribe(objId, callback) as\n | string\n | SubscriptionResult; // TODO: more features\n }\n }\n }\n\n sandbox.verbose &&\n sandbox.log(\n `onEnumMembers(id=${enumId}, members=${JSON.stringify(Object.keys(subscriptions))})`,\n 'info',\n );\n };\n\n init();\n\n sandbox.subscribeObject(enumId, obj => obj && init());\n } else {\n sandbox.log(`onEnumMembers: enum with id \"${enumId}\" doesn't exists`, 'error');\n }\n },\n onFile: function (\n id: string,\n fileNamePattern: string | string[],\n withFileOrCallback:\n | boolean\n | ((id: string, fileName: string, size: number, file?: string | Buffer, mimeType?: string) => void),\n callback?: (\n id: string,\n fileName: string,\n size: number | null,\n file?: string | Buffer,\n mimeType?: string,\n ) => void,\n ): undefined | FileSubscriptionResult | (undefined | FileSubscriptionResult)[] {\n if (typeof withFileOrCallback === 'function') {\n callback = withFileOrCallback as (\n id: string,\n fileName: string,\n size: number | null,\n file?: string | Buffer,\n mimeType?: string,\n ) => void;\n withFileOrCallback = false;\n }\n\n if (!adapter.subscribeForeignFiles) {\n sandbox.log(\n 'onFile: your js-controller does not support yet onFile subscribes. Please update to js-controller@4.1.x or newer',\n 'warn',\n );\n return;\n }\n if (!id || !fileNamePattern) {\n sandbox.log(\n 'onFile: invalid parameters. Usage: onFile(\"vis.0\", \"main/*\", true, (id, fileName, size, file, mimeType) => {});',\n 'error',\n );\n return;\n }\n if (typeof callback !== 'function') {\n sandbox.offFile(id, fileNamePattern);\n return;\n }\n\n if (Array.isArray(fileNamePattern)) {\n return fileNamePattern.map(\n filePattern =>\n sandbox.onFile(id, filePattern, withFileOrCallback, callback) as\n | undefined\n | FileSubscriptionResult,\n );\n }\n\n sandbox.__engine.__subscriptionsFile += 1;\n\n sandbox.verbose &&\n sandbox.log(\n `onFile(id=${id}, fileNamePattern=${fileNamePattern}) - fileSubscriptions=${sandbox.__engine.__subscriptionsFile}`,\n 'info',\n );\n\n if (\n sandbox.__engine.__subscriptionsFile %\n (adapter.config as JavaScriptAdapterConfig).maxTriggersPerScript ===\n 0\n ) {\n sandbox.log(\n `More than ${sandbox.__engine.__subscriptionsFile} file subscriptions registered. Check your script!`,\n 'warn',\n );\n }\n\n let idRegEx: RegExp | undefined;\n let fileRegEx: RegExp | undefined;\n if (id.includes('*')) {\n idRegEx = new RegExp(pattern2RegEx(id));\n }\n if (fileNamePattern.includes('*')) {\n fileRegEx = new RegExp(pattern2RegEx(fileNamePattern));\n }\n\n const subs: FileSubscriptionResult = {\n id,\n fileNamePattern,\n withFile: withFileOrCallback,\n idRegEx,\n fileRegEx,\n callback: (id: string, fileName: string, size: number | null, withFile: boolean): void => {\n try {\n sandbox.verbose &&\n sandbox.log(`onFile changed(id=${id}, fileName=${fileName}, size=${size})`, 'info');\n\n if (withFile && (size || 0) > 0) {\n adapter\n .readFileAsync(id, fileName)\n .then(data => {\n try {\n callback.call(sandbox, id, fileName, size, data.file, data.mimeType);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n })\n .catch(error => errorInCallback(error));\n } else {\n callback.call(sandbox, id, fileName, size);\n }\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n },\n name,\n };\n\n context.subscriptionsFile.push(subs);\n subscribeFile(script, id, fileNamePattern);\n return subs;\n },\n offFile: function (\n idOrObject: FileSubscriptionResult | string | (FileSubscriptionResult | string)[],\n fileNamePattern?: string | string[],\n ): boolean | boolean[] {\n if (!adapter.unsubscribeForeignFiles) {\n sandbox.log(\n 'offFile: your js-controller does not support yet file unsubscribes. Please update to js-controller@4.1.x or newer',\n 'warn',\n );\n return false;\n }\n\n sandbox.verbose &&\n sandbox.log(\n `offFile(idOrObject=${JSON.stringify(idOrObject)}, fileNamePattern=${JSON.stringify(fileNamePattern)}) - fileSubscriptions=${sandbox.__engine.__subscriptionsFile}`,\n 'info',\n );\n\n if (idOrObject && typeof idOrObject === 'object') {\n if (Array.isArray(idOrObject)) {\n const result: boolean[] = [];\n for (let t = 0; t < idOrObject.length; t++) {\n result.push(sandbox.offFile(idOrObject[t]) as boolean);\n }\n return result;\n }\n for (let i = context.subscriptionsFile.length - 1; i >= 0; i--) {\n if (context.subscriptionsFile[i] === idOrObject) {\n unsubscribeFile(\n script,\n context.subscriptionsFile[i].id,\n context.subscriptionsFile[i].fileNamePattern,\n );\n\n sandbox.verbose &&\n sandbox.log(\n `offFile(type=object, fileNamePattern=${JSON.stringify(fileNamePattern)}, removing id=${context.subscriptionsFile[i].id})`,\n 'info',\n );\n\n context.subscriptionsFile.splice(i, 1);\n sandbox.__engine.__subscriptionsFile--;\n return true;\n }\n }\n return false;\n }\n\n if (fileNamePattern && Array.isArray(fileNamePattern)) {\n const result: boolean[] = [];\n for (let t = 0; t < fileNamePattern.length; t++) {\n result.push(sandbox.offFile(idOrObject, fileNamePattern[t]) as boolean);\n }\n return result;\n }\n\n let deleted = 0;\n for (let i = context.subscriptionsFile.length - 1; i >= 0; i--) {\n if (\n context.subscriptionsFile[i].id === idOrObject &&\n context.subscriptionsFile[i].fileNamePattern === fileNamePattern\n ) {\n deleted++;\n unsubscribeFile(\n script,\n context.subscriptionsFile[i].id,\n context.subscriptionsFile[i].fileNamePattern,\n );\n\n sandbox.verbose &&\n sandbox.log(\n `offFile(type=string, fileNamePattern=${fileNamePattern}, removing id=${context.subscriptionsFile[i].id})`,\n 'info',\n );\n\n context.subscriptionsFile.splice(i, 1);\n sandbox.__engine.__subscriptionsFile--;\n }\n }\n return !!deleted;\n },\n /** Registers a one-time subscription which automatically unsubscribes after the first invocation */\n once: function (\n pattern:\n | TimeRule\n | AstroRule\n | Pattern\n | SchedulerRule\n | string\n | (TimeRule | AstroRule | Pattern | SchedulerRule | string)[],\n callback?: (event?: EventObj) => void,\n ): string | SubscriptionResult | Promise {\n function _once(cb: (obj?: EventObj) => void): string | SubscriptionResult {\n // eslint-disable-next-line prefer-const\n let subscription: string | SubscriptionResult;\n const handler = (obj?: EventObj): void => {\n subscription && sandbox.unsubscribe(subscription);\n typeof cb === 'function' && cb(obj);\n };\n subscription = sandbox.subscribe(pattern, handler) as string | SubscriptionResult;\n return subscription;\n }\n if (typeof callback === 'function') {\n // Callback-style: once(\"id\", (obj) => { ... })\n return _once(callback);\n }\n\n // Promise-style: once(\"id\").then(obj => { ... })\n return new Promise(resolve => _once(resolve));\n },\n schedule: function (\n pattern: SchedulerRule | AstroRule | Date | string,\n callback: () => void,\n ): IobSchedule | string | null | undefined {\n if (typeof callback !== 'function') {\n sandbox.log(`schedule callback missing`, 'error');\n return null;\n }\n\n if (\n (typeof pattern === 'string' && pattern[0] === '{') ||\n (typeof pattern === 'object' && (pattern as SchedulerRule).period)\n ) {\n sandbox.verbose &&\n sandbox.log(\n `schedule(wizard=${typeof pattern === 'object' ? JSON.stringify(pattern) : pattern})`,\n 'info',\n );\n\n if (!context.scheduler) {\n sandbox.log(\n `Cannot schedule \"${typeof pattern === 'object' ? JSON.stringify(pattern) : pattern}\" because scheduler is not available`,\n 'error',\n );\n return null;\n }\n\n const schedule: string | null = context.scheduler.add(\n pattern as SchedulerRule | string,\n sandbox.scriptName,\n callback,\n );\n if (schedule) {\n script.wizards.push(schedule);\n sandbox.__engine.__schedules += 1;\n\n if (\n sandbox.__engine.__schedules %\n (adapter.config as JavaScriptAdapterConfig).maxTriggersPerScript ===\n 0\n ) {\n sandbox.log(\n `More than ${sandbox.__engine.__schedules} schedules registered. Check your script!`,\n 'warn',\n );\n }\n }\n\n return schedule;\n }\n\n const adapterConfig: JavaScriptAdapterConfig = adapter.config as JavaScriptAdapterConfig;\n\n if (typeof pattern === 'object' && (pattern as AstroRule).astro) {\n const astroPattern = pattern as AstroRule;\n const nowDate = new Date();\n\n if (\n adapterConfig.latitude === undefined ||\n adapterConfig.longitude === undefined ||\n adapterConfig.latitude === null ||\n adapterConfig.longitude === null\n ) {\n sandbox.log('Longitude or latitude does not set. Cannot use astro.', 'error');\n return null;\n }\n\n // ensure events are calculated independent of current time\n // TODO: use getAstroStartOfDay of adapter?\n const todayNoon = new Date(nowDate);\n todayNoon.setHours(12, 0, 0, 0);\n let ts = mods.suncalc.getTimes(todayNoon, adapterConfig.latitude, adapterConfig.longitude)[\n astroPattern.astro\n ];\n\n // event on the next day, correct or force recalculation at midnight\n if (todayNoon.getDate() !== ts.getDate()) {\n todayNoon.setDate(todayNoon.getDate() - 1);\n ts = mods.suncalc.getTimes(todayNoon, adapterConfig.latitude, adapterConfig.longitude)[\n astroPattern.astro\n ];\n }\n\n if (ts.getTime().toString() === 'NaN') {\n sandbox.log(\n `Cannot calculate \"${astroPattern.astro}\" for ${adapterConfig.latitude}, ${adapterConfig.longitude}`,\n 'warn',\n );\n ts = new Date(nowDate.getTime());\n\n if (\n astroPattern.astro === 'sunriseEnd' ||\n astroPattern.astro === 'goldenHourEnd' ||\n astroPattern.astro === 'sunset' ||\n astroPattern.astro === 'nightEnd' ||\n astroPattern.astro === 'nauticalDusk'\n ) {\n ts.setHours(23);\n ts.setMinutes(59);\n ts.setSeconds(59);\n } else {\n ts.setHours(23);\n ts.setMinutes(59);\n ts.setSeconds(58);\n }\n }\n\n if (ts && astroPattern.shift) {\n ts = new Date(ts.getTime() + astroPattern.shift * 60000);\n }\n\n if (!ts || ts < nowDate) {\n const date = new Date(nowDate);\n // Event doesn't occur today - try again tomorrow\n // Calculate time till 24:00 (local, NOT UTC) and set timeout\n date.setDate(date.getDate() + 1);\n date.setMinutes(0); // Sometimes timer fires at 23:59:59\n date.setHours(0);\n date.setSeconds(1);\n date.setMilliseconds(0);\n\n sandbox.__engine.__schedules += 1;\n\n if (sandbox.__engine.__schedules % adapterConfig.maxTriggersPerScript === 0) {\n sandbox.log(\n `More than ${sandbox.__engine.__schedules} schedules registered. Check your script!`,\n 'warn',\n );\n }\n\n sandbox.verbose &&\n sandbox.log(\n `schedule(astro=${astroPattern.astro}, offset=${astroPattern.shift}) is tomorrow, waiting until ${date.toISOString()}`,\n 'info',\n );\n\n // Calculate new schedule in the next day\n sandbox.setTimeout(() => {\n if (sandbox.__engine.__schedules > 0) {\n sandbox.__engine.__schedules--;\n }\n sandbox.schedule(astroPattern, callback);\n }, date.getTime() - Date.now());\n\n return;\n }\n\n sandbox.__engine.__schedules += 1;\n\n if (sandbox.__engine.__schedules % adapterConfig.maxTriggersPerScript === 0) {\n sandbox.log(\n `More than ${sandbox.__engine.__schedules} schedules registered. Check your script!`,\n 'warn',\n );\n }\n\n sandbox.setTimeout(() => {\n try {\n callback.call(sandbox);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n // Reschedule in 2 seconds\n sandbox.setTimeout(() => {\n if (sandbox.__engine.__schedules > 0) {\n sandbox.__engine.__schedules--;\n }\n sandbox.schedule(astroPattern, callback);\n }, 2000);\n }, ts.getTime() - Date.now());\n\n sandbox.verbose &&\n sandbox.log(\n `schedule(astro=${astroPattern.astro}, offset=${astroPattern.shift}) is today, waiting until ${ts.toISOString()}`,\n 'info',\n );\n } else {\n // fix a problem with sunday and 7\n if (typeof pattern === 'string') {\n // this could be a CRON\n const parts = pattern.replace(/\\s+/g, ' ').split(' ');\n if (parts.length >= 5 && parseInt(parts[5], 10) >= 7) {\n parts[5] = '0';\n }\n pattern = parts.join(' ');\n }\n // created in VM the date object: pattern instanceof Date => false\n // so fix it\n if (typeof pattern === 'object' && (pattern as Date).getDate) {\n pattern = new Date(pattern as Date);\n }\n\n const schedule: IobSchedule = mods.nodeSchedule.scheduleJob(pattern, (): void => {\n try {\n callback.call(sandbox);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n });\n if (schedule) {\n sandbox.__engine.__schedules += 1;\n\n if (\n sandbox.__engine.__schedules %\n (adapter.config as JavaScriptAdapterConfig).maxTriggersPerScript ===\n 0\n ) {\n sandbox.log(\n `More than ${sandbox.__engine.__schedules} schedules registered. Check your script!`,\n 'warn',\n );\n }\n\n schedule._ioBroker = {\n type: 'cron',\n pattern: pattern as string | Date,\n scriptName: sandbox.scriptName,\n id: `cron_${Date.now()}_${Math.round(Math.random() * 100000)}`,\n };\n\n script.schedules.push(schedule);\n } else {\n sandbox.log(`schedule(cron=${JSON.stringify(pattern)}): cannot create schedule`, 'error');\n }\n\n if (sandbox.verbose) {\n sandbox.log(`schedule(cron=${JSON.stringify(pattern)})`, 'info');\n }\n\n return schedule;\n }\n },\n scheduleById: function (id: string, ack: boolean | (() => void) | undefined, callback?: () => void): void {\n let scheduleId: IobSchedule | string | null | undefined = null;\n let currentExp: string | null = null; // current cron expression\n\n if (typeof ack === 'function') {\n callback = ack;\n ack = undefined;\n }\n\n const rhms = /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9]):([0-5]?[0-9])$/; // hh:mm:ss\n const rhm = /^(2[0-3]|[01]?[0-9]):([0-5]?[0-9])$/; // hh:mm\n\n const init = (time: string): void => {\n if (typeof time === 'string') {\n let h: number | undefined = undefined;\n let m: number | undefined = undefined;\n let s: number | undefined = undefined;\n\n let isValid = false;\n\n let result = time.match(rhms);\n if (result) {\n [, h, m, s] = result.map(v => parseInt(v));\n isValid = true;\n } else {\n result = time.match(rhm);\n if (result) {\n [, h, m] = result.map(v => parseInt(v));\n isValid = true;\n }\n }\n\n if (isValid) {\n const cronExp = `${s ?? '0'} ${m ?? '0'} ${h ?? '0'} * * *`;\n\n if (cronExp !== currentExp) {\n sandbox.verbose &&\n sandbox.log(\n `scheduleById(id=${id}): Init with expression ${cronExp} from ${time}`,\n 'info',\n );\n currentExp = cronExp;\n\n if (scheduleId) {\n sandbox.clearSchedule(scheduleId);\n scheduleId = null;\n }\n\n scheduleId = sandbox.schedule(cronExp, () => {\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n });\n }\n } else {\n sandbox.log(\n `scheduleById(id=${id},time=${time}): cannot create schedule - invalid format (HH:MM:SS or H:M:S required)`,\n 'error',\n );\n }\n } else {\n sandbox.log(\n `scheduleById(id=${id}): cannot create schedule - invalid var type (no string)`,\n 'error',\n );\n }\n };\n\n sandbox.getState(id, (err, state) => {\n if (!err && state?.val) {\n if (sandbox.verbose) {\n sandbox.log(`scheduleById(id=${id}): Init with value ${state.val}`, 'info');\n }\n init(state.val.toString());\n }\n });\n\n const triggerDef: Pattern = { id, change: 'any' };\n if (ack !== undefined) {\n triggerDef.ack = ack;\n }\n\n sandbox.on(triggerDef, obj => {\n if (obj?.state?.val) {\n sandbox.verbose &&\n sandbox.log(`scheduleById(id=${id}): Update with value ${obj.state.val}`, 'info');\n init(obj.state.val.toString());\n }\n });\n },\n getAstroDate: function (pattern: AstroEvent, date?: Date | number, offsetMinutes?: number): Date | undefined {\n if (date === undefined) {\n date = new Date();\n }\n if (typeof date === 'number') {\n date = new Date(date);\n } else {\n date = new Date(date.getTime());\n }\n\n if (!consts.astroList.includes(pattern)) {\n const pos = consts.astroListLow.indexOf(pattern.toLowerCase());\n if (pos !== -1) {\n pattern = consts.astroList[pos];\n }\n }\n\n if (\n (!(adapter.config as JavaScriptAdapterConfig).latitude &&\n ((adapter.config as JavaScriptAdapterConfig).latitude as unknown as number) !== 0) ||\n (!(adapter.config as JavaScriptAdapterConfig).longitude &&\n ((adapter.config as JavaScriptAdapterConfig).longitude as unknown as number) !== 0)\n ) {\n sandbox.log('Longitude or latitude does not set. Cannot use astro.', 'error');\n return;\n }\n\n // ensure events are calculated independent of current time\n date.setHours(12, 0, 0, 0);\n let ts = mods.suncalc.getTimes(\n date,\n (adapter.config as JavaScriptAdapterConfig).latitude,\n (adapter.config as JavaScriptAdapterConfig).longitude,\n )[pattern];\n\n if (ts === undefined || ts.getTime().toString() === 'NaN') {\n sandbox.log(\n `Cannot calculate astro date \"${pattern}\" for ${(adapter.config as JavaScriptAdapterConfig).latitude}, ${(adapter.config as JavaScriptAdapterConfig).longitude}`,\n 'warn',\n );\n }\n\n if (sandbox.verbose) {\n sandbox.log(`getAstroDate(pattern=${pattern}, date=${date.toString()}) => ${ts}`, 'info');\n }\n\n if (offsetMinutes !== undefined) {\n ts = new Date(ts.getTime() + offsetMinutes * 60000);\n }\n return ts;\n },\n isAstroDay: function (): boolean | undefined {\n const nowDate = new Date();\n const dayBegin = sandbox.getAstroDate('sunrise');\n const dayEnd = sandbox.getAstroDate('sunset');\n\n if (dayBegin === undefined || dayEnd === undefined) {\n return;\n }\n\n if (sandbox.verbose) {\n sandbox.log(`isAstroDay() => ${nowDate >= dayBegin && nowDate <= dayEnd}`, 'info');\n }\n\n return nowDate >= dayBegin && nowDate <= dayEnd;\n },\n clearSchedule: function (schedule: IobSchedule | ScheduleName | string): boolean {\n if (context.scheduler?.get(schedule as string | ScheduleName)) {\n if (sandbox.verbose) {\n sandbox.log('clearSchedule() => wizard cleared', 'info');\n }\n const pos = script.wizards.indexOf(schedule as string);\n if (pos !== -1) {\n script.wizards.splice(pos, 1);\n if (sandbox.__engine.__schedules > 0) {\n sandbox.__engine.__schedules--;\n }\n }\n context.scheduler.remove(schedule as string | ScheduleName);\n return true;\n }\n for (let i = 0; i < script.schedules.length; i++) {\n if (schedule && typeof schedule === 'object' && (schedule as IobSchedule)._ioBroker?.type === 'cron') {\n if (script.schedules[i]._ioBroker.id === (schedule as IobSchedule)._ioBroker.id) {\n if (!mods.nodeSchedule.cancelJob(script.schedules[i])) {\n sandbox.log('Error by canceling scheduled job', 'error');\n }\n script.schedules.splice(i, 1);\n if (sandbox.__engine.__schedules > 0) {\n sandbox.__engine.__schedules--;\n }\n\n if (sandbox.verbose) {\n sandbox.log('clearSchedule() => cleared', 'info');\n }\n return true;\n }\n } else if (script.schedules[i] === schedule) {\n if (!mods.nodeSchedule.cancelJob(script.schedules[i])) {\n sandbox.log('Error by canceling scheduled job', 'error');\n }\n script.schedules.splice(i, 1);\n if (sandbox.__engine.__schedules > 0) {\n sandbox.__engine.__schedules--;\n }\n\n if (sandbox.verbose) {\n sandbox.log('clearSchedule() => cleared', 'info');\n }\n return true;\n }\n }\n\n if (sandbox.verbose) {\n sandbox.log('clearSchedule() => invalid handler', 'warn');\n }\n return false;\n },\n getSchedules: function (allScripts?: boolean): ScheduleName[] {\n const schedules = context.scheduler?.getList() || [];\n if (allScripts) {\n Object.keys(context.scripts).forEach(\n name =>\n context.scripts[name].schedules &&\n context.scripts[name].schedules.forEach(s =>\n schedules.push(JSON.parse(JSON.stringify(s._ioBroker))),\n ),\n );\n } else {\n script.schedules &&\n script.schedules.forEach(s => schedules.push(JSON.parse(JSON.stringify(s._ioBroker))));\n }\n return schedules;\n },\n setState: function (\n id: string,\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck?: boolean | 'true' | 'false' | ((err?: Error | null) => void),\n callback?: (err?: Error | null) => void,\n ): void {\n return setStateHelper(sandbox, false, false, id, state, isAck, callback);\n },\n setStateChanged: function (\n id: string,\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck?: boolean | ((err?: Error | null) => void),\n callback?: (err?: Error | null) => void,\n ): void {\n return setStateHelper(sandbox, false, true, id, state, isAck, callback);\n },\n setStateDelayed: function (\n id: string,\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck: boolean | number | undefined,\n delay?: number | boolean,\n clearRunning?: boolean | ((err?: Error | null) => void),\n callback?: (err?: Error | null) => void,\n ): number | null {\n // find arguments\n if (typeof isAck !== 'boolean') {\n callback = clearRunning as (err?: Error | null) => void;\n clearRunning = delay as boolean;\n delay = isAck as number;\n isAck = undefined;\n }\n if (typeof delay !== 'number') {\n callback = clearRunning as (err?: Error | null) => void;\n clearRunning = delay as boolean;\n delay = 0;\n }\n if (typeof clearRunning !== 'boolean') {\n callback = clearRunning;\n clearRunning = true;\n }\n\n // Check a type of state\n if (!objects[id] && objects[`${adapter.namespace}.${id}`]) {\n id = `${adapter.namespace}.${id}`;\n }\n\n sandbox.verbose &&\n sandbox.log(\n `setStateDelayed(id=${id}, state=${JSON.stringify(state)}, isAck=${isAck}, delay=${delay}, clearRunning=${clearRunning})`,\n 'info',\n );\n\n if (clearRunning) {\n if (timers[id]) {\n sandbox.verbose &&\n sandbox.log(`setStateDelayed: clear ${timers[id].length} running timers`, 'info');\n\n for (let i = 0; i < timers[id].length; i++) {\n clearTimeout(timers[id][i].t);\n }\n delete timers[id];\n } else {\n if (sandbox.verbose) {\n sandbox.log('setStateDelayed: no running timers', 'info');\n }\n }\n }\n // If no delay => starts immediately\n if (!delay) {\n sandbox.setState(id, state, isAck, callback);\n return null;\n }\n // If delay\n timers[id] = timers[id] || [];\n\n // calculate timerId\n context.timerId++;\n if (context.timerId > 0xfffffffe) {\n context.timerId = 0;\n }\n\n // Start timeout\n const timer = setTimeout(\n function (_timerId, _id, _state, _isAck) {\n sandbox.setState(_id, _state, _isAck, callback);\n // delete timer handler\n if (timers[_id]) {\n // optimisation\n if (timers[_id].length === 1) {\n delete timers[_id];\n } else {\n for (let t = 0; t < timers[_id].length; t++) {\n if (timers[_id][t].id === _timerId) {\n timers[_id].splice(t, 1);\n break;\n }\n }\n if (!timers[_id].length) {\n delete timers[_id];\n }\n }\n }\n },\n delay,\n context.timerId,\n id,\n state,\n isAck,\n );\n\n // add timer handler\n timers[id].push({\n t: timer,\n id: context.timerId,\n ts: Date.now(),\n delay: delay,\n val:\n isObject(state) && (state as ioBroker.SettableState).val !== undefined\n ? ((state as ioBroker.SettableState).val as ioBroker.StateValue)\n : (state as ioBroker.StateValue),\n ack:\n isObject(state) &&\n (state as ioBroker.SettableState).val !== undefined &&\n (state as ioBroker.SettableState).ack !== undefined\n ? (state as ioBroker.SettableState).ack\n : isAck,\n });\n\n return context.timerId;\n },\n clearStateDelayed: function (id: string, timerId: number): boolean {\n // Check a type of state\n if (!objects[id] && objects[`${adapter.namespace}.${id}`]) {\n id = `${adapter.namespace}.${id}`;\n }\n\n if (sandbox.verbose) {\n sandbox.log(`clearStateDelayed(id=${id}, timerId=${timerId})`, 'info');\n }\n\n if (timers[id]) {\n for (let i = timers[id].length - 1; i >= 0; i--) {\n if (timerId === undefined || timers[id][i].id === timerId) {\n clearTimeout(timers[id][i].t);\n if (timerId !== undefined) {\n timers[id].splice(i, 1);\n }\n if (sandbox.verbose) {\n sandbox.log(`clearStateDelayed: clear timer ${timers[id][i].id}`, 'info');\n }\n }\n }\n if (timerId === undefined) {\n delete timers[id];\n } else {\n if (!timers[id].length) {\n delete timers[id];\n }\n }\n return true;\n }\n return false;\n },\n getStateDelayed: function (\n id: string | number,\n ):\n | null\n | { timerId: number; left: number; delay: number; val: ioBroker.StateValue; ack?: boolean }\n | { timerId: number; left: number; delay: number; val: ioBroker.StateValue; ack?: boolean }[]\n | Record<\n string,\n { timerId: number; left: number; delay: number; val: ioBroker.StateValue; ack?: boolean }[]\n > {\n const now = Date.now();\n if (id) {\n // Check a type of state\n if (!objects[id] && objects[`${adapter.namespace}.${id}`]) {\n id = `${adapter.namespace}.${id}`;\n }\n // If timerId given\n if (typeof id === 'number') {\n for (const _id_ in timers) {\n if (Object.prototype.hasOwnProperty.call(timers, _id_)) {\n for (let ttt = 0; ttt < timers[_id_].length; ttt++) {\n if (timers[_id_][ttt].id === id) {\n return {\n timerId: id,\n left: timers[_id_][ttt].delay - (now - timers[id][ttt].ts),\n delay: timers[_id_][ttt].delay,\n val: timers[_id_][ttt].val,\n ack: timers[_id_][ttt].ack,\n };\n }\n }\n }\n }\n return null;\n }\n\n const result: {\n timerId: number;\n left: number;\n delay: number;\n val: ioBroker.StateValue;\n ack?: boolean;\n }[] = [];\n if (Object.prototype.hasOwnProperty.call(timers, id) && timers[id] && timers[id].length) {\n for (let tt = 0; tt < timers[id].length; tt++) {\n result.push({\n timerId: timers[id][tt].id,\n left: timers[id][tt].delay - (now - timers[id][tt].ts),\n delay: timers[id][tt].delay,\n val: timers[id][tt].val,\n ack: timers[id][tt].ack,\n });\n }\n }\n return result;\n }\n const result: Record<\n string,\n { timerId: number; left: number; delay: number; val: ioBroker.StateValue; ack?: boolean }[]\n > = {};\n for (const _id in timers) {\n if (Object.prototype.hasOwnProperty.call(timers, _id) && timers[_id] && timers[_id].length) {\n result[_id] = [];\n for (let t = 0; t < timers[_id].length; t++) {\n result[_id].push({\n timerId: timers[_id][t].id,\n left: timers[_id][t].delay - (now - timers[_id][t].ts),\n delay: timers[_id][t].delay,\n val: timers[_id][t].val,\n ack: timers[_id][t].ack,\n });\n }\n }\n }\n return result;\n },\n getStateAsync: async function (id: string): Promise {\n let state: ioBroker.State | null | undefined;\n if (id.includes('.')) {\n state = await adapter.getForeignStateAsync(id);\n } else {\n state = await adapter.getStateAsync(id);\n }\n return context.convertBackStringifiedValues(id, state);\n },\n setStateAsync: function (\n id: string,\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck?: boolean,\n ): Promise {\n return new Promise((resolve, reject) =>\n setStateHelper(sandbox, false, false, id, state, isAck, err => (err ? reject(err) : resolve())),\n );\n },\n setStateChangedAsync: function (\n id: string,\n state: ioBroker.SettableState | ioBroker.StateValue,\n isAck?: boolean,\n ): Promise {\n return new Promise((resolve, reject) =>\n setStateHelper(sandbox, false, true, id, state, isAck, err => (err ? reject(err) : resolve())),\n );\n },\n getState: function (\n id: string,\n callback?: (err: Error | null | undefined, state?: ioBroker.State | null) => void,\n ): undefined | void | (ioBroker.State & { notExist?: true }) | null {\n if (typeof id !== 'string') {\n sandbox.log(`getState has been called with id of type \"${typeof id}\" but expects a string`, 'error');\n return undefined;\n }\n\n if (typeof callback === 'function') {\n if (!id.includes('.')) {\n adapter.getState(id, (err, state) =>\n callback(err, context.convertBackStringifiedValues(id, state)),\n );\n } else {\n adapter.getForeignState(id, (err, state) =>\n callback(err, context.convertBackStringifiedValues(id, state)),\n );\n }\n } else {\n if ((adapter.config as JavaScriptAdapterConfig).subscribe) {\n sandbox.log(\n 'The \"getState\" method cannot be used synchronously, because the adapter setting \"Do not subscribe to all states on start\" is enabled.',\n 'error',\n );\n sandbox.log(\n `Please disable that setting or use \"getState\" with a callback, e.g.: getState('${id}', (err, state) => { ... });`,\n 'error',\n );\n } else {\n if (states[id]) {\n sandbox.verbose &&\n sandbox.log(\n `getState(id=${id}, timerId=${JSON.stringify(timers[id])}) => ${JSON.stringify(states[id])}`,\n 'info',\n );\n if (context.interimStateValues[id] !== undefined) {\n return context.convertBackStringifiedValues(id, context.interimStateValues[id]);\n }\n return context.convertBackStringifiedValues(id, states[id]);\n } else if (states[`${adapter.namespace}.${id}`]) {\n sandbox.verbose &&\n sandbox.log(\n `getState(id=${id}, timerId=${JSON.stringify(timers[id])}) => ${JSON.stringify(states[`${adapter.namespace}.${id}`])}`,\n 'info',\n );\n if (context.interimStateValues[`${adapter.namespace}.${id}`] !== undefined) {\n return context.convertBackStringifiedValues(\n id,\n context.interimStateValues[`${adapter.namespace}.${id}`],\n );\n }\n return context.convertBackStringifiedValues(id, states[`${adapter.namespace}.${id}`]);\n }\n\n if (sandbox.verbose) {\n sandbox.log(`getState(id=${id}, timerId=${JSON.stringify(timers[id])}) => not found`, 'info');\n }\n\n context.logWithLineInfo(\n `getState \"${id}\" not found (3)${states[id] !== undefined ? ` states[id]=${JSON.stringify(states[id])}` : ''}`,\n ); ///xxx\n return { val: null, notExist: true } as ioBroker.State & { notExist?: true };\n }\n }\n },\n existsState: function (\n id: string,\n callback?: (err: Error | null | undefined, stateExists?: boolean) => void,\n ): void | boolean {\n if (typeof id !== 'string') {\n sandbox.log(`existsState has been called with id of type \"${typeof id}\" but expects a string`, 'error');\n return false;\n }\n\n if (typeof callback === 'function') {\n adapter.getForeignObject(id, (err, obj) => {\n if (!obj || obj.type !== 'state') {\n callback(err, false);\n return;\n }\n\n if ((adapter.config as JavaScriptAdapterConfig).subscribe) {\n adapter.getForeignState(id, (err, state) => {\n callback(err, !!state);\n });\n } else {\n callback(err, !!states[id]);\n }\n });\n } else {\n if ((adapter.config as JavaScriptAdapterConfig).subscribe) {\n sandbox.log(\n 'The \"existsState\" method cannot be used synchronously, because the adapter setting \"Do not subscribe to all states on start\" is enabled.',\n 'error',\n );\n sandbox.log(\n `Please disable that setting or use \"existsState\" with a callback, e.g.: existsState('${id}', (err, stateExists) => { ... });`,\n 'error',\n );\n } else {\n return !!states[id];\n }\n }\n },\n existsObject: function (\n id: string,\n callback?: (err: Error | null | undefined, objectExists?: boolean) => void,\n ): void | boolean {\n if (typeof id !== 'string') {\n sandbox.log(\n `existsObject has been called with id of type \"${typeof id}\" but expects a string`,\n 'error',\n );\n return false;\n }\n\n if (typeof callback === 'function') {\n adapter.getForeignObject(id, (err, obj) => callback(err, !!obj));\n } else {\n return !!objects[id];\n }\n },\n getIdByName: function (name: string, alwaysArray?: boolean): string | string[] | null {\n sandbox.verbose &&\n sandbox.log(\n `getIdByName(name=${name}, alwaysArray=${alwaysArray}) => ${JSON.stringify(context.names[name])}`,\n 'info',\n );\n if (Object.prototype.hasOwnProperty.call(context.names, name)) {\n if (alwaysArray) {\n return !Array.isArray(context.names[name]) ? [context.names[name]] : context.names[name];\n }\n return context.names[name];\n }\n if (alwaysArray) {\n return [];\n }\n return null;\n },\n getObject: function (\n id: string,\n enumName: null | string | ((err: Error | null | undefined, obj?: ioBroker.Object | null) => void),\n cb?: (err: Error | null | undefined, obj?: ioBroker.Object | null) => void,\n ): void | ioBroker.Object | null {\n if (typeof id !== 'string') {\n sandbox.log(`getObject has been called with id of type \"${typeof id}\" but expects a string`, 'error');\n return null;\n }\n\n if (typeof enumName === 'function') {\n cb = enumName;\n enumName = null;\n }\n // with callback\n if (typeof cb === 'function') {\n adapter.getForeignObject(id, (err, obj) => {\n if (obj) {\n objects[id] = obj;\n } else if (objects[id]) {\n delete objects[id];\n }\n let result: ioBroker.Object | null | undefined;\n try {\n result = JSON.parse(JSON.stringify(objects[id]));\n } catch (err: unknown) {\n adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, {\n val: true,\n ack: true,\n c: 'getObject',\n });\n sandbox.log(`Object \"${id}\" can't be copied: ${JSON.stringify(err)}`, 'error');\n return cb(null, null);\n }\n sandbox.verbose &&\n sandbox.log(`getObject(id=${id}, enumName=${enumName}) => ${JSON.stringify(result)}`, 'info');\n cb(err, result);\n });\n } else {\n if (!objects[id]) {\n sandbox.verbose &&\n sandbox.log(`getObject(id=${id}, enumName=${enumName}) => does not exist`, 'info');\n sandbox.log(`Object \"${id}\" does not exist`, 'warn');\n return null;\n }\n if (enumName) {\n const e = eventObj.getObjectEnumsSync(context, id);\n const obj = JSON.parse(JSON.stringify(objects[id]));\n obj.enumIds = JSON.parse(JSON.stringify(e.enumIds));\n obj.enumNames = JSON.parse(JSON.stringify(e.enumNames));\n if (typeof enumName === 'string') {\n const r = new RegExp(`^enum\\\\.${enumName}\\\\.`);\n for (let i = obj.enumIds.length - 1; i >= 0; i--) {\n if (!r.test(obj.enumIds[i])) {\n obj.enumIds.splice(i, 1);\n obj.enumNames.splice(i, 1);\n }\n }\n }\n sandbox.verbose &&\n sandbox.log(`getObject(id=${id}, enumName=${enumName}) => ${JSON.stringify(obj)}`, 'info');\n\n return obj;\n }\n let result: ioBroker.Object | null | undefined;\n try {\n result = JSON.parse(JSON.stringify(objects[id]));\n } catch (err: unknown) {\n adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, {\n val: true,\n ack: true,\n c: 'getObject',\n });\n sandbox.log(`Object \"${id}\" can't be copied: ${JSON.stringify(err)}`, 'error');\n return null;\n }\n sandbox.verbose &&\n sandbox.log(`getObject(id=${id}, enumName=${enumName}) => ${JSON.stringify(result)}`, 'info');\n return result;\n }\n },\n // This function will be overloaded later if the modification of objects is allowed\n setObject: function (\n _id: string,\n _obj: ioBroker.Object,\n callback?: (err?: Error | null, res?: { id: string }) => void,\n ): void {\n sandbox.log('Function \"setObject\" is not allowed. Use adapter settings to allow it.', 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(\n sandbox,\n new Error('Function \"setObject\" is not allowed. Use adapter settings to allow it.'),\n );\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n },\n // This function will be overloaded later if the modification of objects is allowed\n extendObject: function (\n _id: string,\n _obj: Partial,\n callback?: (err?: Error | null, res?: { id: string }) => void,\n ): void {\n sandbox.log('Function \"extendObject\" is not allowed. Use adapter settings to allow it.', 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(\n sandbox,\n new Error('Function \"extendObject\" is not allowed. Use adapter settings to allow it.'),\n );\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n },\n // This function will be overloaded later if the modification of objects is allowed\n deleteObject: function (\n _id: string,\n _isRecursive?: boolean | ioBroker.ErrorCallback,\n callback?: ioBroker.ErrorCallback,\n ): void {\n if (typeof _isRecursive === 'function') {\n callback = _isRecursive;\n }\n sandbox.log('Function \"deleteObject\" is not allowed. Use adapter settings to allow it.', 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(\n sandbox,\n new Error('Function \"deleteObject\" is not allowed. Use adapter settings to allow it.'),\n );\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n },\n getEnums: function (enumName?: string): { id: string; members: string[]; name: ioBroker.StringOrTranslated }[] {\n const result: { id: string; members: string[]; name: ioBroker.StringOrTranslated }[] = [];\n const r = enumName ? new RegExp(`^enum\\\\.${enumName}\\\\.`) : false;\n for (let i = 0; i < enums.length; i++) {\n if (!r || r.test(enums[i])) {\n const common: ioBroker.EnumCommon =\n (objects[enums[i]] as ioBroker.EnumObject).common || ({} as ioBroker.EnumCommon);\n result.push({\n id: enums[i],\n members: common.members || [],\n name: common.name || '',\n });\n }\n }\n if (sandbox.verbose) {\n sandbox.log(`getEnums(enumName=${enumName}) => ${JSON.stringify(result)}`, 'info');\n }\n return JSON.parse(JSON.stringify(result));\n },\n createAlias: function (\n name: string,\n alias: string | CommonAlias,\n forceCreation: boolean | Partial | ((err: Error | null) => void) | undefined,\n common?: Partial | Record | ((err: Error | null) => void),\n native?: Record | ((err: Error | null) => void),\n callback?: (err: Error | null) => void,\n ) {\n if (typeof native === 'function') {\n callback = native as (err: Error | null) => void;\n native = {};\n }\n if (typeof common === 'function') {\n callback = common as (err: Error | null) => void;\n common = undefined;\n }\n if (typeof forceCreation === 'function') {\n callback = forceCreation as (err: Error | null) => void;\n forceCreation = undefined;\n }\n if (isObject(forceCreation)) {\n native = common;\n common = forceCreation as Partial;\n forceCreation = undefined;\n }\n\n if (typeof name !== 'string') {\n const err = `Wrong type of name \"${typeof name}\". Expected \"string\".`;\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n\n if (!name) {\n const err = 'Empty ID is not allowed.';\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n\n if (!name.startsWith('alias.0.')) {\n name = `alias.0.${name}`;\n }\n\n const _common: Partial = (common as Partial) || {};\n if (isObject(_common.alias)) {\n // alias already in common, use this\n } else if (\n isObject(alias) &&\n (typeof (alias as CommonAlias).id === 'string' || isObject((alias as CommonAlias).id))\n ) {\n _common.alias = alias as CommonAlias;\n } else if (typeof alias === 'string') {\n _common.alias = { id: alias };\n } else {\n const err = 'Source ID needs to be provided as string or object with id property.';\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n\n let aliasSourceId = '';\n if (_common.alias) {\n aliasSourceId = isObject(_common.alias.id)\n ? (_common.alias.id as { read: string; write: string }).read\n : (_common.alias.id as string);\n if (!objects[aliasSourceId] && objects[`${adapter.namespace}.${aliasSourceId}`]) {\n aliasSourceId = `${adapter.namespace}.${aliasSourceId}`;\n if (isObject(_common.alias.id)) {\n (_common.alias.id as { read: string; write: string }).read = aliasSourceId;\n } else {\n _common.alias.id = aliasSourceId;\n }\n }\n if (\n isObject(_common.alias.id) &&\n (_common.alias.id as { read: string; write: string }).write &&\n !objects[(_common.alias.id as { read: string; write: string }).write] &&\n objects[`${adapter.namespace}.${(_common.alias.id as { read: string; write: string }).write}`]\n ) {\n (_common.alias.id as { read: string; write: string }).write =\n `${adapter.namespace}.${(_common.alias.id as { read: string; write: string }).write}`;\n }\n }\n const obj = objects[aliasSourceId];\n if (!obj) {\n const err = `Alias source object \"${aliasSourceId}\" does not exist.`;\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n if (obj.type !== 'state') {\n const err = `Alias source object \"${aliasSourceId}\" must be a state object.`;\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n if (_common.name === undefined) {\n _common.name = obj.common.name || name;\n }\n if (_common.type === undefined && obj.common.type !== undefined) {\n _common.type = obj.common.type;\n }\n if (_common.role === undefined && obj.common.role !== undefined) {\n _common.role = obj.common.role;\n }\n if (_common.min === undefined && obj.common.min !== undefined) {\n _common.min = obj.common.min;\n }\n if (_common.max === undefined && obj.common.max !== undefined) {\n _common.max = obj.common.max;\n }\n if (_common.step === undefined && obj.common.step !== undefined) {\n _common.step = obj.common.step;\n }\n if (_common.unit === undefined && obj.common.unit !== undefined) {\n _common.unit = obj.common.unit;\n }\n if (_common.desc === undefined && obj.common.desc !== undefined) {\n _common.desc = obj.common.desc;\n }\n\n return sandbox.createState(\n name,\n undefined,\n forceCreation as boolean,\n _common,\n native,\n callback as (err?: Error | null) => void,\n );\n },\n createState: async function (\n name: string,\n initValue: undefined | ioBroker.StateValue | ioBroker.State,\n forceCreation:\n | boolean\n | undefined\n | Record\n | Partial\n | ((err: Error | null) => void),\n common?: Partial | ((err: Error | null) => void),\n native?: Record | ((err: Error | null) => void),\n callback?: (error: Error | null | undefined, id?: string) => void,\n ) {\n if (typeof native === 'function') {\n callback = native as (err?: Error | null) => void;\n native = {};\n }\n if (typeof common === 'function') {\n callback = common as (err?: Error | null) => void;\n common = undefined;\n }\n if (typeof initValue === 'function') {\n callback = initValue as (err?: Error | null) => void;\n initValue = undefined;\n }\n if (typeof forceCreation === 'function') {\n callback = forceCreation as (err?: Error | null) => void;\n forceCreation = undefined;\n }\n if (isObject(initValue)) {\n common = initValue as Partial;\n native = forceCreation as Record;\n forceCreation = undefined;\n initValue = undefined;\n }\n if (isObject(forceCreation)) {\n native = common as Record;\n common = forceCreation as Partial;\n forceCreation = undefined;\n }\n\n if (typeof name !== 'string') {\n const err = `Wrong type of name \"${typeof name}\". Expected \"string\".`;\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n\n if (!name) {\n const err = 'Empty ID is not allowed.';\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n\n const isAlias = name.startsWith('alias.0.');\n\n const _common: ioBroker.StateCommon = (common || {}) as ioBroker.StateCommon;\n _common.name = _common.name || name;\n _common.role = _common.role || 'state';\n _common.type = _common.type || 'mixed';\n if (!isAlias && initValue === undefined) {\n initValue = _common.def;\n }\n\n native = native || {};\n\n // Check min, max and def values for number\n if (_common.type !== undefined && _common.type === 'number') {\n let min = 0;\n let max = 0;\n let def = 0;\n let err: string | undefined;\n if (_common.min !== undefined) {\n min = _common.min;\n if (typeof min !== 'number') {\n min = parseFloat(min);\n if (isNaN(min)) {\n err = `Wrong type of ${name}.common.min`;\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n _common.min = min;\n }\n }\n if (_common.max !== undefined) {\n max = _common.max;\n if (typeof max !== 'number') {\n max = parseFloat(max);\n if (isNaN(max)) {\n err = `Wrong type of ${name}.common.max`;\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n _common.max = max;\n }\n }\n\n if (_common.def !== undefined) {\n if (isAlias) {\n delete _common.def;\n } else {\n def = _common.def;\n if (typeof def !== 'number') {\n def = parseFloat(def);\n if (isNaN(def)) {\n err = `Wrong type of ${name}.common.def`;\n sandbox.log(err, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n _common.def = def;\n }\n }\n }\n\n if (_common.min !== undefined && _common.max !== undefined && min > max) {\n _common.max = min;\n _common.min = max;\n }\n if (_common.def !== undefined && _common.min !== undefined && def < min) {\n _common.def = min;\n }\n if (_common.def !== undefined && _common.max !== undefined && def > max) {\n _common.def = max;\n }\n }\n\n if (sandbox.verbose) {\n sandbox.log(\n `createState(name=${name}, initValue=${JSON.stringify(initValue)}, forceCreation=${JSON.stringify(forceCreation)}, common=${JSON.stringify(common)}, native=${JSON.stringify(native)}, isAlias=${isAlias})`,\n 'debug',\n );\n }\n\n let id = `${adapter.namespace}.${name}`;\n if (name.match(/^javascript\\.\\d+\\./) || name.startsWith('0_userdata.0.') || isAlias) {\n id = name;\n }\n if (id.match(/^javascript\\.\\d+\\.scriptEnabled/)) {\n sandbox.log(\n `Own states (${id}) should not be created in javascript.X.scriptEnabled.*! Please move the states to 0_userdata.0.*`,\n 'info',\n );\n } else if (id.match(/^javascript\\.\\d+\\.scriptProblem/)) {\n sandbox.log(\n `Own states (${id}) should not be created in javascript.X.scriptProblem.*! Please move the states to 0_userdata.0.*`,\n 'info',\n );\n }\n\n // User can create aliases by two ways:\n // - id is starting with \"alias.0.\" and common.alias.id is set, so the state defined in common.alias.id will be created automatically if not exists\n // - id is not starting with \"alias.0.\", but common.alias is set, so the state defined in common.alias will be created automatically if not exists\n if (!isAlias && _common.alias) {\n // check and create if not exists the alias\n let alias: CommonAlias;\n if (typeof _common.alias === 'string') {\n alias = {\n id: _common.alias,\n };\n } else if (typeof _common.alias === 'boolean') {\n const parts = id.split('.');\n parts[0] = 'alias';\n parts[1] = '0';\n\n alias = {\n id: parts.join('.'),\n };\n } else {\n alias = _common.alias;\n }\n delete _common.alias;\n\n if (!(alias.id as string).startsWith('alias.0.')) {\n alias.id = `alias.0.${alias.id as string}`;\n }\n\n let aObj: ioBroker.StateObject | null | undefined;\n try {\n aObj = (await adapter.getForeignObjectAsync(alias.id as string)) as\n | ioBroker.StateObject\n | null\n | undefined;\n } catch {\n // ignore\n }\n if (!aObj) {\n try {\n const _obj: ioBroker.StateObject = {\n _id: alias.id as string,\n type: 'state',\n common: {\n name: `Alias to ${id}`,\n role: 'state',\n type: _common.type,\n read: _common.read,\n write: _common.write,\n unit: _common.unit,\n alias: {\n id,\n read: alias.read,\n write: alias.write,\n },\n },\n native: {},\n };\n\n await adapter.setForeignObjectAsync(alias.id as string, _obj);\n } catch (err: unknown) {\n sandbox.log(`Cannot create alias \"${alias.id as string}\": ${err as Error}`, 'error');\n }\n }\n } else if (isAlias && _common.alias) {\n if (typeof _common.alias === 'string') {\n _common.alias = {\n id: _common.alias,\n };\n }\n const readId = typeof _common.alias.id === 'string' ? _common.alias.id : _common.alias.id.read;\n let writeId: string | undefined =\n typeof _common.alias.id === 'string' ? _common.alias.id : _common.alias.id.write;\n if (writeId === readId) {\n writeId = undefined;\n }\n // try to create the linked states\n let aObj: ioBroker.StateObject | null | undefined;\n try {\n aObj = (await adapter.getForeignObjectAsync(readId)) as ioBroker.StateObject | null | undefined;\n } catch {\n // ignore\n }\n if (!aObj) {\n try {\n await adapter.setForeignObjectAsync(readId, {\n type: 'state',\n common: {\n name: `State for ${id}`,\n role: 'state',\n type: _common.type,\n read: _common.read,\n write: _common.write,\n unit: _common.unit,\n },\n native: {},\n });\n } catch (err: unknown) {\n sandbox.log(`Cannot create alias \"${readId}\": ${err as Error}`, 'error');\n }\n }\n if (writeId && _common.write !== false) {\n try {\n aObj = (await adapter.getForeignObjectAsync(writeId)) as\n | ioBroker.StateObject\n | null\n | undefined;\n } catch {\n // ignore\n }\n if (!aObj) {\n try {\n await adapter.setForeignObjectAsync(writeId, {\n type: 'state',\n common: {\n name: `Write state for ${id}`,\n role: 'state',\n type: _common.type,\n read: _common.read,\n write: _common.write,\n unit: _common.unit,\n },\n native: {},\n });\n } catch (err: unknown) {\n sandbox.log(`Cannot create alias \"${writeId}\": ${err as Error}`, 'error');\n }\n }\n }\n }\n\n let obj: ioBroker.Object | null | undefined;\n try {\n obj = await adapter.getForeignObjectAsync(id);\n } catch {\n // ignore\n }\n\n if (\n obj?._id &&\n validIdForAutomaticFolderCreation(obj._id) &&\n obj.type === 'folder' &&\n obj.native &&\n obj.native.autocreated === 'by automatic ensure logic'\n ) {\n // ignore a default created object because we now have a better defined one\n obj = null;\n }\n\n if (!obj || forceCreation) {\n // create new one\n const newObj: ioBroker.StateObject = {\n _id: id,\n common: _common,\n native,\n type: 'state',\n };\n try {\n await adapter.setForeignObjectAsync(id, newObj);\n } catch (err: unknown) {\n sandbox.log(`Cannot set object \"${id}\": ${err as Error}`, 'warn');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, err as Error);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n return;\n }\n\n // Update meta objects\n context.updateObjectContext(id, newObj);\n\n if (!isAlias && initValue !== undefined) {\n if (isObject(initValue) && (initValue as ioBroker.State).ack !== undefined) {\n setStateHelper(sandbox, true, false, id, initValue, callback);\n } else {\n setStateHelper(sandbox, true, false, id, initValue, true, callback);\n }\n } else if (!isAlias && !forceCreation) {\n setStateHelper(sandbox, true, false, id, null, callback);\n } else if (isAlias) {\n try {\n const state = await adapter.getForeignStateAsync(id);\n if (state) {\n states[id] = state;\n }\n } catch {\n // ignore\n }\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, null, id);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n } else if (typeof callback === 'function') {\n try {\n callback.call(sandbox, null, id);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n await ensureObjectStructure(id);\n } else {\n // state yet exists\n if (\n !(adapter.config as JavaScriptAdapterConfig).subscribe &&\n !states[id] &&\n states[`${adapter.namespace}.${id}`] === undefined\n ) {\n states[id] = {\n val: null,\n ack: true,\n lc: Date.now(),\n ts: Date.now(),\n q: 0,\n from: `system.adapter.${adapter.namespace}`,\n };\n }\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, null, id);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n\n await ensureObjectStructure(id);\n }\n },\n deleteState: function (id: string, callback?: (err: Error | null | undefined, found?: boolean) => void): void {\n // todo: check rights\n // todo: also remove from \"names\"\n\n if (sandbox.verbose) {\n sandbox.log(`deleteState(id=${id})`, 'debug');\n }\n\n let found = false;\n if ((id.startsWith('0_userdata.0.') || id.startsWith(adapter.namespace)) && objects[id]) {\n found = true;\n delete objects[id];\n if (states[id]) {\n delete states[id];\n }\n\n adapter.delForeignObject(id, function (err) {\n err && sandbox.log(`Object for state \"${id}\" does not exist: ${err}`, 'warn');\n\n adapter.delForeignState(id, function (err) {\n err && sandbox.log(`Cannot delete state \"${id}\": ${err}`, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, err, found);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n });\n });\n } else if (objects[`${adapter.namespace}.${id}`]) {\n delete objects[`${adapter.namespace}.${id}`];\n found = true;\n if (states[`${adapter.namespace}.${id}`]) {\n delete states[`${adapter.namespace}.${id}`];\n }\n\n adapter.delObject(id, function (err) {\n err && sandbox.log(`Object for state \"${id}\" does not exist: ${err}`, 'warn');\n\n adapter.delState(id, function (err) {\n err && sandbox.log(`Cannot delete state \"${id}\": ${err}`, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, err, found);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n });\n });\n } else {\n const err = 'Not found';\n sandbox.log(`Cannot delete state \"${id}\": ${err}`, 'error');\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, new Error(err), found);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n }\n },\n sendTo: function (\n _adapter: string,\n cmd: string,\n msg?: any,\n options?: Record | ((result: any, options: Record, _adapter: string) => void),\n callback?: (result: any, options: Record, _adapter: string) => void,\n ): void {\n const defaultTimeout = 20000;\n\n if (typeof options === 'function') {\n callback = options as (result: any, options: Record, _adapter: string) => void;\n options = { timeout: defaultTimeout };\n }\n\n let timeout: NodeJS.Timeout | null = null;\n if (typeof callback === 'function') {\n const timeoutDuration = parseInt(options?.timeout, 10) || defaultTimeout;\n\n timeout = setTimeout(() => {\n timeout = null;\n\n if (sandbox.verbose) {\n sandbox.log(`sendTo => timeout: ${timeoutDuration}`, 'debug');\n }\n\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, { error: 'timeout' }, options as Record, _adapter);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n callback = undefined;\n }\n }, timeoutDuration);\n }\n\n let cbFunc: undefined | ((result: any) => void);\n if (timeout) {\n cbFunc = function (result: any): void {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n }\n\n if (sandbox.verbose && result) {\n sandbox.log(`sendTo => ${JSON.stringify(result)}`, 'debug');\n }\n\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, result, options as Record, _adapter);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n callback = undefined;\n }\n };\n }\n\n // If specific instance\n if (_adapter.match(/\\.[0-9]+$/)) {\n sandbox.verbose &&\n sandbox.log(\n `sendTo(instance=${_adapter}, cmd=${cmd}, msg=${JSON.stringify(msg)}, hasCallback=${typeof callback === 'function'})`,\n 'info',\n );\n\n adapter.sendTo(_adapter, cmd, msg, cbFunc, options);\n } else {\n // Send it to all instances\n context.adapter.getObjectView(\n 'system',\n 'instance',\n { startkey: `system.adapter.${_adapter}.`, endkey: `system.adapter.${_adapter}.\\u9999` },\n options,\n (err, res) => {\n if (err || !res) {\n sandbox.log(`sendTo failed: ${err?.message}`, 'error');\n return;\n }\n\n const instances = res.rows.map(item => item.id.substring('system.adapter.'.length));\n\n instances.forEach(instance => {\n sandbox.verbose &&\n sandbox.log(\n `sendTo(instance=${instance}, cmd=${cmd}, msg=${JSON.stringify(msg)}, hasCallback=${typeof callback === 'function'})`,\n 'info',\n );\n adapter.sendTo(instance, cmd, msg, cbFunc, options);\n });\n },\n );\n }\n },\n sendto: function (\n _adapter: string,\n cmd: string,\n msg: any,\n callback?: (result: any, options: Record, _adapter: string) => void,\n ): void {\n return sandbox.sendTo(_adapter, cmd, msg, callback);\n },\n sendToAsync: function (_adapter: string, cmd: string, msg?: any, options?: Record): Promise {\n return new Promise((resolve, reject) => {\n sandbox.sendTo(_adapter, cmd, msg, options, res => {\n if (!res || res.error) {\n reject(res ? new Error(res.error) : new Error('Unknown error'));\n } else {\n resolve(res);\n }\n });\n });\n },\n sendToHost: function (host: string, cmd: string, msg?: any, callback?: (result: any) => void): void {\n if (!(adapter.config as JavaScriptAdapterConfig).enableSendToHost) {\n const error =\n 'sendToHost is not available. Please enable \"Enable SendToHost\" option in instance settings';\n sandbox.log(error, 'error');\n\n if (typeof callback === 'function') {\n // leave it as a normal function and not as a lambda, to hide the \"this\" object\n setImmediate(function () {\n callback(error);\n });\n }\n } else {\n sandbox.verbose &&\n sandbox.log(`sendToHost(adapter=${host}, cmd=${cmd}, msg=${JSON.stringify(msg)})`, 'info');\n adapter.sendToHost(host, cmd, msg, callback);\n }\n },\n sendToHostAsync: function (host: string, cmd: string, msg?: any): Promise {\n return new Promise((resolve, reject) => {\n sandbox.sendToHost(host, cmd, msg, res => {\n if (!res || res.error) {\n reject(res ? new Error(res.error) : new Error('Unknown error'));\n } else {\n resolve(res);\n }\n });\n });\n },\n registerNotification: function (msg: string, isAlert?: boolean): void {\n const category = !isAlert ? 'scriptMessage' : 'scriptAlert';\n\n if (sandbox.verbose) {\n sandbox.log(`registerNotification(msg=${msg}, category=${category})`, 'info');\n }\n\n adapter.registerNotification('javascript', category, msg);\n },\n setInterval: function (callback: (...args: any[]) => void, ms: number, ...args: any[]): NodeJS.Timeout | null {\n if (typeof callback === 'function') {\n const int: NodeJS.Timeout = setInterval(() => {\n try {\n callback.call(sandbox, ...args);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }, ms);\n script.intervals.push(int);\n\n if (sandbox.verbose) {\n sandbox.log(`setInterval(ms=${ms})`, 'info');\n }\n return int;\n }\n sandbox.log(`Invalid callback for setInterval! - ${typeof callback}`, 'error');\n return null;\n },\n clearInterval: function (id: NodeJS.Timeout): void {\n const pos = script.intervals.indexOf(id);\n if (pos !== -1) {\n if (sandbox.verbose) {\n sandbox.log('clearInterval() => cleared', 'info');\n }\n clearInterval(id);\n script.intervals.splice(pos, 1);\n } else {\n if (sandbox.verbose) {\n sandbox.log('clearInterval() => not found', 'warn');\n }\n }\n },\n setTimeout: function (callback: (args?: any[]) => void, ms: number, ...args: any[]): NodeJS.Timeout | null {\n if (typeof callback === 'function') {\n const to = setTimeout(() => {\n // Remove timeout from the list\n const pos = script.timeouts.indexOf(to);\n if (pos !== -1) {\n script.timeouts.splice(pos, 1);\n }\n\n try {\n callback.call(sandbox, ...args);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }, ms);\n if (sandbox.verbose) {\n sandbox.log(`setTimeout(ms=${ms})`, 'info');\n }\n\n script.timeouts.push(to);\n return to;\n }\n sandbox.log(`Invalid callback for setTimeout! - ${typeof callback}`, 'error');\n return null;\n },\n clearTimeout: function (id: NodeJS.Timeout): void {\n const pos = script.timeouts.indexOf(id);\n if (pos !== -1) {\n if (sandbox.verbose) {\n sandbox.log('clearTimeout() => cleared', 'info');\n }\n clearTimeout(id);\n script.timeouts.splice(pos, 1);\n } else {\n if (sandbox.verbose) {\n sandbox.log('clearTimeout() => not found', 'warn');\n }\n }\n },\n setImmediate: function (callback: (..._args: any[]) => void, ...args: any[]): void {\n if (typeof callback === 'function') {\n setImmediate(() => {\n try {\n callback.apply(sandbox, args);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n });\n if (sandbox.verbose) {\n sandbox.log('setImmediate()', 'info');\n }\n } else {\n sandbox.log(`Invalid callback for setImmediate! - ${typeof callback}`, 'error');\n }\n },\n cb: function (callback: (..._args: any[]) => void): (...args: any[]) => void {\n return function (args: any[]) {\n if (context.scripts[name]?._id === sandbox._id) {\n if (typeof callback === 'function') {\n try {\n callback.apply(sandbox, args);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n } else {\n sandbox.log(`Callback for old version of script: ${name}`, 'warn');\n }\n };\n },\n compareTime: function (\n startTime: iobJS.AstroDate | string | Date | number,\n endTime: iobJS.AstroDate | string | Date | number | null,\n operation: 'between' | 'not between' | '<' | '<=' | '>' | '>=' | '==' | '<>' | '!=',\n time?: iobJS.AstroDate | string | Date | number,\n ): boolean {\n if (startTime && typeof startTime === 'string') {\n const pos = consts.astroListLow.indexOf(startTime.toLowerCase());\n if (pos !== -1) {\n const aTime = sandbox.getAstroDate(consts.astroList[pos]);\n if (aTime) {\n startTime = aTime.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n } else {\n startTime = 0;\n }\n }\n } else if (startTime && isObject(startTime) && (startTime as iobJS.AstroDate).astro) {\n const aTime = sandbox.getAstroDate(\n (startTime as iobJS.AstroDate).astro,\n (startTime as iobJS.AstroDate).date || new Date(),\n (startTime as iobJS.AstroDate).offset || 0,\n );\n if (aTime) {\n startTime = aTime.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n });\n } else {\n startTime = 0;\n }\n }\n\n if (endTime && typeof endTime === 'string') {\n const pos = consts.astroListLow.indexOf(endTime.toLowerCase());\n if (pos !== -1) {\n const aTime = sandbox.getAstroDate(consts.astroList[pos]);\n endTime =\n aTime?.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n }) || 0;\n }\n } else if (endTime && isObject(endTime) && (endTime as iobJS.AstroDate).astro) {\n const aTime = sandbox.getAstroDate(\n (endTime as iobJS.AstroDate).astro,\n (endTime as iobJS.AstroDate).date || new Date(),\n (endTime as iobJS.AstroDate).offset || 0,\n );\n endTime =\n aTime?.toLocaleTimeString([], {\n hour: '2-digit',\n minute: '2-digit',\n hour12: false,\n }) || 0;\n }\n\n // --- Convert \"time\" to number\n let nTime: number | undefined;\n // maybe it is astro date like 'sunrise' or 'sunset'\n if (time && typeof time === 'string') {\n const pos = consts.astroListLow.indexOf(time.toLowerCase());\n if (pos !== -1) {\n nTime = sandbox.getAstroDate(consts.astroList[pos])?.getTime() || 0;\n }\n } else if (time && isObject(time) && (time as iobJS.AstroDate).astro) {\n nTime =\n sandbox\n .getAstroDate(\n (time as iobJS.AstroDate).astro,\n (time as iobJS.AstroDate).date || new Date(),\n (time as iobJS.AstroDate).offset || 0,\n )\n ?.getTime() || 0;\n }\n\n let daily = true;\n if (time) {\n daily = false;\n }\n // if not astro date\n if (!nTime) {\n if (time && !isObject(time)) {\n if (typeof time === 'string' && !time.includes(' ') && !time.includes('T')) {\n const parts = time.split(':');\n const oTime = new Date();\n oTime.setHours(parseInt(parts[0], 10));\n oTime.setMinutes(parseInt(parts[1], 10));\n oTime.setMilliseconds(0);\n\n if (parts.length === 3) {\n oTime.setSeconds(parseInt(parts[2], 10));\n } else {\n oTime.setSeconds(0);\n }\n nTime = oTime.getTime();\n } else {\n nTime = new Date(time as string | number).getTime();\n }\n } else if (!time) {\n const oTime = new Date();\n oTime.setMilliseconds(0);\n nTime = oTime.getTime();\n } else {\n // If Date\n nTime = (time as Date).getTime();\n }\n }\n // --- End of conversion \"time\" to number\n if (typeof startTime === 'string') {\n if (!startTime.includes(' ') && !startTime.includes('T')) {\n const parts = startTime.split(':');\n startTime = new Date();\n startTime.setHours(parseInt(parts[0], 10));\n startTime.setMinutes(parseInt(parts[1], 10));\n startTime.setMilliseconds(0);\n\n if (parts.length === 3) {\n startTime.setSeconds(parseInt(parts[2], 10));\n } else {\n startTime.setSeconds(0);\n }\n } else {\n daily = false;\n startTime = new Date(startTime);\n }\n } else {\n daily = false;\n startTime = new Date(startTime as number | Date);\n }\n const nStartTime = startTime.getTime();\n\n let nEndTime: number | null;\n if (endTime && typeof endTime === 'string') {\n if (!endTime.includes(' ') && !endTime.includes('T')) {\n const parts = endTime.split(':');\n endTime = new Date();\n endTime.setHours(parseInt(parts[0], 10));\n endTime.setMinutes(parseInt(parts[1], 10));\n endTime.setMilliseconds(0);\n\n if (parts.length === 3) {\n endTime.setSeconds(parseInt(parts[2], 10));\n } else {\n endTime.setSeconds(0);\n }\n } else {\n daily = false;\n endTime = new Date(endTime);\n }\n } else if (endTime) {\n daily = false;\n endTime = new Date(endTime as number | Date);\n } else {\n endTime = null;\n }\n\n if (endTime) {\n nEndTime = endTime.getTime();\n } else {\n nEndTime = null;\n }\n\n if (operation === 'between') {\n if (nEndTime) {\n if (nStartTime > nEndTime && daily) {\n return !(nTime >= nEndTime && nTime < nStartTime);\n }\n return nTime >= nStartTime && nTime < nEndTime;\n }\n sandbox.log(`missing or unrecognized endTime expression: ${JSON.stringify(endTime)}`, 'warn');\n return false;\n }\n\n if (operation === 'not between') {\n if (nEndTime) {\n if (nStartTime > nEndTime && daily) {\n return nTime >= nEndTime && nTime < nStartTime;\n }\n return !(nTime >= nStartTime && nTime < nEndTime);\n }\n sandbox.log(`missing or unrecognized endTime expression: ${JSON.stringify(endTime)}`, 'warn');\n return false;\n }\n\n if (operation === '>') {\n return nTime > nStartTime;\n }\n if (operation === '>=') {\n return nTime >= nStartTime;\n }\n if (operation === '<') {\n return nTime < nStartTime;\n }\n if (operation === '<=') {\n return nTime <= nStartTime;\n }\n if (operation === '==') {\n return nTime === nStartTime;\n }\n if (operation === '<>' || operation === '!=') {\n return nTime !== nStartTime;\n }\n sandbox.log(`Invalid operator: ${operation as string}`, 'warn');\n return false;\n },\n onStop: function (cb: () => void, timeout?: number): void {\n if (sandbox.verbose) {\n sandbox.log(`onStop(timeout=${timeout})`, 'info');\n }\n\n script.onStopCb = cb;\n script.onStopTimeout = timeout || 1000;\n },\n formatValue: function (value: number | string, decimals: number | string, format?: string): string {\n if (typeof decimals === 'string') {\n format = decimals;\n decimals = 0;\n }\n if (!format) {\n if (adapter.isFloatComma !== undefined) {\n format = adapter.isFloatComma ? '.,' : ',.';\n } else if (objects['system.config'] && objects['system.config'].common) {\n format = objects['system.config'].common.isFloatComma ? '.,' : ',.';\n }\n }\n return adapter.formatValue(value, decimals, format);\n },\n formatDate: function (\n date: Date | string | number | iobJS.AstroDate,\n format?: string,\n language?: ioBroker.Languages,\n ): string {\n if (!format) {\n if (adapter.dateFormat) {\n format = adapter.dateFormat;\n } else {\n format =\n objects['system.config'] && objects['system.config'].common\n ? objects['system.config'].common.dateFormat || 'DD.MM.YYYY'\n : 'DD.MM.YYYY';\n }\n format = format || 'DD.MM.YYYY';\n }\n // maybe it is astro date like 'sunrise' or 'sunset'\n if (date && typeof date === 'string') {\n const pos = consts.astroListLow.indexOf(date.toLowerCase());\n if (pos !== -1) {\n date = sandbox.getAstroDate(consts.astroList[pos])?.getTime() || 0;\n }\n } else if (date && isObject(date) && (date as iobJS.AstroDate).astro) {\n date =\n sandbox\n .getAstroDate(\n (date as iobJS.AstroDate).astro,\n (date as iobJS.AstroDate).date || new Date(),\n (date as iobJS.AstroDate).offset || 0,\n )\n ?.getTime() || 0;\n }\n\n if (format.match(/[WНOО]+/)) {\n let text: string = adapter.formatDate(date as Date | string | number, format);\n if (!language || !consts.dayOfWeeksFull[language]) {\n language =\n adapter.language ||\n (objects['system.config'] &&\n objects['system.config'].common &&\n objects['system.config'].common.language) ||\n 'en';\n if (!consts.dayOfWeeksFull[language as ioBroker.Languages]) {\n language = 'en';\n }\n }\n if (typeof date === 'number' || typeof date === 'string') {\n date = new Date(date);\n } else if (typeof (date as Date).getMonth !== 'function') {\n sandbox.log(`Invalid date object provided: ${JSON.stringify(date)}`, 'error');\n return 'Invalid date';\n }\n const d: number = (date as Date).getDay();\n text = text.replace('НН', consts.dayOfWeeksFull[language as ioBroker.Languages][d]);\n let initialText = text;\n text = text.replace('WW', consts.dayOfWeeksFull[language as ioBroker.Languages][d]);\n\n if (initialText === text) {\n text = text.replace('W', consts.dayOfWeeksShort[language as ioBroker.Languages][d]);\n }\n\n text = text.replace('Н', consts.dayOfWeeksShort[language as ioBroker.Languages][d]);\n text = text.replace('Н', consts.dayOfWeeksShort[language as ioBroker.Languages][d]);\n const m: number = (date as Date).getMonth();\n initialText = text;\n text = text.replace('OOO', consts.monthFullGen[language as ioBroker.Languages][m]);\n text = text.replace('ООО', consts.monthFullGen[language as ioBroker.Languages][m]);\n text = text.replace('OO', consts.monthFull[language as ioBroker.Languages][m]);\n text = text.replace('ОО', consts.monthFull[language as ioBroker.Languages][m]);\n\n if (initialText === text) {\n text = text.replace('O', consts.monthShort[language as ioBroker.Languages][m]);\n }\n return text;\n }\n return adapter.formatDate(date as string | number | Date, format);\n },\n formatTimeDiff: function (diff: number, format?: string): string {\n if (!format) {\n format = 'hh:mm:ss';\n }\n\n let text = format;\n\n if (sandbox.verbose) {\n sandbox.log(`formatTimeDiff(format=${format}, diff=${diff})`, 'debug');\n }\n\n const second = 1000;\n const minute = 60 * second;\n const hour = 60 * minute;\n const day = 24 * hour;\n const neg = diff < 0;\n diff = Math.abs(diff);\n\n if (/DD|TT|ДД|D|T|Д/.test(text)) {\n const days = Math.floor(diff / day);\n\n text = text.replace(/DD|TT|ДД/, days < 10 ? `0${days}` : days.toString());\n text = text.replace(/[DTД]/, days.toString());\n\n if (sandbox.verbose) {\n sandbox.log(`formatTimeDiff(format=${format}, text=${text}, days=${days})`, 'debug');\n }\n\n diff -= days * day;\n }\n\n if (/hh|SS|чч|h|S|ч/.test(text)) {\n const hours = Math.floor(diff / hour);\n\n text = text.replace(/hh|SS|чч/, hours < 10 ? `0${hours}` : hours.toString());\n text = text.replace(/[hSч]/, hours.toString());\n\n sandbox.verbose &&\n sandbox.log(`formatTimeDiff(format=${format}, text=${text}, hours=${hours})`, 'debug');\n\n diff -= hours * hour;\n }\n\n if (/mm|мм|m|м/.test(text)) {\n const minutes = Math.floor(diff / minute);\n\n text = text.replace(/mm|мм/, minutes < 10 ? `0${minutes}` : minutes.toString());\n text = text.replace(/[mм]/, minutes.toString());\n\n sandbox.verbose &&\n sandbox.log(`formatTimeDiff(format=${format}, text=${text}, minutes=${minutes})`, 'debug');\n\n diff -= minutes * minute;\n }\n\n if (/ss|сс|мм|s|с/.test(text)) {\n const seconds = Math.floor(diff / second);\n\n text = text.replace(/ss|сс/, seconds < 10 ? `0${seconds}` : seconds.toString());\n text = text.replace(/[sс]/, seconds.toString());\n\n sandbox.verbose &&\n sandbox.log(`formatTimeDiff(format=${format}, text=${text}, seconds=${seconds})`, 'debug');\n // diff -= seconds * second; // no milliseconds\n }\n\n if (sandbox.verbose) {\n sandbox.log(`formatTimeDiff(format=${format}, text=${text})`, 'debug');\n }\n\n return neg ? `-${text}` : text;\n },\n getDateObject: function (date: Date | number | string): Date {\n if (isObject(date)) {\n return date as Date;\n }\n if (typeof date === 'undefined') {\n return new Date();\n }\n if (typeof date !== 'string') {\n return new Date(date);\n }\n\n // If only hours: 20, 2\n if (date.match(/^\\d?\\d$/)) {\n const _now = new Date();\n date = `${_now.getFullYear()}-${_now.getMonth() + 1}-${_now.getDate()} ${date}:00`;\n } else if (date.match(/^\\d?\\d:\\d\\d(:\\d\\d)?$/)) {\n // 20:00, 2:00, 20:00:00, 2:00:00\n const now = new Date();\n date = `${now.getFullYear()}-${now.getMonth() + 1}-${now.getDate()} ${date}`;\n }\n\n return new Date(date);\n },\n writeFile: function (\n _adapter: string,\n fileName: string,\n data: string | Buffer | ((err: Error) => void),\n callback?: (err?: Error | null) => void,\n ): void {\n if (typeof data === 'function' || !data) {\n callback = data as (err?: Error | null) => void;\n data = fileName;\n fileName = _adapter;\n _adapter = '0_userdata.0';\n }\n _adapter = _adapter || '0_userdata.0';\n\n if (debug) {\n sandbox.log(\n `writeFile(adapter=${_adapter}, fileName=${fileName}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n if (typeof callback === 'function') {\n setTimeout(function (): void {\n try {\n callback.call(sandbox);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }, 0);\n }\n } else {\n if (sandbox.verbose) {\n sandbox.log(`writeFile(adapter=${_adapter}, fileName=${fileName})`, 'info');\n }\n if (callback) {\n adapter.writeFile(_adapter, fileName, data, callback);\n } else {\n // @ts-expect-error should be fixed in js-controller\n adapter.writeFile(_adapter, fileName, data);\n }\n }\n },\n readFile: function (\n _adapter: string,\n fileName: string | ((err: Error | null | undefined, data?: Buffer | string, mimeType?: string) => void),\n callback?: (err: Error | null | undefined, data?: Buffer | string, mimeType?: string) => void,\n ): void {\n if (typeof fileName === 'function') {\n callback = fileName as (\n err: Error | null | undefined,\n data?: Buffer | string,\n mimeType?: string,\n ) => void;\n fileName = _adapter;\n _adapter = '0_userdata.0';\n }\n if (typeof callback !== 'function') {\n sandbox.log(`readFile(adapter=${_adapter}, fileName=${fileName}): no callback`, 'error');\n return;\n }\n _adapter = _adapter || '0_userdata.0';\n if (sandbox.verbose) {\n sandbox.log(`readFile(adapter=${_adapter}, fileName=${fileName})`, 'info');\n }\n\n adapter.fileExists(_adapter, fileName, (error: Error | null | undefined, result?: boolean): void => {\n if (error) {\n callback(error);\n } else if (!result) {\n callback(new Error('Not exists'));\n } else {\n adapter.readFile(_adapter, fileName, callback);\n }\n });\n },\n unlink: function (\n _adapter: string,\n fileName: string | ((err?: Error | null) => void),\n callback?: (err?: Error | null) => void,\n ): void {\n if (typeof fileName === 'function') {\n callback = fileName;\n fileName = _adapter;\n _adapter = '0_userdata.0';\n }\n _adapter = _adapter || '0_userdata.0';\n\n if (debug) {\n sandbox.log(\n `unlink(adapter=${_adapter}, fileName=${fileName}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n if (typeof callback === 'function') {\n setTimeout(function (): void {\n try {\n callback.call(sandbox);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }, 0);\n }\n } else {\n if (sandbox.verbose) {\n sandbox.log(`unlink(adapter=${_adapter}, fileName=${fileName})`, 'info');\n }\n if (callback) {\n adapter.unlink(_adapter, fileName, callback);\n } else {\n // @ts-expect-error should be fixed in js-controller\n adapter.unlink(_adapter, fileName);\n }\n }\n },\n delFile: function (\n _adapter: string,\n fileName: string | ((err?: Error | null) => void),\n callback?: (err?: Error | null) => void,\n ): void {\n return sandbox.unlink(_adapter, fileName as string, callback);\n },\n rename: function (_adapter: string, oldName: string, newName: string, callback?: (err?: Error | null) => void) {\n _adapter = _adapter || '0_userdata.0';\n\n if (debug) {\n sandbox.log(\n `rename(adapter=${_adapter}, oldName=${oldName}, newName=${newName}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n if (typeof callback === 'function') {\n setTimeout(function () {\n try {\n callback.call(sandbox);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }, 0);\n }\n } else {\n sandbox.verbose &&\n sandbox.log(`rename(adapter=${_adapter}, oldName=${oldName}, newName=${newName})`, 'info');\n if (callback) {\n adapter.rename(_adapter, oldName, newName, callback);\n } else {\n // @ts-expect-error should be fixed in js-controller\n adapter.rename(_adapter, oldName, newName);\n }\n }\n },\n renameFile: function (\n _adapter: string,\n oldName: string,\n newName: string,\n callback?: (err?: Error | null) => void,\n ): void {\n return sandbox.rename(_adapter, oldName, newName, callback);\n },\n getHistory: function (\n instance: string | (ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }),\n options:\n | (ioBroker.GetHistoryOptions & { id?: string; timeout?: number | string })\n | ((\n error: Error | null,\n result?: ioBroker.GetHistoryResult | null,\n options?: ioBroker.GetHistoryOptions & { id: string; timeout?: number | string },\n instance?: string,\n ) => void),\n callback?: (\n error: Error | null,\n result?: ioBroker.GetHistoryResult | null,\n options?: ioBroker.GetHistoryOptions & { id: string; timeout?: number | string },\n instance?: string,\n ) => void,\n ): void {\n if (isObject(instance)) {\n callback = options as (\n error: Error | null,\n result?: ioBroker.GetHistoryResult | null,\n options?: ioBroker.GetHistoryOptions & { id: string; timeout?: number | string },\n instance?: string,\n ) => void;\n options = instance as ioBroker.GetHistoryOptions & { id?: string; timeout?: number | string };\n instance = '';\n }\n\n if (typeof callback !== 'function') {\n return sandbox.log('No callback found!', 'error');\n }\n if (!isObject(options)) {\n return sandbox.log('No options found!', 'error');\n }\n if (!(options as ioBroker.GetHistoryOptions & { id?: string; timeout?: number | string }).id) {\n return sandbox.log('No ID found!', 'error');\n }\n const timeoutMs =\n parseInt(\n (options as ioBroker.GetHistoryOptions & { id?: string; timeout?: number })\n ?.timeout as unknown as string,\n 10,\n ) || 20000;\n\n if (!instance) {\n // @ts-expect-error defaultHistory is private attribute of adapter. Fix later\n if (adapter.defaultHistory) {\n // @ts-expect-error defaultHistory is private attribute of adapter. Fix later\n instance = adapter.defaultHistory;\n } else {\n instance = objects['system.config']?.common?.defaultHistory || null;\n }\n }\n\n if (sandbox.verbose) {\n sandbox.log(`getHistory(instance=${instance as string}, options=${JSON.stringify(options)})`, 'info');\n }\n\n if (!instance) {\n sandbox.log('No default history instance found!', 'error');\n try {\n callback.call(sandbox, new Error('No default history instance found!'));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n return;\n }\n if ((instance as string).startsWith('system.adapter.')) {\n instance = (instance as string).substring('system.adapter.'.length);\n }\n\n if (!objects[`system.adapter.${instance as string}`]) {\n sandbox.log(`Instance \"${instance as string}\" not found!`, 'error');\n try {\n callback.call(sandbox, new Error(`Instance \"${instance as string}\" not found!`));\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n return;\n }\n\n let _timeout: NodeJS.Timeout | null = setTimeout(() => {\n _timeout = null;\n if (sandbox.verbose) {\n sandbox.log('getHistory => timeout', 'debug');\n }\n\n if (typeof callback === 'function') {\n try {\n callback.call(\n sandbox,\n new Error('Timeout'),\n null,\n options as ioBroker.GetHistoryOptions & { id: string; timeout?: number | string },\n instance as string,\n );\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n callback = undefined;\n }\n }, timeoutMs);\n\n adapter.sendTo(\n instance as string,\n 'getHistory',\n {\n id: (options as ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }).id,\n options,\n },\n (res: any): void => {\n if (_timeout) {\n clearTimeout(_timeout);\n _timeout = null;\n }\n const result: {\n error?: string;\n result?: ioBroker.GetHistoryResult;\n step?: number;\n sessionId?: string;\n } = res;\n\n if (sandbox.verbose && result?.error) {\n sandbox.log(`getHistory => ${result.error}`, 'error');\n }\n if (sandbox.verbose && result?.result) {\n sandbox.log(`getHistory => ${result.result.length} items`, 'debug');\n }\n\n if (typeof callback === 'function') {\n try {\n callback.call(\n sandbox,\n result.error ? new Error(result.error) : null,\n result.result,\n options as ioBroker.GetHistoryOptions & { id: string; timeout?: number | string },\n instance as string,\n );\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n callback = undefined;\n }\n },\n );\n },\n runScript: function (scriptName: string, callback?: (err?: Error | null) => void): boolean {\n scriptName = scriptName || name;\n if (!scriptName.match(/^script\\.js\\./)) {\n scriptName = `script.js.${scriptName}`;\n }\n // start another script\n if (!objects[scriptName] || !objects[scriptName].common) {\n sandbox.log(`Cannot start \"${scriptName}\", because not found`, 'error');\n return false;\n }\n if (debug) {\n sandbox.log(\n `runScript(scriptName=${scriptName}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n typeof callback === 'function' && callback();\n return true;\n }\n if (objects[scriptName].common.enabled) {\n objects[scriptName].common.enabled = false;\n adapter.extendForeignObject(scriptName, { common: { enabled: false } }, (/* err, obj */) => {\n adapter.extendForeignObject(\n scriptName,\n { common: { enabled: true } },\n err => typeof callback === 'function' && callback(err),\n );\n });\n return true;\n }\n adapter.extendForeignObject(\n scriptName,\n { common: { enabled: true } },\n err => typeof callback === 'function' && callback(err),\n );\n return true;\n },\n runScriptAsync: function (scriptName: string): Promise {\n let done = false;\n return new Promise((resolve, reject) => {\n const result = sandbox.runScript(scriptName, err => {\n if (err) {\n reject(err);\n done = true;\n } else {\n resolve();\n }\n });\n if (result === false && !done) {\n reject(new Error(`Script ${scriptName} was not found!`));\n }\n });\n },\n startScript: function (\n scriptName: string,\n ignoreIfStarted?: boolean | ((err: Error | null | undefined, started: boolean) => void),\n callback?: (err: Error | null | undefined, started: boolean) => void,\n ): boolean {\n if (typeof ignoreIfStarted === 'function') {\n callback = ignoreIfStarted as (err: Error | null | undefined, started: boolean) => void;\n ignoreIfStarted = false;\n }\n scriptName = scriptName || name;\n if (!scriptName.match(/^script\\.js\\./)) {\n scriptName = `script.js.${scriptName}`;\n }\n // start another script\n if (!objects[scriptName] || !objects[scriptName].common) {\n sandbox.log(`Cannot start \"${scriptName}\", because not found`, 'error');\n return false;\n }\n if (debug) {\n sandbox.log(\n `startScript(scriptName=${scriptName}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n typeof callback === 'function' && callback(null, false);\n return true;\n }\n if (objects[scriptName].common.enabled) {\n if (!ignoreIfStarted) {\n objects[scriptName].common.enabled = false;\n adapter.extendForeignObject(scriptName, { common: { enabled: false } }, () => {\n adapter.extendForeignObject(\n scriptName,\n { common: { enabled: true } },\n err => typeof callback === 'function' && callback(err, true),\n );\n });\n } else if (typeof callback === 'function') {\n callback(null, false);\n }\n return true;\n }\n adapter.extendForeignObject(scriptName, { common: { enabled: true } }, err => {\n typeof callback === 'function' && callback(err, true);\n });\n return true;\n },\n startScriptAsync: function (scriptName: string, ignoreIfStarted?: boolean): Promise {\n return new Promise((resolve, reject) => {\n const result = sandbox.startScript(\n scriptName,\n !!ignoreIfStarted,\n (err: Error | null | undefined, started: boolean): void => {\n if (err) {\n reject(err);\n } else {\n resolve(started);\n }\n },\n );\n if (result === false) {\n reject(new Error(`Script ${scriptName} was not found!`));\n }\n });\n },\n stopScript: function (\n scriptName: string,\n callback?: (err: Error | null | undefined, stopped: boolean) => void,\n ): boolean {\n scriptName = scriptName || name;\n\n if (!scriptName.match(/^script\\.js\\./)) {\n scriptName = `script.js.${scriptName}`;\n }\n\n // stop another script\n if (!objects[scriptName] || !objects[scriptName].common) {\n sandbox.log(`Cannot stop \"${scriptName}\", because not found`, 'error');\n return false;\n }\n if (debug) {\n sandbox.log(\n `stopScript(scriptName=${scriptName}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n if (typeof callback === 'function') {\n callback(null, false);\n }\n return true;\n }\n if (objects[scriptName].common.enabled) {\n objects[scriptName].common.enabled = false;\n adapter.extendForeignObject(scriptName, { common: { enabled: false } }, err => {\n if (typeof callback === 'function') {\n callback(err, true);\n }\n });\n } else if (typeof callback === 'function') {\n callback(null, false);\n }\n return true;\n },\n stopScriptAsync: function (scriptName: string): Promise {\n return new Promise((resolve, reject) => {\n const result = sandbox.stopScript(\n scriptName,\n (err: Error | null | undefined, stopped: boolean): void => {\n if (err) {\n reject(err);\n } else {\n resolve(stopped);\n }\n },\n );\n if (result === false) {\n reject(new Error(`Script ${scriptName} was not found!`));\n }\n });\n },\n isScriptActive: function (scriptName: string): boolean {\n if (!scriptName.match(/^script\\.js\\./)) {\n scriptName = `script.js.${scriptName}`;\n }\n if (!objects[scriptName] || !objects[scriptName].common) {\n sandbox.log('Script does not exist', 'error');\n return false;\n }\n return objects[scriptName].common.enabled;\n },\n startInstanceAsync: async function (instanceName: string): Promise {\n const objInstanceId = `system.adapter.${instanceName}`;\n const exists = await adapter.foreignObjectExists(objInstanceId);\n\n if (exists) {\n const instanceObj = await adapter.getForeignObjectAsync(objInstanceId);\n\n if (instanceObj?.type === 'instance' && !instanceObj.common.enabled) {\n await adapter.extendForeignObjectAsync(objInstanceId, { common: { enabled: true } });\n\n if (sandbox.verbose) {\n sandbox.log(`startInstanceAsync (instanceName=${instanceName})`, 'info');\n }\n\n return true;\n }\n sandbox.log(`Cannot start instance \"${instanceName}\", because already running`, 'warn');\n } else {\n sandbox.log(`Cannot start instance \"${instanceName}\", because not found`, 'error');\n }\n\n return false;\n },\n restartInstanceAsync: async function (instanceName: string): Promise {\n const objInstanceId = `system.adapter.${instanceName}`;\n const exists = await adapter.foreignObjectExists(objInstanceId);\n\n if (exists) {\n const instanceObj = await adapter.getForeignObjectAsync(objInstanceId);\n\n if (instanceObj?.type === 'instance' && instanceObj.common.enabled) {\n await adapter.extendForeignObjectAsync(objInstanceId, {});\n\n if (sandbox.verbose) {\n sandbox.log(`restartInstanceAsync (instanceName=${instanceName})`, 'info');\n }\n\n return true;\n }\n sandbox.log(`Cannot restart instance \"${instanceName}\", because not running`, 'warn');\n } else {\n sandbox.log(`Cannot restart instance \"${instanceName}\", because not found`, 'error');\n }\n\n return false;\n },\n stopInstanceAsync: async function (instanceName: string): Promise {\n const objInstanceId = `system.adapter.${instanceName}`;\n const exists = await adapter.foreignObjectExists(objInstanceId);\n\n if (exists) {\n const instanceObj = await adapter.getForeignObjectAsync(objInstanceId);\n\n if (instanceObj?.type === 'instance' && instanceObj.common.enabled) {\n await adapter.extendForeignObjectAsync(objInstanceId, { common: { enabled: false } });\n\n if (sandbox.verbose) {\n sandbox.log(`stopInstanceAsync (instanceName=${instanceName})`, 'info');\n }\n\n return true;\n }\n sandbox.log(`Cannot stop instance \"${instanceName}\", because not running`, 'warn');\n } else {\n sandbox.log(`Cannot stop instance \"${instanceName}\", because not found`, 'error');\n }\n\n return false;\n },\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n toInt: function (val: boolean | string | number | 'true' | 'false'): number {\n if (val === true || val === 'true') {\n val = 1;\n }\n if (val === false || val === 'false') {\n val = 0;\n }\n val = parseInt(val as unknown as string) || 0;\n return val;\n },\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n toFloat: function (val: boolean | string | number | 'true' | 'false'): number {\n if (val === true || val === 'true') {\n val = 1;\n }\n if (val === false || val === 'false') {\n val = 0;\n }\n val = parseFloat(val as unknown as string) || 0;\n return val;\n },\n // eslint-disable-next-line @typescript-eslint/no-redundant-type-constituents\n toBoolean: function (val: boolean | string | number | 'true' | 'false'): boolean {\n if (val === '1' || val === 'true') {\n val = true;\n }\n if (val === '0' || val === 'false') {\n val = false;\n }\n return !!val;\n },\n getAttr: function (obj: string | Record, path: string | string[]): any {\n if (typeof path === 'string') {\n path = path.split('.');\n }\n if (typeof obj === 'string') {\n try {\n obj = JSON.parse(obj);\n } catch (err: unknown) {\n adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, {\n val: true,\n ack: true,\n c: 'getAttr',\n });\n sandbox.log(`Cannot parse \"${obj.substring(0, 30)}\": ${err as Error}`, 'error');\n\n return null;\n }\n }\n\n const attr: string = path.shift() || '';\n try {\n obj = (obj as Record)[attr];\n } catch (err: unknown) {\n adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, {\n val: true,\n ack: true,\n c: 'getAttr',\n });\n sandbox.log(`Cannot get ${attr} of \"${JSON.stringify(obj)}\": ${err as Error}`, 'error');\n\n return null;\n }\n\n if (!path.length) {\n return obj;\n }\n const type = typeof obj;\n if (obj === null || obj === undefined || type === 'boolean' || type === 'number') {\n return null;\n }\n return sandbox.getAttr(obj, path);\n },\n messageTo: function (\n target: string | { instance: string | null | number; script: string | null; message: string },\n data: any,\n options: { timeout?: number | string } | ((result: any, options: { timeout?: number | string }) => void),\n callback?: (result: any, options: { timeout?: number | string }, instance: string | number | null) => void,\n ) {\n const defaultTimeout = 5000;\n\n if (typeof target !== 'object') {\n target = { instance: null, script: null, message: target };\n }\n if (typeof options === 'function') {\n callback = options;\n options = { timeout: defaultTimeout };\n }\n\n let timeout: NodeJS.Timeout | null = null;\n if (typeof callback === 'function') {\n const timeoutDuration = parseInt(options?.timeout as unknown as string, 10) || defaultTimeout;\n\n timeout = setTimeout(() => {\n timeout = null;\n\n if (sandbox.verbose) {\n sandbox.log(`messageTo => timeout: ${timeoutDuration}`, 'debug');\n }\n\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, { error: 'timeout' }, options, target.instance);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n callback = undefined;\n }\n }, timeoutDuration);\n }\n let cbFunc: undefined | ((result: any) => void);\n if (timeout) {\n cbFunc = function (res: any) {\n timeout && clearTimeout(timeout);\n const result: { result?: any; error?: string | null } = res;\n\n if (sandbox.verbose && result?.result) {\n sandbox.log(`messageTo => ${JSON.stringify(result)}`, 'debug');\n }\n if (sandbox.verbose && result?.error) {\n sandbox.log(`messageTo => ${result.error}`, 'error');\n }\n\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, result, options, target.instance);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n callback = undefined;\n }\n };\n }\n\n if (target.instance || target.instance === 0) {\n if (\n typeof target.instance === 'string' &&\n target.instance &&\n target.instance.startsWith('system.adapter.')\n ) {\n target.instance = target.instance.substring('system.adapter.'.length);\n } else if (typeof target.instance === 'number') {\n target.instance = `javascript.${target.instance}`;\n }\n\n adapter.sendTo(\n target.instance,\n 'jsMessageBus',\n { message: target.message, script: target.script, data },\n cbFunc,\n );\n } else {\n // Send it to all instances\n context.adapter.getObjectView(\n 'system',\n 'instance',\n { startkey: 'system.adapter.javascript.', endkey: 'system.adapter.javascript.\\u9999' },\n options,\n (err: Error | null | undefined, res): void => {\n if (err || !res) {\n sandbox.log(`messageTo failed: ${err?.message}`, 'error');\n return;\n }\n const len = 'system.adapter.'.length;\n const instances = res.rows.map(item => item.id.substring(len));\n\n instances.forEach(instance => {\n adapter.sendTo(\n instance,\n 'jsMessageBus',\n { message: target.message, script: target.script, data },\n cbFunc,\n );\n });\n },\n );\n }\n },\n messageToAsync: function (\n target: string | { instance: string | null | number; script: string | null; message: string },\n data: any,\n options?: { timeout?: number | string },\n ): Promise {\n return new Promise((resolve, reject) => {\n sandbox.messageTo(target, data, options, (res: any): void => {\n const result: { error?: string } = res;\n if (sandbox.verbose) {\n sandbox.log(`messageTo result => ${JSON.stringify(res)}`, 'debug');\n }\n if (!res || result.error) {\n reject(result ? new Error(result.error) : new Error('Unknown error'));\n } else {\n resolve(result);\n }\n });\n });\n },\n onMessage: function (\n messageName: string,\n callback: (data: any, cb: (result: any) => void) => void,\n ): null | number {\n if (typeof callback !== 'function') {\n sandbox.log('onMessage callback is not a function', 'error');\n\n return null;\n }\n context.messageBusHandlers[sandbox.scriptName] = context.messageBusHandlers[sandbox.scriptName] || {};\n context.messageBusHandlers[sandbox.scriptName][messageName] =\n context.messageBusHandlers[sandbox.scriptName][messageName] || [];\n\n const handler = { id: Date.now() + Math.floor(Math.random() * 10000), cb: callback, sandbox };\n context.messageBusHandlers[sandbox.scriptName][messageName].push(handler);\n\n sandbox.__engine.__subscriptionsMessage += 1;\n\n if (\n sandbox.__engine.__subscriptionsMessage %\n (adapter.config as JavaScriptAdapterConfig).maxTriggersPerScript ===\n 0\n ) {\n sandbox.log(\n `More than ${sandbox.__engine.__subscriptionsMessage} message subscriptions registered. Check your script!`,\n 'warn',\n );\n }\n\n return handler.id;\n },\n onMessageUnregister: function (idOrName: number | string): boolean {\n const ctx = context.messageBusHandlers[sandbox.scriptName];\n let found = false;\n if (ctx) {\n if (typeof idOrName === 'number') {\n for (const messageName in ctx) {\n if (Object.prototype.hasOwnProperty.call(ctx, messageName)) {\n for (let i = 0; i < ctx[messageName].length; i++) {\n if (ctx[messageName][i].id === idOrName) {\n ctx[messageName].splice(i, 1);\n if (!ctx[messageName].length) {\n delete ctx[messageName];\n sandbox.__engine.__subscriptionsMessage--;\n }\n found = true;\n break;\n }\n }\n }\n if (found) {\n break;\n }\n }\n } else if (idOrName && ctx[idOrName]) {\n delete ctx[idOrName];\n sandbox.__engine.__subscriptionsMessage--;\n found = true;\n }\n }\n return found;\n },\n console: {\n log: function (msg: string): void {\n sandbox.log(msg, 'info');\n },\n error: function (msg: string): void {\n sandbox.log(msg, 'error');\n },\n warn: function (msg: string): void {\n sandbox.log(msg, 'warn');\n },\n info: function (msg: string): void {\n sandbox.log(msg, 'info');\n },\n debug: function (msg: string): void {\n sandbox.log(msg, 'debug');\n },\n },\n jsonataExpression: function (data: any, expression: string): Promise {\n return jsonata(expression).evaluate(data);\n },\n wait: function (ms: number): Promise {\n return new Promise((resolve: () => void): void => {\n sandbox.setTimeout(resolve, ms);\n });\n },\n sleep: function (ms: number): Promise {\n return sandbox.wait(ms);\n },\n onObject: function (\n pattern: string | string[],\n callback: (id: string, obj?: ioBroker.Object | null) => void,\n ): SubscribeObject | SubscribeObject[] | null {\n return sandbox.subscribeObject(pattern, callback);\n },\n subscribeObject: function (\n pattern: string | string[],\n callback: (id: string, obj?: ioBroker.Object | null) => void,\n ): SubscribeObject | SubscribeObject[] | null {\n if (Array.isArray(pattern)) {\n const result: {\n name: string;\n pattern: string;\n callback: (id: string, obj?: ioBroker.Object | null) => void;\n }[] = [];\n for (let p = 0; p < pattern.length; p++) {\n result.push(\n sandbox.subscribeObject(pattern[p], callback) as {\n name: string;\n pattern: string;\n callback: (id: string, obj?: ioBroker.Object | null) => void;\n },\n );\n }\n return result;\n }\n\n sandbox.__engine.__subscriptionsObject += 1;\n\n if (\n sandbox.__engine.__subscriptionsObject %\n (adapter.config as JavaScriptAdapterConfig).maxTriggersPerScript ===\n 0\n ) {\n sandbox.log(\n `More than ${sandbox.__engine.__subscriptionsObject} object subscriptions registered. Check your script!`,\n 'warn',\n );\n }\n\n // source is set by regexp if defined as /regexp/\n if (!pattern || typeof pattern !== 'string') {\n sandbox.log('Error by subscribeObject: pattern can be only string or array of strings.', 'error');\n return null;\n }\n\n if (typeof callback !== 'function') {\n sandbox.log('Error by subscribeObject: callback is not a function', 'error');\n return null;\n }\n\n const subs: SubscribeObject = { pattern, callback, name };\n if (sandbox.verbose) {\n sandbox.log(`subscribeObject: ${JSON.stringify(subs)}`, 'info');\n }\n\n adapter.subscribeForeignObjects(pattern);\n\n context.subscriptionsObject.push(subs);\n\n return subs;\n },\n unsubscribeObject: function (subObject: SubscribeObject | SubscribeObject[]): boolean | boolean[] {\n if (subObject && Array.isArray(subObject)) {\n const result: boolean[] = [];\n for (let t = 0; t < subObject.length; t++) {\n result.push(sandbox.unsubscribeObject(subObject[t]) as boolean);\n }\n return result;\n }\n\n if (sandbox.verbose) {\n sandbox.log(`adapterUnsubscribeObject(id=${JSON.stringify(subObject)})`, 'info');\n }\n\n for (let i = context.subscriptionsObject.length - 1; i >= 0; i--) {\n if (context.subscriptionsObject[i] === subObject) {\n adapter.unsubscribeForeignObjects(subObject.pattern);\n context.subscriptionsObject.splice(i, 1);\n sandbox.__engine.__subscriptionsObject--;\n return true;\n }\n }\n let deleted = 0;\n for (let i = context.subscriptionsObject.length - 1; i >= 0; i--) {\n if (\n context.subscriptionsObject[i].name &&\n context.subscriptionsObject[i].pattern === subObject.pattern\n ) {\n deleted++;\n adapter.unsubscribeForeignObjects(subObject.pattern);\n context.subscriptionsObject.splice(i, 1);\n sandbox.__engine.__subscriptionsObject--;\n }\n }\n return !!deleted;\n },\n // internal function to send the block debugging info to the front-end\n _sendToFrontEnd: function (blockId: string, data: any): void {\n if (context.rulesOpened === sandbox.scriptName) {\n adapter.setState(\n 'debug.rules',\n JSON.stringify({ ruleId: sandbox.scriptName, blockId, data, ts: Date.now() }),\n true,\n );\n }\n },\n existsStateAsync: function (_id: string): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n existsObjectAsync: function (_id: string): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n getObjectAsync: function (_id: string, _enumName: null | string): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n setObjectAsync: function (_id: string, _obj: ioBroker.Object): Promise<{ id: string }> {\n return Promise.reject(new Error('Not implemented'));\n },\n extendObjectAsync: function (_id: string, _obj: Partial): Promise<{ id: string }> {\n return Promise.reject(new Error('Not implemented'));\n },\n deleteObjectAsync: function (_id: string, _isRecursive?: boolean): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n createStateAsync: function (\n _name: string,\n _initValue: undefined | ioBroker.StateValue | ioBroker.State,\n _forceCreation:\n | boolean\n | undefined\n | Record\n | Partial\n | ((err: Error | null) => void),\n _common?: Partial | ((err: Error | null) => void),\n _native?: Record | ((err: Error | null) => void),\n ): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n createAliasAsync: function (\n _name: string,\n _alias: string | CommonAlias,\n _forceCreation: boolean | Partial | undefined,\n _common?: Partial | Record,\n _native?: Record,\n ): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n deleteStateAsync: function (_id: string): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n writeFileAsync: function (\n _adapter: string,\n _fileName: string | Buffer,\n _data?: string | Buffer,\n ): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n readFileAsync: function (_adapter: string, _fileName?: string): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n unlinkAsync: function (_adapter: string, _fileName?: string): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n delFileAsync: function (_adapter: string, _fileName?: string): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n renameAsync: function (_adapter: string, _oldName: string, _newName?: string): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n renameFileAsync: function (_adapter: string, _oldName: string, _newName?: string): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n getHistoryAsync: function (\n _instance: string | (ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }),\n _options?: ioBroker.GetHistoryOptions & { id?: string; timeout?: number | string },\n ): Promise {\n return Promise.reject(new Error('Not implemented'));\n },\n httpGetAsync: function (\n _url: string,\n _options?: {\n timeout?: number;\n responseType?: ResponseType;\n headers?: Record;\n basicAuth?: { user: string; password: string } | null;\n bearerAuth?: string;\n validateCertificate?: boolean;\n },\n ): Promise<{\n statusCode: number | null;\n data: any;\n headers: Record;\n responseTime: number;\n }> {\n return Promise.reject(new Error('Not implemented'));\n },\n httpPostAsync: function (\n _url: string,\n _data: any,\n _options: {\n timeout?: number;\n responseType?: ResponseType;\n headers?: Record;\n basicAuth?: { user: string; password: string } | null;\n bearerAuth?: string;\n validateCertificate?: boolean;\n },\n ): Promise<{\n statusCode: number | null;\n data: any;\n headers: Record;\n responseTime: number;\n }> {\n return Promise.reject(new Error('Not implemented'));\n },\n };\n\n // Create advanced functions that can modify objects\n if ((adapter.config as JavaScriptAdapterConfig).enableSetObject) {\n sandbox.setObject = function (\n id: string,\n obj: ioBroker.Object,\n callback?: (err?: Error | null, res?: { id: string }) => void,\n ): void {\n if (id && typeof id === 'string' && id.startsWith('system.adapter.')) {\n sandbox.log(\n `Using setObject on system object ${id} can be dangerous (protected instance attributes may be lost)`,\n 'info',\n );\n }\n if (debug) {\n sandbox.log(\n `setObject(id=${id}, obj=${JSON.stringify(obj)}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n if (typeof callback === 'function') {\n setImmediate(function () {\n try {\n callback.call(sandbox, null, { id });\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n });\n }\n } else {\n if (sandbox.verbose) {\n sandbox.log(`setObject(id=${id}, obj=${JSON.stringify(obj)})`, 'info');\n }\n adapter.setForeignObject(id, obj, (err, res) => {\n if (!err) {\n // Update meta object data\n context.updateObjectContext(id, obj);\n }\n if (typeof callback === 'function') {\n try {\n callback.call(sandbox, err, res);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }\n });\n }\n };\n sandbox.extendObject = function (\n id: string,\n obj: Partial,\n callback?: (err: Error | undefined | null, res?: { id: string }) => void,\n ): void {\n if (debug) {\n sandbox.log(\n `extendObject(id=${id}, obj=${JSON.stringify(obj)}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n if (typeof callback === 'function') {\n setTimeout(function () {\n try {\n callback.call(sandbox, null, { id });\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }, 0);\n }\n } else {\n if (sandbox.verbose) {\n sandbox.log(`extendObject(id=${id}, obj=${JSON.stringify(obj)})`, 'info');\n }\n adapter.extendForeignObject(id, JSON.parse(JSON.stringify(obj)), callback);\n }\n };\n sandbox.deleteObject = function (id: string, isRecursive?: boolean, callback?: ioBroker.ErrorCallback): void {\n if (typeof isRecursive === 'function') {\n callback = isRecursive;\n isRecursive = false;\n }\n if (debug) {\n sandbox.log(\n `deleteObject(id=${id}) - ${words._('was not executed, while debug mode is active')}`,\n 'warn',\n );\n if (typeof callback === 'function') {\n setTimeout(function () {\n try {\n callback.call(sandbox);\n } catch (err: unknown) {\n errorInCallback(err as Error);\n }\n }, 0);\n }\n } else {\n if (sandbox.verbose) {\n sandbox.log(`deleteObject(id=${id})`, 'info');\n }\n adapter.delForeignObject(id, { recursive: isRecursive }, callback);\n }\n };\n }\n\n // promisify methods on the sandbox\n sandbox.existsStateAsync = promisify(sandbox.existsState);\n sandbox.existsObjectAsync = promisify(sandbox.existsObject);\n sandbox.getObjectAsync = promisify(sandbox.getObject);\n sandbox.setObjectAsync = promisify(sandbox.setObject);\n sandbox.extendObjectAsync = promisify(sandbox.extendObject);\n sandbox.deleteObjectAsync = promisify(sandbox.deleteObject);\n sandbox.createStateAsync = promisify(sandbox.createState);\n sandbox.createAliasAsync = promisify(sandbox.createAlias);\n sandbox.deleteStateAsync = promisify(sandbox.deleteState);\n sandbox.writeFileAsync = promisify(sandbox.writeFile);\n sandbox.readFileAsync = promisify(sandbox.readFile);\n sandbox.unlinkAsync = promisify(sandbox.unlink);\n sandbox.delFileAsync = promisify(sandbox.delFile);\n sandbox.renameAsync = promisify(sandbox.rename);\n sandbox.renameFileAsync = promisify(sandbox.renameFile);\n sandbox.getHistoryAsync = promisify(sandbox.getHistory);\n sandbox.httpGetAsync = promisify(sandbox.httpGet);\n sandbox.httpPostAsync = promisify(sandbox.httpPost);\n\n // Make all predefined properties and methods readonly so scripts cannot overwrite them\n for (const prop of Object.keys(sandbox)) {\n Object.defineProperty(sandbox, prop, {\n configurable: false,\n writable: false,\n });\n }\n\n return sandbox;\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/scheduler.js b/build-backend/lib/scheduler.js new file mode 100644 index 00000000..43ca15f2 --- /dev/null +++ b/build-backend/lib/scheduler.js @@ -0,0 +1,553 @@ +"use strict"; +// const DEFAULT = { +// time: { +// exactTime: false, +// +// start: '00:00', +// end: '23:59', +// +// mode: 'hours', +// interval: 1, +// }, +// period: { +// once: '', +// days: 1, +// dows: '', +// dates: '', +// weeks: 0, +// months: '', +// +// years: 0, +// yearMonth: 0, +// yearDate: 0, +// }, +// valid: { +// from: '', +// to: '' +// } +// }; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Scheduler = void 0; +class Scheduler { + list; + Date; + suncalc; + latitude; + longitude; + log; + timer = null; + todaysAstroTimes; + yesterdaysAstroTimes; + astroList; + astroListLow; + constructor(log, DateTest, suncalc, latitude, longitude) { + this.list = {}; + this.Date = DateTest || Date; + this.suncalc = suncalc; + this.latitude = latitude; + this.longitude = longitude; + this.log = log || { + debug: function (text) { + console.log(text); + }, + info: function (text) { + console.log(text); + }, + log: function (text) { + console.log(text); + }, + warn: function (text) { + console.warn(text); + }, + error: function (text) { + console.error(text); + }, + silly: function (text) { + console.log(text); + }, + }; + // this._setAstroVars(); + const todayNoon = new this.Date(); + const yesterdayNoon = new this.Date(); + todayNoon.setHours(12, 0, 0, 0); + yesterdayNoon.setHours(-12, 0, 0, 0); + this.todaysAstroTimes = this.suncalc.getTimes(todayNoon, this.latitude, this.longitude); + this.yesterdaysAstroTimes = this.suncalc.getTimes(yesterdayNoon, this.latitude, this.longitude); + this.astroList = [ + 'dawn', + 'dusk', + 'goldenHour', + 'goldenHourEnd', + 'nadir', + 'nauticalDawn', + 'nauticalDusk', + 'night', + 'nightEnd', + 'solarNoon', + 'sunrise', + 'sunriseEnd', + 'sunset', + 'sunsetStart', + ]; + this.astroListLow = [ + 'dawn', + 'dusk', + 'goldenhour', + 'goldenhourend', + 'nadir', + 'nauticaldawn', + 'nauticaldusk', + 'night', + 'nightend', + 'solarnoon', + 'sunrise', + 'sunriseend', + 'sunset', + 'sunsetstart', + ]; + } + _getId() { + return `${Math.round(Math.random() * 1000000)}.${this.Date.now()}`; + } + recalculate() { + const count = Object.keys(this.list).length; + if (count && !this.timer) { + const d = new this.Date(); + d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone + d.setSeconds(0); + d.setMinutes(d.getMinutes() + 1); + this.timer = setTimeout(notBefore => this.checkSchedules(notBefore), d.getTime() - this.Date.now(), d.getTime()); + } + else if (!count && this.timer) { + clearTimeout(this.timer); + this.timer = null; + } + } + getContext() { + const now = new this.Date(); + return { + now: now.getTime(), + minutesOfDay: now.getHours() * 60 + now.getMinutes(), + y: now.getFullYear(), + M: now.getMonth(), + d: now.getDate(), + h: now.getHours(), + m: now.getMinutes(), + dow: now.getDay(), + }; + } + checkSchedules(notBeforeTime) { + const context = this.getContext(); + // Work around for not those precise RTCs in some system + if (notBeforeTime !== undefined && context.now < notBeforeTime) { + this.timer = setTimeout(notBefore => this.checkSchedules(notBefore), notBeforeTime - this.Date.now(), notBeforeTime); + return; + } + for (const id in this.list) { + if (!Object.prototype.hasOwnProperty.call(this.list, id)) { + continue; + } + if (this.checkSchedule(context, this.list[id])) { + setImmediate(id => this.list[id] && typeof this.list[id].cb === 'function' && this.list[id].cb(id), id); + } + } + const d = new this.Date(); + d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone + d.setSeconds(0); + d.setMinutes(d.getMinutes() + 1); + this.timer = setTimeout(notBefore => this.checkSchedules(notBefore), d.getTime() - this.Date.now(), d.getTime()); + } + monthDiff(d1, d2) { + let months; + months = (d2.getFullYear() - d1.getFullYear()) * 12; + months -= d1.getMonth() + 1; + months += d2.getMonth(); + return months <= 0 ? 0 : months; + } + checkSchedule(context, schedule) { + if (schedule.valid) { + if (schedule.valid.from && + !this.isPast(context, schedule.valid.from) && + !this.isToday(context, schedule.valid.from)) { + return false; + } + // "to" this.Date is in the past => delete it from a list + if (schedule.valid.to && this.isPast(context, schedule.valid.to)) { + delete this.list[schedule.id]; + return false; + } + } + if (schedule.period) { + if (schedule.period.once && !this.isToday(context, schedule.period.once)) { + if (this.isPast(context, schedule.period.once)) { + delete this.list[schedule.id]; + } + return false; + } + else if (schedule.period.days) { + if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) { + return false; + } + else if (schedule.period.days > 1) { + // @ts-expect-error period of days cannot be without valid fromDate + const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24) + 0.5); + if (diff % schedule.period.days) { + return false; + } + } + } + else if (schedule.period.weeks) { + if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) { + return false; + } + if (schedule.period.weeks > 1) { + // @ts-expect-error period of weeks cannot be without valid fromDate + const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24 * 7) + 0.5); + if (diff % schedule.period.weeks) { + return false; + } + } + } + else if (schedule.period.months) { + if (Array.isArray(schedule.period.months) && !schedule.period.months.includes(context.M)) { + return false; + } + if (schedule.period.fromDate && + typeof schedule.period.months === 'number' && + schedule.period.months > 1) { + const diff = this.monthDiff(schedule.period.fromDate, new this.Date(context.now)); + if (diff % schedule.period.months) { + return false; + } + } + if (schedule.period.dates && !schedule.period.dates.includes(context.d)) { + return false; + } + } + else if (schedule.period.years) { + if (schedule.period.yearMonth !== undefined && schedule.period.yearMonth !== context.M) { + return false; + } + if (schedule.period.yearDate && schedule.period.yearDate !== context.d) { + return false; + } + if (schedule.period.fromDate && + typeof schedule.period.years === 'number' && + schedule.period.years > 1) { + const diff = Math.floor(this.monthDiff(schedule.period.fromDate, new this.Date(context.now)) / 12); + if (diff % schedule.period.years) { + return false; + } + } + } + } + if (schedule.time) { + let start; + let end; + const now = new this.Date(context.now); + if (now.getDate() !== this.todaysAstroTimes.sunrise.getDate()) { + this._setAstroVars(); + } + if (typeof schedule.time.start === 'string') { + const astroNameStart = this._getAstroName(schedule.time.start); + if (astroNameStart) { + let times = this.todaysAstroTimes; + if (times[astroNameStart].getDate() !== now.getDate()) { + times = this.yesterdaysAstroTimes; + } + const startDate = times[astroNameStart]; + start = startDate.getHours() * 60 + startDate.getMinutes(); + } + else { + this.log.error(`unknown astro event "${schedule.time.start}"`); + return false; + } + } + else { + start = schedule.time.start; + } + if (typeof schedule.time.end === 'string') { + const astroNameEnd = this._getAstroName(schedule.time.end); + if (astroNameEnd) { + let times = this.todaysAstroTimes; + if (times[astroNameEnd].getDate() !== now.getDate()) { + times = this.yesterdaysAstroTimes; + } + const endDate = times[astroNameEnd]; + end = endDate.getHours() * 60 + endDate.getMinutes(); + } + else { + this.log.error(`unknown astro event "${schedule.time.end}"`); + return false; + } + } + else { + end = schedule.time.end; + } + start = start || 0; + end = end || 60 * 24; + if (schedule.time.exactTime) { + if (context.minutesOfDay !== start) { + return false; + } + } + else { + if (start >= context.minutesOfDay || (end && end < context.minutesOfDay)) { + return false; + } + if (schedule.time.mode === 60) { + if (schedule.time.interval > 1 && (context.minutesOfDay - start) % schedule.time.interval) { + return false; + } + } + else if (schedule.time.mode === 3600) { + if ((context.minutesOfDay - start) % (schedule.time.interval * 60)) { + return false; + } + } + } + } + return true; + } + string2date(date) { + let parts = date.split('.'); + let d; + if (parts.length !== 3) { + parts = date.split('-'); + d = new this.Date(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10)); + } + else { + d = new this.Date(parseInt(parts[2], 10), parseInt(parts[1], 10) - 1, parseInt(parts[0], 10)); + } + return { y: d.getFullYear(), M: d.getMonth(), d: d.getDate() }; + } + isPast(context, date) { + if (date) { + if (date.y < context.y) { + return true; + } + if (date.y === context.y) { + if (date.M < context.M) { + return true; + } + if (date.M === context.M) { + if (date.d < context.d) { + return true; + } + } + } + } + return false; + } + isToday(context, date) { + return date && date.y === context.y && date.M === context.M && date.d === context.d; + } + add(schedule, scriptName, cb) { + let oSchedule; + if (typeof schedule === 'string') { + try { + oSchedule = JSON.parse(schedule); + } + catch { + this.log.error(`Cannot parse schedule: ${schedule}`); + return null; + } + } + else { + oSchedule = schedule; + } + const id = this._getId(); + if (typeof oSchedule !== 'object' || !oSchedule.period) { + this.log.error(`Invalid schedule structure: ${JSON.stringify(oSchedule)}`); + return null; + } + const context = this.getContext(); + const sch = JSON.parse(JSON.stringify(oSchedule)); + sch.scriptName = scriptName; + sch.original = JSON.stringify(oSchedule); + sch.id = id; + sch.cb = cb; + if (oSchedule.time?.start) { + const astroNameStart = this._getAstroName(oSchedule.time.start); + if (astroNameStart && sch.time) { + sch.time.start = astroNameStart; + } + else if (oSchedule.time.start.includes(':')) { + const parts = oSchedule.time.start.split(':'); + if (sch.time) { + sch.time.start = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10); + } + } + else { + this.log.error(`unknown astro event "${oSchedule.time.start}"`); + return null; + } + } + if (oSchedule.time?.end) { + const astroNameEnd = this._getAstroName(oSchedule.time.end); + if (astroNameEnd && sch.time) { + sch.time.end = astroNameEnd; + } + else if (oSchedule.time.end.includes(':')) { + const parts = oSchedule.time.end.split(':'); + if (sch.time) { + sch.time.end = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10); + } + } + else { + this.log.error(`unknown astro event "${oSchedule.time.end}"`); + return null; + } + } + if (sch.time) { + if (oSchedule.time.mode === 'minutes') { + sch.time.mode = 60; + } + else if (oSchedule.time.mode === 'hours') { + sch.time.mode = 3600; + } + } + if (oSchedule.period.once) { + sch.period.once = this.string2date(oSchedule.period.once); + } + if (oSchedule.valid && sch.valid) { + if (oSchedule.valid.from) { + sch.valid.from = this.string2date(oSchedule.valid.from); + } + if (oSchedule.valid.to) { + sch.valid.to = this.string2date(oSchedule.valid.to); + } + if (this.isPast(context, sch.valid.to)) { + this.log.warn('End of schedule is in the past'); + return null; + } + if (typeof oSchedule.period.days === 'number' && oSchedule.period.days > 1 && sch.valid.from) { + // fromDate must be unix time + sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d).getTime(); + } + else if (typeof oSchedule.period.weeks === 'number' && oSchedule.period.weeks > 1) { + const fromDate = sch.valid.from + ? new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d) + : new this.Date(); + //sch.valid.fromDate.setDate(-sch.valid.fromDate.getDate() - sch.valid.fromDate.getDay()); + // fromDate must be unix time + sch.valid.fromDate = fromDate.getTime(); + } + else if (sch.valid.from && typeof oSchedule.period.months === 'number' && oSchedule.period.months > 1) { + // fromDate must be object + sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d); + } + else if (sch.valid.from && typeof oSchedule.period.years === 'number' && oSchedule.period.years > 1) { + // fromDate must be object + sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d); + } + } + if (sch.period && + ((typeof sch.period.days === 'number' && sch.period.days > 1) || + (typeof sch.period.weeks === 'number' && sch.period.weeks > 1) || + (typeof sch.period.months === 'number' && sch.period.months > 1) || + (typeof sch.period.years === 'number' && sch.period.years > 1)) && + (!sch.valid || !sch.valid.fromDate)) { + this.log.warn('Invalid Schedule definition: Period day/weeks/months/years only allowed with a valid.from date!'); + return null; + } + if (oSchedule.period.dows) { + try { + sch.period.dows = JSON.parse(oSchedule.period.dows); + } + catch { + this.log.error(`Cannot parse day of weeks: ${JSON.stringify(sch.period.dows)}`); + return null; + } + if (!Array.isArray(sch.period.dows)) { + this.log.error(`day of weeks is no array: ${JSON.stringify(sch.period.dows)}`); + return null; + } + } + if (oSchedule.period.months && typeof oSchedule.period.months !== 'number') { + // can be number or array-string + try { + sch.period.months = JSON.parse(oSchedule.period.months); + } + catch { + this.log.error(`Cannot parse day of months: ${JSON.stringify(sch.period.months)}`); + return null; + } + sch.period.months = sch.period.months.map(m => m - 1); + } + if (oSchedule.period.dates) { + try { + sch.period.dates = JSON.parse(oSchedule.period.dates); + } + catch { + this.log.error(`Cannot parse day of dates: ${JSON.stringify(sch.period.dates)}`); + return null; + } + } + if (oSchedule.period.yearMonth) { + sch.period.yearMonth = oSchedule.period.yearMonth - 1; + } + this.list[id] = sch; + this.recalculate(); + return id; + } + remove(id) { + if (typeof id === 'object' && + id.type === 'schedule' && + typeof id.id === 'string' && + id.id.startsWith('schedule_')) { + if (this.list[id.id.substring('schedule_'.length)]) { + delete this.list[id.id.substring('schedule_'.length)]; + this.recalculate(); + return true; + } + return false; + } + if (typeof id === 'string' && this.list[id]) { + delete this.list[id]; + this.recalculate(); + return true; + } + return false; + } + getList() { + return Object.keys(this.list).map(id => ({ + id: `schedule_${id}`, + type: 'schedule', + schedule: this.list[id].original, + scriptName: this.list[id].scriptName, + })); + } + get(id) { + if (id && + typeof id === 'object' && + id.type === 'schedule' && + typeof id.id === 'string' && + id.id.startsWith('schedule_')) { + return this.list[id.id.substring('schedule_'.length)]; + } + if (typeof id === 'string') { + return this.list[id]; + } + return null; + } + _setAstroVars() { + const todayNoon = new this.Date(); + const yesterdayNoon = new this.Date(); + todayNoon.setHours(12, 0, 0, 0); + yesterdayNoon.setHours(-12, 0, 0, 0); + this.todaysAstroTimes = this.suncalc.getTimes(todayNoon, this.latitude, this.longitude); + this.yesterdaysAstroTimes = this.suncalc.getTimes(yesterdayNoon, this.latitude, this.longitude); + } + _getAstroName(evt) { + if (typeof evt === 'string') { + const pos = this.astroListLow.indexOf(evt.toLowerCase()); + if (pos > -1) { + return this.astroList[pos]; + } + } + return null; + } +} +exports.Scheduler = Scheduler; +//# sourceMappingURL=scheduler.js.map \ No newline at end of file diff --git a/build-backend/lib/scheduler.js.map b/build-backend/lib/scheduler.js.map new file mode 100644 index 00000000..e7802870 --- /dev/null +++ b/build-backend/lib/scheduler.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/lib/scheduler.ts"],"names":[],"mappings":"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","sourcesContent":["// const DEFAULT = {\n// time: {\n// exactTime: false,\n//\n// start: '00:00',\n// end: '23:59',\n//\n// mode: 'hours',\n// interval: 1,\n// },\n// period: {\n// once: '',\n// days: 1,\n// dows: '',\n// dates: '',\n// weeks: 0,\n// months: '',\n//\n// years: 0,\n// yearMonth: 0,\n// yearDate: 0,\n// },\n// valid: {\n// from: '',\n// to: ''\n// }\n// };\n\nimport type {\n GetMoonIlluminationResult,\n GetMoonPositionResult,\n GetMoonTimes,\n GetSunPositionResult,\n GetTimesResult,\n} from 'suncalc';\n\ninterface SunCalc {\n getTimes: (date: Date, latitude: number, longitude: number, height?: number) => GetTimesResult;\n addTime: (angleInDegrees: number, morningName: string, eveningName: string) => void;\n getPosition: (timeAndDate: Date, latitude: number, longitude: number) => GetSunPositionResult;\n getMoonPosition: (timeAndDate: Date, latitude: number, longitude: number) => GetMoonPositionResult;\n getMoonIllumination: (timeAndDate: Date) => GetMoonIlluminationResult;\n getMoonTimes: (date: Date, latitude: number, longitude: number, inUTC?: boolean) => GetMoonTimes;\n}\n\nexport type AstroEventName =\n | 'dawn'\n | 'dusk'\n | 'goldenHour'\n | 'goldenHourEnd'\n | 'nadir'\n | 'nauticalDawn'\n | 'nauticalDusk'\n | 'night'\n | 'nightEnd'\n | 'solarNoon'\n | 'sunrise'\n | 'sunriseEnd'\n | 'sunset'\n | 'sunsetStart';\n\ntype AstroEventNameLow =\n | 'dawn'\n | 'dusk'\n | 'goldenhour'\n | 'goldenhourend'\n | 'nadir'\n | 'nauticaldawn'\n | 'nauticaldusk'\n | 'night'\n | 'nightend'\n | 'solarnoon'\n | 'sunrise'\n | 'sunriseend'\n | 'sunset'\n | 'sunsetstart';\n\ntype SchedulerContext = {\n now: number;\n minutesOfDay: number;\n y: number;\n M: number;\n d: number;\n h: number;\n m: number;\n dow: number;\n};\n\nexport type SchedulerRule = {\n time: {\n start?: string;\n end?: string;\n mode?: 'minutes' | 'hours';\n interval?: number;\n exactTime?: boolean;\n };\n period: {\n once?: string;\n\n days?: number;\n dows?: string;\n dates?: string;\n weeks?: number;\n months?: string;\n\n years?: number;\n yearMonth?: number;\n yearDate?: number;\n };\n valid?: {\n from?: string;\n to?: string;\n };\n};\n\ntype SchedulerRuleParsed = {\n id: string;\n original: string;\n period: {\n fromDate?: Date;\n months?: number | number[];\n days?: number;\n dows?: number[];\n weeks?: number;\n years?: number;\n yearMonth?: number;\n yearDate?: number;\n dates?: number[];\n once?: { y: number; M: number; d: number };\n };\n time?: {\n exactTime: boolean;\n start: number | AstroEventName;\n end: number | AstroEventName;\n mode: 60 | 3600;\n interval: number;\n };\n valid?: {\n from?: { y: number; M: number; d: number };\n to?: { y: number; M: number; d: number };\n fromDate?: number | Date;\n };\n scriptName: string;\n cb: (id: string) => void;\n};\n\nexport type ScheduleName = {\n id: `schedule_${string}`;\n type: 'schedule';\n schedule: string;\n scriptName: string;\n};\n\nexport class Scheduler {\n private readonly list: Record;\n private readonly Date: typeof Date;\n private readonly suncalc: SunCalc;\n private readonly latitude: number;\n private readonly longitude: number;\n private log: {\n debug: (text: string) => void;\n info: (text: string) => void;\n warn: (text: string) => void;\n error: (text: string) => void;\n silly: (text: string) => void;\n };\n private timer: NodeJS.Timeout | null = null;\n private todaysAstroTimes: Record;\n private yesterdaysAstroTimes: Record;\n private readonly astroList: AstroEventName[] | undefined;\n private astroListLow: AstroEventNameLow[] | undefined;\n\n constructor(\n log: {\n debug: (text: string) => void;\n info: (text: string) => void;\n warn: (text: string) => void;\n error: (text: string) => void;\n silly: (text: string) => void;\n },\n DateTest: typeof Date | null,\n suncalc: SunCalc,\n latitude: number,\n longitude: number,\n ) {\n this.list = {};\n this.Date = DateTest || Date;\n this.suncalc = suncalc;\n this.latitude = latitude;\n this.longitude = longitude;\n this.log = log || {\n debug: function (text: string): void {\n console.log(text);\n },\n info: function (text: string): void {\n console.log(text);\n },\n log: function (text: string): void {\n console.log(text);\n },\n warn: function (text: string): void {\n console.warn(text);\n },\n error: function (text: string): void {\n console.error(text);\n },\n silly: function (text: string): void {\n console.log(text);\n },\n };\n\n // this._setAstroVars();\n const todayNoon = new this.Date();\n const yesterdayNoon = new this.Date();\n todayNoon.setHours(12, 0, 0, 0);\n yesterdayNoon.setHours(-12, 0, 0, 0);\n this.todaysAstroTimes = this.suncalc.getTimes(todayNoon, this.latitude, this.longitude);\n this.yesterdaysAstroTimes = this.suncalc.getTimes(yesterdayNoon, this.latitude, this.longitude);\n\n this.astroList = [\n 'dawn',\n 'dusk',\n 'goldenHour',\n 'goldenHourEnd',\n 'nadir',\n 'nauticalDawn',\n 'nauticalDusk',\n 'night',\n 'nightEnd',\n 'solarNoon',\n 'sunrise',\n 'sunriseEnd',\n 'sunset',\n 'sunsetStart',\n ];\n this.astroListLow = [\n 'dawn',\n 'dusk',\n 'goldenhour',\n 'goldenhourend',\n 'nadir',\n 'nauticaldawn',\n 'nauticaldusk',\n 'night',\n 'nightend',\n 'solarnoon',\n 'sunrise',\n 'sunriseend',\n 'sunset',\n 'sunsetstart',\n ];\n }\n\n _getId(): string {\n return `${Math.round(Math.random() * 1000000)}.${this.Date.now()}`;\n }\n\n recalculate(): void {\n const count = Object.keys(this.list).length;\n if (count && !this.timer) {\n const d = new this.Date();\n d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone\n d.setSeconds(0);\n d.setMinutes(d.getMinutes() + 1);\n this.timer = setTimeout(\n notBefore => this.checkSchedules(notBefore),\n d.getTime() - this.Date.now(),\n d.getTime(),\n );\n } else if (!count && this.timer) {\n clearTimeout(this.timer);\n this.timer = null;\n }\n }\n\n getContext(): SchedulerContext {\n const now = new this.Date();\n return {\n now: now.getTime(),\n minutesOfDay: now.getHours() * 60 + now.getMinutes(),\n y: now.getFullYear(),\n M: now.getMonth(),\n d: now.getDate(),\n h: now.getHours(),\n m: now.getMinutes(),\n dow: now.getDay(),\n };\n }\n\n checkSchedules(notBeforeTime?: number): void {\n const context = this.getContext();\n\n // Work around for not those precise RTCs in some system\n if (notBeforeTime !== undefined && context.now < notBeforeTime) {\n this.timer = setTimeout(\n notBefore => this.checkSchedules(notBefore),\n notBeforeTime - this.Date.now(),\n notBeforeTime,\n );\n return;\n }\n\n for (const id in this.list) {\n if (!Object.prototype.hasOwnProperty.call(this.list, id)) {\n continue;\n }\n if (this.checkSchedule(context, this.list[id])) {\n setImmediate(id => this.list[id] && typeof this.list[id].cb === 'function' && this.list[id].cb(id), id);\n }\n }\n\n const d = new this.Date();\n d.setMilliseconds(2); // 2 ms to be sure that the next second is reached, they do not hurt anyone\n d.setSeconds(0);\n d.setMinutes(d.getMinutes() + 1);\n this.timer = setTimeout(\n notBefore => this.checkSchedules(notBefore),\n d.getTime() - this.Date.now(),\n d.getTime(),\n );\n }\n\n monthDiff(d1: Date, d2: Date): number {\n let months: number;\n months = (d2.getFullYear() - d1.getFullYear()) * 12;\n months -= d1.getMonth() + 1;\n months += d2.getMonth();\n return months <= 0 ? 0 : months;\n }\n\n checkSchedule(context: SchedulerContext, schedule: SchedulerRuleParsed): boolean {\n if (schedule.valid) {\n if (\n schedule.valid.from &&\n !this.isPast(context, schedule.valid.from) &&\n !this.isToday(context, schedule.valid.from)\n ) {\n return false;\n }\n // \"to\" this.Date is in the past => delete it from a list\n if (schedule.valid.to && this.isPast(context, schedule.valid.to)) {\n delete this.list[schedule.id];\n return false;\n }\n }\n if (schedule.period) {\n if (schedule.period.once && !this.isToday(context, schedule.period.once)) {\n if (this.isPast(context, schedule.period.once)) {\n delete this.list[schedule.id];\n }\n return false;\n } else if (schedule.period.days) {\n if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) {\n return false;\n } else if (schedule.period.days > 1) {\n // @ts-expect-error period of days cannot be without valid fromDate\n const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24) + 0.5);\n if (diff % schedule.period.days) {\n return false;\n }\n }\n } else if (schedule.period.weeks) {\n if (schedule.period.dows && !schedule.period.dows.includes(context.dow)) {\n return false;\n }\n if (schedule.period.weeks > 1) {\n // @ts-expect-error period of weeks cannot be without valid fromDate\n const diff = Math.round((context.now - schedule.valid.fromDate) / (60000 * 24 * 7) + 0.5);\n if (diff % schedule.period.weeks) {\n return false;\n }\n }\n } else if (schedule.period.months) {\n if (Array.isArray(schedule.period.months) && !schedule.period.months.includes(context.M)) {\n return false;\n }\n if (\n schedule.period.fromDate &&\n typeof schedule.period.months === 'number' &&\n schedule.period.months > 1\n ) {\n const diff = this.monthDiff(schedule.period.fromDate, new this.Date(context.now));\n if (diff % schedule.period.months) {\n return false;\n }\n }\n if (schedule.period.dates && !schedule.period.dates.includes(context.d)) {\n return false;\n }\n } else if (schedule.period.years) {\n if (schedule.period.yearMonth !== undefined && schedule.period.yearMonth !== context.M) {\n return false;\n }\n if (schedule.period.yearDate && schedule.period.yearDate !== context.d) {\n return false;\n }\n if (\n schedule.period.fromDate &&\n typeof schedule.period.years === 'number' &&\n schedule.period.years > 1\n ) {\n const diff = Math.floor(this.monthDiff(schedule.period.fromDate, new this.Date(context.now)) / 12);\n if (diff % schedule.period.years) {\n return false;\n }\n }\n }\n }\n\n if (schedule.time) {\n let start: number;\n let end: number;\n const now = new this.Date(context.now);\n if (now.getDate() !== this.todaysAstroTimes.sunrise.getDate()) {\n this._setAstroVars();\n }\n if (typeof schedule.time.start === 'string') {\n const astroNameStart = this._getAstroName(schedule.time.start);\n if (astroNameStart) {\n let times = this.todaysAstroTimes;\n\n if (times[astroNameStart].getDate() !== now.getDate()) {\n times = this.yesterdaysAstroTimes;\n }\n const startDate: Date = times[astroNameStart];\n start = startDate.getHours() * 60 + startDate.getMinutes();\n } else {\n this.log.error(`unknown astro event \"${schedule.time.start}\"`);\n return false;\n }\n } else {\n start = schedule.time.start;\n }\n if (typeof schedule.time.end === 'string') {\n const astroNameEnd = this._getAstroName(schedule.time.end);\n if (astroNameEnd) {\n let times = this.todaysAstroTimes;\n if (times[astroNameEnd].getDate() !== now.getDate()) {\n times = this.yesterdaysAstroTimes;\n }\n const endDate: Date = times[astroNameEnd];\n end = endDate.getHours() * 60 + endDate.getMinutes();\n } else {\n this.log.error(`unknown astro event \"${schedule.time.end}\"`);\n return false;\n }\n } else {\n end = schedule.time.end;\n }\n\n start = start || 0;\n end = end || 60 * 24;\n\n if (schedule.time.exactTime) {\n if (context.minutesOfDay !== start) {\n return false;\n }\n } else {\n if (start >= context.minutesOfDay || (end && end < context.minutesOfDay)) {\n return false;\n }\n if (schedule.time.mode === 60) {\n if (schedule.time.interval > 1 && (context.minutesOfDay - start) % schedule.time.interval) {\n return false;\n }\n } else if (schedule.time.mode === 3600) {\n if ((context.minutesOfDay - start) % (schedule.time.interval * 60)) {\n return false;\n }\n }\n }\n }\n return true;\n }\n\n string2date(date: string): { y: number; M: number; d: number } {\n let parts = date.split('.');\n let d: Date;\n if (parts.length !== 3) {\n parts = date.split('-');\n d = new this.Date(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10));\n } else {\n d = new this.Date(parseInt(parts[2], 10), parseInt(parts[1], 10) - 1, parseInt(parts[0], 10));\n }\n return { y: d.getFullYear(), M: d.getMonth(), d: d.getDate() };\n }\n\n isPast(context: SchedulerContext, date: { y: number; M: number; d: number } | undefined): boolean {\n if (date) {\n if (date.y < context.y) {\n return true;\n }\n if (date.y === context.y) {\n if (date.M < context.M) {\n return true;\n }\n if (date.M === context.M) {\n if (date.d < context.d) {\n return true;\n }\n }\n }\n }\n return false;\n }\n\n isToday(context: SchedulerContext, date: { y: number; M: number; d: number }): boolean {\n return date && date.y === context.y && date.M === context.M && date.d === context.d;\n }\n\n add(schedule: SchedulerRule | string, scriptName: string, cb: (id: string) => void): string | null {\n let oSchedule: SchedulerRule;\n if (typeof schedule === 'string') {\n try {\n oSchedule = JSON.parse(schedule);\n } catch {\n this.log.error(`Cannot parse schedule: ${schedule}`);\n return null;\n }\n } else {\n oSchedule = schedule;\n }\n\n const id = this._getId();\n if (typeof oSchedule !== 'object' || !oSchedule.period) {\n this.log.error(`Invalid schedule structure: ${JSON.stringify(oSchedule)}`);\n return null;\n }\n const context = this.getContext();\n const sch: SchedulerRuleParsed = JSON.parse(JSON.stringify(oSchedule));\n sch.scriptName = scriptName;\n sch.original = JSON.stringify(oSchedule);\n sch.id = id;\n sch.cb = cb;\n\n if (oSchedule.time?.start) {\n const astroNameStart = this._getAstroName(oSchedule.time.start);\n if (astroNameStart && sch.time) {\n sch.time.start = astroNameStart;\n } else if (oSchedule.time.start.includes(':')) {\n const parts = oSchedule.time.start.split(':');\n if (sch.time) {\n sch.time.start = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);\n }\n } else {\n this.log.error(`unknown astro event \"${oSchedule.time.start}\"`);\n return null;\n }\n }\n\n if (oSchedule.time?.end) {\n const astroNameEnd = this._getAstroName(oSchedule.time.end);\n if (astroNameEnd && sch.time) {\n sch.time.end = astroNameEnd;\n } else if (oSchedule.time.end.includes(':')) {\n const parts = oSchedule.time.end.split(':');\n if (sch.time) {\n sch.time.end = parseInt(parts[0], 10) * 60 + parseInt(parts[1], 10);\n }\n } else {\n this.log.error(`unknown astro event \"${oSchedule.time.end}\"`);\n return null;\n }\n }\n\n if (sch.time) {\n if (oSchedule.time.mode === 'minutes') {\n sch.time.mode = 60;\n } else if (oSchedule.time.mode === 'hours') {\n sch.time.mode = 3600;\n }\n }\n\n if (oSchedule.period.once) {\n sch.period.once = this.string2date(oSchedule.period.once);\n }\n\n if (oSchedule.valid && sch.valid) {\n if (oSchedule.valid.from) {\n sch.valid.from = this.string2date(oSchedule.valid.from);\n }\n if (oSchedule.valid.to) {\n sch.valid.to = this.string2date(oSchedule.valid.to);\n }\n\n if (this.isPast(context, sch.valid.to)) {\n this.log.warn('End of schedule is in the past');\n return null;\n }\n\n if (typeof oSchedule.period.days === 'number' && oSchedule.period.days > 1 && sch.valid.from) {\n // fromDate must be unix time\n sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d).getTime();\n } else if (typeof oSchedule.period.weeks === 'number' && oSchedule.period.weeks > 1) {\n const fromDate: Date = sch.valid.from\n ? new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d)\n : new this.Date();\n //sch.valid.fromDate.setDate(-sch.valid.fromDate.getDate() - sch.valid.fromDate.getDay());\n // fromDate must be unix time\n sch.valid.fromDate = fromDate.getTime();\n } else if (sch.valid.from && typeof oSchedule.period.months === 'number' && oSchedule.period.months > 1) {\n // fromDate must be object\n sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d);\n } else if (sch.valid.from && typeof oSchedule.period.years === 'number' && oSchedule.period.years > 1) {\n // fromDate must be object\n sch.valid.fromDate = new this.Date(sch.valid.from.y, sch.valid.from.M, sch.valid.from.d);\n }\n }\n if (\n sch.period &&\n ((typeof sch.period.days === 'number' && sch.period.days > 1) ||\n (typeof sch.period.weeks === 'number' && sch.period.weeks > 1) ||\n (typeof sch.period.months === 'number' && sch.period.months > 1) ||\n (typeof sch.period.years === 'number' && sch.period.years > 1)) &&\n (!sch.valid || !sch.valid.fromDate)\n ) {\n this.log.warn(\n 'Invalid Schedule definition: Period day/weeks/months/years only allowed with a valid.from date!',\n );\n return null;\n }\n\n if (oSchedule.period.dows) {\n try {\n sch.period.dows = JSON.parse(oSchedule.period.dows);\n } catch {\n this.log.error(`Cannot parse day of weeks: ${JSON.stringify(sch.period.dows)}`);\n return null;\n }\n if (!Array.isArray(sch.period.dows)) {\n this.log.error(`day of weeks is no array: ${JSON.stringify(sch.period.dows)}`);\n return null;\n }\n }\n\n if (oSchedule.period.months && typeof oSchedule.period.months !== 'number') {\n // can be number or array-string\n try {\n sch.period.months = JSON.parse(oSchedule.period.months) as number[];\n } catch {\n this.log.error(`Cannot parse day of months: ${JSON.stringify(sch.period.months)}`);\n return null;\n }\n sch.period.months = sch.period.months.map(m => m - 1);\n }\n\n if (oSchedule.period.dates) {\n try {\n sch.period.dates = JSON.parse(oSchedule.period.dates) as number[];\n } catch {\n this.log.error(`Cannot parse day of dates: ${JSON.stringify(sch.period.dates)}`);\n return null;\n }\n }\n if (oSchedule.period.yearMonth) {\n sch.period.yearMonth = oSchedule.period.yearMonth - 1;\n }\n this.list[id] = sch;\n this.recalculate();\n return id;\n }\n\n remove(id: string | ScheduleName): boolean {\n if (\n typeof id === 'object' &&\n id.type === 'schedule' &&\n typeof id.id === 'string' &&\n id.id.startsWith('schedule_')\n ) {\n if (this.list[id.id.substring('schedule_'.length)]) {\n delete this.list[id.id.substring('schedule_'.length)];\n this.recalculate();\n return true;\n }\n return false;\n }\n if (typeof id === 'string' && this.list[id]) {\n delete this.list[id];\n this.recalculate();\n return true;\n }\n return false;\n }\n\n getList(): ScheduleName[] {\n return Object.keys(this.list).map(id => ({\n id: `schedule_${id}`,\n type: 'schedule',\n schedule: this.list[id].original,\n scriptName: this.list[id].scriptName,\n }));\n }\n\n get(id: string | ScheduleName): SchedulerRuleParsed | null {\n if (\n id &&\n typeof id === 'object' &&\n id.type === 'schedule' &&\n typeof id.id === 'string' &&\n id.id.startsWith('schedule_')\n ) {\n return this.list[id.id.substring('schedule_'.length)];\n }\n if (typeof id === 'string') {\n return this.list[id];\n }\n return null;\n }\n\n private _setAstroVars(): void {\n const todayNoon = new this.Date();\n const yesterdayNoon = new this.Date();\n todayNoon.setHours(12, 0, 0, 0);\n yesterdayNoon.setHours(-12, 0, 0, 0);\n this.todaysAstroTimes = this.suncalc.getTimes(todayNoon, this.latitude, this.longitude);\n this.yesterdaysAstroTimes = this.suncalc.getTimes(yesterdayNoon, this.latitude, this.longitude);\n }\n\n private _getAstroName(evt: string): AstroEventName | null {\n if (typeof evt === 'string') {\n const pos = (this.astroListLow as string[]).indexOf(evt.toLowerCase() as AstroEventNameLow);\n if (pos > -1) {\n return (this.astroList as string[])[pos] as AstroEventName;\n }\n }\n return null;\n }\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/tools.js b/build-backend/lib/tools.js new file mode 100644 index 00000000..e6aab45d --- /dev/null +++ b/build-backend/lib/tools.js @@ -0,0 +1,185 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.isObject = isObject; +exports.isArray = isArray; +exports.matchAll = matchAll; +exports.enumFilesRecursiveSync = enumFilesRecursiveSync; +exports.promisify = promisify; +exports.promisifyNoError = promisifyNoError; +exports.hashSource = hashSource; +exports.getHttpRequestConfig = getHttpRequestConfig; +const node_fs_1 = require("node:fs"); +const node_path_1 = require("node:path"); +const node_crypto_1 = require("node:crypto"); +const node_https_1 = require("node:https"); +/** + * Tests whether the given variable is a real object and not an Array + * + * @param it The variable to test + */ +function isObject(it) { + // This is necessary because: + // typeof null === 'object' + // typeof [] === 'object' + // [] instanceof Object === true + return Object.prototype.toString.call(it) === '[object Object]'; +} +/** + * Tests whether the given variable is really an Array + * + * @param it The variable to test + */ +function isArray(it) { + return Array.isArray(it); +} +/** + * Finds all matches of a regular expression and returns the matched groups + * + * @param regex The regular expression to match against the string + * @param string The string to test + */ +function matchAll(regex, string) { + const ret = []; + let match; + do { + match = regex.exec(string); + if (match) { + ret.push(match.slice(1)); + } + } while (match); + return ret; +} +/** + * Enumerates all files matching a given predicate + * + * @param rootDir The directory to start in + * @param predicate A function that takes a filename and returns true if the file should be included + */ +function enumFilesRecursiveSync(rootDir, predicate) { + const ret = []; + try { + const filesAndDirs = (0, node_fs_1.readdirSync)(rootDir); + for (const f of filesAndDirs) { + const fullPath = (0, node_path_1.join)(rootDir, f); + if ((0, node_fs_1.statSync)(fullPath).isDirectory()) { + Array.prototype.push.apply(ret, enumFilesRecursiveSync(fullPath, predicate)); + } + else if (typeof predicate === 'function' && predicate(fullPath)) { + ret.push(fullPath); + } + } + } + catch (err) { + console.error(`Cannot read directory: "${rootDir}": ${err}`); + } + return ret; +} +/** + * Promisifies a callback-style function with parameters (err, result) + * + * @param fn The callback-style function to promisify + * @param context The value of `this` in the function + */ +// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type +function promisify(fn, context) { + return function (...args) { + // @ts-expect-error We want this behavior + context = context || this; + return new Promise((resolve, reject) => { + try { + fn.apply(context, [ + ...args, + (error, result) => { + if (error) { + if (typeof error === 'string') { + return reject(new Error(error)); + } + return reject(error); + } + return resolve(result); + }, + ]); + } + catch (error) { + reject(error); + } + }); + }; +} +/** + * Promisifies a callback-style function without an error parameter + * + * @param fn The callback-style function to promisify + * @param context The value of `this` in the function + */ +// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type +function promisifyNoError(fn, context) { + return function (...args) { + // @ts-expect-error We want this behavior + context = context || this; + return new Promise(resolve => { + try { + fn.apply(context, [...args, (result) => resolve(result)]); + } + catch { + resolve(null); // what to do in this case?? + } + }); + }; +} +/** + * Creates an MD5 hash of a script source which can be used to check whether the source of a compiled language changed + * + * @param source The source code to hash + */ +function hashSource(source) { + return (0, node_crypto_1.createHash)('md5').update(source).digest('hex'); +} +function getHttpRequestConfig(url, options) { + options = options || {}; + const timeoutMs = options && !isNaN(options.timeout) ? options.timeout : 2000; + const config = { + method: 'get', + url, + validateStatus: (status) => status >= 200, + responseType: options && options.responseType ? options.responseType : 'text', + responseEncoding: 'utf8', + timeout: timeoutMs, + //signal: AbortSignal.timeout(timeoutMs), // connection related timeouts + }; + options.headers = options.headers || {}; + if (options && options.basicAuth) { + config.auth = { + username: options.basicAuth.user, + password: options.basicAuth.password, + }; + } + else if (options.bearerAuth) { + options.headers.Authorization = `Bearer ${options.bearerAuth}`; + } + else { + const uri = new URL(url); + if (uri.username && uri.password) { + const username = decodeURIComponent(uri.username); + const password = decodeURIComponent(uri.password); + config.url = (config.url || '').replace(`${uri.protocol}//${username}:${password}@`, `${uri.protocol}//`); + config.auth = { + username, + password, + }; + } + } + // Set default headers + config.headers = { + 'User-Agent': 'Mozilla/5.0 (X11; Linux i686; rv:109.0) Gecko/20100101 Firefox/121.0', + ...options.headers, + }; + // Certificate validation + if (options && typeof options?.validateCertificate !== 'undefined') { + config.httpsAgent = new node_https_1.Agent({ + rejectUnauthorized: options.validateCertificate, + }); + } + return config; +} +//# sourceMappingURL=tools.js.map \ No newline at end of file diff --git a/build-backend/lib/tools.js.map b/build-backend/lib/tools.js.map new file mode 100644 index 00000000..7c0c7f39 --- /dev/null +++ b/build-backend/lib/tools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/lib/tools.ts"],"names":[],"mappings":"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","sourcesContent":["import { readdirSync, statSync } from 'node:fs';\nimport { join } from 'node:path';\nimport { createHash } from 'node:crypto';\nimport { Agent } from 'node:https';\nimport type { AxiosRequestConfig, ResponseType } from 'axios';\n\n/**\n * Tests whether the given variable is a real object and not an Array\n *\n * @param it The variable to test\n */\nexport function isObject(it: any): boolean {\n // This is necessary because:\n // typeof null === 'object'\n // typeof [] === 'object'\n // [] instanceof Object === true\n return Object.prototype.toString.call(it) === '[object Object]';\n}\n\n/**\n * Tests whether the given variable is really an Array\n *\n * @param it The variable to test\n */\nexport function isArray(it: any): boolean {\n return Array.isArray(it);\n}\n\n/**\n * Finds all matches of a regular expression and returns the matched groups\n *\n * @param regex The regular expression to match against the string\n * @param string The string to test\n */\nexport function matchAll(regex: RegExp, string: string): string[][] {\n const ret: string[][] = [];\n let match: RegExpExecArray | null;\n do {\n match = regex.exec(string);\n if (match) {\n ret.push(match.slice(1));\n }\n } while (match);\n\n return ret;\n}\n\n/**\n * Enumerates all files matching a given predicate\n *\n * @param rootDir The directory to start in\n * @param predicate A function that takes a filename and returns true if the file should be included\n */\nexport function enumFilesRecursiveSync(rootDir: string, predicate: (filename: string) => boolean): string[] {\n const ret: string[] = [];\n try {\n const filesAndDirs = readdirSync(rootDir);\n for (const f of filesAndDirs) {\n const fullPath = join(rootDir, f);\n\n if (statSync(fullPath).isDirectory()) {\n Array.prototype.push.apply(ret, enumFilesRecursiveSync(fullPath, predicate));\n } else if (typeof predicate === 'function' && predicate(fullPath)) {\n ret.push(fullPath);\n }\n }\n } catch (err: unknown) {\n console.error(`Cannot read directory: \"${rootDir}\": ${err as Error}`);\n }\n\n return ret;\n}\n\n/**\n * Promisifies a callback-style function with parameters (err, result)\n *\n * @param fn The callback-style function to promisify\n * @param context The value of `this` in the function\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function promisify(fn: Function, context?: any): (...args: any[]) => Promise {\n return function (...args) {\n // @ts-expect-error We want this behavior\n context = context || this;\n return new Promise((resolve, reject) => {\n try {\n fn.apply(context, [\n ...args,\n (error: Error | string | null, result: null) => {\n if (error) {\n if (typeof error === 'string') {\n return reject(new Error(error));\n }\n return reject(error);\n }\n return resolve(result);\n },\n ]);\n } catch (error: unknown) {\n reject(error as Error);\n }\n });\n };\n}\n\n/**\n * Promisifies a callback-style function without an error parameter\n *\n * @param fn The callback-style function to promisify\n * @param context The value of `this` in the function\n */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport function promisifyNoError(fn: Function, context: any): (...args: any[]) => Promise {\n return function (...args) {\n // @ts-expect-error We want this behavior\n context = context || this;\n return new Promise(resolve => {\n try {\n fn.apply(context, [...args, (result: any) => resolve(result)]);\n } catch {\n resolve(null); // what to do in this case??\n }\n });\n };\n}\n\n/**\n * Creates an MD5 hash of a script source which can be used to check whether the source of a compiled language changed\n *\n * @param source The source code to hash\n */\nexport function hashSource(source: string | Buffer): string {\n return createHash('md5').update(source).digest('hex');\n}\n\nexport function getHttpRequestConfig(\n url: string,\n options?: {\n timeout?: number;\n responseType?: ResponseType;\n headers?: Record;\n basicAuth?: { user: string; password: string } | null;\n bearerAuth?: string;\n validateCertificate?: boolean;\n },\n): AxiosRequestConfig {\n options = options || {};\n const timeoutMs = options && !isNaN(options.timeout as number) ? options.timeout : 2000;\n\n const config: AxiosRequestConfig = {\n method: 'get',\n url,\n validateStatus: (status: number): boolean => status >= 200,\n responseType: options && options.responseType ? options.responseType : 'text',\n responseEncoding: 'utf8',\n timeout: timeoutMs,\n //signal: AbortSignal.timeout(timeoutMs), // connection related timeouts\n };\n\n options.headers = options.headers || {};\n\n if (options && options.basicAuth) {\n config.auth = {\n username: options.basicAuth.user,\n password: options.basicAuth.password,\n };\n } else if (options.bearerAuth) {\n options.headers.Authorization = `Bearer ${options.bearerAuth}`;\n } else {\n const uri = new URL(url);\n if (uri.username && uri.password) {\n const username = decodeURIComponent(uri.username);\n const password = decodeURIComponent(uri.password);\n\n config.url = (config.url || '').replace(`${uri.protocol}//${username}:${password}@`, `${uri.protocol}//`);\n config.auth = {\n username,\n password,\n };\n }\n }\n\n // Set default headers\n config.headers = {\n 'User-Agent': 'Mozilla/5.0 (X11; Linux i686; rv:109.0) Gecko/20100101 Firefox/121.0',\n ...options.headers,\n };\n\n // Certificate validation\n if (options && typeof options?.validateCertificate !== 'undefined') {\n config.httpsAgent = new Agent({\n rejectUnauthorized: options.validateCertificate,\n });\n }\n\n return config;\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/typescriptSettings.js b/build-backend/lib/typescriptSettings.js new file mode 100644 index 00000000..167d6d45 --- /dev/null +++ b/build-backend/lib/typescriptSettings.js @@ -0,0 +1,35 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.jsDeclarationCompilerOptions = exports.tsCompilerOptions = exports.targetTsLib = void 0; +const typescript_1 = require("typescript"); +// Node.js 18+ supports the features of ES2022 +// consider changing this, so we get to support the newest features too +exports.targetTsLib = 'es2022'; +exports.tsCompilerOptions = { + // don't compile faulty scripts + noEmitOnError: true, + // emit declarations for global scripts + declaration: true, + // This enables TS users to `import * as ... from` and `import ... from` + esModuleInterop: true, + // This flag was introduced in TS 4.4 and may break a lot of legacy scripts + // Better keep it turned off + useUnknownInCatchVariables: false, + // In order to run scripts as a Node.js vm.Script, + // we MUST target ES5, otherwise the compiled + // scripts may include `import` keywords, which are not + // supported by vm.Script. + target: typescript_1.ScriptTarget.ES5, + // This is required for QueryResults to be iterable (https://github.com/ioBroker/ioBroker.javascript/pull/663#issuecomment-721645705) + downlevelIteration: true, + lib: [`lib.${exports.targetTsLib}.d.ts`], +}; +exports.jsDeclarationCompilerOptions = Object.assign({}, exports.tsCompilerOptions, { + // we only care about the declarations + emitDeclarationOnly: true, + // allow errors + noEmitOnError: false, + noImplicitAny: false, + strict: false, +}); +//# sourceMappingURL=typescriptSettings.js.map \ No newline at end of file diff --git a/build-backend/lib/typescriptSettings.js.map b/build-backend/lib/typescriptSettings.js.map new file mode 100644 index 00000000..21ac24af --- /dev/null +++ b/build-backend/lib/typescriptSettings.js.map @@ -0,0 +1 @@ +{"version":3,"file":"typescriptSettings.js","sourceRoot":"","sources":["../../src/lib/typescriptSettings.ts"],"names":[],"mappings":";;;AAAA,2CAAgE;AAEhE,8CAA8C;AAC9C,uEAAuE;AAC1D,QAAA,WAAW,GAAG,QAAQ,CAAC;AAEvB,QAAA,iBAAiB,GAAoB;IAC9C,+BAA+B;IAC/B,aAAa,EAAE,IAAI;IACnB,uCAAuC;IACvC,WAAW,EAAE,IAAI;IACjB,wEAAwE;IACxE,eAAe,EAAE,IAAI;IACrB,2EAA2E;IAC3E,4BAA4B;IAC5B,0BAA0B,EAAE,KAAK;IACjC,kDAAkD;IAClD,6CAA6C;IAC7C,uDAAuD;IACvD,0BAA0B;IAC1B,MAAM,EAAE,yBAAY,CAAC,GAAG;IACxB,qIAAqI;IACrI,kBAAkB,EAAE,IAAI;IACxB,GAAG,EAAE,CAAC,OAAO,mBAAW,OAAO,CAAC;CACnC,CAAC;AAEW,QAAA,4BAA4B,GAAoB,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,yBAAiB,EAAE;IAC9F,sCAAsC;IACtC,mBAAmB,EAAE,IAAI;IACzB,eAAe;IACf,aAAa,EAAE,KAAK;IACpB,aAAa,EAAE,KAAK;IACpB,MAAM,EAAE,KAAK;CAChB,CAAC,CAAC","sourcesContent":["import { type CompilerOptions, ScriptTarget } from 'typescript';\n\n// Node.js 18+ supports the features of ES2022\n// consider changing this, so we get to support the newest features too\nexport const targetTsLib = 'es2022';\n\nexport const tsCompilerOptions: CompilerOptions = {\n // don't compile faulty scripts\n noEmitOnError: true,\n // emit declarations for global scripts\n declaration: true,\n // This enables TS users to `import * as ... from` and `import ... from`\n esModuleInterop: true,\n // This flag was introduced in TS 4.4 and may break a lot of legacy scripts\n // Better keep it turned off\n useUnknownInCatchVariables: false,\n // In order to run scripts as a Node.js vm.Script,\n // we MUST target ES5, otherwise the compiled\n // scripts may include `import` keywords, which are not\n // supported by vm.Script.\n target: ScriptTarget.ES5,\n // This is required for QueryResults to be iterable (https://github.com/ioBroker/ioBroker.javascript/pull/663#issuecomment-721645705)\n downlevelIteration: true,\n lib: [`lib.${targetTsLib}.d.ts`],\n};\n\nexport const jsDeclarationCompilerOptions: CompilerOptions = Object.assign({}, tsCompilerOptions, {\n // we only care about the declarations\n emitDeclarationOnly: true,\n // allow errors\n noEmitOnError: false,\n noImplicitAny: false,\n strict: false,\n});\n"]} \ No newline at end of file diff --git a/build-backend/lib/typescriptTools.js b/build-backend/lib/typescriptTools.js new file mode 100644 index 00000000..4c74e08f --- /dev/null +++ b/build-backend/lib/typescriptTools.js @@ -0,0 +1,432 @@ +'use strict'; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.resolveTypescriptLibs = resolveTypescriptLibs; +exports.resolveTypings = resolveTypings; +exports.transformScriptBeforeCompilation = transformScriptBeforeCompilation; +exports.transformGlobalDeclarations = transformGlobalDeclarations; +exports.scriptIdToTSFilename = scriptIdToTSFilename; +const node_fs_1 = require("node:fs"); +const node_path_1 = require("node:path"); +const typescript_1 = require("typescript"); +const tools_1 = require("./tools"); +/** + * Resolves all TypeScript lib files for the editor + * + * @param targetLib The lib to target (e.g., es2017) + */ +function resolveTypescriptLibs(targetLib) { + const typescriptLibRoot = (0, node_path_1.dirname)(require.resolve(`typescript/lib/lib.d.ts`)); + const ret = {}; + const libReferenceRegex = /\/\/\/ /g; + const matchAllLibs = (str) => (0, tools_1.matchAll)(libReferenceRegex, str).map(groups => groups[0]); + const libQueue = [targetLib]; + while (libQueue.length > 0) { + const libName = libQueue.shift(); + const filename = `lib.${libName}.d.ts`; + // Read the file and remember it in the return dictionary + const fileContent = (0, node_fs_1.readFileSync)((0, node_path_1.join)(typescriptLibRoot, filename), 'utf8'); + ret[filename] = fileContent; + // If this file references another lib file, we need to load that too + // A reference looks like this: /// + // Find all libs we have not loaded yet + matchAllLibs(fileContent) + .filter(lib => !(`lib.${lib}.d.ts` in ret)) + .forEach(lib => libQueue.push(lib)); + } + return ret; +} +function normalizeDTSImport(filename) { + // An import is either... + // a normal import + if (filename.endsWith('.d.ts')) { + return filename; + } + // an extensionless import + if ((0, node_fs_1.existsSync)(`${filename}.d.ts`)) { + return `${filename}.d.ts`; + } + // or a directory import + return (0, node_path_1.join)(filename, 'index.d.ts'); +} +/** + * Resolves the type declarations of a 3rd party package for the editor + * + * @param pkg The package whose typings we're interested in + * @param adapterScopedPackageName the package name on the system + * @param wrapInDeclareModule Whether the root file should be wrapped in `declare module "" { ... }` + * @returns The found declarations or undefined if none were found + */ +function resolveTypings(pkg, adapterScopedPackageName, wrapInDeclareModule) { + let packageJsonPath; + let packageJson; + let rootTypings; + let pkgIncludesTypings = true; + function tryToLoadPackage(path) { + try { + packageJsonPath = require.resolve(path); + packageJson = require(packageJsonPath); + rootTypings = + typeof packageJson.types === 'string' + ? packageJson.types + : typeof packageJson.typings === 'string' + ? packageJson.typings + : undefined; + } + catch { + /* ignore */ + } + } + // First, try to resolve the package itself in case it brings its own typings + tryToLoadPackage(`${adapterScopedPackageName}/package.json`); + // If that didn't work, try again with the @types version of the package + if (!rootTypings) { + tryToLoadPackage(`@types/${pkg}/package.json`); + pkgIncludesTypings = false; + } + // TODO: If that didn't work, download @types/ and retry the previous step + // Nothing to do here since we found no packages + if (!rootTypings) { + return undefined; + } + if (!packageJsonPath) { + return undefined; + } + const packageRoot = (0, node_path_1.dirname)(packageJsonPath); + const normalizeImportPath = (filename) => (0, node_path_1.normalize)(`node_modules/${pkgIncludesTypings ? adapterScopedPackageName : `@types/${pkg}`}/${(0, node_path_1.relative)(packageRoot, filename)}`).replace(/\\/g, '/'); + const ret = {}; + // We need to look at `import/export ... from 'modulename'` and `/// ` + const importDtsRegex = /^\s*(?:import|export) .+ from ["'](\.+\/[^"']+)["']/g; + const pathReferenceRegex = /\/\/\/ /g; + const matchAllImports = (str) => [...(0, tools_1.matchAll)(importDtsRegex, str), ...(0, tools_1.matchAll)(pathReferenceRegex, str)].map(groups => groups[0]); + // the paths are relative to the package.json - we need an absolute path to read the files + rootTypings = (0, node_path_1.join)(packageRoot, rootTypings); + // some @types packages specify `index` as their typings file instead of `index.d.ts` + rootTypings = normalizeDTSImport(rootTypings); + // include package.json in typings, so TypeScript can look up the correct entry point + const relativePath = `node_modules/${pkgIncludesTypings ? '' : '@types/'}${pkg}/package.json`.replace(/\\/g, '/'); + ret[relativePath] = JSON.stringify(packageJson); + // Used to test whether a .d.ts file already uses "declare module" or not + const declareModuleRegex = /^\s*declare module/gm; + // recursively load all typings + const definitionQueue = [rootTypings]; + while (definitionQueue.length > 0) { + const filename = definitionQueue.shift(); + const dirName = (0, node_path_1.dirname)(filename); + // Read the file and remember it in the return dictionary + let fileContent; + try { + fileContent = (0, node_fs_1.readFileSync)(filename, 'utf8'); + } + catch (e) { + // The typings are malformed + console.error(`Failed to load definitions for ${pkg}: ${e.toString()}`); + // Since we cannot use them, return undefined + return undefined; + } + // We need to store the filename relative to the base dir + const relativePath = normalizeImportPath(filename); + // If necessary, wrap the root typings (only those!) + ret[relativePath] = + wrapInDeclareModule && filename === rootTypings && !declareModuleRegex.test(fileContent) + ? `declare module "${pkg}" { ${fileContent} }` + : fileContent; + // If this file references another .d.ts file, we need to load that too + matchAllImports(fileContent) + // resolve the file relative to the current directory + .map(file => (0, node_path_1.join)(dirName, file)) + // find out the correct path of the file we want to import + .map(normalizeDTSImport) + // Find all libs we have not loaded yet + .filter(file => !(normalizeImportPath(file) in ret)) + .forEach(file => definitionQueue.push(file)); + } + // Avoid returning empty declarations + if (Object.keys(ret).length === 0) { + return undefined; + } + return ret; +} +/** + * @param s + * @param isGlobal Whether this is a global script or a normal one + */ +function mustBeHoisted(s, isGlobal) { + return !!( + // Import/export statements must be moved to the top + ((0, typescript_1.isImportDeclaration)(s) || + (0, typescript_1.isImportEqualsDeclaration)(s) || + (0, typescript_1.isExportDeclaration)(s) || + (0, typescript_1.isExportAssignment)(s) || + // as well as many declarations + (0, typescript_1.isTypeAliasDeclaration)(s) || + (0, typescript_1.isInterfaceDeclaration)(s) || + (0, typescript_1.isModuleDeclaration)(s) || + (0, typescript_1.isEnumDeclaration)(s) || + (isGlobal && + // in global scripts we don't wrap classes and functions, so they can be accessed from non-global scripts + ((0, typescript_1.isClassDeclaration)(s) || (0, typescript_1.isFunctionDeclaration)(s))) || + // and declare ... / export ... statements + s.modifiers?.some(s => s.kind === typescript_1.SyntaxKind.DeclareKeyword || s.kind === typescript_1.SyntaxKind.ExportKeyword))); +} +function canBeExported(s) { + return ( + // const, let, var + (0, typescript_1.isVariableStatement)(s) || + // type, interface, enum, class, function + (0, typescript_1.isTypeAliasDeclaration)(s) || + (0, typescript_1.isInterfaceDeclaration)(s) || + (0, typescript_1.isEnumDeclaration)(s) || + (0, typescript_1.isClassDeclaration)(s) || + (0, typescript_1.isFunctionDeclaration)(s)); +} +function addExportModifier(s) { + let modifiers; + // Add export modifiers + if (!s.modifiers) { + modifiers = [typescript_1.factory.createModifier(typescript_1.SyntaxKind.ExportKeyword)]; + } + else if (!s.modifiers.some(m => m.kind === typescript_1.SyntaxKind.ExportKeyword)) { + modifiers = [...s.modifiers, typescript_1.factory.createModifier(typescript_1.SyntaxKind.ExportKeyword)]; + } + else { + return s; + } + if ((0, typescript_1.isVariableStatement)(s)) { + return typescript_1.factory.updateVariableStatement(s, modifiers, s.declarationList); + } + if ((0, typescript_1.isTypeAliasDeclaration)(s)) { + return typescript_1.factory.updateTypeAliasDeclaration(s, modifiers, s.name, s.typeParameters, s.type); + } + if ((0, typescript_1.isInterfaceDeclaration)(s)) { + return typescript_1.factory.updateInterfaceDeclaration(s, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members); + } + if ((0, typescript_1.isEnumDeclaration)(s)) { + return typescript_1.factory.updateEnumDeclaration(s, modifiers, s.name, s.members); + } + if ((0, typescript_1.isClassDeclaration)(s)) { + return typescript_1.factory.updateClassDeclaration(s, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members); + } + if ((0, typescript_1.isFunctionDeclaration)(s)) { + return typescript_1.factory.updateFunctionDeclaration(s, modifiers, s.asteriskToken, s.name, s.typeParameters, s.parameters, s.type, s.body); + } + return s; +} +function removeDeclareModifier(s) { + let modifiers; + // Remove declare modifiers + if (s.modifiers) { + modifiers = s.modifiers.filter(m => m.kind !== typescript_1.SyntaxKind.DeclareKeyword); + } + else { + return s; + } + if ((0, typescript_1.isVariableStatement)(s)) { + return typescript_1.factory.updateVariableStatement(s, modifiers, s.declarationList); + } + if ((0, typescript_1.isTypeAliasDeclaration)(s)) { + return typescript_1.factory.updateTypeAliasDeclaration(s, modifiers, s.name, s.typeParameters, s.type); + } + if ((0, typescript_1.isInterfaceDeclaration)(s)) { + return typescript_1.factory.updateInterfaceDeclaration(s, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members); + } + if ((0, typescript_1.isEnumDeclaration)(s)) { + return typescript_1.factory.updateEnumDeclaration(s, modifiers, s.name, s.members); + } + if ((0, typescript_1.isClassDeclaration)(s)) { + return typescript_1.factory.updateClassDeclaration(s, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members); + } + if ((0, typescript_1.isFunctionDeclaration)(s)) { + return typescript_1.factory.updateFunctionDeclaration(s, modifiers, s.asteriskToken, s.name, s.typeParameters, s.parameters, s.type, s.body); + } + return s; +} +// taken from node_modules\@types\node\globals.d.ts +// the globally available things must be wrapped in `declare global` if the user wants to augment them +const NodeJSGlobals = [ + 'Array', + 'ArrayBuffer', + 'Boolean', + 'Buffer', + 'DataView', + 'Date', + 'Error', + 'EvalError', + 'Float32Array', + 'Float64Array', + 'Function', + 'GLOBAL', + 'Infinity', + 'Int16Array', + 'Int32Array', + 'Int8Array', + 'Intl', + 'JSON', + 'Map', + 'Math', + 'NaN', + 'Number', + 'Object', + 'Promise', + 'RangeError', + 'ReferenceError', + 'RegExp', + 'Set', + 'String', + 'Symbol', + 'SyntaxError', + 'TypeError', + 'URIError', + 'Uint16Array', + 'Uint32Array', + 'Uint8Array', + 'Uint8ClampedArray', + 'WeakMap', + 'WeakSet', + 'clearImmediate', + 'clearInterval', + 'clearTimeout', + 'console', + 'decodeURI', + 'decodeURIComponent', + 'encodeURI', + 'encodeURIComponent', + 'escape', + 'eval', + 'global', + 'isFinite', + 'isNaN', + 'parseFloat', + 'parseInt', + 'process', + 'root', + 'setImmediate', + 'setInterval', + 'setTimeout', + 'queueMicrotask', + 'undefined', + 'unescape', + 'gc', + 'v8debug', +]; +function isGlobalAugmentation(s) { + return !!(((0, typescript_1.isInterfaceDeclaration)(s) || (0, typescript_1.isClassDeclaration)(s) || (0, typescript_1.isFunctionDeclaration)(s)) && + s.name && + NodeJSGlobals.includes(s.name.text)); +} +function wrapInDeclareGlobal(statements) { + return typescript_1.factory.createModuleDeclaration([typescript_1.factory.createModifier(typescript_1.SyntaxKind.DeclareKeyword)], typescript_1.factory.createIdentifier('global'), typescript_1.factory.createModuleBlock(statements), typescript_1.NodeFlags.GlobalAugmentation); +} +/** + * Takes a TypeScript script and does the necessary transformations, so it can be compiled properly + * + * @param source The original TypeScript source + * @param isGlobal Whether the transformed script is a global script or not + */ +function transformScriptBeforeCompilation(source, isGlobal) { + const transformer = (_context) => { + return (sourceFile) => (0, typescript_1.visitNode)(sourceFile, (node) => { + if ((0, typescript_1.isSourceFile)(node)) { + // Wrap all declarations that augment global interfaces in `declare global` + const augmentations = node.statements.filter(s => isGlobalAugmentation(s)); + const nonAugmentations = node.statements.filter(s => !isGlobalAugmentation(s)); + // If there is no top level await, don't move all the statements around + const hasTLA = node.statements.some(s => (0, typescript_1.isExpressionStatement)(s) && s.expression.kind === typescript_1.SyntaxKind.AwaitExpression); + // Move all statements to the top of the file that cannot appear in a function body + let hoistedStatements = hasTLA + ? typescript_1.factory.createNodeArray(nonAugmentations.filter(s => mustBeHoisted(s, isGlobal))) + : typescript_1.factory.createNodeArray(nonAugmentations); + // The rest gets wrapped + const wrappedStatements = hasTLA ? nonAugmentations.filter(s => !mustBeHoisted(s, isGlobal)) : []; + // When transforming global scripts, we need to do a couple of things + if (isGlobal) { + // 1. We need to add an export modifier to everything at the top level that can be exported + hoistedStatements = (0, typescript_1.visitNodes)(hoistedStatements, + // @ts-expect-error s is definitely a Statement + s => (canBeExported(s) ? addExportModifier(s) : s)); + // 3. We need to transform the generated declarations to use `declare global` (this will happen in transformGlobalDeclarations) + } + const needsEmptyExport = + // An empty export is necessary when there is no import declaration + !node.statements.some(s => (0, typescript_1.isImportDeclaration)(s) || (0, typescript_1.isImportEqualsDeclaration)(s)) && + // And there is no statement in a global script which had an export modifier added + (!(isGlobal && + hoistedStatements.some( + // @ts-expect-error s should have modifiers + s => s.modifiers?.some(m => m.kind === typescript_1.SyntaxKind.ExportKeyword))) || + // Or if there is a `declare global` statement + !!augmentations); + return typescript_1.factory.updateSourceFile(node, [ + // Put the hoisted statements at the top (or all of them if there's no top level await) + ...hoistedStatements, + // Then add everything that augments the global scope + ...(augmentations && augmentations.length ? [wrapInDeclareGlobal(augmentations)] : []), + ...(hasTLA + ? // If there is a top-level await, wrap all non-hoisted statements in (async () => { ... })(); + [ + typescript_1.factory.createExpressionStatement(typescript_1.factory.createCallExpression(typescript_1.factory.createArrowFunction([typescript_1.factory.createModifier(typescript_1.SyntaxKind.AsyncKeyword)], undefined, [], undefined, undefined, typescript_1.factory.createBlock(wrappedStatements)), undefined, undefined)), + ] + : []), + ...(needsEmptyExport + ? [ + // Put an empty export {}; at the bottom to force TypeScript to treat the script as a module + typescript_1.factory.createExportDeclaration(undefined, // ModifierLike[] | undefined + false, // isTypeOnly + typescript_1.factory.createNamedExports([]), // NamedExportBindings | undefined + undefined, // moduleSpecifier + undefined), + ] + : []), + ]); + } + return node; + }); + }; + const sourceFile = (0, typescript_1.createSourceFile)('index.ts', source, typescript_1.ScriptTarget.ESNext, /* setParentNodes */ true); + const result = (0, typescript_1.transform)(sourceFile, [transformer]); + return (0, typescript_1.createPrinter)().printNode(typescript_1.EmitHint.Unspecified, result.transformed[0], sourceFile); +} +/** + * Takes the global declarations for a TypeScript and wraps export statements in `declare global` + * + * @param decl The untransformed global declarations + */ +function transformGlobalDeclarations(decl) { + const transformer = (_context) => { + return (sourceFile) => (0, typescript_1.visitNode)(sourceFile, (node) => { + if ((0, typescript_1.isSourceFile)(node)) { + // All non-export-statements stay at the root level, the rest is wrapped in `declare global` + const exportStatements = node.statements.filter( + // @ts-expect-error s should have modifiers + s => s.modifiers?.some(m => m.kind === typescript_1.SyntaxKind.ExportKeyword)); + const otherStatements = node.statements.filter(s => !exportStatements.includes(s)); + const hasExportStatements = exportStatements.length > 0; + const hasImport = otherStatements.some(s => (0, typescript_1.isImportDeclaration)(s) || (0, typescript_1.isImportEqualsDeclaration)(s)); + return typescript_1.factory.updateSourceFile(node, [ + ...otherStatements, + ...(hasExportStatements + ? [wrapInDeclareGlobal(exportStatements.map(s => removeDeclareModifier(s)))] + : []), + ...(hasImport + ? [] // If there is an import, the script is already treated as a module + : [ + // Otherwise, put an empty export {}; at the bottom to force TypeScript to treat the script as a module + typescript_1.factory.createExportDeclaration(undefined, false, typescript_1.factory.createNamedExports([]), undefined, undefined), + ]), + ]); + } + return node; + }); + }; + const sourceFile = (0, typescript_1.createSourceFile)('index.d.ts', decl, typescript_1.ScriptTarget.ESNext, /* setParentNodes */ true); + const result = (0, typescript_1.transform)(sourceFile, [transformer]); + return (0, typescript_1.createPrinter)().printNode(typescript_1.EmitHint.Unspecified, result.transformed[0], sourceFile); +} +/** + * Translates a script ID to a filename for the compiler + * + * @param scriptID The ID of the script + */ +function scriptIdToTSFilename(scriptID) { + return `${scriptID.replace(/^script.js./, '').replace(/\./g, '/')}.ts`; +} +//# sourceMappingURL=typescriptTools.js.map \ No newline at end of file diff --git a/build-backend/lib/typescriptTools.js.map b/build-backend/lib/typescriptTools.js.map new file mode 100644 index 00000000..8ff0eaf4 --- /dev/null +++ b/build-backend/lib/typescriptTools.js.map @@ -0,0 +1 @@ +{"version":3,"file":"typescriptTools.js","sourceRoot":"","sources":["../../src/lib/typescriptTools.ts"],"names":[],"mappings":"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","sourcesContent":["'use strict';\n\nimport { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join, normalize, relative } from 'node:path';\nimport {\n type Statement,\n isImportDeclaration,\n isImportEqualsDeclaration,\n isExportDeclaration,\n isExportAssignment,\n isTypeAliasDeclaration,\n isInterfaceDeclaration,\n isModuleDeclaration,\n isEnumDeclaration,\n isClassDeclaration,\n isFunctionDeclaration,\n isVariableStatement,\n isExpressionStatement,\n createSourceFile,\n createPrinter,\n transform,\n ScriptTarget,\n factory,\n SyntaxKind,\n type Modifier,\n NodeFlags,\n type ModuleDeclaration,\n visitNode,\n visitNodes,\n isSourceFile,\n EmitHint,\n type NodeArray,\n type TransformerFactory,\n type SourceFile,\n type TransformationContext,\n type Transformer,\n} from 'typescript';\nimport { matchAll } from './tools';\n\n/**\n * Resolves all TypeScript lib files for the editor\n *\n * @param targetLib The lib to target (e.g., es2017)\n */\nexport function resolveTypescriptLibs(\n targetLib: 'es2017' | 'es2018' | 'es2019' | 'es2020' | 'es2021' | 'es2022' | 'esnext',\n): Record {\n const typescriptLibRoot = dirname(require.resolve(`typescript/lib/lib.d.ts`));\n const ret: Record = {};\n\n const libReferenceRegex = /\\/\\/\\/ /g;\n const matchAllLibs = (str: string): string[] => matchAll(libReferenceRegex, str).map(groups => groups[0]);\n\n const libQueue: string[] = [targetLib];\n while (libQueue.length > 0) {\n const libName = libQueue.shift();\n const filename = `lib.${libName}.d.ts`;\n // Read the file and remember it in the return dictionary\n const fileContent = readFileSync(join(typescriptLibRoot, filename), 'utf8');\n ret[filename] = fileContent;\n // If this file references another lib file, we need to load that too\n // A reference looks like this: /// \n // Find all libs we have not loaded yet\n matchAllLibs(fileContent)\n .filter(lib => !(`lib.${lib}.d.ts` in ret))\n .forEach(lib => libQueue.push(lib));\n }\n\n return ret;\n}\n\nfunction normalizeDTSImport(filename: string): string {\n // An import is either...\n // a normal import\n if (filename.endsWith('.d.ts')) {\n return filename;\n }\n // an extensionless import\n if (existsSync(`${filename}.d.ts`)) {\n return `${filename}.d.ts`;\n }\n // or a directory import\n return join(filename, 'index.d.ts');\n}\n\n/**\n * Resolves the type declarations of a 3rd party package for the editor\n *\n * @param pkg The package whose typings we're interested in\n * @param adapterScopedPackageName the package name on the system\n * @param wrapInDeclareModule Whether the root file should be wrapped in `declare module \"\" { ... }`\n * @returns The found declarations or undefined if none were found\n */\nexport function resolveTypings(\n pkg: string,\n adapterScopedPackageName: string,\n wrapInDeclareModule?: boolean,\n): Record | undefined {\n let packageJsonPath: string | undefined;\n let packageJson: Record | undefined;\n let rootTypings: string | undefined;\n let pkgIncludesTypings = true;\n\n function tryToLoadPackage(path: string): void {\n try {\n packageJsonPath = require.resolve(path);\n packageJson = require(packageJsonPath);\n rootTypings =\n typeof (packageJson as Record).types === 'string'\n ? (packageJson as Record).types\n : typeof (packageJson as Record).typings === 'string'\n ? (packageJson as Record).typings\n : undefined;\n } catch {\n /* ignore */\n }\n }\n\n // First, try to resolve the package itself in case it brings its own typings\n tryToLoadPackage(`${adapterScopedPackageName}/package.json`);\n\n // If that didn't work, try again with the @types version of the package\n if (!rootTypings) {\n tryToLoadPackage(`@types/${pkg}/package.json`);\n pkgIncludesTypings = false;\n }\n // TODO: If that didn't work, download @types/ and retry the previous step\n\n // Nothing to do here since we found no packages\n if (!rootTypings) {\n return undefined;\n }\n\n if (!packageJsonPath) {\n return undefined;\n }\n\n const packageRoot: string = dirname(packageJsonPath);\n const normalizeImportPath = (filename: string): string =>\n normalize(\n `node_modules/${pkgIncludesTypings ? adapterScopedPackageName : `@types/${pkg}`}/${relative(packageRoot, filename)}`,\n ).replace(/\\\\/g, '/');\n\n const ret: Record = {};\n\n // We need to look at `import/export ... from 'modulename'` and `/// `\n const importDtsRegex = /^\\s*(?:import|export) .+ from [\"'](\\.+\\/[^\"']+)[\"']/g;\n const pathReferenceRegex = /\\/\\/\\/ /g;\n const matchAllImports = (str: string): string[] =>\n [...matchAll(importDtsRegex, str), ...matchAll(pathReferenceRegex, str)].map(groups => groups[0]);\n\n // the paths are relative to the package.json - we need an absolute path to read the files\n rootTypings = join(packageRoot, rootTypings);\n // some @types packages specify `index` as their typings file instead of `index.d.ts`\n rootTypings = normalizeDTSImport(rootTypings);\n\n // include package.json in typings, so TypeScript can look up the correct entry point\n const relativePath = `node_modules/${pkgIncludesTypings ? '' : '@types/'}${pkg}/package.json`.replace(/\\\\/g, '/');\n ret[relativePath] = JSON.stringify(packageJson);\n\n // Used to test whether a .d.ts file already uses \"declare module\" or not\n const declareModuleRegex = /^\\s*declare module/gm;\n\n // recursively load all typings\n const definitionQueue = [rootTypings];\n while (definitionQueue.length > 0) {\n const filename: string = definitionQueue.shift() as string;\n const dirName = dirname(filename);\n // Read the file and remember it in the return dictionary\n let fileContent: string;\n try {\n fileContent = readFileSync(filename, 'utf8');\n } catch (e: any) {\n // The typings are malformed\n console.error(`Failed to load definitions for ${pkg}: ${e.toString()}`);\n // Since we cannot use them, return undefined\n return undefined;\n }\n // We need to store the filename relative to the base dir\n const relativePath = normalizeImportPath(filename);\n // If necessary, wrap the root typings (only those!)\n ret[relativePath] =\n wrapInDeclareModule && filename === rootTypings && !declareModuleRegex.test(fileContent)\n ? `declare module \"${pkg}\" { ${fileContent} }`\n : fileContent;\n // If this file references another .d.ts file, we need to load that too\n matchAllImports(fileContent)\n // resolve the file relative to the current directory\n .map(file => join(dirName, file))\n // find out the correct path of the file we want to import\n .map(normalizeDTSImport)\n // Find all libs we have not loaded yet\n .filter(file => !(normalizeImportPath(file) in ret))\n .forEach(file => definitionQueue.push(file));\n }\n // Avoid returning empty declarations\n if (Object.keys(ret).length === 0) {\n return undefined;\n }\n return ret;\n}\n\n/**\n * @param s\n * @param isGlobal Whether this is a global script or a normal one\n */\nfunction mustBeHoisted(s: Statement & { modifiers?: Modifier[] }, isGlobal?: boolean): boolean {\n return !!(\n // Import/export statements must be moved to the top\n (\n isImportDeclaration(s) ||\n isImportEqualsDeclaration(s) ||\n isExportDeclaration(s) ||\n isExportAssignment(s) ||\n // as well as many declarations\n isTypeAliasDeclaration(s) ||\n isInterfaceDeclaration(s) ||\n isModuleDeclaration(s) ||\n isEnumDeclaration(s) ||\n (isGlobal &&\n // in global scripts we don't wrap classes and functions, so they can be accessed from non-global scripts\n (isClassDeclaration(s) || isFunctionDeclaration(s))) ||\n // and declare ... / export ... statements\n s.modifiers?.some(s => s.kind === SyntaxKind.DeclareKeyword || s.kind === SyntaxKind.ExportKeyword)\n )\n );\n}\n\nfunction canBeExported(s: Statement): boolean {\n return (\n // const, let, var\n isVariableStatement(s) ||\n // type, interface, enum, class, function\n isTypeAliasDeclaration(s) ||\n isInterfaceDeclaration(s) ||\n isEnumDeclaration(s) ||\n isClassDeclaration(s) ||\n isFunctionDeclaration(s)\n );\n}\n\nfunction addExportModifier(s: Statement & { modifiers?: Modifier[] }): Statement {\n let modifiers: Modifier[] | undefined;\n // Add export modifiers\n if (!s.modifiers) {\n modifiers = [factory.createModifier(SyntaxKind.ExportKeyword)];\n } else if (!s.modifiers.some(m => m.kind === SyntaxKind.ExportKeyword)) {\n modifiers = [...s.modifiers, factory.createModifier(SyntaxKind.ExportKeyword)];\n } else {\n return s;\n }\n\n if (isVariableStatement(s)) {\n return factory.updateVariableStatement(s, modifiers, s.declarationList);\n }\n if (isTypeAliasDeclaration(s)) {\n return factory.updateTypeAliasDeclaration(s, modifiers, s.name, s.typeParameters, s.type);\n }\n if (isInterfaceDeclaration(s)) {\n return factory.updateInterfaceDeclaration(s, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members);\n }\n if (isEnumDeclaration(s)) {\n return factory.updateEnumDeclaration(s, modifiers, s.name, s.members);\n }\n if (isClassDeclaration(s)) {\n return factory.updateClassDeclaration(s, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members);\n }\n if (isFunctionDeclaration(s)) {\n return factory.updateFunctionDeclaration(\n s,\n modifiers,\n s.asteriskToken,\n s.name,\n s.typeParameters,\n s.parameters,\n s.type,\n s.body,\n );\n }\n return s;\n}\n\nfunction removeDeclareModifier(s: Statement & { modifiers?: Modifier[] }): Statement {\n let modifiers: Modifier[] | undefined;\n // Remove declare modifiers\n if (s.modifiers) {\n modifiers = s.modifiers.filter(m => m.kind !== SyntaxKind.DeclareKeyword);\n } else {\n return s;\n }\n\n if (isVariableStatement(s)) {\n return factory.updateVariableStatement(s, modifiers, s.declarationList);\n }\n if (isTypeAliasDeclaration(s)) {\n return factory.updateTypeAliasDeclaration(s, modifiers, s.name, s.typeParameters, s.type);\n }\n if (isInterfaceDeclaration(s)) {\n return factory.updateInterfaceDeclaration(s, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members);\n }\n if (isEnumDeclaration(s)) {\n return factory.updateEnumDeclaration(s, modifiers, s.name, s.members);\n }\n if (isClassDeclaration(s)) {\n return factory.updateClassDeclaration(s, modifiers, s.name, s.typeParameters, s.heritageClauses, s.members);\n }\n if (isFunctionDeclaration(s)) {\n return factory.updateFunctionDeclaration(\n s,\n modifiers,\n s.asteriskToken,\n s.name,\n s.typeParameters,\n s.parameters,\n s.type,\n s.body,\n );\n }\n\n return s;\n}\n\n// taken from node_modules\\@types\\node\\globals.d.ts\n// the globally available things must be wrapped in `declare global` if the user wants to augment them\nconst NodeJSGlobals = [\n 'Array',\n 'ArrayBuffer',\n 'Boolean',\n 'Buffer',\n 'DataView',\n 'Date',\n 'Error',\n 'EvalError',\n 'Float32Array',\n 'Float64Array',\n 'Function',\n 'GLOBAL',\n 'Infinity',\n 'Int16Array',\n 'Int32Array',\n 'Int8Array',\n 'Intl',\n 'JSON',\n 'Map',\n 'Math',\n 'NaN',\n 'Number',\n 'Object',\n 'Promise',\n 'RangeError',\n 'ReferenceError',\n 'RegExp',\n 'Set',\n 'String',\n 'Symbol',\n 'SyntaxError',\n 'TypeError',\n 'URIError',\n 'Uint16Array',\n 'Uint32Array',\n 'Uint8Array',\n 'Uint8ClampedArray',\n 'WeakMap',\n 'WeakSet',\n 'clearImmediate',\n 'clearInterval',\n 'clearTimeout',\n 'console',\n 'decodeURI',\n 'decodeURIComponent',\n 'encodeURI',\n 'encodeURIComponent',\n 'escape',\n 'eval',\n 'global',\n 'isFinite',\n 'isNaN',\n 'parseFloat',\n 'parseInt',\n 'process',\n 'root',\n 'setImmediate',\n 'setInterval',\n 'setTimeout',\n 'queueMicrotask',\n 'undefined',\n 'unescape',\n 'gc',\n 'v8debug',\n];\n\nfunction isGlobalAugmentation(s: Statement): boolean {\n return !!(\n (isInterfaceDeclaration(s) || isClassDeclaration(s) || isFunctionDeclaration(s)) &&\n s.name &&\n NodeJSGlobals.includes(s.name.text)\n );\n}\n\nfunction wrapInDeclareGlobal(statements: Statement[]): ModuleDeclaration {\n return factory.createModuleDeclaration(\n [factory.createModifier(SyntaxKind.DeclareKeyword)],\n factory.createIdentifier('global'),\n factory.createModuleBlock(statements),\n NodeFlags.GlobalAugmentation,\n );\n}\n\n/**\n * Takes a TypeScript script and does the necessary transformations, so it can be compiled properly\n *\n * @param source The original TypeScript source\n * @param isGlobal Whether the transformed script is a global script or not\n */\nexport function transformScriptBeforeCompilation(source: string, isGlobal?: boolean): string {\n const transformer: TransformerFactory = (_context: TransformationContext): Transformer => {\n return (sourceFile: SourceFile) =>\n visitNode(sourceFile, (node: SourceFile): any => {\n if (isSourceFile(node)) {\n // Wrap all declarations that augment global interfaces in `declare global`\n const augmentations = node.statements.filter(s => isGlobalAugmentation(s));\n const nonAugmentations = node.statements.filter(s => !isGlobalAugmentation(s));\n\n // If there is no top level await, don't move all the statements around\n const hasTLA = node.statements.some(\n s => isExpressionStatement(s) && s.expression.kind === SyntaxKind.AwaitExpression,\n );\n // Move all statements to the top of the file that cannot appear in a function body\n let hoistedStatements = hasTLA\n ? factory.createNodeArray(nonAugmentations.filter(s => mustBeHoisted(s, isGlobal)))\n : factory.createNodeArray(nonAugmentations);\n\n // The rest gets wrapped\n const wrappedStatements = hasTLA ? nonAugmentations.filter(s => !mustBeHoisted(s, isGlobal)) : [];\n\n // When transforming global scripts, we need to do a couple of things\n if (isGlobal) {\n // 1. We need to add an export modifier to everything at the top level that can be exported\n hoistedStatements = visitNodes(\n hoistedStatements,\n // @ts-expect-error s is definitely a Statement\n s => (canBeExported(s) ? addExportModifier(s) : s),\n ) as NodeArray;\n // 3. We need to transform the generated declarations to use `declare global` (this will happen in transformGlobalDeclarations)\n }\n const needsEmptyExport =\n // An empty export is necessary when there is no import declaration\n !node.statements.some(s => isImportDeclaration(s) || isImportEqualsDeclaration(s)) &&\n // And there is no statement in a global script which had an export modifier added\n (!(\n isGlobal &&\n hoistedStatements.some(\n // @ts-expect-error s should have modifiers\n s => s.modifiers?.some(m => m.kind === SyntaxKind.ExportKeyword),\n )\n ) ||\n // Or if there is a `declare global` statement\n !!augmentations);\n\n return factory.updateSourceFile(node, [\n // Put the hoisted statements at the top (or all of them if there's no top level await)\n ...hoistedStatements,\n // Then add everything that augments the global scope\n ...(augmentations && augmentations.length ? [wrapInDeclareGlobal(augmentations)] : []),\n ...(hasTLA\n ? // If there is a top-level await, wrap all non-hoisted statements in (async () => { ... })();\n [\n factory.createExpressionStatement(\n factory.createCallExpression(\n factory.createArrowFunction(\n [factory.createModifier(SyntaxKind.AsyncKeyword)],\n undefined,\n [],\n undefined,\n undefined,\n factory.createBlock(wrappedStatements),\n ),\n undefined,\n undefined,\n ),\n ),\n ]\n : []),\n ...(needsEmptyExport\n ? [\n // Put an empty export {}; at the bottom to force TypeScript to treat the script as a module\n factory.createExportDeclaration(\n undefined, // ModifierLike[] | undefined\n false, // isTypeOnly\n factory.createNamedExports([]), // NamedExportBindings | undefined\n undefined, // moduleSpecifier\n undefined, // attributes\n ),\n ]\n : []),\n ]);\n }\n return node;\n });\n };\n\n const sourceFile = createSourceFile('index.ts', source, ScriptTarget.ESNext, /* setParentNodes */ true);\n\n const result = transform(sourceFile, [transformer]);\n return createPrinter().printNode(EmitHint.Unspecified, result.transformed[0], sourceFile);\n}\n\n/**\n * Takes the global declarations for a TypeScript and wraps export statements in `declare global`\n *\n * @param decl The untransformed global declarations\n */\nexport function transformGlobalDeclarations(decl: string): string {\n const transformer: TransformerFactory = (_context: TransformationContext): any => {\n return (sourceFile: SourceFile) =>\n visitNode(sourceFile, (node: SourceFile): SourceFile => {\n if (isSourceFile(node)) {\n // All non-export-statements stay at the root level, the rest is wrapped in `declare global`\n const exportStatements = node.statements.filter(\n // @ts-expect-error s should have modifiers\n s => s.modifiers?.some(m => m.kind === SyntaxKind.ExportKeyword),\n );\n const otherStatements = node.statements.filter(s => !exportStatements.includes(s));\n\n const hasExportStatements = exportStatements.length > 0;\n const hasImport = otherStatements.some(s => isImportDeclaration(s) || isImportEqualsDeclaration(s));\n\n return factory.updateSourceFile(node, [\n ...otherStatements,\n ...(hasExportStatements\n ? [wrapInDeclareGlobal(exportStatements.map(s => removeDeclareModifier(s)))]\n : []),\n ...(hasImport\n ? [] // If there is an import, the script is already treated as a module\n : [\n // Otherwise, put an empty export {}; at the bottom to force TypeScript to treat the script as a module\n factory.createExportDeclaration(\n undefined,\n false,\n factory.createNamedExports([]),\n undefined,\n undefined,\n ),\n ]),\n ]);\n }\n\n return node;\n });\n };\n\n const sourceFile = createSourceFile('index.d.ts', decl, ScriptTarget.ESNext, /* setParentNodes */ true);\n\n const result = transform(sourceFile, [transformer]);\n return createPrinter().printNode(EmitHint.Unspecified, result.transformed[0], sourceFile);\n}\n\n/**\n * Translates a script ID to a filename for the compiler\n *\n * @param scriptID The ID of the script\n */\nexport function scriptIdToTSFilename(scriptID: string): string {\n return `${scriptID.replace(/^script.js./, '').replace(/\\./g, '/')}.ts`;\n}\n"]} \ No newline at end of file diff --git a/build-backend/lib/utils.js b/build-backend/lib/utils.js new file mode 100644 index 00000000..234bc43f --- /dev/null +++ b/build-backend/lib/utils.js @@ -0,0 +1,66 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.Adapter = exports.controllerDir = exports.appName = void 0; +exports.getConfig = getConfig; +const node_fs_1 = require("node:fs"); +const node_path_1 = require("node:path"); +const EXIT_CODES = { + NO_ERROR: 0, + CANNOT_FIND_ADAPTER_DIR: 10, +}; +/** + * Returns the application name + * The name of the application can be different, and this function finds it out. + */ +function getAppName() { + const parts = __dirname.replace(/\\/g, '/').split('/'); + return parts[parts.length - 2].split('.')[0]; +} +/** + * looks for js-controller home folder + */ +function getControllerDir(isInstall) { + // Find the js-controller location + const possibilities = ['iobroker.js-controller', 'ioBroker.js-controller']; + let controllerPath; + for (const pkg of possibilities) { + try { + const possiblePath = require.resolve(pkg); + if ((0, node_fs_1.existsSync)(possiblePath)) { + controllerPath = possiblePath; + break; + } + } + catch { + /* not found */ + } + } + if (!controllerPath) { + if (!isInstall) { + console.log('Cannot find js-controller'); + process.exit(EXIT_CODES.CANNOT_FIND_ADAPTER_DIR); + } + else { + process.exit(EXIT_CODES.NO_ERROR); + } + } + // we found the controller + return (0, node_path_1.dirname)(controllerPath); +} +exports.appName = getAppName(); +exports.controllerDir = getControllerDir(typeof process !== 'undefined' && process.argv && process.argv.includes('--install')); +/** + * Reads controller base settings + */ +function getConfig() { + let configPath; + if ((0, node_fs_1.existsSync)((configPath = (0, node_path_1.join)(exports.controllerDir, 'conf', `${exports.appName}.json`)))) { + return JSON.parse((0, node_fs_1.readFileSync)(configPath, 'utf8')); + } + if ((0, node_fs_1.existsSync)((configPath = (0, node_path_1.join)(exports.controllerDir, 'conf', `${+exports.appName.toLowerCase()}.json`)))) { + return JSON.parse((0, node_fs_1.readFileSync)(configPath, 'utf8')); + } + throw new Error(`Cannot find ${exports.controllerDir}/conf/${exports.appName}.json`); +} +exports.Adapter = require((0, node_path_1.join)(exports.controllerDir, 'lib/adapter.js')); +//# sourceMappingURL=utils.js.map \ No newline at end of file diff --git a/build-backend/lib/utils.js.map b/build-backend/lib/utils.js.map new file mode 100644 index 00000000..2a04780e --- /dev/null +++ b/build-backend/lib/utils.js.map @@ -0,0 +1 @@ +{"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":";;;AAyDA,8BASC;AAlED,qCAAmD;AACnD,yCAA0C;AAG1C,MAAM,UAAU,GAAG;IACf,QAAQ,EAAE,CAAC;IACX,uBAAuB,EAAE,EAAE;CAC9B,CAAC;AAEF;;;GAGG;AACH,SAAS,UAAU;IACf,MAAM,KAAK,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACvD,OAAO,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AAED;;GAEG;AACH,SAAS,gBAAgB,CAAC,SAAmB;IACzC,kCAAkC;IAClC,MAAM,aAAa,GAAG,CAAC,wBAAwB,EAAE,wBAAwB,CAAC,CAAC;IAC3E,IAAI,cAAkC,CAAC;IACvC,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;QAC9B,IAAI,CAAC;YACD,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;YAC1C,IAAI,IAAA,oBAAU,EAAC,YAAY,CAAC,EAAE,CAAC;gBAC3B,cAAc,GAAG,YAAY,CAAC;gBAC9B,MAAM;YACV,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACL,eAAe;QACnB,CAAC;IACL,CAAC;IACD,IAAI,CAAC,cAAc,EAAE,CAAC;QAClB,IAAI,CAAC,SAAS,EAAE,CAAC;YACb,OAAO,CAAC,GAAG,CAAC,2BAA2B,CAAC,CAAC;YACzC,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,uBAAuB,CAAC,CAAC;QACrD,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QACtC,CAAC;IACL,CAAC;IAED,0BAA0B;IAC1B,OAAO,IAAA,mBAAO,EAAC,cAAc,CAAC,CAAC;AACnC,CAAC;AAEY,QAAA,OAAO,GAAG,UAAU,EAAE,CAAC;AACvB,QAAA,aAAa,GAAG,gBAAgB,CACzC,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,WAAW,CAAC,CACvF,CAAC;AAEF;;GAEG;AACH,SAAgB,SAAS;IACrB,IAAI,UAAkB,CAAC;IACvB,IAAI,IAAA,oBAAU,EAAC,CAAC,UAAU,GAAG,IAAA,gBAAI,EAAC,qBAAa,EAAE,MAAM,EAAE,GAAG,eAAO,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5E,OAAO,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,IAAI,IAAA,oBAAU,EAAC,CAAC,UAAU,GAAG,IAAA,gBAAI,EAAC,qBAAa,EAAE,MAAM,EAAE,GAAG,CAAC,eAAO,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;QAC3F,OAAO,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IACxD,CAAC;IACD,MAAM,IAAI,KAAK,CAAC,eAAe,qBAAa,SAAS,eAAO,OAAO,CAAC,CAAC;AACzE,CAAC;AAEY,QAAA,OAAO,GAAG,OAAO,CAAC,IAAA,gBAAI,EAAC,qBAAa,EAAE,gBAAgB,CAAC,CAAC,CAAC","sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport type { IoBJson } from '@iobroker/types/build/config';\n\nconst EXIT_CODES = {\n NO_ERROR: 0,\n CANNOT_FIND_ADAPTER_DIR: 10,\n};\n\n/**\n * Returns the application name\n * The name of the application can be different, and this function finds it out.\n */\nfunction getAppName(): string {\n const parts = __dirname.replace(/\\\\/g, '/').split('/');\n return parts[parts.length - 2].split('.')[0];\n}\n\n/**\n * looks for js-controller home folder\n */\nfunction getControllerDir(isInstall?: boolean): string {\n // Find the js-controller location\n const possibilities = ['iobroker.js-controller', 'ioBroker.js-controller'];\n let controllerPath: string | undefined;\n for (const pkg of possibilities) {\n try {\n const possiblePath = require.resolve(pkg);\n if (existsSync(possiblePath)) {\n controllerPath = possiblePath;\n break;\n }\n } catch {\n /* not found */\n }\n }\n if (!controllerPath) {\n if (!isInstall) {\n console.log('Cannot find js-controller');\n process.exit(EXIT_CODES.CANNOT_FIND_ADAPTER_DIR);\n } else {\n process.exit(EXIT_CODES.NO_ERROR);\n }\n }\n\n // we found the controller\n return dirname(controllerPath);\n}\n\nexport const appName = getAppName();\nexport const controllerDir = getControllerDir(\n typeof process !== 'undefined' && process.argv && process.argv.includes('--install'),\n);\n\n/**\n * Reads controller base settings\n */\nexport function getConfig(): IoBJson {\n let configPath: string;\n if (existsSync((configPath = join(controllerDir, 'conf', `${appName}.json`)))) {\n return JSON.parse(readFileSync(configPath, 'utf8'));\n }\n if (existsSync((configPath = join(controllerDir, 'conf', `${+appName.toLowerCase()}.json`)))) {\n return JSON.parse(readFileSync(configPath, 'utf8'));\n }\n throw new Error(`Cannot find ${controllerDir}/conf/${appName}.json`);\n}\n\nexport const Adapter = require(join(controllerDir, 'lib/adapter.js'));\n"]} \ No newline at end of file diff --git a/build-backend/lib/words.js b/build-backend/lib/words.js new file mode 100644 index 00000000..4ff0e208 --- /dev/null +++ b/build-backend/lib/words.js @@ -0,0 +1,76 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.setLanguage = setLanguage; +exports.getLanguage = getLanguage; +exports._ = _; +let systemLang = 'en'; +const systemDictionary = { + 'was not executed, while debug mode is active': { + en: 'was not executed, while debug mode is active', + de: 'wurde nicht ausgeführt, während der Debug-Modus aktiv ist', + ru: 'не был выполнен, пока активен режим отладки', + pt: 'não foi executado, enquanto o modo de depuração está ativo', + nl: 'is niet uitgevoerd, terwijl de foutopsporingsmodus actief is', + fr: "n'a pas été exécuté alors que le mode débogage est actif", + it: 'non è stato eseguito, mentre la modalità debug è attiva', + es: 'no se ejecutó, mientras el modo de depuración está activo', + pl: 'nie zostało wykonane, gdy aktywny jest tryb debugowania', + uk: 'не було виконано, поки активний режим налагодження', + 'zh-cn': '调试模式处于活动状态时未执行', + }, +}; +function setLanguage(language) { + systemLang = language; +} +function getLanguage() { + return systemLang; +} +function translateWord(text, lang, dictionary) { + if (!text) { + return ''; + } + lang = lang || systemLang; + dictionary = dictionary || systemDictionary; + if (dictionary[text]) { + let newText = dictionary[text][lang]; + if (newText) { + return newText; + } + else if (lang !== 'en') { + newText = dictionary[text].en; + if (newText) { + return newText; + } + } + } + else if (typeof text === 'string' && !text.match(/_tooltip$/)) { + console.log(`"${text}": {"en": "${text}", "de": "${text}", "ru": "${text}"},`); + } + else if (typeof text !== 'string') { + console.warn(`Trying to translate non-text: ${JSON.stringify(text)}`); + } + return text; +} +function _(text, arg1, arg2, arg3) { + text = translateWord(text); + let pos = text.indexOf('%s'); + if (pos !== -1) { + text = text.replace('%s', arg1); + } + else { + return text; + } + pos = text.indexOf('%s'); + if (pos !== -1) { + text = text.replace('%s', arg2); + } + else { + return text; + } + pos = text.indexOf('%s'); + if (pos !== -1) { + text = text.replace('%s', arg3); + } + return text; +} +//# sourceMappingURL=words.js.map \ No newline at end of file diff --git a/build-backend/lib/words.js.map b/build-backend/lib/words.js.map new file mode 100644 index 00000000..2ac76ddc --- /dev/null +++ b/build-backend/lib/words.js.map @@ -0,0 +1 @@ +{"version":3,"file":"words.js","sourceRoot":"","sources":["../../src/lib/words.ts"],"names":[],"mappings":"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","sourcesContent":["let systemLang: ioBroker.Languages = 'en';\nconst systemDictionary: Record = {\n 'was not executed, while debug mode is active': {\n en: 'was not executed, while debug mode is active',\n de: 'wurde nicht ausgeführt, während der Debug-Modus aktiv ist',\n ru: 'не был выполнен, пока активен режим отладки',\n pt: 'não foi executado, enquanto o modo de depuração está ativo',\n nl: 'is niet uitgevoerd, terwijl de foutopsporingsmodus actief is',\n fr: \"n'a pas été exécuté alors que le mode débogage est actif\",\n it: 'non è stato eseguito, mentre la modalità debug è attiva',\n es: 'no se ejecutó, mientras el modo de depuración está activo',\n pl: 'nie zostało wykonane, gdy aktywny jest tryb debugowania',\n uk: 'не було виконано, поки активний режим налагодження',\n 'zh-cn': '调试模式处于活动状态时未执行',\n },\n};\n\nexport function setLanguage(language: ioBroker.Languages): void {\n systemLang = language;\n}\n\nexport function getLanguage(): ioBroker.Languages {\n return systemLang;\n}\n\nfunction translateWord(\n text: string,\n lang?: ioBroker.Languages,\n dictionary?: Record,\n): string {\n if (!text) {\n return '';\n }\n lang = lang || systemLang;\n dictionary = dictionary || systemDictionary;\n\n if (dictionary[text]) {\n let newText = dictionary[text][lang];\n if (newText) {\n return newText;\n } else if (lang !== 'en') {\n newText = dictionary[text].en;\n if (newText) {\n return newText;\n }\n }\n } else if (typeof text === 'string' && !text.match(/_tooltip$/)) {\n console.log(`\"${text}\": {\"en\": \"${text}\", \"de\": \"${text}\", \"ru\": \"${text}\"},`);\n } else if (typeof text !== 'string') {\n console.warn(`Trying to translate non-text: ${JSON.stringify(text)}`);\n }\n return text;\n}\n\nexport function _(text: string, arg1?: any, arg2?: any, arg3?: any): string {\n text = translateWord(text);\n\n let pos = text.indexOf('%s');\n if (pos !== -1) {\n text = text.replace('%s', arg1);\n } else {\n return text;\n }\n\n pos = text.indexOf('%s');\n if (pos !== -1) {\n text = text.replace('%s', arg2);\n } else {\n return text;\n }\n\n pos = text.indexOf('%s');\n if (pos !== -1) {\n text = text.replace('%s', arg3);\n }\n\n return text;\n}\n"]} \ No newline at end of file diff --git a/build-backend/main.js b/build-backend/main.js new file mode 100644 index 00000000..2291aeba --- /dev/null +++ b/build-backend/main.js @@ -0,0 +1,2585 @@ +"use strict"; +/* + * Javascript adapter + * + * The MIT License (MIT) + * + * Copyright (c) 2014-2024 bluefox , + * + * Copyright (c) 2014 hobbyquaker + */ +var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + var desc = Object.getOwnPropertyDescriptor(m, k); + if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { + desc = { enumerable: true, get: function() { return m[k]; } }; + } + Object.defineProperty(o, k2, desc); +}) : (function(o, m, k, k2) { + if (k2 === undefined) k2 = k; + o[k2] = m[k]; +})); +var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { + Object.defineProperty(o, "default", { enumerable: true, value: v }); +}) : function(o, v) { + o["default"] = v; +}); +var __importStar = (this && this.__importStar) || function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); + __setModuleDefault(result, mod); + return result; +}; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; +Object.defineProperty(exports, "__esModule", { value: true }); +const node_vm_1 = require("node:vm"); +const node_fs_1 = require("node:fs"); +const node_path_1 = require("node:path"); +const node_child_process_1 = require("node:child_process"); +const virtual_tsc_1 = require("virtual-tsc"); +const node_util_1 = require("node:util"); +const dgram = __importStar(require("node:dgram")); +const crypto = __importStar(require("node:crypto")); +const dns = __importStar(require("node:dns")); +const events = __importStar(require("node:events")); +const http = __importStar(require("node:http")); +const https = __importStar(require("node:https")); +const http2 = __importStar(require("node:http2")); +const net = __importStar(require("node:net")); +const os = __importStar(require("node:os")); +const path = __importStar(require("node:path")); +const util = __importStar(require("node:util")); +const child_process = __importStar(require("node:child_process")); +const stream = __importStar(require("node:stream")); +const zlib = __importStar(require("node:zlib")); +// @ts-expect-error no types available +const suncalc = __importStar(require("suncalc2")); +const axios = __importStar(require("axios")); +// @ts-expect-error no types available +const wake_on_lan = __importStar(require("wake_on_lan")); +const nodeSchedule = __importStar(require("node-schedule")); +const adapter_core_1 = require("@iobroker/adapter-core"); +const mirror_1 = require("./lib/mirror"); +const protectFs_1 = __importDefault(require("./lib/protectFs")); +const words_1 = require("./lib/words"); +const sandbox_1 = require("./lib/sandbox"); +const nodeModulesManagement_1 = require("./lib/nodeModulesManagement"); +const eventObj_1 = require("./lib/eventObj"); +const scheduler_1 = require("./lib/scheduler"); +const typescriptSettings_1 = require("./lib/typescriptSettings"); +const tools_1 = require("./lib/tools"); +const typescriptTools_1 = require("./lib/typescriptTools"); +/** + * List of forbidden Locations for a mirror directory + * relative to the default data directory + * ATTENTION: the same list is also located in index_m.html!! + */ +const forbiddenMirrorLocations = [ + 'backup-objects', + 'files', + 'backitup', + '../backups', + '../node_modules', + '../log', +]; +const packageJson = JSON.parse((0, node_fs_1.readFileSync)(`${__dirname}/../package.json`).toString()); +const SCRIPT_CODE_MARKER = 'script.js.'; +let webstormDebug; +const isCI = !!process.env.CI; +// ambient declarations for typescript +let tsAmbient; +// TypeScript's scripts are only recompiled if their source hash changes. +// If an adapter update fixes the compilation bugs, a user won't notice until the changes and re-saves the script. +// To avoid that, we also include the +// adapter version and TypeScript version in the hash +const tsSourceHashBase = `versions:adapter=${packageJson.version},typescript=${packageJson.dependencies.typescript}`; +// taken from here: https://stackoverflow.com/questions/11887934/how-to-check-if-dst-daylight-saving-time-is-in-effect-and-if-so-the-offset +function dstOffsetAtDate(dateInput) { + const fullYear = dateInput.getFullYear() | 0; + // "Leap Years are any year that can be exactly divided by 4 (2012, 2016, etc) + // except if it can be exactly divided by 100, then it isn't (2100, 2200, etc) + // except if it can be exactly divided by 400, then it is (2000, 2400)" + // (https://www.mathsisfun.com/leap-years.html). + const isLeapYear = ((fullYear & 3) | ((fullYear / 100) & 3)) === 0 ? 1 : 0; + // (fullYear & 3) = (fullYear % 4), but faster + //Alternative:var isLeapYear=(new Date(currentYear,1,29,12)).getDate()===29?1:0 + const fullMonth = dateInput.getMonth() | 0; + return ( + // 1. We know what the time since the Epoch really is + +dateInput - // same as the dateInput.getTime() method + // 2. We know what the time since the Epoch at the start of the year is + +new Date(fullYear, 0) - // day defaults to 1 if not explicitly zeroed + // 3. Now, subtract what we would expect the time to be if daylight savings + // did not exist. This yields the time-offset due to daylight savings. + // Calculate the day of the year in the Gregorian calendar + // The code below works based upon the facts of signed right shifts + // • (x) >> n: shifts n and fills in the n highest bits with 0s + // • (-x) >> n: shifts n and fills in the n highest bits with 1s + // (This assumes that x is a positive integer) + ((((-1 + // the first day in the year is day 1 + (31 & (-fullMonth >> 4)) + // January // (-11)>>4 = -1 + ((28 + isLeapYear) & ((1 - fullMonth) >> 4)) + // February + (31 & ((2 - fullMonth) >> 4)) + // March + (30 & ((3 - fullMonth) >> 4)) + // April + (31 & ((4 - fullMonth) >> 4)) + // May + (30 & ((5 - fullMonth) >> 4)) + // June + (31 & ((6 - fullMonth) >> 4)) + // July + (31 & ((7 - fullMonth) >> 4)) + // August + (30 & ((8 - fullMonth) >> 4)) + // September + (31 & ((9 - fullMonth) >> 4)) + // October + (30 & ((10 - fullMonth) >> 4)) + // November + // There are no months past December: the year rolls into the next. + // Thus, "fullMonth" is 0-based, so it will never be 12 in JavaScript + (dateInput.getDate() | 0)) & // get day of the month + 0xffff) * + 24 * + 60 + // 24 hours in a day, 60 minutes in an hour + (dateInput.getHours() & 0xff) * 60 + // 60 minutes in an hour + (dateInput.getMinutes() & 0xff)) | + 0) * + 60 * + 1000 - // 60 seconds in a minute * 1000 milliseconds in a second + (dateInput.getSeconds() & 0xff) * 1000 - // 1000 milliseconds in a second + dateInput.getMilliseconds()); +} +const regExGlobalOld = /_global$/; +const regExGlobalNew = /script\.js\.global\./; +function checkIsGlobal(obj) { + return obj?.common && (regExGlobalOld.test(obj.common.name) || regExGlobalNew.test(obj._id)); +} +function fileMatching(sub, id, fileName) { + if (sub.idRegEx) { + if (!sub.idRegEx.test(id)) { + return false; + } + } + else { + if (sub.id !== id) { + return false; + } + } + if (sub.fileRegEx) { + if (!sub.fileRegEx.test(fileName)) { + return false; + } + } + else { + if (sub.fileNamePattern !== fileName) { + return false; + } + } + return true; +} +function getNextTimeEvent(time, useNextDay) { + const now = getAstroStartOfDay(); + const [timeHours, timeMinutes] = time.split(':'); + const nTimeHours = parseInt(timeHours, 10); + const nTimeMinutes = parseInt(timeMinutes, 10); + if (useNextDay && + (now.getHours() > nTimeHours || (now.getHours() === nTimeHours && now.getMinutes() > nTimeMinutes))) { + now.setDate(now.getDate() + 1); + } + now.setHours(nTimeHours); + now.setMinutes(nTimeMinutes); + return now; +} +function getAstroStartOfDay() { + const d = new Date(); + d.setMinutes(0); + d.setSeconds(0); + d.setMilliseconds(0); + d.setTime(d.getTime() - d.getTimezoneOffset() * 60 * 1000); + d.setUTCHours(0); + return d; +} +function formatHoursMinutesSeconds(date) { + const h = String(date.getHours()); + const m = String(date.getMinutes()); + const s = String(date.getSeconds()); + return `${h.padStart(2, '0')}:${m.padStart(2, '0')}:${s.padStart(2, '0')}`; +} +// Due to a npm bug, virtual-tsc may be hoisted to the top level node_modules but +// typescript may still be in the adapter level (https://npm.community/t/packages-with-peerdependencies-are-incorrectly-hoisted/4794), +// so we need to tell virtual-tsc where typescript is +(0, virtual_tsc_1.setTypeScriptResolveOptions)({ + paths: [require.resolve('typescript')], +}); +// compiler instance for global JS declarations +const jsDeclarationServer = new virtual_tsc_1.Server(typescriptSettings_1.jsDeclarationCompilerOptions, isCI ? false : undefined); +/** + * Stores the IDs of script objects whose change should be ignored because + * the compiled source was just updated + */ +class JavaScript extends adapter_core_1.Adapter { + context; + errorLogFunction; + mods; + objectsInitDone = false; + statesInitDone = false; + objects = {}; + states = {}; + interimStateValues = {}; + stateIds = []; + subscriptions = []; + subscriptionsFile = []; + subscriptionsObject = []; + subscribedPatterns = {}; + subscribedPatternsFile = {}; + adapterSubs = {}; + timers = {}; + _enums = []; + names = {}; // name: id + scripts = {}; + messageBusHandlers = {}; + logSubscriptions = {}; + tempDirectories = {}; // name: path + folderCreationVerifiedObjects = {}; + /** if logs are subscribed or not */ + logSubscribed = false; + timeSettings = { format12: false, leadingZeros: true }; + dayScheduleTimer = null; // schedule for astrological day + sunScheduleTimer = null; // schedule for sun moment times + timeScheduleTimer = null; // schedule for astrological day + activeStr = ''; // enabled state prefix + mirror; + stopCounters = {}; + setStateCountCheckInterval = null; + globalScript = ''; + /** Generated declarations for global TypeScripts */ + globalDeclarations = ''; + // Remember which definitions the global scripts + // have access to, because it depends on the compilation order + knownGlobalDeclarationsByScript = {}; + globalScriptLines = 0; + // compiler instance for typescript + tsServer; + ignoreObjectChange = new Set(); + debugState = { + scriptName: '', + child: null, + promiseOnEnd: null, + paused: false, + started: 0, + running: false, + }; + constructor(options = {}) { + options = { + ...options, + name: 'javascript', // adapter name + useFormatDate: true, + /** + * If the JS-Controller catches an unhandled error, this will be called + * so we have a chance to handle it ourselves. + */ + error: (err) => { + // Identify unhandled errors originating from callbacks in scripts + // These are not caught by wrapping the execution code in try-catch + if (err && typeof err.stack === 'string') { + const scriptCodeMarkerIndex = err.stack.indexOf(SCRIPT_CODE_MARKER); + if (scriptCodeMarkerIndex > -1) { + // This is a script error + let scriptName = err.stack.substring(scriptCodeMarkerIndex); + scriptName = scriptName.substring(0, scriptName.indexOf(':')); + this.logError(scriptName, err); + // Leave the script running for now + // signal to the JS-Controller that we handled the error ourselves + return true; + } + // check if a path contains adaptername but not own node_module + // this regex matched "iobroker.javascript/" if NOT followed by "node_modules" + if (!err.stack.match(/iobroker\.javascript[/\\](?!.*node_modules).*/g)) { + // This is an error without any info on origin (mostly async errors like connection errors) + // also consider it as being from a script + this.log.error('An error happened which is most likely from one of your scripts, but the originating script could not be detected.'); + this.log.error(`Error: ${err.message}`); + this.log.error(err.stack); + // signal to the JS-Controller that we handled the error ourselves + return true; + } + } + return false; + }, + }; + super(options); + this.on('objectChange', this.onObjectChange.bind(this)); + this.on('stateChange', this.onStateChange.bind(this)); + this.on('ready', this.onReady.bind(this)); + this.on('message', this.onMessage.bind(this)); + this.on('unload', this.onUnload.bind(this)); + this.on('fileChange', this.onFileChange.bind(this)); + this.on('log', this.onLog.bind(this)); + this.mods = { + fs: {}, + 'fs/promises': {}, + dgram, + crypto, + dns, + events, + http, + https, + http2, + net, + os, + path, + util, + child_process, + stream, + zlib, + suncalc, + axios, + wake_on_lan, + nodeSchedule, + }; + // check the webstorm debug and just debug modes + let debugMode; + if (process.argv) { + for (let a = 1; a < process.argv.length; a++) { + if (process.argv[a].startsWith('--webstorm')) { + webstormDebug = process.argv[a].replace(/^(.*?=\s*)/, ''); + } + if (process.argv[a] === '--debugScript') { + if (!process.argv[a + 1]) { + console.log('No script name provided'); + process.exit(300); + } + else { + debugMode = process.argv[a + 1]; + } + } + } + } + this.errorLogFunction = this.log; + this.context = { + mods: this.mods, + objects: this.objects, + states: this.states, + interimStateValues: this.interimStateValues, + stateIds: this.stateIds, + errorLogFunction: this.errorLogFunction, + subscriptions: this.subscriptions, + subscriptionsFile: this.subscriptionsFile, + subscriptionsObject: this.subscriptionsObject, + subscribedPatterns: this.subscribedPatterns, + subscribedPatternsFile: this.subscribedPatternsFile, + adapterSubs: this.adapterSubs, + cacheObjectEnums: {}, + timers: this.timers, + enums: this._enums, + names: this.names, + scripts: this.scripts, + messageBusHandlers: this.messageBusHandlers, + logSubscriptions: this.logSubscriptions, + tempDirectories: this.tempDirectories, + folderCreationVerifiedObjects: this.folderCreationVerifiedObjects, + isEnums: false, // If some subscription wants enum + channels: null, + devices: null, + logWithLineInfo: this.logWithLineInfo.bind(this), + scheduler: null, + timerId: 0, + rulesOpened: null, // opened rules + language: this.language || 'en', + updateLogSubscriptions: this.updateLogSubscriptions.bind(this), + convertBackStringifiedValues: this.convertBackStringifiedValues.bind(this), + updateObjectContext: this.updateObjectContext.bind(this), + prepareStateObject: this.prepareStateObject.bind(this), + debugMode, + getAbsoluteDefaultDataDir: adapter_core_1.getAbsoluteDefaultDataDir, + adapter: this, + logError: this.logError.bind(this), + }; + this.tsServer = new virtual_tsc_1.Server(typescriptSettings_1.tsCompilerOptions, this.tsLog); + } + async onObjectChange(id, obj) { + // Check if we should ignore this change (once!) because we just updated the compiled sources + if (this.ignoreObjectChange.has(id)) { + // Update the cached script object and do nothing more + this.objects[id] = obj; + this.ignoreObjectChange.delete(id); + return; + } + // When still in initializing: already remember current values, + // but data structures are initialized elsewhere + if (!this.objectsInitDone) { + if (obj) { + this.objects[id] = obj; + } + return; + } + if (id.startsWith('enum.')) { + // clear cache + this.context.cacheObjectEnums = {}; + // update this._enums array + if (obj) { + // If new + if (!this._enums.includes(id)) { + this._enums.push(id); + this._enums.sort(); + } + } + else { + const pos = this._enums.indexOf(id); + // if deleted + if (pos !== -1) { + this._enums.splice(pos, 1); + } + } + } + if (id === 'system.config' && obj?.common?.language) { + // set language for debug messages + (0, words_1.setLanguage)(obj.common.language); + this.language = obj.common.language; + this.context.language = this.language; + } + // update stored time format for variables.dayTime + if (id === `${this.namespace}.variables.dayTime` && obj?.native) { + this.timeSettings.format12 = obj.native.format12 || false; + this.timeSettings.leadingZeros = obj.native.leadingZeros === undefined ? true : obj.native.leadingZeros; + } + // send changes to disk mirror + this.mirror?.onObjectChange(id, obj); + const formerObj = this.objects[id]; + this.updateObjectContext(id, obj); // Update all Meta object data + // for the alias object changes on the state objects, we need to manually update the + // state cache value, because the new value is only published on the next change + if (obj?.type === 'state' && id.startsWith('alias.0.')) { + // execute async for speed + this.getForeignStateAsync(id) + .then(state => { + if (state) { + this.states[id] = state; + } + else if (this.states[id] !== undefined) { + delete this.states[id]; + } + }) + .catch(() => { + /* ignore */ + }); + } + this.subscriptionsObject.forEach(sub => { + // ToDo: implement comparing with id.0.* too + if (sub.pattern === id) { + try { + sub.callback(id, obj); + } + catch (err) { + this.log.error(`Error in callback: ${err.toString()}`); + } + } + }); + // handle Script object updates + if (!obj && formerObj?.type === 'script') { + // Object Deleted just now + if (checkIsGlobal(formerObj)) { + // it was a global Script, and it was enabled and is now deleted => restart adapter + if (formerObj.common.enabled) { + this.log.info(`Active global Script ${id} deleted. Restart instance.`); + this.restart(); + } + } + else if (formerObj.common?.engine === `system.adapter.${this.namespace}`) { + // It was a non-global Script and deleted => stop and remove it + await this.stopScript(id); + // delete scriptEnabled.blabla variable + const idActive = `scriptEnabled.${id.substring(SCRIPT_CODE_MARKER.length)}`; + await this.delStateAsync(idActive); + await this.delObjectAsync(idActive); + // delete scriptProblem.blabla variable + const idProblem = `scriptProblem.${id.substring(SCRIPT_CODE_MARKER.length)}`; + await this.delStateAsync(idProblem); + await this.delObjectAsync(idProblem); + } + } + else if (!formerObj && obj?.type === 'script') { + // New script that does not exist before + if (checkIsGlobal(obj)) { + // new global script added => restart adapter + if (obj.common.enabled) { + this.log.info(`Active global Script ${id} created. Restart instance.`); + this.restart(); + } + } + else if (obj.common?.engine === `system.adapter.${this.namespace}`) { + // new non-global script - create states for scripts + await this.createActiveObject(id, obj.common.enabled); + await this.createProblemObject(id); + if (obj.common.enabled) { + // if enabled => Start script + await this.loadScriptById(id); + } + } + } + else if (obj?.type === 'script' && formerObj?.common) { + // Script changed ... + if (checkIsGlobal(obj)) { + if (obj.common.enabled || formerObj.common.enabled) { + this.log.info(`Global Script ${id} updated. Restart instance.`); + this.restart(); + } + } + else { + // No global script + if (obj.common?.engine === `system.adapter.${this.namespace}`) { + // create states for scripts + await this.createActiveObject(id, obj.common.enabled); + await this.createProblemObject(id); + } + if ((formerObj.common.enabled && !obj.common.enabled) || + (formerObj.common.engine === `system.adapter.${this.namespace}` && + obj.common.engine !== `system.adapter.${this.namespace}`)) { + // Script disabled + if (formerObj.common.enabled && formerObj.common.engine === `system.adapter.${this.namespace}`) { + // Remove it from executing + await this.stopScript(id); + } + } + else if ((!formerObj.common.enabled && obj.common.enabled) || + (formerObj.common.engine !== `system.adapter.${this.namespace}` && + obj.common.engine === `system.adapter.${this.namespace}`)) { + // Script enabled + if (obj.common.enabled && obj.common.engine === `system.adapter.${this.namespace}`) { + // Start script + await this.loadScriptById(id); + } + } + else { + // if (obj.common.source !== formerObj.common.source) { + // Source changed => restart the script + this.stopCounters[id] = this.stopCounters[id] ? this.stopCounters[id] + 1 : 1; + this.stopScript(id).then(() => { + // only start again after stop when "last" object change to prevent problems on + // multiple changes in fast frequency + if (!--this.stopCounters[id]) { + this.loadScriptById(id); + } + }); + } + } + } + } + onStateChange(id, state) { + if (this.interimStateValues[id] !== undefined) { + // any update invalidates the remembered interim value + delete this.interimStateValues[id]; + } + if (!id || id.startsWith('messagebox.') || id.startsWith('log.')) { + return; + } + if (id === `${this.namespace}.debug.to` && state && !state.ack) { + if (!this.context.debugMode) { + this.debugSendToInspector(state.val); + } + return; + } + // When still in initializing: already remember current values, + // but data structures are initialized elsewhere + if (!this.statesInitDone) { + if (state) { + this.states[id] = state; + } + return; + } + const oldState = this.states[id]; + if (state) { + if (oldState) { + // enable or disable script + if (!state.ack && id.startsWith(this.activeStr) && this.objects[id]?.native?.script) { + this.extendForeignObject(this.objects[id].native.script, { + common: { enabled: state.val }, + }); + } + // monitor if adapter is alive and send all subscriptions once more, after adapter goes online + if ( /*oldState && */oldState.val === false && state.val && id.endsWith('.alive')) { + if (this.adapterSubs[id]) { + const parts = id.split('.'); + const a = `${parts[2]}.${parts[3]}`; + for (let t = 0; t < this.adapterSubs[id].length; t++) { + this.log.info(`Detected coming adapter "${a}". Send subscribe: ${this.adapterSubs[id][t]}`); + this.sendTo(a, 'subscribe', this.adapterSubs[id][t]); + } + } + } + } + else if ( /*!oldState && */!this.stateIds.includes(id)) { + this.stateIds.push(id); + this.stateIds.sort(); + } + this.states[id] = state; + } + else { + if (oldState) { + delete this.states[id]; + } + state = {}; + const pos = this.stateIds.indexOf(id); + if (pos !== -1) { + this.stateIds.splice(pos, 1); + } + } + const _eventObj = (0, eventObj_1.createEventObject)(this.context, id, this.convertBackStringifiedValues(id, state), this.convertBackStringifiedValues(id, oldState)); + // if this state matches any subscriptions + for (let i = 0, l = this.subscriptions.length; i < l; i++) { + const sub = this.subscriptions[i]; + if (sub?.patternCompareFunctions && patternMatching(_eventObj, sub.patternCompareFunctions)) { + try { + sub.callback(_eventObj); + } + catch (err) { + this.log.error(`Error in callback: ${err.toString()}`); + } + } + } + } + onFileChange(id, fileName, size) { + // if this file matches any subscriptions + for (let i = 0, l = this.subscriptionsFile.length; i < l; i++) { + const sub = this.subscriptionsFile[i]; + if (sub && fileMatching(sub, id, fileName)) { + try { + sub.callback(id, fileName, size, sub.withFile); + } + catch (err) { + this.log.error(`Error in callback: ${err.toString()}`); + } + } + } + } + async onUnload(callback) { + await this.debugStop(); + this.stopTimeSchedules(); + if (this.setStateCountCheckInterval) { + clearInterval(this.setStateCountCheckInterval); + this.setStateCountCheckInterval = null; + } + await this.stopAllScripts(); + if (typeof callback === 'function') { + callback(); + } + } + async onReady() { + this.config.maxSetStatePerMinute = parseInt(this.config.maxSetStatePerMinute, 10) || 1000; + this.config.maxTriggersPerScript = parseInt(this.config.maxTriggersPerScript, 10) || 100; + if (this.supportsFeature && this.supportsFeature('PLUGINS')) { + const sentryInstance = this.getPluginInstance('sentry'); + if (sentryInstance) { + const Sentry = sentryInstance.getSentryObject(); + if (Sentry) { + const scope = Sentry.getCurrentScope(); + scope.addEventProcessor((event, _hint) => { + if (event.exception?.values?.[0]) { + const eventData = event.exception.values[0]; + if (eventData.stacktrace?.frames && + Array.isArray(eventData.stacktrace.frames) && + eventData.stacktrace.frames.length) { + // Exclude event if script Marker is included + if (eventData.stacktrace.frames.find(frame => frame.filename?.includes(SCRIPT_CODE_MARKER))) { + return null; + } + //Exclude event if own directory is included but not inside own node_modules + const ownNodeModulesDir = (0, node_path_1.join)(__dirname, 'node_modules'); + if (!eventData.stacktrace.frames.find(frame => frame.filename && + frame.filename.includes(__dirname) && + !frame.filename.includes(ownNodeModulesDir))) { + return null; + } + // We have exception data and did not sort it out, so report it + return event; + } + } + // No exception in it ... do not report + return null; + }); + } + } + } + await this.main(); + } + onMessage(obj) { + switch (obj?.command) { + // process messageTo commands + case 'toScript': + case 'jsMessageBus': + if (obj.message && + (obj.message.instance === null || + obj.message.instance === undefined || + `javascript.${obj.message.instance}` === this.namespace || + obj.message.instance === this.namespace)) { + Object.keys(this.messageBusHandlers).forEach(name => { + // script name could be script.js.xxx or only xxx + if ((!obj.message.script || obj.message.script === name) && + this.messageBusHandlers[name][obj.message.message]) { + this.messageBusHandlers[name][obj.message.message].forEach(handler => { + const sandbox = handler.sandbox; + sandbox.verbose && sandbox.log(`onMessage: ${JSON.stringify(obj.message)}`, 'info'); + try { + if (obj.callback) { + handler.cb.call(sandbox, obj.message.data, (result) => { + if (sandbox.verbose) { + sandbox.log(`onMessage result: ${JSON.stringify(result)}`, 'info'); + } + this.sendTo(obj.from, obj.command, result, obj.callback); + }); + } + else { + handler.cb.call(sandbox, obj.message.data, (result) => { + sandbox.verbose && + sandbox.log(`onMessage result: ${JSON.stringify(result)}`, 'info'); + }); + } + } + catch (err) { + this.setState(`scriptProblem.${name.substring(SCRIPT_CODE_MARKER.length)}`, true, true); + this.logError('Error in callback', err); + } + }); + } + }); + } + break; + case 'loadTypings': { + // Load typings for the editor + const typings = {}; + // try to load TypeScript lib files from disk + try { + const typescriptLibs = (0, typescriptTools_1.resolveTypescriptLibs)(typescriptSettings_1.targetTsLib); + Object.assign(typings, typescriptLibs); + } + catch { + /* ok, no lib then */ + } + // provide the already-loaded ioBroker typings and global script declarations + Object.assign(typings, tsAmbient); + // also provide the known global declarations for each global script + for (const globalScriptPaths of Object.keys(this.knownGlobalDeclarationsByScript)) { + typings[`${globalScriptPaths}.d.ts`] = this.knownGlobalDeclarationsByScript[globalScriptPaths]; + } + if (obj.callback) { + this.sendTo(obj.from, obj.command, { typings }, obj.callback); + } + break; + } + case 'calcAstroAll': { + if (obj.message) { + const sunriseOffset = parseInt(obj.message.sunriseOffset === undefined + ? this.config.sunriseOffset + : obj.message.sunriseOffset, 10) || 0; + const sunsetOffset = parseInt(obj.message.sunsetOffset === undefined + ? this.config.sunsetOffset + : obj.message.sunsetOffset, 10) || 0; + const longitude = parseFloat(obj.message.longitude === undefined ? this.config.longitude : obj.message.longitude) || 0; + const latitude = parseFloat(obj.message.latitude === undefined ? this.config.latitude : obj.message.latitude) || + 0; + const today = getAstroStartOfDay(); + let astroEvents = {}; + try { + astroEvents = this.mods.suncalc.getTimes(today, latitude, longitude); + } + catch (err) { + this.log.error(`Cannot calculate astro data: ${err}`); + } + if (astroEvents) { + try { + astroEvents.nextSunrise = this.getAstroEvent(today, obj.message.sunriseEvent || this.config.sunriseEvent, obj.message.sunriseLimitStart || this.config.sunriseLimitStart, obj.message.sunriseLimitEnd || this.config.sunriseLimitEnd, sunriseOffset, false, latitude, longitude, true); + astroEvents.nextSunset = this.getAstroEvent(today, obj.message.sunsetEvent || this.config.sunsetEvent, obj.message.sunsetLimitStart || this.config.sunsetLimitStart, obj.message.sunsetLimitEnd || this.config.sunsetLimitEnd, sunsetOffset, true, latitude, longitude, true); + } + catch (err) { + this.log.error(`Cannot calculate astro data: ${err}`); + } + } + const result = {}; + const keys = Object.keys(astroEvents).sort((a, b) => astroEvents[a] - + astroEvents[b]); + keys.forEach(key => { + const validDate = astroEvents[key] !== null && + !isNaN(astroEvents[key].getTime()); + result[key] = { + isValidDate: validDate, + serverTime: validDate + ? formatHoursMinutesSeconds(astroEvents[key]) + : 'n/a', + date: validDate + ? astroEvents[key].toISOString() + : 'n/a', + }; + }); + if (obj.callback) { + this.sendTo(obj.from, obj.command, result, obj.callback); + } + } + break; + } + case 'calcAstro': { + if (obj.message) { + const longitude = parseFloat(obj.message.longitude === undefined ? this.config.longitude : obj.message.longitude) || 0; + const latitude = parseFloat(obj.message.latitude === undefined ? this.config.latitude : obj.message.latitude) || + 0; + const today = getAstroStartOfDay(); + const sunriseEvent = obj.message?.sunriseEvent || this.config.sunriseEvent; + const sunriseLimitStart = obj.message?.sunriseLimitStart || this.config.sunriseLimitStart; + const sunriseLimitEnd = obj.message?.sunriseLimitEnd || this.config.sunriseLimitEnd; + const sunriseOffset = parseInt(obj.message.sunriseOffset === undefined + ? this.config.sunriseOffset + : obj.message.sunriseOffset, 10) || 0; + const nextSunrise = this.getAstroEvent(today, sunriseEvent, sunriseLimitStart, sunriseLimitEnd, sunriseOffset, false, latitude, longitude, true); + const sunsetEvent = obj.message?.sunsetEvent || this.config.sunsetEvent; + const sunsetLimitStart = obj.message?.sunsetLimitStart || this.config.sunsetLimitStart; + const sunsetLimitEnd = obj.message?.sunsetLimitEnd || this.config.sunsetLimitEnd; + const sunsetOffset = parseInt(obj.message.sunsetOffset === undefined + ? this.config.sunsetOffset + : obj.message.sunsetOffset, 10) || 0; + const nextSunset = this.getAstroEvent(today, sunsetEvent, sunsetLimitStart, sunsetLimitEnd, sunsetOffset, true, latitude, longitude, true); + const validDateSunrise = nextSunrise !== null && !isNaN(nextSunrise.getTime()); + const validDateSunset = nextSunset !== null && !isNaN(nextSunset.getTime()); + this.log.debug(`calcAstro sunrise: ${sunriseEvent} -> start ${sunriseLimitStart}, end: ${sunriseLimitEnd}, offset: ${sunriseOffset} - ${validDateSunrise ? nextSunrise.toISOString() : 'n/a'}`); + this.log.debug(`calcAstro sunset: ${sunsetEvent} -> start ${sunsetLimitStart}, end: ${sunsetLimitEnd}, offset: ${sunsetOffset} - ${validDateSunset ? nextSunset.toISOString() : 'n/a'}`); + if (obj.callback) { + this.sendTo(obj.from, obj.command, { + nextSunrise: { + isValidDate: validDateSunrise, + serverTime: validDateSunrise ? formatHoursMinutesSeconds(nextSunrise) : 'n/a', + date: nextSunrise.toISOString(), + }, + nextSunset: { + isValidDate: validDateSunset, + serverTime: validDateSunset ? formatHoursMinutesSeconds(nextSunset) : 'n/a', + date: nextSunset.toISOString(), + }, + }, obj.callback); + } + } + break; + } + case 'debug': { + if (!this.context.debugMode) { + this.debugStart(obj.message); + } + break; + } + case 'debugStop': { + if (!this.context.debugMode) { + this.debugStop().then(() => console.log('stopped')); + } + break; + } + case 'rulesOn': { + this.context.rulesOpened = obj.message; + console.log(`Enable messaging for ${this.context.rulesOpened}`); + break; + } + case 'rulesOff': { + // maybe if (context.rulesOpened === obj.message) + console.log(`Disable messaging for ${this.context.rulesOpened}`); + this.context.rulesOpened = null; + break; + } + case 'getIoBrokerDataDir': { + if (obj.callback) { + this.sendTo(obj.from, obj.command, { + dataDir: (0, adapter_core_1.getAbsoluteDefaultDataDir)(), + sep: node_path_1.sep, + }, obj.callback); + } + break; + } + } + } + onLog(msg) { + Object.keys(this.logSubscriptions).forEach((name) => this.logSubscriptions[name].forEach(handler => { + if (typeof handler.cb === 'function' && + (handler.severity === '*' || handler.severity === msg.severity)) { + handler.sandbox.logHandler = handler.severity || '*'; + handler.cb.call(handler.sandbox, msg); + handler.sandbox.logHandler = undefined; + } + })); + } + logError(msg, e, offs) { + const stack = e.stack ? e.stack.toString().split('\n') : e ? e.toString() : ''; + if (!msg.includes('\n')) { + msg = msg.replace(/[: ]*$/, ': '); + } + this.errorLogFunction.error(msg + this.fixLineNo(stack[0])); + for (let i = offs || 1; i < stack.length; i++) { + if (!stack[i]) { + continue; + } + if (stack[i].match(/runInNewContext|javascript\.js:/)) { + break; + } + this.errorLogFunction.error(this.fixLineNo(stack[i])); + } + } + logWithLineInfo(msg) { + this.errorLogFunction.warn(msg); + // get current error stack + const stack = new Error().stack?.split('\n'); + if (stack) { + for (let i = 3; i < stack.length; i++) { + if (!stack[i]) { + continue; + } + if (stack[i].match(/runInContext|runInNewContext|javascript\.js:/)) { + break; + } + this.errorLogFunction.warn(this.fixLineNo(stack[i])); + } + } + } + async main() { + // Patch the font as it sometimes is wrong + if (!this.context.debugMode) { + if (await this.patchFont()) { + this.log.debug('Font patched'); + } + } + this.log.debug(`config.subscribe (Do not subscribe all states on start): ${this.config.subscribe}`); + // correct jsonConfig for admin + const instObj = await this.getForeignObjectAsync(`system.adapter.${this.namespace}`); + if (instObj?.common) { + if (instObj.common.adminUI?.config !== 'json') { + if (instObj.common.adminUI) { + instObj.common.adminUI.config = 'json'; + } + else { + instObj.common.adminUI = { config: 'json' }; + } + this.setForeignObject(instObj._id, instObj); + } + } + if (webstormDebug) { + this.errorLogFunction = { + error: console.error, + warn: console.warn, + info: console.info, + debug: console.log, + silly: console.log, + }; + this.context.errorLogFunction = this.errorLogFunction; + } + this.activeStr = `${this.namespace}.scriptEnabled.`; + this.mods.fs = new protectFs_1.default(this.log, (0, adapter_core_1.getAbsoluteDefaultDataDir)()); + this.mods['fs/promises'] = this.mods.fs.promises; // to avoid require('fs/promises'); + // try to read TS declarations + try { + tsAmbient = { + 'javascript.d.ts': (0, node_fs_1.readFileSync)(this.mods.path.join(__dirname, 'lib/javascript.d.ts'), 'utf8'), + }; + this.tsServer.provideAmbientDeclarations(tsAmbient); + jsDeclarationServer.provideAmbientDeclarations(tsAmbient); + } + catch (err) { + this.log.warn(`Could not read TypeScript ambient declarations: ${err}`); + // This should not happen, so send an error report to Sentry + if (this.supportsFeature && this.supportsFeature('PLUGINS')) { + const sentryInstance = this.getPluginInstance('sentry'); + if (sentryInstance) { + const sentryObject = sentryInstance.getSentryObject(); + sentryObject?.captureException(err); + } + } + // Keep the adapter from crashing when the included typings cannot be read + tsAmbient = {}; + } + await this.installLibraries(); + // Load the TS declarations for Node.js and all 3rd party modules + this.loadTypeScriptDeclarations(); + await this.getData(); + this.context.scheduler = new scheduler_1.Scheduler(this.log, Date, this.mods.suncalc, this.config.latitude, this.config.longitude); + await this.dayTimeSchedules(); + await this.sunTimeSchedules(); + await this.timeSchedule(); + // Warning. It could have a side effect in compact mode, so all adapters will accept self-signed certificates + if (this.config.allowSelfSignedCerts) { + process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + } + const doc = await this.getObjectViewAsync('script', 'javascript', {}); + if (doc?.rows?.length) { + // assemble global script + for (let g = 0; g < doc.rows.length; g++) { + const obj = doc.rows[g].value; + if (checkIsGlobal(obj)) { + if (obj && obj.common) { + const engineType = (obj.common.engineType || '').toLowerCase(); + if (obj.common.enabled) { + if (engineType.startsWith('typescript')) { + // TypeScript + this.log.info(`${obj._id}: compiling TypeScript source...`); + // In order to compile global TypeScript, we need to do some transformations + // 1. For top-level-await, some statements must be wrapped in an immediately-invoked async function + // 2. If any global script uses `import`, the declarations are no longer visible if they are not exported with `declare global` + const transformedSource = (0, typescriptTools_1.transformScriptBeforeCompilation)(obj.common.source, true); + // The source code must be transformed in order to support top level await + // Global scripts must not be treated as a module, otherwise their methods + // cannot be found by the normal scripts + // We need to hash both global declarations that are known until now + // AND the script source, because changing either can change the compilation output + const sourceHash = (0, tools_1.hashSource)(tsSourceHashBase + this.globalDeclarations + transformedSource); + let compiled; + let declarations; + // If we already stored the compiled source code and the original source hash, + // use the hash to check whether we can rely on the compiled source code or + // if we need to compile it again + if (typeof obj.common.compiled === 'string' && + typeof obj.common.sourceHash === 'string' && + sourceHash === obj.common.sourceHash) { + // We can reuse the stored source + compiled = obj.common.compiled; + declarations = obj.common.declarations; + this.log.info(`${obj._id}: source code did not change, using cached compilation result...`); + } + else { + // We don't have a hashed source code, or the original source changed, compile it + const filename = (0, typescriptTools_1.scriptIdToTSFilename)(obj._id); + let tsCompiled; + try { + tsCompiled = this.tsServer.compile(filename, transformedSource); + } + catch (err) { + this.log.error(`${obj._id}: TypeScript compilation failed:\n${err}`); + continue; + } + const errors = tsCompiled.diagnostics + .map(diag => `${diag.annotatedSource}\n`) + .join('\n'); + if (tsCompiled.success) { + if (errors.length > 0) { + this.log.warn(`${obj._id}: TypeScript compilation completed with errors:\n${errors}`); + } + else { + this.log.info(`${obj._id}: TypeScript compilation successful`); + } + compiled = tsCompiled.result; + // Global scripts that have been transformed to support `import` need to have their declarations transformed aswell + declarations = (0, typescriptTools_1.transformGlobalDeclarations)(tsCompiled.declarations || ''); + const newCommon = { + sourceHash, + compiled, + }; + if (declarations) { + newCommon.declarations = declarations; + } + // Store the compiled source and the original source hash, so we don't need to do the work again next time + this.ignoreObjectChange.add(obj._id); // ignore the next change and don't restart scripts + this.extendForeignObject(obj._id, { + common: newCommon, + }); + } + else { + this.log.error(`${obj._id}: TypeScript compilation failed:\n${errors}`); + continue; + } + } + this.globalScript += `${compiled}\n`; + // if declarations were generated, remember them + if (declarations != null) { + this.provideDeclarationsForGlobalScript(obj._id, declarations); + } + } + else { + // javascript + const sourceCode = obj.common.source; + this.globalScript += `${sourceCode}\n`; + // try to compile the declarations so TypeScripts can use + // functions defined in global JavaScripts + const filename = (0, typescriptTools_1.scriptIdToTSFilename)(obj._id); + let tsCompiled; + try { + tsCompiled = jsDeclarationServer.compile(filename, sourceCode); + } + catch (err) { + this.log.warn(`${obj._id}: Error while generating type declarations, skipping:\n${err}`); + continue; + } + // if declarations were generated, remember them + if (tsCompiled.success && tsCompiled.declarations != null) { + this.provideDeclarationsForGlobalScript(obj._id, tsCompiled.declarations); + } + } + } + } + } + } + } + this.globalScript = this.globalScript.replace(/\r\n/g, '\n'); + this.globalScriptLines = this.globalScript.split(/\n/g).length - 1; + if (doc?.rows?.length) { + // load all scripts + for (let i = 0; i < doc.rows.length; i++) { + if (!checkIsGlobal(doc.rows[i].value)) { + this.loadScript(doc.rows[i].value); + } + } + } + if (this.config.mirrorPath) { + this.config.mirrorInstance = parseInt(this.config.mirrorInstance, 10) || 0; + if (this.instance === this.config.mirrorInstance) { + const ioBDataDir = (0, adapter_core_1.getAbsoluteDefaultDataDir)() + node_path_1.sep; + this.config.mirrorPath = (0, node_path_1.normalize)(this.config.mirrorPath); + let mirrorForbidden = false; + for (let dir of forbiddenMirrorLocations) { + dir = (0, node_path_1.join)(ioBDataDir, dir) + node_path_1.sep; + if (dir.includes(this.config.mirrorPath) || this.config.mirrorPath.startsWith(dir)) { + this.log.error(`The Mirror directory is not allowed to be a central ioBroker directory!`); + this.log.error(`Directory ${this.config.mirrorPath} is not allowed to mirror files!`); + mirrorForbidden = true; + break; + } + } + if (!mirrorForbidden) { + this.mirror = new mirror_1.Mirror({ + adapter: this, + log: this.log, + diskRoot: this.config.mirrorPath, + }); + } + } + } + // CHeck setState counter per minute and stop script if too high + this.setStateCountCheckInterval = setInterval(() => { + Object.keys(this.scripts).forEach(id => { + if (!this.scripts[id]) { + return; + } + const currentSetStatePerMinuteCounter = this.scripts[id].setStatePerMinuteCounter; + this.scripts[id].setStatePerMinuteCounter = 0; + if (currentSetStatePerMinuteCounter > this.config.maxSetStatePerMinute) { + this.scripts[id].setStatePerMinuteProblemCounter++; + this.log.debug(`Script ${id} has reached the maximum of ${this.config.maxSetStatePerMinute} setState calls per minute in ${this.scripts[id].setStatePerMinuteProblemCounter} consecutive minutes`); + // Allow "too high counters" for 1 minute for script starts or such and only + // stop the script when lasts longer + if (this.scripts[id].setStatePerMinuteProblemCounter > 1) { + this.log.error(`Script ${id} is calling setState more than ${this.config.maxSetStatePerMinute} times per minute! Stopping Script now! Please check your script!`); + this.stopScript(id); + } + } + else if (this.scripts[id].setStatePerMinuteProblemCounter > 0) { + this.scripts[id].setStatePerMinuteProblemCounter--; + this.log.debug(`Script ${id} has NOT reached the maximum of ${this.config.maxSetStatePerMinute} setState calls per minute. Decrease problem counter to ${this.scripts[id].setStatePerMinuteProblemCounter}`); + } + }); + }, 60000); + } + loadTypeScriptDeclarations() { + // try to load the typings on disk for all 3rd party modules + const packages = [ + 'node', // this provides auto-completion for most builtins + '@iobroker/types', // this provides auto-completion for most builtins + ]; + // Also include user-selected libraries (but only those that are also installed) + if (typeof this.config?.libraries === 'string' && typeof this.config.libraryTypings === 'string') { + const installedLibs = this.config.libraries + .split(/[,;\s]+/) + .map(s => s.trim().split('@')[0]) + .filter(s => !!s); + const wantsTypings = this.config.libraryTypings + .split(/[,;\s]+/) + .map(s => s.trim()) + .filter(s => !!s); + // Add all installed libraries the user has requested typings for to the list of packages + for (const lib of installedLibs) { + if (wantsTypings.includes(lib) && !packages.includes(lib)) { + packages.push(lib); + } + } + // Some packages have submodules (e.g., rxjs/operators) that are not exposed through the main entry point + // If typings are requested for them, also add them if the base module is installed + for (const lib of wantsTypings) { + // Extract the package name and check if we need to add it + if (!lib.includes('/')) { + continue; + } + const pkgName = lib.substr(0, lib.indexOf('/')); + if (installedLibs.includes(pkgName) && !packages.includes(lib)) { + packages.push(lib); + } + } + } + for (const pkg of packages) { + let pkgTypings = (0, typescriptTools_1.resolveTypings)(pkg, this.getAdapterScopedPackageIdentifier ? this.getAdapterScopedPackageIdentifier(pkg) : pkg, + // node needs ambient typings, so we don't wrap it in declare module + pkg !== 'node'); + if (!pkgTypings) { + // Create the empty dummy declarations so users don't get the "not found" error + // for installed packages + pkgTypings = { + [`node_modules/@types/${pkg}/index.d.ts`]: `declare module "${pkg}";`, + }; + } + this.log.debug(`Loaded TypeScript definitions for ${pkg}: ${JSON.stringify(Object.keys(pkgTypings))}`); + // remember the declarations for the editor + Object.assign(tsAmbient, pkgTypings); + // and give the language servers access to them + this.tsServer.provideAmbientDeclarations(pkgTypings); + jsDeclarationServer.provideAmbientDeclarations(pkgTypings); + } + } + updateObjectContext(id, obj) { + if (obj) { + // add state to state ID's list + if (obj.type === 'state') { + if (!this.stateIds.includes(id)) { + this.stateIds.push(id); + this.stateIds.sort(); + } + if (this.context.devices && this.context.channels) { + const parts = id.split('.'); + parts.pop(); + const chn = parts.join('.'); + this.context.channels[chn] = this.context.channels[chn] || []; + this.context.channels[chn].push(id); + parts.pop(); + const dev = parts.join('.'); + this.context.devices[dev] = this.context.devices[dev] || []; + this.context.devices[dev].push(id); + } + } + } + else { + // delete object from state ID's list + const pos = this.stateIds.indexOf(id); + if (pos !== -1) { + this.stateIds.splice(pos, 1); + } + if (this.context.devices && this.context.channels) { + const parts = id.split('.'); + parts.pop(); + const chn = parts.join('.'); + if (this.context.channels[chn]) { + const posChn = this.context.channels[chn].indexOf(id); + posChn !== -1 && this.context.channels[chn].splice(posChn, 1); + } + parts.pop(); + const dev = parts.join('.'); + if (this.context.devices[dev]) { + const posDev = this.context.devices[dev].indexOf(id); + posDev !== -1 && this.context.devices[dev].splice(posDev, 1); + } + } + delete this.folderCreationVerifiedObjects[id]; + } + if (!obj && this.objects[id]) { + // objects was deleted + this.removeFromNames(id); + delete this.objects[id]; + } + else if (obj && !this.objects[id]) { + // object was added + this.objects[id] = obj; + this.addToNames(obj); + } + else if (obj && this.objects[id].common) { + // Object just changed + this.objects[id] = obj; + const n = this.getName(id); + let nn = this.objects[id].common ? this.objects[id].common.name : ''; + if (nn && typeof nn === 'object') { + nn = nn[(0, words_1.getLanguage)()] || nn.en; + } + if (n !== nn) { + if (n) { + this.removeFromNames(id); + } + if (nn) { + this.addToNames(obj); + } + } + } + } + async stopAllScripts() { + const scripts = Object.keys(this.scripts); + const promises = []; + for (let i = 0; i < scripts.length; i++) { + promises.push(this.stopScript(scripts[i])); + } + return Promise.all(promises).then(() => { }); + } + convertBackStringifiedValues(id, state) { + if (state && + typeof state.val === 'string' && + this.objects[id]?.common && + (this.objects[id].common.type === 'array' || this.objects[id].common.type === 'object')) { + try { + state.val = JSON.parse(state.val); + } + catch (err) { + if (id.startsWith('javascript.') || id.startsWith('0_userdata.0')) { + this.log.info(`Could not parse value for id ${id} into ${this.objects[id].common.type}: ${err.toString()}`); + } + else { + this.log.debug(`Could not parse value for id ${id} into ${this.objects[id].common.type}: ${err.toString()}`); + } + } + } + return state; + } + prepareStateObjectSimple(id, state, isAck) { + let oState; + if (typeof isAck === 'boolean') { + // otherwise, assume that the given state is the value to be set + oState = { val: state, ack: !!isAck }; + } + else { + oState = { val: state }; + } + return this.prepareStateObject(id, oState); + } + prepareStateObject(id, state) { + let oState; + if (state && typeof state === 'object') { + oState = state; + } + else { + oState = { val: null }; + } + if (this.config.subscribe) { + return oState; + } + // set other values to have a full state object + // mirrors logic from statesInRedis + if (oState.ts === undefined) { + oState.ts = Date.now(); + } + if (oState.q === undefined) { + oState.q = 0; + } + oState.from = + typeof oState.from === 'string' && oState.from !== '' ? oState.from : `system.adapter.${this.namespace}`; + if (oState.lc === undefined) { + const formerStateValue = this.interimStateValues[id] || this.states[id]; + if (!formerStateValue) { + oState.lc = oState.ts; + } + else { + // isDeepStrictEqual works on objects and primitive values + const hasChanged = !(0, node_util_1.isDeepStrictEqual)(formerStateValue.val, oState.val); + if (!formerStateValue.lc || hasChanged) { + oState.lc = oState.ts; + } + else { + oState.lc = formerStateValue.lc; + } + } + } + return oState; + } + async getData() { + await this.subscribeForeignObjectsAsync('*'); + if (!this.config.subscribe) { + await this.subscribeForeignStatesAsync('*'); + } + else { + await this.subscribeStatesAsync('debug.to'); + await this.subscribeStatesAsync('scriptEnabled.*'); + } + this.log.info('requesting all states'); + const statesPromise = this.getForeignStatesAsync('*') + .then(res => { + if (!res) { + this.log.error(`Could not initialize states: no result`); + this.terminate(adapter_core_1.EXIT_CODES.START_IMMEDIATELY_AFTER_STOP); + return; + } + if (!this.config.subscribe) { + this.states = Object.assign(res, this.states); + this.context.states = this.states; + this.addGetProperty(this.states); + } + // remember all IDs + for (const id in res) { + if (Object.prototype.hasOwnProperty.call(res, id)) { + this.stateIds.push(id); + } + } + this.statesInitDone = true; + this.log.info('received all states'); + }) + .catch((err) => { + this.log.error(`Could not initialize states: ${err?.message || 'no result'}`); + this.terminate(adapter_core_1.EXIT_CODES.START_IMMEDIATELY_AFTER_STOP); + }); + this.log.info('requesting all objects'); + const objectsPromise = this.getObjectListAsync({ include_docs: true }) + .then(res => { + if (!res?.rows) { + this.log.error(`Could not initialize objects: no result`); + this.terminate(adapter_core_1.EXIT_CODES.START_IMMEDIATELY_AFTER_STOP); + return; + } + this.objects = {}; + this.context.objects = this.objects; + for (let i = 0; i < res.rows.length; i++) { + if (!res.rows[i].doc) { + this.log.debug(`Got empty object for index ${i} (${res.rows[i].id})`); + continue; + } + if (this.objects[res.rows[i].doc._id] === undefined) { + // If was already there ignore + this.objects[res.rows[i].doc._id] = res.rows[i].doc; + } + this.objects[res.rows[i].doc._id].type === 'enum' && this._enums.push(res.rows[i].doc._id); + // Collect all names + this.addToNames(this.objects[res.rows[i].doc._id]); + } + this.addGetProperty(this.objects); + const systemConfig = this.objects['system.config']; + // set language for debug messages + if (systemConfig?.common?.language) { + (0, words_1.setLanguage)(systemConfig.common.language); + this.language = systemConfig.common.language; + this.context.language = this.language; + } + else if (this.language) { + (0, words_1.setLanguage)(this.language); + this.context.language = this.language; + } + // try to use system coordinates + if (this.config.useSystemGPS) { + if (systemConfig?.common?.latitude || systemConfig?.common?.longitude) { + this.config.latitude = systemConfig.common.latitude; + this.config.longitude = systemConfig.common.longitude; + } + else if (this.latitude && this.longitude) { + this.config.latitude = this.latitude; + this.config.longitude = this.longitude; + } + } + this.config.latitude = parseFloat(this.config.latitude); + this.config.longitude = parseFloat(this.config.longitude); + if (isNaN(this.config.latitude)) { + this.log.warn(`Configured latitude is not a number - check (instance/system) configuration`); + } + else if (this.config.latitude < -90 || this.config.latitude > 90) { + this.log.warn(`Configured latitude "${this.config.latitude}" is invalid - check (instance/system) configuration`); + } + if (isNaN(this.config.longitude)) { + this.log.warn(`Configured longitude is not a number - check (instance/system) configuration`); + } + else if (this.config.longitude < -180 || this.config.longitude > 180) { + this.log.warn(`Configured longitude "${this.config.longitude}" is invalid - check (instance/system) configuration`); + } + this.config.sunriseEvent = this.config.sunriseEvent || 'nightEnd'; + this.config.sunriseOffset = this.config.sunriseOffset || 0; + this.config.sunriseLimitStart = this.config.sunriseLimitStart || '06:00'; + this.config.sunriseLimitEnd = this.config.sunriseLimitEnd || '12:00'; + this.config.sunsetEvent = this.config.sunsetEvent || 'dusk'; + this.config.sunsetOffset = this.config.sunsetOffset || 0; + this.config.sunsetLimitStart = this.config.sunsetLimitStart || '18:00'; + this.config.sunsetLimitEnd = this.config.sunsetLimitEnd || '23:00'; + this.objectsInitDone = true; + this.log.info('received all objects'); + }) + .catch((err) => { + this.log.error(`Could not initialize objects: ${err?.message || 'no result'}`); + this.terminate(adapter_core_1.EXIT_CODES.START_IMMEDIATELY_AFTER_STOP); + }); + return Promise.all([statesPromise, objectsPromise]).then(() => { }); + } + async createActiveObject(id, enabled) { + const idActive = `${this.namespace}.scriptEnabled.${id.substring(SCRIPT_CODE_MARKER.length)}`; + if (!this.objects[idActive]) { + this.objects[idActive] = { + _id: idActive, + common: { + name: `scriptEnabled.${id.substring(SCRIPT_CODE_MARKER.length)}`, + desc: 'controls script activity', + type: 'boolean', + write: true, + read: true, + role: 'switch.active', + }, + native: { + script: id, + }, + type: 'state', + }; + try { + this.setForeignObjectAsync(idActive, this.objects[idActive]); + const intermediateStateValue = this.prepareStateObjectSimple(idActive, !!enabled, true); + await this.setForeignStateAsync(idActive, !!enabled, true); + if (enabled && !this.config.subscribe) { + this.interimStateValues[idActive] = intermediateStateValue; + } + } + catch { + // ignore + } + } + else { + const state = await this.getForeignStateAsync(idActive); + if (state && state.val !== enabled) { + const intermediateStateValue = this.prepareStateObjectSimple(idActive, !!enabled, true); + await this.setForeignStateAsync(idActive, !!enabled, true); + if (enabled && !this.config.subscribe) { + this.interimStateValues[id] = intermediateStateValue; + } + } + } + } + async createProblemObject(id) { + const idProblem = `${this.namespace}.scriptProblem.${id.substring(SCRIPT_CODE_MARKER.length)}`; + if (!this.objects[idProblem]) { + this.objects[idProblem] = { + _id: idProblem, + common: { + name: `scriptProblem.${id.substring(SCRIPT_CODE_MARKER.length)}`, + desc: 'Script has a problem', + type: 'boolean', + expert: true, + write: false, + read: true, + role: 'indicator.error', + }, + native: { + script: id, + }, + type: 'state', + }; + try { + await this.setForeignObjectAsync(idProblem, this.objects[idProblem]); + await this.setForeignStateAsync(idProblem, false, true); + } + catch { + // ignore + } + } + else { + const state = await this.getForeignStateAsync(idProblem); + if (state && state.val !== false) { + await this.setForeignStateAsync(idProblem, false, true); + } + } + } + addToNames(obj) { + const id = obj._id; + if (obj.common?.name) { + let name = obj.common.name; + if (name && typeof name === 'object') { + name = name[(0, words_1.getLanguage)()] || name.en; + } + if (!name || typeof name !== 'string') { + // TODO, take name in current language + return; + } + if (!this.names[name]) { + this.names[name] = id; + } + else { + // convert to array + if (!Array.isArray(this.names[name])) { + this.names[name] = [this.names[name]]; + } + this.names[name].push(id); + } + } + } + removeFromNames(id) { + const n = this.getName(id); + if (n) { + if (Array.isArray(this.names[n])) { + const pos = this.names[n].indexOf(id); + if (pos > -1) { + this.names[n].splice(pos, 1); + if (this.names[n].length === 1) { + this.names[n] = this.names[n][0]; + } + } + } + else { + delete this.names[n]; + } + } + } + getName(id) { + for (const n in this.names) { + if (this.names[n] && Array.isArray(this.names[n])) { + if (this.names[n].includes(id)) { + return n; + } + } + else if (this.names[n] === id) { + return n; + } + } + return null; + } + async installNpm(npmLib) { + return new Promise((resolve, reject) => { + const path = __dirname; + // Also, set the working directory (cwd) of the process instead of using --prefix + // because that has ugly bugs on Windows + const cmd = `npm install ${npmLib} --omit=dev`; + this.log.info(`Installing ${npmLib} into ${__dirname} - cmd: ${cmd}`); + // System call used for update of js-controller itself, + // because during the installation the npm packet will be deleted too, but some files must be loaded even during the installation process. + const child = this.mods.child_process.exec(cmd, { + windowsHide: true, + cwd: path, + }); + child.stdout?.on('data', buf => this.log.info(buf.toString('utf8'))); + child.stderr?.on('data', buf => this.log.error(buf.toString('utf8'))); + child.on('err', err => { + this.log.error(`Cannot install ${npmLib}: ${err}`); + reject(new Error(`Cannot install ${npmLib}: ${err}`)); + }); + child.on('error', err => { + this.log.error(`Cannot install ${npmLib}: ${err}`); + reject(new Error(`Cannot install ${npmLib}: ${err}`)); + }); + child.on('exit', (code /* , signal */) => { + if (code) { + this.log.error(`Cannot install ${npmLib}: ${code}`); + reject(new Error(`Cannot install ${npmLib}: ${code}`)); + } + // command succeeded + resolve(code); + }); + }); + } + async installLibraries() { + if (typeof this.config?.libraries !== 'string') { + this.config.libraries = ''; + } + const libraries = this.config.libraries + .split(/[,;\s]+/) + .map(d => d.trim()) + .filter(d => d); + this.log.debug(`Custom libraries in config: "${this.config.libraries}": ${JSON.stringify(libraries)}`); + let installedNodeModules = []; + const keepModules = []; + // js-controller >= 6.x + if (typeof this.listInstalledNodeModules === 'function') { + installedNodeModules = await this.listInstalledNodeModules(); + this.log.debug(`Found installed libraries: ${JSON.stringify(installedNodeModules)}`); + } + for (const lib of libraries) { + let depName = lib; + let version = 'latest'; + if (depName.includes('@') && depName.lastIndexOf('@') > 0) { + const parts = depName.split('@'); + version = parts.pop() ?? 'latest'; + depName = parts.join('@'); + } + /** The real module name, because the dependency can be an url too */ + let moduleName = depName; + if (URL.canParse(depName)) { + moduleName = await (0, nodeModulesManagement_1.requestModuleNameByUrl)(depName); + this.log.debug(`Found custom library in config: "${moduleName}@${version}" (from ${depName})`); + } + else { + this.log.debug(`Found custom library in config: "${moduleName}@${version}"`); + } + keepModules.push(moduleName); + // js-controller >= 6.x + if (typeof this.installNodeModule === 'function') { + try { + const result = await this.installNodeModule(depName, { version }); + if (result.success) { + this.log.debug(`Installed custom library: "${moduleName}@${version}"`); + const importedModule = await this.importNodeModule(moduleName); + this.mods[moduleName] = importedModule.default ?? importedModule; + } + else { + this.log.warn(`Cannot install custom npm package "${moduleName}@${version}"`); + } + } + catch (err) { + this.log.warn(`Cannot install custom npm package "${moduleName}@${version}": ${err}`); + } + } + else if (!(0, node_fs_1.existsSync)(`${__dirname}/node_modules/${depName}/package.json`)) { + // js-controller < 6.x + this.log.info(`Installing custom library (legacy mode): "${lib}"`); + try { + await this.installNpm(lib); + this.log.info(`Installed custom npm package (legacy mode): "${lib}"`); + } + catch (err) { + this.log.warn(`Cannot install custom npm package "${lib}" (legacy mode): ${err.toString()}`); + } + } + } + // js-controller >= 6.x + if (typeof this.uninstallNodeModule === 'function') { + for (const installedNodeModule of installedNodeModules) { + if (!keepModules.includes(installedNodeModule)) { + try { + await this.uninstallNodeModule(installedNodeModule); + this.log.info(`Removed custom npm package: "${installedNodeModule}"`); + } + catch (err) { + this.log.warn(`Cannot remove custom npm package ${installedNodeModule}: ${err.toString()}`); + } + } + } + } + } + createVM(source, name, wrapAsync) { + if (this.context.debugMode && name !== this.context.debugMode) { + return false; + } + if (!this.context.debugMode) { + const logSubscriptionsText = "\n;\nlog(`registered ${__engine.__subscriptions} subscription${__engine.__subscriptions === 1 ? '' : 's'}," + + " ${__engine.__schedules} schedule${__engine.__schedules === 1 ? '' : 's'}," + + " ${__engine.__subscriptionsMessage} message${__engine.__subscriptionsMessage === 1 ? '' : 's'}," + + " ${__engine.__subscriptionsLog} log${__engine.__subscriptionsLog === 1 ? '' : 's'}" + + " and ${__engine.__subscriptionsFile} file subscription${__engine.__subscriptionsFile === 1 ? '' : 's'}`);\n"; + if (wrapAsync) { + source = `(async () => {\n${source}\n${logSubscriptionsText}\n})();`; + } + else { + source = `${source}\n${logSubscriptionsText}`; + } + } + else { + if (wrapAsync) { + source = `(async () => {debugger;\n${source}\n})();`; + } + else { + source = `debugger;${source}`; + } + } + try { + const options = { + filename: name, + // displayErrors: true, + // lineOffset: this.globalScriptLines + }; + return { + script: new node_vm_1.Script(source, options), + }; + } + catch (err) { + this.logError(`${name} compile failed:\r\nat `, err); + return false; + } + } + execute(script, name, engineType, verbose, debug) { + script.intervals = []; + script.timeouts = []; + script.schedules = []; + script.wizards = []; + script.name = name; + script.engineType = engineType; + script._id = Math.floor(Math.random() * 0xffffffff); + script.subscribes = {}; + script.subscribesFile = {}; + script.setStatePerMinuteCounter = 0; + script.setStatePerMinuteProblemCounter = 0; + this.setState(`scriptProblem.${name.substring(SCRIPT_CODE_MARKER.length)}`, { + val: false, + ack: true, + expire: 1000, + }); + const sandbox = (0, sandbox_1.sandBox)(script, name, verbose, debug, this.context); + try { + script.script.runInNewContext(sandbox, { + filename: name, + displayErrors: true, + // lineOffset: this.globalScriptLines + }); + } + catch (err) { + this.setState(`scriptProblem.${name.substring(SCRIPT_CODE_MARKER.length)}`, { + val: true, + ack: true, + c: 'execute', + }); + this.logError(name, err); + } + } + unsubscribe(id) { + if (!id) { + this.log.warn('unsubscribe: empty name'); + return; + } + if (Array.isArray(id)) { + id.forEach(sub => unsubscribe(sub)); + return; + } + if (id.constructor && id.constructor.name === 'RegExp') { + // adapter.log.warn('unsubscribe: todo - process regexp'); + return; + } + if (typeof id !== 'string') { + this.log.error(`unsubscribe: invalid type of id - ${typeof id}`); + return; + } + const parts = id.split('.'); + const _adapter = `system.adapter.${parts[0]}.${parts[1]}`; + if (this.objects[_adapter]?.common?.subscribable) { + const a = `${parts[0]}.${parts[1]}`; + const alive = `system.adapter.${a}.alive`; + if (this.adapterSubs[alive]) { + const pos = this.adapterSubs[alive].indexOf(id); + if (pos !== -1) { + this.adapterSubs[alive].splice(pos, 1); + } + if (!this.adapterSubs[alive].length) { + delete this.adapterSubs[alive]; + } + } + this.sendTo(a, 'unsubscribe', id); + } + } + // Analyze if logs are still required or not + updateLogSubscriptions() { + let found = false; + // go through all scripts and check if some script still requires logs + Object.keys(this.logSubscriptions).forEach(scriptName => { + if (!this.logSubscriptions?.[scriptName] || !this.logSubscriptions[scriptName].length) { + delete this.logSubscriptions[scriptName]; + } + else { + found = true; + } + }); + if (this.requireLog) { + if (found && !this.logSubscribed) { + this.logSubscribed = true; + this.requireLog(this.logSubscribed); + this.log.info(`Subscribed to log messages (found logSubscriptions)`); + } + else if (!found && this.logSubscribed) { + this.logSubscribed = false; + this.requireLog(this.logSubscribed); + this.log.info(`Unsubscribed from log messages (not found logSubscriptions)`); + } + } + } + async stopScript(name) { + this.log.info(`Stopping script ${name}`); + await this.setState(`scriptEnabled.${name.substring(SCRIPT_CODE_MARKER.length)}`, false, true); + if (this.messageBusHandlers[name]) { + delete this.messageBusHandlers[name]; + } + if (this.tempDirectories[name]) { + try { + this.mods.fs.rmSync(this.tempDirectories[name], { recursive: true }); + this.log.debug(`Removed temp directory of ${name}: ${this.tempDirectories[name]}`); + } + catch { + this.log.warn(`Unable to remove temp directory of ${name}: ${this.tempDirectories[name]}`); + } + delete this.tempDirectories[name]; + } + if (this.logSubscriptions[name]) { + delete this.logSubscriptions[name]; + this.updateLogSubscriptions(); + } + if (this.scripts[name]) { + // Remove from subscriptions + this.context.isEnums = false; + if (this.config.subscribe) { + // check all subscribed IDs + Object.keys(this.scripts[name].subscribes).forEach(id => { + if (this.subscribedPatterns[id]) { + this.subscribedPatterns[id] -= this.scripts[name].subscribes[id]; + if (this.subscribedPatterns[id] <= 0) { + this.unsubscribeForeignStates(id); + delete this.subscribedPatterns[id]; + if (this.states[id]) { + delete this.states[id]; + } + } + } + }); + } + for (let i = this.subscriptions.length - 1; i >= 0; i--) { + if (this.subscriptions[i].name === name) { + const sub = this.subscriptions.splice(i, 1)[0]; + if (sub?.pattern.id) { + this.unsubscribe(sub.pattern.id); + } + } + else { + if ((!this.context.isEnums && this.subscriptions[i].pattern.enumName) || + this.subscriptions[i].pattern.enumId) { + this.context.isEnums = true; + } + } + } + // check all subscribed files + Object.keys(this.scripts[name].subscribesFile).forEach(key => { + if (this.subscribedPatternsFile[key]) { + this.subscribedPatternsFile[key] -= this.scripts[name].subscribesFile[key]; + if (this.subscribedPatternsFile[key] <= 0) { + const [id, file] = key.split('$%$'); + this.unsubscribeForeignFiles(id, file); + delete this.subscribedPatternsFile[key]; + } + } + }); + for (let i = this.subscriptionsFile.length - 1; i >= 0; i--) { + if (this.subscriptionsFile[i].name === name) { + this.subscriptionsFile.splice(i, 1); + } + } + for (let i = this.subscriptionsObject.length - 1; i >= 0; i--) { + if (this.subscriptionsObject[i].name === name) { + const sub = this.subscriptionsObject.splice(i, 1)[0]; + if (sub) { + this.unsubscribeForeignObjects(sub.pattern); + } + } + } + // Stop all timeouts + for (let i = 0; i < this.scripts[name].timeouts.length; i++) { + clearTimeout(this.scripts[name].timeouts[i]); + } + // Stop all intervals + for (let i = 0; i < this.scripts[name].intervals.length; i++) { + clearInterval(this.scripts[name].intervals[i]); + } + // Stop all scheduled jobs + for (let i = 0; i < this.scripts[name].schedules.length; i++) { + if (this.scripts[name].schedules[i]) { + const _name = this.scripts[name].schedules[i].name; + if (!this.mods.nodeSchedule.cancelJob(this.scripts[name].schedules[i])) { + this.log.error(`Error by canceling scheduled job "${_name}"`); + } + } + } + // Stop all time wizards jobs + if (this.context.scheduler) { + for (let i = 0; i < this.scripts[name].wizards.length; i++) { + if (this.scripts[name].wizards[i]) { + this.context.scheduler.remove(this.scripts[name].wizards[i]); + } + } + } + // if callback for on stop + if (typeof this.scripts[name].onStopCb === 'function') { + this.scripts[name].onStopTimeout = + parseInt(this.scripts[name].onStopTimeout, 10) || 1000; + await new Promise(resolve => { + let timeout = setTimeout(() => { + if (timeout) { + timeout = null; + resolve(true); + } + }, this.scripts[name].onStopTimeout); + try { + this.scripts[name].onStopCb(() => { + if (timeout) { + clearTimeout(timeout); + timeout = null; + resolve(true); + } + }); + } + catch (err) { + this.log.error(`error in onStop callback: ${err}`); + } + }); + } + delete this.scripts[name]; + return true; + } + return false; + } + async prepareScript(obj) { + if (obj?.common?.enabled && this.debugState.scriptName === obj._id) { + const id = obj._id; + await this.debugStop(); + this.log.info(`Debugging of ${id} was stopped, because started in normal mode`); + return this.prepareScript(obj); + } + if (obj?.common?.source && + (obj.common.enabled || this.context.debugMode === obj._id) && + obj.common.engine === `system.adapter.${this.namespace}`) { + const name = obj._id; + const nameId = name.substring(SCRIPT_CODE_MARKER.length); + if (!nameId.length || nameId.endsWith('.')) { + this.log.error(`Script name ${name} is invalid!`); + return false; + } + const idActive = `scriptEnabled.${nameId}`; + if (!this.config.subscribe) { + this.interimStateValues[idActive] = this.prepareStateObjectSimple(`${this.namespace}.${idActive}`, true, true); + } + await this.setState(idActive, true, true); + obj.common.engineType = obj.common.engineType || ''; + if (obj.common.engineType.toLowerCase().startsWith('javascript') || + obj.common.engineType === 'Blockly' || + obj.common.engineType === 'Rules') { + // Javascript + this.log.info(`Start JavaScript ${name} (${obj.common.engineType})`); + let sourceFn = name; + if (webstormDebug) { + const fn = name.replace(/^script.js./, '').replace(/\./g, '/'); + sourceFn = this.mods.path.join(webstormDebug, `${fn}.js`); + } + const createdScript = this.createVM(`${this.globalScript}\n${obj.common.source}`, sourceFn, true); + if (!createdScript) { + return false; + } + this.scripts[name] = createdScript; + this.execute(this.scripts[name], sourceFn, obj.common.engineType, obj.common.verbose, obj.common.debug); + return true; + } + if (obj.common.engineType.toLowerCase().startsWith('typescript')) { + // TypeScript + this.log.info(`Compiling TypeScript source ${name}`); + // The source code must be transformed in order to support top level await + // and to force TypeScript to compile the code as a module + const transformedSource = (0, typescriptTools_1.transformScriptBeforeCompilation)(obj.common.source, false); + // We need to hash both global declarations that are known until now + // AND the script source, because changing either can change the compilation output + const sourceHash = (0, tools_1.hashSource)(tsSourceHashBase + this.globalDeclarations + transformedSource); + let compiled; + // If we already stored the compiled source code and the original source hash, + // use the hash to check whether we can rely on the compiled source code or + // if we need to compile it again + if (typeof obj.common.compiled === 'string' && + typeof obj.common.sourceHash === 'string' && + sourceHash === obj.common.sourceHash) { + // We can reuse the stored source + compiled = obj.common.compiled; + this.log.info(`${name}: source code did not change, using cached compilation result...`); + } + else { + // We don't have a hashed source code, or the original source changed, compile it + const filename = (0, typescriptTools_1.scriptIdToTSFilename)(name); + let tsCompiled; + try { + tsCompiled = this.tsServer.compile(filename, transformedSource); + } + catch (err) { + this.log.error(`${obj._id}: TypeScript compilation failed:\n${err}`); + return false; + } + const errors = tsCompiled.diagnostics.map(diag => `${diag.annotatedSource}\n`).join('\n'); + if (tsCompiled.success) { + if (errors.length > 0) { + this.log.warn(`${name}: TypeScript compilation had errors:\n${errors}`); + } + else { + this.log.info(`${name}: TypeScript compilation successful`); + } + compiled = tsCompiled.result || ''; + // Store the compiled source and the original source hash, so we don't need to do the work again next time + this.ignoreObjectChange.add(name); // ignore the next change and don't restart scripts + await this.extendForeignObjectAsync(name, { + common: { + sourceHash, + compiled, + }, + }); + } + else { + this.log.error(`${name}: TypeScript compilation failed:\n${errors}`); + return false; + } + } + const createdScript = this.createVM(`${this.globalScript}\n${compiled}`, name, false); + if (!createdScript) { + return false; + } + this.scripts[name] = createdScript; + this.execute(this.scripts[name], name, obj.common.engineType, obj.common.verbose, obj.common.debug); + return true; + } + this.log.warn(`Unknown engine type for "${name}": ${obj.common.engineType}`); + return false; + } + let _name; + if (obj?._id) { + _name = obj._id; + const scriptIdName = _name.substring(SCRIPT_CODE_MARKER.length); + if (!scriptIdName.length || scriptIdName.endsWith('.')) { + this.log.error(`Script name ${_name} is invalid!`); + return false; + } + await this.setState(`scriptEnabled.${scriptIdName}`, false, true); + } + if (!obj) { + this.log.error('Invalid script'); + } + return false; + } + async loadScriptById(id) { + let obj; + try { + obj = (await this.getForeignObjectAsync(id)); + } + catch (err) { + this.log.error(`Invalid script "${id}": ${err}`); + } + if (!obj) { + return false; + } + return this.loadScript(obj); + } + async loadScript(nameOrObject) { + // create states for scripts + await this.createActiveObject(nameOrObject._id, nameOrObject?.common?.enabled); + await this.createProblemObject(nameOrObject._id); + return this.prepareScript(nameOrObject); + } + getAstroEvent(date, astroEvent, start, end, offsetMinutes, isDayEnd, latitude, longitude, useNextDay) { + let ts = this.mods.suncalc.getTimes(date, latitude, longitude)[astroEvent]; + if (!ts || ts.getTime().toString() === 'NaN') { + ts = isDayEnd ? getNextTimeEvent(end, useNextDay) : getNextTimeEvent(start, useNextDay); + } + ts.setMilliseconds(0); + ts.setMinutes(ts.getMinutes() + (parseInt(offsetMinutes, 10) || 0)); + const [timeHoursStart, timeMinutesStart] = start.split(':'); + const nTimeHoursStart = parseInt(timeHoursStart, 10); + const nTimeMinutesStart = parseInt(timeMinutesStart, 10) || 0; + if (ts.getHours() < nTimeHoursStart || + (ts.getHours() === nTimeHoursStart && ts.getMinutes() < nTimeMinutesStart)) { + ts = getNextTimeEvent(start, useNextDay); + ts.setSeconds(0); + } + const [timeHoursEnd, timeMinutesEnd] = end.split(':'); + const nTimeHoursEnd = parseInt(timeHoursEnd, 10); + const nTimeMinutesEnd = parseInt(timeMinutesEnd, 10) || 0; + if (ts.getHours() > nTimeHoursEnd || (ts.getHours() === nTimeHoursEnd && ts.getMinutes() > nTimeMinutesEnd)) { + ts = getNextTimeEvent(end, useNextDay); + ts.setSeconds(0); + } + // if event in the past + if (date > ts && useNextDay) { + // take the next day + ts.setDate(ts.getDate() + 1); + } + return ts; + } + async timeSchedule() { + const now = new Date(); + let hours = now.getHours(); + const minutes = now.getMinutes(); + if (this.timeSettings.format12) { + if (hours > 12) { + hours -= 12; + } + } + let sHours; + if (this.timeSettings.leadingZeros) { + sHours = hours.toString().padStart(2, '0'); + } + else { + sHours = hours.toString(); + } + await this.setState('variables.dayTime', { + val: `${sHours}:${minutes.toString().padStart(2, '0')}`, + ack: true, + }); + now.setMinutes(now.getMinutes() + 1); + now.setSeconds(0); + now.setMilliseconds(0); + const interval = now.getTime() - Date.now(); + this.timeScheduleTimer = setTimeout(() => this.timeSchedule(), interval); + } + async dayTimeSchedules() { + // get astrological event + if (this.config.latitude === undefined || + this.config.longitude === undefined || + this.config.latitude === '' || + this.config.longitude === '' || + this.config.latitude === null || + this.config.longitude === null) { + this.log.error('Longitude or latitude does not set. Cannot use astro.'); + return; + } + // Calculate the next event today + const todayDate = getAstroStartOfDay(); + const nowDate = new Date(); + const todaySunrise = this.getAstroEvent(todayDate, this.config.sunriseEvent, this.config.sunriseLimitStart, this.config.sunriseLimitEnd, this.config.sunriseOffset, false, this.config.latitude, this.config.longitude); + const todaySunset = this.getAstroEvent(todayDate, this.config.sunsetEvent, this.config.sunsetLimitStart, this.config.sunsetLimitEnd, this.config.sunsetOffset, true, this.config.latitude, this.config.longitude); + // Sunrise + let sunriseTimeout = todaySunrise.getTime() - nowDate.getTime(); + if (sunriseTimeout < 0 || sunriseTimeout > 3600000) { + sunriseTimeout = 3600000; + } + // Sunset + let sunsetTimeout = todaySunset.getTime() - nowDate.getTime(); + if (sunsetTimeout < 0 || sunsetTimeout > 3600000) { + sunsetTimeout = 3600000; + } + const isDayTime = await this.getStateAsync('variables.isDayTime'); + let isDay; + if (sunriseTimeout < 5000) { + isDay = true; + } + else if (sunsetTimeout < 5000) { + isDay = false; + } + else { + // check if in between + isDay = nowDate.getTime() > todaySunrise.getTime() - 60000 && nowDate <= todaySunset; + } + const valDayTime = isDayTime ? !!isDayTime.val : false; + if (valDayTime !== isDay || isDayTime === null) { + await this.setState('variables.isDayTime', isDay, true); + } + const dayLightSaving = await this.getStateAsync('variables.isDaylightSaving'); + const isDayLightSaving = dstOffsetAtDate(nowDate) !== 0; + const val = dayLightSaving ? !!dayLightSaving.val : false; + if (val !== isDayLightSaving || dayLightSaving === null) { + await this.setState('variables.isDaylightSaving', isDayLightSaving, true); + } + let nextTimeout = sunriseTimeout; + if (sunriseTimeout > sunsetTimeout) { + nextTimeout = sunsetTimeout; + } + nextTimeout = nextTimeout - 3000; + if (nextTimeout < 3000) { + nextTimeout = 3000; + } + this.dayScheduleTimer = setTimeout(() => this.dayTimeSchedules(), nextTimeout); + } + stopTimeSchedules() { + if (this.dayScheduleTimer) { + clearTimeout(this.dayScheduleTimer); + this.dayScheduleTimer = null; + } + if (this.sunScheduleTimer) { + clearTimeout(this.sunScheduleTimer); + this.sunScheduleTimer = null; + } + if (this.timeScheduleTimer) { + clearTimeout(this.timeScheduleTimer); + this.timeScheduleTimer = null; + } + } + async patchFont() { + let stat; + let dbFile; + try { + stat = (0, node_fs_1.statSync)(`${__dirname}/admin/vs/base/browser/ui/codicons/codicon/codicon.ttf`); + const _dbFile = await this.readFileAsync('javascript.admin', `vs/base/browser/ui/codicons/codicon/codicon.ttf`); + if (_dbFile?.file) { + dbFile = _dbFile.file; + } + } + catch { + // ignore + } + if (stat?.size !== 73452 || dbFile?.byteLength !== 73452) { + try { + const buffer = Buffer.from(JSON.parse((0, node_fs_1.readFileSync)(`${__dirname}/admin/vsFont/codicon.json`).toString()), 'base64'); + const jszip = await Promise.resolve().then(() => __importStar(require('jszip'))); + const zip = await jszip.loadAsync(buffer); + let data; + if (zip) { + data = await zip.file('codicon.ttf')?.async('arraybuffer'); + if (data?.byteLength !== 73452) { + this.log.error(`Cannot patch font: invalid font file!`); + return false; + } + } + else { + this.log.error(`Cannot patch font: invalid font file!`); + return false; + } + (0, node_fs_1.writeFileSync)(`${__dirname}/admin/vs/base/browser/ui/codicons/codicon/codicon.ttf`, Buffer.from(data)); + // upload this file + await this.writeFileAsync('javascript.admin', 'vs/base/browser/ui/codicons/codicon/codicon.ttf', Buffer.from(data)); + return true; + } + catch (err) { + this.log.error(`Cannot patch font: ${err}`); + return false; + } + } + return false; + } + async sunTimeSchedules() { + if (this.config.createAstroStates) { + if (!isNaN(this.config.longitude) && !isNaN(this.config.longitude)) { + const calcDate = getAstroStartOfDay(); + const times = this.mods.suncalc.getTimes(calcDate, this.config.latitude, this.config.longitude); + this.log.debug(`[sunTimeSchedules] Times: ${JSON.stringify(times)}`); + for (const t in times) { + try { + const objId = `variables.astro.${t}`; + await this.setObjectNotExistsAsync(objId, { + type: 'state', + common: { + name: `Astro ${t}`, + type: 'string', + role: 'value', + read: true, + write: false, + }, + native: {}, + }); + if (times[t] !== null && !isNaN(times[t].getTime())) { + const timeFormatted = formatHoursMinutesSeconds(times[t]); + await this.setState(objId, { + val: timeFormatted, + c: times[t].toISOString(), + ack: true, + }); + } + else { + await this.setState(objId, { val: null, c: 'n/a', ack: true, q: 0x01 }); + } + } + catch (err) { + this.log.error(`[sunTimeSchedules] Unable to set state for astro time "${t}" (${times[t].getTime()}): ${err}`); + } + } + const todayDate = new Date(); + todayDate.setHours(0); + todayDate.setMinutes(0); + todayDate.setSeconds(1); + todayDate.setMilliseconds(0); + todayDate.setDate(todayDate.getDate() + 1); + this.log.debug(`[sunTimeSchedules] Next: ${todayDate.toISOString()}`); + this.sunScheduleTimer = setTimeout(() => this.sunTimeSchedules(), todayDate.getTime() - Date.now()); + } + } + else { + // remove astro states if disabled + this.delObject('variables.astro', { recursive: true }); + } + } + /** + * Redirects the virtual-tsc log output to the ioBroker log + */ + tsLog = (message, severity) => { + // shift the severities around, we don't care about the small details + if (!severity || severity === 'info') { + severity = 'debug'; + } + else if (severity === 'debug') { + // Don't spam build logs on Travis + if (isCI) { + return; + } + severity = 'silly'; + } + if (this?.log) { + this.log[severity](message); + } + else { + console.log(`[${severity.toUpperCase()}] ${message}`); + } + }; + addGetProperty(object) { + try { + Object.defineProperty(object, 'get', { + value: function (id) { + return this[id] || this[`${this.namespace}.${id}`]; + }, + enumerable: false, + }); + } + catch { + console.error('Cannot install get property'); + } + } + /** + * @param scriptID - The current script the declarations were generated from + * @param declarations + */ + provideDeclarationsForGlobalScript(scriptID, declarations) { + // Remember which declarations this global script had access to, + // we need this so the editor doesn't show a duplicate identifier error + if (this.globalDeclarations != null && this.globalDeclarations !== '') { + this.knownGlobalDeclarationsByScript[scriptID] = this.globalDeclarations; + } + // and concatenate the global declarations for the next scripts + this.globalDeclarations += `${declarations}\n`; + // remember all previously generated global declarations, + // so global scripts can reference each other + const globalDeclarationPath = 'global.d.ts'; + tsAmbient[globalDeclarationPath] = this.globalDeclarations; + // make sure the next script compilation has access to the updated declarations + this.tsServer.provideAmbientDeclarations({ + [globalDeclarationPath]: this.globalDeclarations, + }); + jsDeclarationServer.provideAmbientDeclarations({ + [globalDeclarationPath]: this.globalDeclarations, + }); + } + fixLineNo(line) { + if (line.includes('javascript.js:')) { + return line; + } + if (!/script[s]?\.js[.\\/]/.test(line)) { + return line; + } + if (/:([\d]+):/.test(line)) { + line = line.replace(/:([\d]+):/, ($0, $1) => `:${$1 > this.globalScriptLines + 1 ? $1 - this.globalScriptLines - 1 : $1}:`); // one line for 'async function ()' + } + else { + line = line.replace(/:([\d]+)$/, ($0, $1) => `:${$1 > this.globalScriptLines + 1 ? $1 - this.globalScriptLines - 1 : $1}`); // one line for 'async function ()' + } + return line; + } + debugStop() { + if (this.debugState.child) { + this.debugSendToInspector({ cmd: 'end' }); + this.debugState.endTimeout = setTimeout(() => { + this.debugState.endTimeout = null; + this.debugState.child?.kill('SIGTERM'); + }, 500); + this.debugState.promiseOnEnd = this.debugState.promiseOnEnd || Promise.resolve(0); + } + else { + this.debugState.promiseOnEnd = Promise.resolve(0); + } + return this.debugState.promiseOnEnd.then(() => { + this.debugState.child = null; + this.debugState.running = false; + this.debugState.scriptName = ''; + if (this.debugState.endTimeout) { + clearTimeout(this.debugState.endTimeout); + this.debugState.endTimeout = null; + } + }); + } + async debugDisableScript(id) { + if (id) { + const obj = this.objects[id]; + if (obj?.common?.enabled) { + await this.extendForeignObjectAsync(obj._id, { common: { enabled: false } }); + } + } + } + debugSendToInspector(message) { + if (this.debugState.child) { + try { + this.log.info(`send to debugger: ${message}`); + this.debugState.child.send(message); + } + catch { + this.debugStop().then(() => this.log.info(`Debugging of "${this.debugState.scriptName}" was stopped, because started in normal mode`)); + } + } + else { + this.log.error(`Cannot send command to terminated inspector`); + this.setState('debug.from', JSON.stringify({ cmd: 'error', error: `Cannot send command to terminated inspector`, id: 1 }), true); + } + } + debugStart(data) { + if (Date.now() - this.debugState.started < 1000) { + console.log('Start ignored'); + return; + } + this.debugState.started = Date.now(); + // stop the script if it's running + this.debugDisableScript(data.scriptName) + .then(() => this.debugStop()) + .then(() => { + if (data.adapter) { + this.debugState.adapterInstance = data.adapter; + this.debugState.scriptName = ''; + } + else { + this.debugState.adapterInstance = ''; + this.debugState.scriptName = data.scriptName; + } + this.debugState.breakOnStart = data.breakOnStart; + this.debugState.promiseOnEnd = new Promise(resolve => { + const options = { + stdio: ['ignore', 'inherit', 'inherit', 'ipc'], + //stdio: ['pipe', 'pipe', 'pipe', 'ipc'] + }; + const args = []; + if (this.debugState.adapterInstance) { + args.push('--breakOnStart'); + } + this.debugState.child = (0, node_child_process_1.fork)(`${__dirname}/lib/inspect.ts`, args, options); + /*debugState.child.stdout.setEncoding('utf8'); + debugState.child.stderr.setEncoding('utf8'); + debugState.child.stdout.on('data', childPrint); + debugState.child.stderr.on('data', childPrint);*/ + this.debugState.child?.on('message', (message) => { + let oMessage; + if (typeof message === 'string') { + try { + oMessage = JSON.parse(message); + } + catch { + return this.log.error(`Cannot parse message from inspector: ${message}`); + } + } + else { + oMessage = message; + } + if (oMessage.cmd !== 'ready') { + this.setState('debug.from', JSON.stringify(oMessage), true); + } + switch (oMessage.cmd) { + case 'ready': { + this.debugSendToInspector({ + cmd: 'start', + scriptName: this.debugState.scriptName, + adapterInstance: this.debugState.adapterInstance, + instance: this.instance, + }); + break; + } + case 'watched': { + //console.log(`WATCHED: ${JSON.stringify(oMessage)}`); + break; + } + case 'paused': { + this.debugState.paused = true; + console.log(`host: PAUSED`); + break; + } + case 'resumed': { + this.debugState.paused = false; + //console.log(`STARTED`); + break; + } + case 'log': { + console.log(`[${oMessage.severity}] ${oMessage.text}`); + break; + } + case 'readyToDebug': { + console.log(`host: readyToDebug (set breakpoints): [${oMessage.scriptId}] ${oMessage.script}`); + break; + } + } + }); + this.debugState.child?.on('error', error => { + this.log.error(`Cannot start inspector: ${error}`); + this.setState('debug.from', JSON.stringify({ cmd: 'error', error }), true); + }); + this.debugState.child?.on('exit', (code) => { + if (code) { + this.setState('debug.from', JSON.stringify({ cmd: 'error', error: `invalid response code: ${code}` }), true); + } + this.setState('debug.from', JSON.stringify({ cmd: 'debugStopped', code }), true); + this.debugState.child = null; + resolve(code); + }); + }); + }); + } +} +function patternMatching(event, patternFunctions) { + let matched = false; + for (let i = 0, len = patternFunctions.length; i < len; i++) { + if (patternFunctions[i](event)) { + if (patternFunctions.logic === 'or') { + return true; + } + matched = true; + } + else if (patternFunctions.logic === 'and') { + return false; + } + } + return matched; +} +// If started as allInOne mode => return function to create instance +if (require.main !== module) { + // Export the constructor in compact mode + module.exports = (options) => new JavaScript(options); +} +else { + // otherwise start the instance directly + (() => new JavaScript())(); +} +//# sourceMappingURL=main.js.map \ No newline at end of file diff --git a/build-backend/main.js.map b/build-backend/main.js.map new file mode 100644 index 00000000..de61dd52 --- /dev/null +++ b/build-backend/main.js.map @@ -0,0 +1 @@ +{"version":3,"file":"main.js","sourceRoot":"","sources":["../src/main.ts"],"names":[],"mappings":";AAAA;;;;;;;;GAQG;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEH,qCAAqD;AACrD,qCAAwF;AACxF,yCAAiD;AACjD,2DAA4D;AAC5D,6CAAkE;AAClE,yCAA8C;AAE9C,kDAAoC;AACpC,oDAAsC;AACtC,8CAAgC;AAChC,oDAAsC;AACtC,gDAAkC;AAClC,kDAAoC;AACpC,kDAAoC;AACpC,8CAAgC;AAChC,4CAA8B;AAC9B,gDAAkC;AAClC,gDAAkC;AAClC,kEAAoD;AACpD,oDAAsC;AACtC,gDAAkC;AAElC,sCAAsC;AACtC,kDAAoC;AACpC,6CAA+B;AAC/B,sCAAsC;AACtC,yDAA2C;AAC3C,4DAA8C;AAE9C,yDAA6G;AAK7G,yCAAsC;AACtC,gEAAwC;AACxC,uCAAuD;AACvD,2CAAwC;AACxC,uEAAqE;AACrE,6CAAkE;AAClE,+CAAiE;AACjE,iEAAwG;AACxG,uCAAyC;AACzC,2DAM+B;AAuC/B;;;;GAIG;AACH,MAAM,wBAAwB,GAAa;IACvC,gBAAgB;IAChB,OAAO;IACP,UAAU;IACV,YAAY;IACZ,iBAAiB;IACjB,QAAQ;CACX,CAAC;AAEF,MAAM,WAAW,GAAwB,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,GAAG,SAAS,kBAAkB,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC;AAC7G,MAAM,kBAAkB,GAAG,YAAY,CAAC;AAExC,IAAI,aAAiC,CAAC;AAEtC,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;AAE9B,sCAAsC;AACtC,IAAI,SAAiC,CAAC;AAEtC,yEAAyE;AACzE,kHAAkH;AAClH,qCAAqC;AACrC,qDAAqD;AACrD,MAAM,gBAAgB,GAAG,oBAAoB,WAAW,CAAC,OAAO,eAAe,WAAW,CAAC,YAAY,CAAC,UAAU,EAAE,CAAC;AAErH,2IAA2I;AAC3I,SAAS,eAAe,CAAC,SAAe;IACpC,MAAM,QAAQ,GAAW,SAAS,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;IACrD,8EAA8E;IAC9E,gFAAgF;IAChF,0EAA0E;IAC1E,gDAAgD;IAChD,MAAM,UAAU,GAAU,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAClF,8CAA8C;IAC9C,+EAA+E;IAC/E,MAAM,SAAS,GAAW,SAAS,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;IACnD,OAAO;IACH,qDAAqD;IACrD,CAAC,SAAS,GAAG,yCAAyC;QACtD,uEAAuE;QACvE,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,GAAG,6CAA6C;QACtE,2EAA2E;QAC3E,2EAA2E;QAC3E,0DAA0D;QAC1D,mEAAmE;QACnE,kEAAkE;QAClE,mEAAmE;QACnE,8CAA8C;QAC9C,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,qCAAqC;YAC1C,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,GAAG,2BAA2B;YACtD,CAAC,CAAC,EAAE,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,WAAW;YAC1D,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ;YACxC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,QAAQ;YACxC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM;YACtC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO;YACvC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,OAAO;YACvC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,SAAS;YACzC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,YAAY;YAC5C,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,UAAU;YAC1C,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,WAAW;YAC5C,mEAAmE;YACnE,qEAAqE;YAErE,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC,GAAG,uBAAuB;YACpD,MAAM,CAAC;YACP,EAAE;YACF,EAAE,GAAG,2CAA2C;YAChD,CAAC,SAAS,CAAC,QAAQ,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,wBAAwB;YAC7D,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,CAAC;YAChC,CAAC,CAAC;YACF,EAAE;YACF,IAAI,GAAG,yDAAyD;QACpE,CAAC,SAAS,CAAC,UAAU,EAAE,GAAG,IAAI,CAAC,GAAG,IAAI,GAAG,gCAAgC;QACzE,SAAS,CAAC,eAAe,EAAE,CAC9B,CAAC;AACN,CAAC;AAED,MAAM,cAAc,GAAG,UAAU,CAAC;AAClC,MAAM,cAAc,GAAG,sBAAsB,CAAC;AAE9C,SAAS,aAAa,CAAC,GAA0B;IAC7C,OAAO,GAAG,EAAE,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;AACjG,CAAC;AAED,SAAS,YAAY,CAAC,GAA2B,EAAE,EAAU,EAAE,QAAgB;IAC3E,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;QACd,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC;YACxB,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;SAAM,CAAC;QACJ,IAAI,GAAG,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;YAChB,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IACD,IAAI,GAAG,CAAC,SAAS,EAAE,CAAC;QAChB,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC;YAChC,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;SAAM,CAAC;QACJ,IAAI,GAAG,CAAC,eAAe,KAAK,QAAQ,EAAE,CAAC;YACnC,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAED,SAAS,gBAAgB,CAAC,IAAY,EAAE,UAAoB;IACxD,MAAM,GAAG,GAAS,kBAAkB,EAAE,CAAC;IACvC,MAAM,CAAC,SAAS,EAAE,WAAW,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACjD,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;IAC3C,MAAM,YAAY,GAAG,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAC/C,IACI,UAAU;QACV,CAAC,GAAG,CAAC,QAAQ,EAAE,GAAG,UAAU,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,KAAK,UAAU,IAAI,GAAG,CAAC,UAAU,EAAE,GAAG,YAAY,CAAC,CAAC,EACrG,CAAC;QACC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;IACnC,CAAC;IAED,GAAG,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC;IACzB,GAAG,CAAC,UAAU,CAAC,YAAY,CAAC,CAAC;IAE7B,OAAO,GAAG,CAAC;AACf,CAAC;AAED,SAAS,kBAAkB;IACvB,MAAM,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC;IACrB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAChB,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;IACrB,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,iBAAiB,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAC;IAC3D,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAEjB,OAAO,CAAC,CAAC;AACb,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAU;IACzC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;IAClC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IACpC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC;IAEpC,OAAO,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AAC/E,CAAC;AAED,iFAAiF;AACjF,sIAAsI;AACtI,qDAAqD;AACrD,IAAA,yCAA2B,EAAC;IACxB,KAAK,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;CACzC,CAAC,CAAC;AAEH,+CAA+C;AAC/C,MAAM,mBAAmB,GAAW,IAAI,oBAAM,CAAC,iDAA4B,EAAE,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;AACvG;;;GAGG;AAEH,MAAM,UAAW,SAAQ,sBAAO;IAGX,OAAO,CAAoB;IAEpC,gBAAgB,CAMtB;IAEe,IAAI,CAAU;IAEvB,eAAe,GAAG,KAAK,CAAC;IACxB,cAAc,GAAG,KAAK,CAAC;IAEvB,OAAO,GAAoC,EAAE,CAAC;IAC9C,MAAM,GAAmC,EAAE,CAAC;IACnC,kBAAkB,GAAmC,EAAE,CAAC;IACxD,QAAQ,GAAa,EAAE,CAAC;IACxB,aAAa,GAAyB,EAAE,CAAC;IACzC,iBAAiB,GAA6B,EAAE,CAAC;IACjD,mBAAmB,GAAsB,EAAE,CAAC;IAC5C,kBAAkB,GAA2B,EAAE,CAAC;IAChD,sBAAsB,GAA2B,EAAE,CAAC;IACpD,WAAW,GAA6B,EAAE,CAAC;IAC3C,MAAM,GAAgD,EAAE,CAAC;IACzD,MAAM,GAAa,EAAE,CAAC;IACtB,KAAK,GAA0C,EAAE,CAAC,CAAC,WAAW;IAC9D,OAAO,GAA6B,EAAE,CAAC;IACvC,kBAAkB,GAG/B,EAAE,CAAC;IACU,gBAAgB,GAQ7B,EAAE,CAAC;IACU,eAAe,GAAqC,EAAE,CAAC,CAAC,aAAa;IACrE,6BAA6B,GAA4B,EAAE,CAAC;IAE7E,oCAAoC;IAC5B,aAAa,GAAG,KAAK,CAAC;IAEtB,YAAY,GAGhB,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;IAEpC,gBAAgB,GAA0B,IAAI,CAAC,CAAC,gCAAgC;IAChF,gBAAgB,GAA0B,IAAI,CAAC,CAAC,gCAAgC;IAChF,iBAAiB,GAA0B,IAAI,CAAC,CAAC,gCAAgC;IAEjF,SAAS,GAAG,EAAE,CAAC,CAAC,uBAAuB;IAEvC,MAAM,CAAqB;IAE3B,YAAY,GAA2B,EAAE,CAAC;IAE1C,0BAA0B,GAA0B,IAAI,CAAC;IAEzD,YAAY,GAAG,EAAE,CAAC;IAC1B,oDAAoD;IAC5C,kBAAkB,GAAG,EAAE,CAAC;IAChC,gDAAgD;IAChD,8DAA8D;IACtD,+BAA+B,GAA2B,EAAE,CAAC;IAC7D,iBAAiB,GAAG,CAAC,CAAC;IAC9B,mCAAmC;IAC3B,QAAQ,CAAS;IAER,kBAAkB,GAAgB,IAAI,GAAG,EAAE,CAAC;IAErD,UAAU,GAAe;QAC7B,UAAU,EAAE,EAAE;QACd,KAAK,EAAE,IAAI;QACX,YAAY,EAAE,IAAI;QAClB,MAAM,EAAE,KAAK;QACb,OAAO,EAAE,CAAC;QACV,OAAO,EAAE,KAAK;KACjB,CAAC;IAEF,YAAY,UAAmC,EAAE;QAC7C,OAAO,GAAG;YACN,GAAG,OAAO;YACV,IAAI,EAAE,YAAY,EAAE,eAAe;YACnC,aAAa,EAAE,IAAI;YACnB;;;eAGG;YACH,KAAK,EAAE,CAAC,GAAU,EAAW,EAAE;gBAC3B,kEAAkE;gBAClE,mEAAmE;gBACnE,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;oBACvC,MAAM,qBAAqB,GAAG,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;oBACpE,IAAI,qBAAqB,GAAG,CAAC,CAAC,EAAE,CAAC;wBAC7B,yBAAyB;wBACzB,IAAI,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;wBAC5D,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,CAAC,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;wBAC9D,IAAI,CAAC,QAAQ,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;wBAE/B,mCAAmC;wBACnC,kEAAkE;wBAClE,OAAO,IAAI,CAAC;oBAChB,CAAC;oBACD,+DAA+D;oBAC/D,8EAA8E;oBAC9E,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,gDAAgD,CAAC,EAAE,CAAC;wBACrE,2FAA2F;wBAC3F,0CAA0C;wBAC1C,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,oHAAoH,CACvH,CAAC;wBACF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;wBACxC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;wBAE1B,kEAAkE;wBAClE,OAAO,IAAI,CAAC;oBAChB,CAAC;gBACL,CAAC;gBAED,OAAO,KAAK,CAAC;YACjB,CAAC;SACJ,CAAC;QAEF,KAAK,CAAC,OAAyB,CAAC,CAAC;QAEjC,IAAI,CAAC,EAAE,CAAC,cAAc,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACxD,IAAI,CAAC,EAAE,CAAC,aAAa,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACtD,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1C,IAAI,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC9C,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC5C,IAAI,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QACpD,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEtC,IAAI,CAAC,IAAI,GAAG;YACR,EAAE,EAAE,EAAe;YACnB,aAAa,EAAE,EAA2B;YAC1C,KAAK;YACL,MAAM;YACN,GAAG;YACH,MAAM;YACN,IAAI;YACJ,KAAK;YACL,KAAK;YACL,GAAG;YACH,EAAE;YACF,IAAI;YACJ,IAAI;YACJ,aAAa;YACb,MAAM;YACN,IAAI;YAEJ,OAAO;YACP,KAAK;YACL,WAAW;YACX,YAAY;SACf,CAAC;QAEF,gDAAgD;QAChD,IAAI,SAA6B,CAAC;QAClC,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;YACf,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3C,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;oBAC3C,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;gBAC9D,CAAC;gBACD,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,eAAe,EAAE,CAAC;oBACtC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC;wBACvB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;wBACvC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACtB,CAAC;yBAAM,CAAC;wBACJ,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;oBACpC,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,CAAC;QAEjC,IAAI,CAAC,OAAO,GAAG;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,aAAa,EAAE,IAAI,CAAC,aAAa;YACjC,iBAAiB,EAAE,IAAI,CAAC,iBAAiB;YACzC,mBAAmB,EAAE,IAAI,CAAC,mBAAmB;YAC7C,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,sBAAsB,EAAE,IAAI,CAAC,sBAAsB;YACnD,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,gBAAgB,EAAE,EAAE;YACpB,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,KAAK,EAAE,IAAI,CAAC,MAAM;YAClB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;YAC3C,gBAAgB,EAAE,IAAI,CAAC,gBAAgB;YACvC,eAAe,EAAE,IAAI,CAAC,eAAe;YACrC,6BAA6B,EAAE,IAAI,CAAC,6BAA6B;YAEjE,OAAO,EAAE,KAAK,EAAE,kCAAkC;YAClD,QAAQ,EAAE,IAAI;YACd,OAAO,EAAE,IAAI;YACb,eAAe,EAAE,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC;YAChD,SAAS,EAAE,IAAI;YACf,OAAO,EAAE,CAAC;YACV,WAAW,EAAE,IAAI,EAAE,eAAe;YAClC,QAAQ,EAAE,IAAI,CAAC,QAAQ,IAAI,IAAI;YAE/B,sBAAsB,EAAE,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC;YAC9D,4BAA4B,EAAE,IAAI,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC;YAC1E,mBAAmB,EAAE,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,IAAI,CAAC;YACxD,kBAAkB,EAAE,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,IAAI,CAAC;YACtD,SAAS;YACT,yBAAyB,EAAzB,wCAAyB;YACzB,OAAO,EAAE,IAAmC;YAC5C,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;SACrC,CAAC;QAEF,IAAI,CAAC,QAAQ,GAAG,IAAI,oBAAM,CAAC,sCAAiB,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,EAAU,EAAE,GAA4B;QACzD,6FAA6F;QAC7F,IAAI,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;YAClC,sDAAsD;YACtD,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,GAAsB,CAAC;YAC1C,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACnC,OAAO;QACX,CAAC;QAED,+DAA+D;QAC/D,gDAAgD;QAChD,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YACxB,IAAI,GAAG,EAAE,CAAC;gBACN,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;YAC3B,CAAC;YACD,OAAO;QACX,CAAC;QAED,IAAI,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACzB,cAAc;YACd,IAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,EAAE,CAAC;YAEnC,2BAA2B;YAC3B,IAAI,GAAG,EAAE,CAAC;gBACN,SAAS;gBACT,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC5B,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACrB,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;gBACvB,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACpC,aAAa;gBACb,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACb,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC/B,CAAC;YACL,CAAC;QACL,CAAC;QAED,IAAI,EAAE,KAAK,eAAe,IAAI,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;YAClD,kCAAkC;YAClC,IAAA,mBAAW,EAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjC,IAAI,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;YACpC,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAA8B,CAAC;QAChE,CAAC;QAED,kDAAkD;QAClD,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,SAAS,oBAAoB,IAAI,GAAG,EAAE,MAAM,EAAE,CAAC;YAC9D,IAAI,CAAC,YAAY,CAAC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,IAAI,KAAK,CAAC;YAC1D,IAAI,CAAC,YAAY,CAAC,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC;QAC5G,CAAC;QAED,8BAA8B;QAC9B,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,EAAE,EAAE,GAAmC,CAAC,CAAC;QAErE,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAEnC,IAAI,CAAC,mBAAmB,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,8BAA8B;QAEjE,oFAAoF;QACpF,gFAAgF;QAChF,IAAI,GAAG,EAAE,IAAI,KAAK,OAAO,IAAI,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YACrD,0BAA0B;YAC1B,IAAI,CAAC,oBAAoB,CAAC,EAAE,CAAC;iBACxB,IAAI,CAAC,KAAK,CAAC,EAAE;gBACV,IAAI,KAAK,EAAE,CAAC;oBACR,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;gBAC5B,CAAC;qBAAM,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;oBACvC,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC3B,CAAC;YACL,CAAC,CAAC;iBACD,KAAK,CAAC,GAAG,EAAE;gBACR,YAAY;YAChB,CAAC,CAAC,CAAC;QACX,CAAC;QAED,IAAI,CAAC,mBAAmB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;YACnC,4CAA4C;YAC5C,IAAI,GAAG,CAAC,OAAO,KAAK,EAAE,EAAE,CAAC;gBACrB,IAAI,CAAC;oBACD,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;gBAC1B,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAChB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBAC3D,CAAC;YACL,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,+BAA+B;QAC/B,IAAI,CAAC,GAAG,IAAI,SAAS,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YACvC,0BAA0B;YAC1B,IAAI,aAAa,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC3B,mFAAmF;gBACnF,IAAI,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,6BAA6B,CAAC,CAAC;oBACvE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;YACL,CAAC;iBAAM,IAAI,SAAS,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;gBACzE,+DAA+D;gBAC/D,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;gBAE1B,uCAAuC;gBACvC,MAAM,QAAQ,GAAG,iBAAiB,EAAE,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC5E,MAAM,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;gBACnC,MAAM,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,CAAC;gBAEpC,uCAAuC;gBACvC,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7E,MAAM,IAAI,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;gBACpC,MAAM,IAAI,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC;YACzC,CAAC;QACL,CAAC;aAAM,IAAI,CAAC,SAAS,IAAI,GAAG,EAAE,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC9C,wCAAwC;YACxC,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,6CAA6C;gBAC7C,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACrB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,EAAE,6BAA6B,CAAC,CAAC;oBACvE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;YACL,CAAC;iBAAM,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;gBACnE,oDAAoD;gBACpD,MAAM,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACtD,MAAM,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;gBACnC,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACrB,6BAA6B;oBAC7B,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;QACL,CAAC;aAAM,IAAI,GAAG,EAAE,IAAI,KAAK,QAAQ,IAAI,SAAS,EAAE,MAAM,EAAE,CAAC;YACrD,qBAAqB;YACrB,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrB,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACjD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,iBAAiB,EAAE,6BAA6B,CAAC,CAAC;oBAChE,IAAI,CAAC,OAAO,EAAE,CAAC;gBACnB,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,mBAAmB;gBACnB,IAAI,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;oBAC5D,4BAA4B;oBAC5B,MAAM,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;oBACtD,MAAM,IAAI,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;gBACvC,CAAC;gBAED,IACI,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;oBACjD,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE;wBAC3D,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE,CAAC,EAC/D,CAAC;oBACC,kBAAkB;oBAClB,IAAI,SAAS,CAAC,MAAM,CAAC,OAAO,IAAI,SAAS,CAAC,MAAM,CAAC,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;wBAC7F,2BAA2B;wBAC3B,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBAC9B,CAAC;gBACL,CAAC;qBAAM,IACH,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,CAAC;oBACjD,CAAC,SAAS,CAAC,MAAM,CAAC,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE;wBAC3D,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE,CAAC,EAC/D,CAAC;oBACC,iBAAiB;oBAEjB,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;wBACjF,eAAe;wBACf,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;oBAClC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,uDAAuD;oBACvD,uCAAuC;oBACvC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC9E,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE;wBAC1B,+EAA+E;wBAC/E,qCAAqC;wBACrC,IAAI,CAAC,EAAE,IAAI,CAAC,YAAY,CAAC,EAAE,CAAC,EAAE,CAAC;4BAC3B,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;wBAC5B,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED,aAAa,CAAC,EAAU,EAAE,KAA6B;QACnD,IAAI,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,KAAK,SAAS,EAAE,CAAC;YAC5C,sDAAsD;YACtD,OAAO,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;QACvC,CAAC;QACD,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC/D,OAAO;QACX,CAAC;QAED,IAAI,EAAE,KAAK,GAAG,IAAI,CAAC,SAAS,WAAW,IAAI,KAAK,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;YAC7D,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;gBAC1B,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACzC,CAAC;YACD,OAAO;QACX,CAAC;QAED,+DAA+D;QAC/D,gDAAgD;QAChD,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YACvB,IAAI,KAAK,EAAE,CAAC;gBACR,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;YAC5B,CAAC;YACD,OAAO;QACX,CAAC;QAED,MAAM,QAAQ,GAAsC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACpE,IAAI,KAAK,EAAE,CAAC;YACR,IAAI,QAAQ,EAAE,CAAC;gBACX,2BAA2B;gBAC3B,IAAI,CAAC,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;oBAClF,IAAI,CAAC,mBAAmB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE;wBACrD,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,CAAC,GAAG,EAAE;qBACjC,CAAC,CAAC;gBACP,CAAC;gBAED,8FAA8F;gBAC9F,KAAI,gBAAiB,QAAQ,CAAC,GAAG,KAAK,KAAK,IAAI,KAAK,CAAC,GAAG,IAAI,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;oBAChF,IAAI,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,EAAE,CAAC;wBACvB,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;wBAC5B,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;wBACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;4BACnD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,CAAC,sBAAsB,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;4BAC5F,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;wBACzD,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,KAAI,iBAAkB,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;gBACvD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;YACzB,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC;QAC5B,CAAC;aAAM,CAAC;YACJ,IAAI,QAAQ,EAAE,CAAC;gBACX,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YAC3B,CAAC;YACD,KAAK,GAAG,EAAoB,CAAC;YAC7B,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACtC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACb,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACjC,CAAC;QACL,CAAC;QACD,MAAM,SAAS,GAAG,IAAA,4BAAiB,EAC/B,IAAI,CAAC,OAAO,EACZ,EAAE,EACF,IAAI,CAAC,4BAA4B,CAAC,EAAE,EAAE,KAAK,CAAC,EAC5C,IAAI,CAAC,4BAA4B,CAAC,EAAE,EAAE,QAAQ,CAAC,CAClD,CAAC;QAEF,0CAA0C;QAC1C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YACxD,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC;YAClC,IAAI,GAAG,EAAE,uBAAuB,IAAI,eAAe,CAAC,SAAS,EAAE,GAAG,CAAC,uBAAuB,CAAC,EAAE,CAAC;gBAC1F,IAAI,CAAC;oBACD,GAAG,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;gBAC5B,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAChB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBAC3D,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED,YAAY,CAAC,EAAU,EAAE,QAAgB,EAAE,IAAmB;QAC1D,yCAAyC;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5D,MAAM,GAAG,GAAG,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC;YACtC,IAAI,GAAG,IAAI,YAAY,CAAC,GAAG,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,CAAC;gBACzC,IAAI,CAAC;oBACD,GAAG,CAAC,QAAQ,CAAC,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;gBACnD,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAChB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBAC3D,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,QAAQ,CAAC,QAAoB;QAC/B,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACvB,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,0BAA0B,EAAE,CAAC;YAClC,aAAa,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;YAC/C,IAAI,CAAC,0BAA0B,GAAG,IAAI,CAAC;QAC3C,CAAC;QACD,MAAM,IAAI,CAAC,cAAc,EAAE,CAAC;QAC5B,IAAI,OAAO,QAAQ,KAAK,UAAU,EAAE,CAAC;YACjC,QAAQ,EAAE,CAAC;QACf,CAAC;IACL,CAAC;IAED,KAAK,CAAC,OAAO;QACT,IAAI,CAAC,MAAM,CAAC,oBAAoB,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAyC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;QAC/G,IAAI,CAAC,MAAM,CAAC,oBAAoB,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,oBAAyC,EAAE,EAAE,CAAC,IAAI,GAAG,CAAC;QAE9G,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;YAC1D,MAAM,cAAc,GAAsC,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAExF,CAAC;YACF,IAAI,cAAc,EAAE,CAAC;gBACjB,MAAM,MAAM,GAAG,cAAc,CAAC,eAAe,EAAE,CAAC;gBAChD,IAAI,MAAM,EAAE,CAAC;oBACT,MAAM,KAAK,GAAG,MAAM,CAAC,eAAe,EAAE,CAAC;oBACvC,KAAK,CAAC,iBAAiB,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE;wBACrC,IAAI,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;4BAC/B,MAAM,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;4BAC5C,IACI,SAAS,CAAC,UAAU,EAAE,MAAM;gCAC5B,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC;gCAC1C,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,EACpC,CAAC;gCACC,6CAA6C;gCAC7C,IACI,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CACrC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,kBAAkB,CAAC,CAC/C,EACH,CAAC;oCACC,OAAO,IAAI,CAAC;gCAChB,CAAC;gCACD,4EAA4E;gCAC5E,MAAM,iBAAiB,GAAG,IAAA,gBAAI,EAAC,SAAS,EAAE,cAAc,CAAC,CAAC;gCAC1D,IACI,CAAC,SAAS,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,CAC7B,KAAK,CAAC,EAAE,CACJ,KAAK,CAAC,QAAQ;oCACd,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,CAAC;oCAClC,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAClD,EACH,CAAC;oCACC,OAAO,IAAI,CAAC;gCAChB,CAAC;gCACD,+DAA+D;gCAC/D,OAAO,KAAK,CAAC;4BACjB,CAAC;wBACL,CAAC;wBAED,uCAAuC;wBACvC,OAAO,IAAI,CAAC;oBAChB,CAAC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;QACL,CAAC;QAED,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAED,SAAS,CAAC,GAAqB;QAC3B,QAAQ,GAAG,EAAE,OAAO,EAAE,CAAC;YACnB,6BAA6B;YAC7B,KAAK,UAAU,CAAC;YAChB,KAAK,cAAc;gBACf,IACI,GAAG,CAAC,OAAO;oBACX,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,IAAI;wBAC1B,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS;wBAClC,cAAc,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,KAAK,IAAI,CAAC,SAAS;wBACvD,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,IAAI,CAAC,SAAS,CAAC,EAC9C,CAAC;oBACC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE;wBAChD,iDAAiD;wBACjD,IACI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,KAAK,IAAI,CAAC;4BACpD,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,EACpD,CAAC;4BACC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;gCACjE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC;gCAEhC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;gCAEpF,IAAI,CAAC;oCACD,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;wCACf,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAW,EAAE,EAAE;4CACvD,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gDAClB,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;4CACvE,CAAC;4CAED,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;wCAC7D,CAAC,CAAC,CAAC;oCACP,CAAC;yCAAM,CAAC;wCACJ,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC,MAAW,EAAE,EAAE;4CACvD,OAAO,CAAC,OAAO;gDACX,OAAO,CAAC,GAAG,CAAC,qBAAqB,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;wCAC3E,CAAC,CAAC,CAAC;oCACP,CAAC;gCACL,CAAC;gCAAC,OAAO,GAAY,EAAE,CAAC;oCACpB,IAAI,CAAC,QAAQ,CACT,iBAAiB,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAC5D,IAAI,EACJ,IAAI,CACP,CAAC;oCACF,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAAE,GAAY,CAAC,CAAC;gCACrD,CAAC;4BACL,CAAC,CAAC,CAAC;wBACP,CAAC;oBACL,CAAC,CAAC,CAAC;gBACP,CAAC;gBACD,MAAM;YAEV,KAAK,aAAa,CAAC,CAAC,CAAC;gBACjB,8BAA8B;gBAC9B,MAAM,OAAO,GAA2B,EAAE,CAAC;gBAE3C,6CAA6C;gBAC7C,IAAI,CAAC;oBACD,MAAM,cAAc,GAAG,IAAA,uCAAqB,EAAC,gCAAW,CAAC,CAAC;oBAC1D,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;gBAC3C,CAAC;gBAAC,MAAM,CAAC;oBACL,qBAAqB;gBACzB,CAAC;gBAED,6EAA6E;gBAC7E,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;gBAElC,oEAAoE;gBACpE,KAAK,MAAM,iBAAiB,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,+BAA+B,CAAC,EAAE,CAAC;oBAChF,OAAO,CAAC,GAAG,iBAAiB,OAAO,CAAC,GAAG,IAAI,CAAC,+BAA+B,CAAC,iBAAiB,CAAC,CAAC;gBACnG,CAAC;gBAED,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;oBACf,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;gBAClE,CAAC;gBACD,MAAM;YACV,CAAC;YAED,KAAK,cAAc,CAAC,CAAC,CAAC;gBAClB,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;oBACd,MAAM,aAAa,GACf,QAAQ,CACJ,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS;wBACnC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa;wBAC3B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAC/B,EAAE,CACL,IAAI,CAAC,CAAC;oBACX,MAAM,YAAY,GACd,QAAQ,CACJ,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS;wBAClC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY;wBAC1B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,EAC9B,EAAE,CACL,IAAI,CAAC,CAAC;oBACX,MAAM,SAAS,GACX,UAAU,CACN,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CACtF,IAAI,CAAC,CAAC;oBACX,MAAM,QAAQ,GACV,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;wBAC5F,CAAC,CAAC;oBACN,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;oBACnC,IAAI,WAAW,GAA6D,EAG3E,CAAC;oBACF,IAAI,CAAC;wBACD,WAAW,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC;oBACzE,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gCAAgC,GAAY,EAAE,CAAC,CAAC;oBACnE,CAAC;oBACD,IAAI,WAAW,EAAE,CAAC;wBACd,IAAI,CAAC;4BACD,WAAW,CAAC,WAAW,GAAG,IAAI,CAAC,aAAa,CACxC,KAAK,EACL,GAAG,CAAC,OAAO,CAAC,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,EACpD,GAAG,CAAC,OAAO,CAAC,iBAAiB,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAC9D,GAAG,CAAC,OAAO,CAAC,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,EAC1D,aAAa,EACb,KAAK,EACL,QAAQ,EACR,SAAS,EACT,IAAI,CACP,CAAC;4BACF,WAAW,CAAC,UAAU,GAAG,IAAI,CAAC,aAAa,CACvC,KAAK,EACL,GAAG,CAAC,OAAO,CAAC,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,EAClD,GAAG,CAAC,OAAO,CAAC,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAC5D,GAAG,CAAC,OAAO,CAAC,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EACxD,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,IAAI,CACP,CAAC;wBACN,CAAC;wBAAC,OAAO,GAAY,EAAE,CAAC;4BACpB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gCAAgC,GAAY,EAAE,CAAC,CAAC;wBACnE,CAAC;oBACL,CAAC;oBAED,MAAM,MAAM,GAA+E,EAAE,CAAC;oBAC9F,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,IAAI,CACtC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CACJ,WAAiD,CAAC,CAAC,CAAC;wBACpD,WAAiD,CAAC,CAAC,CAAC,CAC5D,CAAC;oBACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;wBACf,MAAM,SAAS,GACV,WAAwD,CAAC,GAAG,CAAC,KAAK,IAAI;4BACvE,CAAC,KAAK,CAAE,WAA+C,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;wBAE5E,MAAM,CAAC,GAAG,CAAC,GAAG;4BACV,WAAW,EAAE,SAAS;4BACtB,UAAU,EAAE,SAAS;gCACjB,CAAC,CAAC,yBAAyB,CAAE,WAA+C,CAAC,GAAG,CAAC,CAAC;gCAClF,CAAC,CAAC,KAAK;4BACX,IAAI,EAAE,SAAS;gCACX,CAAC,CAAE,WAA+C,CAAC,GAAG,CAAC,CAAC,WAAW,EAAE;gCACrE,CAAC,CAAC,KAAK;yBACd,CAAC;oBACN,CAAC,CAAC,CAAC;oBAEH,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;wBACf,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,CAAC;oBAC7D,CAAC;gBACL,CAAC;gBACD,MAAM;YACV,CAAC;YAED,KAAK,WAAW,CAAC,CAAC,CAAC;gBACf,IAAI,GAAG,CAAC,OAAO,EAAE,CAAC;oBACd,MAAM,SAAS,GACX,UAAU,CACN,GAAG,CAAC,OAAO,CAAC,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CACtF,IAAI,CAAC,CAAC;oBACX,MAAM,QAAQ,GACV,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC;wBAC5F,CAAC,CAAC;oBACN,MAAM,KAAK,GAAG,kBAAkB,EAAE,CAAC;oBAEnC,MAAM,YAAY,GAAG,GAAG,CAAC,OAAO,EAAE,YAAY,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC;oBAC3E,MAAM,iBAAiB,GAAG,GAAG,CAAC,OAAO,EAAE,iBAAiB,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,CAAC;oBAC1F,MAAM,eAAe,GAAG,GAAG,CAAC,OAAO,EAAE,eAAe,IAAI,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC;oBACpF,MAAM,aAAa,GACf,QAAQ,CACJ,GAAG,CAAC,OAAO,CAAC,aAAa,KAAK,SAAS;wBACnC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,aAAa;wBAC3B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,aAAa,EAC/B,EAAE,CACL,IAAI,CAAC,CAAC;oBACX,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAClC,KAAK,EACL,YAAY,EACZ,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,KAAK,EACL,QAAQ,EACR,SAAS,EACT,IAAI,CACP,CAAC;oBAEF,MAAM,WAAW,GAAG,GAAG,CAAC,OAAO,EAAE,WAAW,IAAI,IAAI,CAAC,MAAM,CAAC,WAAW,CAAC;oBACxE,MAAM,gBAAgB,GAAG,GAAG,CAAC,OAAO,EAAE,gBAAgB,IAAI,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;oBACvF,MAAM,cAAc,GAAG,GAAG,CAAC,OAAO,EAAE,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,CAAC;oBACjF,MAAM,YAAY,GACd,QAAQ,CACJ,GAAG,CAAC,OAAO,CAAC,YAAY,KAAK,SAAS;wBAClC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY;wBAC1B,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,YAAY,EAC9B,EAAE,CACL,IAAI,CAAC,CAAC;oBACX,MAAM,UAAU,GAAG,IAAI,CAAC,aAAa,CACjC,KAAK,EACL,WAAW,EACX,gBAAgB,EAChB,cAAc,EACd,YAAY,EACZ,IAAI,EACJ,QAAQ,EACR,SAAS,EACT,IAAI,CACP,CAAC;oBAEF,MAAM,gBAAgB,GAAG,WAAW,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,OAAO,EAAE,CAAC,CAAC;oBAC/E,MAAM,eAAe,GAAG,UAAU,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC,CAAC;oBAE5E,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,sBAAsB,YAAY,aAAa,iBAAiB,UAAU,eAAe,aAAa,aAAa,MAAM,gBAAgB,CAAC,CAAC,CAAC,WAAW,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAClL,CAAC;oBACF,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,sBAAsB,WAAW,aAAa,gBAAgB,UAAU,cAAc,aAAa,YAAY,MAAM,eAAe,CAAC,CAAC,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,KAAK,EAAE,CAC5K,CAAC;oBAEF,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;wBACf,IAAI,CAAC,MAAM,CACP,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,OAAO,EACX;4BACI,WAAW,EAAE;gCACT,WAAW,EAAE,gBAAgB;gCAC7B,UAAU,EAAE,gBAAgB,CAAC,CAAC,CAAC,yBAAyB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,KAAK;gCAC7E,IAAI,EAAE,WAAW,CAAC,WAAW,EAAE;6BAClC;4BACD,UAAU,EAAE;gCACR,WAAW,EAAE,eAAe;gCAC5B,UAAU,EAAE,eAAe,CAAC,CAAC,CAAC,yBAAyB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,KAAK;gCAC3E,IAAI,EAAE,UAAU,CAAC,WAAW,EAAE;6BACjC;yBACJ,EACD,GAAG,CAAC,QAAQ,CACf,CAAC;oBACN,CAAC;gBACL,CAAC;gBACD,MAAM;YACV,CAAC;YAED,KAAK,OAAO,CAAC,CAAC,CAAC;gBACX,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;oBAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;gBACjC,CAAC;gBACD,MAAM;YACV,CAAC;YAED,KAAK,WAAW,CAAC,CAAC,CAAC;gBACf,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;oBAC1B,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC;gBACxD,CAAC;gBACD,MAAM;YACV,CAAC;YAED,KAAK,SAAS,CAAC,CAAC,CAAC;gBACb,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,GAAG,CAAC,OAAO,CAAC;gBACvC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;gBAChE,MAAM;YACV,CAAC;YAED,KAAK,UAAU,CAAC,CAAC,CAAC;gBACd,iDAAiD;gBACjD,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC;gBACjE,IAAI,CAAC,OAAO,CAAC,WAAW,GAAG,IAAI,CAAC;gBAChC,MAAM;YACV,CAAC;YAED,KAAK,oBAAoB,CAAC,CAAC,CAAC;gBACxB,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;oBACf,IAAI,CAAC,MAAM,CACP,GAAG,CAAC,IAAI,EACR,GAAG,CAAC,OAAO,EACX;wBACI,OAAO,EAAE,IAAA,wCAAyB,GAAE;wBACpC,GAAG,EAAH,eAAG;qBACN,EACD,GAAG,CAAC,QAAQ,CACf,CAAC;gBACN,CAAC;gBACD,MAAM;YACV,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,GAAQ;QACV,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,CAAC,IAAY,EAAQ,EAAE,CAC9D,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;YAC1C,IACI,OAAO,OAAO,CAAC,EAAE,KAAK,UAAU;gBAChC,CAAC,OAAO,CAAC,QAAQ,KAAK,GAAG,IAAI,OAAO,CAAC,QAAQ,KAAK,GAAG,CAAC,QAAQ,CAAC,EACjE,CAAC;gBACC,OAAO,CAAC,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAC;gBACrD,OAAO,CAAC,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBACtC,OAAO,CAAC,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;YAC3C,CAAC;QACL,CAAC,CAAC,CACL,CAAC;IACN,CAAC;IAED,QAAQ,CAAC,GAAW,EAAE,CAAQ,EAAE,IAAa;QACzC,MAAM,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/E,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACtB,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5D,KAAK,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;gBACZ,SAAS;YACb,CAAC;YACD,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,iCAAiC,CAAC,EAAE,CAAC;gBACpD,MAAM;YACV,CAAC;YACD,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1D,CAAC;IACL,CAAC;IAED,eAAe,CAAC,GAAW;QACvB,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAEhC,0BAA0B;QAC1B,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7C,IAAI,KAAK,EAAE,CAAC;YACR,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACpC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;oBACZ,SAAS;gBACb,CAAC;gBACD,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,8CAA8C,CAAC,EAAE,CAAC;oBACjE,MAAM;gBACV,CAAC;gBACD,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACzD,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI;QACN,0CAA0C;QAC1C,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC1B,IAAI,MAAM,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;gBACzB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;YACnC,CAAC;QACL,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,4DAA4D,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC,CAAC;QAEpG,+BAA+B;QAC/B,MAAM,OAAO,GAA+C,MAAM,IAAI,CAAC,qBAAqB,CACxF,kBAAkB,IAAI,CAAC,SAAS,EAAE,CACrC,CAAC;QACF,IAAI,OAAO,EAAE,MAAM,EAAE,CAAC;YAClB,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,KAAK,MAAM,EAAE,CAAC;gBAC5C,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;oBACzB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,GAAG,MAAM,CAAC;gBAC3C,CAAC;qBAAM,CAAC;oBACJ,OAAO,CAAC,MAAM,CAAC,OAAO,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;gBAChD,CAAC;gBACD,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAChD,CAAC;QACL,CAAC;QAED,IAAI,aAAa,EAAE,CAAC;YAChB,IAAI,CAAC,gBAAgB,GAAG;gBACpB,KAAK,EAAE,OAAO,CAAC,KAAK;gBACpB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,IAAI,EAAE,OAAO,CAAC,IAAI;gBAClB,KAAK,EAAE,OAAO,CAAC,GAAG;gBAClB,KAAK,EAAE,OAAO,CAAC,GAAG;aACrB,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,gBAAgB,CAAC;QAC1D,CAAC;QACD,IAAI,CAAC,SAAS,GAAG,GAAG,IAAI,CAAC,SAAS,iBAAiB,CAAC;QAEpD,IAAI,CAAC,IAAI,CAAC,EAAE,GAAG,IAAI,mBAAS,CAAC,IAAI,CAAC,GAAG,EAAE,IAAA,wCAAyB,GAAE,CAAC,CAAC;QACpE,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,CAAC,mCAAmC;QAErF,8BAA8B;QAC9B,IAAI,CAAC;YACD,SAAS,GAAG;gBACR,iBAAiB,EAAE,IAAA,sBAAY,EAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,EAAE,MAAM,CAAC;aACjG,CAAC;YACF,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,SAAS,CAAC,CAAC;YACpD,mBAAmB,CAAC,0BAA0B,CAAC,SAAS,CAAC,CAAC;QAC9D,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mDAAmD,GAAY,EAAE,CAAC,CAAC;YACjF,4DAA4D;YAC5D,IAAI,IAAI,CAAC,eAAe,IAAI,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC1D,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;gBACxD,IAAI,cAAc,EAAE,CAAC;oBACjB,MAAM,YAAY,GAAG,cAAc,CAAC,eAAe,EAAE,CAAC;oBACtD,YAAY,EAAE,gBAAgB,CAAC,GAAY,CAAC,CAAC;gBACjD,CAAC;YACL,CAAC;YACD,0EAA0E;YAC1E,SAAS,GAAG,EAAE,CAAC;QACnB,CAAC;QAED,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,iEAAiE;QACjE,IAAI,CAAC,0BAA0B,EAAE,CAAC;QAElC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;QACrB,IAAI,CAAC,OAAO,CAAC,SAAS,GAAG,IAAI,qBAAS,CAClC,IAAI,CAAC,GAAG,EACR,IAAI,EACJ,IAAI,CAAC,IAAI,CAAC,OAAO,EACjB,IAAI,CAAC,MAAM,CAAC,QAAQ,EACpB,IAAI,CAAC,MAAM,CAAC,SAAS,CACxB,CAAC;QACF,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,MAAM,IAAI,CAAC,gBAAgB,EAAE,CAAC;QAC9B,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAE1B,6GAA6G;QAC7G,IAAI,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;YACnC,OAAO,CAAC,GAAG,CAAC,4BAA4B,GAAG,GAAG,CAAC;QACnD,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAAC,QAAQ,EAAE,YAAY,EAAE,EAAE,CAAC,CAAC;QACtE,IAAI,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACpB,yBAAyB;YACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvC,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC;gBAC9B,IAAI,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC;oBACrB,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;wBACpB,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;wBAE/D,IAAI,GAAG,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;4BACrB,IAAI,UAAU,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gCACtC,aAAa;gCACb,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,kCAAkC,CAAC,CAAC;gCAC5D,4EAA4E;gCAC5E,mGAAmG;gCACnG,+HAA+H;gCAC/H,MAAM,iBAAiB,GAAG,IAAA,kDAAgC,EAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;gCACpF,0EAA0E;gCAC1E,0EAA0E;gCAC1E,wCAAwC;gCACxC,oEAAoE;gCACpE,mFAAmF;gCACnF,MAAM,UAAU,GAAW,IAAA,kBAAU,EACjC,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CACjE,CAAC;gCAEF,IAAI,QAA4B,CAAC;gCACjC,IAAI,YAAgC,CAAC;gCACrC,8EAA8E;gCAC9E,2EAA2E;gCAC3E,iCAAiC;gCACjC,IACI,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ;oCACvC,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,QAAQ;oCACzC,UAAU,KAAK,GAAG,CAAC,MAAM,CAAC,UAAU,EACtC,CAAC;oCACC,iCAAiC;oCACjC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;oCAC/B,YAAY,GAAG,GAAG,CAAC,MAAM,CAAC,YAAY,CAAC;oCACvC,IAAI,CAAC,GAAG,CAAC,IAAI,CACT,GAAG,GAAG,CAAC,GAAG,kEAAkE,CAC/E,CAAC;gCACN,CAAC;qCAAM,CAAC;oCACJ,iFAAiF;oCACjF,MAAM,QAAQ,GAAG,IAAA,sCAAoB,EAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oCAC/C,IAAI,UAAyB,CAAC;oCAC9B,IAAI,CAAC;wCACD,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;oCACpE,CAAC;oCAAC,OAAO,GAAY,EAAE,CAAC;wCACpB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,qCAAqC,GAAY,EAAE,CAAC,CAAC;wCAC9E,SAAS;oCACb,CAAC;oCAED,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW;yCAChC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,IAAI,CAAC;yCACxC,IAAI,CAAC,IAAI,CAAC,CAAC;oCAEhB,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;wCACrB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4CACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CACT,GAAG,GAAG,CAAC,GAAG,oDAAoD,MAAM,EAAE,CACzE,CAAC;wCACN,CAAC;6CAAM,CAAC;4CACJ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC,GAAG,qCAAqC,CAAC,CAAC;wCACnE,CAAC;wCACD,QAAQ,GAAG,UAAU,CAAC,MAAM,CAAC;wCAC7B,mHAAmH;wCACnH,YAAY,GAAG,IAAA,6CAA2B,EAAC,UAAU,CAAC,YAAY,IAAI,EAAE,CAAC,CAAC;wCAE1E,MAAM,SAAS,GAIX;4CACA,UAAU;4CACV,QAAQ;yCACX,CAAC;wCACF,IAAI,YAAY,EAAE,CAAC;4CACf,SAAS,CAAC,YAAY,GAAG,YAAY,CAAC;wCAC1C,CAAC;wCAED,0GAA0G;wCAC1G,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,mDAAmD;wCACzF,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,GAAG,EAAE;4CAC9B,MAAM,EAAE,SAAS;yCACpB,CAAC,CAAC;oCACP,CAAC;yCAAM,CAAC;wCACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,qCAAqC,MAAM,EAAE,CAAC,CAAC;wCACxE,SAAS;oCACb,CAAC;gCACL,CAAC;gCACD,IAAI,CAAC,YAAY,IAAI,GAAG,QAAQ,IAAI,CAAC;gCACrC,gDAAgD;gCAChD,IAAI,YAAY,IAAI,IAAI,EAAE,CAAC;oCACvB,IAAI,CAAC,kCAAkC,CAAC,GAAG,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;gCACnE,CAAC;4BACL,CAAC;iCAAM,CAAC;gCACJ,aAAa;gCACb,MAAM,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC;gCACrC,IAAI,CAAC,YAAY,IAAI,GAAG,UAAU,IAAI,CAAC;gCAEvC,yDAAyD;gCACzD,0CAA0C;gCAC1C,MAAM,QAAQ,GAAG,IAAA,sCAAoB,EAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gCAC/C,IAAI,UAAyB,CAAC;gCAC9B,IAAI,CAAC;oCACD,UAAU,GAAG,mBAAmB,CAAC,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;gCACnE,CAAC;gCAAC,OAAO,GAAY,EAAE,CAAC;oCACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CACT,GAAG,GAAG,CAAC,GAAG,0DAA0D,GAAY,EAAE,CACrF,CAAC;oCACF,SAAS;gCACb,CAAC;gCACD,gDAAgD;gCAChD,IAAI,UAAU,CAAC,OAAO,IAAI,UAAU,CAAC,YAAY,IAAI,IAAI,EAAE,CAAC;oCACxD,IAAI,CAAC,kCAAkC,CAAC,GAAG,CAAC,GAAG,EAAE,UAAU,CAAC,YAAY,CAAC,CAAC;gCAC9E,CAAC;4BACL,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;QAED,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QAC7D,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAEnE,IAAI,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;YACpB,mBAAmB;YACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvC,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;oBACpC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;gBACvC,CAAC;YACL,CAAC;QACL,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC;YACzB,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,cAAmC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;YAChG,IAAI,IAAI,CAAC,QAAQ,KAAK,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;gBAC/C,MAAM,UAAU,GAAG,IAAA,wCAAyB,GAAE,GAAG,eAAG,CAAC;gBACrD,IAAI,CAAC,MAAM,CAAC,UAAU,GAAG,IAAA,qBAAS,EAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC3D,IAAI,eAAe,GAAG,KAAK,CAAC;gBAC5B,KAAK,IAAI,GAAG,IAAI,wBAAwB,EAAE,CAAC;oBACvC,GAAG,GAAG,IAAA,gBAAI,EAAC,UAAU,EAAE,GAAG,CAAC,GAAG,eAAG,CAAC;oBAClC,IAAI,GAAG,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;wBACjF,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yEAAyE,CAAC,CAAC;wBAC1F,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,aAAa,IAAI,CAAC,MAAM,CAAC,UAAU,kCAAkC,CAAC,CAAC;wBACtF,eAAe,GAAG,IAAI,CAAC;wBACvB,MAAM;oBACV,CAAC;gBACL,CAAC;gBACD,IAAI,CAAC,eAAe,EAAE,CAAC;oBACnB,IAAI,CAAC,MAAM,GAAG,IAAI,eAAM,CAAC;wBACrB,OAAO,EAAE,IAAI;wBACb,GAAG,EAAE,IAAI,CAAC,GAAG;wBACb,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,UAAU;qBACnC,CAAC,CAAC;gBACP,CAAC;YACL,CAAC;QACL,CAAC;QAED,gEAAgE;QAChE,IAAI,CAAC,0BAA0B,GAAG,WAAW,CAAC,GAAG,EAAE;YAC/C,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;gBACnC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;oBACpB,OAAO;gBACX,CAAC;gBACD,MAAM,+BAA+B,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,wBAAwB,CAAC;gBAClF,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,wBAAwB,GAAG,CAAC,CAAC;gBAC9C,IAAI,+BAA+B,GAAG,IAAI,CAAC,MAAM,CAAC,oBAAoB,EAAE,CAAC;oBACrE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,+BAA+B,EAAE,CAAC;oBACnD,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,UAAU,EAAE,+BAA+B,IAAI,CAAC,MAAM,CAAC,oBAAoB,iCAAiC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,+BAA+B,sBAAsB,CACrL,CAAC;oBACF,4EAA4E;oBAC5E,oCAAoC;oBACpC,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,+BAA+B,GAAG,CAAC,EAAE,CAAC;wBACvD,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,UAAU,EAAE,kCAAkC,IAAI,CAAC,MAAM,CAAC,oBAAoB,mEAAmE,CACpJ,CAAC;wBACF,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBACxB,CAAC;gBACL,CAAC;qBAAM,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,+BAA+B,GAAG,CAAC,EAAE,CAAC;oBAC9D,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,+BAA+B,EAAE,CAAC;oBACnD,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,UAAU,EAAE,mCAAmC,IAAI,CAAC,MAAM,CAAC,oBAAoB,2DAA2D,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,+BAA+B,EAAE,CAC/L,CAAC;gBACN,CAAC;YACL,CAAC,CAAC,CAAC;QACP,CAAC,EAAE,KAAK,CAAC,CAAC;IACd,CAAC;IAEO,0BAA0B;QAC9B,4DAA4D;QAC5D,MAAM,QAAQ,GAAG;YACb,MAAM,EAAE,kDAAkD;YAC1D,iBAAiB,EAAE,kDAAkD;SACxE,CAAC;QACF,gFAAgF;QAChF,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,SAAS,KAAK,QAAQ,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;YAC/F,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS;iBACtC,KAAK,CAAC,SAAS,CAAC;iBAChB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;iBAChC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAEtB,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc;iBAC1C,KAAK,CAAC,SAAS,CAAC;iBAChB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;iBAClB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YACtB,yFAAyF;YACzF,KAAK,MAAM,GAAG,IAAI,aAAa,EAAE,CAAC;gBAC9B,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACxD,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACvB,CAAC;YACL,CAAC;YACD,yGAAyG;YACzG,mFAAmF;YACnF,KAAK,MAAM,GAAG,IAAI,YAAY,EAAE,CAAC;gBAC7B,0DAA0D;gBAC1D,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACrB,SAAS;gBACb,CAAC;gBACD,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;gBAEhD,IAAI,aAAa,CAAC,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC7D,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBACvB,CAAC;YACL,CAAC;QACL,CAAC;QACD,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YACzB,IAAI,UAAU,GAAG,IAAA,gCAAc,EAC3B,GAAG,EACH,IAAI,CAAC,iCAAiC,CAAC,CAAC,CAAC,IAAI,CAAC,iCAAiC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG;YAC1F,oEAAoE;YACpE,GAAG,KAAK,MAAM,CACjB,CAAC;YACF,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,+EAA+E;gBAC/E,yBAAyB;gBACzB,UAAU,GAAG;oBACT,CAAC,uBAAuB,GAAG,aAAa,CAAC,EAAE,mBAAmB,GAAG,IAAI;iBACxE,CAAC;YACN,CAAC;YACD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qCAAqC,GAAG,KAAK,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,EAAE,CAAC,CAAC;YACvG,2CAA2C;YAC3C,MAAM,CAAC,MAAM,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC;YACrC,+CAA+C;YAC/C,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC;YACrD,mBAAmB,CAAC,0BAA0B,CAAC,UAAU,CAAC,CAAC;QAC/D,CAAC;IACL,CAAC;IAED,mBAAmB,CAAC,EAAU,EAAE,GAAuC;QACnE,IAAI,GAAG,EAAE,CAAC;YACN,+BAA+B;YAC/B,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACvB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC9B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBACvB,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;gBACzB,CAAC;gBACD,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;oBAChD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;oBAC5B,KAAK,CAAC,GAAG,EAAE,CAAC;oBACZ,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC5B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;oBAC9D,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;oBAEpC,KAAK,CAAC,GAAG,EAAE,CAAC;oBACZ,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBAC5B,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC;oBAC5D,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBACvC,CAAC;YACL,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,qCAAqC;YACrC,MAAM,GAAG,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACtC,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;gBACb,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;YACjC,CAAC;YACD,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC;gBAChD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBAC5B,KAAK,CAAC,GAAG,EAAE,CAAC;gBACZ,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC5B,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC7B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBACtD,MAAM,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBAClE,CAAC;gBAED,KAAK,CAAC,GAAG,EAAE,CAAC;gBACZ,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;gBAC5B,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;oBAC5B,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBACrD,MAAM,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;gBACjE,CAAC;YACL,CAAC;YAED,OAAO,IAAI,CAAC,6BAA6B,CAAC,EAAE,CAAC,CAAC;QAClD,CAAC;QAED,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YAC3B,sBAAsB;YACtB,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;YACzB,OAAO,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAC5B,CAAC;aAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YAClC,mBAAmB;YACnB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;YACvB,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACzB,CAAC;aAAM,IAAI,GAAG,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;YACxC,sBAAsB;YACtB,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;YAEvB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;YAErE,IAAI,EAAE,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;gBAC/B,EAAE,GAAG,EAAE,CAAC,IAAA,mBAAW,GAAE,CAAC,IAAI,EAAE,CAAC,EAAE,CAAC;YACpC,CAAC;YAED,IAAI,CAAC,KAAK,EAAE,EAAE,CAAC;gBACX,IAAI,CAAC,EAAE,CAAC;oBACJ,IAAI,CAAC,eAAe,CAAC,EAAE,CAAC,CAAC;gBAC7B,CAAC;gBACD,IAAI,EAAE,EAAE,CAAC;oBACL,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;gBACzB,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,cAAc;QAChB,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,QAAQ,GAAuB,EAAE,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IAChD,CAAC;IAED,4BAA4B,CACxB,EAAU,EACV,KAAwC;QAExC,IACI,KAAK;YACL,OAAO,KAAK,CAAC,GAAG,KAAK,QAAQ;YAC7B,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,MAAM;YACxB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,QAAQ,CAAC,EACzF,CAAC;YACC,IAAI,CAAC;gBACD,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACtC,CAAC;YAAC,OAAO,GAAQ,EAAE,CAAC;gBAChB,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;oBAChE,IAAI,CAAC,GAAG,CAAC,IAAI,CACT,gCAAgC,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,QAAQ,EAAE,EAAE,CAC/F,CAAC;gBACN,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,gCAAgC,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,KAAK,GAAG,CAAC,QAAQ,EAAE,EAAE,CAC/F,CAAC;gBACN,CAAC;YACL,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,wBAAwB,CAAC,EAAU,EAAE,KAA0B,EAAE,KAAc;QAC3E,IAAI,MAAsB,CAAC;QAE3B,IAAI,OAAO,KAAK,KAAK,SAAS,EAAE,CAAC;YAC7B,gEAAgE;YAChE,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,KAAK,EAAoB,CAAC;QAC5D,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,EAAE,GAAG,EAAE,KAAK,EAAoB,CAAC;QAC9C,CAAC;QAED,OAAO,IAAI,CAAC,kBAAkB,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAED,kBAAkB,CAAC,EAAU,EAAE,KAAoC;QAC/D,IAAI,MAAsB,CAAC;QAE3B,IAAI,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;YACrC,MAAM,GAAG,KAAuB,CAAC;QACrC,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,EAAE,GAAG,EAAE,IAAI,EAAoB,CAAC;QAC7C,CAAC;QAED,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACxB,OAAO,MAAM,CAAC;QAClB,CAAC;QACD,+CAA+C;QAC/C,mCAAmC;QACnC,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC3B,CAAC;QAED,IAAI,MAAM,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YACzB,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;QAED,MAAM,CAAC,IAAI;YACP,OAAO,MAAM,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,kBAAkB,IAAI,CAAC,SAAS,EAAE,CAAC;QAE7G,IAAI,MAAM,CAAC,EAAE,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;YACxE,IAAI,CAAC,gBAAgB,EAAE,CAAC;gBACpB,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACJ,0DAA0D;gBAC1D,MAAM,UAAU,GAAG,CAAC,IAAA,6BAAiB,EAAC,gBAAgB,CAAC,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;gBACxE,IAAI,CAAC,gBAAgB,CAAC,EAAE,IAAI,UAAU,EAAE,CAAC;oBACrC,MAAM,CAAC,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACJ,MAAM,CAAC,EAAE,GAAG,gBAAgB,CAAC,EAAE,CAAC;gBACpC,CAAC;YACL,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;IAED,KAAK,CAAC,OAAO;QACT,MAAM,IAAI,CAAC,4BAA4B,CAAC,GAAG,CAAC,CAAC;QAE7C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;YACzB,MAAM,IAAI,CAAC,2BAA2B,CAAC,GAAG,CAAC,CAAC;QAChD,CAAC;aAAM,CAAC;YACJ,MAAM,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;YAC5C,MAAM,IAAI,CAAC,oBAAoB,CAAC,iBAAiB,CAAC,CAAC;QACvD,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;QAEvC,MAAM,aAAa,GAAG,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC;aAChD,IAAI,CAAC,GAAG,CAAC,EAAE;YACR,IAAI,CAAC,GAAG,EAAE,CAAC;gBACP,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wCAAwC,CAAC,CAAC;gBACzD,IAAI,CAAC,SAAS,CAAC,yBAAU,CAAC,4BAA4B,CAAC,CAAC;gBACxD,OAAO;YACX,CAAC;YACD,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBAC9C,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;gBAElC,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACrC,CAAC;YAED,mBAAmB;YACnB,KAAK,MAAM,EAAE,IAAI,GAAG,EAAE,CAAC;gBACnB,IAAI,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,CAAC;oBAChD,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;gBAC3B,CAAC;YACL,CAAC;YACD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;QACzC,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAQ,EAAE,EAAE;YAChB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gCAAgC,GAAG,EAAE,OAAO,IAAI,WAAW,EAAE,CAAC,CAAC;YAC9E,IAAI,CAAC,SAAS,CAAC,yBAAU,CAAC,4BAA4B,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEP,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;QAExC,MAAM,cAAc,GAAG,IAAI,CAAC,kBAAkB,CAAC,EAAE,YAAY,EAAE,IAAI,EAAE,CAAC;aACjE,IAAI,CAAC,GAAG,CAAC,EAAE;YACR,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC;gBACb,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;gBAC1D,IAAI,CAAC,SAAS,CAAC,yBAAU,CAAC,4BAA4B,CAAC,CAAC;gBACxD,OAAO;YACX,CAAC;YACD,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;YAClB,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;YACpC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBACvC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC;oBACnB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,CAAC,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;oBACtE,SAAS;gBACb,CAAC;gBACD,IAAI,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,SAAS,EAAE,CAAC;oBAClD,8BAA8B;oBAC9B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;gBACxD,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBAE3F,oBAAoB;gBACpB,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACvD,CAAC;YACD,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YAElC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;YAEnD,kCAAkC;YAClC,IAAI,YAAY,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;gBACjC,IAAA,mBAAW,EAAC,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;gBAC1C,IAAI,CAAC,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC;gBAC7C,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAA8B,CAAC;YAChE,CAAC;iBAAM,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACvB,IAAA,mBAAW,EAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;gBAC3B,IAAI,CAAC,OAAO,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;YAC1C,CAAC;YAED,gCAAgC;YAChC,IAAI,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,CAAC;gBAC3B,IAAI,YAAY,EAAE,MAAM,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;oBACpE,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,QAAQ,CAAC;oBACpD,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,SAAS,CAAC;gBAC1D,CAAC;qBAAM,IAAI,IAAI,CAAC,QAAQ,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACzC,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;oBACrC,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;gBAC3C,CAAC;YACL,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,QAA6B,CAAC,CAAC;YAC7E,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,SAA8B,CAAC,CAAC;YAE/E,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC9B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6EAA6E,CAAC,CAAC;YACjG,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,CAAC,EAAE,IAAI,IAAI,CAAC,MAAM,CAAC,QAAQ,GAAG,EAAE,EAAE,CAAC;gBACjE,IAAI,CAAC,GAAG,CAAC,IAAI,CACT,wBAAwB,IAAI,CAAC,MAAM,CAAC,QAAQ,sDAAsD,CACrG,CAAC;YACN,CAAC;YAED,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,8EAA8E,CAAC,CAAC;YAClG,CAAC;iBAAM,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,GAAG,EAAE,CAAC;gBACrE,IAAI,CAAC,GAAG,CAAC,IAAI,CACT,yBAAyB,IAAI,CAAC,MAAM,CAAC,SAAS,sDAAsD,CACvG,CAAC;YACN,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,UAAU,CAAC;YAClE,IAAI,CAAC,MAAM,CAAC,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,CAAC,CAAC;YAC3D,IAAI,CAAC,MAAM,CAAC,iBAAiB,GAAG,IAAI,CAAC,MAAM,CAAC,iBAAiB,IAAI,OAAO,CAAC;YACzE,IAAI,CAAC,MAAM,CAAC,eAAe,GAAG,IAAI,CAAC,MAAM,CAAC,eAAe,IAAI,OAAO,CAAC;YAErE,IAAI,CAAC,MAAM,CAAC,WAAW,GAAG,IAAI,CAAC,MAAM,CAAC,WAAW,IAAI,MAAM,CAAC;YAC5D,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,IAAI,CAAC,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,gBAAgB,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,IAAI,OAAO,CAAC;YACvE,IAAI,CAAC,MAAM,CAAC,cAAc,GAAG,IAAI,CAAC,MAAM,CAAC,cAAc,IAAI,OAAO,CAAC;YAEnE,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;YAC5B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC1C,CAAC,CAAC;aACD,KAAK,CAAC,CAAC,GAAQ,EAAE,EAAE;YAChB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,iCAAiC,GAAG,EAAE,OAAO,IAAI,WAAW,EAAE,CAAC,CAAC;YAC/E,IAAI,CAAC,SAAS,CAAC,yBAAU,CAAC,4BAA4B,CAAC,CAAC;QAC5D,CAAC,CAAC,CAAC;QAEP,OAAO,OAAO,CAAC,GAAG,CAAC,CAAC,aAAa,EAAE,cAAc,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;IACvE,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,EAAU,EAAE,OAAgB;QACjD,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,SAAS,kBAAkB,EAAE,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAE9F,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG;gBACrB,GAAG,EAAE,QAAQ;gBACb,MAAM,EAAE;oBACJ,IAAI,EAAE,iBAAiB,EAAE,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE;oBAChE,IAAI,EAAE,0BAA0B;oBAChC,IAAI,EAAE,SAAS;oBACf,KAAK,EAAE,IAAI;oBACX,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,eAAe;iBACxB;gBACD,MAAM,EAAE;oBACJ,MAAM,EAAE,EAAE;iBACb;gBACD,IAAI,EAAE,OAAO;aAChB,CAAC;YACF,IAAI,CAAC;gBACD,IAAI,CAAC,qBAAqB,CAAC,QAAQ,EAAE,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;gBAC7D,MAAM,sBAAsB,GAAG,IAAI,CAAC,wBAAwB,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBACxF,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC3D,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;oBACpC,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,sBAAsB,CAAC;gBAC/D,CAAC;YACL,CAAC;YAAC,MAAM,CAAC;gBACL,SAAS;YACb,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,CAAC,CAAC;YACxD,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;gBACjC,MAAM,sBAAsB,GAAG,IAAI,CAAC,wBAAwB,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBACxF,MAAM,IAAI,CAAC,oBAAoB,CAAC,QAAQ,EAAE,CAAC,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;gBAC3D,IAAI,OAAO,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;oBACpC,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,GAAG,sBAAsB,CAAC;gBACzD,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,mBAAmB,CAAC,EAAU;QAChC,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,SAAS,kBAAkB,EAAE,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,CAAC;QAE/F,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,GAAG;gBACtB,GAAG,EAAE,SAAS;gBACd,MAAM,EAAE;oBACJ,IAAI,EAAE,iBAAiB,EAAE,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE;oBAChE,IAAI,EAAE,sBAAsB;oBAC5B,IAAI,EAAE,SAAS;oBACf,MAAM,EAAE,IAAI;oBACZ,KAAK,EAAE,KAAK;oBACZ,IAAI,EAAE,IAAI;oBACV,IAAI,EAAE,iBAAiB;iBAC1B;gBACD,MAAM,EAAE;oBACJ,MAAM,EAAE,EAAE;iBACb;gBACD,IAAI,EAAE,OAAO;aAChB,CAAC;YACF,IAAI,CAAC;gBACD,MAAM,IAAI,CAAC,qBAAqB,CAAC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,CAAC;gBACrE,MAAM,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAC5D,CAAC;YAAC,MAAM,CAAC;gBACL,SAAS;YACb,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,oBAAoB,CAAC,SAAS,CAAC,CAAC;YACzD,IAAI,KAAK,IAAI,KAAK,CAAC,GAAG,KAAK,KAAK,EAAE,CAAC;gBAC/B,MAAM,IAAI,CAAC,oBAAoB,CAAC,SAAS,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;YAC5D,CAAC;QACL,CAAC;IACL,CAAC;IAED,UAAU,CAAC,GAAoB;QAC3B,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC;QAEnB,IAAI,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;YACnB,IAAI,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC;YAC3B,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACnC,IAAI,GAAG,IAAI,CAAC,IAAA,mBAAW,GAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC;YAC1C,CAAC;YACD,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACpC,sCAAsC;gBACtC,OAAO;YACX,CAAC;YAED,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;gBACpB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC;YAC1B,CAAC;iBAAM,CAAC;gBACJ,mBAAmB;gBACnB,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;oBACnC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAW,CAAC,CAAC;gBACpD,CAAC;gBAEA,IAAI,CAAC,KAAK,CAAC,IAAI,CAAc,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC5C,CAAC;QACL,CAAC;IACL,CAAC;IAED,eAAe,CAAC,EAAU;QACtB,MAAM,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAE3B,IAAI,CAAC,EAAE,CAAC;YACJ,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC/B,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBACtC,IAAI,GAAG,GAAG,CAAC,CAAC,EAAE,CAAC;oBACX,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;oBAE7B,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;wBAC7B,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACrC,CAAC;gBACL,CAAC;YACL,CAAC;iBAAM,CAAC;gBACJ,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,CAAC;QACL,CAAC;IACL,CAAC;IAED,OAAO,CAAC,EAAU;QACd,KAAK,MAAM,CAAC,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACzB,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;gBAChD,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;oBAC7B,OAAO,CAAC,CAAC;gBACb,CAAC;YACL,CAAC;iBAAM,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC;gBAC9B,OAAO,CAAC,CAAC;YACb,CAAC;QACL,CAAC;QAED,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAAc;QAC3B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnC,MAAM,IAAI,GAAG,SAAS,CAAC;YAEvB,iFAAiF;YACjF,wCAAwC;YACxC,MAAM,GAAG,GAAG,eAAe,MAAM,aAAa,CAAC;YAC/C,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,MAAM,SAAS,SAAS,WAAW,GAAG,EAAE,CAAC,CAAC;YAEtE,uDAAuD;YACvD,0IAA0I;YAC1I,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC5C,WAAW,EAAE,IAAI;gBACjB,GAAG,EAAE,IAAI;aACZ,CAAC,CAAC;YAEH,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAErE,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;YAEtE,KAAK,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,CAAC,EAAE;gBAClB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC;gBACnD,MAAM,CAAC,IAAI,KAAK,CAAC,kBAAkB,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;YACH,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE;gBACpB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC;gBACnD,MAAM,CAAC,IAAI,KAAK,CAAC,kBAAkB,MAAM,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;YAC1D,CAAC,CAAC,CAAC;YAEH,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,CAAC,cAAc,EAAE,EAAE;gBAC7C,IAAI,IAAI,EAAE,CAAC;oBACP,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,kBAAkB,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC;oBACpD,MAAM,CAAC,IAAI,KAAK,CAAC,kBAAkB,MAAM,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC;gBAC3D,CAAC;gBACD,oBAAoB;gBACpB,OAAO,CAAC,IAAI,CAAC,CAAC;YAClB,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,SAAS,KAAK,QAAQ,EAAE,CAAC;YAC7C,IAAI,CAAC,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;QAC/B,CAAC;QAED,MAAM,SAAS,GAAa,IAAI,CAAC,MAAM,CAAC,SAAS;aAC5C,KAAK,CAAC,SAAS,CAAC;aAChB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;aAClB,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAEpB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gCAAgC,IAAI,CAAC,MAAM,CAAC,SAAS,MAAM,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAEvG,IAAI,oBAAoB,GAAa,EAAE,CAAC;QACxC,MAAM,WAAW,GAAa,EAAE,CAAC;QAEjC,uBAAuB;QACvB,IAAI,OAAO,IAAI,CAAC,wBAAwB,KAAK,UAAU,EAAE,CAAC;YACtD,oBAAoB,GAAG,MAAM,IAAI,CAAC,wBAAwB,EAAE,CAAC;YAE7D,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,IAAI,CAAC,SAAS,CAAC,oBAAoB,CAAC,EAAE,CAAC,CAAC;QACzF,CAAC;QAED,KAAK,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;YAC1B,IAAI,OAAO,GAAG,GAAG,CAAC;YAClB,IAAI,OAAO,GAAG,QAAQ,CAAC;YAEvB,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACxD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;gBACjC,OAAO,GAAG,KAAK,CAAC,GAAG,EAAE,IAAI,QAAQ,CAAC;gBAClC,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC9B,CAAC;YAED,qEAAqE;YACrE,IAAI,UAAU,GAAG,OAAO,CAAC;YAEzB,IAAI,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;gBACxB,UAAU,GAAG,MAAM,IAAA,8CAAsB,EAAC,OAAO,CAAC,CAAC;gBAEnD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oCAAoC,UAAU,IAAI,OAAO,WAAW,OAAO,GAAG,CAAC,CAAC;YACnG,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,oCAAoC,UAAU,IAAI,OAAO,GAAG,CAAC,CAAC;YACjF,CAAC;YAED,WAAW,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YAE7B,uBAAuB;YACvB,IAAI,OAAO,IAAI,CAAC,iBAAiB,KAAK,UAAU,EAAE,CAAC;gBAC/C,IAAI,CAAC;oBACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,iBAAiB,CAAC,OAAO,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC;oBAClE,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;wBACjB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,8BAA8B,UAAU,IAAI,OAAO,GAAG,CAAC,CAAC;wBAEvE,MAAM,cAAc,GAAQ,MAAM,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;wBACnE,IAAI,CAAC,IAA4B,CAAC,UAAU,CAAC,GAAG,cAAc,CAAC,OAAO,IAAI,cAAc,CAAC;oBAC9F,CAAC;yBAAM,CAAC;wBACJ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,UAAU,IAAI,OAAO,GAAG,CAAC,CAAC;oBAClF,CAAC;gBACL,CAAC;gBAAC,OAAO,GAAY,EAAE,CAAC;oBACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,UAAU,IAAI,OAAO,MAAM,GAAY,EAAE,CAAC,CAAC;gBACnG,CAAC;YACL,CAAC;iBAAM,IAAI,CAAC,IAAA,oBAAU,EAAC,GAAG,SAAS,iBAAiB,OAAO,eAAe,CAAC,EAAE,CAAC;gBAC1E,sBAAsB;gBACtB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6CAA6C,GAAG,GAAG,CAAC,CAAC;gBAEnE,IAAI,CAAC;oBACD,MAAM,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;oBAC3B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gDAAgD,GAAG,GAAG,CAAC,CAAC;gBAC1E,CAAC;gBAAC,OAAO,GAAQ,EAAE,CAAC;oBAChB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,GAAG,oBAAoB,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACjG,CAAC;YACL,CAAC;QACL,CAAC;QAED,uBAAuB;QACvB,IAAI,OAAO,IAAI,CAAC,mBAAmB,KAAK,UAAU,EAAE,CAAC;YACjD,KAAK,MAAM,mBAAmB,IAAI,oBAAoB,EAAE,CAAC;gBACrD,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,mBAAmB,CAAC,EAAE,CAAC;oBAC7C,IAAI,CAAC;wBACD,MAAM,IAAI,CAAC,mBAAmB,CAAC,mBAAmB,CAAC,CAAC;wBAEpD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gCAAgC,mBAAmB,GAAG,CAAC,CAAC;oBAC1E,CAAC;oBAAC,OAAO,GAAQ,EAAE,CAAC;wBAChB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oCAAoC,mBAAmB,KAAK,GAAG,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;oBAChG,CAAC;gBACL,CAAC;YACL,CAAC;QACL,CAAC;IACL,CAAC;IAED,QAAQ,CAAC,MAAc,EAAE,IAAY,EAAE,SAAkB;QACrD,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC5D,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC1B,MAAM,oBAAoB,GACtB,4GAA4G;gBAC5G,4EAA4E;gBAC5E,iGAAiG;gBACjG,oFAAoF;gBACpF,6GAA6G,CAAC;YAElH,IAAI,SAAS,EAAE,CAAC;gBACZ,MAAM,GAAG,mBAAmB,MAAM,KAAK,oBAAoB,SAAS,CAAC;YACzE,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,GAAG,MAAM,KAAK,oBAAoB,EAAE,CAAC;YAClD,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,IAAI,SAAS,EAAE,CAAC;gBACZ,MAAM,GAAG,4BAA4B,MAAM,SAAS,CAAC;YACzD,CAAC;iBAAM,CAAC;gBACJ,MAAM,GAAG,YAAY,MAAM,EAAE,CAAC;YAClC,CAAC;QACL,CAAC;QAED,IAAI,CAAC;YACD,MAAM,OAAO,GAAkB;gBAC3B,QAAQ,EAAE,IAAI;gBACd,uBAAuB;gBACvB,qCAAqC;aACxC,CAAC;YACF,OAAO;gBACH,MAAM,EAAE,IAAI,gBAAM,CAAC,MAAM,EAAE,OAAO,CAAC;aAC1B,CAAC;QAClB,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,yBAAyB,EAAE,GAAY,CAAC,CAAC;YAC9D,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IAED,OAAO,CAAC,MAAgB,EAAE,IAAY,EAAE,UAAsB,EAAE,OAAgB,EAAE,KAAc;QAC5F,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;QACtB,MAAM,CAAC,QAAQ,GAAG,EAAE,CAAC;QACrB,MAAM,CAAC,SAAS,GAAG,EAAE,CAAC;QACtB,MAAM,CAAC,OAAO,GAAG,EAAE,CAAC;QACpB,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC;QACnB,MAAM,CAAC,UAAU,GAAG,UAAU,CAAC;QAC/B,MAAM,CAAC,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC;QACpD,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC;QACvB,MAAM,CAAC,cAAc,GAAG,EAAE,CAAC;QAC3B,MAAM,CAAC,wBAAwB,GAAG,CAAC,CAAC;QACpC,MAAM,CAAC,+BAA+B,GAAG,CAAC,CAAC;QAC3C,IAAI,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAAE;YACxE,GAAG,EAAE,KAAK;YACV,GAAG,EAAE,IAAI;YACT,MAAM,EAAE,IAAI;SACf,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,IAAA,iBAAO,EAAC,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QAEpE,IAAI,CAAC;YACD,MAAM,CAAC,MAAM,CAAC,eAAe,CAAC,OAAO,EAAE;gBACnC,QAAQ,EAAE,IAAI;gBACd,aAAa,EAAE,IAAI;gBACnB,qCAAqC;aACxC,CAAC,CAAC;QACP,CAAC;QAAC,OAAO,GAAY,EAAE,CAAC;YACpB,IAAI,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAAE;gBACxE,GAAG,EAAE,IAAI;gBACT,GAAG,EAAE,IAAI;gBACT,CAAC,EAAE,SAAS;aACf,CAAC,CAAC;YACH,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAY,CAAC,CAAC;QACtC,CAAC;IACL,CAAC;IAED,WAAW,CAAC,EAA8B;QACtC,IAAI,CAAC,EAAE,EAAE,CAAC;YACN,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,yBAAyB,CAAC,CAAC;YACzC,OAAO;QACX,CAAC;QAED,IAAI,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE,CAAC;YACpB,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC;YACpC,OAAO;QACX,CAAC;QAED,IAAI,EAAE,CAAC,WAAW,IAAI,EAAE,CAAC,WAAW,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YACrD,0DAA0D;YAC1D,OAAO;QACX,CAAC;QAED,IAAI,OAAO,EAAE,KAAK,QAAQ,EAAE,CAAC;YACzB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qCAAqC,OAAO,EAAE,EAAE,CAAC,CAAC;YACjE,OAAO;QACX,CAAC;QACD,MAAM,KAAK,GAAG,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5B,MAAM,QAAQ,GAAG,kBAAkB,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC1D,IAAI,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,CAAC;YAC/C,MAAM,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;YACpC,MAAM,KAAK,GAAG,kBAAkB,CAAC,QAAQ,CAAC;YAC1C,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;gBAChD,IAAI,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;oBACb,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;gBAC3C,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;oBAClC,OAAO,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;gBACnC,CAAC;YACL,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,CAAC,EAAE,aAAa,EAAE,EAAE,CAAC,CAAC;QACtC,CAAC;IACL,CAAC;IAED,4CAA4C;IAC5C,sBAAsB;QAClB,IAAI,KAAK,GAAG,KAAK,CAAC;QAClB,sEAAsE;QACtE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE;YACpD,IAAI,CAAC,IAAI,CAAC,gBAAgB,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC,MAAM,EAAE,CAAC;gBACpF,OAAO,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;YAC7C,CAAC;iBAAM,CAAC;gBACJ,KAAK,GAAG,IAAI,CAAC;YACjB,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;YAClB,IAAI,KAAK,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC;gBAC/B,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;gBAC1B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBACpC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qDAAqD,CAAC,CAAC;YACzE,CAAC;iBAAM,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;gBACtC,IAAI,CAAC,aAAa,GAAG,KAAK,CAAC;gBAC3B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;gBACpC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,6DAA6D,CAAC,CAAC;YACjF,CAAC;QACL,CAAC;IACL,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,IAAY;QACzB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,IAAI,EAAE,CAAC,CAAC;QAEzC,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAE/F,IAAI,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,CAAC;QACzC,CAAC;QAED,IAAI,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACD,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAErE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,IAAI,KAAK,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACvF,CAAC;YAAC,MAAM,CAAC;gBACL,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,sCAAsC,IAAI,KAAK,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC/F,CAAC;YAED,OAAO,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACtC,CAAC;QAED,IAAI,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;YAC9B,OAAO,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;YACnC,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAClC,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,4BAA4B;YAC5B,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,KAAK,CAAC;YAC7B,IAAI,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACxB,2BAA2B;gBAC3B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;oBACpD,IAAI,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,EAAE,CAAC;wBAC9B,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;wBACjE,IAAI,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;4BACnC,IAAI,CAAC,wBAAwB,CAAC,EAAE,CAAC,CAAC;4BAClC,OAAO,IAAI,CAAC,kBAAkB,CAAC,EAAE,CAAC,CAAC;4BACnC,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,EAAE,CAAC;gCAClB,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;4BAC3B,CAAC;wBACL,CAAC;oBACL,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBACtD,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBACtC,MAAM,GAAG,GAAG,IAAI,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC/C,IAAI,GAAG,EAAE,OAAO,CAAC,EAAE,EAAE,CAAC;wBAClB,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;oBACrC,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,IACI,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC;wBACjE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EACtC,CAAC;wBACC,IAAI,CAAC,OAAO,CAAC,OAAO,GAAG,IAAI,CAAC;oBAChC,CAAC;gBACL,CAAC;YACL,CAAC;YAED,6BAA6B;YAC7B,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBACzD,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,EAAE,CAAC;oBACnC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;oBAC3E,IAAI,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;wBACxC,MAAM,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;wBACpC,IAAI,CAAC,uBAAuB,CAAC,EAAE,EAAE,IAAI,CAAC,CAAC;wBACvC,OAAO,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,CAAC;oBAC5C,CAAC;gBACL,CAAC;YACL,CAAC,CAAC,CAAC;YACH,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,iBAAiB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1D,IAAI,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC1C,IAAI,CAAC,iBAAiB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBACxC,CAAC;YACL,CAAC;YAED,KAAK,IAAI,CAAC,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC5D,IAAI,IAAI,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;oBAC5C,MAAM,GAAG,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBACrD,IAAI,GAAG,EAAE,CAAC;wBACN,IAAI,CAAC,yBAAyB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBAChD,CAAC;gBACL,CAAC;YACL,CAAC;YAED,oBAAoB;YACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC1D,YAAY,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACjD,CAAC;YACD,qBAAqB;YACrB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3D,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;YACnD,CAAC;YACD,0BAA0B;YAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3D,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC;oBAClC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;oBACnD,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;wBACrE,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,qCAAqC,KAAK,GAAG,CAAC,CAAC;oBAClE,CAAC;gBACL,CAAC;YACL,CAAC;YAED,6BAA6B;YAC7B,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;gBACzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;oBACzD,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;wBAChC,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;oBACjE,CAAC;gBACL,CAAC;YACL,CAAC;YAED,0BAA0B;YAC1B,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;gBACpD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,aAAa;oBAC5B,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,aAAkC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC;gBAEhF,MAAM,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;oBACxB,IAAI,OAAO,GAA0B,UAAU,CAAC,GAAG,EAAE;wBACjD,IAAI,OAAO,EAAE,CAAC;4BACV,OAAO,GAAG,IAAI,CAAC;4BACf,OAAO,CAAC,IAAI,CAAC,CAAC;wBAClB,CAAC;oBACL,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,aAAa,CAAC,CAAC;oBAErC,IAAI,CAAC;wBACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE;4BAC7B,IAAI,OAAO,EAAE,CAAC;gCACV,YAAY,CAAC,OAAO,CAAC,CAAC;gCACtB,OAAO,GAAG,IAAI,CAAC;gCACf,OAAO,CAAC,IAAI,CAAC,CAAC;4BAClB,CAAC;wBACL,CAAC,CAAC,CAAC;oBACP,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,GAAY,EAAE,CAAC,CAAC;oBAChE,CAAC;gBACL,CAAC,CAAC,CAAC;YACP,CAAC;YAED,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC1B,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,GAA0B;QAC1C,IAAI,GAAG,EAAE,MAAM,EAAE,OAAO,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,KAAK,GAAG,CAAC,GAAG,EAAE,CAAC;YACjE,MAAM,EAAE,GAAG,GAAG,CAAC,GAAG,CAAC;YACnB,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACvB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,8CAA8C,CAAC,CAAC;YAChF,OAAO,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;QACnC,CAAC;QAED,IACI,GAAG,EAAE,MAAM,EAAE,MAAM;YACnB,CAAC,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,KAAK,GAAG,CAAC,GAAG,CAAC;YAC1D,GAAG,CAAC,MAAM,CAAC,MAAM,KAAK,kBAAkB,IAAI,CAAC,SAAS,EAAE,EAC1D,CAAC;YACC,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,CAAC;YAErB,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YACzD,IAAI,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACzC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,IAAI,cAAc,CAAC,CAAC;gBAClD,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,MAAM,QAAQ,GAAG,iBAAiB,MAAM,EAAE,CAAC;YAC3C,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBACzB,IAAI,CAAC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,wBAAwB,CAC7D,GAAG,IAAI,CAAC,SAAS,IAAI,QAAQ,EAAE,EAC/B,IAAI,EACJ,IAAI,CACP,CAAC;YACN,CAAC;YACD,MAAM,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAC1C,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,GAAG,CAAC,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC;YAEpD,IACK,GAAG,CAAC,MAAM,CAAC,UAAyB,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;gBAC3E,GAAG,CAAC,MAAM,CAAC,UAAyB,KAAK,SAAS;gBAClD,GAAG,CAAC,MAAM,CAAC,UAAyB,KAAK,OAAO,EACnD,CAAC;gBACC,aAAa;gBACb,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,oBAAoB,IAAI,KAAK,GAAG,CAAC,MAAM,CAAC,UAAU,GAAG,CAAC,CAAC;gBAErE,IAAI,QAAQ,GAAG,IAAI,CAAC;gBACpB,IAAI,aAAa,EAAE,CAAC;oBAChB,MAAM,EAAE,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;oBAC/D,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;gBAC9D,CAAC;gBACD,MAAM,aAAa,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,YAAY,KAAK,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,CAAC,CAAC;gBAClG,IAAI,CAAC,aAAa,EAAE,CAAC;oBACjB,OAAO,KAAK,CAAC;gBACjB,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBACnC,IAAI,CAAC,OAAO,CACR,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAClB,QAAQ,EACR,GAAG,CAAC,MAAM,CAAC,UAAwB,EACnC,GAAG,CAAC,MAAM,CAAC,OAAO,EAClB,GAAG,CAAC,MAAM,CAAC,KAAK,CACnB,CAAC;gBACF,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,IAAI,GAAG,CAAC,MAAM,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;gBAC/D,aAAa;gBACb,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,+BAA+B,IAAI,EAAE,CAAC,CAAC;gBACrD,0EAA0E;gBAC1E,0DAA0D;gBAC1D,MAAM,iBAAiB,GAAG,IAAA,kDAAgC,EAAC,GAAG,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;gBACrF,oEAAoE;gBACpE,mFAAmF;gBACnF,MAAM,UAAU,GAAG,IAAA,kBAAU,EAAC,gBAAgB,GAAG,IAAI,CAAC,kBAAkB,GAAG,iBAAiB,CAAC,CAAC;gBAE9F,IAAI,QAAgB,CAAC;gBACrB,8EAA8E;gBAC9E,2EAA2E;gBAC3E,iCAAiC;gBACjC,IACI,OAAO,GAAG,CAAC,MAAM,CAAC,QAAQ,KAAK,QAAQ;oBACvC,OAAO,GAAG,CAAC,MAAM,CAAC,UAAU,KAAK,QAAQ;oBACzC,UAAU,KAAK,GAAG,CAAC,MAAM,CAAC,UAAU,EACtC,CAAC;oBACC,iCAAiC;oBACjC,QAAQ,GAAG,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC;oBAC/B,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,kEAAkE,CAAC,CAAC;gBAC7F,CAAC;qBAAM,CAAC;oBACJ,iFAAiF;oBACjF,MAAM,QAAQ,GAAG,IAAA,sCAAoB,EAAC,IAAI,CAAC,CAAC;oBAC5C,IAAI,UAAyB,CAAC;oBAC9B,IAAI,CAAC;wBACD,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,QAAQ,EAAE,iBAAiB,CAAC,CAAC;oBACpE,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,GAAG,qCAAqC,GAAY,EAAE,CAAC,CAAC;wBAC9E,OAAO,KAAK,CAAC;oBACjB,CAAC;oBAED,MAAM,MAAM,GAAG,UAAU,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,eAAe,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAE1F,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;wBACrB,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;4BACpB,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,yCAAyC,MAAM,EAAE,CAAC,CAAC;wBAC5E,CAAC;6BAAM,CAAC;4BACJ,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,IAAI,qCAAqC,CAAC,CAAC;wBAChE,CAAC;wBACD,QAAQ,GAAG,UAAU,CAAC,MAAM,IAAI,EAAE,CAAC;wBAEnC,0GAA0G;wBAC1G,IAAI,CAAC,kBAAkB,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,mDAAmD;wBACtF,MAAM,IAAI,CAAC,wBAAwB,CAAC,IAAI,EAAE;4BACtC,MAAM,EAAE;gCACJ,UAAU;gCACV,QAAQ;6BACX;yBACJ,CAAC,CAAC;oBACP,CAAC;yBAAM,CAAC;wBACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,IAAI,qCAAqC,MAAM,EAAE,CAAC,CAAC;wBACrE,OAAO,KAAK,CAAC;oBACjB,CAAC;gBACL,CAAC;gBACD,MAAM,aAAa,GAAqB,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,YAAY,KAAK,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;gBACxG,IAAI,CAAC,aAAa,EAAE,CAAC;oBACjB,OAAO,KAAK,CAAC;gBACjB,CAAC;gBACD,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC;gBACnC,IAAI,CAAC,OAAO,CACR,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAClB,IAAI,EACJ,GAAG,CAAC,MAAM,CAAC,UAAwB,EACnC,GAAG,CAAC,MAAM,CAAC,OAAO,EAClB,GAAG,CAAC,MAAM,CAAC,KAAK,CACnB,CAAC;gBACF,OAAO,IAAI,CAAC;YAChB,CAAC;YAED,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,4BAA4B,IAAI,MAAM,GAAG,CAAC,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;YAC7E,OAAO,KAAK,CAAC;QACjB,CAAC;QAED,IAAI,KAAa,CAAC;QAClB,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC;YACX,KAAK,GAAG,GAAG,CAAC,GAAG,CAAC;YAChB,MAAM,YAAY,GAAG,KAAK,CAAC,SAAS,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC;YAEhE,IAAI,CAAC,YAAY,CAAC,MAAM,IAAI,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;gBACrD,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,eAAe,KAAK,cAAc,CAAC,CAAC;gBACnD,OAAO,KAAK,CAAC;YACjB,CAAC;YACD,MAAM,IAAI,CAAC,QAAQ,CAAC,iBAAiB,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QACtE,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;QACrC,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,EAAU;QAC3B,IAAI,GAA6C,CAAC;QAClD,IAAI,CAAC;YACD,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,qBAAqB,CAAC,EAAE,CAAC,CAA6C,CAAC;QAC7F,CAAC;QAAC,OAAO,GAAQ,EAAE,CAAC;YAChB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,mBAAmB,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,IAAI,CAAC,GAAG,EAAE,CAAC;YACP,OAAO,KAAK,CAAC;QACjB,CAAC;QACD,OAAO,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,YAAmC;QAChD,4BAA4B;QAC5B,MAAM,IAAI,CAAC,kBAAkB,CAAC,YAAY,CAAC,GAAG,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC/E,MAAM,IAAI,CAAC,mBAAmB,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC;QACjD,OAAO,IAAI,CAAC,aAAa,CAAC,YAAY,CAAC,CAAC;IAC5C,CAAC;IAED,aAAa,CACT,IAAU,EACV,UAA0B,EAC1B,KAAa,EACb,GAAW,EACX,aAA8B,EAC9B,QAAiB,EACjB,QAAgB,EAChB,SAAiB,EACjB,UAAoB;QAEpB,IAAI,EAAE,GAAS,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,UAAU,CAAC,CAAC;QAEjF,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,QAAQ,EAAE,KAAK,KAAK,EAAE,CAAC;YAC3C,EAAE,GAAG,QAAQ,CAAC,CAAC,CAAC,gBAAgB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;QAC5F,CAAC;QACD,EAAE,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACtB,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,aAAkC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAEzF,MAAM,CAAC,cAAc,EAAE,gBAAgB,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC5D,MAAM,eAAe,GAAG,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;QACrD,MAAM,iBAAiB,GAAG,QAAQ,CAAC,gBAAgB,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QAE9D,IACI,EAAE,CAAC,QAAQ,EAAE,GAAG,eAAe;YAC/B,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,eAAe,IAAI,EAAE,CAAC,UAAU,EAAE,GAAG,iBAAiB,CAAC,EAC5E,CAAC;YACC,EAAE,GAAG,gBAAgB,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC;YACzC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;QAED,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACtD,MAAM,aAAa,GAAG,QAAQ,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QACjD,MAAM,eAAe,GAAG,QAAQ,CAAC,cAAc,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC;QAE1D,IAAI,EAAE,CAAC,QAAQ,EAAE,GAAG,aAAa,IAAI,CAAC,EAAE,CAAC,QAAQ,EAAE,KAAK,aAAa,IAAI,EAAE,CAAC,UAAU,EAAE,GAAG,eAAe,CAAC,EAAE,CAAC;YAC1G,EAAE,GAAG,gBAAgB,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YACvC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QACrB,CAAC;QAED,uBAAuB;QACvB,IAAI,IAAI,GAAG,EAAE,IAAI,UAAU,EAAE,CAAC;YAC1B,oBAAoB;YACpB,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QACjC,CAAC;QACD,OAAO,EAAE,CAAC;IACd,CAAC;IAED,KAAK,CAAC,YAAY;QACd,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,KAAK,GAAG,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,GAAG,CAAC,UAAU,EAAE,CAAC;QACjC,IAAI,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,CAAC;YAC7B,IAAI,KAAK,GAAG,EAAE,EAAE,CAAC;gBACb,KAAK,IAAI,EAAE,CAAC;YAChB,CAAC;QACL,CAAC;QACD,IAAI,MAAc,CAAC;QACnB,IAAI,IAAI,CAAC,YAAY,CAAC,YAAY,EAAE,CAAC;YACjC,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACJ,MAAM,GAAG,KAAK,CAAC,QAAQ,EAAE,CAAC;QAC9B,CAAC;QAED,MAAM,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAAE;YACrC,GAAG,EAAE,GAAG,MAAM,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE;YACvD,GAAG,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC,CAAC;QACrC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;QAClB,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;QACvB,MAAM,QAAQ,GAAG,GAAG,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC5C,IAAI,CAAC,iBAAiB,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,YAAY,EAAE,EAAE,QAAQ,CAAC,CAAC;IAC7E,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,yBAAyB;QACzB,IACI,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,SAAS;YAClC,IAAI,CAAC,MAAM,CAAC,SAAS,KAAK,SAAS;YAClC,IAAI,CAAC,MAAM,CAAC,QAA8B,KAAK,EAAE;YACjD,IAAI,CAAC,MAAM,CAAC,SAA+B,KAAK,EAAE;YACnD,IAAI,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI;YAC7B,IAAI,CAAC,MAAM,CAAC,SAAS,KAAK,IAAI,EAChC,CAAC;YACC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uDAAuD,CAAC,CAAC;YACxE,OAAO;QACX,CAAC;QAED,iCAAiC;QACjC,MAAM,SAAS,GAAG,kBAAkB,EAAE,CAAC;QACvC,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,CAAC;QAE3B,MAAM,YAAY,GAAG,IAAI,CAAC,aAAa,CACnC,SAAS,EACT,IAAI,CAAC,MAAM,CAAC,YAAY,EACxB,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAC7B,IAAI,CAAC,MAAM,CAAC,eAAe,EAC3B,IAAI,CAAC,MAAM,CAAC,aAAa,EACzB,KAAK,EACL,IAAI,CAAC,MAAM,CAAC,QAAQ,EACpB,IAAI,CAAC,MAAM,CAAC,SAAS,CACxB,CAAC;QACF,MAAM,WAAW,GAAG,IAAI,CAAC,aAAa,CAClC,SAAS,EACT,IAAI,CAAC,MAAM,CAAC,WAAW,EACvB,IAAI,CAAC,MAAM,CAAC,gBAAgB,EAC5B,IAAI,CAAC,MAAM,CAAC,cAAc,EAC1B,IAAI,CAAC,MAAM,CAAC,YAAY,EACxB,IAAI,EACJ,IAAI,CAAC,MAAM,CAAC,QAAQ,EACpB,IAAI,CAAC,MAAM,CAAC,SAAS,CACxB,CAAC;QAEF,UAAU;QACV,IAAI,cAAc,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QAChE,IAAI,cAAc,GAAG,CAAC,IAAI,cAAc,GAAG,OAAO,EAAE,CAAC;YACjD,cAAc,GAAG,OAAO,CAAC;QAC7B,CAAC;QAED,SAAS;QACT,IAAI,aAAa,GAAG,WAAW,CAAC,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QAC9D,IAAI,aAAa,GAAG,CAAC,IAAI,aAAa,GAAG,OAAO,EAAE,CAAC;YAC/C,aAAa,GAAG,OAAO,CAAC;QAC5B,CAAC;QAED,MAAM,SAAS,GAAsC,MAAM,IAAI,CAAC,aAAa,CAAC,qBAAqB,CAAC,CAAC;QACrG,IAAI,KAAc,CAAC;QACnB,IAAI,cAAc,GAAG,IAAI,EAAE,CAAC;YACxB,KAAK,GAAG,IAAI,CAAC;QACjB,CAAC;aAAM,IAAI,aAAa,GAAG,IAAI,EAAE,CAAC;YAC9B,KAAK,GAAG,KAAK,CAAC;QAClB,CAAC;aAAM,CAAC;YACJ,sBAAsB;YACtB,KAAK,GAAG,OAAO,CAAC,OAAO,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,OAAO,IAAI,WAAW,CAAC;QACzF,CAAC;QAED,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QACvD,IAAI,UAAU,KAAK,KAAK,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;YAC7C,MAAM,IAAI,CAAC,QAAQ,CAAC,qBAAqB,EAAE,KAAK,EAAE,IAAI,CAAC,CAAC;QAC5D,CAAC;QAED,MAAM,cAAc,GAChB,MAAM,IAAI,CAAC,aAAa,CAAC,4BAA4B,CAAC,CAAC;QAC3D,MAAM,gBAAgB,GAAG,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC;QACxD,MAAM,GAAG,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC;QAE1D,IAAI,GAAG,KAAK,gBAAgB,IAAI,cAAc,KAAK,IAAI,EAAE,CAAC;YACtD,MAAM,IAAI,CAAC,QAAQ,CAAC,4BAA4B,EAAE,gBAAgB,EAAE,IAAI,CAAC,CAAC;QAC9E,CAAC;QAED,IAAI,WAAW,GAAG,cAAc,CAAC;QACjC,IAAI,cAAc,GAAG,aAAa,EAAE,CAAC;YACjC,WAAW,GAAG,aAAa,CAAC;QAChC,CAAC;QACD,WAAW,GAAG,WAAW,GAAG,IAAI,CAAC;QACjC,IAAI,WAAW,GAAG,IAAI,EAAE,CAAC;YACrB,WAAW,GAAG,IAAI,CAAC;QACvB,CAAC;QAED,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,WAAW,CAAC,CAAC;IACnF,CAAC;IAED,iBAAiB;QACb,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QACjC,CAAC;QACD,IAAI,IAAI,CAAC,gBAAgB,EAAE,CAAC;YACxB,YAAY,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;YACpC,IAAI,CAAC,gBAAgB,GAAG,IAAI,CAAC;QACjC,CAAC;QACD,IAAI,IAAI,CAAC,iBAAiB,EAAE,CAAC;YACzB,YAAY,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;YACrC,IAAI,CAAC,iBAAiB,GAAG,IAAI,CAAC;QAClC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,SAAS;QACX,IAAI,IAAuB,CAAC;QAC5B,IAAI,MAA0B,CAAC;QAC/B,IAAI,CAAC;YACD,IAAI,GAAG,IAAA,kBAAQ,EAAC,GAAG,SAAS,wDAAwD,CAAC,CAAC;YACtF,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,aAAa,CACpC,kBAAkB,EAClB,iDAAiD,CACpD,CAAC;YACF,IAAI,OAAO,EAAE,IAAI,EAAE,CAAC;gBAChB,MAAM,GAAG,OAAO,CAAC,IAAc,CAAC;YACpC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACL,SAAS;QACb,CAAC;QAED,IAAI,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,MAAM,EAAE,UAAU,KAAK,KAAK,EAAE,CAAC;YACvD,IAAI,CAAC;gBACD,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,CACtB,IAAI,CAAC,KAAK,CAAC,IAAA,sBAAY,EAAC,GAAG,SAAS,4BAA4B,CAAC,CAAC,QAAQ,EAAE,CAAC,EAC7E,QAAQ,CACX,CAAC;gBAEF,MAAM,KAAK,GAAG,wDAAa,OAAO,GAAC,CAAC;gBACpC,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;gBAC1C,IAAI,IAA6B,CAAC;gBAClC,IAAI,GAAG,EAAE,CAAC;oBACN,IAAI,GAAG,MAAM,GAAG,CAAC,IAAI,CAAC,aAAa,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC;oBAC3D,IAAI,IAAI,EAAE,UAAU,KAAK,KAAK,EAAE,CAAC;wBAC7B,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;wBACxD,OAAO,KAAK,CAAC;oBACjB,CAAC;gBACL,CAAC;qBAAM,CAAC;oBACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;oBACxD,OAAO,KAAK,CAAC;gBACjB,CAAC;gBACD,IAAA,uBAAa,EAAC,GAAG,SAAS,wDAAwD,EAAE,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;gBACvG,mBAAmB;gBACnB,MAAM,IAAI,CAAC,cAAc,CACrB,kBAAkB,EAClB,iDAAiD,EACjD,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CACpB,CAAC;gBACF,OAAO,IAAI,CAAC;YAChB,CAAC;YAAC,OAAO,GAAY,EAAE,CAAC;gBACpB,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,sBAAsB,GAAY,EAAE,CAAC,CAAC;gBACrD,OAAO,KAAK,CAAC;YACjB,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,gBAAgB;QAClB,IAAI,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;gBACjE,MAAM,QAAQ,GAAG,kBAAkB,EAAE,CAAC;gBAEtC,MAAM,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;gBAEhG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6BAA6B,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAErE,KAAK,MAAM,CAAC,IAAI,KAAK,EAAE,CAAC;oBACpB,IAAI,CAAC;wBACD,MAAM,KAAK,GAAG,mBAAmB,CAAC,EAAE,CAAC;wBAErC,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE;4BACtC,IAAI,EAAE,OAAO;4BACb,MAAM,EAAE;gCACJ,IAAI,EAAE,SAAS,CAAC,EAAE;gCAClB,IAAI,EAAE,QAAQ;gCACd,IAAI,EAAE,OAAO;gCACb,IAAI,EAAE,IAAI;gCACV,KAAK,EAAE,KAAK;6BACf;4BACD,MAAM,EAAE,EAAE;yBACb,CAAC,CAAC;wBAEH,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;4BAClD,MAAM,aAAa,GAAG,yBAAyB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;4BAC1D,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE;gCACvB,GAAG,EAAE,aAAa;gCAClB,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE;gCACzB,GAAG,EAAE,IAAI;6BACZ,CAAC,CAAC;wBACP,CAAC;6BAAM,CAAC;4BACJ,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;wBAC5E,CAAC;oBACL,CAAC;oBAAC,OAAO,GAAY,EAAE,CAAC;wBACpB,IAAI,CAAC,GAAG,CAAC,KAAK,CACV,0DAA0D,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,GAAY,EAAE,CAC1G,CAAC;oBACN,CAAC;gBACL,CAAC;gBAED,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC;gBAC7B,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACtB,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBACxB,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;gBACxB,SAAS,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC;gBAC7B,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;gBAE3C,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,4BAA4B,SAAS,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;gBACtE,IAAI,CAAC,gBAAgB,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,SAAS,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;YACxG,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,kCAAkC;YAClC,IAAI,CAAC,SAAS,CAAC,iBAAiB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,CAAC;IACL,CAAC;IAED;;OAEG;IACH,KAAK,GAAG,CAAC,OAAe,EAAE,QAA4B,EAAQ,EAAE;QAC5D,qEAAqE;QACrE,IAAI,CAAC,QAAQ,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;YACnC,QAAQ,GAAG,OAAO,CAAC;QACvB,CAAC;aAAM,IAAI,QAAQ,KAAK,OAAO,EAAE,CAAC;YAC9B,kCAAkC;YAClC,IAAI,IAAI,EAAE,CAAC;gBACP,OAAO;YACX,CAAC;YACD,QAAQ,GAAG,OAAO,CAAC;QACvB,CAAC;QAED,IAAI,IAAI,EAAE,GAAG,EAAE,CAAC;YACZ,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACJ,OAAO,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,WAAW,EAAE,KAAK,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;IACL,CAAC,CAAC;IAEF,cAAc,CAAC,MAA2B;QACtC,IAAI,CAAC;YACD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,KAAK,EAAE;gBACjC,KAAK,EAAE,UAAU,EAAU;oBACvB,OAAO,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,GAAG,IAAI,CAAC,SAAS,IAAI,EAAE,EAAE,CAAC,CAAC;gBACvD,CAAC;gBACD,UAAU,EAAE,KAAK;aACpB,CAAC,CAAC;QACP,CAAC;QAAC,MAAM,CAAC;YACL,OAAO,CAAC,KAAK,CAAC,6BAA6B,CAAC,CAAC;QACjD,CAAC;IACL,CAAC;IAED;;;OAGG;IACH,kCAAkC,CAAC,QAAgB,EAAE,YAAoB;QACrE,gEAAgE;QAChE,uEAAuE;QACvE,IAAI,IAAI,CAAC,kBAAkB,IAAI,IAAI,IAAI,IAAI,CAAC,kBAAkB,KAAK,EAAE,EAAE,CAAC;YACpE,IAAI,CAAC,+BAA+B,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC;QAC7E,CAAC;QACD,+DAA+D;QAC/D,IAAI,CAAC,kBAAkB,IAAI,GAAG,YAAY,IAAI,CAAC;QAC/C,yDAAyD;QACzD,6CAA6C;QAC7C,MAAM,qBAAqB,GAAG,aAAa,CAAC;QAC5C,SAAS,CAAC,qBAAqB,CAAC,GAAG,IAAI,CAAC,kBAAkB,CAAC;QAC3D,+EAA+E;QAC/E,IAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC;YACrC,CAAC,qBAAqB,CAAC,EAAE,IAAI,CAAC,kBAAkB;SACnD,CAAC,CAAC;QACH,mBAAmB,CAAC,0BAA0B,CAAC;YAC3C,CAAC,qBAAqB,CAAC,EAAE,IAAI,CAAC,kBAAkB;SACnD,CAAC,CAAC;IACP,CAAC;IAED,SAAS,CAAC,IAAY;QAClB,IAAI,IAAI,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,CAAC;YAClC,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,CAAC,sBAAsB,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QAChB,CAAC;QACD,IAAI,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;YACzB,IAAI,GAAG,IAAI,CAAC,OAAO,CACf,WAAW,EACX,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,CAC5F,CAAC,CAAC,mCAAmC;QAC1C,CAAC;aAAM,CAAC;YACJ,IAAI,GAAG,IAAI,CAAC,OAAO,CACf,WAAW,EACX,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAC3F,CAAC,CAAC,mCAAmC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC;IAChB,CAAC;IAED,SAAS;QACL,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACxB,IAAI,CAAC,oBAAoB,CAAC,EAAE,GAAG,EAAE,KAAK,EAAE,CAAC,CAAC;YAC1C,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,GAAG,EAAE;gBACzC,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC;gBAClC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC3C,CAAC,EAAE,GAAG,CAAC,CAAC;YACR,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,UAAU,CAAC,YAAY,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtF,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC;QACtD,CAAC;QAED,OAAO,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,IAAI,CAAC,GAAG,EAAE;YAC1C,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC;YAC7B,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,KAAK,CAAC;YAChC,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,EAAE,CAAC;YAChC,IAAI,IAAI,CAAC,UAAU,CAAC,UAAU,EAAE,CAAC;gBAC7B,YAAY,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;gBACzC,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC;YACtC,CAAC;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,EAAsB;QAC3C,IAAI,EAAE,EAAE,CAAC;YACL,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YAC7B,IAAI,GAAG,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC;gBACvB,MAAM,IAAI,CAAC,wBAAwB,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;YACjF,CAAC;QACL,CAAC;IACL,CAAC;IAED,oBAAoB,CAAC,OAAY;QAC7B,IAAI,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;YACxB,IAAI,CAAC;gBACD,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,qBAAqB,OAAO,EAAE,CAAC,CAAC;gBAC9C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxC,CAAC;YAAC,MAAM,CAAC;gBACL,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,GAAG,EAAE,CACvB,IAAI,CAAC,GAAG,CAAC,IAAI,CACT,iBAAiB,IAAI,CAAC,UAAU,CAAC,UAAU,+CAA+C,CAC7F,CACJ,CAAC;YACN,CAAC;QACL,CAAC;aAAM,CAAC;YACJ,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;YAC9D,IAAI,CAAC,QAAQ,CACT,YAAY,EACZ,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,6CAA6C,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAC7F,IAAI,CACP,CAAC;QACN,CAAC;IACL,CAAC;IAED,UAAU,CAAC,IAAuE;QAC9E,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YAC7B,OAAO;QACX,CAAC;QAED,IAAI,CAAC,UAAU,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACrC,kCAAkC;QAClC,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC;aACnC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;aAC5B,IAAI,CAAC,GAAG,EAAE;YACP,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,IAAI,CAAC,UAAU,CAAC,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC;gBAC/C,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,EAAE,CAAC;YACpC,CAAC;iBAAM,CAAC;gBACJ,IAAI,CAAC,UAAU,CAAC,eAAe,GAAG,EAAE,CAAC;gBACrC,IAAI,CAAC,UAAU,CAAC,UAAU,GAAG,IAAI,CAAC,UAAoB,CAAC;YAC3D,CAAC;YAED,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;YAEjD,IAAI,CAAC,UAAU,CAAC,YAAY,GAAG,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;gBACjD,MAAM,OAAO,GAAgB;oBACzB,KAAK,EAAE,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,CAAC;oBAC9C,wCAAwC;iBAC3C,CAAC;gBACF,MAAM,IAAI,GAAa,EAAE,CAAC;gBAC1B,IAAI,IAAI,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC;oBAClC,IAAI,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBAChC,CAAC;gBAED,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,IAAA,yBAAI,EAAC,GAAG,SAAS,iBAAiB,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;gBAE3E;;;iEAGiD;gBAEjD,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CACrB,SAAS,EACT,CACI,OAQO,EACT,EAAE;oBACA,IAAI,QAMH,CAAC;oBACF,IAAI,OAAO,OAAO,KAAK,QAAQ,EAAE,CAAC;wBAC9B,IAAI,CAAC;4BACD,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;wBACnC,CAAC;wBAAC,MAAM,CAAC;4BACL,OAAO,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,wCAAwC,OAAO,EAAE,CAAC,CAAC;wBAC7E,CAAC;oBACL,CAAC;yBAAM,CAAC;wBACJ,QAAQ,GAAG,OAAO,CAAC;oBACvB,CAAC;oBAED,IAAI,QAAQ,CAAC,GAAG,KAAK,OAAO,EAAE,CAAC;wBAC3B,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC;oBAChE,CAAC;oBAED,QAAQ,QAAQ,CAAC,GAAG,EAAE,CAAC;wBACnB,KAAK,OAAO,CAAC,CAAC,CAAC;4BACX,IAAI,CAAC,oBAAoB,CAAC;gCACtB,GAAG,EAAE,OAAO;gCACZ,UAAU,EAAE,IAAI,CAAC,UAAU,CAAC,UAAU;gCACtC,eAAe,EAAE,IAAI,CAAC,UAAU,CAAC,eAAe;gCAChD,QAAQ,EAAE,IAAI,CAAC,QAAQ;6BAC1B,CAAC,CAAC;4BACH,MAAM;wBACV,CAAC;wBAED,KAAK,SAAS,CAAC,CAAC,CAAC;4BACb,sDAAsD;4BACtD,MAAM;wBACV,CAAC;wBAED,KAAK,QAAQ,CAAC,CAAC,CAAC;4BACZ,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,IAAI,CAAC;4BAC9B,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;4BAC5B,MAAM;wBACV,CAAC;wBAED,KAAK,SAAS,CAAC,CAAC,CAAC;4BACb,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,KAAK,CAAC;4BAC/B,yBAAyB;4BACzB,MAAM;wBACV,CAAC;wBAED,KAAK,KAAK,CAAC,CAAC,CAAC;4BACT,OAAO,CAAC,GAAG,CAAC,IAAI,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;4BACvD,MAAM;wBACV,CAAC;wBAED,KAAK,cAAc,CAAC,CAAC,CAAC;4BAClB,OAAO,CAAC,GAAG,CACP,0CAA0C,QAAQ,CAAC,QAAQ,KAAK,QAAQ,CAAC,MAAM,EAAE,CACpF,CAAC;4BACF,MAAM;wBACV,CAAC;oBACL,CAAC;gBACL,CAAC,CACJ,CAAC;gBACF,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,EAAE,KAAK,CAAC,EAAE;oBACvC,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,2BAA2B,KAAK,EAAE,CAAC,CAAC;oBACnD,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;gBAC/E,CAAC,CAAC,CAAC;gBAEH,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,EAAE,CAAC,IAAY,EAAQ,EAAE;oBACrD,IAAI,IAAI,EAAE,CAAC;wBACP,IAAI,CAAC,QAAQ,CACT,YAAY,EACZ,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,0BAA0B,IAAI,EAAE,EAAE,CAAC,EACzE,IAAI,CACP,CAAC;oBACN,CAAC;oBACD,IAAI,CAAC,QAAQ,CAAC,YAAY,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,cAAc,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC;oBACjF,IAAI,CAAC,UAAU,CAAC,KAAK,GAAG,IAAI,CAAC;oBAC7B,OAAO,CAAC,IAAI,CAAC,CAAC;gBAClB,CAAC,CAAC,CAAC;YACP,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;IACX,CAAC;CACJ;AAED,SAAS,eAAe,CACpB,KAAe,EACf,gBAA0E;IAE1E,IAAI,OAAO,GAAG,KAAK,CAAC;IACpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,GAAG,GAAG,gBAAgB,CAAC,MAAM,EAAE,CAAC,GAAG,GAAG,EAAE,CAAC,EAAE,EAAE,CAAC;QAC1D,IAAI,gBAAgB,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,IAAI,gBAAgB,CAAC,KAAK,KAAK,IAAI,EAAE,CAAC;gBAClC,OAAO,IAAI,CAAC;YAChB,CAAC;YACD,OAAO,GAAG,IAAI,CAAC;QACnB,CAAC;aAAM,IAAI,gBAAgB,CAAC,KAAK,KAAK,KAAK,EAAE,CAAC;YAC1C,OAAO,KAAK,CAAC;QACjB,CAAC;IACL,CAAC;IACD,OAAO,OAAO,CAAC;AACnB,CAAC;AAED,oEAAoE;AACpE,IAAI,OAAO,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;IAC1B,yCAAyC;IACzC,MAAM,CAAC,OAAO,GAAG,CAAC,OAA4C,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AAC/F,CAAC;KAAM,CAAC;IACJ,wCAAwC;IACxC,CAAC,GAAG,EAAE,CAAC,IAAI,UAAU,EAAE,CAAC,EAAE,CAAC;AAC/B,CAAC","sourcesContent":["/*\n * Javascript adapter\n *\n * The MIT License (MIT)\n *\n * Copyright (c) 2014-2024 bluefox ,\n *\n * Copyright (c) 2014 hobbyquaker\n */\n\nimport { Script, type ScriptOptions } from 'node:vm';\nimport { readFileSync, existsSync, statSync, writeFileSync, type Stats } from 'node:fs';\nimport { join, sep, normalize } from 'node:path';\nimport { fork, type ForkOptions } from 'node:child_process';\nimport { setTypeScriptResolveOptions, Server } from 'virtual-tsc';\nimport { isDeepStrictEqual } from 'node:util';\n\nimport * as dgram from 'node:dgram';\nimport * as crypto from 'node:crypto';\nimport * as dns from 'node:dns';\nimport * as events from 'node:events';\nimport * as http from 'node:http';\nimport * as https from 'node:https';\nimport * as http2 from 'node:http2';\nimport * as net from 'node:net';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\nimport * as util from 'node:util';\nimport * as child_process from 'node:child_process';\nimport * as stream from 'node:stream';\nimport * as zlib from 'node:zlib';\n\n// @ts-expect-error no types available\nimport * as suncalc from 'suncalc2';\nimport * as axios from 'axios';\n// @ts-expect-error no types available\nimport * as wake_on_lan from 'wake_on_lan';\nimport * as nodeSchedule from 'node-schedule';\n\nimport { getAbsoluteDefaultDataDir, Adapter, EXIT_CODES, type AdapterOptions } from '@iobroker/adapter-core';\nimport type SentryPlugin from '@iobroker/plugin-sentry';\nimport type { GetTimesResult } from 'suncalc';\nimport type { CompileResult } from 'virtual-tsc/build/util';\n\nimport { Mirror } from './lib/mirror';\nimport ProtectFs from './lib/protectFs';\nimport { setLanguage, getLanguage } from './lib/words';\nimport { sandBox } from './lib/sandbox';\nimport { requestModuleNameByUrl } from './lib/nodeModulesManagement';\nimport { createEventObject, type EventObj } from './lib/eventObj';\nimport { type AstroEventName, Scheduler } from './lib/scheduler';\nimport { targetTsLib, tsCompilerOptions, jsDeclarationCompilerOptions } from './lib/typescriptSettings';\nimport { hashSource } from './lib/tools';\nimport {\n resolveTypescriptLibs,\n resolveTypings,\n scriptIdToTSFilename,\n transformScriptBeforeCompilation,\n transformGlobalDeclarations,\n} from './lib/typescriptTools';\nimport type {\n FileSubscriptionResult,\n JavascriptContext,\n JavaScriptAdapterConfig,\n JsScript,\n ScriptType,\n SubscriptionResult,\n SubscribeObject,\n JavascriptTimer,\n SandboxType,\n LogMessage,\n DebugState,\n} from './types';\nimport type { PatternEventCompareFunction } from './lib/patternCompareFunctions';\n\ntype MODULES = {\n fs: ProtectFs;\n 'fs/promises': ProtectFs['promises'];\n dgram: typeof dgram;\n crypto: typeof crypto;\n dns: typeof dns;\n events: typeof events;\n http: typeof http;\n https: typeof https;\n http2: typeof http2;\n net: typeof net;\n os: typeof os;\n path: typeof path;\n util: typeof util;\n child_process: typeof child_process;\n stream: typeof stream;\n zlib: typeof zlib;\n suncalc: typeof suncalc;\n axios: typeof axios;\n wake_on_lan: typeof wake_on_lan;\n nodeSchedule: typeof nodeSchedule;\n};\n\n/**\n * List of forbidden Locations for a mirror directory\n * relative to the default data directory\n * ATTENTION: the same list is also located in index_m.html!!\n */\nconst forbiddenMirrorLocations: string[] = [\n 'backup-objects',\n 'files',\n 'backitup',\n '../backups',\n '../node_modules',\n '../log',\n];\n\nconst packageJson: Record = JSON.parse(readFileSync(`${__dirname}/../package.json`).toString());\nconst SCRIPT_CODE_MARKER = 'script.js.';\n\nlet webstormDebug: string | undefined;\n\nconst isCI = !!process.env.CI;\n\n// ambient declarations for typescript\nlet tsAmbient: Record;\n\n// TypeScript's scripts are only recompiled if their source hash changes.\n// If an adapter update fixes the compilation bugs, a user won't notice until the changes and re-saves the script.\n// To avoid that, we also include the\n// adapter version and TypeScript version in the hash\nconst tsSourceHashBase = `versions:adapter=${packageJson.version},typescript=${packageJson.dependencies.typescript}`;\n\n// taken from here: https://stackoverflow.com/questions/11887934/how-to-check-if-dst-daylight-saving-time-is-in-effect-and-if-so-the-offset\nfunction dstOffsetAtDate(dateInput: Date): number {\n const fullYear: number = dateInput.getFullYear() | 0;\n // \"Leap Years are any year that can be exactly divided by 4 (2012, 2016, etc)\n // except if it can be exactly divided by 100, then it isn't (2100, 2200, etc)\n // except if it can be exactly divided by 400, then it is (2000, 2400)\"\n // (https://www.mathsisfun.com/leap-years.html).\n const isLeapYear: 1 | 0 = ((fullYear & 3) | ((fullYear / 100) & 3)) === 0 ? 1 : 0;\n // (fullYear & 3) = (fullYear % 4), but faster\n //Alternative:var isLeapYear=(new Date(currentYear,1,29,12)).getDate()===29?1:0\n const fullMonth: number = dateInput.getMonth() | 0;\n return (\n // 1. We know what the time since the Epoch really is\n +dateInput - // same as the dateInput.getTime() method\n // 2. We know what the time since the Epoch at the start of the year is\n +new Date(fullYear, 0) - // day defaults to 1 if not explicitly zeroed\n // 3. Now, subtract what we would expect the time to be if daylight savings\n // did not exist. This yields the time-offset due to daylight savings.\n // Calculate the day of the year in the Gregorian calendar\n // The code below works based upon the facts of signed right shifts\n // • (x) >> n: shifts n and fills in the n highest bits with 0s\n // • (-x) >> n: shifts n and fills in the n highest bits with 1s\n // (This assumes that x is a positive integer)\n ((((-1 + // the first day in the year is day 1\n (31 & (-fullMonth >> 4)) + // January // (-11)>>4 = -1\n ((28 + isLeapYear) & ((1 - fullMonth) >> 4)) + // February\n (31 & ((2 - fullMonth) >> 4)) + // March\n (30 & ((3 - fullMonth) >> 4)) + // April\n (31 & ((4 - fullMonth) >> 4)) + // May\n (30 & ((5 - fullMonth) >> 4)) + // June\n (31 & ((6 - fullMonth) >> 4)) + // July\n (31 & ((7 - fullMonth) >> 4)) + // August\n (30 & ((8 - fullMonth) >> 4)) + // September\n (31 & ((9 - fullMonth) >> 4)) + // October\n (30 & ((10 - fullMonth) >> 4)) + // November\n // There are no months past December: the year rolls into the next.\n // Thus, \"fullMonth\" is 0-based, so it will never be 12 in JavaScript\n\n (dateInput.getDate() | 0)) & // get day of the month\n 0xffff) *\n 24 *\n 60 + // 24 hours in a day, 60 minutes in an hour\n (dateInput.getHours() & 0xff) * 60 + // 60 minutes in an hour\n (dateInput.getMinutes() & 0xff)) |\n 0) *\n 60 *\n 1000 - // 60 seconds in a minute * 1000 milliseconds in a second\n (dateInput.getSeconds() & 0xff) * 1000 - // 1000 milliseconds in a second\n dateInput.getMilliseconds()\n );\n}\n\nconst regExGlobalOld = /_global$/;\nconst regExGlobalNew = /script\\.js\\.global\\./;\n\nfunction checkIsGlobal(obj: ioBroker.ScriptObject): boolean {\n return obj?.common && (regExGlobalOld.test(obj.common.name) || regExGlobalNew.test(obj._id));\n}\n\nfunction fileMatching(sub: FileSubscriptionResult, id: string, fileName: string): boolean {\n if (sub.idRegEx) {\n if (!sub.idRegEx.test(id)) {\n return false;\n }\n } else {\n if (sub.id !== id) {\n return false;\n }\n }\n if (sub.fileRegEx) {\n if (!sub.fileRegEx.test(fileName)) {\n return false;\n }\n } else {\n if (sub.fileNamePattern !== fileName) {\n return false;\n }\n }\n\n return true;\n}\n\nfunction getNextTimeEvent(time: string, useNextDay?: boolean): Date {\n const now: Date = getAstroStartOfDay();\n const [timeHours, timeMinutes] = time.split(':');\n const nTimeHours = parseInt(timeHours, 10);\n const nTimeMinutes = parseInt(timeMinutes, 10);\n if (\n useNextDay &&\n (now.getHours() > nTimeHours || (now.getHours() === nTimeHours && now.getMinutes() > nTimeMinutes))\n ) {\n now.setDate(now.getDate() + 1);\n }\n\n now.setHours(nTimeHours);\n now.setMinutes(nTimeMinutes);\n\n return now;\n}\n\nfunction getAstroStartOfDay(): Date {\n const d = new Date();\n d.setMinutes(0);\n d.setSeconds(0);\n d.setMilliseconds(0);\n d.setTime(d.getTime() - d.getTimezoneOffset() * 60 * 1000);\n d.setUTCHours(0);\n\n return d;\n}\n\nfunction formatHoursMinutesSeconds(date: Date): string {\n const h = String(date.getHours());\n const m = String(date.getMinutes());\n const s = String(date.getSeconds());\n\n return `${h.padStart(2, '0')}:${m.padStart(2, '0')}:${s.padStart(2, '0')}`;\n}\n\n// Due to a npm bug, virtual-tsc may be hoisted to the top level node_modules but\n// typescript may still be in the adapter level (https://npm.community/t/packages-with-peerdependencies-are-incorrectly-hoisted/4794),\n// so we need to tell virtual-tsc where typescript is\nsetTypeScriptResolveOptions({\n paths: [require.resolve('typescript')],\n});\n\n// compiler instance for global JS declarations\nconst jsDeclarationServer: Server = new Server(jsDeclarationCompilerOptions, isCI ? false : undefined);\n/**\n * Stores the IDs of script objects whose change should be ignored because\n * the compiled source was just updated\n */\n\nclass JavaScript extends Adapter {\n public declare config: JavaScriptAdapterConfig;\n\n private readonly context: JavascriptContext;\n\n private errorLogFunction: {\n error: (msg: string) => void;\n warn: (msg: string) => void;\n info: (msg: string) => void;\n debug: (msg: string) => void;\n silly: (msg: string) => void;\n };\n\n private readonly mods: MODULES;\n\n private objectsInitDone = false;\n private statesInitDone = false;\n\n private objects: Record = {};\n private states: Record = {};\n private readonly interimStateValues: Record = {};\n private readonly stateIds: string[] = [];\n private readonly subscriptions: SubscriptionResult[] = [];\n private readonly subscriptionsFile: FileSubscriptionResult[] = [];\n private readonly subscriptionsObject: SubscribeObject[] = [];\n private readonly subscribedPatterns: Record = {};\n private readonly subscribedPatternsFile: Record = {};\n private readonly adapterSubs: Record = {};\n private readonly timers: { [scriptName: string]: JavascriptTimer[] } = {};\n private readonly _enums: string[] = [];\n private readonly names: { [name: string]: string | string[] } = {}; // name: id\n private readonly scripts: Record = {};\n private readonly messageBusHandlers: Record<\n string,\n Record void }[]>\n > = {};\n private readonly logSubscriptions: Record<\n string,\n {\n sandbox: SandboxType;\n cb: (info: LogMessage) => void;\n id: number;\n severity: ioBroker.LogLevel | '*';\n }[]\n > = {};\n private readonly tempDirectories: { [scriptName: string]: string } = {}; // name: path\n private readonly folderCreationVerifiedObjects: Record = {};\n\n /** if logs are subscribed or not */\n private logSubscribed = false;\n\n private timeSettings: {\n format12: boolean;\n leadingZeros: boolean;\n } = { format12: false, leadingZeros: true };\n\n private dayScheduleTimer: NodeJS.Timeout | null = null; // schedule for astrological day\n private sunScheduleTimer: NodeJS.Timeout | null = null; // schedule for sun moment times\n private timeScheduleTimer: NodeJS.Timeout | null = null; // schedule for astrological day\n\n private activeStr = ''; // enabled state prefix\n\n private mirror: Mirror | undefined;\n\n private stopCounters: Record = {};\n\n private setStateCountCheckInterval: NodeJS.Timeout | null = null;\n\n private globalScript = '';\n /** Generated declarations for global TypeScripts */\n private globalDeclarations = '';\n // Remember which definitions the global scripts\n // have access to, because it depends on the compilation order\n private knownGlobalDeclarationsByScript: Record = {};\n private globalScriptLines = 0;\n // compiler instance for typescript\n private tsServer: Server;\n\n private readonly ignoreObjectChange: Set = new Set();\n\n private debugState: DebugState = {\n scriptName: '',\n child: null,\n promiseOnEnd: null,\n paused: false,\n started: 0,\n running: false,\n };\n\n constructor(options: Partial = {}) {\n options = {\n ...options,\n name: 'javascript', // adapter name\n useFormatDate: true,\n /**\n * If the JS-Controller catches an unhandled error, this will be called\n * so we have a chance to handle it ourselves.\n */\n error: (err: Error): boolean => {\n // Identify unhandled errors originating from callbacks in scripts\n // These are not caught by wrapping the execution code in try-catch\n if (err && typeof err.stack === 'string') {\n const scriptCodeMarkerIndex = err.stack.indexOf(SCRIPT_CODE_MARKER);\n if (scriptCodeMarkerIndex > -1) {\n // This is a script error\n let scriptName = err.stack.substring(scriptCodeMarkerIndex);\n scriptName = scriptName.substring(0, scriptName.indexOf(':'));\n this.logError(scriptName, err);\n\n // Leave the script running for now\n // signal to the JS-Controller that we handled the error ourselves\n return true;\n }\n // check if a path contains adaptername but not own node_module\n // this regex matched \"iobroker.javascript/\" if NOT followed by \"node_modules\"\n if (!err.stack.match(/iobroker\\.javascript[/\\\\](?!.*node_modules).*/g)) {\n // This is an error without any info on origin (mostly async errors like connection errors)\n // also consider it as being from a script\n this.log.error(\n 'An error happened which is most likely from one of your scripts, but the originating script could not be detected.',\n );\n this.log.error(`Error: ${err.message}`);\n this.log.error(err.stack);\n\n // signal to the JS-Controller that we handled the error ourselves\n return true;\n }\n }\n\n return false;\n },\n };\n\n super(options as AdapterOptions);\n\n this.on('objectChange', this.onObjectChange.bind(this));\n this.on('stateChange', this.onStateChange.bind(this));\n this.on('ready', this.onReady.bind(this));\n this.on('message', this.onMessage.bind(this));\n this.on('unload', this.onUnload.bind(this));\n this.on('fileChange', this.onFileChange.bind(this));\n this.on('log', this.onLog.bind(this));\n\n this.mods = {\n fs: {} as ProtectFs,\n 'fs/promises': {} as ProtectFs['promises'],\n dgram,\n crypto,\n dns,\n events,\n http,\n https,\n http2,\n net,\n os,\n path,\n util,\n child_process,\n stream,\n zlib,\n\n suncalc,\n axios,\n wake_on_lan,\n nodeSchedule,\n };\n\n // check the webstorm debug and just debug modes\n let debugMode: string | undefined;\n if (process.argv) {\n for (let a = 1; a < process.argv.length; a++) {\n if (process.argv[a].startsWith('--webstorm')) {\n webstormDebug = process.argv[a].replace(/^(.*?=\\s*)/, '');\n }\n if (process.argv[a] === '--debugScript') {\n if (!process.argv[a + 1]) {\n console.log('No script name provided');\n process.exit(300);\n } else {\n debugMode = process.argv[a + 1];\n }\n }\n }\n }\n\n this.errorLogFunction = this.log;\n\n this.context = {\n mods: this.mods,\n objects: this.objects,\n states: this.states,\n interimStateValues: this.interimStateValues,\n stateIds: this.stateIds,\n errorLogFunction: this.errorLogFunction,\n subscriptions: this.subscriptions,\n subscriptionsFile: this.subscriptionsFile,\n subscriptionsObject: this.subscriptionsObject,\n subscribedPatterns: this.subscribedPatterns,\n subscribedPatternsFile: this.subscribedPatternsFile,\n adapterSubs: this.adapterSubs,\n cacheObjectEnums: {},\n timers: this.timers,\n enums: this._enums,\n names: this.names,\n scripts: this.scripts,\n messageBusHandlers: this.messageBusHandlers,\n logSubscriptions: this.logSubscriptions,\n tempDirectories: this.tempDirectories,\n folderCreationVerifiedObjects: this.folderCreationVerifiedObjects,\n\n isEnums: false, // If some subscription wants enum\n channels: null,\n devices: null,\n logWithLineInfo: this.logWithLineInfo.bind(this),\n scheduler: null,\n timerId: 0,\n rulesOpened: null, // opened rules\n language: this.language || 'en',\n\n updateLogSubscriptions: this.updateLogSubscriptions.bind(this),\n convertBackStringifiedValues: this.convertBackStringifiedValues.bind(this),\n updateObjectContext: this.updateObjectContext.bind(this),\n prepareStateObject: this.prepareStateObject.bind(this),\n debugMode,\n getAbsoluteDefaultDataDir,\n adapter: this as unknown as ioBroker.Adapter,\n logError: this.logError.bind(this),\n };\n\n this.tsServer = new Server(tsCompilerOptions, this.tsLog);\n }\n\n async onObjectChange(id: string, obj?: ioBroker.Object | null): Promise {\n // Check if we should ignore this change (once!) because we just updated the compiled sources\n if (this.ignoreObjectChange.has(id)) {\n // Update the cached script object and do nothing more\n this.objects[id] = obj as ioBroker.Object;\n this.ignoreObjectChange.delete(id);\n return;\n }\n\n // When still in initializing: already remember current values,\n // but data structures are initialized elsewhere\n if (!this.objectsInitDone) {\n if (obj) {\n this.objects[id] = obj;\n }\n return;\n }\n\n if (id.startsWith('enum.')) {\n // clear cache\n this.context.cacheObjectEnums = {};\n\n // update this._enums array\n if (obj) {\n // If new\n if (!this._enums.includes(id)) {\n this._enums.push(id);\n this._enums.sort();\n }\n } else {\n const pos = this._enums.indexOf(id);\n // if deleted\n if (pos !== -1) {\n this._enums.splice(pos, 1);\n }\n }\n }\n\n if (id === 'system.config' && obj?.common?.language) {\n // set language for debug messages\n setLanguage(obj.common.language);\n this.language = obj.common.language;\n this.context.language = this.language as ioBroker.Languages;\n }\n\n // update stored time format for variables.dayTime\n if (id === `${this.namespace}.variables.dayTime` && obj?.native) {\n this.timeSettings.format12 = obj.native.format12 || false;\n this.timeSettings.leadingZeros = obj.native.leadingZeros === undefined ? true : obj.native.leadingZeros;\n }\n\n // send changes to disk mirror\n this.mirror?.onObjectChange(id, obj as ioBroker.ScriptObject | null);\n\n const formerObj = this.objects[id];\n\n this.updateObjectContext(id, obj); // Update all Meta object data\n\n // for the alias object changes on the state objects, we need to manually update the\n // state cache value, because the new value is only published on the next change\n if (obj?.type === 'state' && id.startsWith('alias.0.')) {\n // execute async for speed\n this.getForeignStateAsync(id)\n .then(state => {\n if (state) {\n this.states[id] = state;\n } else if (this.states[id] !== undefined) {\n delete this.states[id];\n }\n })\n .catch(() => {\n /* ignore */\n });\n }\n\n this.subscriptionsObject.forEach(sub => {\n // ToDo: implement comparing with id.0.* too\n if (sub.pattern === id) {\n try {\n sub.callback(id, obj);\n } catch (err: any) {\n this.log.error(`Error in callback: ${err.toString()}`);\n }\n }\n });\n\n // handle Script object updates\n if (!obj && formerObj?.type === 'script') {\n // Object Deleted just now\n if (checkIsGlobal(formerObj)) {\n // it was a global Script, and it was enabled and is now deleted => restart adapter\n if (formerObj.common.enabled) {\n this.log.info(`Active global Script ${id} deleted. Restart instance.`);\n this.restart();\n }\n } else if (formerObj.common?.engine === `system.adapter.${this.namespace}`) {\n // It was a non-global Script and deleted => stop and remove it\n await this.stopScript(id);\n\n // delete scriptEnabled.blabla variable\n const idActive = `scriptEnabled.${id.substring(SCRIPT_CODE_MARKER.length)}`;\n await this.delStateAsync(idActive);\n await this.delObjectAsync(idActive);\n\n // delete scriptProblem.blabla variable\n const idProblem = `scriptProblem.${id.substring(SCRIPT_CODE_MARKER.length)}`;\n await this.delStateAsync(idProblem);\n await this.delObjectAsync(idProblem);\n }\n } else if (!formerObj && obj?.type === 'script') {\n // New script that does not exist before\n if (checkIsGlobal(obj)) {\n // new global script added => restart adapter\n if (obj.common.enabled) {\n this.log.info(`Active global Script ${id} created. Restart instance.`);\n this.restart();\n }\n } else if (obj.common?.engine === `system.adapter.${this.namespace}`) {\n // new non-global script - create states for scripts\n await this.createActiveObject(id, obj.common.enabled);\n await this.createProblemObject(id);\n if (obj.common.enabled) {\n // if enabled => Start script\n await this.loadScriptById(id);\n }\n }\n } else if (obj?.type === 'script' && formerObj?.common) {\n // Script changed ...\n if (checkIsGlobal(obj)) {\n if (obj.common.enabled || formerObj.common.enabled) {\n this.log.info(`Global Script ${id} updated. Restart instance.`);\n this.restart();\n }\n } else {\n // No global script\n if (obj.common?.engine === `system.adapter.${this.namespace}`) {\n // create states for scripts\n await this.createActiveObject(id, obj.common.enabled);\n await this.createProblemObject(id);\n }\n\n if (\n (formerObj.common.enabled && !obj.common.enabled) ||\n (formerObj.common.engine === `system.adapter.${this.namespace}` &&\n obj.common.engine !== `system.adapter.${this.namespace}`)\n ) {\n // Script disabled\n if (formerObj.common.enabled && formerObj.common.engine === `system.adapter.${this.namespace}`) {\n // Remove it from executing\n await this.stopScript(id);\n }\n } else if (\n (!formerObj.common.enabled && obj.common.enabled) ||\n (formerObj.common.engine !== `system.adapter.${this.namespace}` &&\n obj.common.engine === `system.adapter.${this.namespace}`)\n ) {\n // Script enabled\n\n if (obj.common.enabled && obj.common.engine === `system.adapter.${this.namespace}`) {\n // Start script\n await this.loadScriptById(id);\n }\n } else {\n // if (obj.common.source !== formerObj.common.source) {\n // Source changed => restart the script\n this.stopCounters[id] = this.stopCounters[id] ? this.stopCounters[id] + 1 : 1;\n this.stopScript(id).then(() => {\n // only start again after stop when \"last\" object change to prevent problems on\n // multiple changes in fast frequency\n if (!--this.stopCounters[id]) {\n this.loadScriptById(id);\n }\n });\n }\n }\n }\n }\n\n onStateChange(id: string, state?: ioBroker.State | null): void {\n if (this.interimStateValues[id] !== undefined) {\n // any update invalidates the remembered interim value\n delete this.interimStateValues[id];\n }\n if (!id || id.startsWith('messagebox.') || id.startsWith('log.')) {\n return;\n }\n\n if (id === `${this.namespace}.debug.to` && state && !state.ack) {\n if (!this.context.debugMode) {\n this.debugSendToInspector(state.val);\n }\n return;\n }\n\n // When still in initializing: already remember current values,\n // but data structures are initialized elsewhere\n if (!this.statesInitDone) {\n if (state) {\n this.states[id] = state;\n }\n return;\n }\n\n const oldState: ioBroker.State | null | undefined = this.states[id];\n if (state) {\n if (oldState) {\n // enable or disable script\n if (!state.ack && id.startsWith(this.activeStr) && this.objects[id]?.native?.script) {\n this.extendForeignObject(this.objects[id].native.script, {\n common: { enabled: state.val },\n });\n }\n\n // monitor if adapter is alive and send all subscriptions once more, after adapter goes online\n if (/*oldState && */ oldState.val === false && state.val && id.endsWith('.alive')) {\n if (this.adapterSubs[id]) {\n const parts = id.split('.');\n const a = `${parts[2]}.${parts[3]}`;\n for (let t = 0; t < this.adapterSubs[id].length; t++) {\n this.log.info(`Detected coming adapter \"${a}\". Send subscribe: ${this.adapterSubs[id][t]}`);\n this.sendTo(a, 'subscribe', this.adapterSubs[id][t]);\n }\n }\n }\n } else if (/*!oldState && */ !this.stateIds.includes(id)) {\n this.stateIds.push(id);\n this.stateIds.sort();\n }\n this.states[id] = state;\n } else {\n if (oldState) {\n delete this.states[id];\n }\n state = {} as ioBroker.State;\n const pos = this.stateIds.indexOf(id);\n if (pos !== -1) {\n this.stateIds.splice(pos, 1);\n }\n }\n const _eventObj = createEventObject(\n this.context,\n id,\n this.convertBackStringifiedValues(id, state),\n this.convertBackStringifiedValues(id, oldState),\n );\n\n // if this state matches any subscriptions\n for (let i = 0, l = this.subscriptions.length; i < l; i++) {\n const sub = this.subscriptions[i];\n if (sub?.patternCompareFunctions && patternMatching(_eventObj, sub.patternCompareFunctions)) {\n try {\n sub.callback(_eventObj);\n } catch (err: any) {\n this.log.error(`Error in callback: ${err.toString()}`);\n }\n }\n }\n }\n\n onFileChange(id: string, fileName: string, size: number | null): void {\n // if this file matches any subscriptions\n for (let i = 0, l = this.subscriptionsFile.length; i < l; i++) {\n const sub = this.subscriptionsFile[i];\n if (sub && fileMatching(sub, id, fileName)) {\n try {\n sub.callback(id, fileName, size, sub.withFile);\n } catch (err: any) {\n this.log.error(`Error in callback: ${err.toString()}`);\n }\n }\n }\n }\n\n async onUnload(callback: () => void): Promise {\n await this.debugStop();\n this.stopTimeSchedules();\n if (this.setStateCountCheckInterval) {\n clearInterval(this.setStateCountCheckInterval);\n this.setStateCountCheckInterval = null;\n }\n await this.stopAllScripts();\n if (typeof callback === 'function') {\n callback();\n }\n }\n\n async onReady(): Promise {\n this.config.maxSetStatePerMinute = parseInt(this.config.maxSetStatePerMinute as unknown as string, 10) || 1000;\n this.config.maxTriggersPerScript = parseInt(this.config.maxTriggersPerScript as unknown as string, 10) || 100;\n\n if (this.supportsFeature && this.supportsFeature('PLUGINS')) {\n const sentryInstance: InstanceType = this.getPluginInstance('sentry') as InstanceType<\n typeof SentryPlugin\n >;\n if (sentryInstance) {\n const Sentry = sentryInstance.getSentryObject();\n if (Sentry) {\n const scope = Sentry.getCurrentScope();\n scope.addEventProcessor((event, _hint) => {\n if (event.exception?.values?.[0]) {\n const eventData = event.exception.values[0];\n if (\n eventData.stacktrace?.frames &&\n Array.isArray(eventData.stacktrace.frames) &&\n eventData.stacktrace.frames.length\n ) {\n // Exclude event if script Marker is included\n if (\n eventData.stacktrace.frames.find(frame =>\n frame.filename?.includes(SCRIPT_CODE_MARKER),\n )\n ) {\n return null;\n }\n //Exclude event if own directory is included but not inside own node_modules\n const ownNodeModulesDir = join(__dirname, 'node_modules');\n if (\n !eventData.stacktrace.frames.find(\n frame =>\n frame.filename &&\n frame.filename.includes(__dirname) &&\n !frame.filename.includes(ownNodeModulesDir),\n )\n ) {\n return null;\n }\n // We have exception data and did not sort it out, so report it\n return event;\n }\n }\n\n // No exception in it ... do not report\n return null;\n });\n }\n }\n }\n\n await this.main();\n }\n\n onMessage(obj: ioBroker.Message): void {\n switch (obj?.command) {\n // process messageTo commands\n case 'toScript':\n case 'jsMessageBus':\n if (\n obj.message &&\n (obj.message.instance === null ||\n obj.message.instance === undefined ||\n `javascript.${obj.message.instance}` === this.namespace ||\n obj.message.instance === this.namespace)\n ) {\n Object.keys(this.messageBusHandlers).forEach(name => {\n // script name could be script.js.xxx or only xxx\n if (\n (!obj.message.script || obj.message.script === name) &&\n this.messageBusHandlers[name][obj.message.message]\n ) {\n this.messageBusHandlers[name][obj.message.message].forEach(handler => {\n const sandbox = handler.sandbox;\n\n sandbox.verbose && sandbox.log(`onMessage: ${JSON.stringify(obj.message)}`, 'info');\n\n try {\n if (obj.callback) {\n handler.cb.call(sandbox, obj.message.data, (result: any) => {\n if (sandbox.verbose) {\n sandbox.log(`onMessage result: ${JSON.stringify(result)}`, 'info');\n }\n\n this.sendTo(obj.from, obj.command, result, obj.callback);\n });\n } else {\n handler.cb.call(sandbox, obj.message.data, (result: any) => {\n sandbox.verbose &&\n sandbox.log(`onMessage result: ${JSON.stringify(result)}`, 'info');\n });\n }\n } catch (err: unknown) {\n this.setState(\n `scriptProblem.${name.substring(SCRIPT_CODE_MARKER.length)}`,\n true,\n true,\n );\n this.logError('Error in callback', err as Error);\n }\n });\n }\n });\n }\n break;\n\n case 'loadTypings': {\n // Load typings for the editor\n const typings: Record = {};\n\n // try to load TypeScript lib files from disk\n try {\n const typescriptLibs = resolveTypescriptLibs(targetTsLib);\n Object.assign(typings, typescriptLibs);\n } catch {\n /* ok, no lib then */\n }\n\n // provide the already-loaded ioBroker typings and global script declarations\n Object.assign(typings, tsAmbient);\n\n // also provide the known global declarations for each global script\n for (const globalScriptPaths of Object.keys(this.knownGlobalDeclarationsByScript)) {\n typings[`${globalScriptPaths}.d.ts`] = this.knownGlobalDeclarationsByScript[globalScriptPaths];\n }\n\n if (obj.callback) {\n this.sendTo(obj.from, obj.command, { typings }, obj.callback);\n }\n break;\n }\n\n case 'calcAstroAll': {\n if (obj.message) {\n const sunriseOffset =\n parseInt(\n obj.message.sunriseOffset === undefined\n ? this.config.sunriseOffset\n : obj.message.sunriseOffset,\n 10,\n ) || 0;\n const sunsetOffset =\n parseInt(\n obj.message.sunsetOffset === undefined\n ? this.config.sunsetOffset\n : obj.message.sunsetOffset,\n 10,\n ) || 0;\n const longitude =\n parseFloat(\n obj.message.longitude === undefined ? this.config.longitude : obj.message.longitude,\n ) || 0;\n const latitude =\n parseFloat(obj.message.latitude === undefined ? this.config.latitude : obj.message.latitude) ||\n 0;\n const today = getAstroStartOfDay();\n let astroEvents: GetTimesResult & { nextSunrise: Date; nextSunset: Date } = {} as GetTimesResult & {\n nextSunrise: Date;\n nextSunset: Date;\n };\n try {\n astroEvents = this.mods.suncalc.getTimes(today, latitude, longitude);\n } catch (err: unknown) {\n this.log.error(`Cannot calculate astro data: ${err as Error}`);\n }\n if (astroEvents) {\n try {\n astroEvents.nextSunrise = this.getAstroEvent(\n today,\n obj.message.sunriseEvent || this.config.sunriseEvent,\n obj.message.sunriseLimitStart || this.config.sunriseLimitStart,\n obj.message.sunriseLimitEnd || this.config.sunriseLimitEnd,\n sunriseOffset,\n false,\n latitude,\n longitude,\n true,\n );\n astroEvents.nextSunset = this.getAstroEvent(\n today,\n obj.message.sunsetEvent || this.config.sunsetEvent,\n obj.message.sunsetLimitStart || this.config.sunsetLimitStart,\n obj.message.sunsetLimitEnd || this.config.sunsetLimitEnd,\n sunsetOffset,\n true,\n latitude,\n longitude,\n true,\n );\n } catch (err: unknown) {\n this.log.error(`Cannot calculate astro data: ${err as Error}`);\n }\n }\n\n const result: Record = {};\n const keys = Object.keys(astroEvents).sort(\n (a, b) =>\n (astroEvents as unknown as Record)[a] -\n (astroEvents as unknown as Record)[b],\n );\n keys.forEach(key => {\n const validDate =\n (astroEvents as unknown as Record)[key] !== null &&\n !isNaN((astroEvents as unknown as Record)[key].getTime());\n\n result[key] = {\n isValidDate: validDate,\n serverTime: validDate\n ? formatHoursMinutesSeconds((astroEvents as unknown as Record)[key])\n : 'n/a',\n date: validDate\n ? (astroEvents as unknown as Record)[key].toISOString()\n : 'n/a',\n };\n });\n\n if (obj.callback) {\n this.sendTo(obj.from, obj.command, result, obj.callback);\n }\n }\n break;\n }\n\n case 'calcAstro': {\n if (obj.message) {\n const longitude =\n parseFloat(\n obj.message.longitude === undefined ? this.config.longitude : obj.message.longitude,\n ) || 0;\n const latitude =\n parseFloat(obj.message.latitude === undefined ? this.config.latitude : obj.message.latitude) ||\n 0;\n const today = getAstroStartOfDay();\n\n const sunriseEvent = obj.message?.sunriseEvent || this.config.sunriseEvent;\n const sunriseLimitStart = obj.message?.sunriseLimitStart || this.config.sunriseLimitStart;\n const sunriseLimitEnd = obj.message?.sunriseLimitEnd || this.config.sunriseLimitEnd;\n const sunriseOffset =\n parseInt(\n obj.message.sunriseOffset === undefined\n ? this.config.sunriseOffset\n : obj.message.sunriseOffset,\n 10,\n ) || 0;\n const nextSunrise = this.getAstroEvent(\n today,\n sunriseEvent,\n sunriseLimitStart,\n sunriseLimitEnd,\n sunriseOffset,\n false,\n latitude,\n longitude,\n true,\n );\n\n const sunsetEvent = obj.message?.sunsetEvent || this.config.sunsetEvent;\n const sunsetLimitStart = obj.message?.sunsetLimitStart || this.config.sunsetLimitStart;\n const sunsetLimitEnd = obj.message?.sunsetLimitEnd || this.config.sunsetLimitEnd;\n const sunsetOffset =\n parseInt(\n obj.message.sunsetOffset === undefined\n ? this.config.sunsetOffset\n : obj.message.sunsetOffset,\n 10,\n ) || 0;\n const nextSunset = this.getAstroEvent(\n today,\n sunsetEvent,\n sunsetLimitStart,\n sunsetLimitEnd,\n sunsetOffset,\n true,\n latitude,\n longitude,\n true,\n );\n\n const validDateSunrise = nextSunrise !== null && !isNaN(nextSunrise.getTime());\n const validDateSunset = nextSunset !== null && !isNaN(nextSunset.getTime());\n\n this.log.debug(\n `calcAstro sunrise: ${sunriseEvent} -> start ${sunriseLimitStart}, end: ${sunriseLimitEnd}, offset: ${sunriseOffset} - ${validDateSunrise ? nextSunrise.toISOString() : 'n/a'}`,\n );\n this.log.debug(\n `calcAstro sunset: ${sunsetEvent} -> start ${sunsetLimitStart}, end: ${sunsetLimitEnd}, offset: ${sunsetOffset} - ${validDateSunset ? nextSunset.toISOString() : 'n/a'}`,\n );\n\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n nextSunrise: {\n isValidDate: validDateSunrise,\n serverTime: validDateSunrise ? formatHoursMinutesSeconds(nextSunrise) : 'n/a',\n date: nextSunrise.toISOString(),\n },\n nextSunset: {\n isValidDate: validDateSunset,\n serverTime: validDateSunset ? formatHoursMinutesSeconds(nextSunset) : 'n/a',\n date: nextSunset.toISOString(),\n },\n },\n obj.callback,\n );\n }\n }\n break;\n }\n\n case 'debug': {\n if (!this.context.debugMode) {\n this.debugStart(obj.message);\n }\n break;\n }\n\n case 'debugStop': {\n if (!this.context.debugMode) {\n this.debugStop().then(() => console.log('stopped'));\n }\n break;\n }\n\n case 'rulesOn': {\n this.context.rulesOpened = obj.message;\n console.log(`Enable messaging for ${this.context.rulesOpened}`);\n break;\n }\n\n case 'rulesOff': {\n // maybe if (context.rulesOpened === obj.message)\n console.log(`Disable messaging for ${this.context.rulesOpened}`);\n this.context.rulesOpened = null;\n break;\n }\n\n case 'getIoBrokerDataDir': {\n if (obj.callback) {\n this.sendTo(\n obj.from,\n obj.command,\n {\n dataDir: getAbsoluteDefaultDataDir(),\n sep,\n },\n obj.callback,\n );\n }\n break;\n }\n }\n }\n\n onLog(msg: any): void {\n Object.keys(this.logSubscriptions).forEach((name: string): void =>\n this.logSubscriptions[name].forEach(handler => {\n if (\n typeof handler.cb === 'function' &&\n (handler.severity === '*' || handler.severity === msg.severity)\n ) {\n handler.sandbox.logHandler = handler.severity || '*';\n handler.cb.call(handler.sandbox, msg);\n handler.sandbox.logHandler = undefined;\n }\n }),\n );\n }\n\n logError(msg: string, e: Error, offs?: number): void {\n const stack = e.stack ? e.stack.toString().split('\\n') : e ? e.toString() : '';\n if (!msg.includes('\\n')) {\n msg = msg.replace(/[: ]*$/, ': ');\n }\n\n this.errorLogFunction.error(msg + this.fixLineNo(stack[0]));\n for (let i = offs || 1; i < stack.length; i++) {\n if (!stack[i]) {\n continue;\n }\n if (stack[i].match(/runInNewContext|javascript\\.js:/)) {\n break;\n }\n this.errorLogFunction.error(this.fixLineNo(stack[i]));\n }\n }\n\n logWithLineInfo(msg: string): void {\n this.errorLogFunction.warn(msg);\n\n // get current error stack\n const stack = new Error().stack?.split('\\n');\n\n if (stack) {\n for (let i = 3; i < stack.length; i++) {\n if (!stack[i]) {\n continue;\n }\n if (stack[i].match(/runInContext|runInNewContext|javascript\\.js:/)) {\n break;\n }\n this.errorLogFunction.warn(this.fixLineNo(stack[i]));\n }\n }\n }\n\n async main(): Promise {\n // Patch the font as it sometimes is wrong\n if (!this.context.debugMode) {\n if (await this.patchFont()) {\n this.log.debug('Font patched');\n }\n }\n\n this.log.debug(`config.subscribe (Do not subscribe all states on start): ${this.config.subscribe}`);\n\n // correct jsonConfig for admin\n const instObj: ioBroker.InstanceObject | null | undefined = await this.getForeignObjectAsync(\n `system.adapter.${this.namespace}`,\n );\n if (instObj?.common) {\n if (instObj.common.adminUI?.config !== 'json') {\n if (instObj.common.adminUI) {\n instObj.common.adminUI.config = 'json';\n } else {\n instObj.common.adminUI = { config: 'json' };\n }\n this.setForeignObject(instObj._id, instObj);\n }\n }\n\n if (webstormDebug) {\n this.errorLogFunction = {\n error: console.error,\n warn: console.warn,\n info: console.info,\n debug: console.log,\n silly: console.log,\n };\n this.context.errorLogFunction = this.errorLogFunction;\n }\n this.activeStr = `${this.namespace}.scriptEnabled.`;\n\n this.mods.fs = new ProtectFs(this.log, getAbsoluteDefaultDataDir());\n this.mods['fs/promises'] = this.mods.fs.promises; // to avoid require('fs/promises');\n\n // try to read TS declarations\n try {\n tsAmbient = {\n 'javascript.d.ts': readFileSync(this.mods.path.join(__dirname, 'lib/javascript.d.ts'), 'utf8'),\n };\n this.tsServer.provideAmbientDeclarations(tsAmbient);\n jsDeclarationServer.provideAmbientDeclarations(tsAmbient);\n } catch (err: unknown) {\n this.log.warn(`Could not read TypeScript ambient declarations: ${err as Error}`);\n // This should not happen, so send an error report to Sentry\n if (this.supportsFeature && this.supportsFeature('PLUGINS')) {\n const sentryInstance = this.getPluginInstance('sentry');\n if (sentryInstance) {\n const sentryObject = sentryInstance.getSentryObject();\n sentryObject?.captureException(err as Error);\n }\n }\n // Keep the adapter from crashing when the included typings cannot be read\n tsAmbient = {};\n }\n\n await this.installLibraries();\n // Load the TS declarations for Node.js and all 3rd party modules\n this.loadTypeScriptDeclarations();\n\n await this.getData();\n this.context.scheduler = new Scheduler(\n this.log,\n Date,\n this.mods.suncalc,\n this.config.latitude,\n this.config.longitude,\n );\n await this.dayTimeSchedules();\n await this.sunTimeSchedules();\n await this.timeSchedule();\n\n // Warning. It could have a side effect in compact mode, so all adapters will accept self-signed certificates\n if (this.config.allowSelfSignedCerts) {\n process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0';\n }\n\n const doc = await this.getObjectViewAsync('script', 'javascript', {});\n if (doc?.rows?.length) {\n // assemble global script\n for (let g = 0; g < doc.rows.length; g++) {\n const obj = doc.rows[g].value;\n if (checkIsGlobal(obj)) {\n if (obj && obj.common) {\n const engineType = (obj.common.engineType || '').toLowerCase();\n\n if (obj.common.enabled) {\n if (engineType.startsWith('typescript')) {\n // TypeScript\n this.log.info(`${obj._id}: compiling TypeScript source...`);\n // In order to compile global TypeScript, we need to do some transformations\n // 1. For top-level-await, some statements must be wrapped in an immediately-invoked async function\n // 2. If any global script uses `import`, the declarations are no longer visible if they are not exported with `declare global`\n const transformedSource = transformScriptBeforeCompilation(obj.common.source, true);\n // The source code must be transformed in order to support top level await\n // Global scripts must not be treated as a module, otherwise their methods\n // cannot be found by the normal scripts\n // We need to hash both global declarations that are known until now\n // AND the script source, because changing either can change the compilation output\n const sourceHash: string = hashSource(\n tsSourceHashBase + this.globalDeclarations + transformedSource,\n );\n\n let compiled: string | undefined;\n let declarations: string | undefined;\n // If we already stored the compiled source code and the original source hash,\n // use the hash to check whether we can rely on the compiled source code or\n // if we need to compile it again\n if (\n typeof obj.common.compiled === 'string' &&\n typeof obj.common.sourceHash === 'string' &&\n sourceHash === obj.common.sourceHash\n ) {\n // We can reuse the stored source\n compiled = obj.common.compiled;\n declarations = obj.common.declarations;\n this.log.info(\n `${obj._id}: source code did not change, using cached compilation result...`,\n );\n } else {\n // We don't have a hashed source code, or the original source changed, compile it\n const filename = scriptIdToTSFilename(obj._id);\n let tsCompiled: CompileResult;\n try {\n tsCompiled = this.tsServer.compile(filename, transformedSource);\n } catch (err: unknown) {\n this.log.error(`${obj._id}: TypeScript compilation failed:\\n${err as Error}`);\n continue;\n }\n\n const errors = tsCompiled.diagnostics\n .map(diag => `${diag.annotatedSource}\\n`)\n .join('\\n');\n\n if (tsCompiled.success) {\n if (errors.length > 0) {\n this.log.warn(\n `${obj._id}: TypeScript compilation completed with errors:\\n${errors}`,\n );\n } else {\n this.log.info(`${obj._id}: TypeScript compilation successful`);\n }\n compiled = tsCompiled.result;\n // Global scripts that have been transformed to support `import` need to have their declarations transformed aswell\n declarations = transformGlobalDeclarations(tsCompiled.declarations || '');\n\n const newCommon: {\n compiled: string | undefined;\n declarations?: string;\n sourceHash: string;\n } = {\n sourceHash,\n compiled,\n };\n if (declarations) {\n newCommon.declarations = declarations;\n }\n\n // Store the compiled source and the original source hash, so we don't need to do the work again next time\n this.ignoreObjectChange.add(obj._id); // ignore the next change and don't restart scripts\n this.extendForeignObject(obj._id, {\n common: newCommon,\n });\n } else {\n this.log.error(`${obj._id}: TypeScript compilation failed:\\n${errors}`);\n continue;\n }\n }\n this.globalScript += `${compiled}\\n`;\n // if declarations were generated, remember them\n if (declarations != null) {\n this.provideDeclarationsForGlobalScript(obj._id, declarations);\n }\n } else {\n // javascript\n const sourceCode = obj.common.source;\n this.globalScript += `${sourceCode}\\n`;\n\n // try to compile the declarations so TypeScripts can use\n // functions defined in global JavaScripts\n const filename = scriptIdToTSFilename(obj._id);\n let tsCompiled: CompileResult;\n try {\n tsCompiled = jsDeclarationServer.compile(filename, sourceCode);\n } catch (err: unknown) {\n this.log.warn(\n `${obj._id}: Error while generating type declarations, skipping:\\n${err as Error}`,\n );\n continue;\n }\n // if declarations were generated, remember them\n if (tsCompiled.success && tsCompiled.declarations != null) {\n this.provideDeclarationsForGlobalScript(obj._id, tsCompiled.declarations);\n }\n }\n }\n }\n }\n }\n }\n\n this.globalScript = this.globalScript.replace(/\\r\\n/g, '\\n');\n this.globalScriptLines = this.globalScript.split(/\\n/g).length - 1;\n\n if (doc?.rows?.length) {\n // load all scripts\n for (let i = 0; i < doc.rows.length; i++) {\n if (!checkIsGlobal(doc.rows[i].value)) {\n this.loadScript(doc.rows[i].value);\n }\n }\n }\n\n if (this.config.mirrorPath) {\n this.config.mirrorInstance = parseInt(this.config.mirrorInstance as unknown as string, 10) || 0;\n if (this.instance === this.config.mirrorInstance) {\n const ioBDataDir = getAbsoluteDefaultDataDir() + sep;\n this.config.mirrorPath = normalize(this.config.mirrorPath);\n let mirrorForbidden = false;\n for (let dir of forbiddenMirrorLocations) {\n dir = join(ioBDataDir, dir) + sep;\n if (dir.includes(this.config.mirrorPath) || this.config.mirrorPath.startsWith(dir)) {\n this.log.error(`The Mirror directory is not allowed to be a central ioBroker directory!`);\n this.log.error(`Directory ${this.config.mirrorPath} is not allowed to mirror files!`);\n mirrorForbidden = true;\n break;\n }\n }\n if (!mirrorForbidden) {\n this.mirror = new Mirror({\n adapter: this,\n log: this.log,\n diskRoot: this.config.mirrorPath,\n });\n }\n }\n }\n\n // CHeck setState counter per minute and stop script if too high\n this.setStateCountCheckInterval = setInterval(() => {\n Object.keys(this.scripts).forEach(id => {\n if (!this.scripts[id]) {\n return;\n }\n const currentSetStatePerMinuteCounter = this.scripts[id].setStatePerMinuteCounter;\n this.scripts[id].setStatePerMinuteCounter = 0;\n if (currentSetStatePerMinuteCounter > this.config.maxSetStatePerMinute) {\n this.scripts[id].setStatePerMinuteProblemCounter++;\n this.log.debug(\n `Script ${id} has reached the maximum of ${this.config.maxSetStatePerMinute} setState calls per minute in ${this.scripts[id].setStatePerMinuteProblemCounter} consecutive minutes`,\n );\n // Allow \"too high counters\" for 1 minute for script starts or such and only\n // stop the script when lasts longer\n if (this.scripts[id].setStatePerMinuteProblemCounter > 1) {\n this.log.error(\n `Script ${id} is calling setState more than ${this.config.maxSetStatePerMinute} times per minute! Stopping Script now! Please check your script!`,\n );\n this.stopScript(id);\n }\n } else if (this.scripts[id].setStatePerMinuteProblemCounter > 0) {\n this.scripts[id].setStatePerMinuteProblemCounter--;\n this.log.debug(\n `Script ${id} has NOT reached the maximum of ${this.config.maxSetStatePerMinute} setState calls per minute. Decrease problem counter to ${this.scripts[id].setStatePerMinuteProblemCounter}`,\n );\n }\n });\n }, 60000);\n }\n\n private loadTypeScriptDeclarations(): void {\n // try to load the typings on disk for all 3rd party modules\n const packages = [\n 'node', // this provides auto-completion for most builtins\n '@iobroker/types', // this provides auto-completion for most builtins\n ];\n // Also include user-selected libraries (but only those that are also installed)\n if (typeof this.config?.libraries === 'string' && typeof this.config.libraryTypings === 'string') {\n const installedLibs = this.config.libraries\n .split(/[,;\\s]+/)\n .map(s => s.trim().split('@')[0])\n .filter(s => !!s);\n\n const wantsTypings = this.config.libraryTypings\n .split(/[,;\\s]+/)\n .map(s => s.trim())\n .filter(s => !!s);\n // Add all installed libraries the user has requested typings for to the list of packages\n for (const lib of installedLibs) {\n if (wantsTypings.includes(lib) && !packages.includes(lib)) {\n packages.push(lib);\n }\n }\n // Some packages have submodules (e.g., rxjs/operators) that are not exposed through the main entry point\n // If typings are requested for them, also add them if the base module is installed\n for (const lib of wantsTypings) {\n // Extract the package name and check if we need to add it\n if (!lib.includes('/')) {\n continue;\n }\n const pkgName = lib.substr(0, lib.indexOf('/'));\n\n if (installedLibs.includes(pkgName) && !packages.includes(lib)) {\n packages.push(lib);\n }\n }\n }\n for (const pkg of packages) {\n let pkgTypings = resolveTypings(\n pkg,\n this.getAdapterScopedPackageIdentifier ? this.getAdapterScopedPackageIdentifier(pkg) : pkg,\n // node needs ambient typings, so we don't wrap it in declare module\n pkg !== 'node',\n );\n if (!pkgTypings) {\n // Create the empty dummy declarations so users don't get the \"not found\" error\n // for installed packages\n pkgTypings = {\n [`node_modules/@types/${pkg}/index.d.ts`]: `declare module \"${pkg}\";`,\n };\n }\n this.log.debug(`Loaded TypeScript definitions for ${pkg}: ${JSON.stringify(Object.keys(pkgTypings))}`);\n // remember the declarations for the editor\n Object.assign(tsAmbient, pkgTypings);\n // and give the language servers access to them\n this.tsServer.provideAmbientDeclarations(pkgTypings);\n jsDeclarationServer.provideAmbientDeclarations(pkgTypings);\n }\n }\n\n updateObjectContext(id: string, obj: ioBroker.Object | null | undefined): void {\n if (obj) {\n // add state to state ID's list\n if (obj.type === 'state') {\n if (!this.stateIds.includes(id)) {\n this.stateIds.push(id);\n this.stateIds.sort();\n }\n if (this.context.devices && this.context.channels) {\n const parts = id.split('.');\n parts.pop();\n const chn = parts.join('.');\n this.context.channels[chn] = this.context.channels[chn] || [];\n this.context.channels[chn].push(id);\n\n parts.pop();\n const dev = parts.join('.');\n this.context.devices[dev] = this.context.devices[dev] || [];\n this.context.devices[dev].push(id);\n }\n }\n } else {\n // delete object from state ID's list\n const pos = this.stateIds.indexOf(id);\n if (pos !== -1) {\n this.stateIds.splice(pos, 1);\n }\n if (this.context.devices && this.context.channels) {\n const parts = id.split('.');\n parts.pop();\n const chn = parts.join('.');\n if (this.context.channels[chn]) {\n const posChn = this.context.channels[chn].indexOf(id);\n posChn !== -1 && this.context.channels[chn].splice(posChn, 1);\n }\n\n parts.pop();\n const dev = parts.join('.');\n if (this.context.devices[dev]) {\n const posDev = this.context.devices[dev].indexOf(id);\n posDev !== -1 && this.context.devices[dev].splice(posDev, 1);\n }\n }\n\n delete this.folderCreationVerifiedObjects[id];\n }\n\n if (!obj && this.objects[id]) {\n // objects was deleted\n this.removeFromNames(id);\n delete this.objects[id];\n } else if (obj && !this.objects[id]) {\n // object was added\n this.objects[id] = obj;\n this.addToNames(obj);\n } else if (obj && this.objects[id].common) {\n // Object just changed\n this.objects[id] = obj;\n\n const n = this.getName(id);\n let nn = this.objects[id].common ? this.objects[id].common.name : '';\n\n if (nn && typeof nn === 'object') {\n nn = nn[getLanguage()] || nn.en;\n }\n\n if (n !== nn) {\n if (n) {\n this.removeFromNames(id);\n }\n if (nn) {\n this.addToNames(obj);\n }\n }\n }\n }\n\n async stopAllScripts(): Promise {\n const scripts = Object.keys(this.scripts);\n const promises: Promise[] = [];\n for (let i = 0; i < scripts.length; i++) {\n promises.push(this.stopScript(scripts[i]));\n }\n return Promise.all(promises).then(() => {});\n }\n\n convertBackStringifiedValues(\n id: string,\n state: ioBroker.State | null | undefined,\n ): ioBroker.State | null | undefined {\n if (\n state &&\n typeof state.val === 'string' &&\n this.objects[id]?.common &&\n (this.objects[id].common.type === 'array' || this.objects[id].common.type === 'object')\n ) {\n try {\n state.val = JSON.parse(state.val);\n } catch (err: any) {\n if (id.startsWith('javascript.') || id.startsWith('0_userdata.0')) {\n this.log.info(\n `Could not parse value for id ${id} into ${this.objects[id].common.type}: ${err.toString()}`,\n );\n } else {\n this.log.debug(\n `Could not parse value for id ${id} into ${this.objects[id].common.type}: ${err.toString()}`,\n );\n }\n }\n }\n return state;\n }\n\n prepareStateObjectSimple(id: string, state: ioBroker.StateValue, isAck: boolean): ioBroker.State {\n let oState: ioBroker.State;\n\n if (typeof isAck === 'boolean') {\n // otherwise, assume that the given state is the value to be set\n oState = { val: state, ack: !!isAck } as ioBroker.State;\n } else {\n oState = { val: state } as ioBroker.State;\n }\n\n return this.prepareStateObject(id, oState);\n }\n\n prepareStateObject(id: string, state: ioBroker.SettableState | null): ioBroker.State {\n let oState: ioBroker.State;\n\n if (state && typeof state === 'object') {\n oState = state as ioBroker.State;\n } else {\n oState = { val: null } as ioBroker.State;\n }\n\n if (this.config.subscribe) {\n return oState;\n }\n // set other values to have a full state object\n // mirrors logic from statesInRedis\n if (oState.ts === undefined) {\n oState.ts = Date.now();\n }\n\n if (oState.q === undefined) {\n oState.q = 0;\n }\n\n oState.from =\n typeof oState.from === 'string' && oState.from !== '' ? oState.from : `system.adapter.${this.namespace}`;\n\n if (oState.lc === undefined) {\n const formerStateValue = this.interimStateValues[id] || this.states[id];\n if (!formerStateValue) {\n oState.lc = oState.ts;\n } else {\n // isDeepStrictEqual works on objects and primitive values\n const hasChanged = !isDeepStrictEqual(formerStateValue.val, oState.val);\n if (!formerStateValue.lc || hasChanged) {\n oState.lc = oState.ts;\n } else {\n oState.lc = formerStateValue.lc;\n }\n }\n }\n\n return oState;\n }\n\n async getData(): Promise {\n await this.subscribeForeignObjectsAsync('*');\n\n if (!this.config.subscribe) {\n await this.subscribeForeignStatesAsync('*');\n } else {\n await this.subscribeStatesAsync('debug.to');\n await this.subscribeStatesAsync('scriptEnabled.*');\n }\n\n this.log.info('requesting all states');\n\n const statesPromise = this.getForeignStatesAsync('*')\n .then(res => {\n if (!res) {\n this.log.error(`Could not initialize states: no result`);\n this.terminate(EXIT_CODES.START_IMMEDIATELY_AFTER_STOP);\n return;\n }\n if (!this.config.subscribe) {\n this.states = Object.assign(res, this.states);\n this.context.states = this.states;\n\n this.addGetProperty(this.states);\n }\n\n // remember all IDs\n for (const id in res) {\n if (Object.prototype.hasOwnProperty.call(res, id)) {\n this.stateIds.push(id);\n }\n }\n this.statesInitDone = true;\n this.log.info('received all states');\n })\n .catch((err: any) => {\n this.log.error(`Could not initialize states: ${err?.message || 'no result'}`);\n this.terminate(EXIT_CODES.START_IMMEDIATELY_AFTER_STOP);\n });\n\n this.log.info('requesting all objects');\n\n const objectsPromise = this.getObjectListAsync({ include_docs: true })\n .then(res => {\n if (!res?.rows) {\n this.log.error(`Could not initialize objects: no result`);\n this.terminate(EXIT_CODES.START_IMMEDIATELY_AFTER_STOP);\n return;\n }\n this.objects = {};\n this.context.objects = this.objects;\n for (let i = 0; i < res.rows.length; i++) {\n if (!res.rows[i].doc) {\n this.log.debug(`Got empty object for index ${i} (${res.rows[i].id})`);\n continue;\n }\n if (this.objects[res.rows[i].doc._id] === undefined) {\n // If was already there ignore\n this.objects[res.rows[i].doc._id] = res.rows[i].doc;\n }\n this.objects[res.rows[i].doc._id].type === 'enum' && this._enums.push(res.rows[i].doc._id);\n\n // Collect all names\n this.addToNames(this.objects[res.rows[i].doc._id]);\n }\n this.addGetProperty(this.objects);\n\n const systemConfig = this.objects['system.config'];\n\n // set language for debug messages\n if (systemConfig?.common?.language) {\n setLanguage(systemConfig.common.language);\n this.language = systemConfig.common.language;\n this.context.language = this.language as ioBroker.Languages;\n } else if (this.language) {\n setLanguage(this.language);\n this.context.language = this.language;\n }\n\n // try to use system coordinates\n if (this.config.useSystemGPS) {\n if (systemConfig?.common?.latitude || systemConfig?.common?.longitude) {\n this.config.latitude = systemConfig.common.latitude;\n this.config.longitude = systemConfig.common.longitude;\n } else if (this.latitude && this.longitude) {\n this.config.latitude = this.latitude;\n this.config.longitude = this.longitude;\n }\n }\n this.config.latitude = parseFloat(this.config.latitude as unknown as string);\n this.config.longitude = parseFloat(this.config.longitude as unknown as string);\n\n if (isNaN(this.config.latitude)) {\n this.log.warn(`Configured latitude is not a number - check (instance/system) configuration`);\n } else if (this.config.latitude < -90 || this.config.latitude > 90) {\n this.log.warn(\n `Configured latitude \"${this.config.latitude}\" is invalid - check (instance/system) configuration`,\n );\n }\n\n if (isNaN(this.config.longitude)) {\n this.log.warn(`Configured longitude is not a number - check (instance/system) configuration`);\n } else if (this.config.longitude < -180 || this.config.longitude > 180) {\n this.log.warn(\n `Configured longitude \"${this.config.longitude}\" is invalid - check (instance/system) configuration`,\n );\n }\n\n this.config.sunriseEvent = this.config.sunriseEvent || 'nightEnd';\n this.config.sunriseOffset = this.config.sunriseOffset || 0;\n this.config.sunriseLimitStart = this.config.sunriseLimitStart || '06:00';\n this.config.sunriseLimitEnd = this.config.sunriseLimitEnd || '12:00';\n\n this.config.sunsetEvent = this.config.sunsetEvent || 'dusk';\n this.config.sunsetOffset = this.config.sunsetOffset || 0;\n this.config.sunsetLimitStart = this.config.sunsetLimitStart || '18:00';\n this.config.sunsetLimitEnd = this.config.sunsetLimitEnd || '23:00';\n\n this.objectsInitDone = true;\n this.log.info('received all objects');\n })\n .catch((err: any) => {\n this.log.error(`Could not initialize objects: ${err?.message || 'no result'}`);\n this.terminate(EXIT_CODES.START_IMMEDIATELY_AFTER_STOP);\n });\n\n return Promise.all([statesPromise, objectsPromise]).then(() => {});\n }\n\n async createActiveObject(id: string, enabled: boolean): Promise {\n const idActive = `${this.namespace}.scriptEnabled.${id.substring(SCRIPT_CODE_MARKER.length)}`;\n\n if (!this.objects[idActive]) {\n this.objects[idActive] = {\n _id: idActive,\n common: {\n name: `scriptEnabled.${id.substring(SCRIPT_CODE_MARKER.length)}`,\n desc: 'controls script activity',\n type: 'boolean',\n write: true,\n read: true,\n role: 'switch.active',\n },\n native: {\n script: id,\n },\n type: 'state',\n };\n try {\n this.setForeignObjectAsync(idActive, this.objects[idActive]);\n const intermediateStateValue = this.prepareStateObjectSimple(idActive, !!enabled, true);\n await this.setForeignStateAsync(idActive, !!enabled, true);\n if (enabled && !this.config.subscribe) {\n this.interimStateValues[idActive] = intermediateStateValue;\n }\n } catch {\n // ignore\n }\n } else {\n const state = await this.getForeignStateAsync(idActive);\n if (state && state.val !== enabled) {\n const intermediateStateValue = this.prepareStateObjectSimple(idActive, !!enabled, true);\n await this.setForeignStateAsync(idActive, !!enabled, true);\n if (enabled && !this.config.subscribe) {\n this.interimStateValues[id] = intermediateStateValue;\n }\n }\n }\n }\n\n async createProblemObject(id: string): Promise {\n const idProblem = `${this.namespace}.scriptProblem.${id.substring(SCRIPT_CODE_MARKER.length)}`;\n\n if (!this.objects[idProblem]) {\n this.objects[idProblem] = {\n _id: idProblem,\n common: {\n name: `scriptProblem.${id.substring(SCRIPT_CODE_MARKER.length)}`,\n desc: 'Script has a problem',\n type: 'boolean',\n expert: true,\n write: false,\n read: true,\n role: 'indicator.error',\n },\n native: {\n script: id,\n },\n type: 'state',\n };\n try {\n await this.setForeignObjectAsync(idProblem, this.objects[idProblem]);\n await this.setForeignStateAsync(idProblem, false, true);\n } catch {\n // ignore\n }\n } else {\n const state = await this.getForeignStateAsync(idProblem);\n if (state && state.val !== false) {\n await this.setForeignStateAsync(idProblem, false, true);\n }\n }\n }\n\n addToNames(obj: ioBroker.Object): void {\n const id = obj._id;\n\n if (obj.common?.name) {\n let name = obj.common.name;\n if (name && typeof name === 'object') {\n name = name[getLanguage()] || name.en;\n }\n if (!name || typeof name !== 'string') {\n // TODO, take name in current language\n return;\n }\n\n if (!this.names[name]) {\n this.names[name] = id;\n } else {\n // convert to array\n if (!Array.isArray(this.names[name])) {\n this.names[name] = [this.names[name] as string];\n }\n\n (this.names[name] as string[]).push(id);\n }\n }\n }\n\n removeFromNames(id: string): void {\n const n = this.getName(id);\n\n if (n) {\n if (Array.isArray(this.names[n])) {\n const pos = this.names[n].indexOf(id);\n if (pos > -1) {\n this.names[n].splice(pos, 1);\n\n if (this.names[n].length === 1) {\n this.names[n] = this.names[n][0];\n }\n }\n } else {\n delete this.names[n];\n }\n }\n }\n\n getName(id: string): string | null {\n for (const n in this.names) {\n if (this.names[n] && Array.isArray(this.names[n])) {\n if (this.names[n].includes(id)) {\n return n;\n }\n } else if (this.names[n] === id) {\n return n;\n }\n }\n\n return null;\n }\n\n async installNpm(npmLib: string): Promise {\n return new Promise((resolve, reject) => {\n const path = __dirname;\n\n // Also, set the working directory (cwd) of the process instead of using --prefix\n // because that has ugly bugs on Windows\n const cmd = `npm install ${npmLib} --omit=dev`;\n this.log.info(`Installing ${npmLib} into ${__dirname} - cmd: ${cmd}`);\n\n // System call used for update of js-controller itself,\n // because during the installation the npm packet will be deleted too, but some files must be loaded even during the installation process.\n const child = this.mods.child_process.exec(cmd, {\n windowsHide: true,\n cwd: path,\n });\n\n child.stdout?.on('data', buf => this.log.info(buf.toString('utf8')));\n\n child.stderr?.on('data', buf => this.log.error(buf.toString('utf8')));\n\n child.on('err', err => {\n this.log.error(`Cannot install ${npmLib}: ${err}`);\n reject(new Error(`Cannot install ${npmLib}: ${err}`));\n });\n child.on('error', err => {\n this.log.error(`Cannot install ${npmLib}: ${err}`);\n reject(new Error(`Cannot install ${npmLib}: ${err}`));\n });\n\n child.on('exit', (code: number /* , signal */) => {\n if (code) {\n this.log.error(`Cannot install ${npmLib}: ${code}`);\n reject(new Error(`Cannot install ${npmLib}: ${code}`));\n }\n // command succeeded\n resolve(code);\n });\n });\n }\n\n async installLibraries(): Promise {\n if (typeof this.config?.libraries !== 'string') {\n this.config.libraries = '';\n }\n\n const libraries: string[] = this.config.libraries\n .split(/[,;\\s]+/)\n .map(d => d.trim())\n .filter(d => d);\n\n this.log.debug(`Custom libraries in config: \"${this.config.libraries}\": ${JSON.stringify(libraries)}`);\n\n let installedNodeModules: string[] = [];\n const keepModules: string[] = [];\n\n // js-controller >= 6.x\n if (typeof this.listInstalledNodeModules === 'function') {\n installedNodeModules = await this.listInstalledNodeModules();\n\n this.log.debug(`Found installed libraries: ${JSON.stringify(installedNodeModules)}`);\n }\n\n for (const lib of libraries) {\n let depName = lib;\n let version = 'latest';\n\n if (depName.includes('@') && depName.lastIndexOf('@') > 0) {\n const parts = depName.split('@');\n version = parts.pop() ?? 'latest';\n depName = parts.join('@');\n }\n\n /** The real module name, because the dependency can be an url too */\n let moduleName = depName;\n\n if (URL.canParse(depName)) {\n moduleName = await requestModuleNameByUrl(depName);\n\n this.log.debug(`Found custom library in config: \"${moduleName}@${version}\" (from ${depName})`);\n } else {\n this.log.debug(`Found custom library in config: \"${moduleName}@${version}\"`);\n }\n\n keepModules.push(moduleName);\n\n // js-controller >= 6.x\n if (typeof this.installNodeModule === 'function') {\n try {\n const result = await this.installNodeModule(depName, { version });\n if (result.success) {\n this.log.debug(`Installed custom library: \"${moduleName}@${version}\"`);\n\n const importedModule: any = await this.importNodeModule(moduleName);\n (this.mods as Record)[moduleName] = importedModule.default ?? importedModule;\n } else {\n this.log.warn(`Cannot install custom npm package \"${moduleName}@${version}\"`);\n }\n } catch (err: unknown) {\n this.log.warn(`Cannot install custom npm package \"${moduleName}@${version}\": ${err as Error}`);\n }\n } else if (!existsSync(`${__dirname}/node_modules/${depName}/package.json`)) {\n // js-controller < 6.x\n this.log.info(`Installing custom library (legacy mode): \"${lib}\"`);\n\n try {\n await this.installNpm(lib);\n this.log.info(`Installed custom npm package (legacy mode): \"${lib}\"`);\n } catch (err: any) {\n this.log.warn(`Cannot install custom npm package \"${lib}\" (legacy mode): ${err.toString()}`);\n }\n }\n }\n\n // js-controller >= 6.x\n if (typeof this.uninstallNodeModule === 'function') {\n for (const installedNodeModule of installedNodeModules) {\n if (!keepModules.includes(installedNodeModule)) {\n try {\n await this.uninstallNodeModule(installedNodeModule);\n\n this.log.info(`Removed custom npm package: \"${installedNodeModule}\"`);\n } catch (err: any) {\n this.log.warn(`Cannot remove custom npm package ${installedNodeModule}: ${err.toString()}`);\n }\n }\n }\n }\n }\n\n createVM(source: string, name: string, wrapAsync: boolean): false | JsScript {\n if (this.context.debugMode && name !== this.context.debugMode) {\n return false;\n }\n\n if (!this.context.debugMode) {\n const logSubscriptionsText =\n \"\\n;\\nlog(`registered ${__engine.__subscriptions} subscription${__engine.__subscriptions === 1 ? '' : 's'},\" +\n \" ${__engine.__schedules} schedule${__engine.__schedules === 1 ? '' : 's'},\" +\n \" ${__engine.__subscriptionsMessage} message${__engine.__subscriptionsMessage === 1 ? '' : 's'},\" +\n \" ${__engine.__subscriptionsLog} log${__engine.__subscriptionsLog === 1 ? '' : 's'}\" +\n \" and ${__engine.__subscriptionsFile} file subscription${__engine.__subscriptionsFile === 1 ? '' : 's'}`);\\n\";\n\n if (wrapAsync) {\n source = `(async () => {\\n${source}\\n${logSubscriptionsText}\\n})();`;\n } else {\n source = `${source}\\n${logSubscriptionsText}`;\n }\n } else {\n if (wrapAsync) {\n source = `(async () => {debugger;\\n${source}\\n})();`;\n } else {\n source = `debugger;${source}`;\n }\n }\n\n try {\n const options: ScriptOptions = {\n filename: name,\n // displayErrors: true,\n // lineOffset: this.globalScriptLines\n };\n return {\n script: new Script(source, options),\n } as JsScript;\n } catch (err: unknown) {\n this.logError(`${name} compile failed:\\r\\nat `, err as Error);\n return false;\n }\n }\n\n execute(script: JsScript, name: string, engineType: ScriptType, verbose: boolean, debug: boolean): void {\n script.intervals = [];\n script.timeouts = [];\n script.schedules = [];\n script.wizards = [];\n script.name = name;\n script.engineType = engineType;\n script._id = Math.floor(Math.random() * 0xffffffff);\n script.subscribes = {};\n script.subscribesFile = {};\n script.setStatePerMinuteCounter = 0;\n script.setStatePerMinuteProblemCounter = 0;\n this.setState(`scriptProblem.${name.substring(SCRIPT_CODE_MARKER.length)}`, {\n val: false,\n ack: true,\n expire: 1000,\n });\n\n const sandbox = sandBox(script, name, verbose, debug, this.context);\n\n try {\n script.script.runInNewContext(sandbox, {\n filename: name,\n displayErrors: true,\n // lineOffset: this.globalScriptLines\n });\n } catch (err: unknown) {\n this.setState(`scriptProblem.${name.substring(SCRIPT_CODE_MARKER.length)}`, {\n val: true,\n ack: true,\n c: 'execute',\n });\n this.logError(name, err as Error);\n }\n }\n\n unsubscribe(id: string | RegExp | string[]): void {\n if (!id) {\n this.log.warn('unsubscribe: empty name');\n return;\n }\n\n if (Array.isArray(id)) {\n id.forEach(sub => unsubscribe(sub));\n return;\n }\n\n if (id.constructor && id.constructor.name === 'RegExp') {\n // adapter.log.warn('unsubscribe: todo - process regexp');\n return;\n }\n\n if (typeof id !== 'string') {\n this.log.error(`unsubscribe: invalid type of id - ${typeof id}`);\n return;\n }\n const parts = id.split('.');\n const _adapter = `system.adapter.${parts[0]}.${parts[1]}`;\n if (this.objects[_adapter]?.common?.subscribable) {\n const a = `${parts[0]}.${parts[1]}`;\n const alive = `system.adapter.${a}.alive`;\n if (this.adapterSubs[alive]) {\n const pos = this.adapterSubs[alive].indexOf(id);\n if (pos !== -1) {\n this.adapterSubs[alive].splice(pos, 1);\n }\n if (!this.adapterSubs[alive].length) {\n delete this.adapterSubs[alive];\n }\n }\n this.sendTo(a, 'unsubscribe', id);\n }\n }\n\n // Analyze if logs are still required or not\n updateLogSubscriptions(): void {\n let found = false;\n // go through all scripts and check if some script still requires logs\n Object.keys(this.logSubscriptions).forEach(scriptName => {\n if (!this.logSubscriptions?.[scriptName] || !this.logSubscriptions[scriptName].length) {\n delete this.logSubscriptions[scriptName];\n } else {\n found = true;\n }\n });\n\n if (this.requireLog) {\n if (found && !this.logSubscribed) {\n this.logSubscribed = true;\n this.requireLog(this.logSubscribed);\n this.log.info(`Subscribed to log messages (found logSubscriptions)`);\n } else if (!found && this.logSubscribed) {\n this.logSubscribed = false;\n this.requireLog(this.logSubscribed);\n this.log.info(`Unsubscribed from log messages (not found logSubscriptions)`);\n }\n }\n }\n\n async stopScript(name: string): Promise {\n this.log.info(`Stopping script ${name}`);\n\n await this.setState(`scriptEnabled.${name.substring(SCRIPT_CODE_MARKER.length)}`, false, true);\n\n if (this.messageBusHandlers[name]) {\n delete this.messageBusHandlers[name];\n }\n\n if (this.tempDirectories[name]) {\n try {\n this.mods.fs.rmSync(this.tempDirectories[name], { recursive: true });\n\n this.log.debug(`Removed temp directory of ${name}: ${this.tempDirectories[name]}`);\n } catch {\n this.log.warn(`Unable to remove temp directory of ${name}: ${this.tempDirectories[name]}`);\n }\n\n delete this.tempDirectories[name];\n }\n\n if (this.logSubscriptions[name]) {\n delete this.logSubscriptions[name];\n this.updateLogSubscriptions();\n }\n\n if (this.scripts[name]) {\n // Remove from subscriptions\n this.context.isEnums = false;\n if (this.config.subscribe) {\n // check all subscribed IDs\n Object.keys(this.scripts[name].subscribes).forEach(id => {\n if (this.subscribedPatterns[id]) {\n this.subscribedPatterns[id] -= this.scripts[name].subscribes[id];\n if (this.subscribedPatterns[id] <= 0) {\n this.unsubscribeForeignStates(id);\n delete this.subscribedPatterns[id];\n if (this.states[id]) {\n delete this.states[id];\n }\n }\n }\n });\n }\n\n for (let i = this.subscriptions.length - 1; i >= 0; i--) {\n if (this.subscriptions[i].name === name) {\n const sub = this.subscriptions.splice(i, 1)[0];\n if (sub?.pattern.id) {\n this.unsubscribe(sub.pattern.id);\n }\n } else {\n if (\n (!this.context.isEnums && this.subscriptions[i].pattern.enumName) ||\n this.subscriptions[i].pattern.enumId\n ) {\n this.context.isEnums = true;\n }\n }\n }\n\n // check all subscribed files\n Object.keys(this.scripts[name].subscribesFile).forEach(key => {\n if (this.subscribedPatternsFile[key]) {\n this.subscribedPatternsFile[key] -= this.scripts[name].subscribesFile[key];\n if (this.subscribedPatternsFile[key] <= 0) {\n const [id, file] = key.split('$%$');\n this.unsubscribeForeignFiles(id, file);\n delete this.subscribedPatternsFile[key];\n }\n }\n });\n for (let i = this.subscriptionsFile.length - 1; i >= 0; i--) {\n if (this.subscriptionsFile[i].name === name) {\n this.subscriptionsFile.splice(i, 1);\n }\n }\n\n for (let i = this.subscriptionsObject.length - 1; i >= 0; i--) {\n if (this.subscriptionsObject[i].name === name) {\n const sub = this.subscriptionsObject.splice(i, 1)[0];\n if (sub) {\n this.unsubscribeForeignObjects(sub.pattern);\n }\n }\n }\n\n // Stop all timeouts\n for (let i = 0; i < this.scripts[name].timeouts.length; i++) {\n clearTimeout(this.scripts[name].timeouts[i]);\n }\n // Stop all intervals\n for (let i = 0; i < this.scripts[name].intervals.length; i++) {\n clearInterval(this.scripts[name].intervals[i]);\n }\n // Stop all scheduled jobs\n for (let i = 0; i < this.scripts[name].schedules.length; i++) {\n if (this.scripts[name].schedules[i]) {\n const _name = this.scripts[name].schedules[i].name;\n if (!this.mods.nodeSchedule.cancelJob(this.scripts[name].schedules[i])) {\n this.log.error(`Error by canceling scheduled job \"${_name}\"`);\n }\n }\n }\n\n // Stop all time wizards jobs\n if (this.context.scheduler) {\n for (let i = 0; i < this.scripts[name].wizards.length; i++) {\n if (this.scripts[name].wizards[i]) {\n this.context.scheduler.remove(this.scripts[name].wizards[i]);\n }\n }\n }\n\n // if callback for on stop\n if (typeof this.scripts[name].onStopCb === 'function') {\n this.scripts[name].onStopTimeout =\n parseInt(this.scripts[name].onStopTimeout as unknown as string, 10) || 1000;\n\n await new Promise(resolve => {\n let timeout: NodeJS.Timeout | null = setTimeout(() => {\n if (timeout) {\n timeout = null;\n resolve(true);\n }\n }, this.scripts[name].onStopTimeout);\n\n try {\n this.scripts[name].onStopCb(() => {\n if (timeout) {\n clearTimeout(timeout);\n timeout = null;\n resolve(true);\n }\n });\n } catch (err: unknown) {\n this.log.error(`error in onStop callback: ${err as Error}`);\n }\n });\n }\n\n delete this.scripts[name];\n return true;\n }\n return false;\n }\n\n async prepareScript(obj: ioBroker.ScriptObject): Promise {\n if (obj?.common?.enabled && this.debugState.scriptName === obj._id) {\n const id = obj._id;\n await this.debugStop();\n this.log.info(`Debugging of ${id} was stopped, because started in normal mode`);\n return this.prepareScript(obj);\n }\n\n if (\n obj?.common?.source &&\n (obj.common.enabled || this.context.debugMode === obj._id) &&\n obj.common.engine === `system.adapter.${this.namespace}`\n ) {\n const name = obj._id;\n\n const nameId = name.substring(SCRIPT_CODE_MARKER.length);\n if (!nameId.length || nameId.endsWith('.')) {\n this.log.error(`Script name ${name} is invalid!`);\n return false;\n }\n const idActive = `scriptEnabled.${nameId}`;\n if (!this.config.subscribe) {\n this.interimStateValues[idActive] = this.prepareStateObjectSimple(\n `${this.namespace}.${idActive}`,\n true,\n true,\n );\n }\n await this.setState(idActive, true, true);\n obj.common.engineType = obj.common.engineType || '';\n\n if (\n (obj.common.engineType as ScriptType).toLowerCase().startsWith('javascript') ||\n (obj.common.engineType as ScriptType) === 'Blockly' ||\n (obj.common.engineType as ScriptType) === 'Rules'\n ) {\n // Javascript\n this.log.info(`Start JavaScript ${name} (${obj.common.engineType})`);\n\n let sourceFn = name;\n if (webstormDebug) {\n const fn = name.replace(/^script.js./, '').replace(/\\./g, '/');\n sourceFn = this.mods.path.join(webstormDebug, `${fn}.js`);\n }\n const createdScript = this.createVM(`${this.globalScript}\\n${obj.common.source}`, sourceFn, true);\n if (!createdScript) {\n return false;\n }\n this.scripts[name] = createdScript;\n this.execute(\n this.scripts[name],\n sourceFn,\n obj.common.engineType as ScriptType,\n obj.common.verbose,\n obj.common.debug,\n );\n return true;\n }\n\n if (obj.common.engineType.toLowerCase().startsWith('typescript')) {\n // TypeScript\n this.log.info(`Compiling TypeScript source ${name}`);\n // The source code must be transformed in order to support top level await\n // and to force TypeScript to compile the code as a module\n const transformedSource = transformScriptBeforeCompilation(obj.common.source, false);\n // We need to hash both global declarations that are known until now\n // AND the script source, because changing either can change the compilation output\n const sourceHash = hashSource(tsSourceHashBase + this.globalDeclarations + transformedSource);\n\n let compiled: string;\n // If we already stored the compiled source code and the original source hash,\n // use the hash to check whether we can rely on the compiled source code or\n // if we need to compile it again\n if (\n typeof obj.common.compiled === 'string' &&\n typeof obj.common.sourceHash === 'string' &&\n sourceHash === obj.common.sourceHash\n ) {\n // We can reuse the stored source\n compiled = obj.common.compiled;\n this.log.info(`${name}: source code did not change, using cached compilation result...`);\n } else {\n // We don't have a hashed source code, or the original source changed, compile it\n const filename = scriptIdToTSFilename(name);\n let tsCompiled: CompileResult;\n try {\n tsCompiled = this.tsServer.compile(filename, transformedSource);\n } catch (err: unknown) {\n this.log.error(`${obj._id}: TypeScript compilation failed:\\n${err as Error}`);\n return false;\n }\n\n const errors = tsCompiled.diagnostics.map(diag => `${diag.annotatedSource}\\n`).join('\\n');\n\n if (tsCompiled.success) {\n if (errors.length > 0) {\n this.log.warn(`${name}: TypeScript compilation had errors:\\n${errors}`);\n } else {\n this.log.info(`${name}: TypeScript compilation successful`);\n }\n compiled = tsCompiled.result || '';\n\n // Store the compiled source and the original source hash, so we don't need to do the work again next time\n this.ignoreObjectChange.add(name); // ignore the next change and don't restart scripts\n await this.extendForeignObjectAsync(name, {\n common: {\n sourceHash,\n compiled,\n },\n });\n } else {\n this.log.error(`${name}: TypeScript compilation failed:\\n${errors}`);\n return false;\n }\n }\n const createdScript: JsScript | false = this.createVM(`${this.globalScript}\\n${compiled}`, name, false);\n if (!createdScript) {\n return false;\n }\n this.scripts[name] = createdScript;\n this.execute(\n this.scripts[name],\n name,\n obj.common.engineType as ScriptType,\n obj.common.verbose,\n obj.common.debug,\n );\n return true;\n }\n\n this.log.warn(`Unknown engine type for \"${name}\": ${obj.common.engineType}`);\n return false;\n }\n\n let _name: string;\n if (obj?._id) {\n _name = obj._id;\n const scriptIdName = _name.substring(SCRIPT_CODE_MARKER.length);\n\n if (!scriptIdName.length || scriptIdName.endsWith('.')) {\n this.log.error(`Script name ${_name} is invalid!`);\n return false;\n }\n await this.setState(`scriptEnabled.${scriptIdName}`, false, true);\n }\n if (!obj) {\n this.log.error('Invalid script');\n }\n return false;\n }\n\n async loadScriptById(id: string): Promise {\n let obj: ioBroker.ScriptObject | null | undefined;\n try {\n obj = (await this.getForeignObjectAsync(id)) as ioBroker.ScriptObject | null | undefined;\n } catch (err: any) {\n this.log.error(`Invalid script \"${id}\": ${err}`);\n }\n if (!obj) {\n return false;\n }\n return this.loadScript(obj);\n }\n\n async loadScript(nameOrObject: ioBroker.ScriptObject): Promise {\n // create states for scripts\n await this.createActiveObject(nameOrObject._id, nameOrObject?.common?.enabled);\n await this.createProblemObject(nameOrObject._id);\n return this.prepareScript(nameOrObject);\n }\n\n getAstroEvent(\n date: Date,\n astroEvent: AstroEventName,\n start: string,\n end: string,\n offsetMinutes: number | string,\n isDayEnd: boolean,\n latitude: number,\n longitude: number,\n useNextDay?: boolean,\n ): Date {\n let ts: Date = this.mods.suncalc.getTimes(date, latitude, longitude)[astroEvent];\n\n if (!ts || ts.getTime().toString() === 'NaN') {\n ts = isDayEnd ? getNextTimeEvent(end, useNextDay) : getNextTimeEvent(start, useNextDay);\n }\n ts.setMilliseconds(0);\n ts.setMinutes(ts.getMinutes() + (parseInt(offsetMinutes as unknown as string, 10) || 0));\n\n const [timeHoursStart, timeMinutesStart] = start.split(':');\n const nTimeHoursStart = parseInt(timeHoursStart, 10);\n const nTimeMinutesStart = parseInt(timeMinutesStart, 10) || 0;\n\n if (\n ts.getHours() < nTimeHoursStart ||\n (ts.getHours() === nTimeHoursStart && ts.getMinutes() < nTimeMinutesStart)\n ) {\n ts = getNextTimeEvent(start, useNextDay);\n ts.setSeconds(0);\n }\n\n const [timeHoursEnd, timeMinutesEnd] = end.split(':');\n const nTimeHoursEnd = parseInt(timeHoursEnd, 10);\n const nTimeMinutesEnd = parseInt(timeMinutesEnd, 10) || 0;\n\n if (ts.getHours() > nTimeHoursEnd || (ts.getHours() === nTimeHoursEnd && ts.getMinutes() > nTimeMinutesEnd)) {\n ts = getNextTimeEvent(end, useNextDay);\n ts.setSeconds(0);\n }\n\n // if event in the past\n if (date > ts && useNextDay) {\n // take the next day\n ts.setDate(ts.getDate() + 1);\n }\n return ts;\n }\n\n async timeSchedule(): Promise {\n const now = new Date();\n let hours = now.getHours();\n const minutes = now.getMinutes();\n if (this.timeSettings.format12) {\n if (hours > 12) {\n hours -= 12;\n }\n }\n let sHours: string;\n if (this.timeSettings.leadingZeros) {\n sHours = hours.toString().padStart(2, '0');\n } else {\n sHours = hours.toString();\n }\n\n await this.setState('variables.dayTime', {\n val: `${sHours}:${minutes.toString().padStart(2, '0')}`,\n ack: true,\n });\n\n now.setMinutes(now.getMinutes() + 1);\n now.setSeconds(0);\n now.setMilliseconds(0);\n const interval = now.getTime() - Date.now();\n this.timeScheduleTimer = setTimeout(() => this.timeSchedule(), interval);\n }\n\n async dayTimeSchedules(): Promise {\n // get astrological event\n if (\n this.config.latitude === undefined ||\n this.config.longitude === undefined ||\n (this.config.latitude as unknown as string) === '' ||\n (this.config.longitude as unknown as string) === '' ||\n this.config.latitude === null ||\n this.config.longitude === null\n ) {\n this.log.error('Longitude or latitude does not set. Cannot use astro.');\n return;\n }\n\n // Calculate the next event today\n const todayDate = getAstroStartOfDay();\n const nowDate = new Date();\n\n const todaySunrise = this.getAstroEvent(\n todayDate,\n this.config.sunriseEvent,\n this.config.sunriseLimitStart,\n this.config.sunriseLimitEnd,\n this.config.sunriseOffset,\n false,\n this.config.latitude,\n this.config.longitude,\n );\n const todaySunset = this.getAstroEvent(\n todayDate,\n this.config.sunsetEvent,\n this.config.sunsetLimitStart,\n this.config.sunsetLimitEnd,\n this.config.sunsetOffset,\n true,\n this.config.latitude,\n this.config.longitude,\n );\n\n // Sunrise\n let sunriseTimeout = todaySunrise.getTime() - nowDate.getTime();\n if (sunriseTimeout < 0 || sunriseTimeout > 3600000) {\n sunriseTimeout = 3600000;\n }\n\n // Sunset\n let sunsetTimeout = todaySunset.getTime() - nowDate.getTime();\n if (sunsetTimeout < 0 || sunsetTimeout > 3600000) {\n sunsetTimeout = 3600000;\n }\n\n const isDayTime: ioBroker.State | null | undefined = await this.getStateAsync('variables.isDayTime');\n let isDay: boolean;\n if (sunriseTimeout < 5000) {\n isDay = true;\n } else if (sunsetTimeout < 5000) {\n isDay = false;\n } else {\n // check if in between\n isDay = nowDate.getTime() > todaySunrise.getTime() - 60000 && nowDate <= todaySunset;\n }\n\n const valDayTime = isDayTime ? !!isDayTime.val : false;\n if (valDayTime !== isDay || isDayTime === null) {\n await this.setState('variables.isDayTime', isDay, true);\n }\n\n const dayLightSaving: ioBroker.State | null | undefined =\n await this.getStateAsync('variables.isDaylightSaving');\n const isDayLightSaving = dstOffsetAtDate(nowDate) !== 0;\n const val = dayLightSaving ? !!dayLightSaving.val : false;\n\n if (val !== isDayLightSaving || dayLightSaving === null) {\n await this.setState('variables.isDaylightSaving', isDayLightSaving, true);\n }\n\n let nextTimeout = sunriseTimeout;\n if (sunriseTimeout > sunsetTimeout) {\n nextTimeout = sunsetTimeout;\n }\n nextTimeout = nextTimeout - 3000;\n if (nextTimeout < 3000) {\n nextTimeout = 3000;\n }\n\n this.dayScheduleTimer = setTimeout(() => this.dayTimeSchedules(), nextTimeout);\n }\n\n stopTimeSchedules(): void {\n if (this.dayScheduleTimer) {\n clearTimeout(this.dayScheduleTimer);\n this.dayScheduleTimer = null;\n }\n if (this.sunScheduleTimer) {\n clearTimeout(this.sunScheduleTimer);\n this.sunScheduleTimer = null;\n }\n if (this.timeScheduleTimer) {\n clearTimeout(this.timeScheduleTimer);\n this.timeScheduleTimer = null;\n }\n }\n\n async patchFont(): Promise {\n let stat: Stats | undefined;\n let dbFile: Buffer | undefined;\n try {\n stat = statSync(`${__dirname}/admin/vs/base/browser/ui/codicons/codicon/codicon.ttf`);\n const _dbFile = await this.readFileAsync(\n 'javascript.admin',\n `vs/base/browser/ui/codicons/codicon/codicon.ttf`,\n );\n if (_dbFile?.file) {\n dbFile = _dbFile.file as Buffer;\n }\n } catch {\n // ignore\n }\n\n if (stat?.size !== 73452 || dbFile?.byteLength !== 73452) {\n try {\n const buffer = Buffer.from(\n JSON.parse(readFileSync(`${__dirname}/admin/vsFont/codicon.json`).toString()),\n 'base64',\n );\n\n const jszip = await import('jszip');\n const zip = await jszip.loadAsync(buffer);\n let data: ArrayBuffer | undefined;\n if (zip) {\n data = await zip.file('codicon.ttf')?.async('arraybuffer');\n if (data?.byteLength !== 73452) {\n this.log.error(`Cannot patch font: invalid font file!`);\n return false;\n }\n } else {\n this.log.error(`Cannot patch font: invalid font file!`);\n return false;\n }\n writeFileSync(`${__dirname}/admin/vs/base/browser/ui/codicons/codicon/codicon.ttf`, Buffer.from(data));\n // upload this file\n await this.writeFileAsync(\n 'javascript.admin',\n 'vs/base/browser/ui/codicons/codicon/codicon.ttf',\n Buffer.from(data),\n );\n return true;\n } catch (err: unknown) {\n this.log.error(`Cannot patch font: ${err as Error}`);\n return false;\n }\n }\n return false;\n }\n\n async sunTimeSchedules(): Promise {\n if (this.config.createAstroStates) {\n if (!isNaN(this.config.longitude) && !isNaN(this.config.longitude)) {\n const calcDate = getAstroStartOfDay();\n\n const times = this.mods.suncalc.getTimes(calcDate, this.config.latitude, this.config.longitude);\n\n this.log.debug(`[sunTimeSchedules] Times: ${JSON.stringify(times)}`);\n\n for (const t in times) {\n try {\n const objId = `variables.astro.${t}`;\n\n await this.setObjectNotExistsAsync(objId, {\n type: 'state',\n common: {\n name: `Astro ${t}`,\n type: 'string',\n role: 'value',\n read: true,\n write: false,\n },\n native: {},\n });\n\n if (times[t] !== null && !isNaN(times[t].getTime())) {\n const timeFormatted = formatHoursMinutesSeconds(times[t]);\n await this.setState(objId, {\n val: timeFormatted,\n c: times[t].toISOString(),\n ack: true,\n });\n } else {\n await this.setState(objId, { val: null, c: 'n/a', ack: true, q: 0x01 });\n }\n } catch (err: unknown) {\n this.log.error(\n `[sunTimeSchedules] Unable to set state for astro time \"${t}\" (${times[t].getTime()}): ${err as Error}`,\n );\n }\n }\n\n const todayDate = new Date();\n todayDate.setHours(0);\n todayDate.setMinutes(0);\n todayDate.setSeconds(1);\n todayDate.setMilliseconds(0);\n todayDate.setDate(todayDate.getDate() + 1);\n\n this.log.debug(`[sunTimeSchedules] Next: ${todayDate.toISOString()}`);\n this.sunScheduleTimer = setTimeout(() => this.sunTimeSchedules(), todayDate.getTime() - Date.now());\n }\n } else {\n // remove astro states if disabled\n this.delObject('variables.astro', { recursive: true });\n }\n }\n\n /**\n * Redirects the virtual-tsc log output to the ioBroker log\n */\n tsLog = (message: string, severity?: ioBroker.LogLevel): void => {\n // shift the severities around, we don't care about the small details\n if (!severity || severity === 'info') {\n severity = 'debug';\n } else if (severity === 'debug') {\n // Don't spam build logs on Travis\n if (isCI) {\n return;\n }\n severity = 'silly';\n }\n\n if (this?.log) {\n this.log[severity](message);\n } else {\n console.log(`[${severity.toUpperCase()}] ${message}`);\n }\n };\n\n addGetProperty(object: Record): void {\n try {\n Object.defineProperty(object, 'get', {\n value: function (id: string): any {\n return this[id] || this[`${this.namespace}.${id}`];\n },\n enumerable: false,\n });\n } catch {\n console.error('Cannot install get property');\n }\n }\n\n /**\n * @param scriptID - The current script the declarations were generated from\n * @param declarations\n */\n provideDeclarationsForGlobalScript(scriptID: string, declarations: string): void {\n // Remember which declarations this global script had access to,\n // we need this so the editor doesn't show a duplicate identifier error\n if (this.globalDeclarations != null && this.globalDeclarations !== '') {\n this.knownGlobalDeclarationsByScript[scriptID] = this.globalDeclarations;\n }\n // and concatenate the global declarations for the next scripts\n this.globalDeclarations += `${declarations}\\n`;\n // remember all previously generated global declarations,\n // so global scripts can reference each other\n const globalDeclarationPath = 'global.d.ts';\n tsAmbient[globalDeclarationPath] = this.globalDeclarations;\n // make sure the next script compilation has access to the updated declarations\n this.tsServer.provideAmbientDeclarations({\n [globalDeclarationPath]: this.globalDeclarations,\n });\n jsDeclarationServer.provideAmbientDeclarations({\n [globalDeclarationPath]: this.globalDeclarations,\n });\n }\n\n fixLineNo(line: string): string {\n if (line.includes('javascript.js:')) {\n return line;\n }\n if (!/script[s]?\\.js[.\\\\/]/.test(line)) {\n return line;\n }\n if (/:([\\d]+):/.test(line)) {\n line = line.replace(\n /:([\\d]+):/,\n ($0, $1) => `:${$1 > this.globalScriptLines + 1 ? $1 - this.globalScriptLines - 1 : $1}:`,\n ); // one line for 'async function ()'\n } else {\n line = line.replace(\n /:([\\d]+)$/,\n ($0, $1) => `:${$1 > this.globalScriptLines + 1 ? $1 - this.globalScriptLines - 1 : $1}`,\n ); // one line for 'async function ()'\n }\n return line;\n }\n\n debugStop(): Promise {\n if (this.debugState.child) {\n this.debugSendToInspector({ cmd: 'end' });\n this.debugState.endTimeout = setTimeout(() => {\n this.debugState.endTimeout = null;\n this.debugState.child?.kill('SIGTERM');\n }, 500);\n this.debugState.promiseOnEnd = this.debugState.promiseOnEnd || Promise.resolve(0);\n } else {\n this.debugState.promiseOnEnd = Promise.resolve(0);\n }\n\n return this.debugState.promiseOnEnd.then(() => {\n this.debugState.child = null;\n this.debugState.running = false;\n this.debugState.scriptName = '';\n if (this.debugState.endTimeout) {\n clearTimeout(this.debugState.endTimeout);\n this.debugState.endTimeout = null;\n }\n });\n }\n\n async debugDisableScript(id: string | undefined): Promise {\n if (id) {\n const obj = this.objects[id];\n if (obj?.common?.enabled) {\n await this.extendForeignObjectAsync(obj._id, { common: { enabled: false } });\n }\n }\n }\n\n debugSendToInspector(message: any): void {\n if (this.debugState.child) {\n try {\n this.log.info(`send to debugger: ${message}`);\n this.debugState.child.send(message);\n } catch {\n this.debugStop().then(() =>\n this.log.info(\n `Debugging of \"${this.debugState.scriptName}\" was stopped, because started in normal mode`,\n ),\n );\n }\n } else {\n this.log.error(`Cannot send command to terminated inspector`);\n this.setState(\n 'debug.from',\n JSON.stringify({ cmd: 'error', error: `Cannot send command to terminated inspector`, id: 1 }),\n true,\n );\n }\n }\n\n debugStart(data: { breakOnStart?: boolean; scriptName?: string; adapter?: string }): void {\n if (Date.now() - this.debugState.started < 1000) {\n console.log('Start ignored');\n return;\n }\n\n this.debugState.started = Date.now();\n // stop the script if it's running\n this.debugDisableScript(data.scriptName)\n .then(() => this.debugStop())\n .then(() => {\n if (data.adapter) {\n this.debugState.adapterInstance = data.adapter;\n this.debugState.scriptName = '';\n } else {\n this.debugState.adapterInstance = '';\n this.debugState.scriptName = data.scriptName as string;\n }\n\n this.debugState.breakOnStart = data.breakOnStart;\n\n this.debugState.promiseOnEnd = new Promise(resolve => {\n const options: ForkOptions = {\n stdio: ['ignore', 'inherit', 'inherit', 'ipc'],\n //stdio: ['pipe', 'pipe', 'pipe', 'ipc']\n };\n const args: string[] = [];\n if (this.debugState.adapterInstance) {\n args.push('--breakOnStart');\n }\n\n this.debugState.child = fork(`${__dirname}/lib/inspect.ts`, args, options);\n\n /*debugState.child.stdout.setEncoding('utf8');\n debugState.child.stderr.setEncoding('utf8');\n debugState.child.stdout.on('data', childPrint);\n debugState.child.stderr.on('data', childPrint);*/\n\n this.debugState.child?.on(\n 'message',\n (\n message:\n | string\n | {\n cmd: 'ready' | 'watched' | 'paused' | 'resumed' | 'log' | 'readyToDebug';\n severity?: string;\n text?: string;\n scriptId?: string;\n script?: string;\n },\n ) => {\n let oMessage: {\n cmd: 'ready' | 'watched' | 'paused' | 'resumed' | 'log' | 'readyToDebug';\n severity?: string;\n text?: string;\n scriptId?: string;\n script?: string;\n };\n if (typeof message === 'string') {\n try {\n oMessage = JSON.parse(message);\n } catch {\n return this.log.error(`Cannot parse message from inspector: ${message}`);\n }\n } else {\n oMessage = message;\n }\n\n if (oMessage.cmd !== 'ready') {\n this.setState('debug.from', JSON.stringify(oMessage), true);\n }\n\n switch (oMessage.cmd) {\n case 'ready': {\n this.debugSendToInspector({\n cmd: 'start',\n scriptName: this.debugState.scriptName,\n adapterInstance: this.debugState.adapterInstance,\n instance: this.instance,\n });\n break;\n }\n\n case 'watched': {\n //console.log(`WATCHED: ${JSON.stringify(oMessage)}`);\n break;\n }\n\n case 'paused': {\n this.debugState.paused = true;\n console.log(`host: PAUSED`);\n break;\n }\n\n case 'resumed': {\n this.debugState.paused = false;\n //console.log(`STARTED`);\n break;\n }\n\n case 'log': {\n console.log(`[${oMessage.severity}] ${oMessage.text}`);\n break;\n }\n\n case 'readyToDebug': {\n console.log(\n `host: readyToDebug (set breakpoints): [${oMessage.scriptId}] ${oMessage.script}`,\n );\n break;\n }\n }\n },\n );\n this.debugState.child?.on('error', error => {\n this.log.error(`Cannot start inspector: ${error}`);\n this.setState('debug.from', JSON.stringify({ cmd: 'error', error }), true);\n });\n\n this.debugState.child?.on('exit', (code: number): void => {\n if (code) {\n this.setState(\n 'debug.from',\n JSON.stringify({ cmd: 'error', error: `invalid response code: ${code}` }),\n true,\n );\n }\n this.setState('debug.from', JSON.stringify({ cmd: 'debugStopped', code }), true);\n this.debugState.child = null;\n resolve(code);\n });\n });\n });\n }\n}\n\nfunction patternMatching(\n event: EventObj,\n patternFunctions: PatternEventCompareFunction[] & { logic?: 'and' | 'or' },\n): boolean {\n let matched = false;\n for (let i = 0, len = patternFunctions.length; i < len; i++) {\n if (patternFunctions[i](event)) {\n if (patternFunctions.logic === 'or') {\n return true;\n }\n matched = true;\n } else if (patternFunctions.logic === 'and') {\n return false;\n }\n }\n return matched;\n}\n\n// If started as allInOne mode => return function to create instance\nif (require.main !== module) {\n // Export the constructor in compact mode\n module.exports = (options: Partial | undefined) => new JavaScript(options);\n} else {\n // otherwise start the instance directly\n (() => new JavaScript())();\n}\n"]} \ No newline at end of file diff --git a/package.json b/package.json index 835f5c61..dc9d1725 100644 --- a/package.json +++ b/package.json @@ -42,19 +42,16 @@ }, "dependencies": { "@iobroker/adapter-core": "^3.2.2", - "@types/node": "^22.7.4", - "@types/request": "^2.48.12", + "@types/node": "^22.9.0", "axios": "^1.7.7", "jsonata": "^2.0.5", "jszip": "^3.10.1", "node-inspect": "^2.0.0", "node-schedule": "2.1.1", - "request": "^2.88.2", "semver": "^7.6.3", "suncalc2": "^1.8.1", - "typescript": "~5.6.2", - "virtual-tsc": "^0.6.2", - "wake_on_lan": "^1.0.0" + "typescript": "~5.6.3", + "virtual-tsc": "^0.6.2" }, "devDependencies": { "@alcalzone/release-script": "^3.8.0", @@ -62,16 +59,16 @@ "@alcalzone/release-script-plugin-license": "^3.7.0", "@iobroker/adapter-dev": "^1.3.0", "@iobroker/build-tools": "^2.0.6", - "@iobroker/eslint-config": "^0.1.6", + "@iobroker/eslint-config": "^0.1.7", "@iobroker/testing": "^5.0.0", - "@iobroker/types": "^6.0.11", + "@iobroker/types": "^7.0.3", "@types/nodemailer": "^6.4.16", "@types/node-schedule": "^2.1.7", "@types/request": "^2.48.12", "@types/suncalc": "^1.9.2", "@iobroker/vis-2-widgets-react-dev": "^4.0.3", - "alcalzone-shared": "^4.0.8", - "chai": "^5.1.1", + "alcalzone-shared": "^5.0.0", + "chai": "^4.5.0", "mocha": "^10.8.2", "timekeeper": "^2.3.1" }, @@ -97,6 +94,7 @@ "translate": "translate-adapter", "//postinstall": "node ./install/installTypings.js", "build": "node tasks", + "tsc-backend": "tsc -p tsconfig.build.json", "release": "release-script --noPush -y --all", "update-packages": "ncu --upgrade && cd src && ncu --upgrade && cd ../src-admin && ncu --upgrade", "npm": "npm i && cd src && npm i -f && cd ../src-admin && npm i -f", diff --git a/src-admin/package.json b/src-admin/package.json index 020cfdd0..01a9364e 100644 --- a/src-admin/package.json +++ b/src-admin/package.json @@ -10,18 +10,18 @@ "devDependencies": { "@babel/plugin-proposal-private-property-in-object": "^7.21.11", "@craco/craco": "^7.1.0", - "@iobroker/adapter-react-v5": "^7.2.3", - "@iobroker/json-config": "^7.2.1", - "@mui/icons-material": "^6.1.2", - "@mui/material": "^6.1.2", - "@mui/x-date-pickers": "^7.19.0", + "@iobroker/adapter-react-v5": "^7.3.0", + "@iobroker/json-config": "^7.3.0", + "@mui/icons-material": "^6.1.7", + "@mui/material": "^6.1.7", + "@mui/x-date-pickers": "^7.22.2", "@originjs/vite-plugin-federation": "^1.3.6", "@rollup/plugin-babel": "^6.0.4", - "@rollup/plugin-commonjs": "^28.0.0", + "@rollup/plugin-commonjs": "^28.0.1", "@rollup/plugin-node-resolve": "^15.3.0", "@rollup/plugin-replace": "^6.0.1", - "@types/react": "^18.3.11", - "@types/react-dom": "^18.3.0", + "@types/react": "^18.3.12", + "@types/react-dom": "^18.3.1", "craco-esbuild": "^0.6.1", "craco-module-federation": "^1.1.0", "date-fns": "^4.1.0", diff --git a/src/lib/debugger.ts b/src/lib/debugger.ts index 5cefcf81..b86fa4d8 100644 --- a/src/lib/debugger.ts +++ b/src/lib/debugger.ts @@ -21,15 +21,40 @@ */ import { join, resolve } from 'node:path'; import { type ReplOptions, type REPLServer, start } from 'repl'; -import { debuglog as debuglogUtil, type InspectOptions, inspect as inspectUtil } from 'node:util'; +import { + debuglog as debuglogUtil, + inspect as inspectUtil, + type InspectOptions, + type InspectOptionsStylized, + type Style, +} from 'node:util'; import { type Context, runInContext } from 'node:vm'; import { fileURLToPath } from 'node:url'; import { builtinModules as PUBLIC_BUILTINS } from 'node:module'; import type { Debugger, Runtime } from 'node:inspector'; -import { type NodeInspector } from './inspect'; + +import type { NodeInspector } from './inspect'; const debuglog = debuglogUtil('inspect'); +interface PropertyPreview { + /** + * Property name. + */ + name: string; + /** + * Object type. Accessor means that the property itself is an accessor property. + */ + type: string; + /** + * User-friendly property value string. + */ + value?: string | undefined; + /** + * Object subtype hint. Specified for object type values only. + */ + subtype?: string | undefined; +} /*const SHORTCUTS = { cont: 'c', next: 'n', @@ -184,8 +209,8 @@ class RemoteObject implements Runtime.RemoteObject { } } - [inspectUtil.custom](_depth: number, opts): string { - function formatProperty(prop): any { + [inspectUtil.custom](_depth: number, opts: InspectOptionsStylized): string { + function formatProperty(prop: PropertyPreview): any { switch (prop.type) { case 'string': case 'undefined': @@ -193,17 +218,17 @@ class RemoteObject implements Runtime.RemoteObject { case 'number': case 'boolean': - return opts.stylize(prop.value, prop.type); + return opts.stylize(prop.value as string, prop.type); case 'object': case 'symbol': if (prop.subtype === 'date') { - return inspectUtil(new Date(prop.value), opts); + return inspectUtil(new Date(prop.value as string), opts); } if (prop.subtype === 'array') { - return opts.stylize(prop.value, 'special'); + return opts.stylize(prop.value as string, 'special'); } - return opts.stylize(prop.value, prop.subtype || 'special'); + return opts.stylize(prop.value as string, (prop.subtype as Style) || 'special'); default: return prop.value; @@ -218,7 +243,7 @@ class RemoteObject implements Runtime.RemoteObject { return inspectUtil(this.value, opts); case 'symbol': - return opts.stylize(this.description, 'special'); + return opts.stylize(this.description as string, 'special'); case 'function': { const fnName = extractFunctionName(this.description); @@ -229,19 +254,19 @@ class RemoteObject implements Runtime.RemoteObject { case 'object': switch (this.subtype) { case 'date': - return inspectUtil(new Date(this.description || ''), opts); + return inspectUtil(new Date(this.description as string), opts); case 'null': return inspectUtil(null, opts); case 'regexp': - return opts.stylize(this.description, 'regexp'); + return opts.stylize(this.description as string, 'regexp'); default: break; } if (this.preview) { - const props = this.preview.properties.map((prop, idx) => { + const props: any[] = this.preview.properties.map((prop, idx) => { const value = formatProperty(prop); if (prop.name === `${idx}`) { return value; @@ -383,12 +408,12 @@ export default function createRepl(inspector: NodeInspector): () => REPLServer { return selectedFrame.location; } - function isCurrentScript(script): boolean { + function isCurrentScript(script: Debugger.ScriptParsedEventDataType & { isNative: boolean }): boolean { return !!selectedFrame && getCurrentLocation().scriptId === script.scriptId; } function formatScripts(displayNatives = false): string { - function isVisible(script): boolean { + function isVisible(script: Debugger.ScriptParsedEventDataType & { isNative: boolean }): boolean { if (displayNatives) { return true; } @@ -409,6 +434,7 @@ export default function createRepl(inspector: NodeInspector): () => REPLServer { function listScripts(displayNatives = false): void { print(formatScripts(displayNatives)); } + // @ts-expect-error no idea what this is listScripts[inspectUtil.custom] = function listWithoutInternal(): string { return formatScripts(); }; @@ -643,7 +669,7 @@ export default function createRepl(inspector: NodeInspector): () => REPLServer { // } function controlEval( - input, + input: string, context: Context, filename: string, callback: (error: Error | null, result?: any) => void, @@ -1243,7 +1269,7 @@ export default function createRepl(inspector: NodeInspector): () => REPLServer { ignoreUndefined: true, }; - repl = start(replOptions); // eslint-disable-line prefer-const + repl = start(replOptions); initializeContext(repl.context); repl.on('reset', initializeContext); diff --git a/src/lib/eventObj.ts b/src/lib/eventObj.ts index a241d7e6..f8ba445b 100644 --- a/src/lib/eventObj.ts +++ b/src/lib/eventObj.ts @@ -166,8 +166,8 @@ export class EventObj { if (!gContext.isEnums) { return undefined; } - const enumIds = []; - const enumNames = []; + const enumIds: string[] = []; + const enumNames: string[] = []; getObjectEnumsSync(gContext, this.id, enumIds, enumNames); Object.defineProperty(this, 'enumNames', { value: enumNames }); return doGetter(this, 'enumIds', enumIds); @@ -176,8 +176,8 @@ export class EventObj { if (!gContext.isEnums) { return undefined; } - const enumIds = []; - const enumNames = []; + const enumIds: string[] = []; + const enumNames: string[] = []; getObjectEnumsSync(gContext, this.id, enumIds, enumNames); Object.defineProperty(this, 'enumIds', { value: enumIds }); return doGetter(this, 'enumNames', enumNames); diff --git a/src/lib/inspect.ts b/src/lib/inspect.ts index 19d82690..1dafed87 100644 --- a/src/lib/inspect.ts +++ b/src/lib/inspect.ts @@ -19,19 +19,19 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS * IN THE SOFTWARE. */ -import { spawn } from 'node:child_process'; +import { spawn, type ChildProcessWithoutNullStreams } from 'node:child_process'; import { EventEmitter } from 'node:events'; import { connect } from 'node:net'; -import { debuglog as utilDebugLog, inspect } from 'node:util'; +import { debuglog as utilDebugLog, inspect, type InspectOptionsStylized } from 'node:util'; import { normalize, join } from 'node:path'; import { existsSync } from 'node:fs'; import type { WriteStream, ReadStream } from 'node:tty'; +// @ts-expect-error no types available import InspectClient from 'node-inspect/lib/internal/inspect_client'; -import createRepl from './debugger'; import type { Debugger, Runtime } from 'node:inspector'; import type { REPLServer } from 'repl'; -import type { ChildProcessWithoutNullStreams } from 'child_process'; +import createRepl from './debugger'; // const runAsStandalone = typeof __dirname !== 'undefined'; const breakOnStart = process.argv.includes('--breakOnStart'); @@ -117,9 +117,10 @@ function runScript( let output = ''; function waitForListenHint(text: string): void { output += text; - if (/Debugger listening on ws:\/\/\[?(.+?)]?:(\d+)\//.test(output)) { - const host = RegExp.$1; - const port = Number.parseInt(RegExp.$2); + const res = /Debugger listening on ws:\/\/\[?(.+?)]?:(\d+)\//.exec(output); + if (res) { + const host = res[1]; + const port = Number.parseInt(res[2]); child.stderr.removeListener('data', waitForListenHint); resolve([child, port, host]); } @@ -132,10 +133,11 @@ function runScript( function createAgentProxy(domain: string, client: InspectClient): ProxyConstructor { const agent: any = new EventEmitter(); - agent.then = (...args) => { + + agent.then = (...args: any[]) => { // TODO: potentially fetch the protocol and pretty-print it here. const descriptor = { - [inspect.custom](_depth: number, { stylize }) { + [inspect.custom](_depth: number, { stylize }: InspectOptionsStylized): string { return stylize(`[Agent ${domain}]`, 'special'); }, }; @@ -615,7 +617,6 @@ function startInspect( } process.on('uncaughtException', handleUnexpectedError); - /* eslint-enable no-console */ } function extractErrorMessage(stack: string | undefined): string { @@ -634,10 +635,10 @@ function convertResultToError(result: Runtime.RemoteObject): Error { return err; } -process.on('message', (message: DebugCommand): void => { +process.on('message', (message: DebugCommand | string): void => { if (typeof message === 'string') { try { - message = JSON.parse(message); + message = JSON.parse(message) as DebugCommand; } catch { return console.error(`Cannot parse: ${JSON.stringify(message)}`); } @@ -753,15 +754,15 @@ function processCommand(data: DebugCommand): void { sendToHost({ cmd: 'script', scriptId: data.scriptId, text: script.scriptSource }), ); } else if (data.cmd === 'cont') { - inspector.Debugger.resume().catch(e => sendToHost({ cmd: 'error', error: e })); + inspector.Debugger.resume().catch((e: any) => sendToHost({ cmd: 'error', error: e })); } else if (data.cmd === 'next') { - inspector.Debugger.stepOver().catch(e => sendToHost({ cmd: 'error', error: e })); + inspector.Debugger.stepOver().catch((e: any) => sendToHost({ cmd: 'error', error: e })); } else if (data.cmd === 'pause') { - inspector.Debugger.pause().catch(e => sendToHost({ cmd: 'error', error: e })); + inspector.Debugger.pause().catch((e: any) => sendToHost({ cmd: 'error', error: e })); } else if (data.cmd === 'step') { - inspector.Debugger.stepInto().catch(e => sendToHost({ cmd: 'error', error: e })); + inspector.Debugger.stepInto().catch((e: any) => sendToHost({ cmd: 'error', error: e })); } else if (data.cmd === 'out') { - inspector.Debugger.stepOut().catch(e => sendToHost({ cmd: 'error', error: e })); + inspector.Debugger.stepOut().catch((e: any) => sendToHost({ cmd: 'error', error: e })); } else if (data.cmd === 'sb') { console.log(JSON.stringify(data)); @@ -778,7 +779,7 @@ function processCommand(data: DebugCommand): void { id: result.breakpointId, location: result.actualLocation, })) - .catch(e => + .catch((e: any) => sendToHost({ cmd: 'error', error: `Cannot set breakpoint: ${e}`, errorContext: e, bp }), ), ) || [], @@ -788,7 +789,7 @@ function processCommand(data: DebugCommand): void { (data.breakpoints as Debugger.BreakpointId[])?.map(breakpointId => inspector.Debugger.removeBreakpoint({ breakpointId } as Debugger.RemoveBreakpointParameterType) .then(() => breakpointId) - .catch(e => + .catch((e: any) => sendToHost({ cmd: 'error', error: `Cannot clear breakpoint: ${e}`, @@ -801,7 +802,7 @@ function processCommand(data: DebugCommand): void { } else if (data.cmd === 'watch') { Promise.all( data.expressions?.map(expr => - inspector.Debugger.watch(expr).catch(e => + inspector.Debugger.watch(expr).catch((e: any) => sendToHost({ cmd: 'error', error: `Cannot watch expr: ${e}`, errorContext: e, expr }), ), ) || [], @@ -809,7 +810,7 @@ function processCommand(data: DebugCommand): void { } else if (data.cmd === 'unwatch') { Promise.all( data.expressions?.map(expr => - inspector.Debugger.unwatch(expr).catch(e => + inspector.Debugger.unwatch(expr).catch((e: any) => sendToHost({ cmd: 'error', error: `Cannot unwatch expr: ${e}`, errorContext: e, expr }), ), ) || [], @@ -823,8 +824,8 @@ function processCommand(data: DebugCommand): void { objectId: scope.object.objectId, generatePreview: true, } as Runtime.GetPropertiesParameterType) - .then(result => ({ type: scope.type, properties: result })) - .catch(e => + .then((result: any) => ({ type: scope.type, properties: result })) + .catch((e: any) => sendToHost({ cmd: 'error', error: `Cannot get scopes expr: ${e}`, errorContext: e }), ), ) || [], @@ -836,7 +837,7 @@ function processCommand(data: DebugCommand): void { newValue: data.newValue, callFrameId: data.callFrameId, } as Debugger.SetVariableValueParameterType) - .catch(e => sendToHost({ cmd: 'setValue', variableName: `Cannot setValue: ${e}`, errorContext: e })) + .catch((e: any) => sendToHost({ cmd: 'setValue', variableName: `Cannot setValue: ${e}`, errorContext: e })) .then(() => sendToHost({ cmd: 'setValue', @@ -863,7 +864,7 @@ function processCommand(data: DebugCommand): void { } return { name: item.name, result }; }) - .catch(e => + .catch((e: any) => sendToHost({ cmd: 'expressions', variableName: `Cannot setValue: ${e}`, errorContext: e }), ), ) || [], @@ -871,7 +872,7 @@ function processCommand(data: DebugCommand): void { } else if (data.cmd === 'stopOnException') { inspector.Debugger.setPauseOnExceptions({ state: data.state ? 'all' : 'none', - } as Debugger.SetPauseOnExceptionsParameterType).catch(e => + } as Debugger.SetPauseOnExceptionsParameterType).catch((e: any) => sendToHost({ cmd: 'stopOnException', variableName: `Cannot stopOnException: ${e}`, errorContext: e }), ); } else if (data.cmd === 'getPossibleBreakpoints') { @@ -879,7 +880,7 @@ function processCommand(data: DebugCommand): void { .then((breakpoints: Debugger.GetPossibleBreakpointsReturnType) => sendToHost({ cmd: 'getPossibleBreakpoints', breakpoints: breakpoints.locations }), ) - .catch(e => + .catch((e: any) => sendToHost({ cmd: 'getPossibleBreakpoints', variableName: `Cannot getPossibleBreakpoints: ${e}`, diff --git a/src/lib/javascript.d.ts b/src/lib/javascript.d.ts index e21aab27..d1b6fe0c 100644 --- a/src/lib/javascript.d.ts +++ b/src/lib/javascript.d.ts @@ -1108,18 +1108,13 @@ declare global { * The instance number of the JavaScript adapter this script runs in */ const instance: number; - /** - * The name of the current script - */ - // @ts-expect-error We need this variable, although it conflicts with lib.es6 - const name: string; /** * The name of the current script */ const scriptName: string; /** - * Absolute path to iobroker-data directory in file system + * Absolute path to iobroker-data directory in a file system */ const defaultDataDir: string; diff --git a/src/lib/mirror.ts b/src/lib/mirror.ts index d7ca758c..bc0fe177 100644 --- a/src/lib/mirror.ts +++ b/src/lib/mirror.ts @@ -661,14 +661,14 @@ export class Mirror { (err, res) => { // this is not required, because JavaScript subscribes on ALL objects // adapter.subscribeForeignObjects('script.js.*'); - const list = {}; + const list: Record = {}; if (err) { this.log.error(`Error while checking scripts channel from objects database: ${err}`); } - if (res && res.rows) { + if (res?.rows) { for (let i = 0; i < res.rows.length; i++) { const value = res.rows[i].value; - if (value && value._id && value.common) { + if (value?._id && value.common) { list[res.rows[i].value._id] = res.rows[i].value; } } @@ -681,10 +681,10 @@ export class Mirror { if (err) { this.log.error(`Error while checking scripts javascript from objects database: ${err}`); } - if (res && res.rows) { + if (res?.rows) { for (let i = 0; i < res.rows.length; i++) { const value = res.rows[i].value; - if (value && value._id && value.common) { + if (value?._id && value.common) { list[res.rows[i].value._id] = res.rows[i].value; // ensure that every script has a folder and if not, then create it this._checkIfAllFoldersAreExist(res.rows[i].value._id, list); diff --git a/src/lib/patternCompareFunctions.ts b/src/lib/patternCompareFunctions.ts index e7a794ed..70b0d3ce 100644 --- a/src/lib/patternCompareFunctions.ts +++ b/src/lib/patternCompareFunctions.ts @@ -19,12 +19,14 @@ function stringOrRegExpCompare( eventPropertyExtractor?: (event: EventObj) => any, invert?: boolean, ): PatternEventCompareFunction { - const field: RegExp | string | string[] = pattern[propName]; + const field: RegExp | string | string[] = (pattern as Record)[propName]; const hasExtractor = typeof eventPropertyExtractor === 'function'; if (isRegExp(field)) { return function (event: EventObj): boolean { - const eventValue = hasExtractor ? eventPropertyExtractor(event) : event[propName]; + const eventValue: any = hasExtractor + ? eventPropertyExtractor(event) + : (event as Record)[propName]; const ret = eventValue != null && (field as RegExp).test(eventValue); return invert ? !ret : ret; }; @@ -32,7 +34,7 @@ function stringOrRegExpCompare( if (Array.isArray(field)) { return function (event: EventObj): boolean { - const eventValue = hasExtractor ? eventPropertyExtractor(event) : event[propName]; + const eventValue = hasExtractor ? eventPropertyExtractor(event) : (event as Record)[propName]; // An array matches when any element is found that satisfies the constraint const ret = eventValue != null && field.find(f => f === eventValue) != null; return invert ? !ret : ret; @@ -40,7 +42,7 @@ function stringOrRegExpCompare( } return function (event: EventObj): boolean { - const eventValue = hasExtractor ? eventPropertyExtractor(event) : event[propName]; + const eventValue = hasExtractor ? eventPropertyExtractor(event) : (event as Record)[propName]; const ret = eventValue != null && field === eventValue; return invert ? !ret : ret; }; @@ -76,6 +78,7 @@ export const patternCompareFunctions = { // on any other logic, just signal about a message } }, + ack: (pattern: Pattern): PatternEventCompareFunction => { if (pattern.ack === true || pattern.ack === 'true') { return (event: EventObj): boolean => event.newState.ack === true; diff --git a/src/lib/protectFs.ts b/src/lib/protectFs.ts index 7a195440..07a933e6 100644 --- a/src/lib/protectFs.ts +++ b/src/lib/protectFs.ts @@ -16,6 +16,13 @@ import type { NoParamCallback, PathOrFileDescriptor, WriteFileOptions, + EncodingOption, + FSWatcher, + ReadStream, + StatsListener, + StatWatcher, + WatchListener, + WriteStream, } from 'node:fs'; import type { Abortable } from 'node:events'; import type { FileHandle, FlagAndOpenMode } from 'node:fs/promises'; @@ -270,19 +277,25 @@ export default class ProtectFs { // Add missing functions for (const m in nodeFS) { - if (typeof nodeFS[m] === 'function' && Object.hasOwn(nodeFS, m) && !Object.hasOwn(this, m)) { + if ( + typeof (nodeFS as unknown as Record)[m] === 'function' && + Object.hasOwn(nodeFS, m) && + !Object.hasOwn(this, m) + ) { // console.debug(`Missing function in ProtectFS: ${m} - adding from node:fs`); + // @ts-expect-error Elsewise we must implement EVERY function in fs this[m] = nodeFS[m]; } } for (const m in nodeFS.promises) { if ( - typeof nodeFS.promises[m] === 'function' && + typeof (nodeFS.promises as unknown as Record)[m] === 'function' && Object.hasOwn(nodeFS.promises, m) && !Object.hasOwn(this.promises, m) ) { // console.debug(`Missing function in ProtectFS: ${m} - adding from node:fs/promises`); + // @ts-expect-error Elsewise we must implement EVERY function in fs this.promises[m] = nodeFS.promises[m]; } } @@ -376,7 +389,7 @@ export default class ProtectFs { target: PathLike, path: PathLike, type: 'dir' | 'file' | 'junction' | undefined | null | NoParamCallback, - callback?: NoParamCallback, + callback: NoParamCallback, ): void { this.#checkProtected(target, true); this.#checkProtected(path, false); @@ -396,7 +409,7 @@ export default class ProtectFs { writeFile( file: PathLike | number, data: string | NodeJS.ArrayBufferView, - options?: WriteFileOptions, + options: WriteFileOptions | NoParamCallback, callback?: NoParamCallback, ): void { if (typeof file !== 'number') { @@ -413,9 +426,8 @@ export default class ProtectFs { return nodeFS.writeFileSync.call(this, file, data, options); // function writeFileSync(path, data, options) { } - unlink(path: PathLike, callback?: NoParamCallback): void { + unlink(path: PathLike, callback: NoParamCallback): void { this.#checkProtected(path, false); - // @ts-expect-error should work return nodeFS.unlink.call(this, path, callback); // function unlink(path, callback) { } @@ -424,11 +436,10 @@ export default class ProtectFs { return nodeFS.unlinkSync.call(this, path); // function unlinkSync(path) { } - appendFile(file: PathLike | number, data: string | Uint8Array, callback?: NoParamCallback): void { + appendFile(file: PathLike | number, data: string | Uint8Array, callback: NoParamCallback): void { if (typeof file !== 'number') { this.#checkProtected(file, false); } - // @ts-expect-error should work return nodeFS.appendFile.call(this, file, data, callback); // function appendFile(path, data, options, callback) { } @@ -439,9 +450,8 @@ export default class ProtectFs { return nodeFS.appendFileSync.call(this, file, data); // function appendFileSync(path, data, options) { } - chmod(path: PathLike, mode: Mode, callback?: NoParamCallback): void { + chmod(path: PathLike, mode: Mode, callback: NoParamCallback): void { this.#checkProtected(path, false); - // @ts-expect-error should work return nodeFS.chmod.call(this, path, mode, callback); // function chmod(path, mode, callback) { } @@ -450,9 +460,8 @@ export default class ProtectFs { return nodeFS.chmodSync.call(this, path, mode); // function chmodSync(path, mode) { } - chown(path: PathLike, uid: number, gid: number, callback?: NoParamCallback): void { + chown(path: PathLike, uid: number, gid: number, callback: NoParamCallback): void { this.#checkProtected(path, false); - // @ts-expect-error should work return nodeFS.chown.call(this, path, uid, gid, callback); // function chown(path, uid, gid, callback) { } @@ -461,7 +470,7 @@ export default class ProtectFs { return nodeFS.chownSync.call(this, path, uid, gid); // function chownSync(path, uid, gid) { } - copyFile(src: PathLike, dest: PathLike, mode?: number | NoParamCallback, callback?: NoParamCallback): void { + copyFile(src: PathLike, dest: PathLike, mode: number | NoParamCallback, callback?: NoParamCallback): void { this.#checkProtected(src, true); this.#checkProtected(dest, false); // @ts-expect-error should work @@ -474,163 +483,213 @@ export default class ProtectFs { return nodeFS.copyFileSync.call(this, src, dest, mode); // function copyFileSync(src, dest, mode) { } - rename(): void { - this.#checkProtected(arguments[0], false); - this.#checkProtected(arguments[1], false); - return nodeFS.rename.apply(this, arguments); // function rename(oldPath, newPath, callback) { + rename(oldPath: PathLike, newPath: PathLike, callback: NoParamCallback): void { + this.#checkProtected(oldPath, false); + this.#checkProtected(newPath, false); + return nodeFS.rename.call(this, oldPath, newPath, callback); // function rename(oldPath, newPath, callback) { } - renameSync(): void { - this.#checkProtected(arguments[0], false); - this.#checkProtected(arguments[1], false); - return nodeFS.renameSync.apply(this, arguments); // function renameSync(oldPath, newPath) { + renameSync(oldPath: PathLike, newPath: PathLike): void { + this.#checkProtected(oldPath, false); + this.#checkProtected(newPath, false); + return nodeFS.renameSync.call(this, oldPath, newPath); // function renameSync(oldPath, newPath) { } - open(): void { - this.#checkProtected(arguments[0], true); - return nodeFS.open.apply(this, arguments); // function open(path, flags, mode, callback) { + open(path: PathLike, callback: (err: NodeJS.ErrnoException | null, fd: number) => void): void { + this.#checkProtected(path, true); + return nodeFS.open.call(this, path, callback); // function open(path, flags, mode, callback) { } - openSync() { - this.#checkProtected(arguments[0], true); - return nodeFS.openSync.apply(this, arguments); // function openSync(path, flags, mode) { + openSync(path: PathLike, flags: OpenMode, mode?: Mode | null): number { + this.#checkProtected(path, true); + return nodeFS.openSync.call(this, path, flags, mode); // function openSync(path, flags, mode) { } - truncate(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.truncate.apply(this, arguments); // function truncate(path, len, callback) { + truncate(path: PathLike, callback: NoParamCallback): void { + this.#checkProtected(path, false); + return nodeFS.truncate.call(this, path, callback); // function truncate(path, len, callback) { } - truncateSync(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.truncateSync.apply(this, arguments); // function truncateSync(path, len) { + truncateSync(path: PathLike): void { + this.#checkProtected(path, false); + return nodeFS.truncateSync.call(this, path); // function truncateSync(path, len) { } - exists(): void { - this.#checkProtected(arguments[0], true); - return nodeFS.exists.apply(this, arguments); // function exists(path, callback) { + exists(path: PathLike, callback: (exists: boolean) => void): void { + this.#checkProtected(path, true); + return nodeFS.exists.call(this, path, callback); // function exists(path, callback) { } - existsSync(): boolean { - this.#checkProtected(arguments[0], true); - return nodeFS.existsSync.apply(this, arguments); // function existsSync(path) { + existsSync(path: PathLike): boolean { + this.#checkProtected(path, true); + return nodeFS.existsSync.call(this, path); // function existsSync(path) { } - stat(): void { - this.#checkProtected(arguments[0], true); - return nodeFS.stat.apply(this, arguments); // function stat(path, options = { bigint: false }, callback) { + stat( + path: PathLike, + options: StatOptions | undefined | ((err: NodeJS.ErrnoException | null, stats: Stats) => void), + callback?: (err: NodeJS.ErrnoException | null, stats: Stats) => void, + ): void { + this.#checkProtected(path, true); + // @ts-expect-error should work + return nodeFS.stat.call(this, path, options, callback); // function stat(path, options = { bigint: false }, callback) { } - statSync(): void { - this.#checkProtected(arguments[0], true); - return nodeFS.statSync.apply(this, arguments); // function statSync(path, options = { bigint: false, throwIfNoEntry: true }) { + statSync(path: PathLike, options?: StatOptions): Stats { + this.#checkProtected(path, true); + return nodeFS.statSync.call(this, path, options); // function statSync(path, options = { bigint: false, throwIfNoEntry: true }) { } - utimes(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.utimes.apply(this, arguments); // function utimes(path, atime, mtime, callback) { + utimes(path: PathLike, atime: TimeLike, mtime: TimeLike, callback: NoParamCallback): void { + this.#checkProtected(path, false); + return nodeFS.utimes.call(this, path, atime, mtime, callback); // function utimes(path, atime, mtime, callback) { } - utimesSync(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.utimesSync.apply(this, arguments); // function utimesSync(path, atime, mtime) { + utimesSync(path: PathLike, atime: TimeLike, mtime: TimeLike): void { + this.#checkProtected(path, false); + return nodeFS.utimesSync.call(this, path, atime, mtime); // function utimesSync(path, atime, mtime) { } - readdir(): void { - this.#checkProtected(arguments[0], true); - return nodeFS.readdir.apply(this, arguments); // function readdir(path, options, callback) { + readdir( + path: PathLike, + options: + | (ObjectEncodingOptions & { + withFileTypes: true; + recursive?: boolean | undefined; + }) + | ((err: NodeJS.ErrnoException | null, files: Dirent[]) => void), + callback?: (err: NodeJS.ErrnoException | null, files: Dirent[]) => void, + ): void { + this.#checkProtected(path, true); + // @ts-expect-error should work + return nodeFS.readdir.call(this, path, options, callback); // function readdir(path, options, callback) { } - readdirSync(): void { - this.#checkProtected(arguments[0], true); - return nodeFS.readdirSync.apply(this, arguments); // function readdirSync(path, options) { + readdirSync( + path: PathLike, + options?: ObjectEncodingOptions & { + withFileTypes: true; + recursive?: boolean | undefined; + }, + ): void { + this.#checkProtected(path, true); + // @ts-expect-error should work + return nodeFS.readdirSync.call(this, path, options); // function readdirSync(path, options) { } - createReadStream(): void { - this.#checkProtected(arguments[0], true); - return nodeFS.createReadStream.apply(this, arguments); // function createReadStream(path, options) { + createReadStream(path: PathLike, options?: BufferEncoding): ReadStream { + this.#checkProtected(path, true); + return nodeFS.createReadStream.call(this, path, options); // function createReadStream(path, options) { } - createWriteStream(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.createWriteStream.apply(this, arguments); // function createWriteStream(path, options) { + createWriteStream(path: PathLike, options?: BufferEncoding): WriteStream { + this.#checkProtected(path, false); + return nodeFS.createWriteStream.call(this, path, options); // function createWriteStream(path, options) { } - lchmod(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.lchmod.apply(this, arguments); // function lchmod(path, mode, callback) { + lchmod(path: PathLike, mode: Mode, callback: NoParamCallback): void { + this.#checkProtected(path, false); + return nodeFS.lchmod.call(this, path, mode, callback); // function lchmod(path, mode, callback) { } - lchmodSync(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.lchmodSync.apply(this, arguments); // function lchmodSync(path, mode) { + lchmodSync(path: PathLike, mode: Mode): void { + this.#checkProtected(path, false); + return nodeFS.lchmodSync.call(this, path, mode); // function lchmodSync(path, mode) { } - lchown(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.lchown.apply(this, arguments); // function lchown(path, uid, gid, callback) { + lchown(path: PathLike, uid: number, gid: number, callback: NoParamCallback): void { + this.#checkProtected(path, false); + return nodeFS.lchown.call(this, path, uid, gid, callback); // function lchown(path, uid, gid, callback) { } - lchownSync(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.lchownSync.apply(this, arguments); // function lchownSync(path, uid, gid) { + lchownSync(path: PathLike, uid: number, gid: number): void { + this.#checkProtected(path, false); + return nodeFS.lchownSync.call(this, path, uid, gid); // function lchownSync(path, uid, gid) { } - link(): void { - this.#checkProtected(arguments[0], false); - this.#checkProtected(arguments[1], false); - return nodeFS.link.apply(this, arguments); // function link(existingPath, newPath, callback) { + link(existingPath: PathLike, newPath: PathLike, callback: NoParamCallback): void { + this.#checkProtected(existingPath, false); + this.#checkProtected(newPath, false); + return nodeFS.link.call(this, existingPath, newPath, callback); // function link(existingPath, newPath, callback) { } - linkSync(): void { - this.#checkProtected(arguments[0], false); - this.#checkProtected(arguments[1], false); - return nodeFS.linkSync.apply(this, arguments); // function linkSync(existingPath, newPath) { + linkSync(existingPath: PathLike, newPath: PathLike): void { + this.#checkProtected(existingPath, false); + this.#checkProtected(newPath, false); + return nodeFS.linkSync.call(this, existingPath, newPath); // function linkSync(existingPath, newPath) { } - lstat(): void { - this.#checkProtected(arguments[0], true); - return nodeFS.lstat.apply(this, arguments); // function lstat(path, options = { bigint: false }, callback) { + lstat( + path: PathLike, + options: StatOptions | undefined | ((err: NodeJS.ErrnoException | null, stats: Stats) => void), + callback: (err: NodeJS.ErrnoException | null, stats: Stats) => void, + ): void { + this.#checkProtected(path, true); + // @ts-expect-error should work + return nodeFS.lstat.call(this, path, options, callback); // function lstat(path, options = { bigint: false }, callback) { } - lstatSync() { - this.#checkProtected(arguments[0], true); - return nodeFS.lstatSync.apply(this, arguments); // function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) { + lstatSync(path: PathLike, options?: StatOptions): Stats { + this.#checkProtected(path, true); + return nodeFS.lstatSync.call(this, path, options); // function lstatSync(path, options = { bigint: false, throwIfNoEntry: true }) { } - lutimes(): void { - this.#checkProtected(arguments[0], false); - return nodeFS.lutimes.apply(this, arguments); // function lutimes(path, atime, mtime, callback) { + lutimes(path: PathLike, atime: TimeLike, mtime: TimeLike, callback: NoParamCallback): void { + this.#checkProtected(path, false); + return nodeFS.lutimes.call(this, path, atime, mtime, callback); // function lutimes(path, atime, mtime, callback) { } - lutimesSync() { - this.#checkProtected(arguments[0], false); - return nodeFS.lutimesSync.apply(this, arguments); // function lutimesSync(path, atime, mtime) { + lutimesSync(path: PathLike, atime: TimeLike, mtime: TimeLike): void { + this.#checkProtected(path, false); + return nodeFS.lutimesSync.call(this, path, atime, mtime); // function lutimesSync(path, atime, mtime) { } - mkdir() { - this.#checkProtected(arguments[0], false); - return nodeFS.mkdir.apply(this, arguments); // function mkdir(path, options, callback) { + mkdir( + path: PathLike, + options: + | Mode + | (MakeDirectoryOptions & { + recursive: true; + }) + | null + | undefined + | ((err: NodeJS.ErrnoException | null, path?: string) => void), + callback?: (err: NodeJS.ErrnoException | null, path?: string) => void, + ): void { + this.#checkProtected(path, false); + // @ts-expect-error should work + return nodeFS.mkdir.call(this, path, options, callback); // function mkdir(path, options, callback) { } - mkdirSync() { - this.#checkProtected(arguments[0], false); - return nodeFS.mkdirSync.apply(this, arguments); // function mkdirSync(path, options) { + mkdirSync( + path: PathLike, + options?: MakeDirectoryOptions & { + recursive: true; + }, + ): string | undefined { + this.#checkProtected(path, false); + return nodeFS.mkdirSync.call(this, path, options); // function mkdirSync(path, options) { } - mkdtemp() { - this.#checkProtected(arguments[0], false); - return nodeFS.mkdtemp.apply(this, arguments); // function mkdtemp(prefix, options, callback) { + mkdtemp( + prefix: string, + options: EncodingOption | ((err: NodeJS.ErrnoException | null, folder: string) => void), + callback?: (err: NodeJS.ErrnoException | null, folder: string) => void, + ): void { + this.#checkProtected(prefix, false); + // @ts-expect-error should work + return nodeFS.mkdtemp.call(this, prefix, options, callback); // function mkdtemp(prefix, options, callback) { } - mkdtempSync() { - this.#checkProtected(arguments[0], false); - return nodeFS.mkdtempSync.apply(this, arguments); // function mkdtempSync(prefix, options) { + mkdtempSync(prefix: string, options?: EncodingOption): string | Buffer { + this.#checkProtected(prefix, false); + return nodeFS.mkdtempSync.call(this, prefix, options); // function mkdtempSync(prefix, options) { } - rm() { - this.#checkProtected(arguments[0], false); - return nodeFS.rm.apply(this, arguments); // function rm(path, options, callback) { + rm(path: PathLike, options: RmOptions | NoParamCallback, callback?: NoParamCallback): void { + this.#checkProtected(path, false); + // @ts-expect-error should work + return nodeFS.rm.call(this, path, options, callback); // function rm(path, options, callback) { } rmSync(path: PathLike, options?: RmOptions): void { @@ -638,23 +697,24 @@ export default class ProtectFs { return nodeFS.rmSync.call(this, path, options); // function rmSync(path, options) { } - rmdir() { - this.#checkProtected(arguments[0], false); - return nodeFS.rmdir.apply(this, arguments); // function rmdir(path, options, callback) { + rmdir(path: PathLike, options: RmDirOptions | NoParamCallback, callback?: NoParamCallback): void { + this.#checkProtected(path, false); + // @ts-expect-error should work + return nodeFS.rmdir.call(this, path, options, callback); // function rmdir(path, options, callback) { } - rmdirSync() { - this.#checkProtected(arguments[0], false); - return nodeFS.rmdirSync.apply(this, arguments); // function rmdirSync(path, options) { + rmdirSync(path: PathLike, options?: RmDirOptions): void { + this.#checkProtected(path, false); + return nodeFS.rmdirSync.call(this, path, options); // function rmdirSync(path, options) { } - watch() { - this.#checkProtected(arguments[0], true); - return nodeFS.watch.apply(this, arguments); // function watch(filename, options, listener) { + watch(filename: PathLike, listener?: WatchListener): FSWatcher { + this.#checkProtected(filename, true); + return nodeFS.watch.call(this, filename, listener); // function watch(filename, options, listener) { } - watchFile() { - this.#checkProtected(arguments[0], true); - return nodeFS.watchFile.apply(this, arguments); // function watchFile(filename, options, listener) { + watchFile(filename: PathLike, listener: StatsListener): StatWatcher { + this.#checkProtected(filename, true); + return nodeFS.watchFile.call(this, filename, listener); // function watchFile(filename, options, listener) { } } diff --git a/src/lib/request.ts b/src/lib/request.ts index 144a5ffb..1a6c648b 100644 --- a/src/lib/request.ts +++ b/src/lib/request.ts @@ -35,25 +35,28 @@ function requestSafe(method: (..._args: any[]) => any, ...args: any[]): any { return method(...args).on('error', requestError); } -// Wrap all methods that accept a callback -const methodsWithCallback = ['get', 'post', 'put', 'head', 'patch', 'del', 'delete', 'initParams']; // and request itself // @ts-expect-error fix later -const request = (...args: any[]): any => requestSafe(_request, ...args); +export const request = (...args: any[]): any => requestSafe(_request, ...args); -for (const methodName of methodsWithCallback) { - request[methodName] = (...args: any[]) => requestSafe(_request[methodName], ...args); -} +request.get = (...args: any[]): any => requestSafe(_request.get, ...args); +request.post = (...args: any[]): any => requestSafe(_request.post, ...args); +request.put = (...args: any[]): any => requestSafe(_request.put, ...args); +request.head = (...args: any[]): any => requestSafe(_request.head, ...args); +request.patch = (...args: any[]): any => requestSafe(_request.patch, ...args); +request.del = (...args: any[]): any => requestSafe(_request.del, ...args); +request.delete = (...args: any[]): any => requestSafe(_request.delete, ...args); +request.initParams = (...args: any[]): any => requestSafe(_request.initParams, ...args); // And copy all other properties and methods -const otherPropsAndMethods = ['defaults', 'forever', 'jar', 'cookie', 'debug']; -for (const propName of otherPropsAndMethods) { - request[propName] = _request[propName]; -} +request.defaults = _request.defaults; +request.forever = _request.forever; +request.jar = _request.jar; +request.cookie = _request.cookie; +request.debug = _request.debug; request.setLogger = function (_logger: { error: (e: string) => void }): void { logger = _logger; }; // end of monkeypatching -module.exports = request; diff --git a/src/lib/sandbox.ts b/src/lib/sandbox.ts index 8c5f3095..eb93da53 100644 --- a/src/lib/sandbox.ts +++ b/src/lib/sandbox.ts @@ -177,7 +177,9 @@ export function sandBox( if (key === 'change' && pattern.change === 'any') { continue; } - const _func = patternCompareFunctions[key]; + const _func: (pattern: Pattern) => PatternEventCompareFunction = ( + patternCompareFunctions as unknown as Record PatternEventCompareFunction> + )[key]; if (!_func) { continue; } @@ -528,11 +530,17 @@ export function sandBox( if (isChanged) { if (!(adapter.config as JavaScriptAdapterConfig).subscribe && context.interimStateValues[id]) { // if the state is changed, we will compare it with interimStateValues - const oldState = context.interimStateValues[id], - attrs = Object.keys(stateAsObject).filter( - attr => attr !== 'ts' && stateAsObject[attr] !== undefined, - ); - if (attrs.every(attr => stateAsObject[attr] === oldState[attr]) === false) { + const oldState = context.interimStateValues[id]; + const attrs: string[] = Object.keys(stateAsObject).filter( + attr => attr !== 'ts' && (stateAsObject as Record)[attr] !== undefined, + ); + if ( + !attrs.every( + attr => + (stateAsObject as Record)[attr] === + (oldState as Record)[attr], + ) + ) { // state is changed for sure, and we will call setForeignState // and store new state to interimStateValues context.interimStateValues[id] = stateAsObject; @@ -4543,7 +4551,7 @@ export function sandBox( readFile: function ( _adapter: string, fileName: string | ((err: Error | null | undefined, data?: Buffer | string, mimeType?: string) => void), - callback: (err: Error | null | undefined, data?: Buffer | string, mimeType?: string) => void, + callback?: (err: Error | null | undefined, data?: Buffer | string, mimeType?: string) => void, ): void { if (typeof fileName === 'function') { callback = fileName as ( @@ -4554,6 +4562,10 @@ export function sandBox( fileName = _adapter; _adapter = '0_userdata.0'; } + if (typeof callback !== 'function') { + sandbox.log(`readFile(adapter=${_adapter}, fileName=${fileName}): no callback`, 'error'); + return; + } _adapter = _adapter || '0_userdata.0'; if (sandbox.verbose) { sandbox.log(`readFile(adapter=${_adapter}, fileName=${fileName})`, 'info'); @@ -4654,7 +4666,12 @@ export function sandBox( instance: string | (ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }), options: | (ioBroker.GetHistoryOptions & { id?: string; timeout?: number | string }) - | ioBroker.GetHistoryCallback, + | (( + error: Error | null, + result?: ioBroker.GetHistoryResult | null, + options?: ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }, + instance?: string, + ) => void), callback?: ( error: Error | null, result?: ioBroker.GetHistoryResult | null, @@ -5093,7 +5110,7 @@ export function sandBox( const attr: string = path.shift() || ''; try { - obj = obj[attr]; + obj = (obj as Record)[attr]; } catch (err: unknown) { adapter.setState(`scriptProblem.${name.substring('script.js.'.length)}`, { val: true, @@ -5436,8 +5453,118 @@ export function sandBox( ); } }, + existsStateAsync: function (_id: string): Promise { + return Promise.reject(new Error('Not implemented')); + }, + existsObjectAsync: function (_id: string): Promise { + return Promise.reject(new Error('Not implemented')); + }, + getObjectAsync: function (_id: string, _enumName: null | string): Promise { + return Promise.reject(new Error('Not implemented')); + }, + setObjectAsync: function (_id: string, _obj: ioBroker.Object): Promise<{ id: string }> { + return Promise.reject(new Error('Not implemented')); + }, + extendObjectAsync: function (_id: string, _obj: Partial): Promise<{ id: string }> { + return Promise.reject(new Error('Not implemented')); + }, + deleteObjectAsync: function (_id: string, _isRecursive?: boolean): Promise { + return Promise.reject(new Error('Not implemented')); + }, + createStateAsync: function ( + _name: string, + _initValue: undefined | ioBroker.StateValue | ioBroker.State, + _forceCreation: + | boolean + | undefined + | Record + | Partial + | ((err: Error | null) => void), + _common?: Partial | ((err: Error | null) => void), + _native?: Record | ((err: Error | null) => void), + ): Promise { + return Promise.reject(new Error('Not implemented')); + }, + createAliasAsync: function ( + _name: string, + _alias: string | CommonAlias, + _forceCreation: boolean | Partial | undefined, + _common?: Partial | Record, + _native?: Record, + ): Promise { + return Promise.reject(new Error('Not implemented')); + }, + deleteStateAsync: function (_id: string): Promise { + return Promise.reject(new Error('Not implemented')); + }, + writeFileAsync: function ( + _adapter: string, + _fileName: string | Buffer, + _data?: string | Buffer, + ): Promise { + return Promise.reject(new Error('Not implemented')); + }, + readFileAsync: function (_adapter: string, _fileName?: string): Promise { + return Promise.reject(new Error('Not implemented')); + }, + unlinkAsync: function (_adapter: string, _fileName?: string): Promise { + return Promise.reject(new Error('Not implemented')); + }, + delFileAsync: function (_adapter: string, _fileName?: string): Promise { + return Promise.reject(new Error('Not implemented')); + }, + renameAsync: function (_adapter: string, _oldName: string, _newName?: string): Promise { + return Promise.reject(new Error('Not implemented')); + }, + renameFileAsync: function (_adapter: string, _oldName: string, _newName?: string): Promise { + return Promise.reject(new Error('Not implemented')); + }, + getHistoryAsync: function ( + _instance: string | (ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }), + _options?: ioBroker.GetHistoryOptions & { id?: string; timeout?: number | string }, + ): Promise { + return Promise.reject(new Error('Not implemented')); + }, + httpGetAsync: function ( + _url: string, + _options?: { + timeout?: number; + responseType?: ResponseType; + headers?: Record; + basicAuth?: { user: string; password: string } | null; + bearerAuth?: string; + validateCertificate?: boolean; + }, + ): Promise<{ + statusCode: number | null; + data: any; + headers: Record; + responseTime: number; + }> { + return Promise.reject(new Error('Not implemented')); + }, + httpPostAsync: function ( + _url: string, + _data: any, + _options: { + timeout?: number; + responseType?: ResponseType; + headers?: Record; + basicAuth?: { user: string; password: string } | null; + bearerAuth?: string; + validateCertificate?: boolean; + }, + ): Promise<{ + statusCode: number | null; + data: any; + headers: Record; + responseTime: number; + }> { + return Promise.reject(new Error('Not implemented')); + }, }; + // Create advanced functions that can modify objects if ((adapter.config as JavaScriptAdapterConfig).enableSetObject) { sandbox.setObject = function ( id: string, @@ -5538,29 +5665,24 @@ export function sandBox( } // promisify methods on the sandbox - const promisifiedMethods = [ - 'existsState', - 'existsObject', - 'getObject', - 'setObject', - 'extendObject', - 'deleteObject', - 'createState', - 'createAlias', - 'deleteState', - 'writeFile', - 'readFile', - 'unlink', - 'delFile', - 'rename', - 'renameFile', - 'getHistory', - 'httpPost', - 'httpGet', - ]; - for (const method of promisifiedMethods) { - sandbox[`${method}Async`] = promisify(sandbox[method]); - } + sandbox.existsStateAsync = promisify(sandbox.existsState); + sandbox.existsObjectAsync = promisify(sandbox.existsObject); + sandbox.getObjectAsync = promisify(sandbox.getObject); + sandbox.setObjectAsync = promisify(sandbox.setObject); + sandbox.extendObjectAsync = promisify(sandbox.extendObject); + sandbox.deleteObjectAsync = promisify(sandbox.deleteObject); + sandbox.createStateAsync = promisify(sandbox.createState); + sandbox.createAliasAsync = promisify(sandbox.createAlias); + sandbox.deleteStateAsync = promisify(sandbox.deleteState); + sandbox.writeFileAsync = promisify(sandbox.writeFile); + sandbox.readFileAsync = promisify(sandbox.readFile); + sandbox.unlinkAsync = promisify(sandbox.unlink); + sandbox.delFileAsync = promisify(sandbox.delFile); + sandbox.renameAsync = promisify(sandbox.rename); + sandbox.renameFileAsync = promisify(sandbox.renameFile); + sandbox.getHistoryAsync = promisify(sandbox.getHistory); + sandbox.httpGetAsync = promisify(sandbox.httpGet); + sandbox.httpPostAsync = promisify(sandbox.httpPost); // Make all predefined properties and methods readonly so scripts cannot overwrite them for (const prop of Object.keys(sandbox)) { diff --git a/src/lib/scheduler.ts b/src/lib/scheduler.ts index fed6e910..d9b32225 100644 --- a/src/lib/scheduler.ts +++ b/src/lib/scheduler.ts @@ -189,22 +189,22 @@ export class Scheduler { this.latitude = latitude; this.longitude = longitude; this.log = log || { - debug: function (text) { + debug: function (text: string): void { console.log(text); }, - info: function (text) { + info: function (text: string): void { console.log(text); }, - log: function (text) { + log: function (text: string): void { console.log(text); }, - warn: function (text) { + warn: function (text: string): void { console.warn(text); }, - error: function (text) { + error: function (text: string): void { console.error(text); }, - silly: function (text) { + silly: function (text: string): void { console.log(text); }, }; diff --git a/src/lib/tools.ts b/src/lib/tools.ts index c46aac59..e50d04ba 100644 --- a/src/lib/tools.ts +++ b/src/lib/tools.ts @@ -116,7 +116,7 @@ export function promisifyNoError(fn: Function, context: any): (...args: any[]) = context = context || this; return new Promise(resolve => { try { - fn.apply(context, [...args, result => resolve(result)]); + fn.apply(context, [...args, (result: any) => resolve(result)]); } catch { resolve(null); // what to do in this case?? } diff --git a/src/main.ts b/src/main.ts index c8db6640..f168711e 100644 --- a/src/main.ts +++ b/src/main.ts @@ -30,8 +30,10 @@ import * as child_process from 'node:child_process'; import * as stream from 'node:stream'; import * as zlib from 'node:zlib'; +// @ts-expect-error no types available import * as suncalc from 'suncalc2'; import * as axios from 'axios'; +// @ts-expect-error no types available import * as wake_on_lan from 'wake_on_lan'; import * as nodeSchedule from 'node-schedule'; @@ -73,6 +75,7 @@ import type { PatternEventCompareFunction } from './lib/patternCompareFunctions' type MODULES = { fs: ProtectFs; + 'fs/promises': ProtectFs['promises']; dgram: typeof dgram; crypto: typeof crypto; dns: typeof dns; @@ -329,7 +332,7 @@ class JavaScript extends Adapter { private globalDeclarations = ''; // Remember which definitions the global scripts // have access to, because it depends on the compilation order - private knownGlobalDeclarationsByScript = {}; + private knownGlobalDeclarationsByScript: Record = {}; private globalScriptLines = 0; // compiler instance for typescript private tsServer: Server; @@ -401,6 +404,7 @@ class JavaScript extends Adapter { this.mods = { fs: {} as ProtectFs, + 'fs/promises': {} as ProtectFs['promises'], dgram, crypto, dns, @@ -853,7 +857,7 @@ class JavaScript extends Adapter { try { if (obj.callback) { - handler.cb.call(sandbox, obj.message.data, result => { + handler.cb.call(sandbox, obj.message.data, (result: any) => { if (sandbox.verbose) { sandbox.log(`onMessage result: ${JSON.stringify(result)}`, 'info'); } @@ -861,7 +865,7 @@ class JavaScript extends Adapter { this.sendTo(obj.from, obj.command, result, obj.callback); }); } else { - handler.cb.call(sandbox, obj.message.data, result => { + handler.cb.call(sandbox, obj.message.data, (result: any) => { sandbox.verbose && sandbox.log(`onMessage result: ${JSON.stringify(result)}`, 'info'); }); @@ -882,7 +886,7 @@ class JavaScript extends Adapter { case 'loadTypings': { // Load typings for the editor - const typings = {}; + const typings: Record = {}; // try to load TypeScript lib files from disk try { @@ -968,15 +972,25 @@ class JavaScript extends Adapter { } } - const result = {}; - const keys = Object.keys(astroEvents).sort((a, b) => astroEvents[a] - astroEvents[b]); + const result: Record = {}; + const keys = Object.keys(astroEvents).sort( + (a, b) => + (astroEvents as unknown as Record)[a] - + (astroEvents as unknown as Record)[b], + ); keys.forEach(key => { - const validDate = astroEvents[key] !== null && !isNaN(astroEvents[key].getTime()); + const validDate = + (astroEvents as unknown as Record)[key] !== null && + !isNaN((astroEvents as unknown as Record)[key].getTime()); result[key] = { isValidDate: validDate, - serverTime: validDate ? formatHoursMinutesSeconds(astroEvents[key]) : 'n/a', - date: validDate ? astroEvents[key].toISOString() : 'n/a', + serverTime: validDate + ? formatHoursMinutesSeconds((astroEvents as unknown as Record)[key]) + : 'n/a', + date: validDate + ? (astroEvents as unknown as Record)[key].toISOString() + : 'n/a', }; }); @@ -1449,7 +1463,7 @@ class JavaScript extends Adapter { // try to load the typings on disk for all 3rd party modules const packages = [ 'node', // this provides auto-completion for most builtins - 'request', // preloaded by the adapter + '@iobroker/types', // this provides auto-completion for most builtins ]; // Also include user-selected libraries (but only those that are also installed) if (typeof this.config?.libraries === 'string' && typeof this.config.libraryTypings === 'string') { @@ -1982,7 +1996,10 @@ class JavaScript extends Adapter { this.config.libraries = ''; } - const libraries = this.config.libraries.split(/[,;\s]+/).filter(d => d.length > 0); + const libraries: string[] = this.config.libraries + .split(/[,;\s]+/) + .map(d => d.trim()) + .filter(d => d); this.log.debug(`Custom libraries in config: "${this.config.libraries}": ${JSON.stringify(libraries)}`); @@ -2027,7 +2044,7 @@ class JavaScript extends Adapter { this.log.debug(`Installed custom library: "${moduleName}@${version}"`); const importedModule: any = await this.importNodeModule(moduleName); - this.mods[moduleName] = importedModule.default ?? importedModule; + (this.mods as Record)[moduleName] = importedModule.default ?? importedModule; } else { this.log.warn(`Cannot install custom npm package "${moduleName}@${version}"`); } @@ -2040,11 +2057,9 @@ class JavaScript extends Adapter { try { await this.installNpm(lib); - this.log.info(`Installed custom npm package (legacy mode): "${libraries[lib]}"`); + this.log.info(`Installed custom npm package (legacy mode): "${lib}"`); } catch (err: any) { - this.log.warn( - `Cannot install custom npm package "${libraries[lib]}" (legacy mode): ${err.toString()}`, - ); + this.log.warn(`Cannot install custom npm package "${lib}" (legacy mode): ${err.toString()}`); } } } diff --git a/src/types.d.ts b/src/types.d.ts index 6328bda4..8743d0e0 100644 --- a/src/types.d.ts +++ b/src/types.d.ts @@ -205,6 +205,22 @@ export type SandboxType = { }, ) => void, ) => void; + httpGetAsync: ( + url: string, + options?: { + timeout?: number; + responseType?: ResponseType; + headers?: Record; + basicAuth?: { user: string; password: string } | null; + bearerAuth?: string; + validateCertificate?: boolean; + }, + ) => Promise<{ + statusCode: number | null; + data: any; + headers: Record; + responseTime: number; + }>; httpPost: ( url: string, data: any, @@ -236,6 +252,23 @@ export type SandboxType = { }, ) => void, ) => void; + httpPostAsync: ( + url: string, + data: any, + options: { + timeout?: number; + responseType?: ResponseType; + headers?: Record; + basicAuth?: { user: string; password: string } | null; + bearerAuth?: string; + validateCertificate?: boolean; + }, + ) => Promise<{ + statusCode: number | null; + data: any; + headers: Record; + responseTime: number; + }>; createTempFile: (fileName: string, data: Buffer | string) => string | undefined; subscribe: ( pattern: @@ -352,36 +385,49 @@ export type SandboxType = { id: string, callback?: (err: Error | null | undefined, stateExists?: boolean) => void, ) => void | boolean; + existsStateAsync: (id: string) => Promise; existsObject: ( id: string, callback?: (err: Error | null | undefined, objectExists?: boolean) => void, ) => void | boolean; + existsObjectAsync: (id: string) => Promise; getIdByName: (name: string, alwaysArray?: boolean) => string | string[] | null; getObject: ( id: string, enumName: null | string | ((err: Error | null | undefined, obj?: ioBroker.Object | null) => void), cb: (err: Error | null | undefined, obj?: ioBroker.Object | null) => void, ) => void; + getObjectAsync: (id: string, enumName: null | string) => Promise; setObject: ( id: string, obj: ioBroker.Object, callback?: (err?: Error | null | string, res?: { id: string }) => void, ) => void; + setObjectAsync: (id: string, obj: ioBroker.Object) => Promise<{ id: string }>; extendObject: ( id: string, obj: Partial, callback?: (err?: Error | null | string, res?: { id: string }) => void, ) => void; + extendObjectAsync: (id: string, obj: Partial) => Promise<{ id: string }>; deleteObject: (id: string, isRecursive?: boolean, callback?: ioBroker.ErrorCallback) => void; + deleteObjectAsync: (id: string, isRecursive?: boolean) => Promise; getEnums: (enumName: string) => { id: string; members: string[]; name: ioBroker.StringOrTranslated }[]; createAlias: ( name: string, - alias: string, - forceCreation: boolean, - common: Partial, - native: Record, - callback: (err: Error | null) => void, + alias: string | CommonAlias, + forceCreation: boolean | Partial | ((err: Error | null) => void) | undefined, + common?: Partial | Record | ((err: Error | null) => void), + native?: Record | ((err: Error | null) => void), + callback?: (err: Error | null) => void, ) => void; + createAliasAsync: ( + name: string, + alias: string | CommonAlias, + forceCreation: boolean | Partial | undefined, + common?: Partial | Record, + native?: Record, + ) => Promise; createState: ( name: string, initValue: undefined | ioBroker.StateValue | ioBroker.State, @@ -395,7 +441,20 @@ export type SandboxType = { native?: Record | ((err: Error | null) => void), callback?: (error: Error | null | undefined, id?: string) => void, ) => void; + createStateAsync: ( + name: string, + initValue: undefined | ioBroker.StateValue | ioBroker.State, + forceCreation: + | boolean + | undefined + | Record + | Partial + | ((err: Error | null) => void), + common?: Partial | ((err: Error | null) => void), + native?: Record | ((err: Error | null) => void), + ) => Promise; deleteState: (id: string, callback: (err: Error | null | undefined, found?: boolean) => void) => void; + deleteStateAsync: (id: string) => Promise; sendTo: ( adapter: string, cmd: string, @@ -434,17 +493,48 @@ export type SandboxType = { ) => string; formatTimeDiff: (diff: number, format?: string) => string; getDateObject: (date: any) => Date; - writeFile: (adapter: string, fileName: string, data: any, callback?: (err?: Error | null) => void) => void; + writeFile: ( + adapter: string, + fileName: string, + data: string | Buffer | ((err?: Error | null) => void), + callback?: (err?: Error | null) => void, + ) => void; + writeFileAsync: (adapter: string, fileName: string | Buffer, data?: string | Buffer) => Promise; readFile: ( adapter: string, fileName: string | ((err: Error | null | undefined, data?: Buffer | string, mimeType?: string) => void), - callback: (err: Error | null | undefined, data?: Buffer | string, mimeType?: string) => void, + callback?: (err: Error | null | undefined, data?: Buffer | string, mimeType?: string) => void, ) => void; + readFileAsync: (adapter: string, fileName?: string) => Promise; unlink: (adapter: string, fileName: string, callback?: (err?: Error | null) => void) => void; + unlinkAsync: (adapter: string, fileName?: string) => Promise; delFile: (adapter: string, fileName: string, callback?: (err?: Error | null) => void) => void; + delFileAsync: (adapter: string, fileName?: string) => Promise; rename: (adapter: string, oldName: string, newName: string, callback?: (err?: Error | null) => void) => void; + renameAsync: (adapter: string, oldName: string, newName?: string) => Promise; renameFile: (adapter: string, oldName: string, newName: string, callback?: (err?: Error | null) => void) => void; - getHistory: (instance: string, options: any, callback: (err: Error | null, result: any) => void) => void; + renameFileAsync: (adapter: string, oldName: string, newName?: string) => Promise; + getHistory: ( + instance: string | (ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }), + options: + | (ioBroker.GetHistoryOptions & { id?: string; timeout?: number | string }) + | (( + error: Error | null, + result?: ioBroker.GetHistoryResult | null, + options?: ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }, + instance?: string, + ) => void), + callback?: ( + error: Error | null, + result?: ioBroker.GetHistoryResult | null, + options?: ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }, + instance?: string, + ) => void, + ) => void; + getHistoryAsync: ( + instance: string | (ioBroker.GetHistoryOptions & { id: string; timeout?: number | string }), + options?: ioBroker.GetHistoryOptions & { id?: string; timeout?: number | string }, + ) => Promise; runScript: (scriptName: string, callback?: (err?: Error | null) => void) => boolean; runScriptAsync: (scriptName: string) => Promise; startScript: ( diff --git a/tsconfig.build.json b/tsconfig.build.json new file mode 100644 index 00000000..bbb9149a --- /dev/null +++ b/tsconfig.build.json @@ -0,0 +1,12 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "allowJs": true, + "checkJs": false, + "noEmit": false, + "declaration": false, + "skipLibCheck": true, + "module": "commonjs" + }, + "include": ["src/**/*.ts", "src/**/*.js"] +} diff --git a/tsconfig.json b/tsconfig.json index 70f07ce5..77e64783 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,30 +1,22 @@ { "compileOnSave": true, "compilerOptions": { - // do not compile anything; this file is just to configure type checking "noEmit": true, - - // check JS files "allowJs": true, "checkJs": true, + "outDir": "./build-backend/", + "sourceMap": true, + "inlineSources": true, - "module": "commonjs", + "module": "esnext", "moduleResolution": "node", - // this is necessary for the automatic typing of the adapter config "resolveJsonModule": true, - - // Set this to false if you want to disable the very strict rules (not recommended) "strict": true, - // Or enable some of those features for more fine-grained control - // "strictNullChecks": true, - // "strictPropertyInitialization": true, - // "strictBindCallApply": true, - "noImplicitAny": false, - // "noUnusedLocals": true, - // "noUnusedParameters": true, + "noImplicitAny": true, "target": "es2022", "esModuleInterop": true, - "types": ["node", "@iobroker/types"], + "types": ["@types/node", "@iobroker/types"], }, - "include": ["src/**/*.ts"] + "include": ["src/**/*.ts"], + "exclude": ["node_modules/**", "admin/**"] }