git-fish-log 1.0.7 → 1.0.9

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/dist/index.js CHANGED
@@ -201,63 +201,90 @@ function formatLocalDate(date) {
201
201
  const s = String(date.getSeconds()).padStart(2, "0");
202
202
  return `${Y}-${M}-${D} ${h}:${m}:${s}`;
203
203
  }
204
+ function cleanBranchRef(refName) {
205
+ if (!refName) return "unknown";
206
+ return refName.replace(/^refs\/heads\//, "").replace(/^refs\/remotes\/[^/]+\//, "").replace(/^HEAD -> /, "").replace(/^refs\//, "");
207
+ }
208
+ function shellQuote(value) {
209
+ return `"${value.replace(/(["\\$`])/g, "\\$1")}"`;
210
+ }
211
+ function getBranchRefs(projectPath) {
212
+ try {
213
+ const stdout = execSync('git for-each-ref --format="%(refname)" refs/heads refs/remotes', {
214
+ cwd: projectPath,
215
+ encoding: "utf8"
216
+ });
217
+ const seen = /* @__PURE__ */ new Set();
218
+ return stdout.replace(/\r/g, "").split("\n").map((ref) => ref.trim()).filter((ref) => ref && !/\/HEAD$/.test(ref)).map((ref) => ({ ref, name: cleanBranchRef(ref) })).filter(({ name }) => name && name !== "unknown").filter(({ name }) => {
219
+ if (seen.has(name)) return false;
220
+ seen.add(name);
221
+ return true;
222
+ });
223
+ } catch {
224
+ return [];
225
+ }
226
+ }
204
227
  function getCommitsForProject(projectPath, since, until) {
205
228
  const projectName = path2.basename(projectPath);
206
229
  const email = getUserEmail(projectPath);
207
230
  const sinceStr = formatLocalDate(since);
208
231
  const untilStr = formatLocalDate(until);
209
- let authorArg = "";
210
- if (email) {
211
- authorArg = `--author="${email.replace(/"/g, '\\"')}"`;
212
- }
232
+ const authorArg = email ? ` --author=${shellQuote(email)}` : "";
213
233
  const delimiter = "|||";
214
234
  const formatStr = `%aI${delimiter}%an${delimiter}%ae${delimiter}%h${delimiter}%s`;
215
- const cmd = `git log --all --since="${sinceStr}" --until="${untilStr}" ${authorArg} --pretty=format:"${formatStr}" --shortstat --date=iso-strict`;
216
- try {
217
- const stdout = execSync(cmd, {
218
- cwd: projectPath,
219
- maxBuffer: 20 * 1024 * 1024,
220
- // 20MB buffer for large repos
221
- encoding: "utf8"
222
- });
223
- if (!stdout.trim()) {
224
- return [];
225
- }
226
- const lines = stdout.split("\n").map((l) => l.trim());
227
- const results = [];
228
- let currentCommit = null;
229
- for (const line of lines) {
230
- if (line.length === 0) continue;
231
- if (line.includes(delimiter)) {
232
- if (currentCommit) {
233
- results.push(currentCommit);
235
+ const branchRefs = getBranchRefs(projectPath);
236
+ const refsToScan = branchRefs.length > 0 ? branchRefs : [{ ref: "--all", name: "unknown" }];
237
+ const results = [];
238
+ for (const branch of refsToScan) {
239
+ const refArg = branch.ref === "--all" ? "--all" : shellQuote(branch.ref);
240
+ const cmd = `git log ${refArg} --since=${shellQuote(sinceStr)} --until=${shellQuote(untilStr)}${authorArg} --pretty=format:${shellQuote(formatStr)} --shortstat --date=iso-strict`;
241
+ try {
242
+ const stdout = execSync(cmd, {
243
+ cwd: projectPath,
244
+ maxBuffer: 20 * 1024 * 1024,
245
+ // 20MB buffer for large repos
246
+ encoding: "utf8"
247
+ });
248
+ if (!stdout.trim()) {
249
+ continue;
250
+ }
251
+ const lines = stdout.replace(/\r/g, "").split("\n");
252
+ let currentCommit = null;
253
+ for (const line of lines) {
254
+ if (line.trim().length === 0) continue;
255
+ if (line.includes(delimiter)) {
256
+ if (currentCommit) {
257
+ results.push(currentCommit);
258
+ }
259
+ const parts = line.split(delimiter);
260
+ const [date, name, authorEmail, hash, ...msgParts] = parts;
261
+ const message = msgParts.join(delimiter);
262
+ currentCommit = {
263
+ project: projectName,
264
+ hash: hash || "",
265
+ date: date || "",
266
+ message: message || "",
267
+ authorName: name || "",
268
+ authorEmail: authorEmail || "",
269
+ additions: 0,
270
+ deletions: 0,
271
+ branch: branch.name,
272
+ branches: branch.name !== "unknown" ? [branch.name] : []
273
+ };
274
+ } else if (currentCommit) {
275
+ const insMatch = line.match(/(\d+)\s+insertions?\(\+\)/);
276
+ const delMatch = line.match(/(\d+)\s+deletions?\(-\)/);
277
+ currentCommit.additions = insMatch ? parseInt(insMatch[1], 10) : 0;
278
+ currentCommit.deletions = delMatch ? parseInt(delMatch[1], 10) : 0;
234
279
  }
235
- const parts = line.split(delimiter);
236
- const [date, name, authorEmail, hash, message] = parts;
237
- currentCommit = {
238
- project: projectName,
239
- hash: hash || "",
240
- date: date || "",
241
- message: message || "",
242
- authorName: name || "",
243
- authorEmail: authorEmail || "",
244
- additions: 0,
245
- deletions: 0
246
- };
247
- } else if (currentCommit) {
248
- const insMatch = line.match(/(\d+)\s+insertions?\(\+\)/);
249
- const delMatch = line.match(/(\d+)\s+deletions?\(-\)/);
250
- currentCommit.additions = insMatch ? parseInt(insMatch[1], 10) : 0;
251
- currentCommit.deletions = delMatch ? parseInt(delMatch[1], 10) : 0;
252
280
  }
281
+ if (currentCommit) {
282
+ results.push(currentCommit);
283
+ }
284
+ } catch {
253
285
  }
254
- if (currentCommit) {
255
- results.push(currentCommit);
256
- }
257
- return results;
258
- } catch (e) {
259
- return [];
260
286
  }
287
+ return results;
261
288
  }
262
289
  function getLocalGitIdentity() {
263
290
  const emails = [];
@@ -380,27 +407,45 @@ async function fetchGitLabCommits(since, until, source) {
380
407
  const untilStr = until.toISOString();
381
408
  const commitPromises = projects.map(async (project) => {
382
409
  try {
383
- const commitsUrl = `${cleanHost}/api/v4/projects/${project.id}/repository/commits?since=${sinceStr}&until=${untilStr}&per_page=100&all=true`;
384
- const commitsRes = await gitLabFetch(commitsUrl, { "PRIVATE-TOKEN": token });
385
- if (!commitsRes.ok) {
386
- return [];
387
- }
388
- const commits = await commitsRes.json();
389
410
  const localIdentity = getLocalGitIdentity();
390
- const userCommits = commits.filter((c) => {
411
+ const isUserCommit = (c) => {
391
412
  const authorEmail = c.author_email.toLowerCase();
392
413
  const authorName = c.author_name.toLowerCase();
393
414
  const matchesGitLab = authorEmail === lowerEmail || authorName === lowerName || authorName === lowerUsername;
394
415
  const matchesLocal = localIdentity.emails.includes(authorEmail) || localIdentity.names.includes(authorName);
395
416
  return matchesGitLab || matchesLocal;
396
- });
417
+ };
418
+ let branchNames = [];
419
+ try {
420
+ const branchesUrl = `${cleanHost}/api/v4/projects/${project.id}/repository/branches?per_page=100`;
421
+ const branchesRes = await gitLabFetch(branchesUrl, { "PRIVATE-TOKEN": token });
422
+ if (branchesRes.ok) {
423
+ const branches = await branchesRes.json();
424
+ branchNames = branches.map((b) => b.name).filter(Boolean);
425
+ }
426
+ } catch {
427
+ }
428
+ const branchCommitResults = branchNames.length > 0 ? await Promise.all(branchNames.map(async (branchName) => {
429
+ const commitsUrl = `${cleanHost}/api/v4/projects/${project.id}/repository/commits?ref_name=${encodeURIComponent(branchName)}&since=${sinceStr}&until=${untilStr}&per_page=100`;
430
+ const commitsRes = await gitLabFetch(commitsUrl, { "PRIVATE-TOKEN": token });
431
+ if (!commitsRes.ok) return [];
432
+ const commits = await commitsRes.json();
433
+ return commits.filter(isUserCommit).map((c) => ({ commit: c, branchName }));
434
+ })) : await (async () => {
435
+ const commitsUrl = `${cleanHost}/api/v4/projects/${project.id}/repository/commits?since=${sinceStr}&until=${untilStr}&per_page=100&all=true`;
436
+ const commitsRes = await gitLabFetch(commitsUrl, { "PRIVATE-TOKEN": token });
437
+ if (!commitsRes.ok) return [];
438
+ const commits = await commitsRes.json();
439
+ return [commits.filter(isUserCommit).map((c) => ({ commit: c, branchName: "gitlab" }))];
440
+ })();
441
+ const userCommits = branchCommitResults.flat();
397
442
  if (userCommits.length === 0) return [];
398
443
  const statsResults = [];
399
444
  const batchSize = 8;
400
445
  for (let i = 0; i < userCommits.length; i += batchSize) {
401
446
  const batch = userCommits.slice(i, i + batchSize);
402
447
  const batchResults = await Promise.all(
403
- batch.map(async (c) => {
448
+ batch.map(async ({ commit: c, branchName }) => {
404
449
  let adds = 0;
405
450
  let dels = 0;
406
451
  try {
@@ -423,7 +468,9 @@ async function fetchGitLabCommits(since, until, source) {
423
468
  authorName: c.author_name,
424
469
  authorEmail: c.author_email,
425
470
  additions: adds,
426
- deletions: dels
471
+ deletions: dels,
472
+ branch: branchName,
473
+ branches: [branchName]
427
474
  };
428
475
  })
429
476
  );
@@ -501,12 +548,14 @@ function calculateDayIndices(commits, isWeekend = false) {
501
548
  const N = commits.length;
502
549
  if (N === 0) {
503
550
  return {
504
- fish: 90,
505
- hardworking: 10,
551
+ fish: 95,
552
+ hardworking: 5,
506
553
  nightOwl: 0,
507
554
  builder: 0,
508
555
  burst: 0,
509
556
  density: 0,
557
+ codeVolume: 0,
558
+ totalLines: 0,
510
559
  tags: ["\u{1F41F} \u4ECA\u65E5\u6682\u65E0\u4EE3\u7801\u6D3B\u52A8"]
511
560
  };
512
561
  }
@@ -515,6 +564,7 @@ function calculateDayIndices(commits, isWeekend = false) {
515
564
  let totalAdditions = 0;
516
565
  let totalDeletions = 0;
517
566
  let nightCount = 0;
567
+ const hourSet = /* @__PURE__ */ new Set();
518
568
  for (const commit of commits) {
519
569
  const parsed = parseGitISODate(commit.date);
520
570
  const fh = parsed.hour + parsed.minute / 60 + parsed.second / 3600;
@@ -523,40 +573,44 @@ function calculateDayIndices(commits, isWeekend = false) {
523
573
  if (parsed.hour >= 0 && parsed.hour <= 5) nightCount++;
524
574
  totalAdditions += commit.additions;
525
575
  totalDeletions += commit.deletions;
576
+ hourSet.add(parsed.hour);
526
577
  }
527
578
  const S = Math.max(0.1, latest - earliest);
528
579
  const L = totalAdditions + totalDeletions;
529
- const avgLines = L / Math.max(N, 1);
530
- const D = N / (S + 1);
531
- const commitScore = Math.min(100, Math.log2(N + 1) * 18);
532
- const spanScore = Math.min(100, Math.sqrt(S) * 18);
533
- const lineScore = Math.min(100, Math.log2(L + 1) * 8);
534
- const densityScore = N <= 1 ? 0 : Math.min(100, D * 35);
535
- const nightScore = Math.min(100, nightCount * 30);
536
- let hardworking = commitScore * 0.3 + lineScore * 0.3 + densityScore * 0.2 + spanScore * 0.2;
580
+ const activeHours = hourSet.size;
581
+ let Neff = 0;
582
+ for (const commit of commits) {
583
+ const cl = commit.additions + commit.deletions;
584
+ if (cl >= 20) {
585
+ Neff++;
586
+ }
587
+ }
588
+ const commitScore = Math.min(100, Math.log2(Neff + 1) * 20);
589
+ const spanScore = Math.min(100, Math.sqrt(S) * 22);
590
+ const spreadScore = Math.min(100, activeHours * 12);
591
+ const lineBonus = Math.min(100, Math.log10(L + 1) * 25);
592
+ const nightBonus = nightCount > 0 ? 5 : 0;
593
+ let workScore = commitScore * 0.35 + spanScore * 0.3 + spreadScore * 0.2 + lineBonus * 0.1 + nightBonus;
537
594
  if (isWeekend && N > 0) {
538
- hardworking += 8;
595
+ workScore += 5;
539
596
  }
540
- hardworking = Math.min(100, Math.round(hardworking));
597
+ const hardworking = Math.min(100, Math.round(workScore));
541
598
  const fish = Math.max(1, 100 - hardworking);
542
- const nightOwl = nightCount === 0 ? 0 : Math.min(100, Math.round(
543
- nightScore * 0.7 + spanScore * 0.3
544
- ));
545
- const builder = Math.min(100, Math.round(
546
- lineScore * 0.7 + commitScore * 0.3
547
- ));
548
- const burst = Math.min(100, Math.round(
549
- Math.log2(avgLines + 1) * 12
550
- ));
599
+ const nightScore = Math.min(100, nightCount * 30);
600
+ const nightOwl = nightCount === 0 ? 0 : Math.min(100, Math.round(nightScore * 0.7 + spanScore * 0.3));
601
+ const builder = Math.min(100, Math.round(lineBonus * 0.6 + commitScore * 0.4));
602
+ const codeVolume = Math.min(100, Math.max(0, Math.round(51.3 * Math.log10(L + 50) - 79.5)));
603
+ const displayAvgLines = Math.round(L / Math.max(N, 1));
604
+ const burst = Math.min(100, Math.round(Math.log2(displayAvgLines + 1) * 12));
551
605
  const tags = [];
552
606
  if (fish >= 80) tags.push("\u{1F41F} \u6478\u9C7C\u5B97\u5E08");
553
607
  if (hardworking >= 80) tags.push("\u{1F525} \u7206\u809D\u6218\u795E");
554
608
  if (nightOwl >= 80) tags.push("\u{1F319} \u6DF1\u591C\u4FEE\u4ED9\u8005");
555
609
  if (builder >= 80) tags.push("\u{1F9F1} \u52E4\u6073\u642C\u7816\u4EBA");
556
- if (burst >= 80 && N <= 2) tags.push(`\u{1F4A5} \u4E00\u628A\u68AD\u54C8\u578B\u7A0B\u5E8F\u5458 (\u5747${Math.round(avgLines)}\u884C/\u6B21)`);
557
- if (commitScore >= 70 && lineScore <= 15) tags.push("\u{1F3F7}\uFE0F PPT \u67B6\u6784\u5E08");
610
+ if (burst >= 80 && N <= 2) tags.push(`\u{1F4A5} \u4E00\u628A\u68AD\u54C8\u578B\u7A0B\u5E8F\u5458 (\u5747${displayAvgLines}\u884C/\u6B21)`);
611
+ if (N >= 8 && Neff <= 1 && L <= 50) tags.push("\u{1F3F7}\uFE0F PPT \u67B6\u6784\u5E08");
558
612
  if (N >= 10 && L <= 30) tags.push("\u{1F3F7}\uFE0F \u683C\u5F0F\u5316\u5927\u5E08");
559
- if (N >= 15 && avgLines <= 2) tags.push("\u{1F3F7}\uFE0F Git \u804A\u5929\u8FBE\u4EBA");
613
+ if (N >= 15 && L / N <= 2) tags.push("\u{1F3F7}\uFE0F Git \u804A\u5929\u8FBE\u4EBA");
560
614
  if (nightOwl >= 80 && N <= 3) tags.push("\u{1F3F7}\uFE0F \u6DF1\u591C\u523A\u5BA2");
561
615
  if (hardworking >= 90 && nightOwl >= 70 && isWeekend) tags.push("\u{1F3F7}\uFE0F \u751F\u4EA7\u961F\u7684\u9A74");
562
616
  if (fish >= 95 && N <= 1) tags.push("\u{1F3F7}\uFE0F \u6478\u9C7C\u4ED9\u4EBA");
@@ -566,7 +620,9 @@ function calculateDayIndices(commits, isWeekend = false) {
566
620
  nightOwl,
567
621
  builder,
568
622
  burst,
569
- density: Math.round(Math.min(100, densityScore)),
623
+ density: Math.round(spreadScore),
624
+ codeVolume,
625
+ totalLines: L,
570
626
  tags
571
627
  };
572
628
  }
@@ -581,11 +637,23 @@ async function getAllCommits(projectPaths, since, until, source) {
581
637
  all = all.concat(gitlabCommits);
582
638
  } catch {
583
639
  }
584
- const seen = /* @__PURE__ */ new Set();
640
+ const seen = /* @__PURE__ */ new Map();
585
641
  const unique = [];
586
642
  for (const c of all) {
587
- if (!seen.has(c.hash)) {
588
- seen.add(c.hash);
643
+ const key = `${c.project}:${c.hash}`;
644
+ const branches = c.branches && c.branches.length > 0 ? c.branches : c.branch && c.branch !== "unknown" ? [c.branch] : [];
645
+ const existing = seen.get(key);
646
+ if (existing) {
647
+ const mergedBranches = /* @__PURE__ */ new Set([
648
+ ...existing.branches || (existing.branch && existing.branch !== "unknown" ? [existing.branch] : []),
649
+ ...branches
650
+ ]);
651
+ existing.branches = Array.from(mergedBranches);
652
+ existing.branch = existing.branches[0] || existing.branch;
653
+ } else {
654
+ c.branches = Array.from(new Set(branches));
655
+ c.branch = c.branches[0] || c.branch;
656
+ seen.set(key, c);
589
657
  unique.push(c);
590
658
  }
591
659
  }
@@ -605,6 +673,12 @@ async function analyzeWeekly(projectPaths, now = /* @__PURE__ */ new Date(), sou
605
673
  const dayCommits = commitsByDay[idx];
606
674
  const projects = Array.from(new Set(dayCommits.map((c) => c.project)));
607
675
  const indices = calculateDayIndices(dayCommits, idx >= 5);
676
+ const branches = new Set(
677
+ dayCommits.flatMap((c) => {
678
+ const commitBranches = c.branches && c.branches.length > 0 ? c.branches : c.branch && c.branch !== "unknown" ? [c.branch] : [];
679
+ return commitBranches.map((branch) => `${c.project}:${branch}`);
680
+ })
681
+ );
608
682
  return {
609
683
  dayName: name,
610
684
  commitsCount: dayCommits.length,
@@ -615,6 +689,9 @@ async function analyzeWeekly(projectPaths, now = /* @__PURE__ */ new Date(), sou
615
689
  builder: indices.builder,
616
690
  burst: indices.burst,
617
691
  density: indices.density,
692
+ codeVolume: indices.codeVolume,
693
+ totalLines: indices.totalLines,
694
+ branchCount: branches.size,
618
695
  tags: indices.tags
619
696
  };
620
697
  });
@@ -656,12 +733,14 @@ async function analyzeWeekly(projectPaths, now = /* @__PURE__ */ new Date(), sou
656
733
  const sumNightOwl = activeDays.reduce((acc, d) => acc + d.nightOwl, 0);
657
734
  const sumBuilder = activeDays.reduce((acc, d) => acc + d.builder, 0);
658
735
  const sumBurst = activeDays.reduce((acc, d) => acc + d.burst, 0);
736
+ const sumCodeVolume = activeDays.reduce((acc, d) => acc + d.codeVolume, 0);
659
737
  const activeCount = activeDays.length || 1;
660
738
  const averageFish = Math.round(sumFish / activeCount);
661
739
  const averageHardworking = Math.round(sumHardworking / activeCount);
662
740
  const averageNightOwl = Math.round(sumNightOwl / activeCount);
663
741
  const averageBuilder = Math.round(sumBuilder / activeCount);
664
742
  const averageBurst = Math.round(sumBurst / activeCount);
743
+ const averageCodeVolume = Math.round(sumCodeVolume / activeCount);
665
744
  return {
666
745
  days,
667
746
  totalCommits: commits.length,
@@ -673,6 +752,7 @@ async function analyzeWeekly(projectPaths, now = /* @__PURE__ */ new Date(), sou
673
752
  averageNightOwl,
674
753
  averageBuilder,
675
754
  averageBurst,
755
+ averageCodeVolume,
676
756
  ghostCommitsCount: ghostCount
677
757
  };
678
758
  }
@@ -706,6 +786,7 @@ async function analyzeMonthly(projectPaths, now = /* @__PURE__ */ new Date(), so
706
786
  let totalNightOwl = 0;
707
787
  let totalBuilder = 0;
708
788
  let totalBurst = 0;
789
+ let totalCodeVolume = 0;
709
790
  const dailyIndices = [];
710
791
  for (let d = 1; d <= maxDay; d++) {
711
792
  const dateStr = `${since.getFullYear()}-${since.getMonth() + 1}-${d}`;
@@ -716,6 +797,7 @@ async function analyzeMonthly(projectPaths, now = /* @__PURE__ */ new Date(), so
716
797
  totalNightOwl += indices.nightOwl;
717
798
  totalBuilder += indices.builder;
718
799
  totalBurst += indices.burst;
800
+ totalCodeVolume += indices.codeVolume;
719
801
  dailyIndices.push({
720
802
  day: d,
721
803
  commitsCount: dayCommits.length,
@@ -723,6 +805,8 @@ async function analyzeMonthly(projectPaths, now = /* @__PURE__ */ new Date(), so
723
805
  hardworking: indices.hardworking,
724
806
  nightOwl: indices.nightOwl,
725
807
  burst: indices.burst,
808
+ codeVolume: indices.codeVolume,
809
+ totalLines: indices.totalLines,
726
810
  tags: indices.tags
727
811
  });
728
812
  }
@@ -731,6 +815,7 @@ async function analyzeMonthly(projectPaths, now = /* @__PURE__ */ new Date(), so
731
815
  const averageNightOwl = Math.round(totalNightOwl / maxDay);
732
816
  const averageBuilder = Math.round(totalBuilder / maxDay);
733
817
  const averageBurst = Math.round(totalBurst / maxDay);
818
+ const averageCodeVolume = Math.round(totalCodeVolume / maxDay);
734
819
  return {
735
820
  totalCommits: commits.length,
736
821
  categories,
@@ -741,6 +826,7 @@ async function analyzeMonthly(projectPaths, now = /* @__PURE__ */ new Date(), so
741
826
  averageNightOwl,
742
827
  averageBuilder,
743
828
  averageBurst,
829
+ averageCodeVolume,
744
830
  dailyIndices
745
831
  };
746
832
  }
@@ -763,95 +849,116 @@ async function getGhostCommits(projectPaths, since, until, source) {
763
849
 
764
850
  // src/critic.ts
765
851
  var SLACK_HIGH_CRITIQUES = [
766
- "\u672C\u5468\u6478\u9C7C\u6307\u6570\u62C9\u6EE1\uFF01\u770B\u6765\u662F\u5728\u6DF1\u5EA6\u8D2F\u5F7B\u2018\u52B3\u9038\u7ED3\u5408\u2019\u7684\u6700\u9AD8\u751F\u4EA7\u529B\u539F\u5219\uFF0C\u8FDE\u4E0B\u5468\u4E2D\u5348\u5403\u4EC0\u4E48\u90FD\u89C4\u5212\u5F97\u4E95\u4E95\u6709\u6761\u3002",
767
- "\u4F60\u7684 Commit \u5217\u8868\u5E72\u51C0\u5F97\u50CF\u521A\u6D17\u8FC7\u7684\u8138\u3002\u84C4\u52BF\u5F85\u53D1\u4E5F\u662F\u4E00\u79CD\u8282\u594F\uFF0C\u671F\u5F85\u4F60\u4E0B\u5468\u79EF\u6512\u7684\u5927\u62DB\uFF01",
768
- "\u770B\u6765\u672C\u5468\u7684\u9879\u76EE\u8FDB\u5165\u4E86\u2018\u517B\u7CBE\u84C4\u9510\u2019\u9636\u6BB5\u2014\u2014\u624B\u673A\u592A\u597D\u73A9\uFF0C\u6216\u8005\u5E8A\u592A\u6696\u548C\u3002\u6478\u9C7C\u6280\u5DE7\u5DF2\u8FBE\u7089\u706B\u7EAF\u9752\u4E4B\u5883\u3002",
769
- "\u4F60\u7684\u63D0\u4EA4\u9891\u7387\u50CF\u6781\u4E86\u9000\u6F6E\u540E\u7684\u6C99\u6EE9\uFF0C\u6BEB\u65E0\u6CE2\u6F9C\u3002\u5EFA\u8BAE\u4E0B\u5468\u7A0D\u5FAE\u52A8\u52A8\u624B\u6307\uFF0C\u8BA9 Git \u56FE\u6807\u91CD\u65B0\u4EAE\u8D77\u6765\u3002",
770
- "\u8FD9\u63D0\u4EA4\u6B21\u6570\uFF0C\u4E24\u53EA\u624B\u90FD\u6570\u5F97\u8FC7\u6765\u3002\u770B\u6765\u662F\u5728\u8DF5\u884C\u2018\u4E0D\u5199\u4EE3\u7801\u5C31\u6CA1\u6709 bug\u2019\u7684\u81F3\u9AD8\u9632\u7EBF\uFF0C\u4E3B\u6253\u4E00\u4E2A\u7A33\u5B57\u5F53\u5934\u3002"
852
+ "\u672C\u5468\u6478\u9C7C\u6307\u6570\u62C9\u6EE1\uFF0C\u677E\u5F1B\u611F\u76F4\u63A5\u6EA2\u51FA\u5C4F\u5E55\u3002\u52B3\u9038\u7ED3\u5408\u8FD9\u5757\uFF0C\u4F60\u7B97\u662F\u73A9\u660E\u767D\u4E86\u3002",
853
+ "Commit \u5217\u8868\u6E05\u723D\u5F97\u50CF\u521A\u683C\u5F0F\u5316\u8FC7\u7684\u786C\u76D8\u3002",
854
+ "\u672C\u5468\u9879\u76EE\u8FDB\u5165\u4E86'\u517B\u7CBE\u84C4\u9510'\u7F13\u51B2\u9636\u6BB5\uFF0C\u6478\u9C7C\u6280\u5DE7\u5DF2\u81FB\u5316\u5883\u3002",
855
+ "\u63D0\u4EA4\u9891\u7387\u5E73\u7F13\u5982\u5FC3\u7535\u56FE\uFF0C\u7A33\u5B9A\uFF0C\u5C31\u662F\u6709\u70B9\u592A\u5E73\u4E86\u3002",
856
+ "\u63D0\u4EA4\u6B21\u6570\u4E24\u53EA\u624B\u6570\u5F97\u8FC7\u6765\u3002'\u4E0D\u5199\u4EE3\u7801\u5C31\u6CA1\u6709bug'\uFF01\u903B\u8F91\u81EA\u6D3D\uFF0C\u65E0\u6CD5\u53CD\u9A73\u3002",
857
+ "\u5C11\u91CF\u63D0\u4EA4\u641E\u5B9A\u5168\u90E8\u4EFB\u52A1\uFF0C\u9AD8\u6548\u6536\u5DE5\u540E\u5B89\u5FC3\u653E\u7A7A\u3002\u61C2\u4F11\u606F\u7684\u4EBA\uFF0C\u624D\u61C2\u957F\u4E45\u3002",
858
+ "Git\u9875\u9762\u4E00\u7247\u6E05\u51C0\uFF0C\u6CA1\u6709\u8FED\u4EE3\u75D5\u8FF9\uFF0C\u4E0D\u7528\u8FFD\u8D76\u8FDB\u5EA6\u7684\u4E00\u5468\uFF0C\u8212\u670D\u5F97\u8BA9\u4EBA\u5AC9\u5992\u3002"
771
859
  ];
772
860
  var SLACK_LOW_CRITIQUES = [
773
- "\u672C\u5468\u7206\u809D\u6307\u6570\u7206\u8868\uFF01\u770B\u5230\u4F60\u8FD9\u5BC6\u5BC6\u9EBB\u9EBB\u7684\u63D0\u4EA4\u8BB0\u5F55\uFF0C\u9694\u58C1\u6D4B\u8BD5\u5C0F\u59D0\u59D0\u7684\u773C\u5708\u7EA2\u4E86\uFF0C\u8FDE\u4F60\u7684\u952E\u76D8\u90FD\u5728\u4E3A\u4F60\u957F\u9E23\u3002",
774
- "\u4F60\u8FD9\u4E48\u62FC\u547D\u5DE5\u4F5C\uFF0C\u4EE3\u7801\u5E93\u7684\u534A\u58C1\u6C5F\u5C71\u90FD\u662F\u4F60\u6253\u4E0B\u6765\u7684\u3002\u4E0B\u5468\u5FC5\u987B\u5B89\u6392\u4E00\u676F\u5976\u8336\uFF0C\u597D\u597D\u7292\u52B3\u4E00\u4E0B\u81EA\u5DF1\uFF01",
775
- "\u5144\u5F1F\uFF0C\u4F60\u8FD9\u5468\u7684\u5DE5\u65F6\u76F4\u63A5\u62C9\u6EE1\u4E86\u3002\u5EFA\u8BAE\u7ED9\u81EA\u5DF1\u653E\u4E2A\u5047\uFF0C\u4EE3\u7801\u53EF\u4EE5\u660E\u5929\u5199\uFF0C\u8EAB\u4F53\u53EF\u6CA1\u6709\u64A4\u9500\u952E\uFF0C\u597D\u597D\u4F11\u606F\u4E00\u4E0B\u3002",
776
- "\u75AF\u72C2\u642C\u7816\uFF0C\u809D\u5929\u809D\u5730\u3002\u4E0D\u4EC5\u5728\u8DDF\u65F6\u95F4\u8D5B\u8DD1\uFF0C\u66F4\u662F\u5728\u7528\u4E00\u5DF1\u4E4B\u529B\u5E2E\u56E2\u961F\u586B\u5E73\u524D\u671F\u7684\u5404\u79CD\u6280\u672F\u5751\uFF0C\u8F9B\u82E6\u4E86\uFF01",
777
- "\u63D0\u4EA4\u6B21\u6570\u591A\u5230\u8BA9\u4EBA\u5FC3\u75BC\u3002\u9879\u76EE\u662F\u957F\u671F\u7684\uFF0C\u8EAB\u4F53\u662F\u81EA\u5DF1\u7684\u3002\u7559\u70B9\u529B\u6C14\uFF0C\u4E0B\u5468\u6211\u4EEC\u7EE7\u7EED\u7EC6\u6C34\u957F\u6D41\u3002"
861
+ "\u8FD9\u5468\u4EE3\u7801\u5E93\u7684\u534A\u58C1\u6C5F\u5C71\u662F\u4F60\u6253\u4E0B\u6765\u7684\u3002\u5FD9\u5B8C\u8BB0\u5F97\u7ED9\u81EA\u5DF1\u70B9\u676F\u51B0\u5976\u8336\uFF0C\u4F60\u503C\u5F97\u3002",
862
+ "\u6709\u6548\u5DE5\u65F6\u62C9\u6EE1\uFF0C\u4ECE\u65E9\u8FED\u4EE3\u5230\u665A\u3002\u4EE3\u7801\u80FD\u56DE\u6EDA\uFF0C\u8EAB\u4F53\u4E0D\u80FD\u2014\u2014\u62BD\u7A7A\u6B47\u6B47\u3002",
863
+ "\u9AD8\u5F3A\u5EA6\u642C\u7816\u4E0D\u505C\u6B47\uFF0C\u4E0D\u6B62\u5728\u8D76 deadline\uFF0C\u8FD8\u5728\u9ED8\u9ED8\u586B\u56E2\u961F\u7684\u5386\u53F2\u5751\u3002\u8F9B\u82E6\u4E86\u3002",
864
+ "\u63D0\u4EA4\u6570\u91CF\u591A\u5230\u5FC3\u75BC\u3002\u9879\u76EE\u662F\u6301\u4E45\u6218\uFF0C\u8EAB\u4F53\u624D\u662F\u672C\u91D1\uFF0C\u7559\u70B9\u4F59\u91CF\u3002",
865
+ "\u5168\u5929\u5728\u7EBF\u6301\u7EED\u8F93\u51FA\uFF0C\u5927\u5C0F\u9700\u6C42\u4E00\u624B\u5305\u63FD\uFF0C\u56E2\u961F\u8FDB\u5EA6\u6709\u4F60\u515C\u5E95\u3002\u8BB0\u5F97\u591A\u559D\u6C34\uFF0C\u591A\u8D70\u52A8\u3002",
866
+ "\u6574\u5468\u9AD8\u8D1F\u8377\u8F93\u51FA\uFF01\u5DE5\u4F5C\u518D\u91CD\u8981\uFF0C\u4E5F\u522B\u628A\u8EAB\u4F53\u5F53\u4E00\u6B21\u6027\u8017\u6750\u3002"
778
867
  ];
779
868
  var GHOST_CRITIQUES = [
780
- "\u3010\u5E7D\u7075\u63D0\u4EA4\u9884\u8B66\u3011\u6DF1\u591C\u7684 Commit \u95EA\u70C1\u7740\u7EFF\u5149\u3002\u4E0D\u8FC7\u4FEE\u4ED9\u5F52\u4FEE\u4ED9\uFF0C\u7761\u89C9\u4E5F\u662F\u7A0B\u5E8F\u5458\u7684\u91CD\u8981\u6280\u80FD\uFF0C\u5FEB\u53BB\u4F11\u606F\u5427\u3002",
781
- "\u534A\u591C\u4E09\u66F4\u8FD8\u5728\u63D0\u4EA4\u4EE3\u7801\uFF0C\u4F60\u662F\u5728\u548C\u5730\u7403\u53E6\u4E00\u7AEF\u7684\u7A0B\u5E8F\u5458\u6253\u65F6\u5DEE\u6218\uFF0C\u8FD8\u662F\u5728\u4EAB\u53D7\u6DF1\u591C\u65E0\u6253\u6270\u7684\u7075\u611F\u7206\u53D1\uFF1F",
782
- "\u6DF1\u591C 12 \u70B9\u540E\u7684\u63D0\u4EA4\u88AB\u68C0\u6D4B\u5230\uFF01\u4F60\u8FD9\u62FC\u547D\u7684\u67B6\u52BF\uFF0C\u662F\u5728\u7528\u6DF1\u591C\u7684\u7075\u611F\u4E3A\u9879\u76EE\u4FDD\u9A7E\u62A4\u822A\uFF0C\u4F46\u4E5F\u522B\u5FD8\u4E86\u7ED9\u8EAB\u4F53\u5145\u5145\u7535\u3002",
783
- "\u522B\u809D\u4E86\u522B\u809D\u4E86\uFF0C\u6DF1\u591C\u8FD8\u5728\u63D0\u4EA4\uFF0C\u8FDE CI \u673A\u5668\u4EBA\u90FD\u60F3\u529D\u4F60\u65E9\u70B9\u7761\uFF0C\u5FEB\u5B58\u76D8\u4E0B\u73ED\uFF0C\u68A6\u91CC\u6CA1\u6709 bug\u3002"
784
- ];
785
- var CATEGORY_FIX_CRITIQUES = [
786
- "\u4F60\u5DF2\u7ECF\u6210\u4E3A\u56E2\u961F\u7684\u2018\u804C\u4E1A\u6551\u706B\u961F\u957F\u2019\uFF0C\u5929\u5929\u5728\u4EE3\u7801\u5E93\u91CC\u8003\u53E4\u548C\u6551\u706B\uFF0C\u56E2\u961F\u7684\u7A33\u5B9A\u9632\u7EBF\u5168\u9760\u4F60\u6B7B\u5B88\u3002",
787
- "\u672C\u6708\u4E3B\u8981\u5DE5\u4F5C\u662F\u4FEE Bug\uFF0C\u5360\u6BD4\u9AD8\u8FBE %PERCENT%%\u3002\u662F\u5728\u4E00\u70B9\u70B9\u507F\u8FD8\u6280\u672F\u503A\uFF0C\u4E5F\u662F\u5728\u7ED9\u540E\u6765\u7684\u4EBA\u94FA\u5E73\u9053\u8DEF\u3002",
788
- "\u5929\u5929\u90FD\u5728 fix\uFF0C\u770B\u6765\u8FD9\u4E2A\u6708\u7684\u7CFB\u7EDF\u7A33\u5B9A\u6027\u5168\u9760\u4F60\u5728\u7EBF\u5B88\u62A4\u4E86\uFF0C\u59A5\u59A5\u7684\u5E55\u540E\u82F1\u96C4\u3002",
789
- "\u4EE3\u7801\u5E93\u7684\u6E05\u9053\u592B\uFF0CBug \u7EC8\u7ED3\u8005\u3002\u6BCF\u4FEE\u6389\u4E00\u4E2A\u95EE\u9898\uFF0C\u7CFB\u7EDF\u5C31\u5C11\u4E00\u5206\u9690\u60A3\uFF0C\u5B89\u5168\u611F\u76F4\u63A5\u62C9\u6EE1\u3002"
790
- ];
791
- var CATEGORY_FEAT_CRITIQUES = [
792
- "\u672C\u6708 Feat \u5360\u6BD4\u9AD8\u8FBE %PERCENT%%\u3002\u65B0\u529F\u80FD\u4E00\u9879\u63A5\u4E00\u9879\uFF0C\u5F00\u53D1\u706B\u529B\u5168\u5F00\uFF0C\u4E1A\u52A1\u7EBF\u56E0\u4F60\u800C\u98DE\u901F\u524D\u8FDB\uFF01",
793
- "\u65B0\u529F\u80FD\u72C2\u9B54\uFF01\u4E0D\u505C\u5730\u63A8\u8FDB\u9700\u6C42\u548C\u65B0\u4E1A\u52A1\u3002\u8F93\u51FA\u62C9\u6EE1\u7684\u540C\u65F6\uFF0C\u4E5F\u522B\u5FD8\u4E86\u5076\u5C14\u56DE\u5934\u6253\u78E8\u4E00\u4E0B\u7EC6\u8282\u3002Btw\uFF1A\u4F60\u8F9B\u82E6\u5566\uFF01",
794
- "\u75AF\u72C2\u8F93\u51FA feature\uFF01\u4EE3\u7801\u5E93\u7684\u8FB9\u754C\u53C8\u88AB\u4F60\u5411\u5916\u62D3\u5C55\u4E86\u4E00\u5708\uFF0C\u59A5\u59A5\u7684\u5F00\u62D3\u5148\u950B\u3002"
795
- ];
796
- var CATEGORY_CHORE_CRITIQUES = [
797
- "Chore/Docs \u5360\u4E86 %PERCENT%%\u3002\u597D\u7684\u9879\u76EE\u4E0D\u4EC5\u9700\u8981\u4EE3\u7801\uFF0C\u66F4\u9700\u8981\u6709\u4EBA\u628A\u6587\u6863\u6C89\u6DC0\u4E0B\u6765\uFF0C\u524D\u4EBA\u683D\u6811\u540E\u4EBA\u4E58\u51C9\u3002",
798
- "\u5929\u5929\u90FD\u5728\u6539\u914D\u7F6E\u3001\u4FEE\u6587\u6863\u3001\u683C\u5F0F\u5316\u4EE3\u7801\u3002\u4F60\u7B80\u76F4\u662F\u4EE3\u7801\u5E93\u7684\u4F18\u79C0\u56ED\u4E01\uFF0C\u8FD9\u4E9B\u5DE5\u4F5C\u867D\u7136\u4F4E\u8C03\uFF0C\u5374\u8BA9\u9879\u76EE\u53D8\u5F97\u66F4\u5065\u5EB7\u3001\u66F4\u6613\u8BFB\u3002",
799
- "Chore/Docs \u5360\u6BD4\u60CA\u4EBA\uFF0C\u9879\u76EE\u7684\u957F\u671F\u7A33\u5B9A\u8FD0\u884C\uFF0C\u79BB\u4E0D\u5F00\u8FD9\u4E9B\u770B\u4F3C\u4E0D\u8D77\u773C\u4F46\u6781\u4E3A\u5173\u952E\u7684\u7EF4\u62A4\u5DE5\u4F5C\u3002"
869
+ "\u3010\u5E7D\u7075\u63D0\u4EA4\u9884\u8B66\u3011\u51CC\u6668\u7684 Commit \u6CDB\u7740\u6E05\u51B7\u7684\u5149\u3002\u9002\u5EA6\u71AC\u591C\u53EF\u4EE5\uFF0C\u4F46\u7761\u89C9\u4E5F\u662F\u6838\u5FC3\u6280\u80FD\u3002",
870
+ "\u534A\u591C\u8FD8\u5728 push\uFF0C\u662F\u8DDF\u540C\u4E8B\u5BF9\u7EBF\uFF0C\u8FD8\u662F\u5355\u7EAF\u4EAB\u53D7\u51CC\u6668\u65E0\u4EBA\u6253\u6270\u7684\u7075\u611F\u7206\u53D1\uFF1F",
871
+ "\u96F6\u70B9\u8FC7\u540E\u5927\u91CF\u63D0\u4EA4\u88AB\u6355\u83B7\uFF01\u71AC\u591C\u7A33\u4F4F\u8FDB\u5EA6\u7684\u6837\u5B50\u5F88\u62FC\uFF0C\u4F46\u8EAB\u4F53\u4E5F\u9700\u8981\u5145\u7535\u3002",
872
+ "\u8FD8\u5728\u901A\u5BB5\u786C\u809D\uFF1FCI \u673A\u5668\u4EBA\u90FD\u60F3\u4E0B\u73ED\u4E86\uFF0C\u5199\u5B8C\u8D76\u7D27\u5B58\u76D8\u4F11\u606F\u3002",
873
+ "\u51CC\u6668\u4E13\u5C5E\u5F00\u53D1\u8005\uFF0C\u767D\u5929\u88AB\u7410\u4E8B\u7F20\u8EAB\uFF0C\u53EA\u80FD\u6DF1\u591C\u5543\u786C\u9AA8\u5934\u3002\u957F\u671F\u71AC\u591C\u4F24\u7684\u662F\u4F60\u81EA\u5DF1\u3002",
874
+ "\u6DF1\u591C\u72EC\u5B88\u5DE5\u4F4D\uFF0C\u6BCF\u6761\u51CC\u6668\u63D0\u4EA4\u90FD\u662F\u5361\u70B9\u7684\u4EE3\u4EF7\u3002\u4E13\u6CE8\u503C\u5F97\u80AF\u5B9A\uFF0C\u4F46\u522B\u5929\u5929\u4FEE\u4ED9\u3002",
875
+ "\u522B\u4EBA\u5DF2\u5165\u68A6\u4E61\uFF0C\u4F60\u7684 Git \u8FD8\u5728\u66F4\u65B0\u3002\u6DF1\u591C\u9002\u5408\u653B\u575A\uFF0C\u8BB0\u5F97\u8BBE\u4E2A\u95F9\u949F\uFF0C\u5230\u70B9\u4E0B\u7EBF\u3002"
800
876
  ];
801
877
  var GENERAL_CRITIQUES = [
802
- "\u4F60\u7684\u63D0\u4EA4\u66F2\u7EBF\u50CF\u5FC3\u7535\u56FE\u4E00\u6837\u5E73\u7F13\uFF0C\u57FA\u672C\u4E0A\u53EA\u5728\u5F00\u4F1A\u524D\u548C\u4E0B\u73ED\u524D\u6709\u6CE2\u52A8\u3002\u5B8C\u7F8E\u5730\u638C\u63E1\u4E86\u5DE5\u4F5C\u4E0E\u4F11\u606F\u7684\u5F8B\u52A8\u3002",
803
- "\u672C\u5468\u7684\u63D0\u4EA4\u96C6\u4E2D\u5728\u7279\u5B9A\u65F6\u95F4\u6BB5\u3002\u4E0A\u5348\u9759\u5982\u5904\u5B50\uFF0C\u4E0B\u5348\u52A8\u5982\u8131\u5154\u3002\u5B8C\u7F8E\u627E\u5230\u4E86\u5C5E\u4E8E\u81EA\u5DF1\u7684\u9AD8\u6548\u7387\u8282\u594F\u3002",
804
- "\u770B\u7740\u4F60\u7684 Git Log\uFF0C\u6211\u4EFF\u4F5B\u770B\u5230\u4E86\u4E00\u4F4D\u8282\u594F\u5927\u5E08\u3002\u4E0D\u7D27\u4E0D\u6162\uFF0C\u5076\u5C14\u843D\u7B14\uFF0C\u5374\u603B\u662F\u6070\u5230\u597D\u5904\u5730\u628A\u5DE5\u4F5C\u5B8C\u6210\u5F97\u65E0\u53EF\u6311\u5254\u3002",
805
- "\u4F60\u8FD9\u661F\u671F\u7684\u63D0\u4EA4\u6570\u636E\u975E\u5E38\u5747\u8861\u2014\u2014\u6BCF\u5929\u90FD\u4FDD\u6301\u7740\u5E73\u7A33\u7684\u8F93\u51FA\u8282\u594F\u3002\u7A33\u624E\u7A33\u6253\uFF0C\u4F60\u5C31\u662F\u56E2\u961F\u91CC\u7684\u5B9A\u6D77\u795E\u9488\u3002"
878
+ "\u6574\u5468\u63D0\u4EA4\u66F2\u7EBF\u5E73\u7F13\u89C4\u5F8B\uFF0C\u6CE2\u52A8\u96C6\u4E2D\u5728\u6668\u4F1A\u524D\u3001\u4E0B\u73ED\u524D\u3002\u62FF\u634F\u4E86\u81EA\u5DF1\u7684\u8282\u594F\uFF0C\u677E\u5F1B\u53C8\u9AD8\u6548\u3002",
879
+ "\u63D0\u4EA4\u65F6\u95F4\u7279\u5F81\u9C9C\u660E\uFF1A\u4E0A\u5348\u9759\u5982\u5904\u5B50\u6C89\u6DC0\u601D\u8DEF\uFF0C\u4E0B\u5348\u52A8\u5982\u8131\u5154\u96C6\u4E2D\u8F93\u51FA\u3002\u7CBE\u51C6\u9501\u5B9A\u9AD8\u6548\u65F6\u6BB5\u3002",
880
+ "Git Log \u50CF\u9876\u7EA7\u8C03\u5EA6\u5927\u5E08\u7684\u4F5C\u54C1\uFF0C\u4E0D\u75BE\u4E0D\u5F90\u3001\u5F20\u5F1B\u6709\u5EA6\u3002\u5076\u5C14\u843D\u5B50\uFF0C\u5374\u6070\u5230\u597D\u5904\u5B8C\u6210\u5168\u90E8\u3002",
881
+ "\u63D0\u4EA4\u6570\u636E\u5747\u8861\u7A33\u5B9A\uFF0C\u6BCF\u65E5\u5747\u5300\u8F93\u51FA\uFF0C\u4E0D\u7206\u809D\u4E0D\u7A7A\u767D\u3002\u7A33\u624E\u7A33\u6253\uFF0C\u662F\u56E2\u961F\u6700\u5B89\u5FC3\u7684\u5B9A\u6D77\u795E\u9488\u3002",
882
+ "\u8282\u594F\u5F20\u5F1B\u6709\u5EA6\uFF0C\u4E0D\u731B\u51B2\u4E0D\u62D6\u5EF6\u3002\u6BCF\u65E5\u7A33\u5B9A\u4EA7\u51FA\u5C11\u91CF\u6709\u6548\u63D0\u4EA4\uFF0C\u7EC6\u6C34\u957F\u6D41\u5B8C\u6210\u89C4\u5212\u3002",
883
+ "\u5F00\u53D1\u65F6\u95F4\u89C4\u5F8B\uFF0C\u61C2\u5F97\u62C6\u5206\u5DE5\u4F5C\u91CF\u5747\u5300\u5206\u644A\u3002\u62D2\u7EDD\u7A81\u51FB\uFF0C\u5E73\u7F13\u8F93\u51FA\uFF0C\u6709\u6548\u964D\u4F4E\u81EA\u8EAB\u538B\u529B\u3002",
884
+ "Git \u5386\u53F2\u8282\u594F\u8212\u670D\uFF0C\u65E0\u6781\u7AEF\u6CE2\u52A8\u3002\u957F\u671F\u5747\u8861\u5F00\u53D1\uFF0C\u4FDD\u8BC1\u63A8\u8FDB\uFF0C\u4E5F\u4E0D\u9677\u5165\u6301\u7EED\u5185\u8017\u3002"
806
885
  ];
807
886
  var TAG_FISH_MASTER_CRITIQUES = [
808
- "\u6478\u9C7C\u5B97\u5E08\u79F0\u53F7\u5DF2\u89E3\u9501\uFF01\u628A\u52B3\u9038\u7ED3\u5408\u53D1\u6325\u5230\u4E86\u6781\u81F4\uFF0C\u8868\u9762\u7A33\u5982\u6CF0\u5C71\uFF0C\u5B9E\u9645\u4E0A\u8111\u6D77\u91CC\u5DF2\u7ECF\u628A\u5047\u671F\u89C4\u5212\u505A\u597D\u4E86\u3002",
809
- "\u6478\u9C7C\u5B97\u5E08\uFF0C\u6CD5\u529B\u65E0\u8FB9\uFF01\u80FD\u628A\u751F\u4EA7\u529B\u7CBE\u786E\u63A7\u5236\u5728\u521A\u521A\u597D\u7684\u8212\u9002\u5708\uFF0C\u4E5F\u662F\u4E00\u79CD\u8BA9\u4EBA\u7FA1\u6155\u7684\u804C\u573A\u8D85\u80FD\u529B\u3002",
810
- "\u606D\u559C\u83B7\u5F97\u300E\u6478\u9C7C\u5B97\u5E08\u300F\u6210\u5C31\uFF01Git \u7684\u7559\u767D\u662F\u4F60\u7684\u901A\u884C\u8BC1\uFF0C\u5B8C\u7F8E\u7684\u8282\u594F\u5927\u5E08\u5C31\u662F\u4F60\u3002"
887
+ "\u6478\u9C7C\u5B97\u5E08\u79F0\u53F7\u5DF2\u89E3\u9501\uFF01\u628A\u52B3\u9038\u7ED3\u5408\u53D1\u6325\u5230\u4E86\u6781\u81F4\uFF0C\u9AD8\u6548\u5B8C\u6210\u672C\u804C\u5DE5\u4F5C\u4E4B\u4F59\uFF0C\u5468\u672B\u51FA\u884C\u3001\u4E0B\u5348\u8336\u6E05\u5355\u65E9\u5DF2\u89C4\u5212\u5B8C\u6BD5\uFF0C\u677E\u5F1B\u611F\u76F4\u63A5\u62C9\u6EE1\u3002",
888
+ "\u6478\u9C7C\u5B97\u5E08\uFF0C\u6CD5\u529B\u65E0\u8FB9\uFF01\u80FD\u628A\u6BCF\u65E5\u751F\u4EA7\u529B\u7CBE\u786E\u63A7\u5236\u5728\u521A\u521A\u597D\u7684\u5E73\u8861\u70B9\uFF0C\u4E0D\u591A\u4E0D\u5C11\u521A\u597D\u8FBE\u6807\uFF0C\u8FD9\u4EFD\u6536\u653E\u81EA\u5982\u7684\u804C\u573A\u5E73\u8861\u672F\uFF0C\u662F\u8BA9\u4EBA\u7FA1\u6155\u7684\u9876\u7EA7\u804C\u573A\u8D85\u80FD\u529B\u3002",
889
+ "\u606D\u559C\u83B7\u5F97\u300E\u6478\u9C7C\u5B97\u5E08\u300F\u6210\u5C31\uFF01Git \u7684\u7559\u767D\u662F\u4F60\u7684\u4E13\u5C5E\u901A\u884C\u8BC1\uFF0C\u5DE5\u4F5C\u8282\u594F\u62FF\u634F\u5F97\u6070\u5230\u597D\u5904\uFF0C\u8BE5\u4EA7\u51FA\u65F6\u4E0D\u6389\u94FE\u5B50\uFF0C\u8BE5\u653E\u677E\u65F6\u7EDD\u4E0D\u5185\u8017\uFF0C\u5B8C\u7F8E\u8282\u594F\u638C\u63A7\u8005\u975E\u4F60\u83AB\u5C5E\u3002",
890
+ "\u9876\u7EA7\u6478\u9C7C\u5B97\u5E08\u767B\u573A\uFF01\u4E0A\u73ED\u72B6\u6001\u677E\u5F1B\u6709\u5EA6\uFF0C\u4EFB\u52A1\u6309\u65F6\u843D\u5730\u7EDD\u4E0D\u62D6\u6C93\uFF0C\u5176\u4F59\u65F6\u95F4\u5B89\u5FC3\u653E\u7A7A\u5145\u7535\uFF0C\u61C2\u5F97\u9002\u65F6\u653E\u677E\u624D\u80FD\u957F\u4E45\u4FDD\u6301\u9AD8\u6548\uFF0C\u667A\u6167\u6253\u5DE5\u4EBA\u6A21\u677F\u6709\u4E86\u3002",
891
+ "\u522B\u4EBA\u5306\u5FD9\u57CB\u5934\u731B\u6572\uFF0C\u4F60\u4ECE\u5BB9\u7A33\u6B65\u5B8C\u6210\u672C\u804C\uFF0C\u6478\u9C7C\u5B97\u5E08\u7684\u7CBE\u9AD3\u4E0D\u662F\u6446\u70C2\uFF0C\u800C\u662F\u9AD8\u6548\u5B8C\u5DE5\u540E\u5B89\u5FC3\u4EAB\u53D7\u95F2\u6687\uFF0C\u5E73\u8861\u5DE5\u4F5C\u4E0E\u751F\u6D3B\u8FD9\u5757\u88AB\u4F60\u73A9\u660E\u767D\u4E86\u3002"
811
892
  ];
812
893
  var TAG_VOLUME_KING_CRITIQUES = [
813
- "\u7206\u809D\u6218\u795E\uFF0C\u6050\u6016\u5982\u65AF\uFF01\u4F60\u7684 Git \u65F6\u95F4\u7EBF\u5DF2\u7ECF\u6EE1\u5F97\u50CF\u6625\u8FD0\u706B\u8F66\u7AD9\uFF0C\u5EFA\u8BAE\u7ED9\u952E\u76D8\u4E70\u4E2A\u610F\u5916\u9669\uFF0C\u8F9B\u82E6\u4E86\uFF01",
814
- "\u7206\u809D\u6218\u795E\u5C31\u4F4D\uFF01\u4E00\u4E2A\u4EBA\u9876\u8D77\u4E00\u4E2A\u56E2\u961F\u7684\u4EA7\u51FA\uFF0C\u8FD9\u4E2A\u63D0\u4EA4\u91CF\uFF0C\u611F\u89C9\u4F60\u7684\u624B\u6307\u5DF2\u7ECF\u6572\u51FA\u4E86\u6B8B\u5F71\u3002",
815
- "\u522B\u4EBA\u5728\u4F11\u606F\uFF0C\u4F60\u5728 commit\uFF1B\u522B\u4EBA\u5728\u7761\u89C9\uFF0C\u4F60\u8FD8\u5728 push\u3002\u7206\u809D\u6218\u795E\u5C31\u662F\u4F60\uFF01\u4E0D\u8FC7\u522B\u5FD8\u4E86\uFF0C\u7A0B\u5E8F\u8981\u8DD1\uFF0C\u4EBA\u4E5F\u8981\u597D\u597D\u4F11\u606F\u3002"
894
+ "\u7206\u809D\u6218\u795E\uFF0C\u6050\u6016\u5982\u65AF\uFF01\u4F60\u7684 Git \u65F6\u95F4\u7EBF\u5BC6\u5BC6\u9EBB\u9EBB\uFF0C\u63D0\u4EA4\u5BC6\u5EA6\u60CA\u4EBA\uFF0C\u5168\u5929\u4E0D\u95F4\u65AD\u6301\u7EED\u8F93\u51FA\uFF0C\u5EFA\u8BAE\u7ED9\u952E\u76D8\u653E\u4E2A\u5047\uFF0C\u957F\u671F\u9AD8\u5F3A\u5EA6\u8F93\u51FA\u771F\u7684\u8F9B\u82E6\u4E86\uFF01",
895
+ "\u7206\u809D\u6218\u795E\u5C31\u4F4D\uFF01\u5355\u4EBA\u4EA7\u51FA\u76F4\u63A5\u9876\u8D77\u534A\u652F\u5C0F\u961F\u7684\u5DE5\u4F5C\u91CF\uFF0C\u5BC6\u5BC6\u9EBB\u9EBB\u7684\u63D0\u4EA4\u8BB0\u5F55\u8089\u773C\u53EF\u89C1\uFF0C\u98DE\u901F\u6572\u51FB\u7684\u952E\u76D8\u90FD\u5FEB\u6572\u51FA\u6B8B\u5F71\uFF0C\u656C\u4E1A\u7A0B\u5EA6\u76F4\u63A5\u62C9\u6EE1\u3002",
896
+ "\u522B\u4EBA\u4E0B\u73ED\u4F11\u606F\u8FFD\u5267\uFF0C\u4F60\u5728\u6301\u7EED commit\uFF1B\u522B\u4EBA\u6DF1\u591C\u5B89\u7A33\u7761\u89C9\uFF0C\u4F60\u8FD8\u5728\u8FDC\u7A0B push \u8FED\u4EE3\u3002\u7206\u809D\u6218\u795E\u5F53\u4E4B\u65E0\u6127\uFF01\u4F46\u7A0B\u5E8F\u7A33\u5B9A\u8FD0\u884C\u7684\u540C\u65F6\uFF0C\u4F60\u4E5F\u8981\u597D\u597D\u5403\u996D\u4F11\u606F\u3002",
897
+ "\u5168\u65F6\u6BB5\u5728\u7EBF\u7206\u809D\u9009\u624B\u4E0A\u7EBF\uFF0C\u4ECE\u65E9\u5230\u665A\u6301\u7EED\u66F4\u65B0\u8FED\u4EE3\uFF0C\u6BCF\u4E00\u6761\u63D0\u4EA4\u8BB0\u5F55\u90FD\u662F\u9ED8\u9ED8\u4ED8\u51FA\u7684\u8BC1\u660E\uFF0C\u56E2\u961F\u79BB\u4E0D\u5F00\u4F60\u7684\u5F3A\u529B\u8F93\u51FA\uFF0C\u8BB0\u5F97\u62BD\u7A7A\u7AD9\u8D77\u6765\u6D3B\u52A8\u8EAB\u4F53\u3001\u591A\u559D\u6E29\u6C34\u3002",
898
+ "\u63D0\u4EA4\u91CF\u65AD\u5C42\u9886\u5148\u5168\u573A\u7684\u7206\u809D\u5927\u4F6C\uFF0C\u5927\u5C0F\u9700\u6C42\u7EDF\u7EDF\u5305\u63FD\u843D\u5730\uFF0C\u4E3A\u9879\u76EE\u63A8\u8FDB\u7ACB\u4E0B\u6C57\u9A6C\u529F\u52B3\uFF0C\u9AD8\u5F3A\u5EA6\u8F93\u51FA\u56FA\u7136\u503C\u5F97\u79F0\u8D5E\uFF0C\u5343\u4E07\u4E0D\u8981\u957F\u671F\u900F\u652F\u81EA\u5DF1\u7684\u8EAB\u4F53\u54E6\u3002"
816
899
  ];
817
900
  var TAG_NIGHT_OWL_CRITIQUES = [
818
- "\u6DF1\u591C\u4FEE\u4ED9\u8005\uFF0C\u6CD5\u529B\u65E0\u8FB9\uFF01\u51CC\u6668\u7684\u4EE3\u7801\u95EA\u70C1\u7740\u72EC\u7279\u7684\u5149\u8292\uFF0C\u8FDE CI \u8DD1\u901A\u8FC7\u53BB\u7684\u901F\u5EA6\u90FD\u53D8\u5FEB\u4E86\u3002",
819
- "\u6210\u4E3A\u6DF1\u591C\u4FEE\u4ED9\u8005\u610F\u5473\u7740\u4F60\u7684\u6700\u4F73\u5DE5\u4F5C\u65F6\u6BB5\u662F 00:00 ~ 05:00\u3002\u767D\u5929\u5728\u5DE5\u4F4D\u79EF\u6512\u7075\u611F\uFF0C\u665A\u4E0A\u5728\u952E\u76D8\u4E0A\u75AF\u72C2\u8F93\u51FA\uFF0C\u53CC\u91CD\u9891\u7387\u65E0\u7F1D\u5207\u6362\u3002",
820
- "\u4FEE\u4ED9\u5927\u80FD\uFF01\u51CC\u6668\u7684 Git \u8BB0\u5F55\u89C1\u8BC1\u4E86\u4F60\u7684\u575A\u6301\u4E0E\u6267\u7740\u3002\u4E0D\u8FC7\u4FEE\u4ED9\u5F52\u4FEE\u4ED9\uFF0C\u8BB0\u5F97\u7ED9\u81EA\u5DF1\u7559\u8DB3\u7761\u7720\u65F6\u95F4\u3002"
901
+ "\u6DF1\u591C\u4FEE\u4ED9\u8005\uFF0C\u6CD5\u529B\u65E0\u8FB9\uFF01\u51CC\u6668\u5B89\u9759\u65F6\u6BB5\u6572\u51FA\u7684\u4EE3\u7801\u81EA\u5E26\u4E13\u6CE8\u52A0\u6210\uFF0C\u65E0\u4EBA\u6253\u6270\u7684\u6DF1\u591C\u7075\u611F\u7206\u53D1\uFF0C\u8FDE\u601D\u8DEF\u8FD0\u8F6C\u7684\u901F\u5EA6\u90FD\u4EFF\u4F5B\u53D8\u5FEB\u4E86\u4E0D\u5C11\u3002",
902
+ "\u6DF1\u591C\u4FEE\u4ED9\u8005\u7684\u4E13\u5C5E\u9EC4\u91D1\u5DE5\u4F5C\u65F6\u6BB5\u9501\u5B9A 00:00 ~ 05:00\u3002\u767D\u5929\u5DE5\u4F4D\u6C89\u6DC0\u68B3\u7406\u9700\u6C42\u79EF\u6512\u7075\u611F\uFF0C\u6DF1\u591C\u72EC\u5904\u65F6\u96C6\u4E2D\u8F93\u51FA\u843D\u5730\uFF0C\u663C\u591C\u53CC\u65F6\u6BB5\u6A21\u5F0F\u65E0\u7F1D\u81EA\u7531\u5207\u6362\u3002",
903
+ "\u4FEE\u4ED9\u5927\u80FD\u8BA4\u8BC1\uFF01\u4E00\u6761\u6761\u51CC\u6668Git\u8BB0\u5F55\u9ED8\u9ED8\u89C1\u8BC1\u4F60\u7684\u575A\u6301\u4E0E\u4E13\u6CE8\uFF0C\u6DF1\u591C\u5B89\u9759\u73AF\u5883\u66F4\u5BB9\u6613\u7406\u6E05\u590D\u6742\u903B\u8F91\u3002\u4E0D\u8FC7\u9002\u5EA6\u4FEE\u4ED9\u5373\u53EF\uFF0C\u8BB0\u5F97\u9884\u7559\u5145\u8DB3\u7761\u7720\u65F6\u95F4\u6062\u590D\u7CBE\u529B\u3002",
904
+ "\u504F\u7231\u6DF1\u591C\u72EC\u5904\u7F16\u7801\u7684\u4FEE\u4ED9\u9009\u624B\uFF0C\u4E07\u7C41\u4FF1\u5BC2\u7684\u65F6\u5019\u601D\u8DEF\u683C\u5916\u6E05\u6670\uFF0C\u5F88\u591A\u68D8\u624B\u96BE\u9898\u90FD\u5728\u51CC\u6668\u88AB\u4F60\u9010\u4E2A\u653B\u514B\uFF0C\u9AD8\u6548\u591C\u95F4\u9009\u624B\u8BA4\u8BC1\uFF0C\u522B\u957F\u671F\u71AC\u5230\u5929\u5149\u624D\u4F11\u606F\u3002",
905
+ "\u767D\u65E5\u5904\u7406\u6C9F\u901A\u7410\u4E8B\uFF0C\u6DF1\u591C\u6C89\u6D78\u5F0F\u4E13\u6CE8\u7F16\u7801\uFF0C\u6DF1\u591C\u4FEE\u4ED9\u6A21\u5F0F\u9002\u914D\u5EA6\u6EE1\u5206\uFF0C\u9760\u7740\u6DF1\u591C\u5B89\u9759\u73AF\u5883\u653B\u514B\u5927\u91CF\u96BE\u70B9\uFF0C\u8BB0\u5F97\u5B9A\u65F6\u653E\u4E0B\u7535\u8111\uFF0C\u4FDD\u8BC1\u5145\u8DB3\u7761\u7720\u517B\u62A4\u8EAB\u4F53\u3002"
821
906
  ];
822
907
  var TAG_BUILDER_CRITIQUES = [
823
- "\u52E4\u6073\u642C\u7816\u4EBA\uFF0C\u8E0F\u5B9E\u5982\u8001\u9EC4\u725B\uFF01\u6BCF\u4E00\u884C\u4EE3\u7801\u90FD\u662F\u4F60\u7528\u624B\u6572\u51FA\u6765\u7684\uFF0C\u7A33\u624E\u7A33\u6253\uFF0C\u662F\u6574\u4E2A\u9879\u76EE\u6700\u575A\u5B9E\u7684\u5E95\u5EA7\u3002",
824
- "\u642C\u7816\u4EBA\u642C\u7816\u9B42\uFF0C\u4EE3\u7801\u57FA\u5EFA\u5168\u9760\u52E4\u3002\u4F60\u8FD9\u4E2A\u6708\u7684\u4EE3\u7801\u91CF\uFF0C\u5DF2\u7ECF\u9ED8\u9ED8\u4E3A\u9879\u76EE\u780C\u8D77\u4E86\u4E00\u5EA7\u9AD8\u5899\u3002",
825
- "\u52E4\u6073\u642C\u7816\uFF0C\u7A33\u5982\u6CF0\u5C71\u3002\u4E0D\u662F\u6700\u7231\u79C0\u6280\u5DE7\u7684\u90A3\u4E2A\uFF0C\u4F46\u7EDD\u5BF9\u662F\u56E2\u961F\u91CC\u6700\u8BA9\u4EBA\u653E\u5FC3\u7684\u90A3\u9897\u87BA\u4E1D\u9489\u3002\u7EE7\u7EED\u52A0\u6CB9\uFF01"
908
+ "\u52E4\u6073\u642C\u7816\u4EBA\uFF0C\u8E0F\u5B9E\u5982\u8001\u9EC4\u725B\uFF01\u9879\u76EE\u91CC\u6BCF\u4E00\u884C\u843D\u5730\u53EF\u7528\u7684\u4EE3\u7801\u90FD\u662F\u4F60\u4EB2\u624B\u9010\u884C\u6572\u5199\uFF0C\u505A\u4E8B\u7A33\u624E\u7A33\u6253\u4E0D\u6295\u673A\u53D6\u5DE7\uFF0C\u662F\u652F\u6491\u6574\u4E2A\u9879\u76EE\u7A33\u5B9A\u8FD0\u884C\u6700\u575A\u5B9E\u7684\u5E95\u5C42\u5E95\u5EA7\u3002",
909
+ "\u642C\u7816\u4EBA\u642C\u7816\u9B42\uFF0C\u9879\u76EE\u4EE3\u7801\u57FA\u5EFA\u5168\u9760\u52E4\u6073\u642D\u5EFA\u3002\u672C\u6708\u7A33\u5B9A\u6301\u7EED\u8F93\u51FA\u5927\u91CF\u4E1A\u52A1\u4EE3\u7801\uFF0C\u4E00\u6B65\u4E00\u4E2A\u811A\u5370\u9ED8\u9ED8\u4E3A\u9879\u76EE\u7B51\u8D77\u7A33\u56FA\u529F\u80FD\u9AD8\u5899\uFF0C\u9760\u8C31\u7A0B\u5EA6\u62C9\u6EE1\u3002",
910
+ "\u52E4\u6073\u642C\u7816\uFF0C\u7A33\u5982\u6CF0\u5C71\u3002\u4E0D\u8FFD\u9010\u82B1\u54E8\u70AB\u6280\u7684\u5199\u6CD5\uFF0C\u4E13\u6CE8\u5B8C\u6210\u843D\u5730\u53EF\u7528\u7684\u4E1A\u52A1\u903B\u8F91\uFF0C\u662F\u56E2\u961F\u91CC\u6240\u6709\u4EBA\u90FD\u653E\u5FC3\u6258\u4ED8\u9700\u6C42\u7684\u5B9A\u5FC3\u87BA\u4E1D\u9489\uFF0C\u811A\u8E0F\u5B9E\u5730\u7EE7\u7EED\u95EA\u95EA\u53D1\u5149\uFF01",
911
+ "\u4F4E\u8C03\u52A1\u5B9E\u7684\u8D44\u6DF1\u642C\u7816\u9009\u624B\uFF0C\u4E0D\u62A2\u98CE\u5934\u4E0D\u641E\u82B1\u6D3B\uFF0C\u4E13\u6CE8\u592F\u5B9E\u57FA\u7840\u4E1A\u52A1\u80FD\u529B\uFF0C\u6240\u6709\u7E41\u6742\u57FA\u7840\u9700\u6C42\u90FD\u80FD\u7A33\u59A5\u4EA4\u4ED8\uFF0C\u9879\u76EE\u7A33\u5B9A\u8FD0\u884C\u79BB\u4E0D\u5F00\u4F60\u7684\u9ED8\u9ED8\u8015\u8018\u3002",
912
+ "\u65E5\u590D\u4E00\u65E5\u7A33\u5B9A\u8F93\u51FA\u7684\u57FA\u5EFA\u9009\u624B\uFF0C\u5927\u5C0F\u7410\u788E\u4E1A\u52A1\u9700\u6C42\u5168\u90E8\u59A5\u5584\u627F\u63A5\uFF0C\u505A\u4E8B\u7EC6\u81F4\u9760\u8C31\u4E0D\u51FA\u7EB0\u6F0F\uFF0C\u56E2\u961F\u57FA\u77F3\u822C\u7684\u5B58\u5728\uFF0C\u4F60\u7684\u8E0F\u5B9E\u4ED8\u51FA\u6240\u6709\u4EBA\u90FD\u770B\u5728\u773C\u91CC\u3002"
826
913
  ];
827
914
  var TAG_BURST_CODER_CRITIQUES = [
828
- "\u4E00\u628A\u68AD\u54C8\u578B\u7A0B\u5E8F\u5458\uFF01\u8981\u4E48\u4E0D\u5199\uFF0C\u4E00\u5199\u5C31\u662F\u51E0\u5343\u884C\u3002\u4F60\u7684\u5927\u62DB\u5F0F Git Diff \u8BA9 reviewer \u9ED8\u9ED8\u6CE1\u4E86\u4E00\u676F\u5496\u5561\u51C6\u5907\u7EC6\u7EC6\u54C1\u5473\u3002",
829
- "\u4E00\u628A\u68AD\u54C8\u73A9\u5BB6\uFF01\u5168\u90E8\u9700\u6C42\u4E00\u4E2A commit \u641E\u5B9A\uFF0C\u4EE3\u7801\u5728\u4F60\u7684\u8111\u6D77\u91CC\u65E9\u5DF2\u6210\u578B\uFF0C\u76F4\u63A5\u6765\u4E86\u4E00\u6CE2\u5B8C\u7F8E\u7684 Rush-B \u843D\u5730\u3002",
830
- "\u4E00\u628A\u68AD\u54C8\u827A\u672F\u5BB6\uFF01\u4F60\u7684\u6BCF\u6B21\u63D0\u4EA4\u90FD\u662F\u4E00\u7BC7\u5185\u5BB9\u4E30\u5BCC\u7684\u4E2D\u7BC7\u5C0F\u8BF4\uFF0C\u4E0D\u9E23\u5219\u5DF2\uFF0C\u4E00\u9E23\u60CA\u4EBA\u3002"
915
+ "\u4E00\u628A\u68AD\u54C8\u578B\u7A0B\u5E8F\u5458\u767B\u573A\uFF01\u5355\u6B21\u8D85\u5927\u7BC7\u5E45Git Diff\u76F4\u63A5\u62C9\u6EE1\uFF0C\u8D1F\u8D23review\u7684\u540C\u4E8B\u53EF\u4EE5\u6CE1\u4E0A\u4E00\u676F\u70ED\u8336\uFF0C\u51C6\u5907\u9759\u5FC3\u7814\u8BFB\u4F60\u4E00\u6B21\u6027\u843D\u5730\u7684\u5B8C\u6574\u903B\u8F91\u3002",
916
+ "\u4E00\u628A\u68AD\u54C8\u786C\u6838\u73A9\u5BB6\uFF01\u6574\u5957\u9700\u6C42\u903B\u8F91\u5168\u90E8\u6574\u5408\u8FDB\u5355\u6B21commit\u4E00\u6B21\u6027\u4EA4\u4ED8\uFF0C\u5B8C\u6574\u65B9\u6848\u65E9\u5728\u8111\u6D77\u4E2D\u6784\u601D\u6210\u578B\uFF0C\u76F4\u63A5\u4E00\u6CE2\u4E1D\u6ED1\u63A8\u8FDB\u5B8C\u6574\u843D\u5730\uFF0C\u6548\u7387\u60CA\u4EBA\u3002",
917
+ "\u4E00\u628A\u68AD\u54C8\u4EE3\u7801\u827A\u672F\u5BB6\uFF01\u4F60\u7684\u6BCF\u4E00\u6B21\u63D0\u4EA4\u90FD\u50CF\u4E00\u7BC7\u5185\u5BB9\u5B8C\u6574\u903B\u8F91\u95ED\u73AF\u7684\u4E2D\u7BC7\u6280\u672F\u6587\u7A3F\uFF0C\u5E73\u65F6\u5C11\u6709\u96F6\u6563\u5C0F\u6539\u52A8\uFF0C\u4E00\u65E6\u51FA\u624B\u4FBF\u662F\u5B8C\u6574\u529F\u80FD\u5927\u66F4\u65B0\uFF0C\u4E0D\u9E23\u5219\u5DF2\u4E00\u9E23\u60CA\u4EBA\u3002",
918
+ "\u4E60\u60EF\u6574\u4F53\u6784\u601D\u5B8C\u6574\u518D\u7EDF\u4E00\u63D0\u4EA4\u7684\u68AD\u54C8\u5927\u4F6C\uFF0C\u7701\u53BB\u9891\u7E41\u788E\u7247\u5316\u63D0\u4EA4\uFF0C\u6574\u5957\u529F\u80FD\u4E00\u6B21\u6027\u843D\u5730\uFF0C\u903B\u8F91\u8FDE\u8D2F\u5B8C\u6574\uFF0C\u8BC4\u5BA1\u9636\u6BB5\u9700\u8981\u591A\u82B1\u4E00\u70B9\u65F6\u95F4\u7814\u8BFB\uFF0C\u4F46\u903B\u8F91\u8FDE\u8D2F\u5B8C\u6574\u503C\u5F97\u6295\u5165\u3002",
919
+ "\u4E00\u6B21\u6027\u641E\u5B9A\u6574\u5957\u4E1A\u52A1\u6A21\u5757\u7684\u68AD\u54C8\u5927\u795E\uFF0C\u64C5\u957F\u5168\u76D8\u68B3\u7406\u9700\u6C42\u540E\u96C6\u4E2D\u8F93\u51FA\uFF0C\u7701\u53BB\u53CD\u590D\u62C6\u5206\u63D0\u4EA4\u7684\u7E41\u7410\uFF0C\u5927\u5C40\u89C2\u62C9\u6EE1\uFF0C\u582A\u79F0\u5B8C\u6574\u9700\u6C42\u4E00\u6B21\u6027\u4EA4\u4ED8\u6807\u6746\u3002"
831
920
  ];
832
921
  var TAG_PPT_ARCHITECT_CRITIQUES = [
833
- "\u67B6\u6784\u5E08\u98CE\u8303\u9690\u85CF\u6210\u5C31\u89E3\u9501\uFF01\u63D0\u4EA4\u591A\u3001\u6539\u52A8\u5C11\uFF0C\u4F60\u7684 Git \u5386\u53F2\u5C31\u50CF\u4E00\u90E8\u5145\u6EE1\u4EEA\u5F0F\u611F\u7684\u827A\u672F\u54C1\uFF0C\u91CD\u5728\u68B3\u7406\u903B\u8F91\u4E0E\u7ED3\u6784\u3002",
834
- "\u606D\u559C\u83B7\u5F97\u300E\u4F18\u96C5\u67B6\u6784\u5E08\u300F\u79F0\u53F7\uFF01\u6BCF\u4E2A commit \u90FD\u5E26\u7740\u6E05\u6670\u7684\u601D\u8DEF\uFF0C\u91CD\u6784\u4E8E\u65E0\u5F62\u4E4B\u4E2D\uFF0Cdiff \u8F7B\u76C8\u5374\u81F3\u5173\u91CD\u8981\u3002"
922
+ "\u67B6\u6784\u5E08\u98CE\u8303\u9690\u85CF\u6210\u5C31\u89E3\u9501\uFF01\u63D0\u4EA4\u6B21\u6570\u9891\u7E41\u4F46\u5355\u8F6E\u6539\u52A8\u7CBE\u7B80\u514B\u5236\uFF0C\u4F60\u7684Git\u5386\u53F2\u8BB0\u5F55\u50CF\u7CBE\u5FC3\u7F16\u6392\u7684\u6280\u672F\u827A\u672F\u54C1\uFF0C\u91CD\u5FC3\u653E\u5728\u68B3\u7406\u9879\u76EE\u903B\u8F91\u3001\u4F18\u5316\u6574\u4F53\u67B6\u6784\u3002",
923
+ "\u606D\u559C\u83B7\u5F97\u300E\u4F18\u96C5\u67B6\u6784\u5E08\u300F\u79F0\u53F7\uFF01\u6BCF\u4E00\u6761commit\u90FD\u5E26\u7740\u6E05\u6670\u89C4\u6574\u7684\u91CD\u6784\u601D\u8DEF\uFF0C\u5728\u65E0\u5F62\u4E4B\u4E2D\u68B3\u7406\u4F18\u5316\u9879\u76EE\u7ED3\u6784\uFF0Cdiff\u6539\u52A8\u8F7B\u76C8\u7CBE\u7B80\uFF0C\u5374\u5BF9\u6574\u4F53\u67B6\u6784\u8D77\u5230\u81F3\u5173\u91CD\u8981\u7684\u4F18\u5316\u4F5C\u7528\u3002",
924
+ "\u4E13\u6CE8\u67B6\u6784\u4F18\u5316\u7684\u4F18\u96C5\u5927\u4F6C\uFF0C\u4E0D\u5806\u780C\u5197\u4F59\u4E1A\u52A1\u4EE3\u7801\uFF0C\u4E13\u6CE8\u8C03\u6574\u9879\u76EE\u5206\u5C42\u3001\u89C4\u8303\u8C03\u7528\u903B\u8F91\uFF0C\u6BCF\u6B21\u5C0F\u63D0\u4EA4\u90FD\u5728\u6F5C\u79FB\u9ED8\u5316\u4F18\u5316\u9879\u76EE\u5E95\u5C42\u7ED3\u6784\uFF0C\u773C\u5149\u957F\u8FDC\u3002",
925
+ "\u4EE3\u7801\u4E16\u754C\u7684\u89C4\u5212\u8BBE\u8BA1\u5E08\uFF0C\u9891\u7E41\u5FAE\u8C03\u9879\u76EE\u7ED3\u6784\u4E0E\u5206\u5C42\u903B\u8F91\uFF0C\u6BD4\u8D77\u589E\u91CF\u529F\u80FD\u66F4\u770B\u91CD\u9879\u76EE\u957F\u671F\u53EF\u7EF4\u62A4\u6027\uFF0C\u7EC6\u788E\u63D0\u4EA4\u80CC\u540E\u90FD\u662F\u5BF9\u67B6\u6784\u957F\u8FDC\u53D1\u5C55\u7684\u6DF1\u5EA6\u8003\u91CF\u3002",
926
+ "\u4EE5\u91CD\u6784\u4F18\u5316\u4E3A\u6838\u5FC3\u5DE5\u4F5C\u7684\u67B6\u6784\u80FD\u624B\uFF0C\u8F7B\u91CF\u9AD8\u9891\u63D0\u4EA4\u6301\u7EED\u6253\u78E8\u9879\u76EE\u9AA8\u67B6\uFF0C\u9ED8\u9ED8\u89C4\u907F\u540E\u7EED\u8FED\u4EE3\u9690\u60A3\uFF0C\u773C\u5149\u653E\u5F97\u957F\u8FDC\uFF0C\u662F\u56E2\u961F\u6280\u672F\u89C4\u5212\u7684\u91CD\u8981\u63A8\u624B\u3002"
835
927
  ];
836
928
  var TAG_FORMAT_MASTER_CRITIQUES = [
837
- "\u683C\u5F0F\u5316\u5927\u5E08\u9690\u85CF\u6210\u5C31\u89E3\u9501\uFF01\u63D0\u4EA4\u4E86 10 \u6B21\uFF0C\u6539\u4E86\u4E0D\u5230 30 \u884C\u2014\u2014\u4F60\u5BF9\u4EE3\u7801\u6D01\u7656\u7684\u575A\u6301\uFF0C\u8BA9\u6574\u4E2A\u9879\u76EE\u7115\u7136\u4E00\u65B0\u3002",
838
- "\u683C\u5F0F\u5316\u5927\u5E08\uFF01\u51E0\u5341\u6B21\u63D0\u4EA4\u5168\u662F\u6539\u7A7A\u683C\u3001\u52A0\u6CE8\u91CA\u3001\u8C03\u7F29\u8FDB\u3002\u4EE3\u7801\u5E93\u7684\u989C\u503C\u88AB\u4F60\u62C9\u5230\u4E86\u5DC5\u5CF0\uFF0C\u53EF\u8BFB\u6027\u5927\u5927\u63D0\u5347\uFF01"
929
+ "\u683C\u5F0F\u5316\u5927\u5E08\u9690\u85CF\u6210\u5C31\u89E3\u9501\uFF01\u7D2F\u8BA1\u63D0\u4EA4\u591A\u6B21\uFF0C\u4EE3\u7801\u6539\u52A8\u884C\u6570\u5BE5\u5BE5\u2014\u2014\u4F60\u5BF9\u4EE3\u7801\u89C4\u8303\u4E0E\u6574\u6D01\u5EA6\u6709\u7740\u6781\u81F4\u8FFD\u6C42\uFF0C\u7EC6\u5FAE\u8C03\u6574\u76F4\u63A5\u8BA9\u6574\u4E2A\u9879\u76EE\u4EE3\u7801\u5E93\u7115\u7136\u4E00\u65B0\u3002",
930
+ "\u683C\u5F0F\u5316\u5927\u5E08\u5B9E\u9524\uFF01\u591A\u6B21\u63D0\u4EA4\u5168\u90E8\u805A\u7126\u8C03\u6574\u7A7A\u683C\u3001\u8865\u5145\u6CE8\u91CA\u3001\u7EDF\u4E00\u7F29\u8FDB\u89C4\u8303\uFF0C\u4E0D\u6C42\u65B0\u589E\u5927\u91CF\u529F\u80FD\u4EE3\u7801\uFF0C\u4E00\u5FC3\u62C9\u9AD8\u4EE3\u7801\u5E93\u6574\u4F53\u989C\u503C\uFF0C\u5927\u5E45\u63D0\u5347\u540E\u7EED\u9605\u8BFB\u53EF\u8BFB\u6027\uFF01",
931
+ "\u6267\u7740\u4E8E\u4EE3\u7801\u6574\u6D01\u5EA6\u7684\u89C4\u8303\u5B88\u62A4\u8005\uFF0C\u4E0D\u653E\u8FC7\u4EFB\u4F55\u4E00\u5904\u7F29\u8FDB\u3001\u7A7A\u683C\u3001\u6CE8\u91CA\u7455\u75B5\uFF0C\u53CD\u590D\u63D0\u4EA4\u5FAE\u8C03\u7EDF\u4E00\u9879\u76EE\u7F16\u7801\u98CE\u683C\uFF0C\u8BA9\u540C\u4E8B\u63A5\u624B\u4EE3\u7801\u65F6\u90FD\u80FD\u770B\u5F97\u6E05\u6670\u987A\u7545\u3002",
932
+ "\u4EE3\u7801\u989C\u503C\u7BA1\u7406\u5458\u4E0A\u7EBF\uFF0C\u6BD4\u8D77\u65B0\u589E\u4E1A\u52A1\u529F\u80FD\uFF0C\u66F4\u5728\u610F\u6574\u4F53\u4EE3\u7801\u98CE\u683C\u7EDF\u4E00\u89C4\u6574\uFF0C\u7EC6\u788E\u7684\u89C4\u8303\u5316\u8C03\u6574\u65E5\u79EF\u6708\u7D2F\uFF0C\u5927\u5E45\u964D\u4F4E\u56E2\u961F\u540E\u7EED\u534F\u4F5C\u9605\u8BFB\u6210\u672C\u3002",
933
+ "\u6781\u81F4\u7EC6\u8282\u63A7\u683C\u5F0F\u5316\u5927\u4F6C\uFF0C\u6BCF\u4E00\u5904\u6392\u7248\u3001\u6CE8\u91CA\u3001\u7B26\u53F7\u90FD\u4E25\u683C\u9075\u5FAA\u7EDF\u4E00\u6807\u51C6\uFF0C\u4E00\u6B21\u6B21\u7EC6\u5FAE\u63D0\u4EA4\u6253\u78E8\u9879\u76EE\u4EE3\u7801\u98CE\u8C8C\uFF0C\u5B8C\u7F8E\u6CBB\u6108\u6240\u6709\u4EBA\u7684\u4EE3\u7801\u5F3A\u8FEB\u75C7\u3002"
839
934
  ];
840
935
  var TAG_GIT_CHATTER_CRITIQUES = [
841
- "Git \u8BB0\u5F55\u8FBE\u4EBA\u9690\u85CF\u6210\u5C31\uFF0115 \u6B21\u63D0\u4EA4\uFF0C\u5E73\u5747\u6BCF\u6B21\u4E0D\u5230 2 \u884C\u2014\u2014\u4F60\u662F\u5728\u7528 Git \u8BB0\u5F55\u81EA\u5DF1\u7684\u5FC3\u8DEF\u5386\u7A0B\u5417\uFF1F\u7EC6\u9897\u7C92\u5EA6\u7684\u63D0\u4EA4\u8BA9\u7248\u672C\u56DE\u6EDA\u6BEB\u65E0\u538B\u529B\uFF01",
842
- "Git \u8BB0\u5F55\u8FBE\u4EBA\uFF01\u628A commit \u5206\u62C6\u5F97\u6781\u5176\u7EC6\u817B\uFF0C\u5C31\u50CF\u5728\u5199\u5B9E\u65F6\u65E5\u5FD7\u3002\u8FD9\u79CD\u9AD8\u9891\u5FAE\u8C03\u7684\u4E60\u60EF\uFF0C\u8BA9\u4EE3\u7801\u8FFD\u8E2A\u53D8\u5F97\u7B80\u5355\u660E\u4E86\u3002"
936
+ "Git \u8BB0\u5F55\u8FBE\u4EBA\u9690\u85CF\u6210\u5C31\uFF01\u591A\u6B21\u62C6\u5206\u63D0\u4EA4\uFF0C\u5E73\u5747\u5355\u6B21\u6539\u52A8\u7CBE\u7B80\u81F3\u6781\u2014\u2014\u4F60\u50CF\u662F\u5728\u7528Git\u7248\u672C\u5E93\u5B9E\u65F6\u8BB0\u5F55\u7F16\u7801\u601D\u8DEF\uFF0C\u6781\u81F4\u7EC6\u9897\u7C92\u5EA6\u62C6\u5206\uFF0C\u540E\u7EED\u7248\u672C\u56DE\u6EDA\u8C03\u8BD5\u6BEB\u65E0\u538B\u529B\uFF01",
937
+ "Git \u8BB0\u5F55\u8FBE\u4EBA\u8BA4\u8BC1\uFF01\u628A\u6BCF\u4E00\u5C0F\u6B65\u6539\u52A8\u90FD\u62C6\u5206\u4E3A\u72EC\u7ACBcommit\uFF0C\u7EC6\u7C92\u5EA6\u62C6\u5206\u5982\u540C\u5B9E\u65F6\u7F16\u5199\u5F00\u53D1\u65E5\u5FD7\uFF0C\u8C03\u8BD5\u3001\u56DE\u6EDA\u3001\u5B9A\u4F4D\u95EE\u9898\u65F6\u4E00\u76EE\u4E86\u7136\uFF0C\u4EE3\u7801\u8FFD\u8E2A\u96BE\u5EA6\u5927\u5E45\u964D\u4F4E\u3002",
938
+ "\u6781\u81F4\u7EC6\u5206\u63D0\u4EA4\u4E60\u60EF\u7684\u7EC6\u81F4\u9009\u624B\uFF0C\u4EFB\u4F55\u5FAE\u5C0F\u6539\u52A8\u5355\u72EC\u8BB0\u5F55\uFF0C\u4E0D\u6015\u63D0\u4EA4\u6570\u91CF\u591A\uFF0C\u53EA\u6C42\u6BCF\u4E00\u6B65\u6539\u52A8\u6E05\u6670\u53EF\u8FFD\u6EAF\uFF0C\u6392\u67E5\u7EBF\u4E0Abug\u65F6\u8FD9\u4EFD\u7EC6\u81F4\u80FD\u7701\u4E0B\u5927\u91CF\u6392\u67E5\u65F6\u95F4\u3002",
939
+ "\u5F00\u53D1\u8FC7\u7A0B\u53EF\u89C6\u5316\u5927\u5E08\uFF0C\u5C06\u65B0\u589E\u3001\u4FEE\u6539\u3001\u4FEE\u590D\u5168\u90E8\u62C6\u5206\u4E3A\u72EC\u7ACB\u8BB0\u5F55\uFF0CGit\u5386\u53F2\u6E05\u6670\u8BB0\u5F55\u6BCF\u4E00\u6B65\u5F00\u53D1\u601D\u8DEF\uFF0C\u534F\u4F5C\u8C03\u8BD5\u65F6\u80FD\u5FEB\u901F\u770B\u61C2\u4EE3\u7801\u8FED\u4EE3\u5168\u8FC7\u7A0B\uFF0C\u534F\u4F5C\u4F53\u9A8C\u62C9\u6EE1\u3002",
940
+ "\u504F\u7231\u5C0F\u6B65\u5FEB\u8DD1\u5F0F\u7F16\u7801\u7684\u7EC6\u5FC3\u5F00\u53D1\u8005\uFF0C\u4E00\u70B9\u6539\u52A8\u4E00\u6B21\u63D0\u4EA4\uFF0C\u62D2\u7EDD\u5927\u6BB5\u6DF7\u5408\u4FEE\u6539\uFF0C\u7248\u672C\u5386\u53F2\u5E72\u51C0\u901A\u900F\uFF0C\u662F\u56E2\u961F\u91CC\u65B9\u4FBF\u534F\u540C\u6392\u9519\u7684\u4F18\u8D28\u5F00\u53D1\u6A21\u677F\u3002"
843
941
  ];
844
942
  var TAG_NIGHT_ASSASSIN_CRITIQUES = [
845
- "\u6DF1\u591C\u523A\u5BA2\u9690\u85CF\u6210\u5C31\uFF01\u4FEE\u4ED9\u6307\u6570\u7206\u8868\u4F46\u63D0\u4EA4\u6781\u5176\u7CBE\u70BC\u2014\u2014\u4F60\u662F\u534A\u591C\u9876\u7740\u591C\u8272\u5077\u5077\u4E0A\u7EBF\u641E\u5B9A\u6838\u5FC3 bug\uFF0C\u6DF1\u85CF\u529F\u4E0E\u540D\u3002",
846
- "\u6DF1\u591C\u523A\u5BA2\uFF01\u5BE5\u5BE5\u51E0\u6B21\u63D0\u4EA4\u5168\u5728\u51CC\u6668\uFF0C\u767D\u5929\u95ED\u76EE\u517B\u795E\uFF0C\u534A\u591C\u4E00\u51FB\u5FC5\u6740\uFF0C\u53CC\u9762\u6781\u5BA2\u4EBA\u751F\u5C5E\u5B9E\u7CBE\u5F69\u3002"
943
+ "\u6DF1\u591C\u523A\u5BA2\u9690\u85CF\u6210\u5C31\uFF01\u4FEE\u4ED9\u71AC\u591C\u6307\u6570\u76F4\u63A5\u7206\u8868\uFF0C\u4F46\u6BCF\u6B21\u63D0\u4EA4\u5185\u5BB9\u7CBE\u70BC\u9AD8\u6548\u2014\u2014\u4E13\u6311\u591C\u6DF1\u4EBA\u9759\u7684\u6DF1\u591C\u4E0A\u7EBF\uFF0C\u6084\u65E0\u58F0\u606F\u641E\u5B9A\u6838\u5FC3\u963B\u585Ebug\uFF0C\u4E8B\u6210\u4E4B\u540E\u6DF1\u85CF\u529F\u4E0E\u540D\u3002",
944
+ "\u6DF1\u591C\u523A\u5BA2\u767B\u573A\uFF01\u5C11\u91CF\u9AD8\u8D28\u91CF\u63D0\u4EA4\u5168\u90E8\u8BDE\u751F\u4E8E\u51CC\u6668\u65F6\u6BB5\uFF0C\u767D\u5929\u4F4E\u8C03\u6C89\u6DC0\u4E0D\u5F20\u626C\uFF0C\u6DF1\u591C\u51FA\u624B\u7CBE\u51C6\u89E3\u51B3\u5173\u952E\u96BE\u9898\uFF0C\u663C\u591C\u53CD\u5DEE\u62C9\u6EE1\uFF0C\u53CC\u9762\u6781\u5BA2\u4EBA\u751F\u76F8\u5F53\u7CBE\u5F69\u3002",
945
+ "\u4E13\u5C5E\u6DF1\u591C\u4E0A\u7EBF\u7684bug\u6740\u624B\uFF0C\u907F\u5F00\u767D\u5929\u5608\u6742\u6C9F\u901A\u65F6\u6BB5\uFF0C\u51CC\u6668\u5B89\u9759\u73AF\u5883\u7CBE\u51C6\u5B9A\u4F4D\u6838\u5FC3\u6545\u969C\uFF0C\u5C11\u91CF\u7CBE\u70BC\u6539\u52A8\u76F4\u63A5\u6839\u6CBB\u7591\u96BE\u95EE\u9898\uFF0C\u4F4E\u8C03\u89E3\u51B3\u56E2\u961F\u68D8\u624B\u5361\u70B9\u3002",
946
+ "\u767D\u5929\u4F4E\u8C03\u5904\u7406\u65E5\u5E38\u7410\u4E8B\uFF0C\u6DF1\u591C\u5316\u8EAB\u4EE3\u7801\u523A\u5BA2\u7CBE\u51C6\u653B\u575A\u963B\u585E\u9879\u76EE\u7684\u6838\u5FC3\u96BE\u9898\uFF0C\u6CA1\u6709\u65E0\u6548\u63D0\u4EA4\uFF0C\u4E00\u62DB\u4E00\u5F0F\u76F4\u51FB\u95EE\u9898\u6839\u6E90\uFF0C\u9AD8\u6548\u53C8\u4F4E\u8C03\u3002",
947
+ "\u64C5\u957F\u5229\u7528\u51CC\u6668\u5B89\u9759\u7A97\u53E3\u89E3\u51B3\u987D\u56FA\u7EBF\u4E0A\u95EE\u9898\uFF0C\u6CA1\u6709\u65E0\u6548\u63D0\u4EA4\uFF0C\u6BCF\u4E00\u6B21\u6DF1\u591C\u66F4\u65B0\u90FD\u76F4\u51FB\u6838\u5FC3\u75DB\u70B9\uFF0C\u9ED8\u9ED8\u626B\u6E05\u9879\u76EE\u8FED\u4EE3\u8DEF\u4E0A\u7684\u5404\u7C7B\u969C\u788D\u3002"
847
948
  ];
848
949
  var TAG_DONKEY_CRITIQUES = [
849
- "\u5168\u80FD\u6218\u795E\u9690\u85CF\u6210\u5C31\u89E3\u9501\uFF01\u5468\u672B\u7206\u809D + \u6DF1\u591C\u4FEE\u4ED9\u3002Git \u5DF2\u7ECF\u8BB0\u4F4F\u4E86\u4F60\u7684\u6BCF\u4E00\u5206\u52AA\u529B\u4E0E\u4ED8\u51FA\uFF0C\u4F46\u4E5F\u5E0C\u671B\u4F60\u522B\u5FD8\u4E86\u597D\u597D\u7167\u987E\u81EA\u5DF1\u3002",
850
- "\u5468\u672B\u548C\u6DF1\u591C\u90FD\u7559\u4E0B\u4E86\u4F60\u7684\u8DB3\u8FF9\uFF0C\u8FD9\u4EFD\u8D23\u4EFB\u611F\u4E0E\u575A\u6301\u5DF2\u7ECF\u62C9\u6EE1\u3002\u8F9B\u82E6\u4ED8\u51FA\u7684\u540C\u65F6\uFF0C\u4E5F\u8BF7\u4E00\u5B9A\u8981\u7559\u51FA\u65F6\u95F4\u597D\u597D\u751F\u6D3B\u3002"
950
+ "\u5168\u80FD\u6218\u795E\u9690\u85CF\u6210\u5C31\u89E3\u9501\uFF01\u5468\u672B\u6301\u7EED\u7206\u809D\u8FED\u4EE3 + \u65E5\u5E38\u6DF1\u591C\u4FEE\u4ED9\u653B\u575A\u53CC\u6A21\u5F0F\u53E0\u52A0\u3002Git\u8BB0\u5F55\u4E86\u4F60\u6BCF\u4E00\u4EFD\u8F9B\u82E6\u4ED8\u51FA\uFF0C\u4F46\u4E5F\u8BB0\u5F97\u522B\u957F\u671F\u900F\u652F\uFF0C\u7559\u51FA\u65F6\u95F4\u597D\u597D\u7167\u987E\u81EA\u5DF1\u3002",
951
+ "\u5468\u672B\u4F11\u606F\u65F6\u6BB5\u3001\u4E07\u7C41\u4FF1\u5BC2\u7684\u6DF1\u591C\u90FD\u7559\u4E0B\u4E86\u4F60\u7684\u4EE3\u7801\u63D0\u4EA4\u8DB3\u8FF9\uFF0C\u8D23\u4EFB\u5FC3\u4E0E\u5403\u82E6\u8010\u52B3\u5C5E\u6027\u76F4\u63A5\u62C9\u6EE1\u3002\u5168\u529B\u4E3A\u9879\u76EE\u51B2\u950B\u7684\u540C\u65F6\uFF0C\u52A1\u5FC5\u7559\u51FA\u7A7A\u95F2\u65F6\u95F4\u597D\u597D\u751F\u6D3B\u653E\u677E\u3002",
952
+ "\u5168\u5E74\u65E0\u4F11\u5F0F\u5168\u80FD\u9009\u624B\uFF0C\u5DE5\u4F5C\u65E5\u71AC\u591C\u653B\u575A\u3001\u5468\u672B\u4E3B\u52A8\u8865\u5168\u8FED\u4EE3\uFF0C\u9879\u76EE\u4EFB\u4F55\u65F6\u6BB5\u7F3A\u4EBA\u515C\u5E95\u603B\u6709\u4F60\uFF0C\u4ED8\u51FA\u503C\u5F97\u6240\u6709\u4EBA\u8BA4\u53EF\uFF0C\u5207\u8BB0\u52B3\u9038\u7ED3\u5408\u4E0D\u8981\u8FC7\u5EA6\u52B3\u7D2F\u3002",
953
+ "\u517C\u987E\u6DF1\u591C\u653B\u575A\u4E0E\u5468\u672B\u8865\u8FED\u4EE3\u7684\u5168\u80FD\u515C\u5E95\u9009\u624B\uFF0C\u9879\u76EE\u6709\u7D27\u6025\u9700\u6C42\u65F6\u603B\u80FD\u4E0A\u7EBF\u5904\u7406\uFF0C\u627F\u62C5\u5927\u91CF\u989D\u5916\u5DE5\u4F5C\u91CF\uFF0C\u5728\u62FC\u547D\u63A8\u8FDB\u8FDB\u5EA6\u7684\u540C\u65F6\u8BB0\u5F97\u591A\u4F11\u606F\u8C03\u517B\u8EAB\u5FC3\u3002",
954
+ "\u5168\u5929\u5019\u5F85\u547D\u7684\u9879\u76EE\u5B88\u62A4\u8005\uFF0C\u4E0D\u5206\u5DE5\u4F5C\u65E5\u4F11\u606F\u65E5\u3001\u4E0D\u5206\u767D\u663C\u6DF1\u591C\uFF0C\u968F\u65F6\u4E0A\u7EBF\u89E3\u51B3\u8FED\u4EE3\u5361\u70B9\uFF0C\u9AD8\u5F3A\u5EA6\u4ED8\u51FA\u503C\u5F97\u70B9\u8D5E\uFF0C\u4E00\u5B9A\u8981\u7ED9\u81EA\u5DF1\u7559\u51FA\u653E\u677E\u4F11\u606F\u7684\u4E13\u5C5E\u65F6\u95F4\u3002"
851
955
  ];
852
956
  var TAG_FISH_IMMORTAL_CRITIQUES = [
853
- "\u6478\u9C7C\u4ED9\u4EBA\u9690\u85CF\u6210\u5C31\uFF01\u6478\u9C7C\u6307\u6570\u7A81\u7834 95%\uFF0C\u4E00\u5929\u53EA\u63D0\u4EA4 0 \u6216 1 \u6B21\u2014\u2014\u4F60\u5DF2\u7ECF\u8D85\u8D8A\u4E86\u666E\u901A\u7684\u6478\u9C7C\uFF0C\u8FBE\u5230\u4E86\u65E0\u62DB\u80DC\u6709\u62DB\u7684\u65E0\u4E3A\u5883\u754C\u3002",
854
- "\u6478\u9C7C\u4ED9\u4EBA\uFF0C\u5883\u754C\u5DF2\u8D85\u51E1\u4EBA\uFF01\u5BE5\u5BE5\u4E00\u6B21\u63D0\u4EA4\uFF0C\u9AD8\u8FBE 95%+ \u7684\u6DE1\u5B9A\u7387\u3002\u7528\u6700\u5C11\u7684\u52A8\u4F5C\u7EF4\u6301\u7CFB\u7EDF\u7684\u8FD0\u8F6C\uFF0C\u4E0D\u6127\u662F\u4E16\u5916\u9AD8\u4EBA\u3002"
957
+ "\u6478\u9C7C\u4ED9\u4EBA\u9690\u85CF\u6210\u5C31\uFF01\u6478\u9C7C\u677E\u5F1B\u6307\u6570\u62C9\u6EE1\uFF0C\u5355\u65E5\u63D0\u4EA40-1\u6B21\u5373\u53EF\u5B8C\u6210\u5168\u90E8\u672C\u804C\u5DE5\u4F5C\u2014\u2014\u65E9\u5DF2\u8D85\u8D8A\u666E\u901A\u6D45\u5C42\u6478\u9C7C\uFF0C\u62B5\u8FBE\u4EE5\u7B80\u9A6D\u7E41\u3001\u65E0\u62DB\u80DC\u6709\u62DB\u7684\u804C\u573A\u81F3\u9AD8\u5883\u754C\u3002",
958
+ "\u6478\u9C7C\u4ED9\u4EBA\uFF0C\u5883\u754C\u5DF2\u7136\u4E0D\u540C\u51E1\u54CD\uFF01\u6BCF\u65E5\u4EC5\u9700\u5BE5\u5BE5\u4E00\u6B21\u8F7B\u91CF\u63D0\u4EA4\uFF0C\u6DE1\u5B9A\u677E\u5F1B\u7387\u6781\u9AD8\uFF0C\u7528\u6700\u5C11\u7684\u63D0\u4EA4\u7A33\u7A33\u7EF4\u6301\u4E1A\u52A1\u6B63\u5E38\u8FD0\u8F6C\uFF0C\u59A5\u59A5\u4E16\u5916\u804C\u573A\u9AD8\u4EBA\u3002",
959
+ "\u53C2\u900F\u804C\u573A\u5E73\u8861\u4E4B\u9053\u7684\u6478\u9C7C\u4ED9\u4EBA\uFF0C\u8D85\u9AD8\u6548\u7387\u5FEB\u901F\u5B8C\u6210\u5F53\u65E5\u5168\u90E8\u4EFB\u52A1\uFF0C\u5269\u4F59\u65F6\u95F4\u5B89\u5FC3\u653E\u7A7A\u5145\u7535\uFF0C\u4E0D\u7528\u5185\u5377\u6D88\u8017\u81EA\u5DF1\uFF0C\u9AD8\u6548\u5B8C\u6210\u672C\u804C\u5C31\u662F\u6700\u9AD8\u7EA7\u7684\u6478\u9C7C\u667A\u6167\u3002",
960
+ "\u6781\u7B80\u5DE5\u4F5C\u6D41\u4ED9\u4EBA\uFF0C\u5C11\u91CF\u64CD\u4F5C\u5C31\u80FD\u7A33\u59A5\u4EA4\u4ED8\u5168\u90E8\u5DE5\u4F5C\u5185\u5BB9\uFF0C\u4ECE\u4E0D\u76F2\u76EE\u6D88\u8017\u65F6\u95F4\u5185\u5377\uFF0C\u61C2\u5F97\u9AD8\u6548\u5B8C\u5DE5\u3001\u9002\u5EA6\u653E\u677E\uFF0C\u628A\u5DE5\u4F5C\u751F\u6D3B\u5E73\u8861\u62FF\u634F\u5230\u6781\u81F4\u3002",
961
+ "\u522B\u4EBA\u82B1\u8D39\u4E00\u6574\u5929\u5FD9\u788C\u5728\u5DE5\u4F4D\uFF0C\u4F60\u77ED\u65F6\u9AD8\u6548\u5B8C\u6210\u5168\u90E8\u9700\u6C42\uFF0C\u5176\u4F59\u65F6\u95F4\u4ECE\u5BB9\u81EA\u5728\u4F11\u6574\uFF0C\u6478\u9C7C\u4ED9\u4EBA\u7684\u6838\u5FC3\u4ECE\u6765\u4E0D\u662F\u6446\u70C2\uFF0C\u662F\u8D85\u9AD8\u5DE5\u4F5C\u6548\u7387\u5E26\u6765\u7684\u677E\u5F1B\u81EA\u7531\u3002"
855
962
  ];
856
963
  function getRandomItem(arr) {
857
964
  const idx = Math.floor(Math.random() * arr.length);
@@ -871,6 +978,7 @@ function getAICritic(weeklyStats) {
871
978
  }
872
979
  const tagCritics = getTagCriticsFromDays(weeklyStats.days);
873
980
  if (tagCritics.length > 0) {
981
+ parts.push("\u2500".repeat(50));
874
982
  parts.push(...tagCritics.slice(0, 2));
875
983
  }
876
984
  if (parts.length === 0) {
@@ -883,20 +991,6 @@ function getAICriticForMonth(monthlyStats) {
883
991
  if (monthlyStats.ghostCommitsCount > 3) {
884
992
  parts.push(getRandomItem(GHOST_CRITIQUES));
885
993
  }
886
- const { fix, feat, chore, other } = monthlyStats.categories;
887
- const total = fix + feat + chore + other;
888
- if (total > 0) {
889
- const fixPct = Math.round(fix / total * 100);
890
- const featPct = Math.round(feat / total * 100);
891
- const chorePct = Math.round(chore / total * 100);
892
- if (fixPct >= 50) {
893
- parts.push(getRandomItem(CATEGORY_FIX_CRITIQUES).replace("%PERCENT%%", `${fixPct}%`));
894
- } else if (featPct >= 50) {
895
- parts.push(getRandomItem(CATEGORY_FEAT_CRITIQUES).replace("%PERCENT%%", `${featPct}%`));
896
- } else if (chorePct >= 40) {
897
- parts.push(getRandomItem(CATEGORY_CHORE_CRITIQUES).replace("%PERCENT%%", `${chorePct}%`));
898
- }
899
- }
900
994
  if (monthlyStats.totalCommits === 0) {
901
995
  parts.push("\u672C\u6708\u63D0\u4EA4\u6B21\u6570\u4E3A 0\uFF01\u4F60\u6210\u529F\u5730\u5728\u516C\u53F8\u84B8\u53D1\u4E86\u4E00\u4E2A\u6708\uFF0C\u62FF\u5230\u4E86\u5168\u989D\u5DE5\u8D44\u3002\u5EFA\u8BAE\u4F60\u4E0B\u4E2A\u6708\u7EE7\u7EED\u4FDD\u6301\u4F4E\u8C03\uFF0C\u4E0D\u8981\u8BA9 HR \u6CE8\u610F\u5230\u4F60\u3002");
902
996
  } else if (monthlyStats.averageFish >= 70) {
@@ -947,6 +1041,96 @@ function getTagCriticsFromDays(days) {
947
1041
  return critics;
948
1042
  }
949
1043
 
1044
+ // src/holiday.ts
1045
+ var holiday_in_law = {
1046
+ "2025-01-01": { "type": "holiday", "name": "\u5143\u65E6" },
1047
+ "2025-01-26": { "type": "workday", "name": "\u6625\u8282\u8C03\u4F11\u73ED" },
1048
+ "2025-01-28": { "type": "holiday", "name": "\u6625\u8282" },
1049
+ "2025-01-29": { "type": "holiday", "name": "\u6625\u8282" },
1050
+ "2025-01-30": { "type": "holiday", "name": "\u6625\u8282" },
1051
+ "2025-01-31": { "type": "holiday", "name": "\u6625\u8282" },
1052
+ "2025-02-01": { "type": "holiday", "name": "\u6625\u8282" },
1053
+ "2025-02-02": { "type": "holiday", "name": "\u6625\u8282" },
1054
+ "2025-02-03": { "type": "holiday", "name": "\u6625\u8282" },
1055
+ "2025-02-04": { "type": "holiday", "name": "\u6625\u8282" },
1056
+ "2025-02-08": { "type": "workday", "name": "\u6625\u8282\u8C03\u4F11\u73ED" },
1057
+ "2025-04-04": { "type": "holiday", "name": "\u6E05\u660E\u8282" },
1058
+ "2025-04-05": { "type": "holiday", "name": "\u6E05\u660E\u8282" },
1059
+ "2025-04-06": { "type": "holiday", "name": "\u6E05\u660E\u8282" },
1060
+ "2025-04-27": { "type": "workday", "name": "\u52B3\u52A8\u8282\u8C03\u4F11\u73ED" },
1061
+ "2025-05-01": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1062
+ "2025-05-02": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1063
+ "2025-05-03": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1064
+ "2025-05-04": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1065
+ "2025-05-05": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1066
+ "2025-05-31": { "type": "holiday", "name": "\u7AEF\u5348\u8282" },
1067
+ "2025-06-01": { "type": "holiday", "name": "\u7AEF\u5348\u8282" },
1068
+ "2025-06-02": { "type": "holiday", "name": "\u7AEF\u5348\u8282" },
1069
+ "2025-09-28": { "type": "workday", "name": "\u56FD\u5E86\u8282\u8C03\u4F11\u73ED" },
1070
+ "2025-10-01": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1071
+ "2025-10-02": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1072
+ "2025-10-03": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1073
+ "2025-10-04": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1074
+ "2025-10-05": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1075
+ "2025-10-06": { "type": "holiday", "name": "\u4E2D\u79CB\u8282" },
1076
+ "2025-10-07": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1077
+ "2025-10-08": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1078
+ "2025-10-11": { "type": "workday", "name": "\u56FD\u5E86\u8282\u8C03\u4F11\u73ED" },
1079
+ "2026-01-01": { "type": "holiday", "name": "\u5143\u65E6" },
1080
+ "2026-01-02": { "type": "holiday", "name": "\u5143\u65E6" },
1081
+ "2026-01-03": { "type": "holiday", "name": "\u5143\u65E6" },
1082
+ "2026-01-04": { "type": "workday", "name": "\u5143\u65E6\u8C03\u4F11\u73ED" },
1083
+ "2026-02-14": { "type": "workday", "name": "\u6625\u8282\u8C03\u4F11\u73ED" },
1084
+ "2026-02-15": { "type": "holiday", "name": "\u6625\u8282" },
1085
+ "2026-02-16": { "type": "holiday", "name": "\u6625\u8282" },
1086
+ "2026-02-17": { "type": "holiday", "name": "\u6625\u8282" },
1087
+ "2026-02-18": { "type": "holiday", "name": "\u6625\u8282" },
1088
+ "2026-02-19": { "type": "holiday", "name": "\u6625\u8282" },
1089
+ "2026-02-20": { "type": "holiday", "name": "\u6625\u8282" },
1090
+ "2026-02-21": { "type": "holiday", "name": "\u6625\u8282" },
1091
+ "2026-02-22": { "type": "holiday", "name": "\u6625\u8282" },
1092
+ "2026-02-23": { "type": "holiday", "name": "\u6625\u8282" },
1093
+ "2026-02-28": { "type": "workday", "name": "\u6625\u8282\u8C03\u4F11\u73ED" },
1094
+ "2026-04-04": { "type": "holiday", "name": "\u6E05\u660E\u8282" },
1095
+ "2026-04-05": { "type": "holiday", "name": "\u6E05\u660E\u8282" },
1096
+ "2026-04-06": { "type": "holiday", "name": "\u6E05\u660E\u8282" },
1097
+ "2026-05-01": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1098
+ "2026-05-02": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1099
+ "2026-05-03": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1100
+ "2026-05-04": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1101
+ "2026-05-05": { "type": "holiday", "name": "\u52B3\u52A8\u8282" },
1102
+ "2026-05-09": { "type": "workday", "name": "\u52B3\u52A8\u8282\u8C03\u4F11\u73ED" },
1103
+ "2026-06-19": { "type": "holiday", "name": "\u7AEF\u5348\u8282" },
1104
+ "2026-06-20": { "type": "holiday", "name": "\u7AEF\u5348\u8282" },
1105
+ "2026-06-21": { "type": "holiday", "name": "\u7AEF\u5348\u8282" },
1106
+ "2026-09-20": { "type": "workday", "name": "\u56FD\u5E86\u8282\u8C03\u4F11\u73ED" },
1107
+ "2026-09-25": { "type": "holiday", "name": "\u4E2D\u79CB\u8282" },
1108
+ "2026-09-26": { "type": "holiday", "name": "\u4E2D\u79CB\u8282" },
1109
+ "2026-09-27": { "type": "holiday", "name": "\u4E2D\u79CB\u8282" },
1110
+ "2026-10-01": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1111
+ "2026-10-02": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1112
+ "2026-10-03": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1113
+ "2026-10-04": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1114
+ "2026-10-05": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1115
+ "2026-10-06": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1116
+ "2026-10-07": { "type": "holiday", "name": "\u56FD\u5E86\u8282" },
1117
+ "2026-10-10": { "type": "workday", "name": "\u56FD\u5E86\u8282\u8C03\u4F11\u73ED" }
1118
+ };
1119
+ function formatDateKey(date) {
1120
+ const y = date.getFullYear();
1121
+ const m = String(date.getMonth() + 1).padStart(2, "0");
1122
+ const d = String(date.getDate()).padStart(2, "0");
1123
+ return `${y}-${m}-${d}`;
1124
+ }
1125
+ function isHoliday(date) {
1126
+ const key = formatDateKey(date);
1127
+ return holiday_in_law[key]?.type === "holiday";
1128
+ }
1129
+ function isCompensatoryWorkday(date) {
1130
+ const key = formatDateKey(date);
1131
+ return holiday_in_law[key]?.type === "workday";
1132
+ }
1133
+
950
1134
  // src/index.ts
951
1135
  var program = new Command();
952
1136
  function getCliVersion() {
@@ -1016,6 +1200,22 @@ function formatOvertimeIndex(fish) {
1016
1200
  return chalk.red.bold(`${fish}% (\u7EC8\u6781\u7206\u809D \u2620\uFE0F)`);
1017
1201
  }
1018
1202
  }
1203
+ function formatCodeVolume(totalLines) {
1204
+ if (totalLines <= 0) return "";
1205
+ if (totalLines >= 1e3) {
1206
+ return chalk.red.bold(`${totalLines}\u884C (\u4EE3\u7801\u6838\u7206 \u2622\uFE0F)`);
1207
+ } else if (totalLines >= 500) {
1208
+ return chalk.magenta(`${totalLines}\u884C (\u642C\u7816\u72C2\u9B54 \u{1F69A})`);
1209
+ } else if (totalLines >= 200) {
1210
+ return chalk.yellow(`${totalLines}\u884C (\u5927\u578B\u6539\u52A8 \u{1F9F1})`);
1211
+ } else if (totalLines >= 80) {
1212
+ return chalk.cyan(`${totalLines}\u884C (\u6B63\u5E38\u8425\u4E1A \u{1F4E6})`);
1213
+ } else if (totalLines >= 20) {
1214
+ return chalk.green(`${totalLines}\u884C (\u7F1D\u7F1D\u8865\u8865 \u{1F527})`);
1215
+ } else {
1216
+ return chalk.gray(`${totalLines}\u884C (\u5C0F\u4FEE\u5C0F\u8865 \u270F\uFE0F)`);
1217
+ }
1218
+ }
1019
1219
  function getPersonalityTag(day) {
1020
1220
  return day.tags.length > 0 ? day.tags.join(" ") : null;
1021
1221
  }
@@ -1028,10 +1228,10 @@ function colorizeTags(tagStr) {
1028
1228
  "\u{1F4A5} \u4E00\u628A\u68AD\u54C8\u578B\u7A0B\u5E8F\u5458": chalk.magenta,
1029
1229
  "\u{1F3F7}\uFE0F PPT \u67B6\u6784\u5E08": chalk.blue,
1030
1230
  "\u{1F3F7}\uFE0F \u683C\u5F0F\u5316\u5927\u5E08": chalk.cyan,
1031
- "\u{1F3F7}\uFE0F Git \u804A\u5929\u8FBE\u4EBA": chalk.greenBright,
1032
- "\u{1F3F7}\uFE0F \u6DF1\u591C\u523A\u5BA2": chalk.redBright,
1033
- "\u{1F3F7}\uFE0F \u751F\u4EA7\u961F\u7684\u9A74": chalk.yellowBright,
1034
- "\u{1F3F7}\uFE0F \u6478\u9C7C\u4ED9\u4EBA": chalk.green.bold,
1231
+ "\u{1F4AC} Git \u804A\u5929\u8FBE\u4EBA": chalk.greenBright,
1232
+ "\u{1F319} \u6DF1\u591C\u523A\u5BA2": chalk.redBright,
1233
+ "\u{1F434} \u751F\u4EA7\u961F\u7684\u9A74": chalk.yellowBright,
1234
+ "\u{1F41F} \u6478\u9C7C\u4ED9\u4EBA": chalk.green.bold,
1035
1235
  "\u{1F41F} \u4ECA\u65E5\u6682\u65E0\u4EE3\u7801\u6D3B\u52A8": chalk.green
1036
1236
  };
1037
1237
  const sortedKeys = Object.keys(colorMap).sort((a, b) => b.length - a.length);
@@ -1071,7 +1271,7 @@ function colorizeFishRow(row) {
1071
1271
  result += chunk;
1072
1272
  } else if (val >= 80) {
1073
1273
  result += chalk.green(chunk);
1074
- } else if (val >= 50) {
1274
+ } else if (val >= 40) {
1075
1275
  result += chalk.yellow(chunk);
1076
1276
  } else {
1077
1277
  result += chalk.red(chunk);
@@ -1170,7 +1370,7 @@ function getHourTag(hour) {
1170
1370
  else pool = COMMENT_POOLS["23"];
1171
1371
  return pool.color(` (${randomPick(pool.tags)})`);
1172
1372
  }
1173
- async function runWeeklyReport(weeksAgo, source) {
1373
+ async function runWeeklyReport(weeksAgo, source, showProjects = false) {
1174
1374
  const projects = getProjects();
1175
1375
  let timeTag = "";
1176
1376
  if (weeksAgo === 1) timeTag = " \u4E0A\u5468";
@@ -1213,7 +1413,7 @@ async function runWeeklyReport(weeksAgo, source) {
1213
1413
  if (isFuture && day.commitsCount === 0) {
1214
1414
  console.log(` ${day.dayName}\uFF1A${chalk.gray("\u672A\u5230")}`);
1215
1415
  } else {
1216
- const projStr = day.projects.length > 0 ? ` | ${day.projects.length}\u4E2A\u9879\u76EE (${day.projects.join(", ")})` : "";
1416
+ const projStr = day.projects.length > 0 ? ` | ${day.projects.length}\u4E2A\u9879\u76EE${showProjects ? ` (${day.projects.join(", ")})` : ""}` : "";
1217
1417
  const commitStr = day.commitsCount > 0 ? chalk.white.bold(`${day.commitsCount} \u6B21`) : "0 \u6B21";
1218
1418
  const indices = [];
1219
1419
  if (isWeekend) {
@@ -1221,14 +1421,18 @@ async function runWeeklyReport(weeksAgo, source) {
1221
1421
  } else {
1222
1422
  indices.push(`\u{1F41F} \u6478\u9C7C\u6307\u6570: ${formatSlackIndex(day.fish)}`);
1223
1423
  }
1424
+ if (day.totalLines > 0) {
1425
+ indices.push(`\u{1F9F1} \u4EE3\u7801\u91CF: ${formatCodeVolume(day.totalLines)}`);
1426
+ }
1224
1427
  if (day.nightOwl >= 10) {
1225
1428
  const nightStr = formatNightOwlIndex(day.nightOwl);
1226
1429
  if (nightStr) indices.push(`\u{1F319} \u4FEE\u4ED9\u6307\u6570: ${nightStr}`);
1227
1430
  }
1228
1431
  const extraIndices = indices.length > 0 ? ` | ${indices.join(" | ")}` : "";
1432
+ const branchStr = day.branchCount > 0 ? ` | \u{1F33F} ${day.branchCount}\u4E2A\u5206\u652F` : "";
1229
1433
  const tag = getPersonalityTag(day);
1230
1434
  const tagStr = tag ? ` \u{1F3F7} ${colorizeTags(tag)}` : "";
1231
- console.log(` ${day.dayName}\uFF1A${commitStr}${extraIndices}${projStr}${tagStr}`);
1435
+ console.log(` ${day.dayName}\uFF1A${commitStr}${extraIndices}${projStr}${branchStr}${tagStr}`);
1232
1436
  }
1233
1437
  });
1234
1438
  console.log("\n" + chalk.gray("-".repeat(50)));
@@ -1270,7 +1474,7 @@ async function runWeeklyReport(weeksAgo, source) {
1270
1474
  }
1271
1475
  console.log(chalk.gray("-".repeat(50)));
1272
1476
  const avgNightStr = stats.averageNightOwl > 0 ? ` | \u{1F319} \u4FEE\u4ED9: ${stats.averageNightOwl}%` : "";
1273
- console.log(chalk.dim(`\u{1F4CA} \u672C\u5468\u5747\u503C\uFF1A\u{1F41F} \u6478\u9C7C ${stats.averageFish}%${avgNightStr}`));
1477
+ console.log(chalk.cyan.bold(`\u{1F4CA} \u672C\u5468\u5747\u503C\uFF1A\u{1F41F} \u6478\u9C7C\u6307\u6570 ${stats.averageFish}%${avgNightStr}`));
1274
1478
  console.log(chalk.gray("-".repeat(50)));
1275
1479
  console.log(`\u{1F916} ${chalk.magenta.bold("\u9510\u8BC4")}\uFF1A`);
1276
1480
  console.log(chalk.white(getAICritic(stats)));
@@ -1332,7 +1536,20 @@ async function runMonthlyReport(monthsAgo, source) {
1332
1536
  const dateRaw = `${monthLabel}${d.day}\u65E5`;
1333
1537
  const fishRaw = `${d.fish}%`;
1334
1538
  const columnIndex = (firstDayOffset + d.day - 1) % 7;
1335
- dateRow += visualPad(dateRaw, COL_WIDTH);
1539
+ const dateObj = new Date(targetDate.getFullYear(), targetDate.getMonth(), d.day);
1540
+ let suffix = "";
1541
+ let suffixPlain = "";
1542
+ if (isHoliday(dateObj)) {
1543
+ suffix = chalk.green("\u2022");
1544
+ suffixPlain = "\u2022";
1545
+ } else if (isCompensatoryWorkday(dateObj)) {
1546
+ suffix = chalk.red("!");
1547
+ suffixPlain = "!";
1548
+ }
1549
+ const plainText = dateRaw + suffixPlain;
1550
+ const vw = visualWidth(plainText);
1551
+ const padding = vw < COL_WIDTH ? " ".repeat(COL_WIDTH - vw) : "";
1552
+ dateRow += dateRaw + suffix + padding;
1336
1553
  fishRow += visualPad(fishRaw, COL_WIDTH);
1337
1554
  if (columnIndex === 6 || d === stats.dailyIndices[stats.dailyIndices.length - 1]) {
1338
1555
  lines.push(chalk.gray(dateRow.trimEnd()));
@@ -1347,19 +1564,6 @@ async function runMonthlyReport(monthsAgo, source) {
1347
1564
  for (const l of lines) {
1348
1565
  console.log(` ${l}`);
1349
1566
  }
1350
- const dailyWithCommits = stats.dailyIndices.filter((d) => d.commitsCount > 0);
1351
- if (dailyWithCommits.length > 0) {
1352
- const mostFish = [...dailyWithCommits].sort((a, b) => b.fish - a.fish)[0];
1353
- const mostWork = [...dailyWithCommits].sort((a, b) => a.fish - b.fish)[0];
1354
- if (mostFish.fish >= 75) {
1355
- console.log(chalk.green(`
1356
- \u{1F3A3} \u6478\u9C7C\u738B: ${monthLabel}${mostFish.day}\u65E5 \u2192 \u6478\u9C7C\u6307\u6570 ${mostFish.fish}%` + (mostFish.tags.length > 0 ? ` ${mostFish.tags.join(" ")}` : "")));
1357
- }
1358
- if (mostWork.fish <= 40) {
1359
- console.log(chalk.red(`
1360
- \u{1F525} \u7206\u809D\u738B: ${monthLabel}${mostWork.day}\u65E5 \u2192 \u6478\u9C7C\u6307\u6570 ${mostWork.fish}%` + (mostWork.tags.length > 0 ? ` ${mostWork.tags.join(" ")}` : "")));
1361
- }
1362
- }
1363
1567
  }
1364
1568
  console.log("\n" + chalk.gray("-".repeat(50)));
1365
1569
  console.log(`\u{1F916} ${chalk.magenta.bold("\u9510\u8BC4")}\uFF1A`);
@@ -1475,7 +1679,7 @@ async function runGhostReport(weeksAgo, source) {
1475
1679
  console.log(chalk.red("\u547D\u662F\u81EA\u5DF1\u7684\uFF0C\u5927\u798F\u62A5\u7559\u7ED9\u8001\u677F\u5427\uFF01\u8D76\u7D27\u7761\u89C9\uFF0C\u4FDD\u547D\u8981\u7D27\uFF01\n"));
1476
1680
  }
1477
1681
  }
1478
- program.name("fish").description("\u{1F41F} Git \u6478\u9C7C & \u7206\u809D\u5206\u6790\u5668 CLI").version(getCliVersion()).option("-m, --month [monthsAgo]", "\u67E5\u770B\u6478\u9C7C/\u7206\u809D\u6708\u62A5 (\u9ED8\u8BA4 0 \u4E3A\u672C\u6708\uFF0C1 \u4E3A\u4E0A\u6708\uFF0C2 \u4E3A\u4E0A\u4E0A\u6708...)").option("-p, --project", "\u67E5\u770B\u9879\u76EE\u7206\u809D\u6392\u884C").option("-t, --time", "\u67E5\u770B\u9EC4\u91D1\u6478\u9C7C\u65F6\u95F4\u6BB5 analysis (24\u5C0F\u65F6\u5206\u5E03)").option("-g, --ghost", "\u68C0\u6D4B\u6DF1\u591C\u5E7D\u7075\u63D0\u4EA4").option("-w, --weeks-ago <number>", "\u67E5\u8BE2\u51E0\u5468\u524D/\u6708\u524D\u7684\u62A5\u544A (\u9ED8\u8BA4 0\uFF0C\u5373\u672C\u5468/\u672C\u6708)", "0").option("-s, --source <source>", "\u9009\u62E9\u8981\u67E5\u8BE2\u7684 GitLab \u6570\u636E\u6E90 (\u5E8F\u53F7\u6216\u522B\u540D/host)").action(async (options) => {
1682
+ program.name("fish").description("\u{1F41F} Git \u6478\u9C7C & \u7206\u809D\u5206\u6790\u5668 CLI").version(getCliVersion()).option("-m, --month [monthsAgo]", "\u67E5\u770B\u6478\u9C7C/\u7206\u809D\u6708\u62A5 (\u9ED8\u8BA4 0 \u4E3A\u672C\u6708\uFF0C1 \u4E3A\u4E0A\u6708\uFF0C2 \u4E3A\u4E0A\u4E0A\u6708...)").option("-p, --project", "\u67E5\u770B\u9879\u76EE\u7206\u809D\u6392\u884C").option("-t, --time", "\u67E5\u770B\u9EC4\u91D1\u6478\u9C7C\u65F6\u95F4\u6BB5 analysis (24\u5C0F\u65F6\u5206\u5E03)").option("-g, --ghost", "\u68C0\u6D4B\u6DF1\u591C\u5E7D\u7075\u63D0\u4EA4").option("-w, --weeks-ago <number>", "\u67E5\u8BE2\u51E0\u5468\u524D/\u6708\u524D\u7684\u62A5\u544A (\u9ED8\u8BA4 0\uFF0C\u5373\u672C\u5468/\u672C\u6708)", "0").option("-P, --show-projects", "\u663E\u793A\u5177\u4F53\u9879\u76EE\u540D\u79F0\uFF08\u9ED8\u8BA4\u9690\u85CF\uFF09").option("-s, --source <source>", "\u9009\u62E9\u8981\u67E5\u8BE2\u7684 GitLab \u6570\u636E\u6E90 (\u5E8F\u53F7\u6216\u522B\u540D/host)").action(async (options) => {
1479
1683
  const weeksAgo = parseInt(options.weeksAgo || "0", 10);
1480
1684
  const source = options.source;
1481
1685
  if (options.month !== void 0 && options.project) {
@@ -1494,7 +1698,7 @@ program.name("fish").description("\u{1F41F} Git \u6478\u9C7C & \u7206\u809D\u520
1494
1698
  } else if (options.ghost) {
1495
1699
  await runGhostReport(weeksAgo, source);
1496
1700
  } else {
1497
- await runWeeklyReport(weeksAgo, source);
1701
+ await runWeeklyReport(weeksAgo, source, options.showProjects);
1498
1702
  }
1499
1703
  });
1500
1704
  var configCmd = program.command("config").description("\u7BA1\u7406\u76D1\u63A7\u7684\u9879\u76EE\u8DEF\u5F84\u4E0E GitLab \u51ED\u8BC1");