pxt-core 7.5.2 → 7.5.5

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.
Files changed (67) hide show
  1. package/built/cli.js +61 -46
  2. package/built/pxt.js +256 -91
  3. package/built/pxtblockly.js +652 -657
  4. package/built/pxtblocks.d.ts +1 -0
  5. package/built/pxtblocks.js +98 -42
  6. package/built/pxtcompiler.js +45 -4
  7. package/built/pxtlib.d.ts +7 -2
  8. package/built/pxtlib.js +77 -39
  9. package/built/pxtpy.js +73 -2
  10. package/built/server.js +4 -0
  11. package/built/target.js +1 -1
  12. package/built/web/authcode/css/main.1cf9dc37.css +2 -0
  13. package/built/web/authcode/js/main.03da4c20.js +2 -0
  14. package/built/web/main.js +1 -1
  15. package/built/web/pxtapp.js +1 -1
  16. package/built/web/pxtasseteditor.js +1 -1
  17. package/built/web/pxtblockly.js +2 -2
  18. package/built/web/pxtblocks.js +1 -1
  19. package/built/web/pxtcompiler.js +1 -1
  20. package/built/web/pxtembed.js +2 -2
  21. package/built/web/pxtlib.js +1 -1
  22. package/built/web/pxtpy.js +1 -1
  23. package/built/web/pxtworker.js +1 -1
  24. package/built/web/react-common-authcode.css +6200 -0
  25. package/built/web/react-common-skillmap.css +1 -1
  26. package/built/web/rtlreact-common-skillmap.css +1 -1
  27. package/built/web/rtlsemantic.css +1 -1
  28. package/built/web/semantic.css +1 -1
  29. package/built/web/skillmap/css/{main.e0620cee.chunk.css → main.73b22966.chunk.css} +1 -1
  30. package/built/web/skillmap/js/{2.f7cdfd75.chunk.js → 2.3e47a285.chunk.js} +2 -2
  31. package/built/web/skillmap/js/main.2485091f.chunk.js +1 -0
  32. package/common-docs/faq.md +1 -1
  33. package/common-docs/translate.md +2 -2
  34. package/docfiles/apptracking.html +1 -1
  35. package/docfiles/tracking.html +1 -1
  36. package/localtypings/projectheader.d.ts +6 -0
  37. package/package.json +5 -3
  38. package/pxtarget.json +1 -1
  39. package/react-common/components/controls/Button.tsx +4 -1
  40. package/react-common/components/controls/EditorToggle.tsx +153 -0
  41. package/react-common/components/controls/FocusList.tsx +120 -0
  42. package/react-common/components/controls/Input.tsx +4 -4
  43. package/react-common/components/controls/Link.tsx +36 -0
  44. package/react-common/components/controls/MenuBar.tsx +5 -95
  45. package/react-common/components/controls/MenuDropdown.tsx +4 -1
  46. package/react-common/components/controls/Textarea.tsx +103 -0
  47. package/react-common/components/share/GifInfo.tsx +63 -0
  48. package/react-common/components/share/GifRecorder.tsx +97 -0
  49. package/react-common/components/share/Share.tsx +49 -0
  50. package/react-common/components/share/ShareInfo.tsx +186 -0
  51. package/react-common/components/share/SocialButton.tsx +53 -0
  52. package/react-common/styles/controls/Button.less +4 -0
  53. package/react-common/styles/controls/EditorToggle.less +271 -0
  54. package/react-common/styles/controls/Modal.less +7 -5
  55. package/react-common/styles/controls/Textarea.less +81 -0
  56. package/react-common/styles/react-common-authcode-core.less +10 -0
  57. package/react-common/styles/react-common-authcode.less +12 -0
  58. package/react-common/styles/react-common-variables.less +19 -0
  59. package/react-common/styles/react-common.less +3 -0
  60. package/react-common/styles/share/share.less +116 -0
  61. package/theme/image-editor/imageEditor.less +8 -116
  62. package/webapp/public/authcode.html +1 -0
  63. package/webapp/public/blockly/blockly_compressed.js +554 -615
  64. package/webapp/public/index.html +1 -1
  65. package/webapp/public/run.html +32 -5
  66. package/webapp/public/skillmap.html +2 -2
  67. package/built/web/skillmap/js/main.f6866fc6.chunk.js +0 -1
package/built/pxt.js CHANGED
@@ -101595,6 +101595,25 @@ var pxt;
101595
101595
  });
101596
101596
  }
101597
101597
  blocks.hasHandler = hasHandler;
101598
+ function getHelpUrl(fn) {
101599
+ if (fn.attributes.help) {
101600
+ const helpUrl = fn.attributes.help.replace(/^\//, '');
101601
+ if (/^github:/.test(helpUrl)) {
101602
+ return helpUrl;
101603
+ }
101604
+ else if (helpUrl !== "none") {
101605
+ return "/reference/" + helpUrl;
101606
+ }
101607
+ }
101608
+ else if (fn.pkg && !pxt.appTarget.bundledpkgs[fn.pkg]) { // added package
101609
+ let anchor = fn.qName.toLowerCase().split('.');
101610
+ if (anchor[0] == fn.pkg)
101611
+ anchor.shift();
101612
+ return `/pkg/${fn.pkg}#${encodeURIComponent(anchor.join('-'))}`;
101613
+ }
101614
+ return undefined;
101615
+ }
101616
+ blocks.getHelpUrl = getHelpUrl;
101598
101617
  /**
101599
101618
  * Returns which Blockly block type to use for an argument reporter based
101600
101619
  * on the specified TypeScript type.
@@ -101606,6 +101625,9 @@ var pxt;
101606
101625
  if (varType === "boolean" || varType === "number" || varType === "string") {
101607
101626
  reporterType = `argument_reporter_${varType}`;
101608
101627
  }
101628
+ if (/^(?:Array<(?:.+)>)|(?:(?:.+)\[\])$/.test(varType)) {
101629
+ reporterType = "argument_reporter_array";
101630
+ }
101609
101631
  return reporterType;
101610
101632
  }
101611
101633
  blocks.reporterTypeForArgType = reporterTypeForArgType;
@@ -107513,6 +107535,7 @@ var pxt;
107513
107535
  github.isOrgAsync = isOrgAsync;
107514
107536
  class MemoryGithubDb {
107515
107537
  constructor() {
107538
+ this.latestVersions = {};
107516
107539
  this.configs = {};
107517
107540
  this.packages = {};
107518
107541
  }
@@ -107535,8 +107558,10 @@ var pxt;
107535
107558
  return pxt.U.clone(cfg);
107536
107559
  }
107537
107560
  async loadConfigAsync(repopath, tag) {
107538
- if (!tag)
107561
+ if (!tag) {
107562
+ pxt.debug(`dep: default to master branch`);
107539
107563
  tag = "master";
107564
+ }
107540
107565
  // cache lookup
107541
107566
  const key = `${repopath}/${tag}`;
107542
107567
  let res = this.configs[key];
@@ -107559,9 +107584,19 @@ var pxt;
107559
107584
  const cfg = await downloadTextAsync(repopath, tag, pxt.CONFIG_NAME);
107560
107585
  return this.cacheConfig(key, cfg);
107561
107586
  }
107587
+ async latestVersionAsync(repopath, config) {
107588
+ let resolved = this.latestVersions[repopath];
107589
+ if (!resolved) {
107590
+ pxt.debug(`dep: resolve latest version of ${repopath}`);
107591
+ this.latestVersions[repopath] = resolved = await pxt.github.latestVersionAsync(repopath, config, true, false);
107592
+ }
107593
+ return resolved;
107594
+ }
107562
107595
  async loadPackageAsync(repopath, tag) {
107563
- if (!tag)
107596
+ if (!tag) {
107597
+ pxt.debug(`load pkg: default to master branch`);
107564
107598
  tag = "master";
107599
+ }
107565
107600
  // try using github proxy first
107566
107601
  if (hasProxy()) {
107567
107602
  try {
@@ -107877,34 +107912,38 @@ var pxt;
107877
107912
  .then(resolveRefAsync, e => ghGetJsonAsync(`https://api.github.com/repos/${parsed.slug}/git/refs/heads/${tag}`)
107878
107913
  .then(resolveRefAsync));
107879
107914
  }
107880
- function pkgConfigAsync(repopath, tag = "master") {
107881
- return github.db.loadConfigAsync(repopath, tag);
107915
+ async function pkgConfigAsync(repopath, tag, config) {
107916
+ if (!tag)
107917
+ tag = await github.db.latestVersionAsync(repopath, config);
107918
+ return await github.db.loadConfigAsync(repopath, tag);
107882
107919
  }
107883
107920
  github.pkgConfigAsync = pkgConfigAsync;
107884
- function downloadPackageAsync(repoWithTag, config) {
107921
+ async function downloadPackageAsync(repoWithTag, config) {
107885
107922
  const p = parseRepoId(repoWithTag);
107886
107923
  if (!p) {
107887
107924
  pxt.log('Unknown GitHub syntax');
107888
- return Promise.resolve(undefined);
107925
+ return undefined;
107889
107926
  }
107890
107927
  if (isRepoBanned(p, config)) {
107891
107928
  pxt.tickEvent("github.download.banned");
107892
107929
  pxt.log('Github repo is banned');
107893
- return Promise.resolve(undefined);
107930
+ return undefined;
107894
107931
  }
107895
- return github.db.loadPackageAsync(p.fullName, p.tag)
107896
- .then(cached => {
107897
- const dv = upgradedDisablesVariants(config, repoWithTag);
107898
- if (dv) {
107899
- const cfg = pxt.Package.parseAndValidConfig(cached.files[pxt.CONFIG_NAME]);
107900
- if (cfg) {
107901
- pxt.log(`auto-disable ${dv.join(",")} due to targetconfig entry for ${repoWithTag}`);
107902
- cfg.disablesVariants = dv;
107903
- cached.files[pxt.CONFIG_NAME] = pxt.Package.stringifyConfig(cfg);
107904
- }
107932
+ // always try to upgrade unbound versions
107933
+ if (!p.tag) {
107934
+ p.tag = await github.db.latestVersionAsync(p.slug, config);
107935
+ }
107936
+ const cached = await github.db.loadPackageAsync(p.fullName, p.tag);
107937
+ const dv = upgradedDisablesVariants(config, repoWithTag);
107938
+ if (dv) {
107939
+ const cfg = pxt.Package.parseAndValidConfig(cached.files[pxt.CONFIG_NAME]);
107940
+ if (cfg) {
107941
+ pxt.log(`auto-disable ${dv.join(",")} due to targetconfig entry for ${repoWithTag}`);
107942
+ cfg.disablesVariants = dv;
107943
+ cached.files[pxt.CONFIG_NAME] = pxt.Package.stringifyConfig(cfg);
107905
107944
  }
107906
- return cached;
107907
- });
107945
+ }
107946
+ return cached;
107908
107947
  }
107909
107948
  github.downloadPackageAsync = downloadPackageAsync;
107910
107949
  async function downloadLatestPackageAsync(repo) {
@@ -107914,7 +107953,7 @@ var pxt;
107914
107953
  const repoWithTag = `${repo.fullName}#${tag}`;
107915
107954
  await pxt.github.downloadPackageAsync(repoWithTag, packageConfig);
107916
107955
  // return config
107917
- const config = await pkgConfigAsync(repo.fullName, tag);
107956
+ const config = await pkgConfigAsync(repo.fullName, tag, packageConfig);
107918
107957
  const version = `github:${repoWithTag}`;
107919
107958
  return { version, config };
107920
107959
  }
@@ -108244,14 +108283,15 @@ var pxt;
108244
108283
  }
108245
108284
  github.isGithubId = isGithubId;
108246
108285
  function stringifyRepo(p) {
108247
- return p ? "github:" + p.fullName.toLowerCase() + "#" + (p.tag || "master") : undefined;
108286
+ return p ? "github:" + p.fullName.toLowerCase() + (p.tag ? `#${p.tag}` : '') : undefined;
108248
108287
  }
108249
108288
  github.stringifyRepo = stringifyRepo;
108250
- function normalizeRepoId(id) {
108289
+ function normalizeRepoId(id, defaultTag) {
108251
108290
  const gid = parseRepoId(id);
108252
108291
  if (!gid)
108253
108292
  return undefined;
108254
- gid.tag = gid.tag || "master";
108293
+ if (!gid.tag && defaultTag)
108294
+ gid.tag = defaultTag;
108255
108295
  return stringifyRepo(gid);
108256
108296
  }
108257
108297
  github.normalizeRepoId = normalizeRepoId;
@@ -111393,22 +111433,20 @@ var pxt;
111393
111433
  && json.dependencies && Object.keys(json.dependencies).every(k => typeof json.dependencies[k] === "string")
111394
111434
  && json;
111395
111435
  }
111396
- static getConfigAsync(pkgTargetVersion, id, fullVers) {
111397
- return Promise.resolve().then(() => {
111398
- if (pxt.github.isGithubId(fullVers)) {
111399
- const repoInfo = pxt.github.parseRepoId(fullVers);
111400
- return pxt.packagesConfigAsync()
111401
- .then(config => pxt.github.repoAsync(repoInfo.fullName, config)) // Make sure repo exists and is whitelisted
111402
- .then(gitRepo => gitRepo ? pxt.github.pkgConfigAsync(repoInfo.fullName, repoInfo.tag) : null);
111403
- }
111404
- else {
111405
- // If it's not from GH, assume it's a bundled package
111406
- // TODO: Add logic for shared packages if we enable that
111407
- const updatedRef = pxt.patching.upgradePackageReference(pkgTargetVersion, id, fullVers);
111408
- const bundledPkg = pxt.appTarget.bundledpkgs[updatedRef];
111409
- return JSON.parse(bundledPkg[pxt.CONFIG_NAME]);
111410
- }
111411
- });
111436
+ static async getConfigAsync(pkgTargetVersion, id, fullVers) {
111437
+ if (pxt.github.isGithubId(fullVers)) {
111438
+ const repoInfo = pxt.github.parseRepoId(fullVers);
111439
+ const packagesConfig = await pxt.packagesConfigAsync();
111440
+ const gitRepo = await pxt.github.repoAsync(repoInfo.fullName, packagesConfig); // Make sure repo exists and is whitelisted
111441
+ return gitRepo ? await pxt.github.pkgConfigAsync(repoInfo.fullName, repoInfo.tag, packagesConfig) : null;
111442
+ }
111443
+ else {
111444
+ // If it's not from GH, assume it's a bundled package
111445
+ // TODO: Add logic for shared packages if we enable that
111446
+ const updatedRef = pxt.patching.upgradePackageReference(pkgTargetVersion, id, fullVers);
111447
+ const bundledPkg = pxt.appTarget.bundledpkgs[updatedRef];
111448
+ return JSON.parse(bundledPkg[pxt.CONFIG_NAME]);
111449
+ }
111412
111450
  }
111413
111451
  static corePackages() {
111414
111452
  const pkgs = pxt.appTarget.bundledpkgs;
@@ -120902,6 +120940,9 @@ var pxt;
120902
120940
  });
120903
120941
  });
120904
120942
  }
120943
+ latestVersionAsync(repopath, config) {
120944
+ return this.db.latestVersionAsync(repopath, config);
120945
+ }
120905
120946
  loadConfigAsync(repopath, tag) {
120906
120947
  return this.loadAsync(repopath, tag, "pxt", (r, t) => this.db.loadConfigAsync(r, t));
120907
120948
  }
@@ -125490,6 +125531,8 @@ ${output}</xml>`;
125490
125531
  return getTaggedTemplateExpression(n);
125491
125532
  case SK.CallExpression:
125492
125533
  return getStatementBlock(n, undefined, undefined, true);
125534
+ case SK.AsExpression:
125535
+ return getOutputBlock(n.expression);
125493
125536
  default:
125494
125537
  error(n, pxtc.Util.lf("Unsupported syntax kind for output expression block: {0}", SK[n.kind]));
125495
125538
  break;
@@ -126370,11 +126413,14 @@ ${output}</xml>`;
126370
126413
  r.mutationChildren = [];
126371
126414
  n.parameters.forEach(p => {
126372
126415
  const paramName = p.name.getText();
126416
+ let type = normalizeType(p.type.getText());
126417
+ if (pxt.U.endsWith(type, "[]"))
126418
+ type = "Array";
126373
126419
  r.mutationChildren.push({
126374
126420
  nodeName: "arg",
126375
126421
  attributes: {
126376
126422
  name: paramName,
126377
- type: p.type.getText(),
126423
+ type,
126378
126424
  id: env.functionParamIds[name][paramName]
126379
126425
  }
126380
126426
  });
@@ -126450,11 +126496,14 @@ ${output}</xml>`;
126450
126496
  env.declaredFunctions[name].parameters.forEach((p, i) => {
126451
126497
  const paramName = p.name.getText();
126452
126498
  const argId = env.functionParamIds[name][paramName];
126499
+ let type = normalizeType(p.type.getText());
126500
+ if (pxt.U.endsWith(type, "[]"))
126501
+ type = "Array";
126453
126502
  r.mutationChildren.push({
126454
126503
  nodeName: "arg",
126455
126504
  attributes: {
126456
126505
  name: paramName,
126457
- type: p.type.getText(),
126506
+ type: type,
126458
126507
  id: argId
126459
126508
  }
126460
126509
  });
@@ -127322,7 +127371,8 @@ ${output}</xml>`;
127322
127371
  if (!type) {
127323
127372
  return pxtc.Util.lf("Function parameters must declare a type");
127324
127373
  }
127325
- if (env.opts.allowedArgumentTypes.indexOf(normalizeType(type)) === -1) {
127374
+ const normalized = normalizeType(type);
127375
+ if (env.opts.allowedArgumentTypes.indexOf(normalized) === -1 && !pxtc.U.endsWith(normalized, "[]")) {
127326
127376
  return pxtc.Util.lf("Only types that can be added in blocks can be used for function arguments");
127327
127377
  }
127328
127378
  }
@@ -127597,6 +127647,8 @@ ${output}</xml>`;
127597
127647
  return checkStatement(n, env, true, undefined);
127598
127648
  case SK.TaggedTemplateExpression:
127599
127649
  return checkTaggedTemplateExpression(n, env);
127650
+ case SK.AsExpression:
127651
+ return checkAsExpression(n);
127600
127652
  }
127601
127653
  return pxtc.Util.lf("Unsupported syntax kind for output expression block: {0}", SK[n.kind]);
127602
127654
  function checkStringLiteral(n) {
@@ -127693,6 +127745,31 @@ ${output}</xml>`;
127693
127745
  // The compiler will have already caught any invalid tags or templates
127694
127746
  return undefined;
127695
127747
  }
127748
+ function checkAsExpression(n) {
127749
+ // The only time we allow casts to decompile is in the very special case where someone has
127750
+ // written a program comparing two string, boolean, or numeric literals in blocks and
127751
+ // converted to text. e.g. 3 == 5 or true != false
127752
+ if (n.type.getText().trim() === "any" && (ts.isStringOrNumericLiteral(n.expression) ||
127753
+ n.expression.kind === SK.TrueKeyword || n.expression.kind === SK.FalseKeyword)) {
127754
+ const [parent] = getParent(n);
127755
+ if (parent.kind === SK.BinaryExpression) {
127756
+ switch (parent.operatorToken.kind) {
127757
+ case SK.EqualsEqualsToken:
127758
+ case SK.EqualsEqualsEqualsToken:
127759
+ case SK.ExclamationEqualsToken:
127760
+ case SK.ExclamationEqualsEqualsToken:
127761
+ case SK.LessThanToken:
127762
+ case SK.LessThanEqualsToken:
127763
+ case SK.GreaterThanToken:
127764
+ case SK.GreaterThanEqualsToken:
127765
+ return undefined;
127766
+ default:
127767
+ break;
127768
+ }
127769
+ }
127770
+ }
127771
+ return pxtc.Util.lf("Casting not supported in blocks");
127772
+ }
127696
127773
  function getParent(node) {
127697
127774
  if (!node.parent) {
127698
127775
  return [undefined, node];
@@ -133485,8 +133562,10 @@ ${lbl}: .short 0xffff
133485
133562
  return needsNumberConversions() ? pxtc.ir.rtcall("pxt::toInt", [e]) : e;
133486
133563
  };
133487
133564
  // c = a[i]
133488
- if (iterVar)
133565
+ if (iterVar) {
133489
133566
  proc.emitExpr(iterVar.storeByRef(pxtc.ir.rtcall(indexer, [collectionVar.loadCore(), toInt(intVarIter.loadCore())])));
133567
+ emitBrk(node.initializer);
133568
+ }
133490
133569
  flushHoistedFunctionDefinitions();
133491
133570
  emit(node.statement);
133492
133571
  proc.emitLblDirect(l.cont);
@@ -140954,6 +141033,14 @@ var pxt;
140954
141033
  FloorDiv: 1,
140955
141034
  Mult: 1, // this can be also used on strings and arrays, but let's ignore that for now
140956
141035
  };
141036
+ const arithmeticCompareOps = {
141037
+ Eq: 1,
141038
+ NotEq: 1,
141039
+ Lt: 1,
141040
+ LtE: 1,
141041
+ Gt: 1,
141042
+ GtE: 1
141043
+ };
140957
141044
  const opMapping = {
140958
141045
  Add: "+",
140959
141046
  Sub: "-",
@@ -141825,9 +141912,24 @@ var pxt;
141825
141912
  let idx = B.mkInfix(expr(n.comparators[0]), ".", B.H.mkCall("indexOf", [expr(n.left)]));
141826
141913
  return B.mkInfix(idx, n.ops[0] == "In" ? ">=" : "<", B.mkText("0"));
141827
141914
  }
141828
- let r = binop(expr(n.left), n.ops[0], expr(n.comparators[0]));
141915
+ let left = expr(n.left);
141916
+ let right = expr(n.comparators[0]);
141917
+ // Special handling for comparisons of literal types, e.g. 0 === 5
141918
+ const castIfLiteralComparison = (op, leftExpr, rightExpr) => {
141919
+ if (arithmeticCompareOps[op]) {
141920
+ if (isNumStringOrBool(leftExpr) && isNumStringOrBool(rightExpr) && B.flattenNode([left]) !== B.flattenNode([right])) {
141921
+ left = B.H.mkParenthesizedExpression(B.mkGroup([left, B.mkText(" as any")]));
141922
+ right = B.H.mkParenthesizedExpression(B.mkGroup([right, B.mkText(" as any")]));
141923
+ }
141924
+ }
141925
+ };
141926
+ castIfLiteralComparison(n.ops[0], n.left, n.comparators[0]);
141927
+ let r = binop(left, n.ops[0], right);
141829
141928
  for (let i = 1; i < n.ops.length; ++i) {
141830
- r = binop(r, "And", binop(expr(n.comparators[i - 1]), n.ops[i], expr(n.comparators[i])));
141929
+ left = expr(n.comparators[i - 1]);
141930
+ right = expr(n.comparators[i]);
141931
+ castIfLiteralComparison(n.ops[i], n.comparators[i - 1], n.comparators[i]);
141932
+ r = binop(r, "And", binop(left, n.ops[i], right));
141831
141933
  }
141832
141934
  return r;
141833
141935
  },
@@ -142615,6 +142717,16 @@ var pxt;
142615
142717
  const t = canonicalize(typeOf(expr));
142616
142718
  return t && t.primType === "@array";
142617
142719
  }
142720
+ function isNumStringOrBool(expr) {
142721
+ switch (expr.kind) {
142722
+ case "Num":
142723
+ case "Str":
142724
+ return true;
142725
+ case "NameConstant":
142726
+ return expr.value !== null;
142727
+ }
142728
+ return false;
142729
+ }
142618
142730
  function buildOverride(override, args, recv) {
142619
142731
  const result = [];
142620
142732
  for (const part of override.parts) {
@@ -145986,6 +146098,42 @@ var pxt;
145986
146098
  }
145987
146099
  return fn(s);
145988
146100
  }
146101
+ function getParent(node) {
146102
+ if (!node.parent) {
146103
+ return undefined;
146104
+ }
146105
+ else if (node.parent.kind === ts.SyntaxKind.ParenthesizedExpression) {
146106
+ return getParent(node.parent);
146107
+ }
146108
+ else {
146109
+ return node.parent;
146110
+ }
146111
+ }
146112
+ function isDecompilableAsExpression(n) {
146113
+ // The only time we allow casts to decompile is in the very special case where someone has
146114
+ // written a program comparing two string, boolean, or numeric literals in blocks and
146115
+ // converted to text. e.g. 3 == 5 or true != false
146116
+ if (n.type.getText().trim() === "any" && (ts.isNumericLiteral(n.expression) || ts.isStringLiteral(n.expression) ||
146117
+ n.expression.kind === ts.SyntaxKind.TrueKeyword || n.expression.kind === ts.SyntaxKind.FalseKeyword)) {
146118
+ const parent = getParent(n);
146119
+ if ((parent === null || parent === void 0 ? void 0 : parent.kind) === ts.SyntaxKind.BinaryExpression) {
146120
+ switch (parent.operatorToken.kind) {
146121
+ case ts.SyntaxKind.EqualsEqualsToken:
146122
+ case ts.SyntaxKind.EqualsEqualsEqualsToken:
146123
+ case ts.SyntaxKind.ExclamationEqualsToken:
146124
+ case ts.SyntaxKind.ExclamationEqualsEqualsToken:
146125
+ case ts.SyntaxKind.LessThanToken:
146126
+ case ts.SyntaxKind.LessThanEqualsToken:
146127
+ case ts.SyntaxKind.GreaterThanToken:
146128
+ case ts.SyntaxKind.GreaterThanEqualsToken:
146129
+ return true;
146130
+ default:
146131
+ break;
146132
+ }
146133
+ }
146134
+ }
146135
+ return false;
146136
+ }
145989
146137
  function isConstExp(s) {
145990
146138
  let isConst = (s) => {
145991
146139
  switch (s.kind) {
@@ -146068,6 +146216,8 @@ var pxt;
146068
146216
  return asExpRes(s.getText());
146069
146217
  if (ts.isConditionalExpression(s))
146070
146218
  return emitCondExp(s);
146219
+ if (ts.isAsExpression(s) && isDecompilableAsExpression(s))
146220
+ return emitExp(s.expression);
146071
146221
  // TODO handle more expressions
146072
146222
  pxt.tickEvent("depython.todo.expression", { kind: s.kind });
146073
146223
  // return asExpRes(s.getText(), ["# unknown expression: " + s.kind]) // uncomment for easier locating
@@ -156136,6 +156286,9 @@ class FileGithubDb {
156136
156286
  return p;
156137
156287
  });
156138
156288
  }
156289
+ latestVersionAsync(repopath, config) {
156290
+ return this.db.latestVersionAsync(repopath, config);
156291
+ }
156139
156292
  loadConfigAsync(repopath, tag) {
156140
156293
  return this.loadAsync(repopath, tag, "pxt", (r, t) => this.db.loadConfigAsync(r, t));
156141
156294
  }
@@ -156152,46 +156305,6 @@ function searchAsync(...query) {
156152
156305
  }
156153
156306
  });
156154
156307
  }
156155
- function pkginfoAsync(repopath) {
156156
- let parsed = pxt.github.parseRepoId(repopath);
156157
- if (!parsed) {
156158
- console.log('Unknown repo');
156159
- return Promise.resolve();
156160
- }
156161
- const pkgInfo = (cfg, tag) => {
156162
- pxt.log(`name: ${cfg.name}`);
156163
- pxt.log(`description: ${cfg.description}`);
156164
- if (pxt.appTarget.appTheme)
156165
- pxt.log(`shareable url: ${pxt.appTarget.appTheme.embedUrl}#pub:gh/${parsed.fullName}${tag ? "#" + tag : ""}`);
156166
- };
156167
- return pxt.packagesConfigAsync()
156168
- .then(config => {
156169
- const status = pxt.github.repoStatus(parsed, config);
156170
- pxt.log(`github org: ${parsed.owner}`);
156171
- if (parsed.tag)
156172
- pxt.log(`github tag: ${parsed.tag}`);
156173
- pxt.log(`package status: ${status == pxt.github.GitRepoStatus.Approved ? "approved" : status == pxt.github.GitRepoStatus.Banned ? "banned" : "neutral"}`);
156174
- if (parsed.tag)
156175
- return pxt.github.downloadPackageAsync(repopath, config)
156176
- .then(pkg => {
156177
- let cfg = JSON.parse(pkg.files[pxt.CONFIG_NAME]);
156178
- pkgInfo(cfg, parsed.tag);
156179
- pxt.debug(`size: ${JSON.stringify(pkg.files).length}`);
156180
- });
156181
- return pxt.github.pkgConfigAsync(parsed.fullName)
156182
- .then(cfg => {
156183
- pkgInfo(cfg);
156184
- return pxt.github.listRefsAsync(repopath)
156185
- .then(tags => {
156186
- pxt.log("tags: " + tags.join(", "));
156187
- return pxt.github.listRefsAsync(repopath, "heads");
156188
- })
156189
- .then(heads => {
156190
- pxt.log("branches: " + heads.join(", "));
156191
- });
156192
- });
156193
- });
156194
- }
156195
156308
  function pokeRepoAsync(parsed) {
156196
156309
  const repo = parsed.args[0];
156197
156310
  let data = {
@@ -156292,7 +156405,8 @@ function pxtFileList(pref) {
156292
156405
  .concat(onlyExts(nodeutil.allFiles(pref + "built/web", 1), [".js", ".css"]))
156293
156406
  .concat(nodeutil.allFiles(pref + "built/web/fonts", 1))
156294
156407
  .concat(nodeutil.allFiles(pref + "built/web/vs", 4))
156295
- .concat(nodeutil.allFiles(pref + "built/web/skillmap", 4));
156408
+ .concat(nodeutil.allFiles(pref + "built/web/skillmap", 4))
156409
+ .concat(nodeutil.allFiles(pref + "built/web/authcode", 4));
156296
156410
  }
156297
156411
  function semverCmp(a, b) {
156298
156412
  let parse = (s) => {
@@ -156372,7 +156486,8 @@ function ciAsync() {
156372
156486
  p = p
156373
156487
  .then(() => buildWebStringsAsync())
156374
156488
  .then(() => crowdin.execCrowdinAsync("upload", "built/webstrings.json"))
156375
- .then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"));
156489
+ .then(() => crowdin.execCrowdinAsync("upload", "built/skillmap-strings.json"))
156490
+ .then(() => crowdin.execCrowdinAsync("upload", "built/authcode-strings.json"));
156376
156491
  if (uploadApiStrings)
156377
156492
  p = p.then(() => crowdin.execCrowdinAsync("upload", "built/strings.json"));
156378
156493
  if (uploadDocs || uploadApiStrings)
@@ -156890,6 +157005,7 @@ function uploadCoreAsync(opts) {
156890
157005
  "multiUrl": opts.localDir + "multi.html",
156891
157006
  "asseteditorUrl": opts.localDir + "asseteditor.html",
156892
157007
  "skillmapUrl": opts.localDir + "skillmap.html",
157008
+ "authcodeUrl": opts.localDir + "authcode.html",
156893
157009
  "isStatic": true,
156894
157010
  };
156895
157011
  const targetImagePaths = targetImages.map(k => `${opts.localDir}${path.join('./docs', logos[k])}`);
@@ -156935,13 +157051,15 @@ function uploadCoreAsync(opts) {
156935
157051
  "workerConfig.js",
156936
157052
  "multi.html",
156937
157053
  "asseteditor.html",
156938
- "skillmap.html"
157054
+ "skillmap.html",
157055
+ "authcode.html"
156939
157056
  ];
156940
157057
  // expandHtml is manually called on these files before upload
156941
157058
  // runs <!-- @include --> substitutions, fills in locale, etc
156942
157059
  let expandFiles = [
156943
157060
  "index.html",
156944
- "skillmap.html"
157061
+ "skillmap.html",
157062
+ "authcode.html"
156945
157063
  ];
156946
157064
  nodeutil.mkdirP("built/uploadrepl");
156947
157065
  function encodeURLs(urls) {
@@ -157735,7 +157853,7 @@ async function buildSemanticUIAsync(parsed) {
157735
157853
  ]
157736
157854
  });
157737
157855
  }
157738
- // Generate react-common css for skillmap
157856
+ // Generate react-common css for skillmap and authcode
157739
157857
  const skillmapFile = isPxtCore ? "react-common/styles/react-common-skillmap-core.less" :
157740
157858
  "node_modules/pxt-core/react-common/styles/react-common-skillmap.less";
157741
157859
  await nodeutil.spawnAsync({
@@ -157747,6 +157865,17 @@ async function buildSemanticUIAsync(parsed) {
157747
157865
  "--include-path=" + lessIncludePaths
157748
157866
  ]
157749
157867
  });
157868
+ const authcodeFile = isPxtCore ? "react-common/styles/react-common-authcode-core.less" :
157869
+ "node_modules/pxt-core/react-common/styles/react-common-authcode.less";
157870
+ await nodeutil.spawnAsync({
157871
+ cmd: "node",
157872
+ args: [
157873
+ lessCPath,
157874
+ authcodeFile,
157875
+ "built/web/react-common-authcode.css",
157876
+ "--include-path=" + lessIncludePaths
157877
+ ]
157878
+ });
157750
157879
  let skillmapCss = await readFileAsync(`built/web/react-common-skillmap.css`, "utf8");
157751
157880
  skillmapCss = await linkFontAsync("fa-solid-900", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
157752
157881
  skillmapCss = await linkFontAsync("fa-regular-400", skillmapCss, fontAwesomeSource, "\\.\\.\\/webfonts\\/");
@@ -157840,6 +157969,31 @@ function buildSkillMapAsync(parsed) {
157840
157969
  });
157841
157970
  });
157842
157971
  }
157972
+ function buildAuthcodeAsync(parsed) {
157973
+ // local serve
157974
+ const appRoot = "node_modules/pxt-core/authcode";
157975
+ return rimrafAsync(`${appRoot}/public/blb`, {})
157976
+ .then(() => rimrafAsync(`${appRoot}/build/assets`, {}))
157977
+ .then(() => rimrafAsync(`${appRoot}/public/docs`, {}))
157978
+ .then(() => rimrafAsync(`${appRoot}/public/static`, {}))
157979
+ .then(() => {
157980
+ // read pxtarget.json, save into 'pxtTargetBundle' global variable
157981
+ let cfg = readLocalPxTarget();
157982
+ nodeutil.writeFileSync(`${appRoot}/public/blb/target.js`, "// eslint-disable-next-line \n" + targetJsPrefix + JSON.stringify(cfg));
157983
+ nodeutil.cp("node_modules/pxt-core/built/pxtlib.js", `${appRoot}/public/blb`);
157984
+ nodeutil.cp("built/web/semantic.css", `${appRoot}/public/blb`);
157985
+ nodeutil.cp("node_modules/pxt-core/built/web/icons.css", `${appRoot}/public/blb`);
157986
+ nodeutil.cp("node_modules/pxt-core/built/web/react-common-authcode.css", `${appRoot}/public/blb`);
157987
+ // copy 'assets' over from docs/static
157988
+ nodeutil.cpR("docs/static/authcode/assets", `${appRoot}/public/assets`);
157989
+ return nodeutil.spawnAsync({
157990
+ cmd: os.platform() === "win32" ? "npm.cmd" : "npm",
157991
+ args: ["run-script", "start"],
157992
+ cwd: appRoot,
157993
+ shell: true
157994
+ });
157995
+ });
157996
+ }
157843
157997
  function updateDefaultProjects(cfg) {
157844
157998
  let defaultProjects = [
157845
157999
  pxt.BLOCKS_PROJECT_NAME,
@@ -158742,7 +158896,7 @@ function installPackageNameAsync(packageName) {
158742
158896
  return pxt.packagesConfigAsync()
158743
158897
  .then(config => (parsed.tag ? Promise.resolve(parsed.tag) : pxt.github.latestVersionAsync(parsed.slug, config))
158744
158898
  .then(tag => { parsed.tag = tag; })
158745
- .then(() => pxt.github.pkgConfigAsync(parsed.fullName, parsed.tag))
158899
+ .then(() => pxt.github.pkgConfigAsync(parsed.fullName, parsed.tag, config))
158746
158900
  .then(cfg => mainPkg.loadAsync(true)
158747
158901
  .then(() => {
158748
158902
  let ver = pxt.github.stringifyRepo(parsed);
@@ -162202,6 +162356,17 @@ ${pxt.crowdin.KEY_VARIABLE} - crowdin key
162202
162356
  }
162203
162357
  }
162204
162358
  }, buildSkillMapAsync);
162359
+ p.defineCommand({
162360
+ name: "buildauthcode",
162361
+ aliases: ["authcode"],
162362
+ advanced: true,
162363
+ help: "Serves the authcode webapp",
162364
+ flags: {
162365
+ serve: {
162366
+ description: "Serve the authcode app locally after building (npm start)"
162367
+ }
162368
+ }
162369
+ }, buildAuthcodeAsync);
162205
162370
  advancedCommand("augmentdocs", "test markdown docs replacements", augmnetDocsAsync, "<temlate.md> <doc.md>");
162206
162371
  advancedCommand("crowdin", "upload, download, clean, stats files to/from crowdin", pc => crowdin.execCrowdinAsync.apply(undefined, pc.args), "<cmd> <path> [output]");
162207
162372
  advancedCommand("hidlist", "list HID devices", hid.listAsync);