pxt-core 8.0.5 → 8.1.3

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.
package/built/pxt.js CHANGED
@@ -106384,13 +106384,20 @@ var pxt;
106384
106384
  docs.prepTemplate = prepTemplate;
106385
106385
  function setupRenderer(renderer) {
106386
106386
  renderer.image = function (href, title, text) {
106387
- let out = '<img class="ui image" src="' + href + '" alt="' + text + '"';
106388
- if (title) {
106389
- out += ' title="' + title + '"';
106387
+ if (href.startsWith("youtube:")) {
106388
+ let out = '<div class="tutorial-video-embed"><iframe src="https://www.youtube.com/embed/' + href.split(":").pop()
106389
+ + '" title="' + title + '" frameborder="0" ' + 'allowFullScreen ' + 'allow="autoplay; picture-in-picture"></iframe></div>';
106390
+ return out;
106391
+ }
106392
+ else {
106393
+ let out = '<img class="ui image" src="' + href + '" alt="' + text + '"';
106394
+ if (title) {
106395
+ out += ' title="' + title + '"';
106396
+ }
106397
+ out += ' loading="lazy"';
106398
+ out += this.options.xhtml ? '/>' : '>';
106399
+ return out;
106390
106400
  }
106391
- out += ' loading="lazy"';
106392
- out += this.options.xhtml ? '/>' : '>';
106393
- return out;
106394
106401
  };
106395
106402
  renderer.listitem = function (text) {
106396
106403
  const m = /^\s*\[( |x)\]/i.exec(text);
@@ -115688,7 +115695,7 @@ var pxt;
115688
115695
  id,
115689
115696
  type: "tilemap" /* Tilemap */,
115690
115697
  meta: {
115691
- displayName: id
115698
+ displayName: name || id
115692
115699
  },
115693
115700
  data: data
115694
115701
  });
@@ -125956,6 +125963,101 @@ ${output}</xml>`;
125956
125963
  }
125957
125964
  return undefined;
125958
125965
  }
125966
+ /**
125967
+ * We split up comments according to the following rules:
125968
+ * 1. If the comment is not top-level:
125969
+ * a. Combine it with all comments for the following statement
125970
+ * b. If there is no following statement in the current block, group it with the previous statement
125971
+ * c. If there are no statements inside the block, group it with the parent block
125972
+ * d. If trailing the same line as the statement, group it with the comments for that statement
125973
+ * 2. If the comment is top-level:
125974
+ * b. If the comment is followed by an empty line, it becomes a workspace comment
125975
+ * c. If the comment is followed by a multi-line comment, it becomes a workspace comment
125976
+ * a. If the comment is a single-line comment, combine it with the next single-line comment
125977
+ * d. If the comment is not followed with an empty line, group it with the next statement or event
125978
+ * e. All other comments are workspace comments
125979
+ *
125980
+ * The below function gathers any comments associated to the Node, and attaches them
125981
+ * to the StatementNode.
125982
+ */
125983
+ function getNodeComments(commented, stmt) {
125984
+ let comments = [];
125985
+ let current;
125986
+ for (let i = 0; i < commentMap.length; i++) {
125987
+ current = commentMap[i];
125988
+ if (!current.owner && current.start >= commented.pos && current.end <= commented.end) {
125989
+ current.owner = commented;
125990
+ current.ownerStatement = stmt;
125991
+ comments.push(current);
125992
+ }
125993
+ if (current.start > commented.end)
125994
+ break;
125995
+ }
125996
+ if (current && current.isTrailingComment) {
125997
+ const endLine = ts.getLineAndCharacterOfPosition(file, commented.end);
125998
+ const commentLine = ts.getLineAndCharacterOfPosition(file, current.start);
125999
+ if (endLine.line === commentLine.line) {
126000
+ // If the comment is trailing and on the same line as the statement, it probably belongs
126001
+ // to this statement. Remove it from any statement it's already assigned to and any workspace
126002
+ // comments
126003
+ if (current.ownerStatement) {
126004
+ current.ownerStatement.comment.splice(current.ownerStatement.comment.indexOf(current), 1);
126005
+ for (const wsComment of workspaceComments) {
126006
+ wsComment.comment.splice(wsComment.comment.indexOf(current), 1);
126007
+ }
126008
+ }
126009
+ current.owner = commented;
126010
+ current.ownerStatement = stmt;
126011
+ comments.push(current);
126012
+ }
126013
+ }
126014
+ if (comments.length) {
126015
+ const wsCommentRefs = [];
126016
+ if (isTopLevelComment(commented)) {
126017
+ let currentWorkspaceComment = [];
126018
+ const localWorkspaceComments = [];
126019
+ comments.forEach((comment, index) => {
126020
+ let beforeStatement = comment.owner && comment.start < comment.owner.getStart();
126021
+ if (comment.kind === CommentKind.MultiLine && beforeStatement) {
126022
+ if (currentWorkspaceComment.length) {
126023
+ localWorkspaceComments.push(currentWorkspaceComment);
126024
+ currentWorkspaceComment = [];
126025
+ }
126026
+ if (index != comments.length - 1) {
126027
+ localWorkspaceComments.push([comment]);
126028
+ return;
126029
+ }
126030
+ }
126031
+ currentWorkspaceComment.push(comment);
126032
+ if (comment.followedByEmptyLine && beforeStatement) {
126033
+ localWorkspaceComments.push(currentWorkspaceComment);
126034
+ currentWorkspaceComment = [];
126035
+ }
126036
+ });
126037
+ comments = currentWorkspaceComment;
126038
+ localWorkspaceComments.forEach(comment => {
126039
+ const refId = getCommentRef();
126040
+ wsCommentRefs.push(refId);
126041
+ workspaceComments.push({ comment, refId });
126042
+ });
126043
+ }
126044
+ // Attach comments to StatementNode
126045
+ if (stmt) {
126046
+ if (wsCommentRefs.length) {
126047
+ if (stmt.data)
126048
+ stmt.data += ";" + wsCommentRefs.join(";");
126049
+ else
126050
+ stmt.data = wsCommentRefs.join(";");
126051
+ }
126052
+ if (comments && comments.length) {
126053
+ if (stmt.comment)
126054
+ stmt.comment = stmt.comment.concat(comments);
126055
+ else
126056
+ stmt.comment = comments;
126057
+ }
126058
+ }
126059
+ }
126060
+ }
125959
126061
  function getStatementBlock(n, next, parent, asExpression = false, topLevel = false) {
125960
126062
  const node = n;
125961
126063
  let stmt;
@@ -126058,7 +126160,7 @@ ${output}</xml>`;
126058
126160
  }
126059
126161
  }
126060
126162
  if (!skipComments) {
126061
- getComments(parent || node);
126163
+ getNodeComments(parent || node, stmt);
126062
126164
  }
126063
126165
  return stmt;
126064
126166
  function getNext() {
@@ -126067,97 +126169,6 @@ ${output}</xml>`;
126067
126169
  }
126068
126170
  return undefined;
126069
126171
  }
126070
- /**
126071
- * We split up comments according to the following rules:
126072
- * 1. If the comment is not top-level:
126073
- * a. Combine it with all comments for the following statement
126074
- * b. If there is no following statement in the current block, group it with the previous statement
126075
- * c. If there are no statements inside the block, group it with the parent block
126076
- * d. If trailing the same line as the statement, group it with the comments for that statement
126077
- * 2. If the comment is top-level:
126078
- * b. If the comment is followed by an empty line, it becomes a workspace comment
126079
- * c. If the comment is followed by a multi-line comment, it becomes a workspace comment
126080
- * a. If the comment is a single-line comment, combine it with the next single-line comment
126081
- * d. If the comment is not followed with an empty line, group it with the next statement or event
126082
- * e. All other comments are workspace comments
126083
- */
126084
- function getComments(commented) {
126085
- let comments = [];
126086
- let current;
126087
- for (let i = 0; i < commentMap.length; i++) {
126088
- current = commentMap[i];
126089
- if (!current.owner && current.start >= commented.pos && current.end <= commented.end) {
126090
- current.owner = commented;
126091
- current.ownerStatement = stmt;
126092
- comments.push(current);
126093
- }
126094
- if (current.start > commented.end)
126095
- break;
126096
- }
126097
- if (current && current.isTrailingComment) {
126098
- const endLine = ts.getLineAndCharacterOfPosition(file, commented.end);
126099
- const commentLine = ts.getLineAndCharacterOfPosition(file, current.start);
126100
- if (endLine.line === commentLine.line) {
126101
- // If the comment is trailing and on the same line as the statement, it probably belongs
126102
- // to this statement. Remove it from any statement it's already assigned to and any workspace
126103
- // comments
126104
- if (current.ownerStatement) {
126105
- current.ownerStatement.comment.splice(current.ownerStatement.comment.indexOf(current), 1);
126106
- for (const wsComment of workspaceComments) {
126107
- wsComment.comment.splice(wsComment.comment.indexOf(current), 1);
126108
- }
126109
- }
126110
- current.owner = commented;
126111
- current.ownerStatement = stmt;
126112
- comments.push(current);
126113
- }
126114
- }
126115
- if (comments.length) {
126116
- const wsCommentRefs = [];
126117
- if (isTopLevelComment(commented)) {
126118
- let currentWorkspaceComment = [];
126119
- const localWorkspaceComments = [];
126120
- comments.forEach((comment, index) => {
126121
- let beforeStatement = comment.owner && comment.start < comment.owner.getStart();
126122
- if (comment.kind === CommentKind.MultiLine && beforeStatement) {
126123
- if (currentWorkspaceComment.length) {
126124
- localWorkspaceComments.push(currentWorkspaceComment);
126125
- currentWorkspaceComment = [];
126126
- }
126127
- if (index != comments.length - 1) {
126128
- localWorkspaceComments.push([comment]);
126129
- return;
126130
- }
126131
- }
126132
- currentWorkspaceComment.push(comment);
126133
- if (comment.followedByEmptyLine && beforeStatement) {
126134
- localWorkspaceComments.push(currentWorkspaceComment);
126135
- currentWorkspaceComment = [];
126136
- }
126137
- });
126138
- comments = currentWorkspaceComment;
126139
- localWorkspaceComments.forEach(comment => {
126140
- const refId = getCommentRef();
126141
- wsCommentRefs.push(refId);
126142
- workspaceComments.push({ comment, refId });
126143
- });
126144
- }
126145
- if (stmt) {
126146
- if (wsCommentRefs.length) {
126147
- if (stmt.data)
126148
- stmt.data += ";" + wsCommentRefs.join(";");
126149
- else
126150
- stmt.data = wsCommentRefs.join(";");
126151
- }
126152
- if (comments && comments.length) {
126153
- if (stmt.comment)
126154
- stmt.comment = stmt.comment.concat(comments);
126155
- else
126156
- stmt.comment = comments;
126157
- }
126158
- }
126159
- }
126160
- }
126161
126172
  }
126162
126173
  function getTypeScriptStatementBlock(node, prefix, err) {
126163
126174
  if (options.errorOnGreyBlocks)
@@ -126927,12 +126938,13 @@ ${output}</xml>`;
126927
126938
  eventStatements.map(n => getStatementBlock(n, undefined, undefined, false, topLevel)).forEach(emitStatementNode);
126928
126939
  if (blockStatements.length) {
126929
126940
  // wrap statement in "on start" if top level
126930
- const stmtNode = blockStatements.shift();
126931
- const stmt = getStatementBlock(stmtNode, blockStatements, parent, false, topLevel);
126941
+ const blockNode = blockStatements.shift();
126942
+ const stmt = getStatementBlock(blockNode, blockStatements, parent, false, topLevel);
126932
126943
  if (emitOnStart) {
126933
126944
  // Preserve any variable edeclarations that were never used
126934
- let current = stmt;
126935
- let currentNode = stmtNode;
126945
+ // stmt and blockNode will not yet align if there was an auto-declared variable.
126946
+ let currentStmtNode = stmt;
126947
+ let currentBlockNode = blockNode;
126936
126948
  autoDeclarations.forEach(([name, node]) => {
126937
126949
  if (varUsages[name] === ReferenceType.InBlocksOnly) {
126938
126950
  return;
@@ -126946,17 +126958,21 @@ ${output}</xml>`;
126946
126958
  v = getTypeScriptStatementBlock(node, "let ");
126947
126959
  }
126948
126960
  else {
126949
- v = getVariableSetOrChangeBlock(stmtNode, node.name, node.initializer, false, true);
126961
+ v = getVariableSetOrChangeBlock(blockNode, node.name, node.initializer, false, true);
126950
126962
  }
126951
- v.next = current;
126952
- current = v;
126953
- currentNode = node;
126963
+ // Auto-declared variables were not previously inserted into the stmt linked-list.
126964
+ // Insert auto-declared 'v' as the currentStmtNode.
126965
+ v.next = currentStmtNode;
126966
+ currentStmtNode = v;
126967
+ currentBlockNode = node;
126968
+ // Attach to currentStmtNode any associated comments
126969
+ getNodeComments(currentBlockNode.parent, currentStmtNode);
126954
126970
  });
126955
- if (current) {
126956
- const r = mkStmt(ts.pxtc.ON_START_TYPE, currentNode);
126971
+ if (currentStmtNode) {
126972
+ const r = mkStmt(ts.pxtc.ON_START_TYPE, currentBlockNode);
126957
126973
  r.handlers = [{
126958
126974
  name: "HANDLER",
126959
- statement: current
126975
+ statement: currentStmtNode
126960
126976
  }];
126961
126977
  return r;
126962
126978
  }
@@ -139471,6 +139487,7 @@ var ts;
139471
139487
  let snippet;
139472
139488
  if (preDefinedSnippet) {
139473
139489
  snippet = [preDefinedSnippet];
139490
+ snippetPrefix = undefined;
139474
139491
  }
139475
139492
  else {
139476
139493
  snippet = [fnName];
@@ -153172,6 +153189,7 @@ var pxsim;
153172
153189
  }
153173
153190
  }
153174
153191
  createFrame(url) {
153192
+ var _a;
153175
153193
  const wrapper = document.createElement("div");
153176
153194
  wrapper.className = `simframe ui embed`;
153177
153195
  const frame = document.createElement('iframe');
@@ -153186,6 +153204,8 @@ var pxsim;
153186
153204
  frame.frameBorder = "0";
153187
153205
  frame.dataset['runid'] = this.runId;
153188
153206
  frame.dataset['origin'] = new URL(furl).origin || "*";
153207
+ if ((_a = this._runOptions) === null || _a === void 0 ? void 0 : _a.autofocus)
153208
+ frame.setAttribute("autofocus", "true");
153189
153209
  wrapper.appendChild(frame);
153190
153210
  const i = document.createElement("i");
153191
153211
  i.className = "videoplay xicon icon";
@@ -153439,11 +153459,14 @@ var pxsim;
153439
153459
  return true;
153440
153460
  }
153441
153461
  handleMessage(msg, source) {
153462
+ var _a;
153442
153463
  switch (msg.type || '') {
153443
153464
  case 'ready': {
153444
153465
  const frameid = msg.frameid;
153445
153466
  const frame = document.getElementById(frameid);
153446
153467
  if (frame) {
153468
+ if ((_a = this._runOptions) === null || _a === void 0 ? void 0 : _a.autofocus)
153469
+ frame.focus();
153447
153470
  this.startFrame(frame);
153448
153471
  if (this.options.revealElement)
153449
153472
  this.options.revealElement(frame);
@@ -157709,11 +157732,11 @@ function onlyExts(files, exts) {
157709
157732
  }
157710
157733
  function pxtFileList(pref) {
157711
157734
  return nodeutil.allFiles(pref + "webapp/public")
157712
- .concat(onlyExts(nodeutil.allFiles(pref + "built/web", 1), [".js", ".css"]))
157713
- .concat(nodeutil.allFiles(pref + "built/web/fonts", 1))
157714
- .concat(nodeutil.allFiles(pref + "built/web/vs", 4))
157715
- .concat(nodeutil.allFiles(pref + "built/web/skillmap", 4))
157716
- .concat(nodeutil.allFiles(pref + "built/web/authcode", 4));
157735
+ .concat(onlyExts(nodeutil.allFiles(pref + "built/web", { maxDepth: 1 }), [".js", ".css"]))
157736
+ .concat(nodeutil.allFiles(pref + "built/web/fonts", { maxDepth: 1 }))
157737
+ .concat(nodeutil.allFiles(pref + "built/web/vs", { maxDepth: 4 }))
157738
+ .concat(nodeutil.allFiles(pref + "built/web/skillmap", { maxDepth: 4 }))
157739
+ .concat(nodeutil.allFiles(pref + "built/web/authcode", { maxDepth: 4 }));
157717
157740
  }
157718
157741
  function semverCmp(a, b) {
157719
157742
  let parse = (s) => {
@@ -158025,7 +158048,7 @@ function targetFileList() {
158025
158048
  let lst = onlyExts(nodeutil.allFiles("built"), [".js", ".css", ".json", ".webmanifest"])
158026
158049
  .concat(nodeutil.allFiles(path.join(simDir(), "public")));
158027
158050
  if (simDir() != "sim")
158028
- lst = lst.concat(nodeutil.allFiles(path.join("sim", "public"), 5, true));
158051
+ lst = lst.concat(nodeutil.allFiles(path.join("sim", "public"), { maxDepth: 5, allowMissing: true }));
158029
158052
  pxt.debug(`target files (on disk): ${lst.join('\r\n ')}`);
158030
158053
  return lst;
158031
158054
  }
@@ -158540,7 +158563,7 @@ function forEachBundledPkgAsync(f, includeProjects = false) {
158540
158563
  let prev = process.cwd();
158541
158564
  let folders = pxt.appTarget.bundleddirs;
158542
158565
  if (includeProjects) {
158543
- let projects = nodeutil.allFiles("libs", 1, /*allowMissing*/ false, /*includeDirs*/ true).filter(f => /prj$/.test(f));
158566
+ let projects = nodeutil.allFiles("libs", { maxDepth: 1, includeDirs: true }).filter(f => /prj$/.test(f));
158544
158567
  folders = folders.concat(projects);
158545
158568
  }
158546
158569
  return U.promiseMapAllSeries(folders, (dirname) => {
@@ -158705,7 +158728,7 @@ function buildEditorExtensionAsync(dirname, optionName) {
158705
158728
  else
158706
158729
  p = buildFolderAsync(dirname, true, dirname);
158707
158730
  return p.then(() => {
158708
- const prepends = nodeutil.allFiles(path.join(dirname, "prepend"), 1, true)
158731
+ const prepends = nodeutil.allFiles(path.join(dirname, "prepend"), { maxDepth: 1, allowMissing: true })
158709
158732
  .filter(f => /\.js$/.test(f));
158710
158733
  if (prepends && prepends.length) {
158711
158734
  const editorjs = path.join("built", dirname + ".js");
@@ -159306,7 +159329,7 @@ function updateDefaultProjects(cfg) {
159306
159329
  pxt.BLOCKS_PROJECT_NAME,
159307
159330
  pxt.JAVASCRIPT_PROJECT_NAME
159308
159331
  ];
159309
- nodeutil.allFiles("libs", 1, /*allowMissing*/ false, /*includeDirs*/ true)
159332
+ nodeutil.allFiles("libs", { maxDepth: 1, includeDirs: true })
159310
159333
  .filter((f) => {
159311
159334
  return defaultProjects.indexOf(path.basename(f)) !== -1;
159312
159335
  })
@@ -159767,7 +159790,7 @@ function renderDocs(builtPackaged, localDir) {
159767
159790
  docFolders.push(...nodeutil.getBundledPackagesDocs());
159768
159791
  docFolders.push("docs");
159769
159792
  for (const docFolder of docFolders) {
159770
- for (const f of nodeutil.allFiles(docFolder, 8)) {
159793
+ for (const f of nodeutil.allFiles(docFolder, { maxDepth: 8 })) {
159771
159794
  pxt.log(`rendering ${f}`);
159772
159795
  const pathUnderDocs = f.slice(docFolder.length + 1);
159773
159796
  let outputFile = path.join(dst, "docs", pathUnderDocs);
@@ -161891,7 +161914,7 @@ function buildJResSpritesDirectoryAsync(dir) {
161891
161914
  return [(v >> 16) & 0xff, (v >> 8) & 0xff, (v >> 0) & 0xff];
161892
161915
  });
161893
161916
  let ts = `namespace ${metaInfo.star.namespace} {\n`;
161894
- for (let fn of nodeutil.allFiles(dir, 1)) {
161917
+ for (let fn of nodeutil.allFiles(dir, { maxDepth: 1 })) {
161895
161918
  fn = fn.replace(/\\/g, "/");
161896
161919
  let m = /(.*\/)(.*)\.png$/i.exec(fn);
161897
161920
  if (!m)
@@ -162466,6 +162489,12 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162466
162489
  const docsRoot = nodeutil.targetDir;
162467
162490
  const docsTemplate = server.expandDocFileTemplate("docs.html");
162468
162491
  pxt.log(`checking docs`);
162492
+ const ignoredFoldersKey = ".checkdocs-ignore";
162493
+ const ignoredFolders = nodeutil.allFiles("docs", { includeHiddenFiles: true })
162494
+ .filter(el => el.endsWith(ignoredFoldersKey))
162495
+ .map(el => path.dirname(path.join(el.substring(4))) + path.sep);
162496
+ if (ignoredFolders.length)
162497
+ pxt.log(`Ignoring folders [${ignoredFolders.join(", ")}]`);
162469
162498
  const noTOCs = [];
162470
162499
  const todo = [];
162471
162500
  let urls = {};
@@ -162474,12 +162503,12 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162474
162503
  // only check each snippet once.
162475
162504
  const existingSnippets = {};
162476
162505
  let snippets = [];
162477
- const maxFileSize = checkFileSize(nodeutil.allFiles("docs", 10, true, true, ".ignorelargefiles"));
162506
+ const maxFileSize = checkFileSize(nodeutil.allFiles("docs", { maxDepth: 10, allowMissing: true, includeDirs: true, ignoredFileMarker: ".ignorelargefiles" }));
162478
162507
  if (!pxt.appTarget.ignoreDocsErrors
162479
162508
  && maxFileSize > (pxt.appTarget.cloud.maxFileSize || (5000000)))
162480
162509
  U.userError(`files too big in docs folder`);
162481
162510
  // scan and fix image links
162482
- nodeutil.allFiles("docs")
162511
+ nodeutil.allFiles("docs", { ignoredFileMarker: ignoredFoldersKey })
162483
162512
  .filter(f => /\.md/.test(f))
162484
162513
  .forEach(f => {
162485
162514
  let md = fs.readFileSync(f, { encoding: "utf8" });
@@ -162534,6 +162563,9 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162534
162563
  urls[url] = isResource
162535
162564
  ? nodeutil.fileExistsSync(path.join(docsRoot, "docs", url))
162536
162565
  : nodeutil.resolveMd(docsRoot, url);
162566
+ const pathedUrl = path.join(url);
162567
+ if (ignoredFolders.some(el => pathedUrl.startsWith(el)))
162568
+ return;
162537
162569
  if (!isResource && urls[url])
162538
162570
  todo.push(url);
162539
162571
  }
@@ -162551,7 +162583,8 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162551
162583
  entry.subitems.forEach(checkTOCEntry);
162552
162584
  }
162553
162585
  // check over TOCs
162554
- nodeutil.allFiles("docs", 5).filter(f => /SUMMARY\.md$/.test(f))
162586
+ nodeutil.allFiles("docs", { maxDepth: 5, ignoredFileMarker: ignoredFoldersKey })
162587
+ .filter(f => /SUMMARY\.md$/.test(f))
162555
162588
  .forEach(summaryFile => {
162556
162589
  const summaryPath = path.join(path.dirname(summaryFile), 'SUMMARY').replace(/^docs[\/\\]/, '');
162557
162590
  pxt.log(`looking for ${summaryPath}`);
@@ -162589,7 +162622,8 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162589
162622
  if (targetDirs) {
162590
162623
  targetDirs.forEach(dir => {
162591
162624
  pxt.log(`looking for markdown files in ${dir}`);
162592
- nodeutil.allFiles(path.join("docs", dir), 3).filter(f => mdRegex.test(f))
162625
+ nodeutil.allFiles(path.join("docs", dir), { maxDepth: 3, ignoredFileMarker: ".checkdocs-ignore" })
162626
+ .filter(f => mdRegex.test(f))
162593
162627
  .forEach(md => {
162594
162628
  pushUrl(md.slice(5).replace(mdRegex, ""), true);
162595
162629
  });
@@ -162666,6 +162700,9 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162666
162700
  card.otherActions.forEach(a => { if (a.url)
162667
162701
  urls.push(a.url); });
162668
162702
  for (let url of urls) {
162703
+ const pathedUrl = path.join(url);
162704
+ if (ignoredFolders.some(el => pathedUrl.startsWith(el)))
162705
+ return;
162669
162706
  const tutorialMd = nodeutil.resolveMd(docsRoot, url);
162670
162707
  if (!tutorialMd) {
162671
162708
  pxt.log(`unable to resolve ${url}`);
@@ -162715,6 +162752,9 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162715
162752
  card.otherActions.forEach(a => { if (a.url)
162716
162753
  urls.push(a.url); });
162717
162754
  for (let url of urls) {
162755
+ const pathedUrl = path.join(url);
162756
+ if (ignoredFolders.some(el => pathedUrl.startsWith(el)))
162757
+ return;
162718
162758
  const exMd = nodeutil.resolveMd(docsRoot, url);
162719
162759
  if (!exMd) {
162720
162760
  pxt.log(`unable to resolve ${url}`);
@@ -162764,7 +162804,7 @@ function internalCheckDocsAsync(compileSnippets, re, fix, pycheck) {
162764
162804
  async function upgradeCardsAsync() {
162765
162805
  const docsRoot = nodeutil.targetDir;
162766
162806
  // markdowns with cards
162767
- const mds = nodeutil.allFiles(docsRoot, 10, false, false)
162807
+ const mds = nodeutil.allFiles(docsRoot, { maxDepth: 10 })
162768
162808
  .filter(fn => /\.md$/.test(fn))
162769
162809
  .map(fn => ({ filename: fn, content: nodeutil.readText(fn) }))
162770
162810
  .filter(f => /```codecard/.test(f.content));
@@ -162792,7 +162832,7 @@ function internalCacheUsedBlocksAsync() {
162792
162832
  if (targetDirs) {
162793
162833
  targetDirs.forEach(dir => {
162794
162834
  pxt.log(`looking for tutorial markdown in ${dir}`);
162795
- nodeutil.allFiles(path.join("docs", dir), 3).filter(f => mdRegex.test(f))
162835
+ nodeutil.allFiles(path.join("docs", dir), { maxDepth: 3 }).filter(f => mdRegex.test(f))
162796
162836
  .forEach(md => {
162797
162837
  mdPaths.push(md.slice(5).replace(mdRegex, ""));
162798
162838
  });
@@ -162971,7 +163011,7 @@ function webstringsJson() {
162971
163011
  }
162972
163012
  function extractLocStringsAsync(output, dirs) {
162973
163013
  let prereqs = [];
162974
- dirs.forEach(dir => prereqs = prereqs.concat(nodeutil.allFiles(dir, 20)));
163014
+ dirs.forEach(dir => prereqs = prereqs.concat(nodeutil.allFiles(dir, { maxDepth: 20 })));
162975
163015
  let errCnt = 0;
162976
163016
  let translationStrings = {};
162977
163017
  function processLf(filename) {