@markw65/monkeyc-optimizer 1.0.10 → 1.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- 0 && (module.exports = {copyRecursiveAsNeeded,launchSimulator,defaultConfig,buildOptimizedProject,generateOptimizedProject,generateApiMirTests});
1
+ 0 && (module.exports = {copyRecursiveAsNeeded,get_jungle,launchSimulator,manifestProducts,mctree,simulateProgram,defaultConfig,isErrorWithLocation,buildOptimizedProject,generateOptimizedProject,getProjectAnalysis,generateApiMirTests});
2
2
  /******/ (() => { // webpackBootstrap
3
3
  /******/ var __webpack_modules__ = ({
4
4
 
@@ -9772,6 +9772,18 @@ module.exports = require("zlib");
9772
9772
  /******/ }
9773
9773
  /******/
9774
9774
  /************************************************************************/
9775
+ /******/ /* webpack/runtime/compat get default export */
9776
+ /******/ (() => {
9777
+ /******/ // getDefaultExport function for compatibility with non-harmony modules
9778
+ /******/ __webpack_require__.n = (module) => {
9779
+ /******/ var getter = module && module.__esModule ?
9780
+ /******/ () => (module['default']) :
9781
+ /******/ () => (module);
9782
+ /******/ __webpack_require__.d(getter, { a: getter });
9783
+ /******/ return getter;
9784
+ /******/ };
9785
+ /******/ })();
9786
+ /******/
9775
9787
  /******/ /* webpack/runtime/define property getters */
9776
9788
  /******/ (() => {
9777
9789
  /******/ // define getter functions for harmony exports
@@ -9815,9 +9827,18 @@ __webpack_require__.d(__webpack_exports__, {
9815
9827
  "defaultConfig": () => (/* binding */ defaultConfig),
9816
9828
  "generateApiMirTests": () => (/* binding */ generateApiMirTests),
9817
9829
  "generateOptimizedProject": () => (/* binding */ generateOptimizedProject),
9818
- "launchSimulator": () => (/* reexport */ launchSimulator)
9830
+ "getProjectAnalysis": () => (/* binding */ getProjectAnalysis),
9831
+ "get_jungle": () => (/* reexport */ get_jungle),
9832
+ "isErrorWithLocation": () => (/* binding */ isErrorWithLocation),
9833
+ "launchSimulator": () => (/* reexport */ launchSimulator),
9834
+ "manifestProducts": () => (/* reexport */ manifestProducts),
9835
+ "mctree": () => (/* reexport */ prettier_plugin_monkeyc_namespaceObject.mctree),
9836
+ "simulateProgram": () => (/* reexport */ simulateProgram)
9819
9837
  });
9820
9838
 
9839
+ ;// CONCATENATED MODULE: external "@markw65/prettier-plugin-monkeyc"
9840
+ const prettier_plugin_monkeyc_namespaceObject = require("@markw65/prettier-plugin-monkeyc");
9841
+ var prettier_plugin_monkeyc_default = /*#__PURE__*/__webpack_require__.n(prettier_plugin_monkeyc_namespaceObject);
9821
9842
  ;// CONCATENATED MODULE: external "crypto"
9822
9843
  const external_crypto_namespaceObject = require("crypto");
9823
9844
  ;// CONCATENATED MODULE: external "fs/promises"
@@ -9830,72 +9851,66 @@ const external_api_cjs_namespaceObject = require("./api.cjs");
9830
9851
  const external_sdk_util_cjs_namespaceObject = require("./sdk-util.cjs");
9831
9852
  ;// CONCATENATED MODULE: external "./util.cjs"
9832
9853
  const external_util_cjs_namespaceObject = require("./util.cjs");
9833
- ;// CONCATENATED MODULE: ./src/build.js
9834
-
9854
+ ;// CONCATENATED MODULE: ./src/build.ts
9835
9855
 
9836
9856
 
9837
9857
 
9838
9858
  async function build_project(product, options, lineCallback) {
9839
- const {
9840
- workspace,
9841
- program,
9842
- jungleFiles,
9843
- developerKeyPath,
9844
- simulatorBuild,
9845
- releaseBuild,
9846
- compilerOptions,
9847
- compilerWarnings,
9848
- typeCheckLevel,
9849
- returnCommand,
9850
- } = options;
9851
- const sdk = await (0,external_sdk_util_cjs_namespaceObject.getSdkPath)();
9852
- let extraArgs = [];
9853
- if (compilerOptions) {
9854
- extraArgs.push(...compilerOptions.split(/\s+/));
9855
- }
9856
- if (compilerWarnings) {
9857
- extraArgs.push("-w");
9858
- }
9859
- if (releaseBuild) {
9860
- extraArgs.push("-r");
9861
- }
9862
- if (!product) {
9863
- extraArgs.push("-e");
9864
- }
9865
- switch (typeCheckLevel) {
9866
- case "Off":
9867
- extraArgs.push("-l", "0");
9868
- break;
9869
- case "Gradual":
9870
- extraArgs.push("-l", "1");
9871
- break;
9872
- case "Informative":
9873
- extraArgs.push("-l", "2");
9874
- break;
9875
- case "Strict":
9876
- extraArgs.push("-l", "3");
9877
- break;
9878
- }
9879
- if (product) {
9880
- extraArgs.push("-d", simulatorBuild !== false ? `${product}_sim` : product);
9881
- }
9882
- const exe = external_path_.resolve(sdk, "bin", external_sdk_util_cjs_namespaceObject.isWin ? "monkeyc.bat" : "monkeyc");
9883
- const args = [
9884
- ["-o", program],
9885
- ["-f", jungleFiles],
9886
- ["-y", developerKeyPath],
9887
- extraArgs,
9888
- ].flat();
9889
-
9890
- const handlers = [
9891
- lineCallback || ((line) => console.log(line)),
9892
- (line) => console.error(line),
9893
- ];
9894
- return returnCommand
9895
- ? { exe, args, program: external_path_.resolve(workspace, program), product }
9896
- : (0,external_util_cjs_namespaceObject.spawnByLine)(exe, args, handlers, {
9897
- cwd: workspace,
9898
- });
9859
+ const { workspace, program, jungleFiles, developerKeyPath, simulatorBuild, releaseBuild, testBuild, compilerOptions, compilerWarnings, typeCheckLevel, returnCommand, } = options;
9860
+ const sdk = await (0,external_sdk_util_cjs_namespaceObject.getSdkPath)();
9861
+ let extraArgs = [];
9862
+ if (compilerOptions) {
9863
+ extraArgs.push(...compilerOptions.split(/\s+/));
9864
+ }
9865
+ if (compilerWarnings) {
9866
+ extraArgs.push("-w");
9867
+ }
9868
+ if (testBuild) {
9869
+ extraArgs.push("-t");
9870
+ }
9871
+ else if (releaseBuild) {
9872
+ extraArgs.push("-r");
9873
+ }
9874
+ if (!product) {
9875
+ extraArgs.push("-e");
9876
+ }
9877
+ switch (typeCheckLevel) {
9878
+ case "Off":
9879
+ extraArgs.push("-l", "0");
9880
+ break;
9881
+ case "Gradual":
9882
+ extraArgs.push("-l", "1");
9883
+ break;
9884
+ case "Informative":
9885
+ extraArgs.push("-l", "2");
9886
+ break;
9887
+ case "Strict":
9888
+ extraArgs.push("-l", "3");
9889
+ break;
9890
+ }
9891
+ if (product) {
9892
+ extraArgs.push("-d", testBuild || simulatorBuild !== false ? `${product}_sim` : product);
9893
+ }
9894
+ else if (testBuild) {
9895
+ throw new Error("Building for tests requires a device to build for!");
9896
+ }
9897
+ const exe = external_path_.resolve(sdk, "bin", external_sdk_util_cjs_namespaceObject.isWin ? "monkeyc.bat" : "monkeyc");
9898
+ const args = [
9899
+ ["-o", program],
9900
+ ["-f", jungleFiles],
9901
+ ["-y", developerKeyPath],
9902
+ extraArgs,
9903
+ ].flat();
9904
+ if (!returnCommand) {
9905
+ const handlers = [
9906
+ lineCallback || ((line) => console.log(line)),
9907
+ (line) => console.error(line),
9908
+ ];
9909
+ await (0,external_util_cjs_namespaceObject.spawnByLine)(exe, args, handlers, {
9910
+ cwd: workspace,
9911
+ });
9912
+ }
9913
+ return { exe, args, program: external_path_.resolve(workspace, program), product };
9899
9914
  }
9900
9915
 
9901
9916
  // EXTERNAL MODULE: ./node_modules/extract-zip/index.js
@@ -9904,123 +9919,112 @@ var extract_zip = __webpack_require__(2106);
9904
9919
  var xml2js = __webpack_require__(5055);
9905
9920
  ;// CONCATENATED MODULE: ./build/jungle.js
9906
9921
  function peg$subclass(u,A){function E(){this.constructor=u}E.prototype=A.prototype,u.prototype=new E}function peg$SyntaxError(u,A,E,C){var F=Error.call(this,u);return Object.setPrototypeOf&&Object.setPrototypeOf(F,peg$SyntaxError.prototype),F.expected=A,F.found=E,F.location=C,F.name="SyntaxError",F}function peg$padEnd(u,A,E){return E=E||" ",u.length>A?u:(A-=u.length,u+(E+=E.repeat(A)).slice(0,A))}function peg$parse(u,A){var E,C,F,t,B={},r=(A=void 0!==A?A:{}).grammarSource,e={Jungle:Su},D=Su,n=/^[\n\r\u2028\u2029]/,o=/^[a-z\xB5\xDF-\xF6\xF8-\xFF\u0101\u0103\u0105\u0107\u0109\u010B\u010D\u010F\u0111\u0113\u0115\u0117\u0119\u011B\u011D\u011F\u0121\u0123\u0125\u0127\u0129\u012B\u012D\u012F\u0131\u0133\u0135\u0137-\u0138\u013A\u013C\u013E\u0140\u0142\u0144\u0146\u0148-\u0149\u014B\u014D\u014F\u0151\u0153\u0155\u0157\u0159\u015B\u015D\u015F\u0161\u0163\u0165\u0167\u0169\u016B\u016D\u016F\u0171\u0173\u0175\u0177\u017A\u017C\u017E-\u0180\u0183\u0185\u0188\u018C-\u018D\u0192\u0195\u0199-\u019B\u019E\u01A1\u01A3\u01A5\u01A8\u01AA-\u01AB\u01AD\u01B0\u01B4\u01B6\u01B9-\u01BA\u01BD-\u01BF\u01C6\u01C9\u01CC\u01CE\u01D0\u01D2\u01D4\u01D6\u01D8\u01DA\u01DC-\u01DD\u01DF\u01E1\u01E3\u01E5\u01E7\u01E9\u01EB\u01ED\u01EF-\u01F0\u01F3\u01F5\u01F9\u01FB\u01FD\u01FF\u0201\u0203\u0205\u0207\u0209\u020B\u020D\u020F\u0211\u0213\u0215\u0217\u0219\u021B\u021D\u021F\u0221\u0223\u0225\u0227\u0229\u022B\u022D\u022F\u0231\u0233-\u0239\u023C\u023F-\u0240\u0242\u0247\u0249\u024B\u024D\u024F-\u0293\u0295-\u02AF\u0371\u0373\u0377\u037B-\u037D\u0390\u03AC-\u03CE\u03D0-\u03D1\u03D5-\u03D7\u03D9\u03DB\u03DD\u03DF\u03E1\u03E3\u03E5\u03E7\u03E9\u03EB\u03ED\u03EF-\u03F3\u03F5\u03F8\u03FB-\u03FC\u0430-\u045F\u0461\u0463\u0465\u0467\u0469\u046B\u046D\u046F\u0471\u0473\u0475\u0477\u0479\u047B\u047D\u047F\u0481\u048B\u048D\u048F\u0491\u0493\u0495\u0497\u0499\u049B\u049D\u049F\u04A1\u04A3\u04A5\u04A7\u04A9\u04AB\u04AD\u04AF\u04B1\u04B3\u04B5\u04B7\u04B9\u04BB\u04BD\u04BF\u04C2\u04C4\u04C6\u04C8\u04CA\u04CC\u04CE-\u04CF\u04D1\u04D3\u04D5\u04D7\u04D9\u04DB\u04DD\u04DF\u04E1\u04E3\u04E5\u04E7\u04E9\u04EB\u04ED\u04EF\u04F1\u04F3\u04F5\u04F7\u04F9\u04FB\u04FD\u04FF\u0501\u0503\u0505\u0507\u0509\u050B\u050D\u050F\u0511\u0513\u0515\u0517\u0519\u051B\u051D\u051F\u0521\u0523\u0525\u0527\u0529\u052B\u052D\u052F\u0560-\u0588\u10D0-\u10FA\u10FD-\u10FF\u13F8-\u13FD\u1C80-\u1C88\u1D00-\u1D2B\u1D6B-\u1D77\u1D79-\u1D9A\u1E01\u1E03\u1E05\u1E07\u1E09\u1E0B\u1E0D\u1E0F\u1E11\u1E13\u1E15\u1E17\u1E19\u1E1B\u1E1D\u1E1F\u1E21\u1E23\u1E25\u1E27\u1E29\u1E2B\u1E2D\u1E2F\u1E31\u1E33\u1E35\u1E37\u1E39\u1E3B\u1E3D\u1E3F\u1E41\u1E43\u1E45\u1E47\u1E49\u1E4B\u1E4D\u1E4F\u1E51\u1E53\u1E55\u1E57\u1E59\u1E5B\u1E5D\u1E5F\u1E61\u1E63\u1E65\u1E67\u1E69\u1E6B\u1E6D\u1E6F\u1E71\u1E73\u1E75\u1E77\u1E79\u1E7B\u1E7D\u1E7F\u1E81\u1E83\u1E85\u1E87\u1E89\u1E8B\u1E8D\u1E8F\u1E91\u1E93\u1E95-\u1E9D\u1E9F\u1EA1\u1EA3\u1EA5\u1EA7\u1EA9\u1EAB\u1EAD\u1EAF\u1EB1\u1EB3\u1EB5\u1EB7\u1EB9\u1EBB\u1EBD\u1EBF\u1EC1\u1EC3\u1EC5\u1EC7\u1EC9\u1ECB\u1ECD\u1ECF\u1ED1\u1ED3\u1ED5\u1ED7\u1ED9\u1EDB\u1EDD\u1EDF\u1EE1\u1EE3\u1EE5\u1EE7\u1EE9\u1EEB\u1EED\u1EEF\u1EF1\u1EF3\u1EF5\u1EF7\u1EF9\u1EFB\u1EFD\u1EFF-\u1F07\u1F10-\u1F15\u1F20-\u1F27\u1F30-\u1F37\u1F40-\u1F45\u1F50-\u1F57\u1F60-\u1F67\u1F70-\u1F7D\u1F80-\u1F87\u1F90-\u1F97\u1FA0-\u1FA7\u1FB0-\u1FB4\u1FB6-\u1FB7\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FC7\u1FD0-\u1FD3\u1FD6-\u1FD7\u1FE0-\u1FE7\u1FF2-\u1FF4\u1FF6-\u1FF7\u210A\u210E-\u210F\u2113\u212F\u2134\u2139\u213C-\u213D\u2146-\u2149\u214E\u2184\u2C30-\u2C5E\u2C61\u2C65-\u2C66\u2C68\u2C6A\u2C6C\u2C71\u2C73-\u2C74\u2C76-\u2C7B\u2C81\u2C83\u2C85\u2C87\u2C89\u2C8B\u2C8D\u2C8F\u2C91\u2C93\u2C95\u2C97\u2C99\u2C9B\u2C9D\u2C9F\u2CA1\u2CA3\u2CA5\u2CA7\u2CA9\u2CAB\u2CAD\u2CAF\u2CB1\u2CB3\u2CB5\u2CB7\u2CB9\u2CBB\u2CBD\u2CBF\u2CC1\u2CC3\u2CC5\u2CC7\u2CC9\u2CCB\u2CCD\u2CCF\u2CD1\u2CD3\u2CD5\u2CD7\u2CD9\u2CDB\u2CDD\u2CDF\u2CE1\u2CE3-\u2CE4\u2CEC\u2CEE\u2CF3\u2D00-\u2D25\u2D27\u2D2D\uA641\uA643\uA645\uA647\uA649\uA64B\uA64D\uA64F\uA651\uA653\uA655\uA657\uA659\uA65B\uA65D\uA65F\uA661\uA663\uA665\uA667\uA669\uA66B\uA66D\uA681\uA683\uA685\uA687\uA689\uA68B\uA68D\uA68F\uA691\uA693\uA695\uA697\uA699\uA69B\uA723\uA725\uA727\uA729\uA72B\uA72D\uA72F-\uA731\uA733\uA735\uA737\uA739\uA73B\uA73D\uA73F\uA741\uA743\uA745\uA747\uA749\uA74B\uA74D\uA74F\uA751\uA753\uA755\uA757\uA759\uA75B\uA75D\uA75F\uA761\uA763\uA765\uA767\uA769\uA76B\uA76D\uA76F\uA771-\uA778\uA77A\uA77C\uA77F\uA781\uA783\uA785\uA787\uA78C\uA78E\uA791\uA793-\uA795\uA797\uA799\uA79B\uA79D\uA79F\uA7A1\uA7A3\uA7A5\uA7A7\uA7A9\uA7AF\uA7B5\uA7B7\uA7B9\uA7FA\uAB30-\uAB5A\uAB60-\uAB65\uAB70-\uABBF\uFB00-\uFB06\uFB13-\uFB17\uFF41-\uFF5A]/,s=/^[\u02B0-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0374\u037A\u0559\u0640\u06E5-\u06E6\u07F4-\u07F5\u07FA\u081A\u0824\u0828\u0971\u0E46\u0EC6\u10FC\u17D7\u1843\u1AA7\u1C78-\u1C7D\u1D2C-\u1D6A\u1D78\u1D9B-\u1DBF\u2071\u207F\u2090-\u209C\u2C7C-\u2C7D\u2D6F\u2E2F\u3005\u3031-\u3035\u303B\u309D-\u309E\u30FC-\u30FE\uA015\uA4F8-\uA4FD\uA60C\uA67F\uA69C-\uA69D\uA717-\uA71F\uA770\uA788\uA7F8-\uA7F9\uA9CF\uA9E6\uAA70\uAADD\uAAF3-\uAAF4\uAB5C-\uAB5F\uFF70\uFF9E-\uFF9F]/,a=/^[\xAA\xBA\u01BB\u01C0-\u01C3\u0294\u05D0-\u05EA\u05EF-\u05F2\u0620-\u063F\u0641-\u064A\u066E-\u066F\u0671-\u06D3\u06D5\u06EE-\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u0800-\u0815\u0840-\u0858\u0860-\u086A\u08A0-\u08B4\u08B6-\u08BD\u0904-\u0939\u093D\u0950\u0958-\u0961\u0972-\u0980\u0985-\u098C\u098F-\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC-\u09DD\u09DF-\u09E1\u09F0-\u09F1\u09FC\u0A05-\u0A0A\u0A0F-\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32-\u0A33\u0A35-\u0A36\u0A38-\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2-\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0-\u0AE1\u0AF9\u0B05-\u0B0C\u0B0F-\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32-\u0B33\u0B35-\u0B39\u0B3D\u0B5C-\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99-\u0B9A\u0B9C\u0B9E-\u0B9F\u0BA3-\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58-\u0C5A\u0C60-\u0C61\u0C80\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0-\u0CE1\u0CF1-\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D54-\u0D56\u0D5F-\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32-\u0E33\u0E40-\u0E45\u0E81-\u0E82\u0E84\u0E87-\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA-\u0EAB\u0EAD-\u0EB0\u0EB2-\u0EB3\u0EBD\u0EC0-\u0EC4\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065-\u1066\u106E-\u1070\u1075-\u1081\u108E\u1100-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16F1-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17DC\u1820-\u1842\u1844-\u1878\u1880-\u1884\u1887-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u1A00-\u1A16\u1A20-\u1A54\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE-\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C77\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5-\u1CF6\u2135-\u2138\u2D30-\u2D67\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u3006\u303C\u3041-\u3096\u309F\u30A1-\u30FA\u30FF\u3105-\u312F\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FEF\uA000-\uA014\uA016-\uA48C\uA4D0-\uA4F7\uA500-\uA60B\uA610-\uA61F\uA62A-\uA62B\uA66E\uA6A0-\uA6E5\uA78F\uA7F7\uA7FB-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA8FD-\uA8FE\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9E0-\uA9E4\uA9E7-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA6F\uAA71-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5-\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADC\uAAE0-\uAAEA\uAAF2\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40-\uFB41\uFB43-\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF66-\uFF6F\uFF71-\uFF9D\uFFA0-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]/,c=/^[\u01C5\u01C8\u01CB\u01F2\u1F88-\u1F8F\u1F98-\u1F9F\u1FA8-\u1FAF\u1FBC\u1FCC\u1FFC]/,l=/^[A-Z\xC0-\xD6\xD8-\xDE\u0100\u0102\u0104\u0106\u0108\u010A\u010C\u010E\u0110\u0112\u0114\u0116\u0118\u011A\u011C\u011E\u0120\u0122\u0124\u0126\u0128\u012A\u012C\u012E\u0130\u0132\u0134\u0136\u0139\u013B\u013D\u013F\u0141\u0143\u0145\u0147\u014A\u014C\u014E\u0150\u0152\u0154\u0156\u0158\u015A\u015C\u015E\u0160\u0162\u0164\u0166\u0168\u016A\u016C\u016E\u0170\u0172\u0174\u0176\u0178-\u0179\u017B\u017D\u0181-\u0182\u0184\u0186-\u0187\u0189-\u018B\u018E-\u0191\u0193-\u0194\u0196-\u0198\u019C-\u019D\u019F-\u01A0\u01A2\u01A4\u01A6-\u01A7\u01A9\u01AC\u01AE-\u01AF\u01B1-\u01B3\u01B5\u01B7-\u01B8\u01BC\u01C4\u01C7\u01CA\u01CD\u01CF\u01D1\u01D3\u01D5\u01D7\u01D9\u01DB\u01DE\u01E0\u01E2\u01E4\u01E6\u01E8\u01EA\u01EC\u01EE\u01F1\u01F4\u01F6-\u01F8\u01FA\u01FC\u01FE\u0200\u0202\u0204\u0206\u0208\u020A\u020C\u020E\u0210\u0212\u0214\u0216\u0218\u021A\u021C\u021E\u0220\u0222\u0224\u0226\u0228\u022A\u022C\u022E\u0230\u0232\u023A-\u023B\u023D-\u023E\u0241\u0243-\u0246\u0248\u024A\u024C\u024E\u0370\u0372\u0376\u037F\u0386\u0388-\u038A\u038C\u038E-\u038F\u0391-\u03A1\u03A3-\u03AB\u03CF\u03D2-\u03D4\u03D8\u03DA\u03DC\u03DE\u03E0\u03E2\u03E4\u03E6\u03E8\u03EA\u03EC\u03EE\u03F4\u03F7\u03F9-\u03FA\u03FD-\u042F\u0460\u0462\u0464\u0466\u0468\u046A\u046C\u046E\u0470\u0472\u0474\u0476\u0478\u047A\u047C\u047E\u0480\u048A\u048C\u048E\u0490\u0492\u0494\u0496\u0498\u049A\u049C\u049E\u04A0\u04A2\u04A4\u04A6\u04A8\u04AA\u04AC\u04AE\u04B0\u04B2\u04B4\u04B6\u04B8\u04BA\u04BC\u04BE\u04C0-\u04C1\u04C3\u04C5\u04C7\u04C9\u04CB\u04CD\u04D0\u04D2\u04D4\u04D6\u04D8\u04DA\u04DC\u04DE\u04E0\u04E2\u04E4\u04E6\u04E8\u04EA\u04EC\u04EE\u04F0\u04F2\u04F4\u04F6\u04F8\u04FA\u04FC\u04FE\u0500\u0502\u0504\u0506\u0508\u050A\u050C\u050E\u0510\u0512\u0514\u0516\u0518\u051A\u051C\u051E\u0520\u0522\u0524\u0526\u0528\u052A\u052C\u052E\u0531-\u0556\u10A0-\u10C5\u10C7\u10CD\u13A0-\u13F5\u1C90-\u1CBA\u1CBD-\u1CBF\u1E00\u1E02\u1E04\u1E06\u1E08\u1E0A\u1E0C\u1E0E\u1E10\u1E12\u1E14\u1E16\u1E18\u1E1A\u1E1C\u1E1E\u1E20\u1E22\u1E24\u1E26\u1E28\u1E2A\u1E2C\u1E2E\u1E30\u1E32\u1E34\u1E36\u1E38\u1E3A\u1E3C\u1E3E\u1E40\u1E42\u1E44\u1E46\u1E48\u1E4A\u1E4C\u1E4E\u1E50\u1E52\u1E54\u1E56\u1E58\u1E5A\u1E5C\u1E5E\u1E60\u1E62\u1E64\u1E66\u1E68\u1E6A\u1E6C\u1E6E\u1E70\u1E72\u1E74\u1E76\u1E78\u1E7A\u1E7C\u1E7E\u1E80\u1E82\u1E84\u1E86\u1E88\u1E8A\u1E8C\u1E8E\u1E90\u1E92\u1E94\u1E9E\u1EA0\u1EA2\u1EA4\u1EA6\u1EA8\u1EAA\u1EAC\u1EAE\u1EB0\u1EB2\u1EB4\u1EB6\u1EB8\u1EBA\u1EBC\u1EBE\u1EC0\u1EC2\u1EC4\u1EC6\u1EC8\u1ECA\u1ECC\u1ECE\u1ED0\u1ED2\u1ED4\u1ED6\u1ED8\u1EDA\u1EDC\u1EDE\u1EE0\u1EE2\u1EE4\u1EE6\u1EE8\u1EEA\u1EEC\u1EEE\u1EF0\u1EF2\u1EF4\u1EF6\u1EF8\u1EFA\u1EFC\u1EFE\u1F08-\u1F0F\u1F18-\u1F1D\u1F28-\u1F2F\u1F38-\u1F3F\u1F48-\u1F4D\u1F59\u1F5B\u1F5D\u1F5F\u1F68-\u1F6F\u1FB8-\u1FBB\u1FC8-\u1FCB\u1FD8-\u1FDB\u1FE8-\u1FEC\u1FF8-\u1FFB\u2102\u2107\u210B-\u210D\u2110-\u2112\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u2130-\u2133\u213E-\u213F\u2145\u2183\u2C00-\u2C2E\u2C60\u2C62-\u2C64\u2C67\u2C69\u2C6B\u2C6D-\u2C70\u2C72\u2C75\u2C7E-\u2C80\u2C82\u2C84\u2C86\u2C88\u2C8A\u2C8C\u2C8E\u2C90\u2C92\u2C94\u2C96\u2C98\u2C9A\u2C9C\u2C9E\u2CA0\u2CA2\u2CA4\u2CA6\u2CA8\u2CAA\u2CAC\u2CAE\u2CB0\u2CB2\u2CB4\u2CB6\u2CB8\u2CBA\u2CBC\u2CBE\u2CC0\u2CC2\u2CC4\u2CC6\u2CC8\u2CCA\u2CCC\u2CCE\u2CD0\u2CD2\u2CD4\u2CD6\u2CD8\u2CDA\u2CDC\u2CDE\u2CE0\u2CE2\u2CEB\u2CED\u2CF2\uA640\uA642\uA644\uA646\uA648\uA64A\uA64C\uA64E\uA650\uA652\uA654\uA656\uA658\uA65A\uA65C\uA65E\uA660\uA662\uA664\uA666\uA668\uA66A\uA66C\uA680\uA682\uA684\uA686\uA688\uA68A\uA68C\uA68E\uA690\uA692\uA694\uA696\uA698\uA69A\uA722\uA724\uA726\uA728\uA72A\uA72C\uA72E\uA732\uA734\uA736\uA738\uA73A\uA73C\uA73E\uA740\uA742\uA744\uA746\uA748\uA74A\uA74C\uA74E\uA750\uA752\uA754\uA756\uA758\uA75A\uA75C\uA75E\uA760\uA762\uA764\uA766\uA768\uA76A\uA76C\uA76E\uA779\uA77B\uA77D-\uA77E\uA780\uA782\uA784\uA786\uA78B\uA78D\uA790\uA792\uA796\uA798\uA79A\uA79C\uA79E\uA7A0\uA7A2\uA7A4\uA7A6\uA7A8\uA7AA-\uA7AE\uA7B0-\uA7B4\uA7B6\uA7B8\uFF21-\uFF3A]/,i=/^[\u0903\u093B\u093E-\u0940\u0949-\u094C\u094E-\u094F\u0982-\u0983\u09BE-\u09C0\u09C7-\u09C8\u09CB-\u09CC\u09D7\u0A03\u0A3E-\u0A40\u0A83\u0ABE-\u0AC0\u0AC9\u0ACB-\u0ACC\u0B02-\u0B03\u0B3E\u0B40\u0B47-\u0B48\u0B4B-\u0B4C\u0B57\u0BBE-\u0BBF\u0BC1-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCC\u0BD7\u0C01-\u0C03\u0C41-\u0C44\u0C82-\u0C83\u0CBE\u0CC0-\u0CC4\u0CC7-\u0CC8\u0CCA-\u0CCB\u0CD5-\u0CD6\u0D02-\u0D03\u0D3E-\u0D40\u0D46-\u0D48\u0D4A-\u0D4C\u0D57\u0D82-\u0D83\u0DCF-\u0DD1\u0DD8-\u0DDF\u0DF2-\u0DF3\u0F3E-\u0F3F\u0F7F\u102B-\u102C\u1031\u1038\u103B-\u103C\u1056-\u1057\u1062-\u1064\u1067-\u106D\u1083-\u1084\u1087-\u108C\u108F\u109A-\u109C\u17B6\u17BE-\u17C5\u17C7-\u17C8\u1923-\u1926\u1929-\u192B\u1930-\u1931\u1933-\u1938\u1A19-\u1A1A\u1A55\u1A57\u1A61\u1A63-\u1A64\u1A6D-\u1A72\u1B04\u1B35\u1B3B\u1B3D-\u1B41\u1B43-\u1B44\u1B82\u1BA1\u1BA6-\u1BA7\u1BAA\u1BE7\u1BEA-\u1BEC\u1BEE\u1BF2-\u1BF3\u1C24-\u1C2B\u1C34-\u1C35\u1CE1\u1CF2-\u1CF3\u1CF7\u302E-\u302F\uA823-\uA824\uA827\uA880-\uA881\uA8B4-\uA8C3\uA952-\uA953\uA983\uA9B4-\uA9B5\uA9BA-\uA9BB\uA9BD-\uA9C0\uAA2F-\uAA30\uAA33-\uAA34\uAA4D\uAA7B\uAA7D\uAAEB\uAAEE-\uAAEF\uAAF5\uABE3-\uABE4\uABE6-\uABE7\uABE9-\uABEA\uABEC]/,f=/^[\u0300-\u036F\u0483-\u0487\u0591-\u05BD\u05BF\u05C1-\u05C2\u05C4-\u05C5\u05C7\u0610-\u061A\u064B-\u065F\u0670\u06D6-\u06DC\u06DF-\u06E4\u06E7-\u06E8\u06EA-\u06ED\u0711\u0730-\u074A\u07A6-\u07B0\u07EB-\u07F3\u07FD\u0816-\u0819\u081B-\u0823\u0825-\u0827\u0829-\u082D\u0859-\u085B\u08D3-\u08E1\u08E3-\u0902\u093A\u093C\u0941-\u0948\u094D\u0951-\u0957\u0962-\u0963\u0981\u09BC\u09C1-\u09C4\u09CD\u09E2-\u09E3\u09FE\u0A01-\u0A02\u0A3C\u0A41-\u0A42\u0A47-\u0A48\u0A4B-\u0A4D\u0A51\u0A70-\u0A71\u0A75\u0A81-\u0A82\u0ABC\u0AC1-\u0AC5\u0AC7-\u0AC8\u0ACD\u0AE2-\u0AE3\u0AFA-\u0AFF\u0B01\u0B3C\u0B3F\u0B41-\u0B44\u0B4D\u0B56\u0B62-\u0B63\u0B82\u0BC0\u0BCD\u0C00\u0C04\u0C3E-\u0C40\u0C46-\u0C48\u0C4A-\u0C4D\u0C55-\u0C56\u0C62-\u0C63\u0C81\u0CBC\u0CBF\u0CC6\u0CCC-\u0CCD\u0CE2-\u0CE3\u0D00-\u0D01\u0D3B-\u0D3C\u0D41-\u0D44\u0D4D\u0D62-\u0D63\u0DCA\u0DD2-\u0DD4\u0DD6\u0E31\u0E34-\u0E3A\u0E47-\u0E4E\u0EB1\u0EB4-\u0EB9\u0EBB-\u0EBC\u0EC8-\u0ECD\u0F18-\u0F19\u0F35\u0F37\u0F39\u0F71-\u0F7E\u0F80-\u0F84\u0F86-\u0F87\u0F8D-\u0F97\u0F99-\u0FBC\u0FC6\u102D-\u1030\u1032-\u1037\u1039-\u103A\u103D-\u103E\u1058-\u1059\u105E-\u1060\u1071-\u1074\u1082\u1085-\u1086\u108D\u109D\u135D-\u135F\u1712-\u1714\u1732-\u1734\u1752-\u1753\u1772-\u1773\u17B4-\u17B5\u17B7-\u17BD\u17C6\u17C9-\u17D3\u17DD\u180B-\u180D\u1885-\u1886\u18A9\u1920-\u1922\u1927-\u1928\u1932\u1939-\u193B\u1A17-\u1A18\u1A1B\u1A56\u1A58-\u1A5E\u1A60\u1A62\u1A65-\u1A6C\u1A73-\u1A7C\u1A7F\u1AB0-\u1ABD\u1B00-\u1B03\u1B34\u1B36-\u1B3A\u1B3C\u1B42\u1B6B-\u1B73\u1B80-\u1B81\u1BA2-\u1BA5\u1BA8-\u1BA9\u1BAB-\u1BAD\u1BE6\u1BE8-\u1BE9\u1BED\u1BEF-\u1BF1\u1C2C-\u1C33\u1C36-\u1C37\u1CD0-\u1CD2\u1CD4-\u1CE0\u1CE2-\u1CE8\u1CED\u1CF4\u1CF8-\u1CF9\u1DC0-\u1DF9\u1DFB-\u1DFF\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2CEF-\u2CF1\u2D7F\u2DE0-\u2DFF\u302A-\u302D\u3099-\u309A\uA66F\uA674-\uA67D\uA69E-\uA69F\uA6F0-\uA6F1\uA802\uA806\uA80B\uA825-\uA826\uA8C4-\uA8C5\uA8E0-\uA8F1\uA8FF\uA926-\uA92D\uA947-\uA951\uA980-\uA982\uA9B3\uA9B6-\uA9B9\uA9BC\uA9E5\uAA29-\uAA2E\uAA31-\uAA32\uAA35-\uAA36\uAA43\uAA4C\uAA7C\uAAB0\uAAB2-\uAAB4\uAAB7-\uAAB8\uAABE-\uAABF\uAAC1\uAAEC-\uAAED\uAAF6\uABE5\uABE8\uABED\uFB1E\uFE00-\uFE0F\uFE20-\uFE2F]/,h=/^[0-9\u0660-\u0669\u06F0-\u06F9\u07C0-\u07C9\u0966-\u096F\u09E6-\u09EF\u0A66-\u0A6F\u0AE6-\u0AEF\u0B66-\u0B6F\u0BE6-\u0BEF\u0C66-\u0C6F\u0CE6-\u0CEF\u0D66-\u0D6F\u0DE6-\u0DEF\u0E50-\u0E59\u0ED0-\u0ED9\u0F20-\u0F29\u1040-\u1049\u1090-\u1099\u17E0-\u17E9\u1810-\u1819\u1946-\u194F\u19D0-\u19D9\u1A80-\u1A89\u1A90-\u1A99\u1B50-\u1B59\u1BB0-\u1BB9\u1C40-\u1C49\u1C50-\u1C59\uA620-\uA629\uA8D0-\uA8D9\uA900-\uA909\uA9D0-\uA9D9\uA9F0-\uA9F9\uAA50-\uAA59\uABF0-\uABF9\uFF10-\uFF19]/,x=/^[\u16EE-\u16F0\u2160-\u2182\u2185-\u2188\u3007\u3021-\u3029\u3038-\u303A\uA6E6-\uA6EF]/,p=/^[_\u203F-\u2040\u2054\uFE33-\uFE34\uFE4D-\uFE4F\uFF3F]/,d=/^[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/,P={type:"any"},g=Pu("=",!1),v=Pu(".",!1),y=Pu(";",!1),m=Pu("$(",!1),$=Pu(")",!1),S=vu("raw string"),b=vu("quoted string"),w=Pu('"',!1),j=Pu("[",!1),O=Pu("]",!1),R=Pu(" ",!1),_=Pu("\t",!1),L=Pu("\\",!1),z=vu("identifier"),M=Pu("_",!1),Z=Pu("$",!1),k=Pu("-",!1),q=Pu("‌",!1),J=Pu("‍",!1),N=Pu("/",!1),Q=Pu("*",!1),U=vu("whitespace"),G=Pu("\v",!1),H=Pu("\f",!1),I=Pu(" ",!1),K=Pu("\ufeff",!1),T=gu(["\n","\r","\u2028","\u2029"],!1,!1),V=vu("end of line"),W=Pu("\n",!1),X=Pu("\r\n",!1),Y=Pu("\r",!1),uu=Pu("\u2028",!1),Au=Pu("\u2029",!1),Eu=vu("comment"),Cu=Pu("#",!1),Fu=gu([["a","z"],"µ",["ß","ö"],["ø","ÿ"],"ā","ă","ą","ć","ĉ","ċ","č","ď","đ","ē","ĕ","ė","ę","ě","ĝ","ğ","ġ","ģ","ĥ","ħ","ĩ","ī","ĭ","į","ı","ij","ĵ",["ķ","ĸ"],"ĺ","ļ","ľ","ŀ","ł","ń","ņ",["ň","ʼn"],"ŋ","ō","ŏ","ő","œ","ŕ","ŗ","ř","ś","ŝ","ş","š","ţ","ť","ŧ","ũ","ū","ŭ","ů","ű","ų","ŵ","ŷ","ź","ż",["ž","ƀ"],"ƃ","ƅ","ƈ",["ƌ","ƍ"],"ƒ","ƕ",["ƙ","ƛ"],"ƞ","ơ","ƣ","ƥ","ƨ",["ƪ","ƫ"],"ƭ","ư","ƴ","ƶ",["ƹ","ƺ"],["ƽ","ƿ"],"dž","lj","nj","ǎ","ǐ","ǒ","ǔ","ǖ","ǘ","ǚ",["ǜ","ǝ"],"ǟ","ǡ","ǣ","ǥ","ǧ","ǩ","ǫ","ǭ",["ǯ","ǰ"],"dz","ǵ","ǹ","ǻ","ǽ","ǿ","ȁ","ȃ","ȅ","ȇ","ȉ","ȋ","ȍ","ȏ","ȑ","ȓ","ȕ","ȗ","ș","ț","ȝ","ȟ","ȡ","ȣ","ȥ","ȧ","ȩ","ȫ","ȭ","ȯ","ȱ",["ȳ","ȹ"],"ȼ",["ȿ","ɀ"],"ɂ","ɇ","ɉ","ɋ","ɍ",["ɏ","ʓ"],["ʕ","ʯ"],"ͱ","ͳ","ͷ",["ͻ","ͽ"],"ΐ",["ά","ώ"],["ϐ","ϑ"],["ϕ","ϗ"],"ϙ","ϛ","ϝ","ϟ","ϡ","ϣ","ϥ","ϧ","ϩ","ϫ","ϭ",["ϯ","ϳ"],"ϵ","ϸ",["ϻ","ϼ"],["а","џ"],"ѡ","ѣ","ѥ","ѧ","ѩ","ѫ","ѭ","ѯ","ѱ","ѳ","ѵ","ѷ","ѹ","ѻ","ѽ","ѿ","ҁ","ҋ","ҍ","ҏ","ґ","ғ","ҕ","җ","ҙ","қ","ҝ","ҟ","ҡ","ң","ҥ","ҧ","ҩ","ҫ","ҭ","ү","ұ","ҳ","ҵ","ҷ","ҹ","һ","ҽ","ҿ","ӂ","ӄ","ӆ","ӈ","ӊ","ӌ",["ӎ","ӏ"],"ӑ","ӓ","ӕ","ӗ","ә","ӛ","ӝ","ӟ","ӡ","ӣ","ӥ","ӧ","ө","ӫ","ӭ","ӯ","ӱ","ӳ","ӵ","ӷ","ӹ","ӻ","ӽ","ӿ","ԁ","ԃ","ԅ","ԇ","ԉ","ԋ","ԍ","ԏ","ԑ","ԓ","ԕ","ԗ","ԙ","ԛ","ԝ","ԟ","ԡ","ԣ","ԥ","ԧ","ԩ","ԫ","ԭ","ԯ",["ՠ","ֈ"],["ა","ჺ"],["ჽ","ჿ"],["ᏸ","ᏽ"],["ᲀ","ᲈ"],["ᴀ","ᴫ"],["ᵫ","ᵷ"],["ᵹ","ᶚ"],"ḁ","ḃ","ḅ","ḇ","ḉ","ḋ","ḍ","ḏ","ḑ","ḓ","ḕ","ḗ","ḙ","ḛ","ḝ","ḟ","ḡ","ḣ","ḥ","ḧ","ḩ","ḫ","ḭ","ḯ","ḱ","ḳ","ḵ","ḷ","ḹ","ḻ","ḽ","ḿ","ṁ","ṃ","ṅ","ṇ","ṉ","ṋ","ṍ","ṏ","ṑ","ṓ","ṕ","ṗ","ṙ","ṛ","ṝ","ṟ","ṡ","ṣ","ṥ","ṧ","ṩ","ṫ","ṭ","ṯ","ṱ","ṳ","ṵ","ṷ","ṹ","ṻ","ṽ","ṿ","ẁ","ẃ","ẅ","ẇ","ẉ","ẋ","ẍ","ẏ","ẑ","ẓ",["ẕ","ẝ"],"ẟ","ạ","ả","ấ","ầ","ẩ","ẫ","ậ","ắ","ằ","ẳ","ẵ","ặ","ẹ","ẻ","ẽ","ế","ề","ể","ễ","ệ","ỉ","ị","ọ","ỏ","ố","ồ","ổ","ỗ","ộ","ớ","ờ","ở","ỡ","ợ","ụ","ủ","ứ","ừ","ử","ữ","ự","ỳ","ỵ","ỷ","ỹ","ỻ","ỽ",["ỿ","ἇ"],["ἐ","ἕ"],["ἠ","ἧ"],["ἰ","ἷ"],["ὀ","ὅ"],["ὐ","ὗ"],["ὠ","ὧ"],["ὰ","ώ"],["ᾀ","ᾇ"],["ᾐ","ᾗ"],["ᾠ","ᾧ"],["ᾰ","ᾴ"],["ᾶ","ᾷ"],"ι",["ῂ","ῄ"],["ῆ","ῇ"],["ῐ","ΐ"],["ῖ","ῗ"],["ῠ","ῧ"],["ῲ","ῴ"],["ῶ","ῷ"],"ℊ",["ℎ","ℏ"],"ℓ","ℯ","ℴ","ℹ",["ℼ","ℽ"],["ⅆ","ⅉ"],"ⅎ","ↄ",["ⰰ","ⱞ"],"ⱡ",["ⱥ","ⱦ"],"ⱨ","ⱪ","ⱬ","ⱱ",["ⱳ","ⱴ"],["ⱶ","ⱻ"],"ⲁ","ⲃ","ⲅ","ⲇ","ⲉ","ⲋ","ⲍ","ⲏ","ⲑ","ⲓ","ⲕ","ⲗ","ⲙ","ⲛ","ⲝ","ⲟ","ⲡ","ⲣ","ⲥ","ⲧ","ⲩ","ⲫ","ⲭ","ⲯ","ⲱ","ⲳ","ⲵ","ⲷ","ⲹ","ⲻ","ⲽ","ⲿ","ⳁ","ⳃ","ⳅ","ⳇ","ⳉ","ⳋ","ⳍ","ⳏ","ⳑ","ⳓ","ⳕ","ⳗ","ⳙ","ⳛ","ⳝ","ⳟ","ⳡ",["ⳣ","ⳤ"],"ⳬ","ⳮ","ⳳ",["ⴀ","ⴥ"],"ⴧ","ⴭ","ꙁ","ꙃ","ꙅ","ꙇ","ꙉ","ꙋ","ꙍ","ꙏ","ꙑ","ꙓ","ꙕ","ꙗ","ꙙ","ꙛ","ꙝ","ꙟ","ꙡ","ꙣ","ꙥ","ꙧ","ꙩ","ꙫ","ꙭ","ꚁ","ꚃ","ꚅ","ꚇ","ꚉ","ꚋ","ꚍ","ꚏ","ꚑ","ꚓ","ꚕ","ꚗ","ꚙ","ꚛ","ꜣ","ꜥ","ꜧ","ꜩ","ꜫ","ꜭ",["ꜯ","ꜱ"],"ꜳ","ꜵ","ꜷ","ꜹ","ꜻ","ꜽ","ꜿ","ꝁ","ꝃ","ꝅ","ꝇ","ꝉ","ꝋ","ꝍ","ꝏ","ꝑ","ꝓ","ꝕ","ꝗ","ꝙ","ꝛ","ꝝ","ꝟ","ꝡ","ꝣ","ꝥ","ꝧ","ꝩ","ꝫ","ꝭ","ꝯ",["ꝱ","ꝸ"],"ꝺ","ꝼ","ꝿ","ꞁ","ꞃ","ꞅ","ꞇ","ꞌ","ꞎ","ꞑ",["ꞓ","ꞕ"],"ꞗ","ꞙ","ꞛ","ꞝ","ꞟ","ꞡ","ꞣ","ꞥ","ꞧ","ꞩ","ꞯ","ꞵ","ꞷ","ꞹ","ꟺ",["ꬰ","ꭚ"],["ꭠ","ꭥ"],["ꭰ","ꮿ"],["ff","st"],["ﬓ","ﬗ"],["a","z"]],!1,!1),tu=gu([["ʰ","ˁ"],["ˆ","ˑ"],["ˠ","ˤ"],"ˬ","ˮ","ʹ","ͺ","ՙ","ـ",["ۥ","ۦ"],["ߴ","ߵ"],"ߺ","ࠚ","ࠤ","ࠨ","ॱ","ๆ","ໆ","ჼ","ៗ","ᡃ","ᪧ",["ᱸ","ᱽ"],["ᴬ","ᵪ"],"ᵸ",["ᶛ","ᶿ"],"ⁱ","ⁿ",["ₐ","ₜ"],["ⱼ","ⱽ"],"ⵯ","ⸯ","々",["〱","〵"],"〻",["ゝ","ゞ"],["ー","ヾ"],"ꀕ",["ꓸ","ꓽ"],"ꘌ","ꙿ",["ꚜ","ꚝ"],["ꜗ","ꜟ"],"ꝰ","ꞈ",["ꟸ","ꟹ"],"ꧏ","ꧦ","ꩰ","ꫝ",["ꫳ","ꫴ"],["ꭜ","ꭟ"],"ー",["゙","゚"]],!1,!1),Bu=gu(["ª","º","ƻ",["ǀ","ǃ"],"ʔ",["א","ת"],["ׯ","ײ"],["ؠ","ؿ"],["ف","ي"],["ٮ","ٯ"],["ٱ","ۓ"],"ە",["ۮ","ۯ"],["ۺ","ۼ"],"ۿ","ܐ",["ܒ","ܯ"],["ݍ","ޥ"],"ޱ",["ߊ","ߪ"],["ࠀ","ࠕ"],["ࡀ","ࡘ"],["ࡠ","ࡪ"],["ࢠ","ࢴ"],["ࢶ","ࢽ"],["ऄ","ह"],"ऽ","ॐ",["क़","ॡ"],["ॲ","ঀ"],["অ","ঌ"],["এ","ঐ"],["ও","ন"],["প","র"],"ল",["শ","হ"],"ঽ","ৎ",["ড়","ঢ়"],["য়","ৡ"],["ৰ","ৱ"],"ৼ",["ਅ","ਊ"],["ਏ","ਐ"],["ਓ","ਨ"],["ਪ","ਰ"],["ਲ","ਲ਼"],["ਵ","ਸ਼"],["ਸ","ਹ"],["ਖ਼","ੜ"],"ਫ਼",["ੲ","ੴ"],["અ","ઍ"],["એ","ઑ"],["ઓ","ન"],["પ","ર"],["લ","ળ"],["વ","હ"],"ઽ","ૐ",["ૠ","ૡ"],"ૹ",["ଅ","ଌ"],["ଏ","ଐ"],["ଓ","ନ"],["ପ","ର"],["ଲ","ଳ"],["ଵ","ହ"],"ଽ",["ଡ଼","ଢ଼"],["ୟ","ୡ"],"ୱ","ஃ",["அ","ஊ"],["எ","ஐ"],["ஒ","க"],["ங","ச"],"ஜ",["ஞ","ட"],["ண","த"],["ந","ப"],["ம","ஹ"],"ௐ",["అ","ఌ"],["ఎ","ఐ"],["ఒ","న"],["ప","హ"],"ఽ",["ౘ","ౚ"],["ౠ","ౡ"],"ಀ",["ಅ","ಌ"],["ಎ","ಐ"],["ಒ","ನ"],["ಪ","ಳ"],["ವ","ಹ"],"ಽ","ೞ",["ೠ","ೡ"],["ೱ","ೲ"],["അ","ഌ"],["എ","ഐ"],["ഒ","ഺ"],"ഽ","ൎ",["ൔ","ൖ"],["ൟ","ൡ"],["ൺ","ൿ"],["අ","ඖ"],["ක","න"],["ඳ","ර"],"ල",["ව","ෆ"],["ก","ะ"],["า","ำ"],["เ","ๅ"],["ກ","ຂ"],"ຄ",["ງ","ຈ"],"ຊ","ຍ",["ດ","ທ"],["ນ","ຟ"],["ມ","ຣ"],"ລ","ວ",["ສ","ຫ"],["ອ","ະ"],["າ","ຳ"],"ຽ",["ເ","ໄ"],["ໜ","ໟ"],"ༀ",["ཀ","ཇ"],["ཉ","ཬ"],["ྈ","ྌ"],["က","ဪ"],"ဿ",["ၐ","ၕ"],["ၚ","ၝ"],"ၡ",["ၥ","ၦ"],["ၮ","ၰ"],["ၵ","ႁ"],"ႎ",["ᄀ","ቈ"],["ቊ","ቍ"],["ቐ","ቖ"],"ቘ",["ቚ","ቝ"],["በ","ኈ"],["ኊ","ኍ"],["ነ","ኰ"],["ኲ","ኵ"],["ኸ","ኾ"],"ዀ",["ዂ","ዅ"],["ወ","ዖ"],["ዘ","ጐ"],["ጒ","ጕ"],["ጘ","ፚ"],["ᎀ","ᎏ"],["ᐁ","ᙬ"],["ᙯ","ᙿ"],["ᚁ","ᚚ"],["ᚠ","ᛪ"],["ᛱ","ᛸ"],["ᜀ","ᜌ"],["ᜎ","ᜑ"],["ᜠ","ᜱ"],["ᝀ","ᝑ"],["ᝠ","ᝬ"],["ᝮ","ᝰ"],["ក","ឳ"],"ៜ",["ᠠ","ᡂ"],["ᡄ","ᡸ"],["ᢀ","ᢄ"],["ᢇ","ᢨ"],"ᢪ",["ᢰ","ᣵ"],["ᤀ","ᤞ"],["ᥐ","ᥭ"],["ᥰ","ᥴ"],["ᦀ","ᦫ"],["ᦰ","ᧉ"],["ᨀ","ᨖ"],["ᨠ","ᩔ"],["ᬅ","ᬳ"],["ᭅ","ᭋ"],["ᮃ","ᮠ"],["ᮮ","ᮯ"],["ᮺ","ᯥ"],["ᰀ","ᰣ"],["ᱍ","ᱏ"],["ᱚ","ᱷ"],["ᳩ","ᳬ"],["ᳮ","ᳱ"],["ᳵ","ᳶ"],["ℵ","ℸ"],["ⴰ","ⵧ"],["ⶀ","ⶖ"],["ⶠ","ⶦ"],["ⶨ","ⶮ"],["ⶰ","ⶶ"],["ⶸ","ⶾ"],["ⷀ","ⷆ"],["ⷈ","ⷎ"],["ⷐ","ⷖ"],["ⷘ","ⷞ"],"〆","〼",["ぁ","ゖ"],"ゟ",["ァ","ヺ"],"ヿ",["ㄅ","ㄯ"],["ㄱ","ㆎ"],["ㆠ","ㆺ"],["ㇰ","ㇿ"],["㐀","䶵"],["一","鿯"],["ꀀ","ꀔ"],["ꀖ","ꒌ"],["ꓐ","ꓷ"],["ꔀ","ꘋ"],["ꘐ","ꘟ"],["ꘪ","ꘫ"],"ꙮ",["ꚠ","ꛥ"],"ꞏ","ꟷ",["ꟻ","ꠁ"],["ꠃ","ꠅ"],["ꠇ","ꠊ"],["ꠌ","ꠢ"],["ꡀ","ꡳ"],["ꢂ","ꢳ"],["ꣲ","ꣷ"],"ꣻ",["ꣽ","ꣾ"],["ꤊ","ꤥ"],["ꤰ","ꥆ"],["ꥠ","ꥼ"],["ꦄ","ꦲ"],["ꧠ","ꧤ"],["ꧧ","ꧯ"],["ꧺ","ꧾ"],["ꨀ","ꨨ"],["ꩀ","ꩂ"],["ꩄ","ꩋ"],["ꩠ","ꩯ"],["ꩱ","ꩶ"],"ꩺ",["ꩾ","ꪯ"],"ꪱ",["ꪵ","ꪶ"],["ꪹ","ꪽ"],"ꫀ","ꫂ",["ꫛ","ꫜ"],["ꫠ","ꫪ"],"ꫲ",["ꬁ","ꬆ"],["ꬉ","ꬎ"],["ꬑ","ꬖ"],["ꬠ","ꬦ"],["ꬨ","ꬮ"],["ꯀ","ꯢ"],["가","힣"],["ힰ","ퟆ"],["ퟋ","ퟻ"],["豈","舘"],["並","龎"],"יִ",["ײַ","ﬨ"],["שׁ","זּ"],["טּ","לּ"],"מּ",["נּ","סּ"],["ףּ","פּ"],["צּ","ﮱ"],["ﯓ","ﴽ"],["ﵐ","ﶏ"],["ﶒ","ﷇ"],["ﷰ","ﷻ"],["ﹰ","ﹴ"],["ﹶ","ﻼ"],["ヲ","ッ"],["ア","ン"],["ᅠ","ᄒ"],["ᅡ","ᅦ"],["ᅧ","ᅬ"],["ᅭ","ᅲ"],["ᅳ","ᅵ"]],!1,!1),ru=gu(["Dž","Lj","Nj","Dz",["ᾈ","ᾏ"],["ᾘ","ᾟ"],["ᾨ","ᾯ"],"ᾼ","ῌ","ῼ"],!1,!1),eu=gu([["A","Z"],["À","Ö"],["Ø","Þ"],"Ā","Ă","Ą","Ć","Ĉ","Ċ","Č","Ď","Đ","Ē","Ĕ","Ė","Ę","Ě","Ĝ","Ğ","Ġ","Ģ","Ĥ","Ħ","Ĩ","Ī","Ĭ","Į","İ","IJ","Ĵ","Ķ","Ĺ","Ļ","Ľ","Ŀ","Ł","Ń","Ņ","Ň","Ŋ","Ō","Ŏ","Ő","Œ","Ŕ","Ŗ","Ř","Ś","Ŝ","Ş","Š","Ţ","Ť","Ŧ","Ũ","Ū","Ŭ","Ů","Ű","Ų","Ŵ","Ŷ",["Ÿ","Ź"],"Ż","Ž",["Ɓ","Ƃ"],"Ƅ",["Ɔ","Ƈ"],["Ɖ","Ƌ"],["Ǝ","Ƒ"],["Ɠ","Ɣ"],["Ɩ","Ƙ"],["Ɯ","Ɲ"],["Ɵ","Ơ"],"Ƣ","Ƥ",["Ʀ","Ƨ"],"Ʃ","Ƭ",["Ʈ","Ư"],["Ʊ","Ƴ"],"Ƶ",["Ʒ","Ƹ"],"Ƽ","DŽ","LJ","NJ","Ǎ","Ǐ","Ǒ","Ǔ","Ǖ","Ǘ","Ǚ","Ǜ","Ǟ","Ǡ","Ǣ","Ǥ","Ǧ","Ǩ","Ǫ","Ǭ","Ǯ","DZ","Ǵ",["Ƕ","Ǹ"],"Ǻ","Ǽ","Ǿ","Ȁ","Ȃ","Ȅ","Ȇ","Ȉ","Ȋ","Ȍ","Ȏ","Ȑ","Ȓ","Ȕ","Ȗ","Ș","Ț","Ȝ","Ȟ","Ƞ","Ȣ","Ȥ","Ȧ","Ȩ","Ȫ","Ȭ","Ȯ","Ȱ","Ȳ",["Ⱥ","Ȼ"],["Ƚ","Ⱦ"],"Ɂ",["Ƀ","Ɇ"],"Ɉ","Ɋ","Ɍ","Ɏ","Ͱ","Ͳ","Ͷ","Ϳ","Ά",["Έ","Ί"],"Ό",["Ύ","Ώ"],["Α","Ρ"],["Σ","Ϋ"],"Ϗ",["ϒ","ϔ"],"Ϙ","Ϛ","Ϝ","Ϟ","Ϡ","Ϣ","Ϥ","Ϧ","Ϩ","Ϫ","Ϭ","Ϯ","ϴ","Ϸ",["Ϲ","Ϻ"],["Ͻ","Я"],"Ѡ","Ѣ","Ѥ","Ѧ","Ѩ","Ѫ","Ѭ","Ѯ","Ѱ","Ѳ","Ѵ","Ѷ","Ѹ","Ѻ","Ѽ","Ѿ","Ҁ","Ҋ","Ҍ","Ҏ","Ґ","Ғ","Ҕ","Җ","Ҙ","Қ","Ҝ","Ҟ","Ҡ","Ң","Ҥ","Ҧ","Ҩ","Ҫ","Ҭ","Ү","Ұ","Ҳ","Ҵ","Ҷ","Ҹ","Һ","Ҽ","Ҿ",["Ӏ","Ӂ"],"Ӄ","Ӆ","Ӈ","Ӊ","Ӌ","Ӎ","Ӑ","Ӓ","Ӕ","Ӗ","Ә","Ӛ","Ӝ","Ӟ","Ӡ","Ӣ","Ӥ","Ӧ","Ө","Ӫ","Ӭ","Ӯ","Ӱ","Ӳ","Ӵ","Ӷ","Ӹ","Ӻ","Ӽ","Ӿ","Ԁ","Ԃ","Ԅ","Ԇ","Ԉ","Ԋ","Ԍ","Ԏ","Ԑ","Ԓ","Ԕ","Ԗ","Ԙ","Ԛ","Ԝ","Ԟ","Ԡ","Ԣ","Ԥ","Ԧ","Ԩ","Ԫ","Ԭ","Ԯ",["Ա","Ֆ"],["Ⴀ","Ⴥ"],"Ⴧ","Ⴭ",["Ꭰ","Ᏽ"],["Ა","Ჺ"],["Ჽ","Ჿ"],"Ḁ","Ḃ","Ḅ","Ḇ","Ḉ","Ḋ","Ḍ","Ḏ","Ḑ","Ḓ","Ḕ","Ḗ","Ḙ","Ḛ","Ḝ","Ḟ","Ḡ","Ḣ","Ḥ","Ḧ","Ḩ","Ḫ","Ḭ","Ḯ","Ḱ","Ḳ","Ḵ","Ḷ","Ḹ","Ḻ","Ḽ","Ḿ","Ṁ","Ṃ","Ṅ","Ṇ","Ṉ","Ṋ","Ṍ","Ṏ","Ṑ","Ṓ","Ṕ","Ṗ","Ṙ","Ṛ","Ṝ","Ṟ","Ṡ","Ṣ","Ṥ","Ṧ","Ṩ","Ṫ","Ṭ","Ṯ","Ṱ","Ṳ","Ṵ","Ṷ","Ṹ","Ṻ","Ṽ","Ṿ","Ẁ","Ẃ","Ẅ","Ẇ","Ẉ","Ẋ","Ẍ","Ẏ","Ẑ","Ẓ","Ẕ","ẞ","Ạ","Ả","Ấ","Ầ","Ẩ","Ẫ","Ậ","Ắ","Ằ","Ẳ","Ẵ","Ặ","Ẹ","Ẻ","Ẽ","Ế","Ề","Ể","Ễ","Ệ","Ỉ","Ị","Ọ","Ỏ","Ố","Ồ","Ổ","Ỗ","Ộ","Ớ","Ờ","Ở","Ỡ","Ợ","Ụ","Ủ","Ứ","Ừ","Ử","Ữ","Ự","Ỳ","Ỵ","Ỷ","Ỹ","Ỻ","Ỽ","Ỿ",["Ἀ","Ἇ"],["Ἐ","Ἕ"],["Ἠ","Ἧ"],["Ἰ","Ἷ"],["Ὀ","Ὅ"],"Ὑ","Ὓ","Ὕ","Ὗ",["Ὠ","Ὧ"],["Ᾰ","Ά"],["Ὲ","Ή"],["Ῐ","Ί"],["Ῠ","Ῥ"],["Ὸ","Ώ"],"ℂ","ℇ",["ℋ","ℍ"],["ℐ","ℒ"],"ℕ",["ℙ","ℝ"],"ℤ","Ω","ℨ",["K","ℭ"],["ℰ","ℳ"],["ℾ","ℿ"],"ⅅ","Ↄ",["Ⰰ","Ⱞ"],"Ⱡ",["Ɫ","Ɽ"],"Ⱨ","Ⱪ","Ⱬ",["Ɑ","Ɒ"],"Ⱳ","Ⱶ",["Ȿ","Ⲁ"],"Ⲃ","Ⲅ","Ⲇ","Ⲉ","Ⲋ","Ⲍ","Ⲏ","Ⲑ","Ⲓ","Ⲕ","Ⲗ","Ⲙ","Ⲛ","Ⲝ","Ⲟ","Ⲡ","Ⲣ","Ⲥ","Ⲧ","Ⲩ","Ⲫ","Ⲭ","Ⲯ","Ⲱ","Ⲳ","Ⲵ","Ⲷ","Ⲹ","Ⲻ","Ⲽ","Ⲿ","Ⳁ","Ⳃ","Ⳅ","Ⳇ","Ⳉ","Ⳋ","Ⳍ","Ⳏ","Ⳑ","Ⳓ","Ⳕ","Ⳗ","Ⳙ","Ⳛ","Ⳝ","Ⳟ","Ⳡ","Ⳣ","Ⳬ","Ⳮ","Ⳳ","Ꙁ","Ꙃ","Ꙅ","Ꙇ","Ꙉ","Ꙋ","Ꙍ","Ꙏ","Ꙑ","Ꙓ","Ꙕ","Ꙗ","Ꙙ","Ꙛ","Ꙝ","Ꙟ","Ꙡ","Ꙣ","Ꙥ","Ꙧ","Ꙩ","Ꙫ","Ꙭ","Ꚁ","Ꚃ","Ꚅ","Ꚇ","Ꚉ","Ꚋ","Ꚍ","Ꚏ","Ꚑ","Ꚓ","Ꚕ","Ꚗ","Ꚙ","Ꚛ","Ꜣ","Ꜥ","Ꜧ","Ꜩ","Ꜫ","Ꜭ","Ꜯ","Ꜳ","Ꜵ","Ꜷ","Ꜹ","Ꜻ","Ꜽ","Ꜿ","Ꝁ","Ꝃ","Ꝅ","Ꝇ","Ꝉ","Ꝋ","Ꝍ","Ꝏ","Ꝑ","Ꝓ","Ꝕ","Ꝗ","Ꝙ","Ꝛ","Ꝝ","Ꝟ","Ꝡ","Ꝣ","Ꝥ","Ꝧ","Ꝩ","Ꝫ","Ꝭ","Ꝯ","Ꝺ","Ꝼ",["Ᵹ","Ꝿ"],"Ꞁ","Ꞃ","Ꞅ","Ꞇ","Ꞌ","Ɥ","Ꞑ","Ꞓ","Ꞗ","Ꞙ","Ꞛ","Ꞝ","Ꞟ","Ꞡ","Ꞣ","Ꞥ","Ꞧ","Ꞩ",["Ɦ","Ɪ"],["Ʞ","Ꞵ"],"Ꞷ","Ꞹ",["A","Z"]],!1,!1),Du=gu(["ः","ऻ",["ा","ी"],["ॉ","ौ"],["ॎ","ॏ"],["ং","ঃ"],["া","ী"],["ে","ৈ"],["ো","ৌ"],"ৗ","ਃ",["ਾ","ੀ"],"ઃ",["ા","ી"],"ૉ",["ો","ૌ"],["ଂ","ଃ"],"ା","ୀ",["େ","ୈ"],["ୋ","ୌ"],"ୗ",["ா","ி"],["ு","ூ"],["ெ","ை"],["ொ","ௌ"],"ௗ",["ఁ","ః"],["ు","ౄ"],["ಂ","ಃ"],"ಾ",["ೀ","ೄ"],["ೇ","ೈ"],["ೊ","ೋ"],["ೕ","ೖ"],["ം","ഃ"],["ാ","ീ"],["െ","ൈ"],["ൊ","ൌ"],"ൗ",["ං","ඃ"],["ා","ෑ"],["ෘ","ෟ"],["ෲ","ෳ"],["༾","༿"],"ཿ",["ါ","ာ"],"ေ","း",["ျ","ြ"],["ၖ","ၗ"],["ၢ","ၤ"],["ၧ","ၭ"],["ႃ","ႄ"],["ႇ","ႌ"],"ႏ",["ႚ","ႜ"],"ា",["ើ","ៅ"],["ះ","ៈ"],["ᤣ","ᤦ"],["ᤩ","ᤫ"],["ᤰ","ᤱ"],["ᤳ","ᤸ"],["ᨙ","ᨚ"],"ᩕ","ᩗ","ᩡ",["ᩣ","ᩤ"],["ᩭ","ᩲ"],"ᬄ","ᬵ","ᬻ",["ᬽ","ᭁ"],["ᭃ","᭄"],"ᮂ","ᮡ",["ᮦ","ᮧ"],"᮪","ᯧ",["ᯪ","ᯬ"],"ᯮ",["᯲","᯳"],["ᰤ","ᰫ"],["ᰴ","ᰵ"],"᳡",["ᳲ","ᳳ"],"᳷",["〮","〯"],["ꠣ","ꠤ"],"ꠧ",["ꢀ","ꢁ"],["ꢴ","ꣃ"],["ꥒ","꥓"],"ꦃ",["ꦴ","ꦵ"],["ꦺ","ꦻ"],["ꦽ","꧀"],["ꨯ","ꨰ"],["ꨳ","ꨴ"],"ꩍ","ꩻ","ꩽ","ꫫ",["ꫮ","ꫯ"],"ꫵ",["ꯣ","ꯤ"],["ꯦ","ꯧ"],["ꯩ","ꯪ"],"꯬"],!1,!1),nu=gu([["̀","ͯ"],["҃","҇"],["֑","ֽ"],"ֿ",["ׁ","ׂ"],["ׄ","ׅ"],"ׇ",["ؐ","ؚ"],["ً","ٟ"],"ٰ",["ۖ","ۜ"],["۟","ۤ"],["ۧ","ۨ"],["۪","ۭ"],"ܑ",["ܰ","݊"],["ަ","ް"],["߫","߳"],"߽",["ࠖ","࠙"],["ࠛ","ࠣ"],["ࠥ","ࠧ"],["ࠩ","࠭"],["࡙","࡛"],["࣓","࣡"],["ࣣ","ं"],"ऺ","़",["ु","ै"],"्",["॑","ॗ"],["ॢ","ॣ"],"ঁ","়",["ু","ৄ"],"্",["ৢ","ৣ"],"৾",["ਁ","ਂ"],"਼",["ੁ","ੂ"],["ੇ","ੈ"],["ੋ","੍"],"ੑ",["ੰ","ੱ"],"ੵ",["ઁ","ં"],"઼",["ુ","ૅ"],["ે","ૈ"],"્",["ૢ","ૣ"],["ૺ","૿"],"ଁ","଼","ି",["ୁ","ୄ"],"୍","ୖ",["ୢ","ୣ"],"ஂ","ீ","்","ఀ","ఄ",["ా","ీ"],["ె","ై"],["ొ","్"],["ౕ","ౖ"],["ౢ","ౣ"],"ಁ","಼","ಿ","ೆ",["ೌ","್"],["ೢ","ೣ"],["ഀ","ഁ"],["഻","഼"],["ു","ൄ"],"്",["ൢ","ൣ"],"්",["ි","ු"],"ූ","ั",["ิ","ฺ"],["็","๎"],"ັ",["ິ","ູ"],["ົ","ຼ"],["່","ໍ"],["༘","༙"],"༵","༷","༹",["ཱ","ཾ"],["ྀ","྄"],["྆","྇"],["ྍ","ྗ"],["ྙ","ྼ"],"࿆",["ိ","ူ"],["ဲ","့"],["္","်"],["ွ","ှ"],["ၘ","ၙ"],["ၞ","ၠ"],["ၱ","ၴ"],"ႂ",["ႅ","ႆ"],"ႍ","ႝ",["፝","፟"],["ᜒ","᜔"],["ᜲ","᜴"],["ᝒ","ᝓ"],["ᝲ","ᝳ"],["឴","឵"],["ិ","ួ"],"ំ",["៉","៓"],"៝",["᠋","᠍"],["ᢅ","ᢆ"],"ᢩ",["ᤠ","ᤢ"],["ᤧ","ᤨ"],"ᤲ",["᤹","᤻"],["ᨗ","ᨘ"],"ᨛ","ᩖ",["ᩘ","ᩞ"],"᩠","ᩢ",["ᩥ","ᩬ"],["ᩳ","᩼"],"᩿",["᪰","᪽"],["ᬀ","ᬃ"],"᬴",["ᬶ","ᬺ"],"ᬼ","ᭂ",["᭫","᭳"],["ᮀ","ᮁ"],["ᮢ","ᮥ"],["ᮨ","ᮩ"],["᮫","ᮭ"],"᯦",["ᯨ","ᯩ"],"ᯭ",["ᯯ","ᯱ"],["ᰬ","ᰳ"],["ᰶ","᰷"],["᳐","᳒"],["᳔","᳠"],["᳢","᳨"],"᳭","᳴",["᳸","᳹"],["᷀","᷹"],["᷻","᷿"],["⃐","⃜"],"⃡",["⃥","⃰"],["⳯","⳱"],"⵿",["ⷠ","ⷿ"],["〪","〭"],["゙","゚"],"꙯",["ꙴ","꙽"],["ꚞ","ꚟ"],["꛰","꛱"],"ꠂ","꠆","ꠋ",["ꠥ","ꠦ"],["꣄","ꣅ"],["꣠","꣱"],"ꣿ",["ꤦ","꤭"],["ꥇ","ꥑ"],["ꦀ","ꦂ"],"꦳",["ꦶ","ꦹ"],"ꦼ","ꧥ",["ꨩ","ꨮ"],["ꨱ","ꨲ"],["ꨵ","ꨶ"],"ꩃ","ꩌ","ꩼ","ꪰ",["ꪲ","ꪴ"],["ꪷ","ꪸ"],["ꪾ","꪿"],"꫁",["ꫬ","ꫭ"],"꫶","ꯥ","ꯨ","꯭","ﬞ",["︀","️"],["︠","︯"]],!1,!1),ou=gu([["0","9"],["٠","٩"],["۰","۹"],["߀","߉"],["०","९"],["০","৯"],["੦","੯"],["૦","૯"],["୦","୯"],["௦","௯"],["౦","౯"],["೦","೯"],["൦","൯"],["෦","෯"],["๐","๙"],["໐","໙"],["༠","༩"],["၀","၉"],["႐","႙"],["០","៩"],["᠐","᠙"],["᥆","᥏"],["᧐","᧙"],["᪀","᪉"],["᪐","᪙"],["᭐","᭙"],["᮰","᮹"],["᱀","᱉"],["᱐","᱙"],["꘠","꘩"],["꣐","꣙"],["꤀","꤉"],["꧐","꧙"],["꧰","꧹"],["꩐","꩙"],["꯰","꯹"],["0","9"]],!1,!1),su=gu([["ᛮ","ᛰ"],["Ⅰ","ↂ"],["ↅ","ↈ"],"〇",["〡","〩"],["〸","〺"],["ꛦ","ꛯ"]],!1,!1),au=gu(["_",["‿","⁀"],"⁔",["︳","︴"],["﹍","﹏"],"_"],!1,!1),cu=gu([" "," "," ",[" "," "]," "," "," "],!1,!1),lu=0,iu=0,fu=[{line:1,column:1}],hu=0,xu=[],pu=0,du={};if("startRule"in A){if(!(A.startRule in e))throw new Error("Can't start parsing from rule \""+A.startRule+'".');D=e[A.startRule]}function Pu(u,A){return{type:"literal",text:u,ignoreCase:A}}function gu(u,A,E){return{type:"class",parts:u,inverted:A,ignoreCase:E}}function vu(u){return{type:"other",description:u}}function yu(A){var E,C=fu[A];if(C)return C;for(E=A-1;!fu[E];)E--;for(C={line:(C=fu[E]).line,column:C.column};E<A;)10===u.charCodeAt(E)?(C.line++,C.column=1):C.column++,E++;return fu[A]=C,C}function mu(u,A){var E=yu(u),C=yu(A);return{source:r,start:{offset:u,line:E.line,column:E.column},end:{offset:A,line:C.line,column:C.column}}}function $u(u){lu<hu||(lu>hu&&(hu=lu,xu=[]),xu.push(u))}function Su(){var A,E,C,F,t,r=32*lu+0,e=du[r];if(e)return lu=e.nextPos,e.result;for(A=lu,E=[],C=lu,F=Ru(),(t=bu())!==B?C=t:(lu=C,C=B);C!==B;)E.push(C),C=lu,F=Ru(),(t=bu())!==B?C=t:(lu=C,C=B);return C=Ru(),F=lu,pu++,u.length>lu?(t=u.charAt(lu),lu++):(t=B,0===pu&&$u(P)),pu--,t===B?F=void 0:(lu=F,F=B),F!==B?A=E:(lu=A,A=B),du[r]={nextPos:lu,result:A},A}function bu(){var A,E,C,F,t,r=32*lu+1,e=du[r];return e?(lu=e.nextPos,e.result):(A=lu,(E=wu())!==B?(Ru(),61===u.charCodeAt(lu)?(C="=",lu++):(C=B,0===pu&&$u(g)),C!==B?(Ru(),(F=ju())!==B?(Ru(),iu=A,t=F,A=Uu({names:E.names,values:t})):(lu=A,A=B)):(lu=A,A=B)):(lu=A,A=B),du[r]={nextPos:lu,result:A},A)}function wu(){var A,E,C,F,t,r,e,D=32*lu+2,n=du[D];if(n)return lu=n.nextPos,n.result;if(A=lu,(E=Lu())!==B){for(C=[],F=lu,_u(),46===u.charCodeAt(lu)?(t=".",lu++):(t=B,0===pu&&$u(v)),t!==B?(_u(),(r=Lu())!==B?F=r:(lu=F,F=B)):(lu=F,F=B);F!==B;)C.push(F),F=lu,_u(),46===u.charCodeAt(lu)?(t=".",lu++):(t=B,0===pu&&$u(v)),t!==B?(_u(),(r=Lu())!==B?F=r:(lu=F,F=B)):(lu=F,F=B);iu=A,e=C,A=Uu({type:"QualifiedName",names:[E,...e]})}else lu=A,A=B;return du[D]={nextPos:lu,result:A},A}function ju(){var A,E,C,F,t,r,e,D=32*lu+3,n=du[D];if(n)return lu=n.nextPos,n.result;if(A=lu,(E=Ou())!==B){for(C=[],F=lu,_u(),59===u.charCodeAt(lu)?(t=";",lu++):(t=B,0===pu&&$u(y)),t!==B?(_u(),(r=Ou())!==B?F=r:(lu=F,F=B)):(lu=F,F=B);F!==B;)C.push(F),F=lu,_u(),59===u.charCodeAt(lu)?(t=";",lu++):(t=B,0===pu&&$u(y)),t!==B?(_u(),(r=Ou())!==B?F=r:(lu=F,F=B)):(lu=F,F=B);iu=A,e=C,A=[E,...e]}else lu=A,A=B;return du[D]={nextPos:lu,result:A},A}function Ou(){var A,E,C,F,t=32*lu+4,r=du[t];return r?(lu=r.nextPos,r.result):(A=lu,"$("===u.substr(lu,2)?(E="$(",lu+=2):(E=B,0===pu&&$u(m)),E!==B&&(C=wu())!==B?(41===u.charCodeAt(lu)?(F=")",lu++):(F=B,0===pu&&$u($)),F!==B?A=C:(lu=A,A=B)):(lu=A,A=B),A===B&&(A=function(){var u,A,E,C,F,t=32*lu+5,r=du[t];if(r)return lu=r.nextPos,r.result;if(pu++,u=lu,(A=Zu())!==B){for(E=[],C=lu,_u(),(F=Zu())!==B?C=F:(lu=C,C=B);C!==B;)E.push(C),C=lu,_u(),(F=Zu())!==B?C=F:(lu=C,C=B);iu=u,u=Uu({type:"Literal",value:A+E.join("")})}else lu=u,u=B;return pu--,u===B&&(A=B,0===pu&&$u(S)),du[t]={nextPos:lu,result:u},u}(),A===B&&(A=function(){var A,E,C,F,t,r,e,D,n,o,s=32*lu+6,a=du[s];if(a)return lu=a.nextPos,a.result;if(pu++,A=lu,34===u.charCodeAt(lu)?(E='"',lu++):(E=B,0===pu&&$u(w)),E!==B){if(C=lu,F=lu,t=[],(r=Zu())!==B)for(;r!==B;)t.push(r),r=Zu();else t=B;if(t!==B){if(r=[],e=lu,D=[],(n=qu())!==B)for(;n!==B;)D.push(n),n=qu();else D=B;if(D!==B){if(n=[],(o=Zu())!==B)for(;o!==B;)n.push(o),o=Zu();else n=B;n!==B?e=D=[D,n]:(lu=e,e=B)}else lu=e,e=B;for(;e!==B;){if(r.push(e),e=lu,D=[],(n=qu())!==B)for(;n!==B;)D.push(n),n=qu();else D=B;if(D!==B){if(n=[],(o=Zu())!==B)for(;o!==B;)n.push(o),o=Zu();else n=B;n!==B?e=D=[D,n]:(lu=e,e=B)}else lu=e,e=B}for(e=[],D=qu();D!==B;)e.push(D),D=qu();F=t=[t,r,e]}else lu=F,F=B;(C=F!==B?u.substring(C,lu):F)!==B?(34===u.charCodeAt(lu)?(F='"',lu++):(F=B,0===pu&&$u(w)),F!==B?(iu=A,A=Uu({type:"Literal",value:C})):(lu=A,A=B)):(lu=A,A=B)}else lu=A,A=B;return pu--,A===B&&(E=B,0===pu&&$u(b)),du[s]={nextPos:lu,result:A},A}(),A===B&&(A=function(){var A,E,C,F,t=32*lu+7,r=du[t];return r?(lu=r.nextPos,r.result):(A=lu,91===u.charCodeAt(lu)?(E="[",lu++):(E=B,0===pu&&$u(j)),E!==B&&(C=ju())!==B?(93===u.charCodeAt(lu)?(F="]",lu++):(F=B,0===pu&&$u(O)),F!==B?(iu=A,A=Uu({type:"SubList",values:C})):(lu=A,A=B)):(lu=A,A=B),du[t]={nextPos:lu,result:A},A)}()))),du[t]={nextPos:lu,result:A},A)}function Ru(){var u,A,E=32*lu+8,C=du[E];if(C)return lu=C.nextPos,C.result;for(u=[],(A=qu())===B&&(A=Nu())===B&&(A=Qu());A!==B;)u.push(A),(A=qu())===B&&(A=Nu())===B&&(A=Qu());return du[E]={nextPos:lu,result:u},u}function _u(){var A,E,C,F,t=32*lu+9,r=du[t];if(r)return lu=r.nextPos,r.result;for(A=[],32===u.charCodeAt(lu)?(E=" ",lu++):(E=B,0===pu&&$u(R)),E===B&&(9===u.charCodeAt(lu)?(E="\t",lu++):(E=B,0===pu&&$u(_)),E===B&&(E=lu,92===u.charCodeAt(lu)?(C="\\",lu++):(C=B,0===pu&&$u(L)),C!==B&&(F=Nu())!==B?E=C=[C,F]:(lu=E,E=B),E===B&&(E=Qu())));E!==B;)A.push(E),32===u.charCodeAt(lu)?(E=" ",lu++):(E=B,0===pu&&$u(R)),E===B&&(9===u.charCodeAt(lu)?(E="\t",lu++):(E=B,0===pu&&$u(_)),E===B&&(E=lu,92===u.charCodeAt(lu)?(C="\\",lu++):(C=B,0===pu&&$u(L)),C!==B&&(F=Nu())!==B?E=C=[C,F]:(lu=E,E=B),E===B&&(E=Qu())));return du[t]={nextPos:lu,result:A},A}function Lu(){var u,A,E,C,F=32*lu+10,t=du[F];if(t)return lu=t.nextPos,t.result;if(pu++,u=lu,(A=zu())!==B){for(E=[],C=Mu();C!==B;)E.push(C),C=Mu();iu=u,u=A+E.join("")}else lu=u,u=B;return pu--,u===B&&(A=B,0===pu&&$u(z)),du[F]={nextPos:lu,result:u},u}function zu(){var A,E=32*lu+11,C=du[E];return C?(lu=C.nextPos,C.result):(A=function(){var A,E=32*lu+14,C=du[E];return C?(lu=C.nextPos,C.result):(A=function(){var A,E=32*lu+25,C=du[E];return C?(lu=C.nextPos,C.result):(l.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(eu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+21,C=du[E];return C?(lu=C.nextPos,C.result):(o.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(Fu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+24,C=du[E];return C?(lu=C.nextPos,C.result):(c.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(ru)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+22,C=du[E];return C?(lu=C.nextPos,C.result):(s.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(tu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+23,C=du[E];return C?(lu=C.nextPos,C.result):(a.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(Bu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+29,C=du[E];return C?(lu=C.nextPos,C.result):(x.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(su)),du[E]={nextPos:lu,result:A},A)}()))))),du[E]={nextPos:lu,result:A},A)}(),A===B&&(95===u.charCodeAt(lu)?(A="_",lu++):(A=B,0===pu&&$u(M))),du[E]={nextPos:lu,result:A},A)}function Mu(){var A,E=32*lu+12,C=du[E];return C?(lu=C.nextPos,C.result):((A=zu())===B&&(A=function(){var A,E=32*lu+15,C=du[E];return C?(lu=C.nextPos,C.result):(A=function(){var A,E=32*lu+27,C=du[E];return C?(lu=C.nextPos,C.result):(f.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(nu)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+26,C=du[E];return C?(lu=C.nextPos,C.result):(i.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(Du)),du[E]={nextPos:lu,result:A},A)}()),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+28,C=du[E];return C?(lu=C.nextPos,C.result):(h.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(ou)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(A=function(){var A,E=32*lu+30,C=du[E];return C?(lu=C.nextPos,C.result):(p.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(au)),du[E]={nextPos:lu,result:A},A)}(),A===B&&(36===u.charCodeAt(lu)?(A="$",lu++):(A=B,0===pu&&$u(Z)),A===B&&(45===u.charCodeAt(lu)?(A="-",lu++):(A=B,0===pu&&$u(k)),A===B&&(8204===u.charCodeAt(lu)?(A="‌",lu++):(A=B,0===pu&&$u(q)),A===B&&(8205===u.charCodeAt(lu)?(A="‍",lu++):(A=B,0===pu&&$u(J))))))))),du[E]={nextPos:lu,result:A},A)}function Zu(){var A,E,C=32*lu+13,F=du[C];return F?(lu=F.nextPos,F.result):((A=Mu())===B&&(46===u.charCodeAt(lu)?(A=".",lu++):(A=B,0===pu&&$u(v)),A===B&&(47===u.charCodeAt(lu)?(A="/",lu++):(A=B,0===pu&&$u(N)),A===B&&(42===u.charCodeAt(lu)?(A="*",lu++):(A=B,0===pu&&$u(Q)),A===B&&(A=lu,92===u.charCodeAt(lu)?(E="\\",lu++):(E=B,0===pu&&$u(L)),E!==B&&(iu=A,E="/"),A=E)))),du[C]={nextPos:lu,result:A},A)}function ku(){var A,E=32*lu+16,C=du[E];return C?(lu=C.nextPos,C.result):(u.length>lu?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(P)),du[E]={nextPos:lu,result:A},A)}function qu(){var A,E=32*lu+17,C=du[E];return C?(lu=C.nextPos,C.result):(pu++,9===u.charCodeAt(lu)?(A="\t",lu++):(A=B,0===pu&&$u(_)),A===B&&(11===u.charCodeAt(lu)?(A="\v",lu++):(A=B,0===pu&&$u(G)),A===B&&(12===u.charCodeAt(lu)?(A="\f",lu++):(A=B,0===pu&&$u(H)),A===B&&(32===u.charCodeAt(lu)?(A=" ",lu++):(A=B,0===pu&&$u(R)),A===B&&(160===u.charCodeAt(lu)?(A=" ",lu++):(A=B,0===pu&&$u(I)),A===B&&(65279===u.charCodeAt(lu)?(A="\ufeff",lu++):(A=B,0===pu&&$u(K)),A===B&&(A=function(){var A,E=32*lu+31,C=du[E];return C?(lu=C.nextPos,C.result):(d.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(cu)),du[E]={nextPos:lu,result:A},A)}())))))),pu--,A===B&&0===pu&&$u(U),du[E]={nextPos:lu,result:A},A)}function Ju(){var A,E=32*lu+18,C=du[E];return C?(lu=C.nextPos,C.result):(n.test(u.charAt(lu))?(A=u.charAt(lu),lu++):(A=B,0===pu&&$u(T)),du[E]={nextPos:lu,result:A},A)}function Nu(){var A,E=32*lu+19,C=du[E];return C?(lu=C.nextPos,C.result):(pu++,10===u.charCodeAt(lu)?(A="\n",lu++):(A=B,0===pu&&$u(W)),A===B&&("\r\n"===u.substr(lu,2)?(A="\r\n",lu+=2):(A=B,0===pu&&$u(X)),A===B&&(13===u.charCodeAt(lu)?(A="\r",lu++):(A=B,0===pu&&$u(Y)),A===B&&(8232===u.charCodeAt(lu)?(A="\u2028",lu++):(A=B,0===pu&&$u(uu)),A===B&&(8233===u.charCodeAt(lu)?(A="\u2029",lu++):(A=B,0===pu&&$u(Au)))))),pu--,A===B&&0===pu&&$u(V),du[E]={nextPos:lu,result:A},A)}function Qu(){var A,E,C,F,t,r,e=32*lu+20,D=du[e];if(D)return lu=D.nextPos,D.result;if(pu++,A=lu,35===u.charCodeAt(lu)?(E="#",lu++):(E=B,0===pu&&$u(Cu)),E!==B){for(C=[],F=lu,t=lu,pu++,r=Ju(),pu--,r===B?t=void 0:(lu=t,t=B),t!==B&&(r=ku())!==B?F=t=[t,r]:(lu=F,F=B);F!==B;)C.push(F),F=lu,t=lu,pu++,r=Ju(),pu--,r===B?t=void 0:(lu=t,t=B),t!==B&&(r=ku())!==B?F=t=[t,r]:(lu=F,F=B);A=E=[E,C]}else lu=A,A=B;return pu--,A===B&&(E=B,0===pu&&$u(Eu)),du[e]={nextPos:lu,result:A},A}function Uu(u){return{...u,source:mu(iu,lu).source}}if((E=D())!==B&&lu===u.length)return E;throw E!==B&&lu<u.length&&$u({type:"end"}),C=xu,F=hu<u.length?u.charAt(hu):null,t=hu<u.length?mu(hu,hu+1):mu(hu,hu),new peg$SyntaxError(peg$SyntaxError.buildMessage(C,F),C,F,t)}peg$subclass(peg$SyntaxError,Error),peg$SyntaxError.prototype.format=function(u){var A="Error: "+this.message;if(this.location){var E,C=null;for(E=0;E<u.length;E++)if(u[E].source===this.location.source){C=u[E].text.split(/\r\n|\n|\r/g);break}var F=this.location.start,t=this.location.source+":"+F.line+":"+F.column;if(C){var B=this.location.end,r=peg$padEnd("",F.line.toString().length),e=C[F.line-1],D=F.line===B.line?B.column:e.length+1;A+="\n --\x3e "+t+"\n"+r+" |\n"+F.line+" | "+e+"\n"+r+" | "+peg$padEnd("",F.column-1)+peg$padEnd("",D-F.column,"^")}else A+="\n at "+t}return A},peg$SyntaxError.buildMessage=function(u,A){var E={literal:function(u){return'"'+F(u.text)+'"'},class:function(u){var A=u.parts.map((function(u){return Array.isArray(u)?t(u[0])+"-"+t(u[1]):t(u)}));return"["+(u.inverted?"^":"")+A+"]"},any:function(){return"any character"},end:function(){return"end of input"},other:function(u){return u.description}};function C(u){return u.charCodeAt(0).toString(16).toUpperCase()}function F(u){return u.replace(/\\/g,"\\\\").replace(/"/g,'\\"').replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,(function(u){return"\\x0"+C(u)})).replace(/[\x10-\x1F\x7F-\x9F]/g,(function(u){return"\\x"+C(u)}))}function t(u){return u.replace(/\\/g,"\\\\").replace(/\]/g,"\\]").replace(/\^/g,"\\^").replace(/-/g,"\\-").replace(/\0/g,"\\0").replace(/\t/g,"\\t").replace(/\n/g,"\\n").replace(/\r/g,"\\r").replace(/[\x00-\x0F]/g,(function(u){return"\\x0"+C(u)})).replace(/[\x10-\x1F\x7F-\x9F]/g,(function(u){return"\\x"+C(u)}))}function B(u){return E[u.type](u)}return"Expected "+function(u){var A,E,C=u.map(B);if(C.sort(),C.length>0){for(A=1,E=1;A<C.length;A++)C[A-1]!==C[A]&&(C[E]=C[A],E++);C.length=E}switch(C.length){case 1:return C[0];case 2:return C[0]+" or "+C[1];default:return C.slice(0,-1).join(", ")+", or "+C[C.length-1]}}(u)+" but "+function(u){return u?'"'+F(u)+'"':"end of input"}(A)+" found."};
9907
- ;// CONCATENATED MODULE: ./src/manifest.js
9908
-
9922
+ ;// CONCATENATED MODULE: ./src/manifest.ts
9909
9923
 
9910
9924
 
9911
9925
 
9912
9926
  async function readManifest(manifest) {
9913
- const data = await promises_namespaceObject.readFile(manifest);
9914
- return (0,xml2js.parseStringPromise)(data.toString(), { trim: true });
9927
+ const data = await promises_namespaceObject.readFile(manifest);
9928
+ return (0,xml2js.parseStringPromise)(data.toString(), { trim: true });
9915
9929
  }
9916
-
9917
9930
  async function writeManifest(filename, xml) {
9918
- let builder = new xml2js.Builder();
9919
- let text = builder.buildObject(xml);
9920
- return promises_namespaceObject.writeFile(filename, text);
9931
+ let builder = new xml2js.Builder();
9932
+ let text = builder.buildObject(xml);
9933
+ return promises_namespaceObject.writeFile(filename, text);
9921
9934
  }
9922
-
9923
9935
  function manifestProducts(manifest) {
9924
- const app =
9925
- manifest["iq:manifest"]["iq:application"] ||
9926
- manifest["iq:manifest"]["iq:barrel"];
9927
- return ((app[0]["iq:products"] || [{}])[0]["iq:product"] || [])
9928
- .map((p) => p.$.id)
9929
- .sort()
9930
- .filter((p, i, a) => !i || p !== a[i - 1]);
9936
+ const app = manifest["iq:manifest"]["iq:application"] ||
9937
+ manifest["iq:manifest"]["iq:barrel"];
9938
+ return (app?.[0]["iq:products"]?.[0]["iq:product"] || [])
9939
+ .map((p) => p.$.id)
9940
+ .sort()
9941
+ .filter((p, i, a) => !i || p !== a[i - 1]);
9931
9942
  }
9932
-
9933
9943
  function manifestBarrels(manifest) {
9934
- const app = manifest["iq:manifest"]["iq:application"];
9935
- if (
9936
- Array.isArray(app) &&
9937
- app.length &&
9938
- app[0] &&
9939
- Array.isArray(app[0]["iq:barrels"]) &&
9940
- app[0]["iq:barrels"].length &&
9941
- Array.isArray(app[0]["iq:barrels"][0]["iq:depends"])
9942
- ) {
9943
- return app[0]["iq:barrels"][0]["iq:depends"]
9944
- .map((p) => p.$.name)
9945
- .sort()
9946
- .filter((p, i, a) => !i || p !== a[i - 1]);
9947
- }
9948
- return [];
9944
+ const app = manifest["iq:manifest"]["iq:application"];
9945
+ if (Array.isArray(app) &&
9946
+ app.length &&
9947
+ app[0] &&
9948
+ Array.isArray(app[0]["iq:barrels"]) &&
9949
+ app[0]["iq:barrels"].length &&
9950
+ Array.isArray(app[0]["iq:barrels"][0]["iq:depends"])) {
9951
+ return app[0]["iq:barrels"][0]["iq:depends"]
9952
+ .map((p) => p.$.name)
9953
+ .sort()
9954
+ .filter((p, i, a) => !i || p !== a[i - 1]);
9955
+ }
9956
+ return [];
9949
9957
  }
9950
-
9951
9958
  function manifestDropBarrels(manifest) {
9952
- delete manifest["iq:manifest"]["iq:application"][0]["iq:barrels"];
9959
+ const app = manifest["iq:manifest"]["iq:application"];
9960
+ if (!app)
9961
+ return;
9962
+ delete app[0]["iq:barrels"];
9953
9963
  }
9954
-
9955
9964
  function manifestBarrelName(manifestName, manifest) {
9956
- const barrel = manifest["iq:manifest"]["iq:barrel"];
9957
- if (!barrel) throw new Error(`Not a barrel manifest: ${manifestName}`);
9958
- return barrel[0].$.module;
9965
+ const barrel = manifest["iq:manifest"]["iq:barrel"];
9966
+ if (!barrel)
9967
+ throw new Error(`Not a barrel manifest: ${manifestName}`);
9968
+ return barrel[0].$.module;
9959
9969
  }
9960
-
9961
9970
  function manifestAnnotations(manifest) {
9962
- const barrel = manifest["iq:manifest"]["iq:barrel"];
9963
- if (!barrel) return null;
9964
- const annotations = barrel[0]["iq:annotations"];
9965
- return annotations && annotations[0]["iq:annotation"];
9971
+ const barrel = manifest["iq:manifest"]["iq:barrel"];
9972
+ if (!barrel)
9973
+ return undefined;
9974
+ const annotations = barrel[0]["iq:annotations"];
9975
+ return annotations && annotations[0]["iq:annotation"];
9966
9976
  }
9967
-
9968
9977
  async function checkManifest(manifest, products) {
9969
- let ok = true;
9970
- if (!manifest["iq:manifest"]["$"]["xmlns:iq"]) {
9971
- manifest["iq:manifest"]["$"]["xmlns:iq"] =
9972
- "http://www.garmin.com/xml/connectiq";
9973
- ok = false;
9974
- }
9975
- const app = manifest["iq:manifest"]["iq:application"];
9976
- if (!app) return ok;
9977
-
9978
- const elm = app[0];
9979
- const id = elm.$.id;
9980
- if (id.length < 32 || !/^[-_0-9a-f.]+$/.test(id)) {
9981
- ok = false;
9982
- elm.$.id = "08070f9d-8b4e-40a4-9c49-fe67a2a55dec";
9983
- }
9984
- const type = elm.$.type.replace(/-/g, "").toLowerCase();
9985
- const deviceInfo = await (0,external_sdk_util_cjs_namespaceObject.getDeviceInfo)();
9986
- const allowedProducts = products.sort().filter(
9987
- (p) =>
9988
- deviceInfo[p] &&
9989
- deviceInfo[p].appTypes.find((at) => {
9990
- const t = at.type.toLowerCase();
9991
- return t === type || `${t}app` === type;
9992
- })
9993
- );
9994
- if (
9995
- JSON.stringify(allowedProducts) !=
9996
- JSON.stringify(manifestProducts(manifest))
9997
- ) {
9998
- ok = false;
9999
- elm["iq:products"][0]["iq:product"] = allowedProducts.map((id) => {
10000
- return { $: { id } };
9978
+ let ok = true;
9979
+ if (!manifest["iq:manifest"]["$"]["xmlns:iq"]) {
9980
+ manifest["iq:manifest"]["$"]["xmlns:iq"] =
9981
+ "http://www.garmin.com/xml/connectiq";
9982
+ ok = false;
9983
+ }
9984
+ const app = manifest["iq:manifest"]["iq:application"];
9985
+ if (!app)
9986
+ return ok;
9987
+ const elm = app[0];
9988
+ const id = elm.$.id;
9989
+ if (id.length < 32 || !/^[-_0-9a-f.]+$/.test(id)) {
9990
+ ok = false;
9991
+ elm.$.id = "08070f9d-8b4e-40a4-9c49-fe67a2a55dec";
9992
+ }
9993
+ const type = elm.$.type.replace(/-/g, "").toLowerCase();
9994
+ const deviceInfo = await (0,external_sdk_util_cjs_namespaceObject.getDeviceInfo)();
9995
+ const allowedProducts = products.sort().filter((p) => deviceInfo[p] &&
9996
+ deviceInfo[p].appTypes.find((at) => {
9997
+ const t = at.type.toLowerCase();
9998
+ return t === type || `${t}app` === type;
9999
+ }));
10000
+ if (JSON.stringify(allowedProducts) !=
10001
+ JSON.stringify(manifestProducts(manifest))) {
10002
+ ok = false;
10003
+ elm["iq:products"] = [
10004
+ {
10005
+ "iq:product": allowedProducts.map((id) => {
10006
+ return { $: { id } };
10007
+ }),
10008
+ },
10009
+ ];
10010
+ }
10011
+ Object.keys(elm).forEach((key) => {
10012
+ if (![
10013
+ "$",
10014
+ "iq:permissions",
10015
+ "iq:languages",
10016
+ "iq:products",
10017
+ "iq:barrels",
10018
+ "iq:trialMode",
10019
+ ].includes(key)) {
10020
+ ok = false;
10021
+ delete elm[key];
10022
+ }
10001
10023
  });
10002
- }
10003
- Object.keys(elm).forEach((key) => {
10004
- if (
10005
- ![
10006
- "$",
10007
- "iq:permissions",
10008
- "iq:languages",
10009
- "iq:products",
10010
- "iq:barrels",
10011
- "iq:trialMode",
10012
- ].includes(key)
10013
- ) {
10014
- ok = false;
10015
- delete elm[key];
10016
- }
10017
- });
10018
-
10019
- return ok;
10024
+ return ok;
10020
10025
  }
10021
10026
 
10022
- ;// CONCATENATED MODULE: ./src/jungles.js
10023
-
10027
+ ;// CONCATENATED MODULE: ./src/jungles.ts
10024
10028
 
10025
10029
 
10026
10030
 
@@ -10031,510 +10035,509 @@ async function checkManifest(manifest, products) {
10031
10035
 
10032
10036
 
10033
10037
 
10038
+ function isJNode(obj) {
10039
+ return (0,external_api_cjs_namespaceObject.hasProperty)(obj, "type");
10040
+ }
10034
10041
  async function default_jungle() {
10035
- const assignments = [];
10036
- const devices = await (0,external_sdk_util_cjs_namespaceObject.getDeviceInfo)();
10037
- const languages = await (0,external_sdk_util_cjs_namespaceObject.getLanguages)();
10038
- const literal = (value) => ({ type: "Literal", value });
10039
- const qname = (name) => ({ type: "QualifiedName", names: name.split(".") });
10040
- const assign = (name, values) =>
10041
- assignments.push({ names: name.split("."), values });
10042
- const rassign = (name, values, base) => {
10043
- assign(name, base ? [qname(name)].concat(values) : values);
10044
- };
10045
- const rezAndLang = (id, rez, base) => {
10046
- if (base) {
10047
- assign(id, [qname(base)]);
10048
- }
10049
- rassign(`${id}.resourcePath`, [literal(rez)], base);
10050
-
10051
- languages.forEach((l) =>
10052
- rassign(`${id}.lang.${l.id}`, [literal(`${rez}-${l.id}`)], base)
10053
- );
10054
- };
10055
- const done = {};
10056
-
10057
- assign("base.sourcePath", [literal("./**.mc")]);
10058
- rezAndLang("base", "resources");
10059
- Object.entries(devices).forEach(([deviceId, { deviceFamily }]) => {
10060
- const match = deviceFamily.match(/^(\w+)-\d+x\d+/);
10061
- if (!match) {
10062
- throw new Error(
10063
- `Strange deviceFamily (${deviceFamily}) for device ${deviceId}`
10064
- );
10065
- }
10066
- const shape = match[1];
10067
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(done, shape)) {
10068
- rezAndLang(shape, `resources-${shape}`, "base");
10069
- done[shape] = true;
10070
- }
10071
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(done, deviceFamily)) {
10072
- rezAndLang(deviceFamily, `resources-${deviceFamily}`, shape);
10073
- done[deviceFamily] = true;
10074
- }
10075
- rezAndLang(deviceId, `resources-${deviceId}`, deviceFamily);
10076
- });
10077
- return process_assignments(assignments, {});
10042
+ const assignments = [];
10043
+ const devices = await (0,external_sdk_util_cjs_namespaceObject.getDeviceInfo)();
10044
+ const languages = await (0,external_sdk_util_cjs_namespaceObject.getLanguages)();
10045
+ const literal = (value) => ({ type: "Literal", value });
10046
+ const qname = (name) => ({
10047
+ type: "QualifiedName",
10048
+ names: name.split("."),
10049
+ });
10050
+ const assign = (name, values) => assignments.push({ names: name.split("."), values });
10051
+ const rassign = (name, values, base) => {
10052
+ assign(name, base ? [qname(name)].concat(values) : values);
10053
+ };
10054
+ const rezAndLang = (id, rez, base = null) => {
10055
+ if (base) {
10056
+ assign(id, [qname(base)]);
10057
+ }
10058
+ rassign(`${id}.resourcePath`, [literal(rez)], base);
10059
+ languages.forEach((l) => rassign(`${id}.lang.${l.id}`, [literal(`${rez}-${l.id}`)], base));
10060
+ };
10061
+ const done = {};
10062
+ assign("base.sourcePath", [literal("./**.mc")]);
10063
+ rezAndLang("base", "resources");
10064
+ Object.entries(devices).forEach(([deviceId, { deviceFamily }]) => {
10065
+ const match = deviceFamily.match(/^(\w+)-\d+x\d+/);
10066
+ if (!match) {
10067
+ throw new Error(`Strange deviceFamily (${deviceFamily}) for device ${deviceId}`);
10068
+ }
10069
+ const shape = match[1];
10070
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(done, shape)) {
10071
+ rezAndLang(shape, `resources-${shape}`, "base");
10072
+ done[shape] = true;
10073
+ }
10074
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(done, deviceFamily)) {
10075
+ rezAndLang(deviceFamily, `resources-${deviceFamily}`, shape);
10076
+ done[deviceFamily] = true;
10077
+ }
10078
+ rezAndLang(deviceId, `resources-${deviceId}`, deviceFamily);
10079
+ });
10080
+ return process_assignments(assignments, {});
10078
10081
  }
10079
-
10080
10082
  function process_assignments(assignments, current) {
10081
- return assignments.reduce((state, a) => {
10082
- const { node, dot, dotnames } = a.names.reduce(
10083
- (r, name) => {
10084
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(r.node, name)) r.node[name] = {};
10085
- r.dotnames.push(name);
10086
- r.node = r.node[name];
10087
- if (r.node["."]) {
10088
- r.dot = r.node["."];
10089
- r.dotnames = [];
10090
- }
10091
- return r;
10092
- },
10093
- { node: state, dot: null, dotnames: [] }
10094
- );
10095
- // an assignment to a node overwrites its old value
10096
- Object.keys(node).forEach((k) => delete node[k]);
10097
- const process_list = (values) => {
10098
- for (let i = values.length; i--; ) {
10099
- const v = values[i];
10100
- if (
10101
- v.type == "QualifiedName" &&
10102
- v.names.every((n, i) => n === a.names[i])
10103
- ) {
10104
- values.splice(
10105
- i,
10106
- 1,
10107
- ...(dot
10108
- ? dot.map((v) =>
10109
- v.type == "QualifiedName"
10110
- ? { ...v, names: v.names.concat(dotnames) }
10111
- : v
10112
- )
10113
- : [])
10114
- );
10115
- } else if (v.type == "SubList") {
10116
- process_list(v.values);
10117
- }
10118
- }
10119
- };
10120
- process_list(a.values);
10121
- if (
10122
- a.names.length === 1 &&
10123
- a.values.length === 1 &&
10124
- a.values[0].type === "QualifiedName" &&
10125
- a.values[0].names.length === 1
10126
- ) {
10127
- // some older manifests have things like "round_watch"
10128
- // as a product. You can't put that in a jungle file
10129
- // so instead, we identify every round device, and
10130
- // replace round_watch with all the corresponding
10131
- // devices. So we look for assignments of the form
10132
- // device = $(shape-size)
10133
- // and put all such devices on a `shape`_watch entry
10134
- const match = a.values[0].names[0].match(/^(\w+)-(\w+)$/);
10135
- if (match) {
10136
- const key = `${match[1]}_watch`;
10137
- if (!state[key]) state[key] = { products: [] };
10138
- state[key].products.push(a.names[0]);
10139
- }
10140
- }
10141
- node["."] = a.values;
10142
- return state;
10143
- }, current);
10083
+ return assignments.reduce((state, a) => {
10084
+ const { node, dot, dotnames } = a.names.reduce((r, name) => {
10085
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(r.node, name))
10086
+ r.node[name] = {};
10087
+ r.dotnames.push(name);
10088
+ r.node = r.node[name];
10089
+ if (r.node["."]) {
10090
+ r.dot = r.node["."];
10091
+ r.dotnames = [];
10092
+ }
10093
+ return r;
10094
+ }, { node: state, dot: undefined, dotnames: [] });
10095
+ // an assignment to a node overwrites its old value
10096
+ Object.keys(node).forEach((k) => delete node[k]);
10097
+ const process_list = (values) => {
10098
+ for (let i = values.length; i--;) {
10099
+ const v = values[i];
10100
+ if (v.type == "QualifiedName" &&
10101
+ v.names.every((n, i) => n === a.names[i])) {
10102
+ values.splice(i, 1, ...(dot
10103
+ ? dot.map((v) => v.type == "QualifiedName"
10104
+ ? { ...v, names: v.names.concat(dotnames) }
10105
+ : v)
10106
+ : []));
10107
+ }
10108
+ else if (v.type == "SubList") {
10109
+ process_list(v.values);
10110
+ }
10111
+ }
10112
+ };
10113
+ process_list(a.values);
10114
+ if (a.names.length === 1 &&
10115
+ a.values.length === 1 &&
10116
+ a.values[0].type === "QualifiedName" &&
10117
+ a.values[0].names.length === 1) {
10118
+ // some older manifests have things like "round_watch"
10119
+ // as a product. You can't put that in a jungle file
10120
+ // so instead, we identify every round device, and
10121
+ // replace round_watch with all the corresponding
10122
+ // devices. So we look for assignments of the form
10123
+ // device = $(shape-size)
10124
+ // and put all such devices on a `shape`_watch entry
10125
+ const match = a.values[0].names[0].match(/^(\w+)-(\w+)$/);
10126
+ if (match) {
10127
+ const key = `${match[1]}_watch`;
10128
+ if (!current[key])
10129
+ current[key] = { products: [] };
10130
+ current[key].products.push(a.names[0]);
10131
+ }
10132
+ }
10133
+ node["."] = a.values;
10134
+ return state;
10135
+ }, current);
10144
10136
  }
10145
-
10146
10137
  function evaluate_locals(assignments) {
10147
- const locals = {};
10148
- while (true) {
10149
- assignments = assignments.filter((a) => {
10150
- if (a.names.length == 1 && a.values.every((v) => typeof v === "string")) {
10151
- locals[a.names[0]] = a.values;
10152
- return false;
10153
- }
10154
- return true;
10155
- });
10156
- if (!Object.keys(locals).length) break;
10157
- const process_list = (values) => {
10158
- for (let i = values.length; i--; ) {
10159
- const v = values[i];
10160
- if (
10161
- v.type == "QualifiedName" &&
10162
- v.names.length == 1 &&
10163
- (0,external_api_cjs_namespaceObject.hasProperty)(locals, v.names[0])
10164
- ) {
10165
- values.splice(i, 1, ...locals[v.names[0]]);
10166
- } else if (v.type == "SubList") {
10167
- process_list(v.values);
10168
- }
10169
- }
10170
- };
10171
- assignments.forEach((a) => process_list(a.values));
10172
- }
10173
- return assignments;
10138
+ const locals = {};
10139
+ while (true) {
10140
+ assignments = assignments.filter((a) => {
10141
+ if (a.names.length == 1 && a.values.every((v) => typeof v === "string")) {
10142
+ locals[a.names[0]] = a.values;
10143
+ return false;
10144
+ }
10145
+ return true;
10146
+ });
10147
+ if (!Object.keys(locals).length)
10148
+ break;
10149
+ const process_list = (values) => {
10150
+ for (let i = values.length; i--;) {
10151
+ const v = values[i];
10152
+ if (v.type == "QualifiedName" &&
10153
+ v.names.length == 1 &&
10154
+ (0,external_api_cjs_namespaceObject.hasProperty)(locals, v.names[0])) {
10155
+ values.splice(i, 1, ...locals[v.names[0]]);
10156
+ }
10157
+ else if (v.type == "SubList") {
10158
+ process_list(v.values);
10159
+ }
10160
+ }
10161
+ };
10162
+ assignments.forEach((a) => process_list(a.values));
10163
+ }
10164
+ return assignments;
10174
10165
  }
10175
-
10176
10166
  async function parse_one(file) {
10177
- const [fileName, grammarSource] = Array.isArray(file) ? file : [file, file];
10178
- const source = await promises_namespaceObject.readFile(fileName);
10179
- const assignments = peg$parse(source.toString(), { grammarSource });
10180
- return evaluate_locals(assignments);
10167
+ const [fileName, grammarSource] = Array.isArray(file) ? file : [file, file];
10168
+ const source = await promises_namespaceObject.readFile(fileName).catch(() => {
10169
+ throw new Error(`Couldn't read jungle file '${fileName}`);
10170
+ });
10171
+ const assignments = peg$parse(source.toString(), { grammarSource });
10172
+ return evaluate_locals(assignments);
10181
10173
  }
10182
-
10183
10174
  // Read default.jungle, and all jungles in sources, and
10184
10175
  // return a jungle object with all local variables resolved,
10185
10176
  // but all qualifier references left unresolved.
10186
10177
  async function process_jungles(sources) {
10187
- if (!Array.isArray(sources)) {
10188
- sources = [sources];
10189
- }
10190
- const results = await Promise.all(sources.map(parse_one));
10191
- const state = await default_jungle();
10192
- results.forEach((r) => process_assignments(r, state));
10193
- return state;
10178
+ if (!Array.isArray(sources)) {
10179
+ sources = [sources];
10180
+ }
10181
+ const results = await Promise.all(sources.map(parse_one));
10182
+ const state = await default_jungle();
10183
+ results.forEach((r) => process_assignments(r, state));
10184
+ return state;
10194
10185
  }
10195
-
10196
10186
  function resolve_node_list(state, list) {
10197
- for (let i = list.length; i--; ) {
10198
- const v = list[i];
10199
- if (v.type === "QualifiedName") {
10200
- const rep = resolve_node(state, resolve_node_by_path(state, v.names));
10201
- if (Array.isArray(rep)) {
10202
- if (rep.length !== 1 || rep[0].type) {
10203
- resolve_node_list(state, rep);
10204
- }
10205
- list.splice(i, 1, ...rep);
10206
- } else if (rep != null) {
10207
- list[i] = rep;
10208
- } else {
10209
- list.splice(i, 1);
10210
- }
10211
- } else if (v.type === "SubList") {
10212
- resolve_node_list(state, v.values);
10187
+ if (!Array.isArray(list)) {
10188
+ throw new Error("Expected an array");
10189
+ }
10190
+ for (let i = list.length; i--;) {
10191
+ const v = list[i];
10192
+ if (typeof v === "string" || Array.isArray(v))
10193
+ continue;
10194
+ if (v.type === "QualifiedName") {
10195
+ const rep = resolve_node(state, resolve_node_by_path(state, v.names));
10196
+ if (Array.isArray(rep)) {
10197
+ if (rep.length !== 1 || (isJNode(rep[0]) && rep[0].type)) {
10198
+ resolve_node_list(state, rep);
10199
+ }
10200
+ list.splice(i, 1, ...rep);
10201
+ }
10202
+ else if (rep != null) {
10203
+ list[i] = rep;
10204
+ }
10205
+ else {
10206
+ list.splice(i, 1);
10207
+ }
10208
+ }
10209
+ else if (v.type === "SubList") {
10210
+ resolve_node_list(state, v.values);
10211
+ }
10213
10212
  }
10214
- }
10215
- return list;
10213
+ return list;
10216
10214
  }
10217
-
10218
- function check_non_leaf_dot(dot, path, i) {
10219
- if (dot.length !== 1 || dot[0].type) {
10220
- throw new Error(
10221
- `'.' node at ${(path || [])
10222
- .slice(0, i + 1)
10223
- .join(".")} should have length 1: ${JSON.stringify(dot)}`
10224
- );
10225
- }
10215
+ function check_non_leaf_dot(dot, path = null, i = 0) {
10216
+ if (dot.length !== 1 || dot[0].type) {
10217
+ throw new Error(`'.' node at ${(path || [])
10218
+ .slice(0, i + 1)
10219
+ .join(".")} should have length 1: ${JSON.stringify(dot)}`);
10220
+ }
10226
10221
  }
10227
10222
  // return the resolved node at path
10228
10223
  function resolve_node_by_path(state, path) {
10229
- return path.reduce((s, n, i) => {
10230
- if (!s[n] && s["."]) {
10231
- let resolved = resolve_node_list(state, s["."])[0][n];
10232
- if (resolved == null && s["."].every((e) => e.type == "Literal")) {
10233
- // foo = string
10234
- // bar = $(foo.resourcePath)
10235
- // is supposed to work as if you'd left out the (obviously
10236
- // incorrect) ".resourcePath"
10237
- return s;
10238
- }
10239
- check_non_leaf_dot(s["."], path, i);
10240
- }
10241
- return s[n];
10242
- }, state);
10224
+ return path.reduce((s, n, i) => {
10225
+ if (!s || Array.isArray(s)) {
10226
+ return s;
10227
+ }
10228
+ if (!s[n] && s["."]) {
10229
+ const sdot = s["."];
10230
+ let resolved = resolve_node_list(state, sdot);
10231
+ if (!resolved.length)
10232
+ return undefined;
10233
+ const r = resolved[0][n];
10234
+ if (!r && sdot.every((e) => e.type == "Literal")) {
10235
+ /*
10236
+ * We had something like:
10237
+ *
10238
+ * foo = whatever
10239
+ * bar = $(foo.resourcePath)
10240
+ *
10241
+ * and its supposed to work as if you'd left out the (obviously
10242
+ * incorrect) ".resourcePath"
10243
+ */
10244
+ return s;
10245
+ }
10246
+ /*
10247
+ * This is a pretty unusual edge case.
10248
+ *
10249
+ * If we do something like:
10250
+ *
10251
+ * fenix6 = $(base)
10252
+ * fenix5.sourcePath = $(fenix6.sourcePath)
10253
+ *
10254
+ * and fenix5 gets resolved before fenix6 (which it will,
10255
+ * currently, because products are resolved in lexicographical
10256
+ * order), we'll end up here when we try to resolve
10257
+ * fenix6.sourcePath.
10258
+ */
10259
+ check_non_leaf_dot(sdot, path, i);
10260
+ return r;
10261
+ }
10262
+ return s[n];
10263
+ }, state);
10243
10264
  }
10244
-
10245
10265
  // fully resolve the given node, and all its children
10246
10266
  function resolve_node(state, node) {
10247
- if (node == null || Array.isArray(node)) {
10248
- // an already optimized leaf node
10249
- return node;
10250
- }
10251
- const { ".": dot, ...rest } = node;
10252
- if (dot) {
10253
- const entries = Object.entries(rest);
10254
- resolve_node_list(state, dot);
10255
- if (entries.length) {
10256
- // not a leaf, so dot must have a single element
10257
- check_non_leaf_dot(dot);
10258
- Object.entries(dot[0]).forEach(([k, v]) => {
10259
- node[k] = v;
10260
- });
10261
- entries.forEach(([k, v]) => {
10262
- node[k] = v;
10263
- });
10264
- } else if (dot.length === 1 && !dot[0].type) {
10265
- Object.entries(dot[0]).forEach(([k, v]) => {
10266
- node[k] = v;
10267
- });
10268
- } else {
10269
- return dot;
10267
+ if (node === undefined || Array.isArray(node)) {
10268
+ // an already optimized leaf node
10269
+ return node;
10270
+ }
10271
+ const { ".": dot, ...rest } = node;
10272
+ if (dot) {
10273
+ const entries = Object.entries(rest);
10274
+ resolve_node_list(state, dot);
10275
+ if (entries.length) {
10276
+ // not a leaf, so dot must have a single element
10277
+ check_non_leaf_dot(dot);
10278
+ Object.entries(dot[0]).forEach(([k, v]) => {
10279
+ node[k] = v;
10280
+ });
10281
+ entries.forEach(([k, v]) => {
10282
+ node[k] = v;
10283
+ });
10284
+ }
10285
+ else if (dot.length === 1 && !dot[0].type) {
10286
+ Object.entries(dot[0]).forEach(([k, v]) => {
10287
+ node[k] = v;
10288
+ });
10289
+ }
10290
+ else {
10291
+ return dot;
10292
+ }
10293
+ delete node["."];
10270
10294
  }
10271
- delete node["."];
10272
- }
10273
- Object.entries(node).forEach(([key, value]) => {
10274
- node[key] = resolve_node(state, value);
10275
- });
10276
- return node;
10295
+ Object.entries(node).forEach(([key, value]) => {
10296
+ node[key] = resolve_node(state, value);
10297
+ });
10298
+ return node;
10277
10299
  }
10278
-
10279
- function resolve_filename(literal, default_source) {
10280
- if (typeof literal === "string") return literal;
10281
- const root = external_path_.dirname(literal.source || default_source);
10282
- return external_path_.resolve(root, literal.value);
10300
+ function resolve_filename(literal, default_source = null) {
10301
+ if (typeof literal === "string")
10302
+ return literal;
10303
+ const root = external_path_.dirname(literal.source || default_source);
10304
+ return external_path_.resolve(root, literal.value);
10283
10305
  }
10284
-
10285
10306
  async function resolve_literals(qualifier, default_source) {
10286
- const resolve_file_list = async (literals) =>
10287
- literals &&
10288
- (
10289
- await Promise.all(
10290
- literals.map(async (v) => {
10291
- if (v.type == "SubList") {
10292
- return resolve_file_list(v.values);
10293
- }
10294
- let resolved = resolve_filename(v, default_source);
10295
- if (/[*?\[\]\{\}]/.test(resolved)) {
10296
- // Jungle files can contain "./**.mc" which is supposed to match
10297
- // any mc file under "./". The standard way to express that
10298
- // is "./**/*.mc", which is what glob expects, so translate.
10299
- resolved = resolved.replace(/[\\\/]\*\*([^\\\/])/g, "/**/*$1");
10300
- const match = await (0,external_util_cjs_namespaceObject.globa)(resolved);
10301
- return match.length ? resolved : null;
10302
- } else {
10303
- const stat = await promises_namespaceObject.stat(resolved).catch(() => null);
10304
- return stat ? resolved : null;
10305
- }
10306
- })
10307
- )
10308
- ).filter((name) => name != null);
10309
-
10310
- const resolve_one_file_list = async (base, name) => {
10311
- if (!base[name]) return;
10312
- const result = await resolve_file_list(base[name]);
10313
- if (!result || !result.length) {
10314
- delete base[name];
10315
- } else {
10316
- base[name] = result;
10307
+ const resolve_file_list = async (literals) => literals &&
10308
+ (await Promise.all(literals.map(async (v) => {
10309
+ if (!isJNode(v)) {
10310
+ return v;
10311
+ }
10312
+ if (v.type == "QualifiedName") {
10313
+ throw new Error("Unexpected QualifiedName found!");
10314
+ }
10315
+ if (v.type == "SubList") {
10316
+ return resolve_file_list(v.values);
10317
+ }
10318
+ let resolved = resolve_filename(v, default_source);
10319
+ if (/[*?\[\]\{\}]/.test(resolved)) {
10320
+ // Jungle files can contain "./**.mc" which is supposed to match
10321
+ // any mc file under "./". The standard way to express that
10322
+ // is "./**/*.mc", which is what glob expects, so translate.
10323
+ resolved = resolved.replace(/[\\\/]\*\*([^\\\/])/g, "/**/*$1");
10324
+ const match = await (0,external_util_cjs_namespaceObject.globa)(resolved);
10325
+ return match.length ? resolved : null;
10326
+ }
10327
+ else {
10328
+ const stat = await promises_namespaceObject.stat(resolved).catch(() => null);
10329
+ return stat ? resolved : null;
10330
+ }
10331
+ }))).filter((name) => name != null);
10332
+ const resolve_one_file_list = async (base, name) => {
10333
+ const bname = base[name];
10334
+ if (!bname)
10335
+ return;
10336
+ const result = await resolve_file_list(bname);
10337
+ if (!result || !result.length) {
10338
+ delete base[name];
10339
+ }
10340
+ else {
10341
+ base[name] = result;
10342
+ }
10343
+ };
10344
+ await resolve_one_file_list(qualifier, "sourcePath");
10345
+ await resolve_one_file_list(qualifier, "resourcePath");
10346
+ await resolve_one_file_list(qualifier, "barrelPath");
10347
+ const lang = qualifier["lang"];
10348
+ if (lang) {
10349
+ await Promise.all(Object.keys(lang).map((key) => resolve_one_file_list(lang, key)));
10350
+ if (Object.keys(lang).length === 0)
10351
+ delete qualifier["lang"];
10317
10352
  }
10318
- };
10319
-
10320
- await resolve_one_file_list(qualifier, "sourcePath");
10321
- await resolve_one_file_list(qualifier, "resourcePath");
10322
- await resolve_one_file_list(qualifier, "barrelPath");
10323
- const lang = qualifier["lang"];
10324
- if (lang) {
10325
- await Promise.all(
10326
- Object.keys(lang).map((key) => resolve_one_file_list(lang, key))
10327
- );
10328
- if (Object.keys(lang).length === 0) delete qualifier["lang"];
10329
- } else {
10330
- delete qualifier["lang"];
10331
- }
10332
-
10333
- const resolve_literal_list = (base, name) => {
10334
- const literals = base[name];
10335
- if (!literals || !literals.length) return;
10336
- base[name] = literals.map((v) => v.value);
10337
- };
10338
- resolve_literal_list(qualifier, "excludeAnnotations");
10339
- // turn the annotations inside out.
10340
- // in the jungle we have
10341
- // qualifier.BarrelName.annotations = Foo;Bar
10342
- // but its more convenient as
10343
- // qualifier.annotations.BarrelName = Foo;Bar
10344
- const annotations = {};
10345
- Object.entries(qualifier).forEach(([k, v]) => {
10346
- if ((0,external_api_cjs_namespaceObject.hasProperty)(v, "annotations")) {
10347
- annotations[k] = v.annotations;
10348
- resolve_literal_list(annotations, k);
10349
- delete qualifier[k];
10353
+ else {
10354
+ delete qualifier["lang"];
10350
10355
  }
10351
- });
10352
- qualifier.annotations = annotations;
10356
+ const resolve_literal_list = (base, name) => {
10357
+ const literals = base[name];
10358
+ if (!literals || !literals.length)
10359
+ return;
10360
+ base[name] = literals.map((v) => v.value);
10361
+ };
10362
+ resolve_literal_list(qualifier, "excludeAnnotations");
10363
+ // turn the annotations inside out.
10364
+ // in the jungle we have
10365
+ // qualifier.BarrelName.annotations = Foo;Bar
10366
+ // but its more convenient as
10367
+ // qualifier.annotations.BarrelName = Foo;Bar
10368
+ const annotations = {};
10369
+ Object.entries(qualifier).forEach(([k, v]) => {
10370
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(v, "annotations")) {
10371
+ annotations[k] = v["annotations"];
10372
+ resolve_literal_list(annotations, k);
10373
+ delete qualifier[k];
10374
+ }
10375
+ });
10376
+ qualifier.annotations = annotations;
10377
+ return qualifier;
10353
10378
  }
10354
-
10355
10379
  async function find_build_instructions_in_resource(file) {
10356
- const data = await promises_namespaceObject.readFile(file);
10357
- const rez = await (0,xml2js.parseStringPromise)(data).catch(() => ({}));
10358
- if (rez.build && rez.build.exclude) {
10380
+ const data = await promises_namespaceObject.readFile(file);
10381
+ const rez = await (0,xml2js.parseStringPromise)(data).catch(() => ({}));
10382
+ if (!rez.build || !rez.build.exclude)
10383
+ return null;
10359
10384
  const dir = external_path_.dirname(file);
10360
10385
  const sourceExcludes = rez.build.exclude
10361
- .map((e) => e.$.file)
10362
- .filter((f) => f != null)
10363
- .map((f) => external_path_.resolve(dir, f).replace(/\\/g, "/"));
10364
-
10386
+ .map((e) => e.$.file)
10387
+ .filter((f) => f != null)
10388
+ .map((f) => external_path_.resolve(dir, f).replace(/\\/g, "/"));
10365
10389
  const filePatterns = rez.build.exclude
10366
- .map((e) => e.$.dir)
10367
- .filter((f) => f != null)
10368
- .map((f) => external_path_.join(dir, f, "**", "*.mc").replace(/\\/g, "/"));
10390
+ .map((e) => e.$.dir)
10391
+ .filter((f) => f != null)
10392
+ .map((f) => external_path_.join(dir, f, "**", "*.mc").replace(/\\/g, "/"));
10369
10393
  if (filePatterns.length) {
10370
- const files = (
10371
- await Promise.all(filePatterns.map((p) => (0,external_util_cjs_namespaceObject.globa)(p)))
10372
- ).flat();
10373
- sourceExcludes.push(...files);
10394
+ const files = (await Promise.all(filePatterns.map((p) => (0,external_util_cjs_namespaceObject.globa)(p)))).flat();
10395
+ sourceExcludes.push(...files);
10374
10396
  }
10375
10397
  const excludeAnnotations = rez.build.exclude
10376
- .map((e) => e.$.annotation)
10377
- .filter((f) => f != null);
10398
+ .map((e) => e.$.annotation)
10399
+ .filter((f) => f != null);
10378
10400
  return { sourceExcludes, excludeAnnotations };
10379
- }
10380
10401
  }
10381
10402
  async function find_build_instructions(targets) {
10382
- const resourceGroups = {};
10383
- await Promise.all(
10384
- targets.map(async (p) => {
10385
- if (!p.qualifier.resourcePath) return;
10386
- const key = p.qualifier.resourcePath.join(";");
10387
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(resourceGroups, key)) {
10388
- resourceGroups[key] = {
10389
- resourcePath: p.qualifier.resourcePath,
10390
- products: [],
10391
- };
10392
- const paths = (
10393
- await Promise.all(
10394
- p.qualifier.resourcePath.map((pattern) =>
10395
- (0,external_util_cjs_namespaceObject.globa)(pattern, { mark: true })
10396
- )
10397
- )
10398
- ).flat();
10399
-
10400
- const sourceExcludes = [];
10401
- const excludeAnnotations = [];
10402
- const resourceFiles = await Promise.all(
10403
- paths.map((path) =>
10404
- path.endsWith("/") ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.xml`, { mark: true }) : path
10405
- )
10406
- );
10407
- const buildInstructions = await Promise.all(
10408
- resourceFiles
10409
- .flat()
10410
- .filter((file) => !file.endsWith("/"))
10411
- .map((file) => find_build_instructions_in_resource(file))
10412
- );
10413
- buildInstructions
10414
- .filter((i) => i != null)
10415
- .map((i) => {
10416
- if (i.sourceExcludes) sourceExcludes.push(...i.sourceExcludes);
10417
- if (i.excludeAnnotations)
10418
- excludeAnnotations.push(...i.excludeAnnotations);
10419
- });
10420
- if (sourceExcludes.length) {
10421
- p.qualifier.sourceExcludes = sourceExcludes;
10422
- }
10423
- if (excludeAnnotations.length) {
10424
- if (p.qualifier.excludeAnnotations) {
10425
- p.qualifier.excludeAnnotations.push(excludeAnnotations);
10426
- } else {
10427
- p.qualifier.excludeAnnotations = excludeAnnotations;
10428
- }
10403
+ const resourceGroups = {};
10404
+ await Promise.all(targets.map(async (p) => {
10405
+ if (!p.qualifier.resourcePath)
10406
+ return;
10407
+ const key = p.qualifier.resourcePath.join(";");
10408
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(resourceGroups, key)) {
10409
+ resourceGroups[key] = {
10410
+ resourcePath: p.qualifier.resourcePath,
10411
+ products: [],
10412
+ };
10413
+ const paths = (await Promise.all(p.qualifier.resourcePath.map((pattern) => (0,external_util_cjs_namespaceObject.globa)(pattern, { mark: true })))).flat();
10414
+ const sourceExcludes = [];
10415
+ const excludeAnnotations = [];
10416
+ const resourceFiles = await Promise.all(paths.map((path) => path.endsWith("/") ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.xml`, { mark: true }) : path));
10417
+ const buildInstructions = await Promise.all(resourceFiles
10418
+ .flat()
10419
+ .filter((file) => !file.endsWith("/"))
10420
+ .map((file) => find_build_instructions_in_resource(file)));
10421
+ buildInstructions
10422
+ .filter((i) => i != null)
10423
+ .map((i) => {
10424
+ if (i.sourceExcludes)
10425
+ sourceExcludes.push(...i.sourceExcludes);
10426
+ if (i.excludeAnnotations)
10427
+ excludeAnnotations.push(...i.excludeAnnotations);
10428
+ });
10429
+ if (sourceExcludes.length) {
10430
+ p.qualifier.sourceExcludes = sourceExcludes;
10431
+ }
10432
+ if (excludeAnnotations.length) {
10433
+ if (p.qualifier.excludeAnnotations) {
10434
+ p.qualifier.excludeAnnotations.push(...excludeAnnotations);
10435
+ }
10436
+ else {
10437
+ p.qualifier.excludeAnnotations = excludeAnnotations;
10438
+ }
10439
+ }
10429
10440
  }
10430
- }
10431
- resourceGroups[key].products.push(p.product);
10432
- })
10433
- );
10441
+ resourceGroups[key].products.push(p.product);
10442
+ }));
10434
10443
  }
10435
-
10436
10444
  function identify_optimizer_groups(targets, options) {
10437
- const groups = {};
10438
- let key = 0;
10439
- const ignoreStrOption = (str) =>
10440
- str == null
10441
- ? null
10442
- : str === "*"
10443
- ? "*"
10444
- : Object.fromEntries(str.split(";").map((e) => [e, true]));
10445
- const getStrsWithIgnore = (strs, option) => {
10446
- if (option === "*") {
10447
- return [];
10448
- } else {
10449
- return strs.filter((a) => !(0,external_api_cjs_namespaceObject.hasProperty)(option, a));
10450
- }
10451
- };
10452
- const ignoreRegExpOption = (str) => {
10453
- try {
10454
- if (!str) return null;
10455
- return new RegExp(str);
10456
- } catch {
10457
- return null;
10458
- }
10459
- };
10460
-
10461
- const ignoredExcludeAnnotations = ignoreStrOption(
10462
- options.ignoredExcludeAnnotations
10463
- );
10464
- const ignoredAnnotations = ignoreStrOption(options.ignoredAnnotations);
10465
- const ignoredSourcePathsRe = ignoreRegExpOption(options.ignoredSourcePaths);
10466
-
10467
- const ignoredSourcePaths = ignoredSourcePathsRe
10468
- ? targets.reduce(
10469
- (state, target) => {
10470
- if (target.qualifier.sourcePath) {
10471
- target.qualifier.sourcePath.forEach((path) => {
10472
- const m = path.match(ignoredSourcePathsRe);
10473
- const key = m ? "key-" + m.slice(1).join("") : path;
10474
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.keys, key)) {
10475
- state.keys[key] = {};
10476
- }
10477
- state.keys[key][path] = true;
10478
- state.paths[path] = state.keys[key];
10445
+ const groups = {};
10446
+ let key = 0;
10447
+ const ignoreStrOption = (str) => str == null
10448
+ ? null
10449
+ : str === "*"
10450
+ ? "*"
10451
+ : Object.fromEntries(str.split(";").map((e) => [e, true]));
10452
+ const getStrsWithIgnore = (strs, option) => {
10453
+ if (option === "*") {
10454
+ return [];
10455
+ }
10456
+ else {
10457
+ return strs.filter((a) => !(0,external_api_cjs_namespaceObject.hasProperty)(option, a));
10458
+ }
10459
+ };
10460
+ const ignoreRegExpOption = (str) => {
10461
+ try {
10462
+ if (!str)
10463
+ return null;
10464
+ return new RegExp(str);
10465
+ }
10466
+ catch {
10467
+ return null;
10468
+ }
10469
+ };
10470
+ const ignoredExcludeAnnotations = ignoreStrOption(options.ignoredExcludeAnnotations);
10471
+ const ignoredAnnotations = ignoreStrOption(options.ignoredAnnotations);
10472
+ const ignoredSourcePathsRe = ignoreRegExpOption(options.ignoredSourcePaths);
10473
+ const ignoredSourcePaths = ignoredSourcePathsRe
10474
+ ? targets.reduce((state, target) => {
10475
+ if (target.qualifier.sourcePath) {
10476
+ target.qualifier.sourcePath.forEach((path) => {
10477
+ const m = path.match(ignoredSourcePathsRe);
10478
+ const key = m ? "key-" + m.slice(1).join("") : path;
10479
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.keys, key)) {
10480
+ state.keys[key] = {};
10481
+ }
10482
+ state.keys[key][path] = true;
10483
+ state.paths[path] = state.keys[key];
10484
+ });
10485
+ }
10486
+ return state;
10487
+ }, { keys: {}, paths: {} }).paths
10488
+ : null;
10489
+ targets.forEach((target) => {
10490
+ let { sourcePath, sourceExcludes, barrelPath, barrelMap, excludeAnnotations, annotations, } = target.qualifier;
10491
+ if (excludeAnnotations && ignoredExcludeAnnotations) {
10492
+ excludeAnnotations = getStrsWithIgnore(excludeAnnotations, ignoredExcludeAnnotations);
10493
+ }
10494
+ annotations &&
10495
+ Object.entries(annotations).forEach(([key, value]) => {
10496
+ if (ignoredAnnotations) {
10497
+ annotations[key] = getStrsWithIgnore(value, ignoredAnnotations);
10498
+ }
10479
10499
  });
10480
- }
10481
- return state;
10482
- },
10483
- { keys: {}, paths: {} }
10484
- ).paths
10485
- : null;
10486
-
10487
- targets.forEach((target) => {
10488
- let {
10489
- sourcePath,
10490
- sourceExcludes,
10491
- barrelPath,
10492
- barrelMap,
10493
- excludeAnnotations,
10494
- annotations,
10495
- } = target.qualifier;
10496
- if (excludeAnnotations && ignoredExcludeAnnotations) {
10497
- excludeAnnotations = getStrsWithIgnore(
10498
- excludeAnnotations,
10499
- ignoredExcludeAnnotations
10500
- );
10501
- }
10502
- Object.entries(annotations).forEach(([key, value]) => {
10503
- if (ignoredAnnotations) {
10504
- annotations[key] = getStrsWithIgnore(value, ignoredAnnotations);
10505
- }
10500
+ if (ignoredSourcePaths) {
10501
+ sourcePath = sourcePath
10502
+ ?.map((path) => Object.keys(ignoredSourcePaths[path]))
10503
+ .flat()
10504
+ .sort()
10505
+ .filter((v, i, a) => i === 0 || v !== a[i - 1]);
10506
+ }
10507
+ const optimizerConfig = {
10508
+ sourcePath,
10509
+ sourceExcludes,
10510
+ barrelPath,
10511
+ barrelMap,
10512
+ excludeAnnotations,
10513
+ annotations,
10514
+ };
10515
+ const toSortedEntries = (value) => Object.entries(value)
10516
+ .filter(([, v]) => v != null)
10517
+ .sort((a, b) => (a[0] < b[0] ? -1 : a[0] === b[0] ? 0 : 1));
10518
+ const serialized = JSON.stringify(optimizerConfig, function (key, value) {
10519
+ if (!value || Array.isArray(value) || typeof value !== "object") {
10520
+ return value;
10521
+ }
10522
+ if (key === "" && barrelMap) {
10523
+ const bm = toSortedEntries(barrelMap).map(([k, v]) => {
10524
+ const { jungles, qualifier } = v;
10525
+ return [k, [jungles, qualifier]];
10526
+ });
10527
+ value = { ...value, barrelMap: bm };
10528
+ }
10529
+ return toSortedEntries(value);
10530
+ });
10531
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(groups, serialized)) {
10532
+ groups[serialized] = {
10533
+ key: "group" + key.toString().padStart(3, "0"),
10534
+ optimizerConfig,
10535
+ };
10536
+ key++;
10537
+ }
10538
+ target.group = groups[serialized];
10506
10539
  });
10507
- if (ignoredSourcePaths) {
10508
- sourcePath = sourcePath
10509
- .map((path) => Object.keys(ignoredSourcePaths[path]))
10510
- .flat()
10511
- .sort()
10512
- .filter((v, i, a) => i === 0 || v !== a[i - 1]);
10513
- }
10514
- const optimizerConfig = {
10515
- sourcePath,
10516
- sourceExcludes,
10517
- barrelPath,
10518
- barrelMap,
10519
- excludeAnnotations,
10520
- annotations,
10521
- };
10522
-
10523
- const serialized = JSON.stringify(
10524
- optimizerConfig,
10525
- Object.keys(optimizerConfig).sort()
10526
- );
10527
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(groups, serialized)) {
10528
- groups[serialized] = {
10529
- key: "group" + key.toString().padStart(3, "0"),
10530
- optimizerConfig,
10531
- };
10532
- key++;
10533
- }
10534
- target.group = groups[serialized];
10535
- });
10536
10540
  }
10537
-
10538
10541
  /**
10539
10542
  * Find the barrels referred to by barrelPath.
10540
10543
  *
@@ -10547,65 +10550,21 @@ function identify_optimizer_groups(targets, options) {
10547
10550
  * @returns {Promise<string[]>}
10548
10551
  */
10549
10552
  function find_barrels(barrelPath) {
10550
- if (Array.isArray(barrelPath)) {
10551
- // This is a sublist. The barrel has more than one jungle file.
10552
- return Promise.all(
10553
- barrelPath.map((path) => (0,external_util_cjs_namespaceObject.globa)(path, { mark: true }))
10554
- ).then((paths) => [
10555
- paths
10556
- .flat()
10557
- .filter((path) => path.endsWith(".jungle"))
10558
- .join(";"),
10559
- ]);
10560
- }
10561
- return (0,external_util_cjs_namespaceObject.globa)(barrelPath, { mark: true })
10562
- .then((paths) =>
10563
- Promise.all(
10564
- paths.map((path) =>
10565
- path.endsWith("/") ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.barrel`) : path
10566
- )
10567
- )
10568
- )
10569
- .then((barrelPaths) =>
10570
- barrelPaths
10553
+ if (Array.isArray(barrelPath)) {
10554
+ // This is a sublist. The barrel has more than one jungle file.
10555
+ return Promise.all(barrelPath.map((path) => (0,external_util_cjs_namespaceObject.globa)(path, { mark: true }))).then((paths) => [
10556
+ paths
10557
+ .flat()
10558
+ .filter((path) => path.endsWith(".jungle"))
10559
+ .join(";"),
10560
+ ]);
10561
+ }
10562
+ return (0,external_util_cjs_namespaceObject.globa)(barrelPath, { mark: true })
10563
+ .then((paths) => Promise.all(paths.map((path) => path.endsWith("/") ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.barrel`) : path)))
10564
+ .then((barrelPaths) => barrelPaths
10571
10565
  .flat()
10572
- .filter((path) => path.endsWith(".jungle") || path.endsWith(".barrel"))
10573
- );
10566
+ .filter((path) => path.endsWith(".jungle") || path.endsWith(".barrel")));
10574
10567
  }
10575
-
10576
- /**
10577
- *@typedef {Object} Target - Build instructions for a particular product in a jungle
10578
- *
10579
- * @typedef {Object} JungleInfoBase - The result of parsing a jungle file, without resolving any products
10580
- * @property {string[]} jungles - Paths to the barrel's jungle files
10581
- * @property {string} manifest - Path to the barrel's manifest file
10582
- * @property {Object} xml - The xml content of the manifest, as returned by xml2js
10583
- * @property {string[]=} annotations - Array of annotations supported by this barrel
10584
- *
10585
- * @typedef {Object} PartialJungle - Used to extend JungleInfoBase to ResolvedJungle
10586
- * @property {Target[]} targets - All of the supported targets in the manifest
10587
- *
10588
- * @typedef {Object} PartialBarrel - Used to extend JungleInfoBase to ResolvedBarrel
10589
- * @property {JungleQualifier} qualifier - the qualifier for this PartialBarrel's target
10590
- *
10591
- * @typedef {JungleInfoBase & PartialJungle} ResolvedJungle - The result of parsing an application's jungle file
10592
- * @typedef {JungleInfoBase & PartialBarrel} ResolvedBarrel - The result of parsing a barrel's jungle file for a particular product
10593
- *
10594
- * @typedef {Object} JungleQualifier
10595
- * @property {string[]=} sourcePath - locations to find source file
10596
- * @property {string[]=} sourceExcludes - array of files to exclude from the build (from resource build instructions)
10597
- * @property {string[]=} excludeAnnotations - array of excludeAnnotations
10598
- * @property {string[]=} resourcePath - locations to find resource files
10599
- * @property {LangResourcePaths} lang - locations to find resource files
10600
- * @property {(string|string[])[]=} barrelPath - locations to find barrels
10601
- * @property {BarrelAnnotations=} annotations - map from barrel names to arrays of annotations
10602
- * @property {BarrelMap=} barrelMap
10603
- *
10604
- * @typedef {{[key:string]:string[]}} LangResourcePaths - Map from language codes to the corresponding resource paths
10605
- * @typedef {{[key:string]:string[]}} BarrelAnnotations - Map from barrel name to imported annotations
10606
- * @typedef {{[key:string]:ResolvedBarrel}} BarrelMap - Map from barrel name to the set of resolved barrel projects for that name. Note that they must all share a manifest.
10607
- */
10608
-
10609
10568
  /**
10610
10569
  * Given a .barrel file, unpack it into barrelDir, then process its .jungle file as below
10611
10570
  * Given a .jungle file, resolve it to a ResolvedJungle
@@ -10613,53 +10572,43 @@ function find_barrels(barrelPath) {
10613
10572
  * @param {string} barrel Path to a .jungle or .barrel file to resolve
10614
10573
  * @param {string} barrelDir Directory where .barrel files should be unpacked
10615
10574
  * @param {string[]} products The products supported by the importing project
10616
- * @param {*} options
10575
+ * @param {BuildConfig} options
10617
10576
  * @returns {Promise<ResolvedJungle>}
10618
10577
  */
10619
10578
  function resolve_barrel(barrel, barrelDir, products, options) {
10620
- const cache = options._cache;
10621
- if ((0,external_api_cjs_namespaceObject.hasProperty)(cache.barrels, barrel)) {
10622
- return cache.barrels[barrel];
10623
- }
10624
- let promise = Promise.resolve();
10625
- let rawBarrel = barrel;
10626
- if (barrel.endsWith(".barrel")) {
10627
- // A barrel with the given name could in theory resolve to a different physical
10628
- // barrel file for each product, so uniqify the local name with a sha1.
10629
- const sha1 = external_crypto_namespaceObject.createHash("sha1")
10630
- .update(barrel, "binary")
10631
- .digest("base64")
10632
- .replace(/[\/=+]/g, "");
10633
- const localPath = external_path_.resolve(
10634
- barrelDir,
10635
- `${external_path_.basename(barrel, ".barrel")}-${sha1}`
10636
- );
10637
- rawBarrel = external_path_.resolve(localPath, "barrel.jungle");
10638
- promise = promise.then(() =>
10639
- promises_namespaceObject.stat(localPath)
10640
- .then(
10641
- (localStat) =>
10642
- !localStat.isDirectory() ||
10579
+ const cache = options._cache;
10580
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(cache.barrels, barrel)) {
10581
+ return cache.barrels[barrel];
10582
+ }
10583
+ let promise = Promise.resolve();
10584
+ let rawBarrel = barrel;
10585
+ if (barrel.endsWith(".barrel")) {
10586
+ // A barrel with the given name could in theory resolve to a different physical
10587
+ // barrel file for each product, so uniqify the local name with a sha1.
10588
+ const sha1 = external_crypto_namespaceObject.createHash("sha1")
10589
+ .update(barrel, "binary")
10590
+ .digest("base64")
10591
+ .replace(/[\/=+]/g, "");
10592
+ const localPath = external_path_.resolve(barrelDir, `${external_path_.basename(barrel, ".barrel")}-${sha1}`);
10593
+ rawBarrel = external_path_.resolve(localPath, "barrel.jungle");
10594
+ promise = promise.then(() => promises_namespaceObject.stat(localPath)
10595
+ .then((localStat) => !localStat.isDirectory() ||
10643
10596
  promises_namespaceObject.stat(barrel)
10644
- .then((barrelStat) => localStat.mtimeMs < barrelStat.mtimeMs),
10645
- () => true
10646
- )
10647
- .then(
10648
- (needsUpdate) =>
10597
+ .then((barrelStat) => localStat.mtimeMs < barrelStat.mtimeMs), () => true)
10598
+ .then((needsUpdate) => {
10649
10599
  needsUpdate &&
10650
- promises_namespaceObject.rm(localPath, { recursive: true, force: true })
10651
- .then(() => extract_zip(barrel, { dir: localPath }))
10652
- )
10653
- );
10654
- }
10655
- return promise
10656
- .then(() => get_jungle_and_barrels(rawBarrel, products, options))
10657
- .then((result) => {
10658
- if (!cache.barrels) cache.barrels = {};
10659
- return (cache.barrels[barrel] = { ...result });
10600
+ promises_namespaceObject.rm(localPath, { recursive: true, force: true })
10601
+ .then(() => extract_zip(barrel, { dir: localPath }));
10602
+ }));
10603
+ }
10604
+ return promise
10605
+ .then(() => get_jungle_and_barrels(rawBarrel, products, options))
10606
+ .then((result) => {
10607
+ if (!cache.barrels)
10608
+ cache.barrels = {};
10609
+ return (cache.barrels[barrel] = { ...result });
10660
10610
  });
10661
10611
  }
10662
-
10663
10612
  /**
10664
10613
  * Find and resolve the BarrelMap for product, and add it to qualifier.
10665
10614
  *
@@ -10667,944 +10616,975 @@ function resolve_barrel(barrel, barrelDir, products, options) {
10667
10616
  * @param {JungleQualifier} qualifier The qualifier for product from the main jungle
10668
10617
  * @param {string[]} barrels The barrels imported by the project's manifest
10669
10618
  * @param {string[]} products The products supported by the importing project (used when the barrel project has none)
10670
- * @param {*} options
10619
+ * @param {BuildConfig} options
10671
10620
  * @returns {Promise<void>}
10672
10621
  */
10673
10622
  function resolve_barrels(product, qualifier, barrels, products, options) {
10674
- if (qualifier.annotations) {
10675
- Object.keys(qualifier.annotations).forEach((key) => {
10676
- // delete annotations for non-existent barrels such as
10677
- if (!barrels.includes(key)) {
10678
- delete qualifier.annotations[key];
10679
- }
10680
- });
10681
- }
10682
- if (!barrels.length) {
10683
- delete qualifier.barrelPath;
10684
- return;
10685
- }
10686
- const cache = options._cache || (options._cache = {});
10687
- const barrelMapKey = JSON.stringify([barrels, qualifier.barrelPath]);
10688
- const setBarrelMap = (barrelMap) => {
10689
- qualifier.barrelMap = barrels.reduce((result, barrel) => {
10690
- const { targets, ...rest } = barrelMap[barrel];
10691
- const target = targets.find((t) => t.product === product);
10692
- if (!target) {
10693
- throw new Error(`Barrel ${barrel} does not support device ${product}`);
10694
- }
10695
- rest.qualifier = target.qualifier;
10696
- result[barrel] = rest;
10697
- return result;
10698
- }, {});
10699
- };
10700
- if ((0,external_api_cjs_namespaceObject.hasProperty)(cache.barrelMap, barrelMapKey)) {
10701
- setBarrelMap(cache.barrelMap[barrelMapKey]);
10702
- return;
10703
- }
10704
- const barrelDir = external_path_.resolve(
10705
- options.workspace,
10706
- options.outputPath,
10707
- "raw-barrels"
10708
- );
10709
- const barrelMap = Object.fromEntries(barrels.map((b) => [b, null]));
10710
- return (qualifier.barrelPath || [])
10711
- .reduce(
10712
- (promise, barrelPath) =>
10713
- promise
10714
- .then(() => find_barrels(barrelPath))
10715
- .then((barrelPaths) => {
10716
- return Promise.all(
10717
- barrelPaths.map((barrel) =>
10718
- resolve_barrel(barrel, barrelDir, products, options)
10719
- )
10720
- );
10721
- })
10722
- .then((resolvedBarrels) => {
10723
- resolvedBarrels.forEach((resolvedBarrel) => {
10724
- const name = manifestBarrelName(
10725
- resolvedBarrel.manifest,
10726
- resolvedBarrel.xml
10727
- );
10728
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(barrelMap, name)) return;
10729
- if (barrelMap[name]) {
10623
+ if (qualifier.annotations) {
10624
+ Object.keys(qualifier.annotations).forEach((key) => {
10625
+ // delete annotations for non-existent barrels such as
10626
+ if (!barrels.includes(key)) {
10627
+ delete qualifier.annotations[key];
10628
+ }
10629
+ });
10630
+ }
10631
+ if (!barrels.length) {
10632
+ delete qualifier.barrelPath;
10633
+ return null;
10634
+ }
10635
+ const cache = options._cache || (options._cache = {});
10636
+ const barrelMapKey = JSON.stringify([barrels, qualifier.barrelPath]);
10637
+ const setBarrelMap = (barrelMap) => {
10638
+ qualifier.barrelMap = barrels.reduce((result, barrel) => {
10639
+ const { targets, ...rest } = barrelMap[barrel];
10640
+ const target = targets.find((t) => t.product === product);
10641
+ if (!target) {
10642
+ throw new Error(`Barrel ${barrel} does not support device ${product}`);
10643
+ }
10644
+ const resolvedBarrel = { qualifier: target.qualifier, ...rest };
10645
+ result[barrel] = resolvedBarrel;
10646
+ return result;
10647
+ }, {});
10648
+ };
10649
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(cache.barrelMap, barrelMapKey)) {
10650
+ setBarrelMap(cache.barrelMap[barrelMapKey]);
10651
+ return null;
10652
+ }
10653
+ const barrelDir = external_path_.resolve(options.workspace, options.outputPath, "raw-barrels");
10654
+ const barrelMap = Object.fromEntries(barrels.map((b) => [b, null]));
10655
+ return (qualifier.barrelPath || [])
10656
+ .reduce((promise, barrelPath) => promise
10657
+ .then(() => find_barrels(barrelPath))
10658
+ .then((barrelPaths) => {
10659
+ return Promise.all(barrelPaths.map((barrel) => resolve_barrel(barrel, barrelDir, products, options)));
10660
+ })
10661
+ .then((resolvedBarrels) => {
10662
+ resolvedBarrels.forEach((resolvedBarrel) => {
10663
+ const name = manifestBarrelName(resolvedBarrel.manifest, resolvedBarrel.xml);
10664
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(barrelMap, name))
10665
+ return;
10666
+ const bmapName = barrelMap[name];
10667
+ if (bmapName) {
10730
10668
  const bname = (r) => r.jungles.join(";");
10731
- throw new Error(
10732
- `Barrel ${name} already resolved to ${bname(
10733
- barrelMap[name]
10734
- )}; can't also resolve to ${bname(resolvedBarrel)}`
10735
- );
10736
- }
10737
- barrelMap[name] = resolvedBarrel;
10738
- });
10739
- }),
10740
- Promise.resolve()
10741
- )
10742
- .then(() => {
10743
- const unresolved = Object.entries(barrelMap).filter((v) => v[1] === null);
10744
- if (unresolved.length) {
10745
- throw new Error(
10746
- `Failed to resolve some barrels: ${unresolved
10747
- .map(([name]) => name)
10748
- .join(",")}`
10749
- );
10750
- }
10751
- if (!cache.barrelMap) cache.barrelMap = {};
10752
- cache.barrelMap[barrelMapKey] = barrelMap;
10753
- setBarrelMap(barrelMap);
10669
+ throw new Error(`Barrel ${name} already resolved to ${bname(bmapName)}; can't also resolve to ${bname(resolvedBarrel)}`);
10670
+ }
10671
+ barrelMap[name] = resolvedBarrel;
10672
+ });
10673
+ }), Promise.resolve())
10674
+ .then(() => {
10675
+ const unresolved = Object.entries(barrelMap).filter((v) => v[1] === null);
10676
+ if (unresolved.length) {
10677
+ throw new Error(`Failed to resolve some barrels: ${unresolved
10678
+ .map(([name]) => name)
10679
+ .join(",")}`);
10680
+ }
10681
+ const finalMap = barrelMap;
10682
+ if (!cache.barrelMap)
10683
+ cache.barrelMap = {};
10684
+ cache.barrelMap[barrelMapKey] = finalMap;
10685
+ setBarrelMap(finalMap);
10754
10686
  });
10755
10687
  }
10756
10688
  /**
10757
10689
  *
10758
10690
  * @param {string} jungleFiles Semicolon separated list of jungle files
10759
10691
  * @param {string[]} defaultProducts Default set of products. Only used by a barrel with no products of its own
10760
- * @param {*} options
10692
+ * @param {BuildConfig} options
10761
10693
  * @returns {Promise<ResolvedJungle>}
10762
10694
  */
10763
10695
  async function get_jungle_and_barrels(jungleFiles, defaultProducts, options) {
10764
- const jungles = jungleFiles
10765
- .split(";")
10766
- .map((jungle) => external_path_.resolve(options.workspace || "./", jungle));
10767
- const barrels_jungle = external_path_.resolve(
10768
- external_path_.dirname(jungles[0]),
10769
- "barrels.jungle"
10770
- );
10771
- if (!jungles.includes(barrels_jungle)) {
10772
- if (
10773
- await promises_namespaceObject.stat(barrels_jungle)
10774
- .then((s) => s.isFile())
10775
- .catch(() => false)
10776
- ) {
10777
- jungles.push(barrels_jungle);
10778
- }
10779
- }
10780
- const state = await process_jungles(jungles);
10781
- // apparently square_watch is an alias for rectangle_watch
10782
- state["square_watch"] = state["rectangle_watch"];
10783
- const manifest_node = resolve_node(
10784
- state,
10785
- resolve_node_by_path(state, ["project", "manifest"])
10786
- );
10787
- if (!manifest_node) throw new Error("No manifest found!");
10788
- const manifest = resolve_filename(manifest_node[0]);
10789
- if (!options.workspace) {
10790
- options.workspace = external_path_.dirname(manifest);
10791
- }
10792
- const xml = await readManifest(manifest);
10793
- const targets = [];
10794
- const barrels = manifestBarrels(xml);
10795
- const annotations = manifestAnnotations(xml);
10796
- const products = manifestProducts(xml);
10797
- if (products.length === 0) products.push(...defaultProducts);
10798
- let promise = Promise.resolve();
10799
- const add_one = (product, shape) => {
10800
- const qualifier = resolve_node(state, state[product]);
10801
- if (!qualifier) return;
10802
- promise = promise
10803
- .then(() => resolve_literals(qualifier, manifest))
10804
- .then(() =>
10805
- resolve_barrels(product, qualifier, barrels, products, options)
10806
- )
10807
- .then(() => {
10808
- targets.push({ product, qualifier, shape });
10809
- });
10810
- };
10811
- products.forEach((product) => {
10812
- if ((0,external_api_cjs_namespaceObject.hasProperty)(state, product) && state[product].products) {
10813
- // this was something like round_watch. Add all the corresponding
10814
- // products.
10815
- state[product].products.forEach((p) => add_one(p, product));
10816
- } else {
10817
- add_one(product);
10818
- }
10819
- });
10820
- await promise;
10821
- await find_build_instructions(targets);
10822
- return { manifest, targets, xml, annotations, jungles };
10696
+ const jungles = jungleFiles
10697
+ .split(";")
10698
+ .map((jungle) => external_path_.resolve(options.workspace || "./", jungle));
10699
+ const barrels_jungle = external_path_.resolve(external_path_.dirname(jungles[0]), "barrels.jungle");
10700
+ if (!jungles.includes(barrels_jungle)) {
10701
+ if (await promises_namespaceObject.stat(barrels_jungle)
10702
+ .then((s) => s.isFile())
10703
+ .catch(() => false)) {
10704
+ jungles.push(barrels_jungle);
10705
+ }
10706
+ }
10707
+ const state = await process_jungles(jungles);
10708
+ // apparently square_watch is an alias for rectangle_watch
10709
+ state["square_watch"] = state["rectangle_watch"];
10710
+ const manifest_node = resolve_node(state, resolve_node_by_path(state, ["project", "manifest"]));
10711
+ if (!manifest_node)
10712
+ throw new Error("No manifest found!");
10713
+ const manifest = resolve_filename(manifest_node[0]);
10714
+ if (!options.workspace) {
10715
+ options.workspace = external_path_.dirname(manifest);
10716
+ }
10717
+ const xml = await readManifest(manifest);
10718
+ const targets = [];
10719
+ const barrels = manifestBarrels(xml);
10720
+ const annotations = manifestAnnotations(xml);
10721
+ const products = manifestProducts(xml);
10722
+ if (products.length === 0)
10723
+ products.push(...defaultProducts);
10724
+ let promise = Promise.resolve();
10725
+ const add_one = (product, shape = undefined) => {
10726
+ const rawQualifier = resolve_node(state, state[product]);
10727
+ if (!rawQualifier || Array.isArray(rawQualifier))
10728
+ return;
10729
+ promise = promise
10730
+ .then(() => resolve_literals(rawQualifier, manifest))
10731
+ .then((qualifier) => {
10732
+ targets.push({ product, qualifier, shape });
10733
+ return resolve_barrels(product, qualifier, barrels, products, options);
10734
+ })
10735
+ .then(() => { });
10736
+ };
10737
+ products.forEach((product) => {
10738
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(state, product)) {
10739
+ const sp = state[product];
10740
+ if (sp && !Array.isArray(sp) && sp.products) {
10741
+ // this was something like round_watch. Add all the corresponding
10742
+ // products.
10743
+ sp.products.forEach((p) => add_one(p, product));
10744
+ }
10745
+ else {
10746
+ add_one(product);
10747
+ }
10748
+ }
10749
+ });
10750
+ await promise;
10751
+ await find_build_instructions(targets);
10752
+ return { manifest, targets, xml, annotations, jungles };
10823
10753
  }
10824
-
10825
10754
  async function get_jungle(jungles, options) {
10826
- options = options || {};
10827
- const result = await get_jungle_and_barrels(jungles, [], options);
10828
- identify_optimizer_groups(result.targets, options);
10829
- return result;
10755
+ options = options || {};
10756
+ const result = await get_jungle_and_barrels(jungles, [], options);
10757
+ identify_optimizer_groups(result.targets, options);
10758
+ return result;
10830
10759
  }
10831
10760
 
10832
10761
  ;// CONCATENATED MODULE: external "child_process"
10833
10762
  const external_child_process_namespaceObject = require("child_process");
10834
- ;// CONCATENATED MODULE: ./src/launch.js
10835
-
10763
+ ;// CONCATENATED MODULE: ./src/launch.ts
10836
10764
 
10837
10765
 
10838
10766
 
10839
10767
 
10840
10768
  function launchSimulator() {
10841
- return (0,external_sdk_util_cjs_namespaceObject.getSdkPath)().then((sdk) => {
10842
- const child = (0,external_child_process_namespaceObject.execFile)(
10843
- external_path_.resolve(sdk, "bin", external_sdk_util_cjs_namespaceObject.isWin ? "simulator" : "connectiq")
10844
- );
10845
- child.unref();
10846
- });
10769
+ return (0,external_sdk_util_cjs_namespaceObject.getSdkPath)().then((sdk) => {
10770
+ const child = (0,external_child_process_namespaceObject.execFile)(external_path_.resolve(sdk, "bin", external_sdk_util_cjs_namespaceObject.isWin ? "simulator" : "connectiq"));
10771
+ child.unref();
10772
+ });
10847
10773
  }
10848
-
10849
- function simulateProgram(prg, device) {
10850
- return getSdkPath().then((sdk) =>
10851
- spawnByLine(path.resolve(sdk, "bin", "monkeydo"), [prg, device], (line) =>
10852
- console.log(line)
10853
- )
10854
- );
10774
+ function simulateProgram(prg, device, test) {
10775
+ const args = [prg, device];
10776
+ if (test)
10777
+ args.push("-t");
10778
+ return (0,external_sdk_util_cjs_namespaceObject.getSdkPath)().then((sdk) => (0,external_util_cjs_namespaceObject.spawnByLine)(external_path_.resolve(sdk, "bin", "monkeydo"), args, (line) => console.log(line)).then(() => { }));
10855
10779
  }
10856
10780
 
10857
- ;// CONCATENATED MODULE: external "@markw65/prettier-plugin-monkeyc"
10858
- const prettier_plugin_monkeyc_namespaceObject = require("@markw65/prettier-plugin-monkeyc");
10859
- ;// CONCATENATED MODULE: ./src/mc-rewrite.js
10860
-
10781
+ ;// CONCATENATED MODULE: ./src/mc-rewrite.ts
10861
10782
 
10862
10783
 
10863
10784
 
10864
10785
 
10865
10786
  function processImports(allImports, lookup) {
10866
- allImports.forEach(({ node, stack }) => {
10867
- const [name, module] = lookup(node.id, node.as && node.as.name, stack);
10868
- if (name && module) {
10869
- const [parent] = stack.slice(-1);
10870
- if (!parent.decls) parent.decls = {};
10871
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(parent.decls, name)) parent.decls[name] = [];
10872
- module.forEach((m) => {
10873
- if (m.type == "ModuleDeclaration") {
10874
- (0,external_util_cjs_namespaceObject.pushUnique)(parent.decls[name], m);
10787
+ allImports.forEach(({ node, stack }) => {
10788
+ const [name, module] = lookup(node.id, ("as" in node && node.as && node.as.name) || null, stack);
10789
+ if (name && module) {
10790
+ const [parent] = stack.slice(-1);
10791
+ if (!parent.decls)
10792
+ parent.decls = {};
10793
+ const decls = parent.decls;
10794
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(parent.decls, name))
10795
+ parent.decls[name] = [];
10796
+ module.forEach((m) => {
10797
+ if ((0,external_api_cjs_namespaceObject.isStateNode)(m) && m.type == "ModuleDeclaration") {
10798
+ (0,external_util_cjs_namespaceObject.pushUnique)(decls[name], m);
10799
+ }
10800
+ });
10875
10801
  }
10876
- });
10877
- }
10878
- });
10802
+ });
10879
10803
  }
10880
-
10881
10804
  function collectClassInfo(state) {
10882
- state.allClasses.forEach((elm) => {
10883
- if (elm.node.superClass) {
10884
- const [, classes] = state.lookup(elm.node.superClass, null, elm.stack);
10885
- if (classes) {
10886
- elm.superClass = classes.filter((c) => c.type == "ClassDeclaration");
10887
- }
10888
- // set it "true" if there is a superClass, but we can't find it.
10889
- if (!elm.superClass || !elm.superClass.length) elm.superClass = true;
10890
- }
10891
- });
10892
-
10893
- const markOverrides = (cls, scls) => {
10894
- if (scls === true) return;
10895
- scls.forEach((c) => {
10896
- c.decls &&
10897
- Object.values(c.decls).forEach((f) => {
10898
- if (f.type == "FunctionDeclaration") {
10899
- if ((0,external_api_cjs_namespaceObject.hasProperty)(cls.decls, f.name)) {
10900
- f.hasOverride = true;
10901
- }
10902
- }
10805
+ state.allClasses.forEach((elm) => {
10806
+ if (elm.node.superClass) {
10807
+ const [, classes] = state.lookup(elm.node.superClass, null, elm.stack);
10808
+ const superClass = classes &&
10809
+ classes.filter((c) => (0,external_api_cjs_namespaceObject.isStateNode)(c) && c.type === "ClassDeclaration");
10810
+ // set it "true" if there is a superClass, but we can't find it.
10811
+ elm.superClass = superClass && superClass.length ? superClass : true;
10812
+ }
10813
+ });
10814
+ const markOverrides = (cls, scls) => {
10815
+ if (scls === true)
10816
+ return;
10817
+ scls.forEach((c) => {
10818
+ c.decls &&
10819
+ Object.values(c.decls).forEach((funcs) => {
10820
+ funcs.forEach((f) => {
10821
+ if ((0,external_api_cjs_namespaceObject.isStateNode)(f) &&
10822
+ f.type === "FunctionDeclaration" &&
10823
+ (0,external_api_cjs_namespaceObject.hasProperty)(cls.decls, f.name)) {
10824
+ f.node.hasOverride = true;
10825
+ }
10826
+ });
10827
+ });
10828
+ if (c.superClass)
10829
+ markOverrides(cls, c.superClass);
10903
10830
  });
10904
- if (c.superClass) markOverrides(cls, c.superClass);
10831
+ };
10832
+ state.allClasses.forEach((elm) => {
10833
+ if (elm.superClass)
10834
+ markOverrides(elm, elm.superClass);
10905
10835
  });
10906
- };
10907
-
10908
- state.allClasses.forEach((elm) => {
10909
- if (elm.superClass) markOverrides(elm, elm.superClass);
10910
- });
10911
10836
  }
10912
-
10913
- async function analyze(fnMap) {
10914
- let excludeAnnotations;
10915
- const allImports = [];
10916
- const state = {
10917
- allFunctions: [],
10918
- allClasses: [],
10919
- shouldExclude(node) {
10920
- if (node.attrs && node.attrs.attrs) {
10921
- if (
10922
- node.attrs.attrs.some((attr) => {
10923
- if (attr.type != "UnaryExpression") return false;
10924
- if (attr.argument.type != "Identifier") return false;
10925
- return (0,external_api_cjs_namespaceObject.hasProperty)(excludeAnnotations, attr.argument.name);
10926
- })
10927
- ) {
10928
- return true;
10837
+ function getFileSources(fnMap) {
10838
+ return Promise.all(Object.entries(fnMap).map(([name, value]) => {
10839
+ return (value.monkeyCSource ||
10840
+ promises_namespaceObject.readFile(name)
10841
+ .then((data) => (value.monkeyCSource = data.toString().replace(/\r\n/g, "\n"))));
10842
+ })).then(() => { });
10843
+ }
10844
+ function getFileASTs(fnMap) {
10845
+ return getFileSources(fnMap).then(() => Object.entries(fnMap).reduce((ok, [name, value]) => {
10846
+ if (!value.ast) {
10847
+ try {
10848
+ value.ast = prettier_plugin_monkeyc_default().parsers.monkeyc.parse(value.monkeyCSource, null, {
10849
+ filepath: name,
10850
+ });
10851
+ }
10852
+ catch (e) {
10853
+ ok = false;
10854
+ if (e instanceof Error) {
10855
+ value.parserError = e;
10856
+ }
10857
+ else {
10858
+ value.parserError = new Error("An unknown parser error occurred");
10859
+ }
10860
+ }
10929
10861
  }
10930
- }
10931
- },
10932
- post(node) {
10933
- switch (node.type) {
10934
- case "FunctionDeclaration":
10935
- case "ClassDeclaration": {
10936
- const [scope] = state.stack.slice(-1);
10937
- const stack = state.stack.slice(0, -1);
10938
- scope.stack = stack;
10939
- (node.type == "FunctionDeclaration"
10940
- ? state.allFunctions
10941
- : state.allClasses
10942
- ).push(scope);
10943
- return;
10944
- }
10945
- case "Using":
10946
- case "ImportModule":
10947
- allImports.push({ node, stack: state.stack.slice() });
10948
- return;
10949
- }
10950
- },
10951
- };
10952
-
10953
- await (0,external_api_cjs_namespaceObject.getApiMapping)(state);
10954
-
10955
- // Mark all functions from api.mir as "special" by
10956
- // setting their bodies to null. In api.mir, they're
10957
- // all empty, which makes it look like they're
10958
- // do-nothing functions.
10959
- const markApi = (node) => {
10960
- if (node.type == "FunctionDeclaration") {
10961
- node.node.body = null;
10962
- }
10963
- if (node.decls) {
10964
- Object.values(node.decls).forEach(markApi);
10965
- }
10966
- };
10967
- markApi(state.stack[0]);
10968
-
10969
- const getAst = (source, monkeyCSource, exclude) => {
10970
- excludeAnnotations = exclude;
10971
- const ast = prettier_plugin_monkeyc_namespaceObject.parsers.monkeyc.parse(monkeyCSource, {
10972
- grammarSource: source,
10862
+ return ok;
10863
+ }, true));
10864
+ }
10865
+ async function analyze(fnMap) {
10866
+ let excludeAnnotations;
10867
+ let hasTests = false;
10868
+ const allImports = [];
10869
+ const preState = {
10870
+ allFunctions: [],
10871
+ allClasses: [],
10872
+ shouldExclude(node) {
10873
+ if ("attrs" in node &&
10874
+ node.attrs &&
10875
+ "attrs" in node.attrs &&
10876
+ node.attrs.attrs) {
10877
+ return node.attrs.attrs.reduce((drop, attr) => {
10878
+ if (attr.type != "UnaryExpression")
10879
+ return drop;
10880
+ if (attr.argument.type != "Identifier")
10881
+ return drop;
10882
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(excludeAnnotations, attr.argument.name)) {
10883
+ return true;
10884
+ }
10885
+ if (attr.argument.name == "test") {
10886
+ hasTests = true;
10887
+ }
10888
+ return drop;
10889
+ }, false);
10890
+ }
10891
+ return null;
10892
+ },
10893
+ post(node, state) {
10894
+ switch (node.type) {
10895
+ case "FunctionDeclaration":
10896
+ case "ClassDeclaration": {
10897
+ const [scope] = state.stack.slice(-1);
10898
+ const stack = state.stack.slice(0, -1);
10899
+ scope.stack = stack;
10900
+ if (scope.type == "FunctionDeclaration") {
10901
+ state.allFunctions.push(scope);
10902
+ }
10903
+ else {
10904
+ state.allClasses.push(scope);
10905
+ }
10906
+ return null;
10907
+ }
10908
+ case "Using":
10909
+ case "ImportModule":
10910
+ allImports.push({ node, stack: state.stack.slice() });
10911
+ return null;
10912
+ default:
10913
+ return null;
10914
+ }
10915
+ },
10916
+ };
10917
+ await (0,external_api_cjs_namespaceObject.getApiMapping)(preState);
10918
+ const state = preState;
10919
+ // Mark all functions from api.mir as "special" by
10920
+ // setting their bodies to null. In api.mir, they're
10921
+ // all empty, which makes it look like they're
10922
+ // do-nothing functions.
10923
+ const markApi = (node) => {
10924
+ if (node.type == "FunctionDeclaration") {
10925
+ node.node.body = null;
10926
+ }
10927
+ if ((0,external_api_cjs_namespaceObject.isStateNode)(node) && node.decls) {
10928
+ Object.values(node.decls).forEach((v) => v.forEach(markApi));
10929
+ }
10930
+ };
10931
+ markApi(state.stack[0]);
10932
+ await getFileASTs(fnMap);
10933
+ Object.entries(fnMap).forEach(([name, value]) => {
10934
+ const { ast, parserError } = value;
10935
+ if (!ast) {
10936
+ throw parserError || new Error(`Failed to parse ${name}`);
10937
+ }
10938
+ excludeAnnotations = value.excludeAnnotations;
10939
+ hasTests = false;
10940
+ (0,external_api_cjs_namespaceObject.collectNamespaces)(ast, state);
10941
+ value.hasTests = hasTests;
10973
10942
  });
10974
- ast.source = source;
10975
- ast.monkeyCSource = monkeyCSource;
10976
- (0,external_api_cjs_namespaceObject.collectNamespaces)(ast, state);
10977
- return ast;
10978
- };
10979
- const files = await Promise.all(
10980
- Object.entries(fnMap).map(([name, { excludeAnnotations }]) =>
10981
- promises_namespaceObject.readFile(name).then((data) => ({
10982
- name,
10983
- ast: getAst(
10984
- name,
10985
- data.toString().replace(/\r\n/g, "\n"),
10986
- excludeAnnotations
10987
- ),
10988
- }))
10989
- )
10990
- );
10991
-
10992
- delete state.shouldExclude;
10993
- delete state.post;
10994
-
10995
- processImports(allImports, state.lookup);
10996
- collectClassInfo(state);
10997
-
10998
- return { files, state };
10943
+ delete state.shouldExclude;
10944
+ delete state.post;
10945
+ processImports(allImports, state.lookup);
10946
+ collectClassInfo(state);
10947
+ return state;
10999
10948
  }
11000
-
11001
- function getLiteralNode(node) {
11002
- if (Array.isArray(node)) {
11003
- if (!node.length) return null;
11004
- if (node.length === 1) return getLiteralNode(node[0]);
11005
- let result;
11006
- if (
11007
- node.every((n) => {
11008
- const lit = getLiteralNode(n);
11009
- if (!lit) return false;
11010
- if (!result) {
11011
- result = lit;
11012
- } else {
11013
- if (lit.value !== result.value) return false;
10949
+ function compareLiteralLike(a, b) {
10950
+ while (a.type === "BinaryExpression")
10951
+ a = a.left;
10952
+ while (b.type === "BinaryExpression")
10953
+ b = b.left;
10954
+ return a.type === "Literal" && b.type === "Literal" && a.value === b.value;
10955
+ }
10956
+ function getLiteralFromDecls(decls) {
10957
+ if (!decls.length)
10958
+ return null;
10959
+ let result = null;
10960
+ if (decls.every((d) => {
10961
+ if (d.type === "EnumStringMember" ||
10962
+ (d.type === "VariableDeclarator" && d.kind === "const")) {
10963
+ const init = getLiteralNode(d.init);
10964
+ if (!init)
10965
+ return false;
10966
+ if (!result) {
10967
+ result = init;
10968
+ return true;
10969
+ }
10970
+ else {
10971
+ return compareLiteralLike(init, result);
10972
+ }
11014
10973
  }
11015
- return true;
11016
- })
11017
- ) {
11018
- return result;
10974
+ return false;
10975
+ })) {
10976
+ return result;
11019
10977
  }
11020
10978
  return null;
11021
- }
11022
- if (node.type == "Literal") return node;
11023
- if (node.type == "BinaryExpression" && node.operator == "as") {
11024
- return getLiteralNode(node.left) && node;
11025
- }
11026
- if (node.type == "UnaryExpression") {
11027
- if (node.argument.type != "Literal") return null;
11028
- switch (node.operator) {
11029
- case "-":
11030
- if (typeof node.argument.value == "number") {
11031
- return {
11032
- ...node.argument,
11033
- value: -node.argument.value,
11034
- raw: "-" + node.argument.value,
11035
- enumType: node.enumType,
11036
- };
10979
+ }
10980
+ function getLiteralNode(node) {
10981
+ if (node == null)
10982
+ return null;
10983
+ if (node.type == "Literal")
10984
+ return node;
10985
+ if (node.type == "BinaryExpression" && node.operator == "as") {
10986
+ return getLiteralNode(node.left) && node;
10987
+ }
10988
+ if (node.type == "UnaryExpression") {
10989
+ if (node.argument.type != "Literal")
10990
+ return null;
10991
+ switch (node.operator) {
10992
+ case "-":
10993
+ if (typeof node.argument.value == "number") {
10994
+ return {
10995
+ ...node.argument,
10996
+ value: -node.argument.value,
10997
+ raw: "-" + node.argument.value,
10998
+ enumType: node.enumType,
10999
+ };
11000
+ }
11037
11001
  }
11038
11002
  }
11039
- }
11003
+ return null;
11040
11004
  }
11041
-
11042
11005
  function getNodeValue(node) {
11043
- if (
11044
- node.type == "BinaryExpression" &&
11045
- node.operator == "as" &&
11046
- node.right.type == "TypeSpecList" &&
11047
- node.right.ts.length == 1 &&
11048
- typeof node.right.ts[0] == "string"
11049
- ) {
11050
- // this is a cast we inserted to retain the type of an enum
11051
- // any arithmetic on it will revert to "Number", or "Long",
11052
- // so just ignore it.
11053
- return getNodeValue(node.left);
11054
- }
11055
- if (node.type != "Literal") {
11056
- return [null, null];
11057
- }
11058
- let type = node.value === null ? "Null" : typeof node.value;
11059
- if (type === "number") {
11060
- const match = external_api_cjs_namespaceObject.LiteralIntegerRe.exec(node.raw);
11061
- if (match) {
11062
- type = match[2] == "l" ? "Long" : "Number";
11063
- } else if (node.raw.endsWith("d")) {
11064
- type = "Double";
11065
- } else {
11066
- type = "Float";
11006
+ if (node.type == "BinaryExpression" &&
11007
+ node.operator == "as" &&
11008
+ node.right.type == "TypeSpecList" &&
11009
+ node.right.ts.length == 1 &&
11010
+ typeof node.right.ts[0] == "string") {
11011
+ // this is a cast we inserted to retain the type of an enum
11012
+ // any arithmetic on it will revert to "Number", or "Long",
11013
+ // so just ignore it.
11014
+ return getNodeValue(node.left);
11015
+ }
11016
+ if (node.type != "Literal") {
11017
+ return [null, null];
11018
+ }
11019
+ let type = node.value === null ? "Null" : typeof node.value;
11020
+ if (type === "number") {
11021
+ const match = node.raw && prettier_plugin_monkeyc_namespaceObject.LiteralIntegerRe.exec(node.raw);
11022
+ if (match) {
11023
+ type = match[2] == "l" ? "Long" : "Number";
11024
+ }
11025
+ else if (node.raw && node.raw.endsWith("d")) {
11026
+ type = "Double";
11027
+ }
11028
+ else {
11029
+ type = "Float";
11030
+ }
11067
11031
  }
11068
- } else if (type === "string") {
11069
- type = "String";
11070
- } else if (type === "boolean") {
11071
- type = "Boolean";
11072
- } else {
11073
- type = "Unknown";
11074
- }
11075
- return [node, type];
11032
+ else if (type === "string") {
11033
+ type = "String";
11034
+ }
11035
+ else if (type === "boolean") {
11036
+ type = "Boolean";
11037
+ }
11038
+ else {
11039
+ type = "Unknown";
11040
+ }
11041
+ return [node, type];
11076
11042
  }
11077
-
11078
11043
  function optimizeNode(node) {
11079
- switch (node.type) {
11080
- case "UnaryExpression": {
11081
- const [arg, type] = getNodeValue(node.argument);
11082
- if (arg === null) break;
11083
- switch (node.operator) {
11084
- case "+":
11085
- if (type === "Number" || type === "Long") {
11086
- return arg;
11087
- }
11088
- break;
11089
- case "-":
11090
- if (type === "Number" || type === "Long") {
11091
- return {
11092
- ...arg,
11093
- value: -arg.value,
11094
- raw: (-arg.value).toString() + (type === "Long" ? "l" : ""),
11095
- };
11096
- }
11097
- break;
11098
- case "!":
11099
- case "~":
11100
- {
11101
- let value;
11102
- if (type === "Number" || type === "Long") {
11103
- value = -arg.value - 1;
11104
- } else if (type === "Boolean" && node.operator == "!") {
11105
- value = !arg.value;
11044
+ switch (node.type) {
11045
+ case "UnaryExpression": {
11046
+ const [arg, type] = getNodeValue(node.argument);
11047
+ if (arg === null)
11048
+ break;
11049
+ switch (node.operator) {
11050
+ case "+":
11051
+ if (type === "Number" || type === "Long") {
11052
+ return arg;
11053
+ }
11054
+ break;
11055
+ case "-":
11056
+ if (type === "Number" || type === "Long") {
11057
+ return {
11058
+ ...arg,
11059
+ value: -arg.value,
11060
+ raw: (-arg.value).toString() + (type === "Long" ? "l" : ""),
11061
+ };
11062
+ }
11063
+ break;
11064
+ case "!":
11065
+ case "~":
11066
+ {
11067
+ let value;
11068
+ if (type === "Number" || type === "Long") {
11069
+ value = -arg.value - 1;
11070
+ }
11071
+ else if (type === "Boolean" && node.operator == "!") {
11072
+ value = !arg.value;
11073
+ }
11074
+ if (value !== undefined) {
11075
+ return {
11076
+ ...arg,
11077
+ value,
11078
+ raw: value.toString() + (type === "Long" ? "l" : ""),
11079
+ };
11080
+ }
11081
+ }
11082
+ break;
11106
11083
  }
11107
- if (value !== undefined) {
11108
- return {
11109
- ...arg,
11110
- value,
11111
- raw: value.toString() + (type === "Long" ? "l" : ""),
11112
- };
11084
+ break;
11085
+ }
11086
+ case "BinaryExpression": {
11087
+ const operators = {
11088
+ "+": (left, right) => left + right,
11089
+ "-": (left, right) => left - right,
11090
+ "*": (left, right) => left * right,
11091
+ "/": (left, right) => Math.trunc(left / right),
11092
+ "%": (left, right) => left % right,
11093
+ "&": (left, right, type) => type === "Number" ? left & right : null,
11094
+ "|": (left, right, type) => type === "Number" ? left | right : null,
11095
+ "<<": (left, right, type) => type === "Number" ? left << right : null,
11096
+ ">>": (left, right, type) => type === "Number" ? left >> right : null,
11097
+ };
11098
+ const op = operators[node.operator];
11099
+ if (op) {
11100
+ const [left, left_type] = getNodeValue(node.left);
11101
+ const [right, right_type] = getNodeValue(node.right);
11102
+ if (!left || !right)
11103
+ break;
11104
+ if (left_type != right_type ||
11105
+ (left_type != "Number" && left_type != "Long")) {
11106
+ break;
11107
+ }
11108
+ const value = op(left.value, right.value, left_type);
11109
+ if (value === null)
11110
+ break;
11111
+ return {
11112
+ ...left,
11113
+ value,
11114
+ raw: value.toString() + (left_type === "Long" ? "l" : ""),
11115
+ };
11113
11116
  }
11114
- }
11115
- break;
11116
- }
11117
- break;
11118
- }
11119
- case "BinaryExpression": {
11120
- const operators = {
11121
- "+": (left, right) => left + right,
11122
- "-": (left, right) => left - right,
11123
- "*": (left, right) => left * right,
11124
- "/": (left, right) => Math.trunc(left / right),
11125
- "%": (left, right) => left % right,
11126
- "&": (left, right, type) => (type === "Number" ? left & right : null),
11127
- "|": (left, right, type) => (type === "Number" ? left | right : null),
11128
- "<<": (left, right, type) => (type === "Number" ? left << right : null),
11129
- ">>": (left, right, type) => (type === "Number" ? left >> right : null),
11130
- };
11131
- const op = operators[node.operator];
11132
- if (op) {
11133
- const [left, left_type] = getNodeValue(node.left);
11134
- const [right, right_type] = getNodeValue(node.right);
11135
- if (!left || !right) break;
11136
- if (
11137
- left_type != right_type ||
11138
- (left_type != "Number" && left_type != "Long")
11139
- ) {
11140
- break;
11117
+ break;
11141
11118
  }
11142
- const value = op(left.value, right.value, left_type);
11143
- if (value === null) break;
11144
- return {
11145
- ...left,
11146
- value,
11147
- raw: value.toString() + (left_type === "Long" ? "l" : ""),
11148
- };
11149
- }
11150
- break;
11119
+ case "FunctionDeclaration":
11120
+ if (node.body && evaluateFunction(node, null) !== false) {
11121
+ node.optimizable = true;
11122
+ }
11123
+ break;
11151
11124
  }
11152
- case "FunctionDeclaration":
11153
- if (node.body && evaluateFunction(node, null) !== false) {
11154
- node.optimizable = true;
11155
- }
11156
- break;
11157
- }
11125
+ return null;
11158
11126
  }
11159
-
11160
11127
  function evaluateFunction(func, args) {
11161
- if (args && args.length != func.params.length) {
11162
- return false;
11163
- }
11164
- const paramValues =
11165
- args && Object.fromEntries(func.params.map((p, i) => [p.name, args[i]]));
11166
- let ret = null;
11167
- const body = args ? JSON.parse(JSON.stringify(func.body)) : func.body;
11168
- try {
11169
- (0,external_api_cjs_namespaceObject.traverseAst)(
11170
- body,
11171
- (node) => {
11172
- switch (node.type) {
11173
- case "BlockStatement":
11174
- case "ReturnStatement":
11175
- case "UnaryExpression":
11176
- case "BinaryExpression":
11177
- case "Literal":
11178
- case "Identifier":
11179
- return;
11180
- default:
11181
- throw new Error("Bad node type");
11182
- }
11183
- },
11184
- args &&
11185
- ((node) => {
11186
- switch (node.type) {
11187
- case "ReturnStatement":
11188
- ret = node.argument;
11189
- return;
11190
- case "BlockStatement":
11191
- case "Literal":
11192
- return;
11193
- case "Identifier":
11194
- if ((0,external_api_cjs_namespaceObject.hasProperty)(paramValues, node.name)) {
11195
- return paramValues[node.name];
11196
- }
11197
- // fall through;
11198
- default: {
11199
- const repl = optimizeNode(node);
11200
- if (repl && repl.type === "Literal") return repl;
11201
- throw new Error("Didn't optimize");
11202
- }
11203
- }
11204
- })
11205
- );
11206
- return ret;
11207
- } catch (e) {
11208
- return false;
11209
- }
11210
- }
11211
-
11212
- async function optimizeMonkeyC(fnMap) {
11213
- const { files, state } = await analyze(fnMap);
11214
- const replace = (node, obj) => {
11215
- for (const k of Object.keys(node)) {
11216
- delete node[k];
11217
- }
11218
- if (obj.enumType) {
11219
- obj = {
11220
- type: "BinaryExpression",
11221
- operator: "as",
11222
- left: obj,
11223
- right: { type: "TypeSpecList", ts: [obj.enumType] },
11224
- };
11225
- }
11226
- for (const [k, v] of Object.entries(obj)) {
11227
- node[k] = v;
11228
- }
11229
- };
11230
- const lookupAndReplace = (node) => {
11231
- const [, objects] = state.lookup(node);
11232
- if (!objects) {
11233
- return false;
11234
- }
11235
- const obj = getLiteralNode(objects);
11236
- if (!obj) {
11237
- return false;
11128
+ if (args && args.length != func.params.length) {
11129
+ return false;
11238
11130
  }
11239
- replace(node, obj);
11240
- return true;
11241
- };
11242
-
11243
- /*
11244
- * Might this function be called from somewhere, including
11245
- * callbacks from the api (eg getSettingsView, etc).
11246
- */
11247
- const maybeCalled = (func) => {
11248
- if (!func.body) {
11249
- // this is an api.mir function. It can be called
11250
- return true;
11131
+ const paramValues = args &&
11132
+ Object.fromEntries(func.params.map((p, i) => [(0,external_api_cjs_namespaceObject.variableDeclarationName)(p), args[i]]));
11133
+ let ret = null;
11134
+ const body = args ? JSON.parse(JSON.stringify(func.body)) : func.body;
11135
+ try {
11136
+ (0,external_api_cjs_namespaceObject.traverseAst)(body, (node) => {
11137
+ switch (node.type) {
11138
+ case "BlockStatement":
11139
+ case "ReturnStatement":
11140
+ case "UnaryExpression":
11141
+ case "BinaryExpression":
11142
+ case "Literal":
11143
+ case "Identifier":
11144
+ return;
11145
+ default:
11146
+ throw new Error("Bad node type");
11147
+ }
11148
+ }, !args
11149
+ ? undefined
11150
+ : (node) => {
11151
+ switch (node.type) {
11152
+ case "ReturnStatement":
11153
+ ret = node.argument || null;
11154
+ return null;
11155
+ case "BlockStatement":
11156
+ case "Literal":
11157
+ return null;
11158
+ case "Identifier":
11159
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(paramValues, node.name)) {
11160
+ return paramValues[node.name];
11161
+ }
11162
+ // fall through;
11163
+ default: {
11164
+ const repl = optimizeNode(node);
11165
+ if (repl && repl.type === "Literal")
11166
+ return repl;
11167
+ throw new Error("Didn't optimize");
11168
+ }
11169
+ }
11170
+ });
11171
+ return ret;
11251
11172
  }
11252
- if ((0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, func.id.name)) return true;
11253
- if ((0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, func.id.name)) {
11254
- return (
11255
- state.calledFunctions[func.id.name].find((f) => f === func) !== null
11256
- );
11173
+ catch (e) {
11174
+ return false;
11257
11175
  }
11258
- };
11259
- /*
11260
- * Does elm (a class) have a maybeCalled function called name,
11261
- * anywhere in its superClass chain.
11262
- */
11263
- const checkInherited = (elm, name) =>
11264
- elm.superClass === true ||
11265
- elm.superClass.some(
11266
- (sc) =>
11267
- ((0,external_api_cjs_namespaceObject.hasProperty)(sc.decls, name) &&
11268
- sc.decls[name].some(
11269
- (f) => f.type == "FunctionDeclaration" && maybeCalled(f)
11270
- )) ||
11271
- (sc.superClass && checkInherited(sc, name))
11272
- );
11273
-
11274
- state.localsStack = [{}];
11275
- state.exposed = {};
11276
- state.calledFunctions = {};
11277
- state.pre = (node) => {
11278
- switch (node.type) {
11279
- case "ConditionalExpression":
11280
- case "IfStatement":
11281
- case "DoWhileStatement":
11282
- case "WhileStatement":
11283
- state.traverse(node.test);
11284
- const [value, type] = getNodeValue(node.test);
11285
- if (value) {
11286
- let result = null;
11287
- if (type === "Null") {
11288
- result = false;
11289
- } else if (
11290
- type === "Boolean" ||
11291
- type === "Number" ||
11292
- type === "Long"
11293
- ) {
11294
- result = !!value.value;
11295
- }
11296
- if (result !== null) {
11297
- if (
11298
- node.type === "IfStatement" ||
11299
- node.type === "ConditionalExpression"
11300
- ) {
11301
- if (result === false) {
11302
- node.consequent = null;
11303
- } else {
11304
- node.alternate = null;
11305
- }
11306
- node.test = result;
11307
- } else if (node.type === "WhileStatement") {
11308
- if (result === false) {
11309
- node.body = null;
11310
- }
11311
- } else if (node.type === "DoWhileStatement") {
11312
- if (result === false) {
11313
- node.test = null;
11314
- }
11315
- } else {
11316
- throw new Error("Unexpected Node type");
11317
- }
11318
- }
11176
+ }
11177
+ async function optimizeMonkeyC(fnMap) {
11178
+ const state = {
11179
+ ...(await analyze(fnMap)),
11180
+ localsStack: [{}],
11181
+ exposed: {},
11182
+ calledFunctions: {},
11183
+ };
11184
+ const replace = (node, obj) => {
11185
+ for (const k of Object.keys(node)) {
11186
+ delete node[k];
11187
+ }
11188
+ if (obj.enumType) {
11189
+ obj = {
11190
+ type: "BinaryExpression",
11191
+ operator: "as",
11192
+ left: obj,
11193
+ right: { type: "TypeSpecList", ts: [obj.enumType] },
11194
+ };
11195
+ }
11196
+ for (const [k, v] of Object.entries(obj)) {
11197
+ node[k] = v;
11198
+ }
11199
+ };
11200
+ const lookupAndReplace = (node) => {
11201
+ const [, objects] = state.lookup(node);
11202
+ if (!objects) {
11203
+ return false;
11204
+ }
11205
+ const obj = getLiteralFromDecls(objects);
11206
+ if (!obj) {
11207
+ return false;
11208
+ }
11209
+ replace(node, obj);
11210
+ return true;
11211
+ };
11212
+ const topLocals = () => state.localsStack[state.localsStack.length - 1];
11213
+ /*
11214
+ * Might this function be called from somewhere, including
11215
+ * callbacks from the api (eg getSettingsView, etc).
11216
+ */
11217
+ const maybeCalled = (func) => {
11218
+ if (!func.body) {
11219
+ // this is an api.mir function. It can be called
11220
+ return true;
11221
+ }
11222
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, func.id.name))
11223
+ return true;
11224
+ if (func.attrs &&
11225
+ func.attrs.attrs &&
11226
+ func.attrs.attrs.some((attr) => {
11227
+ if (attr.type != "UnaryExpression")
11228
+ return false;
11229
+ if (attr.argument.type != "Identifier")
11230
+ return false;
11231
+ return attr.argument.name == "test";
11232
+ })) {
11233
+ return true;
11234
+ }
11235
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, func.id.name)) {
11236
+ return (state.calledFunctions[func.id.name].find((f) => f === func) !== null);
11319
11237
  }
11320
- return;
11321
-
11322
- case "EnumDeclaration":
11323
11238
  return false;
11324
- case "ForStatement": {
11325
- const map = state.localsStack.slice(-1).pop().map;
11326
- if (map) {
11327
- state.localsStack.push({ node, map: { ...map } });
11328
- }
11329
- break;
11330
- }
11331
- case "VariableDeclarator": {
11332
- const locals = state.localsStack.slice(-1).pop();
11333
- const { map } = locals;
11334
- if (map) {
11335
- if ((0,external_api_cjs_namespaceObject.hasProperty)(map, node.id.name)) {
11336
- // We already have a variable with this name in scope
11337
- // Recent monkeyc compilers complain, so rename it
11338
- let suffix = 0;
11339
- let node_name = node.id.name;
11340
- const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
11341
- if (match) {
11342
- node_name = match[1];
11343
- suffix = parseInt(match[2], 10) + 1;
11239
+ };
11240
+ /*
11241
+ * Does elm (a class) have a maybeCalled function called name,
11242
+ * anywhere in its superClass chain.
11243
+ */
11244
+ const checkInherited = (elm, name) => elm.superClass === true ||
11245
+ elm.superClass.some((sc) => ((0,external_api_cjs_namespaceObject.hasProperty)(sc.decls, name) &&
11246
+ sc.decls[name].some((f) => (0,external_api_cjs_namespaceObject.isStateNode)(f) &&
11247
+ f.type == "FunctionDeclaration" &&
11248
+ maybeCalled(f.node))) ||
11249
+ (sc.superClass && checkInherited(sc, name)));
11250
+ state.pre = (node) => {
11251
+ switch (node.type) {
11252
+ case "ConditionalExpression":
11253
+ case "IfStatement":
11254
+ case "DoWhileStatement":
11255
+ case "WhileStatement":
11256
+ const test = (state.traverse(node.test) ||
11257
+ node.test);
11258
+ const [value, type] = getNodeValue(test);
11259
+ if (value) {
11260
+ let result = null;
11261
+ if (type === "Null") {
11262
+ result = false;
11263
+ }
11264
+ else if (type === "Boolean" ||
11265
+ type === "Number" ||
11266
+ type === "Long") {
11267
+ result = !!value.value;
11268
+ }
11269
+ if (result !== null) {
11270
+ node.test = { type: "Literal", value: result };
11271
+ if (node.type === "IfStatement" ||
11272
+ node.type === "ConditionalExpression") {
11273
+ return [result ? "consequent" : "alternate"];
11274
+ }
11275
+ else if (node.type === "WhileStatement") {
11276
+ return result === false ? [] : ["body"];
11277
+ }
11278
+ else if (node.type === "DoWhileStatement") {
11279
+ return ["body"];
11280
+ }
11281
+ else {
11282
+ throw new Error("Unexpected Node type");
11283
+ }
11284
+ }
11285
+ }
11286
+ return null;
11287
+ case "EnumDeclaration":
11288
+ return false;
11289
+ case "ForStatement": {
11290
+ const map = topLocals().map;
11291
+ if (map) {
11292
+ state.localsStack.push({ node, map: { ...map } });
11293
+ }
11294
+ break;
11344
11295
  }
11345
- if (!locals.inners) {
11346
- // find all the names declared in this scope, to avoid
11347
- // more conflicts
11348
- locals.inners = {};
11349
- (0,external_api_cjs_namespaceObject.traverseAst)(locals.node, (node) => {
11350
- if (node.type === "VariableDeclarator") {
11351
- locals.inners[node.id.name] = true;
11296
+ case "VariableDeclarator": {
11297
+ const locals = topLocals();
11298
+ const { map } = locals;
11299
+ if (map) {
11300
+ const declName = (0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id);
11301
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(map, declName)) {
11302
+ // We already have a variable with this name in scope
11303
+ // Recent monkeyc compilers complain, so rename it
11304
+ let suffix = 0;
11305
+ let node_name = declName;
11306
+ const match = node_name.match(/^pmcr_(.*)_(\d+)$/);
11307
+ if (match) {
11308
+ node_name = match[1];
11309
+ suffix = parseInt(match[2], 10) + 1;
11310
+ }
11311
+ if (!locals.inners) {
11312
+ // find all the names declared in this scope, to avoid
11313
+ // more conflicts
11314
+ locals.inners = {};
11315
+ const inners = locals.inners;
11316
+ (0,external_api_cjs_namespaceObject.traverseAst)(locals.node, (node) => {
11317
+ if (node.type === "VariableDeclarator") {
11318
+ inners[(0,external_api_cjs_namespaceObject.variableDeclarationName)(node.id)] = true;
11319
+ }
11320
+ });
11321
+ }
11322
+ let name;
11323
+ while (true) {
11324
+ name = `pmcr_${node_name}_${suffix}`;
11325
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(map, name) &&
11326
+ !(0,external_api_cjs_namespaceObject.hasProperty)(locals.inners, name)) {
11327
+ // we also need to ensure that we don't hide the name of
11328
+ // an outer module, class, function, enum or variable,
11329
+ // since someone might want to access it from this scope.
11330
+ let ok = false;
11331
+ let i;
11332
+ for (i = state.stack.length; i--;) {
11333
+ const elm = state.stack[i];
11334
+ if (ok) {
11335
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(elm.decls, name)) {
11336
+ break;
11337
+ }
11338
+ }
11339
+ else if (elm.node &&
11340
+ elm.node.type === "FunctionDeclaration") {
11341
+ ok = true;
11342
+ }
11343
+ }
11344
+ if (i < 0) {
11345
+ break;
11346
+ }
11347
+ }
11348
+ suffix++;
11349
+ }
11350
+ map[declName] = name;
11351
+ map[name] = true;
11352
+ if (node.id.type === "Identifier") {
11353
+ node.id.name = name;
11354
+ }
11355
+ else {
11356
+ node.id.left.name = name;
11357
+ }
11358
+ }
11359
+ else {
11360
+ map[declName] = true;
11361
+ }
11352
11362
  }
11353
- });
11363
+ return ["init"];
11354
11364
  }
11355
- let name;
11356
- while (true) {
11357
- name = `pmcr_${node_name}_${suffix}`;
11358
- if (
11359
- !(0,external_api_cjs_namespaceObject.hasProperty)(map, name) &&
11360
- !(0,external_api_cjs_namespaceObject.hasProperty)(locals.inners, name)
11361
- ) {
11362
- // we also need to ensure that we don't hide the name of
11363
- // an outer module, class, function, enum or variable,
11364
- // since someone might want to access it from this scope.
11365
- let ok = false;
11366
- let i;
11367
- for (i = state.stack.length; i--; ) {
11368
- const elm = state.stack[i];
11369
- if (ok) {
11370
- if ((0,external_api_cjs_namespaceObject.hasProperty)(elm.decls, name)) {
11371
- break;
11365
+ case "UnaryExpression":
11366
+ if (node.operator == ":") {
11367
+ // If we produce a Symbol, for a given name,
11368
+ // its possible that someone uses that symbol
11369
+ // indirectly, so we can't remove any enums or
11370
+ // constants with that name (we can still replace
11371
+ // uses of those constants though).
11372
+ state.exposed[node.argument.name] = true;
11373
+ // In any case, we can't replace *this* use of the
11374
+ // symbol with its value...
11375
+ return false;
11376
+ }
11377
+ break;
11378
+ case "Identifier": {
11379
+ const map = topLocals().map;
11380
+ if (map) {
11381
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(map, node.name)) {
11382
+ const name = map[node.name];
11383
+ if (name !== true) {
11384
+ node.name = name;
11385
+ }
11372
11386
  }
11373
- } else if (elm.node.type === "FunctionDeclaration") {
11374
- ok = true;
11375
- }
11376
11387
  }
11377
- if (i < 0) {
11378
- break;
11388
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, node.name)) {
11389
+ if (!lookupAndReplace(node)) {
11390
+ state.exposed[node.name] = true;
11391
+ }
11379
11392
  }
11380
- }
11381
- suffix++;
11393
+ return false;
11382
11394
  }
11383
- map[node.id.name] = name;
11384
- map[name] = true;
11385
- node.id.name = name;
11386
- } else {
11387
- map[node.id.name] = true;
11388
- }
11389
- }
11390
- return ["init"];
11391
- }
11392
- case "UnaryExpression":
11393
- if (node.operator == ":") {
11394
- // If we produce a Symbol, for a given name,
11395
- // its possible that someone uses that symbol
11396
- // indirectly, so we can't remove any enums or
11397
- // constants with that name (we can still replace
11398
- // uses of those constants though).
11399
- state.exposed[node.argument.name] = true;
11400
- // In any case, we can't replace *this* use of the
11401
- // symbol with its value...
11402
- return false;
11403
- }
11404
- break;
11405
- case "Identifier": {
11406
- const map = state.localsStack.slice(-1).pop().map;
11407
- if (map) {
11408
- if ((0,external_api_cjs_namespaceObject.hasProperty)(map, node.name)) {
11409
- const name = map[node.name];
11410
- if (name !== true) {
11411
- node.name = name;
11395
+ case "MemberExpression":
11396
+ if (node.property.type === "Identifier" && !node.computed) {
11397
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, node.property.name)) {
11398
+ if (lookupAndReplace(node)) {
11399
+ return false;
11400
+ }
11401
+ else {
11402
+ state.exposed[node.property.name] = true;
11403
+ }
11404
+ }
11405
+ // Don't optimize the property.
11406
+ return ["object"];
11407
+ }
11408
+ break;
11409
+ case "BlockStatement": {
11410
+ const map = topLocals().map;
11411
+ if (map) {
11412
+ state.localsStack.push({
11413
+ node,
11414
+ map: { ...map },
11415
+ });
11416
+ }
11417
+ break;
11412
11418
  }
11413
- }
11414
- }
11415
- if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, node.name)) {
11416
- if (!lookupAndReplace(node)) {
11417
- state.exposed[node.name] = true;
11418
- }
11419
- }
11420
- return false;
11421
- }
11422
- case "MemberExpression":
11423
- if (node.property.type === "Identifier" && !node.computed) {
11424
- if ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, node.property.name)) {
11425
- if (lookupAndReplace(node)) {
11426
- return false;
11427
- } else {
11428
- state.exposed[node.property.name] = true;
11419
+ case "FunctionDeclaration": {
11420
+ const map = {};
11421
+ node.params &&
11422
+ node.params.forEach((p) => (map[(0,external_api_cjs_namespaceObject.variableDeclarationName)(p)] = true));
11423
+ state.localsStack.push({ node, map });
11424
+ const [parent] = state.stack.slice(-2);
11425
+ if (parent.type == "ClassDeclaration" && !maybeCalled(node)) {
11426
+ let used = false;
11427
+ if (node.id.name == "initialize") {
11428
+ used = true;
11429
+ }
11430
+ else if (parent.superClass) {
11431
+ used = checkInherited(parent, node.id.name);
11432
+ }
11433
+ if (used) {
11434
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, node.id.name)) {
11435
+ state.calledFunctions[node.id.name] = [];
11436
+ }
11437
+ state.calledFunctions[node.id.name].push(node);
11438
+ }
11439
+ }
11429
11440
  }
11430
- }
11431
- // Don't optimize the property.
11432
- return ["object"];
11433
- }
11434
- break;
11435
- case "BlockStatement": {
11436
- const map = state.localsStack.slice(-1).pop().map;
11437
- if (map) {
11438
- state.localsStack.push({
11439
- node,
11440
- map: { ...map },
11441
- });
11442
11441
  }
11443
- break;
11444
- }
11445
- case "FunctionDeclaration": {
11446
- const map = {};
11447
- node.params && node.params.forEach((p) => (map[p.name] = true));
11448
- state.localsStack.push({ node, map });
11449
- const [parent] = state.stack.slice(-2);
11450
- if (parent.type == "ClassDeclaration" && !maybeCalled(node)) {
11451
- let used = false;
11452
- if (node.id.name == "initialize") {
11453
- used = true;
11454
- } else if (parent.superClass) {
11455
- used = checkInherited(parent, node.id.name);
11456
- }
11457
- if (used) {
11458
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, node.id.name)) {
11459
- state.calledFunctions[node.id.name] = [];
11460
- }
11461
- state.calledFunctions[node.id.name].push(node);
11462
- }
11442
+ return null;
11443
+ };
11444
+ state.post = (node) => {
11445
+ if (topLocals().node === node) {
11446
+ state.localsStack.pop();
11463
11447
  }
11464
- }
11465
- }
11466
- };
11467
- state.post = (node) => {
11468
- if (state.localsStack.slice(-1).pop().node === node) {
11469
- state.localsStack.pop();
11470
- }
11471
- const opt = optimizeNode(node);
11472
- if (opt) {
11473
- replace(node, opt);
11474
- return;
11475
- }
11476
- switch (node.type) {
11477
- case "ConditionalExpression":
11478
- case "IfStatement":
11479
- if (typeof node.test === "boolean") {
11480
- const rep = node.test ? node.consequent : node.alternate;
11481
- if (!rep) return false;
11482
- replace(node, rep);
11483
- }
11484
- break;
11485
- case "WhileStatement":
11486
- if (!node.body) return false;
11487
- break;
11488
- case "DoWhileStatement":
11489
- if (!node.test) return node.body;
11490
- break;
11491
-
11492
- case "CallExpression": {
11493
- const [name, callees] = state.lookup(node.callee);
11494
- if (!callees || !callees.length) {
11495
- const n =
11496
- name ||
11497
- node.callee.name ||
11498
- (node.callee.property && node.callee.property.name);
11499
- if (n) {
11500
- state.exposed[n] = true;
11501
- } else {
11502
- // There are unnamed CallExpressions, such as new [size]
11503
- // So there's nothing to do here.
11504
- }
11505
- return;
11448
+ const opt = optimizeNode(node);
11449
+ if (opt) {
11450
+ replace(node, opt);
11451
+ return null;
11506
11452
  }
11507
- if (callees.length == 1) {
11508
- const callee = callees[0].node;
11509
- if (
11510
- callee.optimizable &&
11511
- !callee.hasOverride &&
11512
- node.arguments.every((n) => getNodeValue(n)[0] !== null)
11513
- ) {
11514
- const ret = evaluateFunction(callee, node.arguments);
11515
- if (ret) {
11516
- replace(node, ret);
11517
- return;
11453
+ switch (node.type) {
11454
+ case "ConditionalExpression":
11455
+ case "IfStatement":
11456
+ if (node.test.type === "Literal" &&
11457
+ typeof node.test.value === "boolean") {
11458
+ const rep = node.test.value ? node.consequent : node.alternate;
11459
+ if (!rep)
11460
+ return false;
11461
+ replace(node, rep);
11462
+ }
11463
+ break;
11464
+ case "WhileStatement":
11465
+ if (node.test.type === "Literal" && node.test.value === false) {
11466
+ return false;
11467
+ }
11468
+ break;
11469
+ case "DoWhileStatement":
11470
+ if (node.test.type === "Literal" && node.test.value === false) {
11471
+ return node.body;
11472
+ }
11473
+ break;
11474
+ case "CallExpression": {
11475
+ const [name, callees] = state.lookup(node.callee);
11476
+ if (!callees || !callees.length) {
11477
+ const n = name ||
11478
+ ("name" in node.callee && node.callee.name) ||
11479
+ ("property" in node.callee &&
11480
+ node.callee.property &&
11481
+ "name" in node.callee.property &&
11482
+ node.callee.property.name);
11483
+ if (n) {
11484
+ state.exposed[n] = true;
11485
+ }
11486
+ else {
11487
+ // There are unnamed CallExpressions, such as new [size]
11488
+ // So there's nothing to do here.
11489
+ }
11490
+ return null;
11491
+ }
11492
+ if (callees.length == 1) {
11493
+ const callee = (0,external_api_cjs_namespaceObject.isStateNode)(callees[0]) && callees[0].node;
11494
+ if (callee &&
11495
+ callee.type == "FunctionDeclaration" &&
11496
+ callee.optimizable &&
11497
+ !callee.hasOverride &&
11498
+ node.arguments.every((n) => getNodeValue(n)[0] !== null)) {
11499
+ const ret = evaluateFunction(callee, node.arguments);
11500
+ if (ret) {
11501
+ replace(node, ret);
11502
+ return null;
11503
+ }
11504
+ }
11505
+ }
11506
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, name)) {
11507
+ state.calledFunctions[name] = [];
11508
+ }
11509
+ callees.forEach((c) => (0,external_api_cjs_namespaceObject.isStateNode)(c) && state.calledFunctions[name].push(c.node));
11510
+ break;
11518
11511
  }
11519
- }
11520
- }
11521
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(state.calledFunctions, name)) {
11522
- state.calledFunctions[name] = [];
11523
11512
  }
11524
- callees.forEach((c) => state.calledFunctions[name].push(c.node));
11525
- break;
11526
- }
11527
- }
11528
- };
11529
- files.forEach((f) => {
11530
- (0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
11531
- });
11532
- files.forEach((f) => {
11533
- (0,external_api_cjs_namespaceObject.traverseAst)(f.ast, null, (node) => {
11534
- switch (node.type) {
11535
- case "EnumStringBody":
11536
- if (
11537
- node.members.every((m) => {
11538
- const name = m.name || m.id.name;
11539
- return (
11540
- (0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) &&
11541
- !(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name)
11542
- );
11543
- })
11544
- ) {
11545
- node.enumType = [
11546
- ...new Set(
11547
- node.members.map((m) => {
11548
- if (!m.init) return "Number";
11549
- const [node, type] = getNodeValue(m.init);
11550
- if (!node) {
11551
- throw new Error("Failed to get type for eliminated enum");
11552
- }
11553
- return type;
11554
- })
11555
- ),
11556
- ].join(" or ");
11557
- node.members.splice(0);
11558
- }
11559
- break;
11560
- case "EnumDeclaration":
11561
- if (!node.body.members.length) {
11562
- if (!node.id) return false;
11563
- if (!node.body.enumType) {
11564
- throw new Error("Missing enumType on optimized enum");
11513
+ return null;
11514
+ };
11515
+ Object.values(fnMap).forEach((f) => {
11516
+ (0,external_api_cjs_namespaceObject.collectNamespaces)(f.ast, state);
11517
+ });
11518
+ Object.values(fnMap).forEach((f) => {
11519
+ (0,external_api_cjs_namespaceObject.traverseAst)(f.ast, undefined, (node) => {
11520
+ switch (node.type) {
11521
+ case "EnumStringBody":
11522
+ if (node.members.every((m) => {
11523
+ const name = "name" in m ? m.name : m.id.name;
11524
+ return ((0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) &&
11525
+ !(0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
11526
+ })) {
11527
+ node.enumType = [
11528
+ ...new Set(node.members.map((m) => {
11529
+ if (!("init" in m))
11530
+ return "Number";
11531
+ const [node, type] = getNodeValue(m.init);
11532
+ if (!node) {
11533
+ throw new Error("Failed to get type for eliminated enum");
11534
+ }
11535
+ return type;
11536
+ })),
11537
+ ].join(" or ");
11538
+ node.members.splice(0);
11539
+ }
11540
+ break;
11541
+ case "EnumDeclaration":
11542
+ if (!node.body.members.length) {
11543
+ if (!node.id)
11544
+ return false;
11545
+ if (!node.body["enumType"]) {
11546
+ throw new Error("Missing enumType on optimized enum");
11547
+ }
11548
+ replace(node, {
11549
+ type: "TypedefDeclaration",
11550
+ id: node.id,
11551
+ ts: {
11552
+ type: "UnaryExpression",
11553
+ argument: { type: "TypeSpecList", ts: [node.body.enumType] },
11554
+ prefix: true,
11555
+ operator: " as",
11556
+ },
11557
+ });
11558
+ }
11559
+ break;
11560
+ case "VariableDeclaration": {
11561
+ node.declarations = node.declarations.filter((d) => {
11562
+ const name = (0,external_api_cjs_namespaceObject.variableDeclarationName)(d.id);
11563
+ return (!(0,external_api_cjs_namespaceObject.hasProperty)(state.index, name) ||
11564
+ (0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, name));
11565
+ });
11566
+ if (!node.declarations.length) {
11567
+ return false;
11568
+ }
11569
+ break;
11570
+ }
11571
+ case "ClassElement":
11572
+ if (!node.item) {
11573
+ return false;
11574
+ }
11575
+ break;
11576
+ case "FunctionDeclaration":
11577
+ if (!maybeCalled(node)) {
11578
+ return false;
11579
+ }
11580
+ break;
11565
11581
  }
11566
- replace(node, {
11567
- type: "TypedefDeclaration",
11568
- id: node.id,
11569
- ts: {
11570
- type: "UnaryExpression",
11571
- argument: { type: "TypeSpecList", ts: [node.body.enumType] },
11572
- prefix: true,
11573
- operator: " as",
11574
- },
11575
- });
11576
- }
11577
- break;
11578
- case "VariableDeclaration": {
11579
- node.declarations = node.declarations.filter(
11580
- (d) =>
11581
- !(0,external_api_cjs_namespaceObject.hasProperty)(state.index, d.id.name) ||
11582
- (0,external_api_cjs_namespaceObject.hasProperty)(state.exposed, d.id.name)
11583
- );
11584
- if (!node.declarations.length) {
11585
- return false;
11586
- }
11587
- break;
11588
- }
11589
- case "ClassElement":
11590
- if (!node.item) {
11591
- return false;
11592
- }
11593
- break;
11594
- case "FunctionDeclaration":
11595
- if (!maybeCalled(node)) {
11596
- return false;
11597
- }
11598
- break;
11599
- }
11582
+ return null;
11583
+ });
11600
11584
  });
11601
- });
11602
-
11603
- return files;
11604
11585
  }
11605
11586
 
11606
- ;// CONCATENATED MODULE: ./src/optimizer.js
11607
-
11587
+ ;// CONCATENATED MODULE: ./src/optimizer.ts
11608
11588
 
11609
11589
 
11610
11590
 
@@ -11619,81 +11599,95 @@ async function optimizeMonkeyC(fnMap) {
11619
11599
 
11620
11600
 
11621
11601
  function relative_path_no_dotdot(relative) {
11622
- return relative.replace(
11623
- /^(\.\.[\\\/])+/,
11624
- (str) => `__${"dot".repeat(str.length / 3)}__${str.slice(-1)}`
11625
- );
11602
+ return relative.replace(/^(\.\.[\\\/])+/, (str) => `__${"dot".repeat(str.length / 3)}__${str.slice(-1)}`);
11626
11603
  }
11627
-
11628
11604
  async function getVSCodeSettings(path) {
11629
- try {
11630
- const settings = await promises_namespaceObject.readFile(path);
11631
- return JSON.parse(settings.toString());
11632
- } catch (e) {
11633
- return {};
11634
- }
11605
+ try {
11606
+ const settings = await promises_namespaceObject.readFile(path);
11607
+ return JSON.parse(settings.toString());
11608
+ }
11609
+ catch (e) {
11610
+ return {};
11611
+ }
11635
11612
  }
11636
-
11637
11613
  const defaultConfig = {
11638
- outputPath: "bin/optimized",
11639
- workspace: "./",
11614
+ outputPath: "bin/optimized",
11615
+ workspace: "./",
11640
11616
  };
11641
-
11642
- async function getConfig(options) {
11643
- const config = { ...defaultConfig, ...(options || {}) };
11644
- let promise;
11645
- [
11646
- "jungleFiles",
11647
- "developerKeyPath",
11648
- "typeCheckLevel",
11649
- "compilerOptions",
11650
- "compilerWarnings",
11651
- ].forEach((key) => {
11652
- if (config[key]) return;
11653
- if (!promise) {
11654
- promise = Promise.resolve()
11655
- .then(() => getVSCodeSettings(`${external_sdk_util_cjs_namespaceObject.appSupport}/Code/User/settings.json`))
11656
- .then((globals) =>
11657
- getVSCodeSettings(`${config.workspace}/.vscode/settings.json`).then(
11658
- (locals) => ({ ...globals, ...locals })
11659
- )
11660
- );
11661
- }
11662
- promise.then((settings) => {
11663
- const value = settings[`monkeyC.${key}`];
11664
- if (value) {
11665
- config[key] = value;
11666
- }
11667
- });
11668
- });
11669
- promise && (await promise);
11670
- return config;
11617
+ function isErrorWithLocation(e) {
11618
+ return (0,external_api_cjs_namespaceObject.hasProperty)(e, "location");
11671
11619
  }
11672
-
11620
+ /**
11621
+ * @param {BuildConfig} options
11622
+ * @returns {Promise<BuildConfig>}
11623
+ */
11624
+ function getConfig(options) {
11625
+ const config = { ...defaultConfig, ...(options || {}) };
11626
+ return [
11627
+ "jungleFiles",
11628
+ "developerKeyPath",
11629
+ "typeCheckLevel",
11630
+ "compilerOptions",
11631
+ "compilerWarnings",
11632
+ "ignoredExcludeAnnotations",
11633
+ "ignoredAnnotations",
11634
+ "ignoredSourcePaths",
11635
+ ]
11636
+ .reduce((promise, key) => {
11637
+ if (key in config)
11638
+ return promise;
11639
+ return promise
11640
+ .then((v) => v ||
11641
+ getVSCodeSettings(`${external_sdk_util_cjs_namespaceObject.appSupport}/Code/User/settings.json`).then((globals) => getVSCodeSettings(`${config.workspace}/.vscode/settings.json`).then((locals) => ({ ...globals, ...locals }))))
11642
+ .then((settings) => {
11643
+ const value = settings[`monkeyC.${key}`] || settings[`prettierMonkeyC.${key}`];
11644
+ if (value !== undefined) {
11645
+ config[key] = value;
11646
+ }
11647
+ return settings;
11648
+ });
11649
+ }, Promise.resolve(null))
11650
+ .then(() => config);
11651
+ }
11652
+ /**
11653
+ *
11654
+ * @param {string | null} product
11655
+ * @param {BuildConfig} options
11656
+ * @returns
11657
+ */
11673
11658
  async function buildOptimizedProject(product, options) {
11674
- const config = await getConfig(options);
11675
- if (product) {
11676
- config.products = [product];
11677
- } else if (!(0,external_api_cjs_namespaceObject.hasProperty)(config, "releaseBuild")) {
11678
- config.releaseBuild = true;
11679
- }
11680
- const { jungleFiles, program } = await generateOptimizedProject(config);
11681
- config.jungleFiles = jungleFiles;
11682
- let bin = config.buildDir || "bin";
11683
- let name = `optimized-${program}.prg`;
11684
- if (product) {
11685
- product = config.products[0];
11686
- if (config.simulatorBuild === false) {
11687
- bin = external_path_.join(bin, product);
11688
- }
11689
- } else {
11690
- bin = external_path_.join(bin, "exported");
11691
- name = `${program}.iq`;
11692
- }
11693
- config.program = external_path_.join(bin, name);
11694
- return build_project(product, config);
11659
+ const config = await getConfig(options);
11660
+ if (product) {
11661
+ config.products = [product];
11662
+ }
11663
+ else {
11664
+ delete config.testBuild;
11665
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(config, "releaseBuild")) {
11666
+ config.releaseBuild = true;
11667
+ }
11668
+ }
11669
+ const { jungleFiles, program, hasTests } = await generateOptimizedProject(config);
11670
+ config.jungleFiles = jungleFiles;
11671
+ let bin = config.buildDir || "bin";
11672
+ let name = `optimized-${program}.prg`;
11673
+ if (product) {
11674
+ product = config.products[0];
11675
+ if (config.simulatorBuild === false) {
11676
+ bin = external_path_.join(bin, product);
11677
+ }
11678
+ }
11679
+ else {
11680
+ bin = external_path_.join(bin, "exported");
11681
+ name = `${program}.iq`;
11682
+ }
11683
+ config.program = external_path_.join(bin, name);
11684
+ if (!hasTests)
11685
+ delete config.testBuild;
11686
+ return build_project(product, config).then((result) => ({
11687
+ hasTests,
11688
+ ...result,
11689
+ }));
11695
11690
  }
11696
-
11697
11691
  /**
11698
11692
  * For each barrel project included in the build, we want to build
11699
11693
  * a local barrel project inside the optimized directory.
@@ -11707,464 +11701,410 @@ async function buildOptimizedProject(product, options) {
11707
11701
  * files corresponding to an input barrel), we create a copy of
11708
11702
  * the barrel with all the sources removed (and pick up the sources
11709
11703
  * from the input barrel)
11704
+ *
11705
+ * @param {BuildConfig} options
11706
+ * @param {Target[]} targets
11710
11707
  */
11711
11708
  async function createLocalBarrels(targets, options) {
11712
- if (
11713
- targets.every(
11714
- (target) =>
11715
- !target.group.optimizerConfig.barrelMap ||
11716
- Object.values(target.group.optimizerConfig.barrelMap).every(
11717
- (resolvedBarrel) => !resolvedBarrel.qualifier.resourcePath
11718
- )
11719
- )
11720
- ) {
11721
- // there are no barrels, or every barrel has no resources.
11722
- // we can drop any barrels altogether (we'll need to drop them
11723
- // from the manifest file too).
11724
- return;
11725
- }
11726
- // where to create the local barrel projects.
11727
- const barrelDir = external_path_.resolve(
11728
- options.workspace,
11729
- options.outputPath,
11730
- "opt-barrels"
11731
- );
11732
- return targets.reduce((promise, target) => {
11733
- const barrelMap = target.group.optimizerConfig.barrelMap;
11734
- if (!barrelMap || target.group.optBarrels) {
11735
- return promise;
11736
- }
11737
- const optBarrels = (target.group.optimizerConfig.optBarrels = {});
11738
- return Object.entries(barrelMap).reduce(
11739
- (promise, [barrel, resolvedBarrel]) => {
11740
- const { manifest, jungles } = resolvedBarrel;
11741
- const rawBarrelDir = external_path_.dirname(jungles[0]);
11742
- const rawJungles = jungles.map((jungle) =>
11743
- external_path_.relative(rawBarrelDir, jungle)
11744
- );
11745
- const sha1 = external_crypto_namespaceObject.createHash("sha1")
11746
- .update(rawBarrelDir, "binary")
11747
- .digest("base64")
11748
- .replace(/[\/=+]/g, "");
11749
- const optBarrelDir = external_path_.resolve(barrelDir, `${barrel}-${sha1}`);
11750
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(optBarrels, barrel)) {
11751
- optBarrels[barrel] = {
11752
- rawBarrelDir,
11753
- manifest,
11754
- jungleFiles: [...rawJungles],
11755
- optBarrelDir,
11756
- };
11757
- return promise.then(() =>
11758
- (0,external_util_cjs_namespaceObject.copyRecursiveAsNeeded)(
11759
- rawBarrelDir,
11760
- optBarrelDir,
11761
- (src) => !src.endsWith(".mc")
11762
- )
11763
- );
11764
- }
11765
- if (
11766
- optBarrels[barrel].manifest !== manifest ||
11767
- optBarrels[barrel].optBarrelDir !== optBarrelDir ||
11768
- optBarrels[barrel].rawBarrelDir != rawBarrelDir
11769
- ) {
11770
- throw new Error(
11771
- `For device ${
11772
- target.product
11773
- }, barrel ${barrel} was mapped to both ${external_path_.relative(
11774
- optBarrels[barrel].rawBarrelDir,
11775
- optBarrels[barrel].manifest
11776
- )} in ${optBarrels[barrel].rawBarrelDir} and ${external_path_.relative(
11777
- rawBarrelDir,
11778
- manifest
11779
- )} in ${rawBarrelDir}.`
11780
- );
11781
- }
11782
- optBarrels[barrel].jungleFiles.push(...rawJungles);
11783
- return promise;
11784
- },
11785
- promise
11786
- );
11787
- }, Promise.resolve());
11709
+ if (targets.every((target) => !target.group?.optimizerConfig.barrelMap ||
11710
+ Object.values(target.group.optimizerConfig.barrelMap).every((resolvedBarrel) => !resolvedBarrel.qualifier.resourcePath))) {
11711
+ // there are no barrels, or every barrel has no resources.
11712
+ // we can drop any barrels altogether (we'll need to drop them
11713
+ // from the manifest file too).
11714
+ return null;
11715
+ }
11716
+ // where to create the local barrel projects.
11717
+ const barrelDir = external_path_.resolve(options.workspace, options.outputPath, "opt-barrels");
11718
+ return targets.reduce((promise, target) => {
11719
+ if (!target.group)
11720
+ return promise;
11721
+ const barrelMap = target.group.optimizerConfig.barrelMap;
11722
+ if (!barrelMap || target.group.optimizerConfig.optBarrels) {
11723
+ return promise;
11724
+ }
11725
+ const optBarrels = (target.group.optimizerConfig.optBarrels = {});
11726
+ return Object.entries(barrelMap).reduce((promise, [barrel, resolvedBarrel]) => {
11727
+ const { manifest, jungles } = resolvedBarrel;
11728
+ const rawBarrelDir = external_path_.dirname(jungles[0]);
11729
+ const rawJungles = jungles.map((jungle) => external_path_.relative(rawBarrelDir, jungle));
11730
+ const sha1 = external_crypto_namespaceObject.createHash("sha1")
11731
+ .update(rawBarrelDir, "binary")
11732
+ .digest("base64")
11733
+ .replace(/[\/=+]/g, "");
11734
+ const optBarrelDir = external_path_.resolve(barrelDir, `${barrel}-${sha1}`);
11735
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(optBarrels, barrel)) {
11736
+ optBarrels[barrel] = {
11737
+ rawBarrelDir,
11738
+ manifest,
11739
+ jungleFiles: [...rawJungles],
11740
+ optBarrelDir,
11741
+ };
11742
+ return promise.then(() => (0,external_util_cjs_namespaceObject.copyRecursiveAsNeeded)(rawBarrelDir, optBarrelDir, (src) => !src.endsWith(".mc")));
11743
+ }
11744
+ if (optBarrels[barrel].manifest !== manifest ||
11745
+ optBarrels[barrel].optBarrelDir !== optBarrelDir ||
11746
+ optBarrels[barrel].rawBarrelDir != rawBarrelDir) {
11747
+ throw new Error(`For device ${target.product}, barrel ${barrel} was mapped to both ${external_path_.relative(optBarrels[barrel].rawBarrelDir, optBarrels[barrel].manifest)} in ${optBarrels[barrel].rawBarrelDir} and ${external_path_.relative(rawBarrelDir, manifest)} in ${rawBarrelDir}.`);
11748
+ }
11749
+ optBarrels[barrel].jungleFiles.push(...rawJungles);
11750
+ return promise;
11751
+ }, promise);
11752
+ }, Promise.resolve());
11788
11753
  }
11789
-
11790
11754
  async function generateOptimizedProject(options) {
11791
- const config = await getConfig(options);
11792
- const workspace = config.workspace;
11793
-
11794
- const { manifest, targets, xml, jungles } = await get_jungle(
11795
- config.jungleFiles,
11796
- config
11797
- );
11798
-
11799
- const dependencyFiles = [manifest, ...jungles];
11800
- await createLocalBarrels(targets, options);
11801
-
11802
- const buildConfigs = {};
11803
- const products = {};
11804
- let pick_one = config.products ? config.products.indexOf("pick-one") : -1;
11805
- if (config.skipOptimization) {
11806
- if (pick_one >= 0) {
11807
- options.products = [...options.products];
11808
- options.products[pick_one] = targets[0].product;
11809
- }
11810
- return {
11811
- jungleFiles: config.jungleFiles,
11812
- program: external_path_.basename(external_path_.dirname(manifest)),
11813
- };
11814
- }
11815
- let dropBarrels = false;
11816
- const configKey = (p) =>
11817
- p.group.key + (config.releaseBuild ? "-release" : "-debug");
11818
- targets.forEach((p) => {
11819
- const key = configKey(p);
11820
- if (!(0,external_api_cjs_namespaceObject.hasProperty)(buildConfigs, key)) {
11821
- p.group.dir = key;
11822
- if (
11823
- p.group.optimizerConfig.barrelMap &&
11824
- !p.group.optimizerConfig.optBarrels
11825
- ) {
11826
- dropBarrels = true;
11827
- }
11828
- buildConfigs[key] = null;
11829
- }
11830
- if (
11831
- pick_one >= 0 ||
11832
- !options.products ||
11833
- options.products.includes(p.product) ||
11834
- (p.shape && options.products.includes(p.shape))
11835
- ) {
11836
- if (pick_one >= 0) {
11837
- // don't modify the original array since it may be shared
11838
- // (and *is* shared when we're called from test.js)
11839
- options.products = [...options.products];
11840
- options.products[pick_one] = p.product;
11841
- pick_one = -1;
11842
- }
11843
- if (!buildConfigs[key]) {
11844
- buildConfigs[key] = p.group.optimizerConfig;
11845
- products[key] = [];
11846
- }
11847
- products[key].push(p.product);
11755
+ const config = await getConfig(options);
11756
+ const workspace = config.workspace;
11757
+ const { manifest, targets, xml, jungles } = await get_jungle(config.jungleFiles, config);
11758
+ if (!xml["iq:manifest"]["iq:application"]) {
11759
+ const error = new Error(xml["iq:manifest"]["iq:barrel"]
11760
+ ? "Optimize the project that uses this barrel, not the barrel itself"
11761
+ : "Manifest is missing an `iq:application` tag");
11762
+ error.location = {
11763
+ start: { line: 1, column: 1 },
11764
+ end: { line: 1, column: 1 },
11765
+ source: manifest,
11766
+ };
11767
+ throw error;
11768
+ }
11769
+ const dependencyFiles = [manifest, ...jungles];
11770
+ await createLocalBarrels(targets, options);
11771
+ const buildConfigs = {};
11772
+ const products = {};
11773
+ let pick_one = config.products ? config.products.indexOf("pick-one") : -1;
11774
+ if (config.skipOptimization) {
11775
+ if (pick_one >= 0) {
11776
+ options.products = [...options.products];
11777
+ options.products[pick_one] = targets[0].product;
11778
+ }
11779
+ return {
11780
+ jungleFiles: config.jungleFiles,
11781
+ program: external_path_.basename(external_path_.dirname(manifest)),
11782
+ };
11848
11783
  }
11849
- });
11850
-
11851
- // console.log(JSON.stringify(targets));
11852
-
11853
- const jungle_dir = external_path_.resolve(workspace, config.outputPath);
11854
- await promises_namespaceObject.mkdir(jungle_dir, { recursive: true });
11855
- const relative_path = (s) => external_path_.relative(jungle_dir, s);
11856
- let relative_manifest = relative_path(manifest);
11857
- const manifestOk =
11858
- (!config.checkManifest ||
11859
- (await checkManifest(
11860
- xml,
11861
- targets.map((t) => t.product)
11862
- ))) &&
11863
- !dropBarrels;
11864
- const promises = Object.keys(buildConfigs)
11865
- .sort()
11866
- .map((key) => {
11867
- const buildConfig = buildConfigs[key];
11868
- const outputPath = external_path_.join(config.outputPath, key);
11869
-
11870
- return buildConfig
11871
- ? generateOneConfig({
11872
- ...config,
11873
- buildConfig,
11874
- outputPath,
11875
- dependencyFiles,
11876
- }).catch((e) => {
11877
- if (!e.stack) {
11878
- e = new Error(e.toString());
11784
+ let dropBarrels = false;
11785
+ const configKey = (p) => p.group.key + (config.releaseBuild ? "-release" : "-debug");
11786
+ targets.forEach((p) => {
11787
+ if (!p.group) {
11788
+ throw new Error(`Missing group in build target ${p.product}`);
11789
+ }
11790
+ const key = configKey(p);
11791
+ if (!(0,external_api_cjs_namespaceObject.hasProperty)(buildConfigs, key)) {
11792
+ p.group.dir = key;
11793
+ if (p.group.optimizerConfig.barrelMap &&
11794
+ !p.group.optimizerConfig.optBarrels) {
11795
+ dropBarrels = true;
11879
11796
  }
11880
- e.products = products[key];
11881
- throw e;
11882
- })
11883
- : promises_namespaceObject.rm(external_path_.resolve(workspace, outputPath), {
11884
- recursive: true,
11885
- force: true,
11886
- });
11797
+ buildConfigs[key] = null;
11798
+ }
11799
+ if (pick_one >= 0 ||
11800
+ !options.products ||
11801
+ options.products.includes(p.product) ||
11802
+ (p.shape && options.products.includes(p.shape))) {
11803
+ if (pick_one >= 0) {
11804
+ // don't modify the original array since it may be shared
11805
+ // (and *is* shared when we're called from test.js)
11806
+ options.products = [...options.products];
11807
+ options.products[pick_one] = p.product;
11808
+ pick_one = -1;
11809
+ }
11810
+ if (!buildConfigs[key]) {
11811
+ buildConfigs[key] = p.group.optimizerConfig;
11812
+ products[key] = [];
11813
+ }
11814
+ products[key].push(p.product);
11815
+ }
11887
11816
  });
11888
-
11889
- if (!manifestOk) {
11890
- if (dropBarrels) {
11891
- manifestDropBarrels(xml);
11892
- }
11893
- const manifestFile = external_path_.join(jungle_dir, "manifest.xml");
11894
- promises.push(writeManifest(manifestFile, xml));
11895
- relative_manifest = "manifest.xml";
11896
- }
11897
-
11898
- const parts = [`project.manifest=${relative_manifest}`];
11899
- const process_field = (prefix, base, name, mapper) => {
11900
- if (!base[name]) return;
11901
- const map_one = (s) => (mapper ? mapper(s) : s);
11902
- const map = (s) =>
11903
- Array.isArray(s) ? `[${s.map(map_one).join(";")}]` : map_one(s);
11904
- parts.push(`${prefix}${name} = ${base[name].map(map).join(";")}`);
11905
- };
11906
- targets.forEach((jungle) => {
11907
- if (!buildConfigs[configKey(jungle)]) return;
11908
- const { product, qualifier, group } = jungle;
11909
- const prefix = `${product}.`;
11910
- process_field(prefix, qualifier, "sourcePath", (s) =>
11911
- external_path_.join(
11912
- group.dir,
11913
- "source",
11914
- relative_path_no_dotdot(external_path_.relative(workspace, s))
11915
- )
11916
- .replace(/([\\\/]\*\*)[\\\/]\*/g, "$1")
11917
- );
11918
- if (group.optimizerConfig.optBarrels) {
11919
- parts.push(
11920
- `${prefix}barrelPath = ${Object.values(group.optimizerConfig.optBarrels)
11921
- .map(
11922
- (value) =>
11923
- `[${value.jungleFiles
11817
+ // console.log(JSON.stringify(targets));
11818
+ const jungle_dir = external_path_.resolve(workspace, config.outputPath);
11819
+ await promises_namespaceObject.mkdir(jungle_dir, { recursive: true });
11820
+ const relative_path = (s) => external_path_.relative(jungle_dir, s);
11821
+ let relative_manifest = relative_path(manifest);
11822
+ const manifestOk = (!config.checkManifest ||
11823
+ (await checkManifest(xml, targets.map((t) => t.product)))) &&
11824
+ !dropBarrels;
11825
+ let hasTests = false;
11826
+ const promises = Object.keys(buildConfigs)
11827
+ .sort()
11828
+ .map((key) => {
11829
+ const buildConfig = buildConfigs[key];
11830
+ const outputPath = external_path_.join(config.outputPath, key);
11831
+ return buildConfig
11832
+ ? generateOneConfig(buildConfig, dependencyFiles, {
11833
+ ...config,
11834
+ outputPath,
11835
+ })
11836
+ .catch((e) => {
11837
+ if (!e.stack) {
11838
+ e = new Error(e.toString());
11839
+ }
11840
+ e.products = products[key];
11841
+ throw e;
11842
+ })
11843
+ .then((t) => t && (hasTests = true))
11844
+ : promises_namespaceObject.rm(external_path_.resolve(workspace, outputPath), {
11845
+ recursive: true,
11846
+ force: true,
11847
+ });
11848
+ });
11849
+ if (!manifestOk) {
11850
+ if (dropBarrels) {
11851
+ manifestDropBarrels(xml);
11852
+ }
11853
+ const manifestFile = external_path_.join(jungle_dir, "manifest.xml");
11854
+ promises.push(writeManifest(manifestFile, xml));
11855
+ relative_manifest = "manifest.xml";
11856
+ }
11857
+ const parts = [`project.manifest=${relative_manifest}`];
11858
+ const process_field = (prefix, base, name, mapper = null) => {
11859
+ const obj = base[name];
11860
+ if (!obj)
11861
+ return;
11862
+ const map_one = (s) => (mapper ? mapper(s) : s);
11863
+ const map = (s) => Array.isArray(s) ? `[${s.map(map_one).join(";")}]` : map_one(s);
11864
+ parts.push(`${prefix}${name} = ${obj.map(map).join(";")}`);
11865
+ };
11866
+ targets.forEach((target) => {
11867
+ if (!buildConfigs[configKey(target)])
11868
+ return;
11869
+ const { product, qualifier, group } = target;
11870
+ if (!group) {
11871
+ throw new Error(`Missing group in target ${target.product}`);
11872
+ }
11873
+ const prefix = `${product}.`;
11874
+ process_field(prefix, qualifier, "sourcePath", (s) => external_path_.join(group.dir, "source", relative_path_no_dotdot(external_path_.relative(workspace, s)))
11875
+ .replace(/([\\\/]\*\*)[\\\/]\*/g, "$1"));
11876
+ if (group.optimizerConfig.optBarrels) {
11877
+ parts.push(`${prefix}barrelPath = ${Object.values(group.optimizerConfig.optBarrels)
11878
+ .map((value) => `[${value.jungleFiles
11924
11879
  .map((j) => relative_path(external_path_.join(value.optBarrelDir, j)))
11925
- .join(";")}]`
11926
- )
11927
- .join(";")}`
11928
- );
11929
- }
11930
- if (group.optimizerConfig.barrelMap) {
11931
- parts.push(
11932
- `${prefix}sourcePath = ${[`$(${prefix}sourcePath)`]
11933
- .concat(
11934
- Object.entries(group.optimizerConfig.barrelMap)
11935
- .map(([barrel, resolvedBarrel]) => {
11880
+ .join(";")}]`)
11881
+ .join(";")}`);
11882
+ }
11883
+ if (group.optimizerConfig.barrelMap) {
11884
+ parts.push(`${prefix}sourcePath = ${[`$(${prefix}sourcePath)`]
11885
+ .concat(Object.entries(group.optimizerConfig.barrelMap)
11886
+ .map(([barrel, resolvedBarrel]) => {
11936
11887
  const root = external_path_.dirname(resolvedBarrel.jungles[0]);
11937
- return (resolvedBarrel.qualifier.sourcePath || []).map((s) =>
11938
- external_path_.join(group.dir, "barrels", barrel, external_path_.relative(root, s))
11939
- .replace(/([\\\/]\*\*)[\\\/]\*/g, "$1")
11940
- );
11941
- })
11942
- .flat()
11943
- .sort()
11944
- .filter((s, i, arr) => !i || s !== arr[i - 1])
11945
- )
11946
- .join(";")}`
11947
- );
11948
- }
11949
- // annotations were handled via source transformations.
11950
- process_field(prefix, qualifier, "resourcePath", relative_path);
11951
- process_field(prefix, qualifier, "excludeAnnotations");
11952
- if (qualifier.lang) {
11953
- Object.keys(qualifier.lang).forEach((key) => {
11954
- process_field(`${prefix}lang.`, qualifier.lang, key, relative_path);
11955
- });
11956
- }
11957
- });
11958
-
11959
- const jungleFiles = external_path_.join(
11960
- jungle_dir,
11961
- `${config.releaseBuild ? "release" : "debug"}.jungle`
11962
- );
11963
- promises.push(promises_namespaceObject.writeFile(jungleFiles, parts.join("\n")));
11964
-
11965
- await Promise.all(promises);
11966
- return {
11967
- jungleFiles,
11968
- program: external_path_.basename(external_path_.dirname(manifest)),
11969
- };
11888
+ return (resolvedBarrel.qualifier.sourcePath || []).map((s) => external_path_.join(group.dir, "barrels", barrel, external_path_.relative(root, s))
11889
+ .replace(/([\\\/]\*\*)[\\\/]\*/g, "$1"));
11890
+ })
11891
+ .flat()
11892
+ .sort()
11893
+ .filter((s, i, arr) => !i || s !== arr[i - 1]))
11894
+ .join(";")}`);
11895
+ }
11896
+ // annotations were handled via source transformations.
11897
+ process_field(prefix, qualifier, "resourcePath", relative_path);
11898
+ process_field(prefix, qualifier, "excludeAnnotations");
11899
+ const qlang = qualifier.lang;
11900
+ if (qlang) {
11901
+ Object.keys(qlang).forEach((key) => {
11902
+ process_field(`${prefix}lang.`, qlang, key, relative_path);
11903
+ });
11904
+ }
11905
+ });
11906
+ const jungleFiles = external_path_.join(jungle_dir, `${config.releaseBuild ? "release" : "debug"}.jungle`);
11907
+ promises.push(promises_namespaceObject.writeFile(jungleFiles, parts.join("\n")));
11908
+ await Promise.all(promises);
11909
+ return {
11910
+ jungleFiles,
11911
+ xml,
11912
+ program: external_path_.basename(external_path_.dirname(manifest)),
11913
+ hasTests,
11914
+ };
11970
11915
  }
11971
-
11972
- async function fileInfoFromConfig(
11973
- workspace,
11974
- output,
11975
- buildConfig,
11976
- extraExcludes
11977
- ) {
11978
- const paths = (
11979
- await Promise.all(
11980
- buildConfig.sourcePath.map((pattern) =>
11981
- (0,external_util_cjs_namespaceObject.globa)(pattern, { cwd: workspace, mark: true })
11982
- )
11983
- )
11984
- ).flat();
11985
-
11986
- const files = (
11987
- await Promise.all(
11988
- paths.map((path) =>
11989
- path.endsWith("/")
11990
- ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.mc`, { cwd: workspace, mark: true })
11991
- : path
11992
- )
11993
- )
11994
- )
11995
- .flat()
11996
- .filter(
11997
- (file) =>
11998
- file.endsWith(".mc") &&
11916
+ async function fileInfoFromConfig(workspace, output, buildConfig, extraExcludes) {
11917
+ const paths = (await Promise.all(buildConfig.sourcePath?.map((pattern) => (0,external_util_cjs_namespaceObject.globa)(pattern, { cwd: workspace, mark: true })) || [])).flat();
11918
+ const files = (await Promise.all(paths.map((path) => path.endsWith("/")
11919
+ ? (0,external_util_cjs_namespaceObject.globa)(`${path}**/*.mc`, { cwd: workspace, mark: true })
11920
+ : path)))
11921
+ .flat()
11922
+ .filter((file) => file.endsWith(".mc") &&
11999
11923
  !external_path_.relative(workspace, file).startsWith("bin") &&
12000
11924
  (!buildConfig.sourceExcludes ||
12001
- !buildConfig.sourceExcludes.includes(file))
12002
- );
12003
-
12004
- const excludeAnnotations = Object.assign(
12005
- buildConfig.excludeAnnotations
12006
- ? Object.fromEntries(
12007
- buildConfig.excludeAnnotations.map((ex) => [ex, true])
12008
- )
12009
- : {},
12010
- extraExcludes
12011
- );
12012
-
12013
- return Object.fromEntries(
12014
- files.map((file) => [
12015
- file,
12016
- {
12017
- output: external_path_.join(
12018
- output,
12019
- relative_path_no_dotdot(external_path_.relative(workspace, file))
12020
- ),
12021
- excludeAnnotations,
12022
- },
12023
- ])
12024
- );
11925
+ !buildConfig.sourceExcludes.includes(file)));
11926
+ const excludeAnnotations = Object.assign(buildConfig.excludeAnnotations
11927
+ ? Object.fromEntries(buildConfig.excludeAnnotations.map((ex) => [ex, true]))
11928
+ : {}, extraExcludes);
11929
+ return {
11930
+ fnMap: Object.fromEntries(files.map((file) => [
11931
+ file,
11932
+ {
11933
+ output: external_path_.join(output, relative_path_no_dotdot(external_path_.relative(workspace, file))),
11934
+ excludeAnnotations,
11935
+ },
11936
+ ])),
11937
+ paths: paths.filter((path) => path.endsWith("/")),
11938
+ };
12025
11939
  }
12026
-
12027
11940
  function excludesFromAnnotations(barrel, annotations, resolvedBarrel) {
12028
- const excludes = resolvedBarrel.annotations
12029
- ? Object.fromEntries(resolvedBarrel.annotations.map((a) => [a, true]))
12030
- : {};
12031
- if (annotations && annotations[barrel]) {
12032
- annotations[barrel].forEach((a) => {
12033
- delete excludes[a];
12034
- });
12035
- }
12036
- return excludes;
11941
+ const excludes = resolvedBarrel.annotations
11942
+ ? Object.fromEntries(resolvedBarrel.annotations.map((a) => [a, true]))
11943
+ : {};
11944
+ if (annotations && annotations[barrel]) {
11945
+ annotations[barrel].forEach((a) => {
11946
+ delete excludes[a];
11947
+ });
11948
+ }
11949
+ return excludes;
12037
11950
  }
12038
-
12039
- async function generateOneConfig(config) {
12040
- const { workspace, buildConfig } = config;
12041
- const output = external_path_.join(workspace, config.outputPath);
12042
-
12043
- const dependencyFiles = [...config.dependencyFiles];
12044
-
12045
- const buildModeExcludes = {
12046
- // note: exclude debug in release builds, and release in debug builds
12047
- [config.releaseBuild ? "debug" : "release"]: true,
12048
- };
12049
-
12050
- const fnMap = await fileInfoFromConfig(
12051
- workspace,
12052
- external_path_.join(output, "source"),
12053
- buildConfig,
12054
- buildModeExcludes
12055
- );
12056
-
12057
- if (buildConfig.barrelMap) {
12058
- const barrelFnMaps = await Promise.all(
12059
- Object.entries(buildConfig.barrelMap)
12060
- .map(([barrel, resolvedBarrel]) => {
12061
- dependencyFiles.push(
12062
- ...resolvedBarrel.jungles,
12063
- resolvedBarrel.manifest
12064
- );
12065
- return fileInfoFromConfig(
12066
- external_path_.dirname(resolvedBarrel.jungles[0]),
12067
- external_path_.join(output, "barrels", barrel),
12068
- resolvedBarrel.qualifier,
12069
- {
12070
- ...buildModeExcludes,
12071
- ...excludesFromAnnotations(
12072
- barrel,
12073
- buildConfig.annotations,
12074
- resolvedBarrel
12075
- ),
12076
- }
12077
- );
11951
+ const configOptionsToCheck = [
11952
+ "workspace",
11953
+ "releaseBuild",
11954
+ "testBuild",
11955
+ "checkManifest",
11956
+ "ignoredExcludeAnnotations",
11957
+ "ignoredAnnotations",
11958
+ "ignoredSourcePaths",
11959
+ ];
11960
+ /**
11961
+ * @param {BuildConfig} config
11962
+ * @param {*} buildConfig
11963
+ * @param {string[]} dependencyFiles
11964
+ * @returns
11965
+ */
11966
+ async function generateOneConfig(buildConfig, dependencyFiles, config) {
11967
+ const { workspace } = config;
11968
+ const output = external_path_.join(workspace, config.outputPath);
11969
+ const buildModeExcludes = {
11970
+ // note: exclude debug in release builds, and release in debug builds
11971
+ [config.releaseBuild ? "debug" : "release"]: true,
11972
+ };
11973
+ if (!config.testBuild) {
11974
+ buildModeExcludes.test = true;
11975
+ }
11976
+ const { fnMap } = await fileInfoFromConfig(workspace, external_path_.join(output, "source"), buildConfig, buildModeExcludes);
11977
+ if (buildConfig.barrelMap) {
11978
+ const barrelFnMaps = await Promise.all(Object.entries(buildConfig.barrelMap)
11979
+ .map(([barrel, resolvedBarrel]) => {
11980
+ dependencyFiles = dependencyFiles.concat(resolvedBarrel.jungles, resolvedBarrel.manifest);
11981
+ return fileInfoFromConfig(external_path_.dirname(resolvedBarrel.jungles[0]), external_path_.join(output, "barrels", barrel), resolvedBarrel.qualifier, {
11982
+ ...buildModeExcludes,
11983
+ ...excludesFromAnnotations(barrel, buildConfig.annotations, resolvedBarrel),
11984
+ }).then(({ fnMap }) => fnMap);
12078
11985
  })
11986
+ .flat());
11987
+ barrelFnMaps.forEach((barrelFnMap) => Object.assign(fnMap, barrelFnMap));
11988
+ }
11989
+ const actualOptimizedFiles = (await (0,external_util_cjs_namespaceObject.globa)(external_path_.join(output, "**", "*.mc"), { mark: true }))
11990
+ .filter((file) => !file.endsWith("/"))
11991
+ .sort();
11992
+ const { hasTests, ...prevOptions } = JSON.parse(await promises_namespaceObject.readFile(external_path_.join(output, "build-info.json"), "utf-8")
11993
+ .catch(() => "{}"));
11994
+ // check that the set of files thats actually there is the same as the
11995
+ // set of files we're going to generate (in case eg a jungle file change
11996
+ // might have altered it), and that the options we care about haven't
11997
+ // changed
11998
+ if (hasTests != null &&
11999
+ configOptionsToCheck.every((option) => prevOptions[option] === config[option]) &&
12000
+ actualOptimizedFiles.length == Object.values(fnMap).length &&
12001
+ Object.values(fnMap)
12002
+ .map((v) => v.output)
12003
+ .sort()
12004
+ .every((f, i) => f == actualOptimizedFiles[i])) {
12005
+ // now if the newest source file is older than
12006
+ // the oldest optimized file, we don't need to regenerate
12007
+ const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(Object.keys(fnMap).concat(dependencyFiles));
12008
+ const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(Object.values(fnMap).map((v) => v.output));
12009
+ if (source_time < opt_time && 1653671578547 < opt_time) {
12010
+ return hasTests;
12011
+ }
12012
+ }
12013
+ await promises_namespaceObject.rm(output, { recursive: true, force: true });
12014
+ await promises_namespaceObject.mkdir(output, { recursive: true });
12015
+ await optimizeMonkeyC(fnMap);
12016
+ return Promise.all(Object.values(fnMap).map(async (info) => {
12017
+ const name = info.output;
12018
+ const dir = external_path_.dirname(name);
12019
+ await promises_namespaceObject.mkdir(dir, { recursive: true });
12020
+ const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(info.ast, info.monkeyCSource);
12021
+ await promises_namespaceObject.writeFile(name, opt_source);
12022
+ return info.hasTests;
12023
+ })).then((results) => {
12024
+ const hasTests = results.some((v) => v);
12025
+ return promises_namespaceObject.writeFile(external_path_.join(output, "build-info.json"), JSON.stringify({
12026
+ hasTests,
12027
+ ...Object.fromEntries(configOptionsToCheck.map((option) => [option, config[option]])),
12028
+ }))
12029
+ .then(() => hasTests);
12030
+ });
12031
+ }
12032
+ async function getProjectAnalysis(targets, analysis, options) {
12033
+ const sourcePath = targets
12034
+ .map(({ qualifier: { sourcePath } }) => sourcePath)
12035
+ .filter((sp) => sp != null)
12079
12036
  .flat()
12080
- );
12081
- barrelFnMaps.forEach((barrelFnMap) => Object.assign(fnMap, barrelFnMap));
12082
- }
12083
-
12084
- const actualOptimizedFiles = (
12085
- await (0,external_util_cjs_namespaceObject.globa)(external_path_.join(output, "**", "*.mc"), { mark: true })
12086
- )
12087
- .filter((file) => !file.endsWith("/"))
12088
- .sort();
12089
-
12090
- // check that the set of files thats actually there is the same as the
12091
- // set of files we're going to generate (in case eg a jungle file change
12092
- // might have altered it)
12093
- if (
12094
- actualOptimizedFiles.length == Object.values(fnMap).length &&
12095
- Object.values(fnMap)
12096
- .map((v) => v.output)
12097
- .sort()
12098
- .every((f, i) => f == actualOptimizedFiles[i])
12099
- ) {
12100
- // now if the newest source file is older than
12101
- // the oldest optimized file, we don't need to regenerate
12102
- const source_time = await (0,external_util_cjs_namespaceObject.last_modified)(
12103
- Object.keys(fnMap).concat(dependencyFiles)
12104
- );
12105
- const opt_time = await (0,external_util_cjs_namespaceObject.first_modified)(
12106
- Object.values(fnMap).map((v) => v.output)
12107
- );
12108
- if (source_time < opt_time && 1652050734499 < opt_time) return;
12109
- }
12110
-
12111
- await promises_namespaceObject.rm(output, { recursive: true, force: true });
12112
- await promises_namespaceObject.mkdir(output, { recursive: true });
12113
- const optFiles = await optimizeMonkeyC(fnMap);
12114
- return await Promise.all(
12115
- optFiles.map(async (file) => {
12116
- const name = fnMap[file.name].output;
12117
- const dir = external_path_.dirname(name);
12118
- await promises_namespaceObject.mkdir(dir, { recursive: true });
12119
-
12120
- const opt_source = (0,external_api_cjs_namespaceObject.formatAst)(file.ast);
12121
- await promises_namespaceObject.writeFile(name, opt_source);
12122
- return name;
12123
- })
12124
- );
12037
+ .sort()
12038
+ .filter((s, i, arr) => !i || s !== arr[i - 1]);
12039
+ const { fnMap, paths } = await fileInfoFromConfig(options.workspace, options.workspace, { sourcePath }, {});
12040
+ if (analysis) {
12041
+ Object.entries(fnMap).forEach(([k, v]) => {
12042
+ if ((0,external_api_cjs_namespaceObject.hasProperty)(analysis.fnMap, k)) {
12043
+ const old = analysis.fnMap[k];
12044
+ if (old.monkeyCSource)
12045
+ v.monkeyCSource = old.monkeyCSource;
12046
+ if (old.ast)
12047
+ v.ast = old.ast;
12048
+ }
12049
+ });
12050
+ }
12051
+ if (!(await getFileASTs(fnMap))) {
12052
+ return { fnMap, paths };
12053
+ }
12054
+ const state = await analyze(fnMap);
12055
+ return { fnMap: fnMap, paths, state };
12125
12056
  }
12126
-
12057
+ /**
12058
+ *
12059
+ * @param {BuildConfig} options
12060
+ * @returns
12061
+ */
12127
12062
  async function generateApiMirTests(options) {
12128
- const config = { ...defaultConfig, ...(options || {}) };
12129
- const tests = [];
12130
- const api = await (0,external_api_cjs_namespaceObject.getApiMapping)();
12131
- const findConstants = (node) => {
12132
- Object.entries(node.decls).forEach(([key, decl]) => {
12133
- if (decl.length > 1) throw `Bad decl length:${node.fullName}.${key}`;
12134
- if (decl.length != 1) return;
12135
- if (decl[0].type == "Literal") {
12136
- tests.push([`${node.fullName}.${key}`, (0,external_api_cjs_namespaceObject.formatAst)(decl[0])]);
12137
- } else if (decl[0].decls) {
12138
- findConstants(decl[0]);
12139
- }
12140
- });
12141
- };
12142
- findConstants(api);
12143
- function hasTests(name) {
12144
- const names = name.split(".");
12145
- return names
12146
- .map((t, i, arr) => arr.slice(0, i).join(".") + " has :" + t)
12147
- .slice(2)
12148
- .join(" && ");
12149
- }
12150
- const source = [
12151
- "import Toybox.Lang;",
12152
- "import Toybox.Test;",
12153
- "(:test,:typecheck(false))",
12154
- "function apiTest(logger as Logger) as Boolean {",
12155
- ...tests.map(
12156
- (t) =>
12157
- ` if (${hasTests(t[0])}) { if (${t[0]} != ${t[1]}) { logger.debug("${
12158
- t[0]
12159
- }: "+${t[0]}.toString()+" != ${
12160
- t[1]
12161
- }"); } } else { logger.debug("Not tested: ${t[0]}"); }`
12162
- ),
12163
- " return true;",
12164
- "}",
12165
- ].join("\n");
12166
- const workspace = config.workspace;
12167
- return promises_namespaceObject.writeFile(`${workspace}/source/apiTest.mc`, source);
12063
+ const config = { ...defaultConfig, ...(options || {}) };
12064
+ const tests = [];
12065
+ const api = await (0,external_api_cjs_namespaceObject.getApiMapping)();
12066
+ if (!api) {
12067
+ throw new Error("Failed to read api.mir");
12068
+ }
12069
+ const findConstants = (node) => {
12070
+ node.decls &&
12071
+ Object.entries(node.decls).forEach(([key, decl]) => {
12072
+ if (decl.length > 1)
12073
+ throw `Bad decl length:${node.fullName}.${key}`;
12074
+ if (decl.length != 1)
12075
+ return;
12076
+ const d = decl[0];
12077
+ if (d.type === "EnumStringMember" ||
12078
+ (d.type === "VariableDeclarator" && d.kind === "const")) {
12079
+ if (!d.init) {
12080
+ throw new Error(`Missing init for ${node.fullName}.${key}`);
12081
+ }
12082
+ tests.push([`${node.fullName}.${key}`, (0,external_api_cjs_namespaceObject.formatAst)(d.init)]);
12083
+ }
12084
+ else if ((0,external_api_cjs_namespaceObject.isStateNode)(d)) {
12085
+ findConstants(d);
12086
+ }
12087
+ });
12088
+ };
12089
+ findConstants(api);
12090
+ function hasTests(name) {
12091
+ const names = name.split(".");
12092
+ return names
12093
+ .map((t, i, arr) => arr.slice(0, i).join(".") + " has :" + t)
12094
+ .slice(2)
12095
+ .join(" && ");
12096
+ }
12097
+ const source = [
12098
+ "import Toybox.Lang;",
12099
+ "import Toybox.Test;",
12100
+ "(:test,:typecheck(false))",
12101
+ "function apiTest(logger as Logger) as Boolean {",
12102
+ ...tests.map((t) => ` if (${hasTests(t[0])}) { if (${t[0]} != ${t[1]}) { logger.debug("${t[0]}: "+${t[0]}.toString()+" != ${t[1]}"); } } else { logger.debug("Not tested: ${t[0]}"); }`),
12103
+ " return true;",
12104
+ "}",
12105
+ ].join("\n");
12106
+ const workspace = config.workspace;
12107
+ return promises_namespaceObject.writeFile(`${workspace}/source/apiTest.mc`, source);
12168
12108
  }
12169
12109
 
12170
12110
  })();