@ihabdevteam/core 0.322.0 → 0.324.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (198) hide show
  1. package/CHANGELOG.md +557 -0
  2. package/dist/components.cjs.js +183 -183
  3. package/dist/components.esm.css +1 -1
  4. package/dist/hooks.cjs.js +3 -3
  5. package/dist/i18n.cjs.js +3 -3
  6. package/dist/ihabdevteam-core.cjs.js +187 -187
  7. package/dist/ihabdevteam-core.d.ts +55 -17
  8. package/dist/packages/core/src/components/Accordion.js +3 -3
  9. package/dist/packages/core/src/components/Alert.js +2 -2
  10. package/dist/packages/core/src/components/BarChart.js +120 -119
  11. package/dist/packages/core/src/components/BottomNav.js +18 -18
  12. package/dist/packages/core/src/components/BulkBar.js +25 -25
  13. package/dist/packages/core/src/components/Button.js +16 -16
  14. package/dist/packages/core/src/components/Calendar.js +17 -17
  15. package/dist/packages/core/src/components/ChartSection.js +30 -30
  16. package/dist/packages/core/src/components/CountTile.js +38 -38
  17. package/dist/packages/core/src/components/DatePicker.js +59 -59
  18. package/dist/packages/core/src/components/Dialog.js +14 -14
  19. package/dist/packages/core/src/components/Effect/EffectPartyPopperHost.js +8 -8
  20. package/dist/packages/core/src/components/FilterPanel.js +6 -6
  21. package/dist/packages/core/src/components/FilterSectionInfo.js +6 -6
  22. package/dist/packages/core/src/components/GameIntro.js +1 -1
  23. package/dist/packages/core/src/components/Icon.js +2 -2
  24. package/dist/packages/core/src/components/ItemActions.js +16 -16
  25. package/dist/packages/core/src/components/LandingHeader.js +6 -6
  26. package/dist/packages/core/src/components/LineChart.js +24 -24
  27. package/dist/packages/core/src/components/Loader.js +5 -5
  28. package/dist/packages/core/src/components/NoticeBox.js +3 -3
  29. package/dist/packages/core/src/components/PageTitle.js +2 -2
  30. package/dist/packages/core/src/components/Pagination.js +4 -4
  31. package/dist/packages/core/src/components/Panel.js +2 -2
  32. package/dist/packages/core/src/components/PanelRow.js +6 -13
  33. package/dist/packages/core/src/components/PassCard/PassCard.js +9 -9
  34. package/dist/packages/core/src/components/PassCard/passCardProduct.js +2 -2
  35. package/dist/packages/core/src/components/PaymentPlan.js +5 -5
  36. package/dist/packages/core/src/components/Popup/ConfirmPopup.js +29 -29
  37. package/dist/packages/core/src/components/Popup/CouponInputPopup.js +2 -2
  38. package/dist/packages/core/src/components/Popup/DeviceSideTable.js +18 -25
  39. package/dist/packages/core/src/components/Popup/ListPopup.js +3 -3
  40. package/dist/packages/core/src/components/Popup/LoadTablePopup.js +7 -7
  41. package/dist/packages/core/src/components/Popup/Popup.js +27 -27
  42. package/dist/packages/core/src/components/Popup/SaveTablePopup.js +5 -5
  43. package/dist/packages/core/src/components/Popup/TrainingResultPopup.js +4 -4
  44. package/dist/packages/core/src/components/Popup/customerDetailUtils.js +18 -18
  45. package/dist/packages/core/src/components/Popup/useDiscardGuard.js +4 -4
  46. package/dist/packages/core/src/components/ProgressIndicator.js +5 -5
  47. package/dist/packages/core/src/components/PromoBannerBg/promoBannerBg.js +16 -16
  48. package/dist/packages/core/src/components/Rating.js +20 -20
  49. package/dist/packages/core/src/components/Report/ReportDocument.js +21 -21
  50. package/dist/packages/core/src/components/RingChart.js +5 -5
  51. package/dist/packages/core/src/components/SectionHeadFloat.js +15 -15
  52. package/dist/packages/core/src/components/SegmentedControl.js +34 -34
  53. package/dist/packages/core/src/components/SideNav.js +37 -37
  54. package/dist/packages/core/src/components/Slider.js +2 -2
  55. package/dist/packages/core/src/components/SoundCompass.js +5 -5
  56. package/dist/packages/core/src/components/Table.js +257 -98
  57. package/dist/packages/core/src/components/Tabs.js +12 -12
  58. package/dist/packages/core/src/components/TextField.js +34 -34
  59. package/dist/packages/core/src/components/Toast.js +6 -6
  60. package/dist/packages/core/src/components/Tooltip/MenuTooltip.js +4 -4
  61. package/dist/packages/core/src/components/Tooltip/Tooltip.js +22 -22
  62. package/dist/packages/core/src/components/Tooltip/TrainingTooltip.js +4 -4
  63. package/dist/packages/core/src/components/TopBanner.js +28 -28
  64. package/dist/packages/core/src/components/Training/AudioPlayerWaveForm.js +11 -11
  65. package/dist/packages/core/src/components/Training/CategoryIcon.js +2 -2
  66. package/dist/packages/core/src/components/Training/NoisePlayerContext.js +12 -12
  67. package/dist/packages/core/src/components/Training/NoiseSettingsTooltip.js +2 -2
  68. package/dist/packages/core/src/components/Training/TrainingBlock.js +11 -11
  69. package/dist/packages/core/src/components/Training/TrainingBlockButton.js +10 -10
  70. package/dist/packages/core/src/components/Training/TrainingBlockGrid.js +21 -21
  71. package/dist/packages/core/src/components/Training/TrainingCard.css +13 -1
  72. package/dist/packages/core/src/components/Training/TrainingCard.js +2 -2
  73. package/dist/packages/core/src/components/Training/TrainingCardGroup.js +6 -6
  74. package/dist/packages/core/src/components/Training/TrainingPagePopup.js +81 -81
  75. package/dist/packages/core/src/components/Training/TrainingPagePopupBottom.js +17 -17
  76. package/dist/packages/core/src/components/Training/TrainingStepAudioPlayer.js +127 -127
  77. package/dist/packages/core/src/components/Training/TrainingStepCard.js +18 -18
  78. package/dist/packages/core/src/components/Training/TrainingStepConfirmWithText.js +4 -4
  79. package/dist/packages/core/src/components/Training/TrainingStepOrderList.js +12 -12
  80. package/dist/packages/core/src/components/Training/TrainingStepTextBox.js +12 -12
  81. package/dist/packages/core/src/components/Training/TrainingStepTitle.js +4 -4
  82. package/dist/packages/core/src/components/Training/TrainingWordCard.js +17 -17
  83. package/dist/packages/core/src/components/Training/WordTablePopup.js +5 -5
  84. package/dist/packages/core/src/components/Training/audioPlaybackRules.js +8 -8
  85. package/dist/packages/core/src/components/Training/audioTimeline.js +25 -25
  86. package/dist/packages/core/src/components/Training/oneShotSound.js +13 -13
  87. package/dist/packages/core/src/components/Training/trainingMissStats.js +20 -20
  88. package/dist/packages/core/src/components/Training/trainingPopupUtils.js +7 -7
  89. package/dist/packages/core/src/components/Training/useAudioPreview.js +15 -15
  90. package/dist/packages/core/src/components/Training/useFloatingFocus.js +14 -14
  91. package/dist/packages/core/src/components/Training/useNoiseFade.js +22 -22
  92. package/dist/packages/core/src/components/Training/useObjectUrls.js +2 -2
  93. package/dist/packages/core/src/components/Training/usePlaybackSequencer.d.ts +2 -2
  94. package/dist/packages/core/src/components/Training/usePlaybackSequencer.js +23 -23
  95. package/dist/packages/core/src/components/Training/useProgressTicker.js +33 -33
  96. package/dist/packages/core/src/components/Training/useTTSPlayback.js +17 -17
  97. package/dist/packages/core/src/components/Training/useWaveReady.js +11 -11
  98. package/dist/packages/core/src/components/UpdateAlert.js +6 -6
  99. package/dist/packages/core/src/components/Word/PhonemeSelectBlock.js +7 -1
  100. package/dist/packages/core/src/components/Word/TableFilterPanel.js +3 -3
  101. package/dist/packages/core/src/components/Word/WordSearchResultBlock.js +10 -10
  102. package/dist/packages/core/src/components/Word/WordTableBlock.js +28 -28
  103. package/dist/packages/core/src/components/Word/WordTableButton.css +16 -2
  104. package/dist/packages/core/src/components/Word/WordTableThumbnail.css +6 -1
  105. package/dist/packages/core/src/components/Word/generatedDraft.js +14 -14
  106. package/dist/packages/core/src/components/Word/useWordTableDisplaySettings.js +7 -7
  107. package/dist/packages/core/src/components/Word/wordScoreStats.js +15 -15
  108. package/dist/packages/core/src/components/Word/wordTablePrint.js +10 -10
  109. package/dist/packages/core/src/components/Word/wordTableRecommend.js +11 -11
  110. package/dist/packages/core/src/components/Word/wordTableReview.js +28 -28
  111. package/dist/packages/core/src/components/Word/wordTableSettings.d.ts +8 -11
  112. package/dist/packages/core/src/components/Word/wordTableSettings.js +48 -36
  113. package/dist/packages/core/src/components/WordTable.js +130 -130
  114. package/dist/packages/core/src/components/barChartData.d.ts +16 -1
  115. package/dist/packages/core/src/components/barChartData.js +49 -29
  116. package/dist/packages/core/src/components/barChartTypes.js +8 -8
  117. package/dist/packages/core/src/components/tableTrackList.js +11 -11
  118. package/dist/packages/core/src/components/updateAlertStack.js +28 -28
  119. package/dist/packages/core/src/components/useBarChartControl.js +4 -6
  120. package/dist/packages/core/src/components/useComboboxSuggestions.js +17 -17
  121. package/dist/packages/core/src/components/useToastLifecycle.js +18 -18
  122. package/dist/packages/core/src/components/wordTableLayout.d.ts +17 -4
  123. package/dist/packages/core/src/components/wordTableLayout.js +5 -5
  124. package/dist/packages/core/src/context/I18nProvider.js +6 -6
  125. package/dist/packages/core/src/hooks/focusReturn.js +27 -27
  126. package/dist/packages/core/src/hooks/inputModality.js +13 -13
  127. package/dist/packages/core/src/hooks/touchToggle.js +39 -39
  128. package/dist/packages/core/src/hooks/useAnchoredMenu.js +30 -30
  129. package/dist/packages/core/src/hooks/useDailyTrainingSelection.js +28 -28
  130. package/dist/packages/core/src/hooks/useDocumentTitle.js +10 -10
  131. package/dist/packages/core/src/hooks/useEditableList.js +4 -4
  132. package/dist/packages/core/src/hooks/useFocusTrap.js +2 -2
  133. package/dist/packages/core/src/hooks/useFontScale.js +6 -6
  134. package/dist/packages/core/src/hooks/useIcon.js +7 -7
  135. package/dist/packages/core/src/hooks/useListControls.js +2 -2
  136. package/dist/packages/core/src/hooks/usePageResetOnChange.js +3 -3
  137. package/dist/packages/core/src/hooks/usePasswordChange.js +4 -4
  138. package/dist/packages/core/src/hooks/usePendingPress.js +7 -7
  139. package/dist/packages/core/src/hooks/useRelativeDay.js +4 -4
  140. package/dist/packages/core/src/hooks/useSoundCompassExam.js +6 -6
  141. package/dist/packages/core/src/hooks/useTablePaging.d.ts +0 -11
  142. package/dist/packages/core/src/hooks/useTablePaging.js +29 -34
  143. package/dist/packages/core/src/hooks/useTrainingSessionLog.js +35 -35
  144. package/dist/packages/core/src/hooks/useVisitSchedule.js +4 -4
  145. package/dist/packages/core/src/hooks/useWordAttributeFilter.js +14 -14
  146. package/dist/packages/core/src/hooks/useWordMeanings.js +5 -5
  147. package/dist/packages/core/src/hooks/useWordTrainingFilter.js +7 -7
  148. package/dist/packages/core/src/i18n/locales/en.json +14 -2
  149. package/dist/packages/core/src/i18n/locales/ko.json +13 -1
  150. package/dist/packages/core/src/types/wordSearch.d.ts +9 -0
  151. package/dist/packages/core/src/utils/audioMeter.js +5 -5
  152. package/dist/packages/core/src/utils/audioPeaks.d.ts +1 -1
  153. package/dist/packages/core/src/utils/audioPeaks.js +18 -18
  154. package/dist/packages/core/src/utils/blockGrid.js +4 -4
  155. package/dist/packages/core/src/utils/chunkSkew.js +9 -9
  156. package/dist/packages/core/src/utils/clipboard.js +3 -3
  157. package/dist/packages/core/src/utils/dailySelectionUtils.js +12 -12
  158. package/dist/packages/core/src/utils/date.js +12 -12
  159. package/dist/packages/core/src/utils/devWarn.js +4 -4
  160. package/dist/packages/core/src/utils/deviceKind.d.ts +37 -7
  161. package/dist/packages/core/src/utils/deviceKind.js +53 -10
  162. package/dist/packages/core/src/utils/errorMessage.js +7 -7
  163. package/dist/packages/core/src/utils/filterPanelSummary.js +14 -14
  164. package/dist/packages/core/src/utils/format.js +4 -4
  165. package/dist/packages/core/src/utils/getTrainingData.js +9 -9
  166. package/dist/packages/core/src/utils/imageConfig.js +17 -17
  167. package/dist/packages/core/src/utils/koreanSyllable.js +18 -18
  168. package/dist/packages/core/src/utils/navScroll.js +2 -2
  169. package/dist/packages/core/src/utils/phonemeConvert.d.ts +7 -0
  170. package/dist/packages/core/src/utils/phonemeConvert.js +19 -10
  171. package/dist/packages/core/src/utils/phonemeGroups.js +2 -2
  172. package/dist/packages/core/src/utils/phonemePairSearch.d.ts +1 -0
  173. package/dist/packages/core/src/utils/phonemePairSearch.js +129 -105
  174. package/dist/packages/core/src/utils/phonemePairSearchTypes.d.ts +2 -0
  175. package/dist/packages/core/src/utils/phonemeSectionCodes.d.ts +52 -0
  176. package/dist/packages/core/src/utils/phonemeSectionCodes.js +76 -0
  177. package/dist/packages/core/src/utils/prefetchChunk.js +6 -6
  178. package/dist/packages/core/src/utils/safeHref.js +4 -4
  179. package/dist/packages/core/src/utils/savedWordTables.js +5 -5
  180. package/dist/packages/core/src/utils/speak.js +12 -12
  181. package/dist/packages/core/src/utils/textSort.d.ts +0 -10
  182. package/dist/packages/core/src/utils/textSort.js +38 -48
  183. package/dist/packages/core/src/utils/theme.js +3 -3
  184. package/dist/packages/core/src/utils/trainingItemResults.js +3 -3
  185. package/dist/packages/core/src/utils/ttsConfig.js +2 -2
  186. package/dist/packages/core/src/utils/wordAttributeFilterCodes.d.ts +1 -1
  187. package/dist/packages/core/src/utils/wordAttributeFilterCodes.js +65 -45
  188. package/dist/packages/core/src/utils/wordContrast.js +3 -3
  189. package/dist/packages/core/src/utils/wordPairIndex.js +4 -4
  190. package/dist/packages/core/src/utils/wordTrainingGenerators.js +4 -4
  191. package/dist/packages/core/src/utils/wordTrainingPool.js +15 -15
  192. package/dist/packages/core/src/utils/wordTrainingRuntime.js +6 -6
  193. package/dist/packages/core/src/utils/wornDate.d.ts +3 -3
  194. package/dist/packages/core/src/utils/wornDate.js +14 -14
  195. package/dist/packages/core/src/version.d.ts +1 -1
  196. package/dist/packages/core/src/version.js +1 -1
  197. package/dist/utils.cjs.js +4 -4
  198. package/package.json +1 -1
@@ -417,12 +417,12 @@ async function _buildUsablePool(opts) {
417
417
  let posContrastMap = null;
418
418
  if (posContrast) {
419
419
  const mapKey = _posContrastCacheKey(opts);
420
- const 이미지집합 = excludeNoImage ? getImageOkWordSet() : null;
421
- const 전 = _posContrastCache.get(mapKey);
422
- posContrastMap = 전 && 전.이미지집합 === 이미지집합
423
- ? 전.map
420
+ const imageOkSet = excludeNoImage ? getImageOkWordSet() : null;
421
+ const cached = _posContrastCache.get(mapKey);
422
+ posContrastMap = cached && cached.imageOkSet === imageOkSet
423
+ ? cached.map
424
424
  : buildMultiPartPosContrast(composition, allOkArr, decompOf, sameStructureOnly, phonemeView, pronOfWord);
425
- _posContrastCache.set(mapKey, { 이미지집합, map: posContrastMap });
425
+ _posContrastCache.set(mapKey, { imageOkSet, map: posContrastMap });
426
426
  }
427
427
  // candidates 크기 제한 — 이미지 필터 이후이므로 okCandidates 기반
428
428
  const RANDOM_CAND_CAP = 500; // random: classifyPairDifficulty 없으나 루프 자체 제한
@@ -471,28 +471,28 @@ async function _buildUsablePool(opts) {
471
471
  else if (useRandomPool) {
472
472
  // 'random' 또는 null(difficulty:false 타입): 음운론적 제약은 없지만,
473
473
  // 정답과 오답의 음절수는 같아야 한다(단어 길이만으로 정답을 짐작하지 못하도록) — 본 단어와 다른 단어 + 음절수(글자수) 동일
474
- const 쓸수있음 = (other) => other !== w.w && other.length === w.w.length && pronOfWord(other) !== wPron;
474
+ const canUse = (other) => other !== w.w && other.length === w.w.length && pronOfWord(other) !== wPron;
475
475
  /* 셈(fullCount — 가능 단어 수 안내)은 **서로 소리가 다른 오답이 보기 수 − 1 개** 있는지까지만 본다(countUsableWords 가 그
476
476
  기준으로 센다). 2.2만 후보마다 600개를 끝까지 걸러 칩 한 번에 300ms 넘게 멈췄다. */
477
477
  if (opts.fullCount) {
478
478
  const need = Math.max(1, (opts.choicesPerItem ?? 3) - 1);
479
- const 고름 = [];
480
- const 소리 = new Set();
479
+ const picked = [];
480
+ const prons = new Set();
481
481
  for (const other of distractorPool) {
482
- if (!쓸수있음(other))
482
+ if (!canUse(other))
483
483
  continue;
484
484
  const p = pronOfWord(other);
485
- if (소리.has(p))
485
+ if (prons.has(p))
486
486
  continue;
487
- 소리.add(p);
488
- 고름.push(other);
489
- if (고름.length >= need)
487
+ prons.add(p);
488
+ picked.push(other);
489
+ if (picked.length >= need)
490
490
  break;
491
491
  }
492
- usable = 고름;
492
+ usable = picked;
493
493
  }
494
494
  else
495
- usable = distractorPool.filter(쓸수있음);
495
+ usable = distractorPool.filter(canUse);
496
496
  }
497
497
  else {
498
498
  // cho/jung/jong: 발음 기반 pairIndex에서 해당 종류 대립쌍 조회(공용 엔진). 구조 필터는 후처리에서 일괄.
@@ -73,10 +73,10 @@ async function genIncluded(opts) {
73
73
  const syllables = [...pron]; // 한 글자 = 한 음절
74
74
  /* 음소를 골랐으면 **그 음소를 가진 음절**을 들려준다 — 전에는 아무 음절이나 골라 초성 ㄱ 을 골라도 '가방' 의 '방' 을
75
75
  들려주었다(고른 음소와 무관한 훈련). 들리는 음절(발음)에 그 음소가 없으면 전처럼 아무 음절. */
76
- const 고른음절 = comp && primarySelPart(comp)
76
+ const pickedPart = comp && primarySelPart(comp)
77
77
  ? syllables.filter(s => { const p = parseSyllable(s); return !!p && syllMatchesComp(p, comp); })
78
78
  : [];
79
- const targetSyllable = pickOne(고른음절.length ? 고른음절 : syllables);
79
+ const targetSyllable = pickOne(pickedPart.length ? pickedPart : syllables);
80
80
  if (!targetSyllable)
81
81
  continue;
82
82
  // 오답: targetSyllable이 발음에 포함되지 않고, 정답과 음절수(글자수)가 같으며, 발음이 다른 단어.
@@ -357,7 +357,7 @@ async function genMerge3Syll(opts) {
357
357
  }
358
358
  /* 탈락 문제의 '실단어' 집합 — '이미지 있는 단어만' 이면 이미지 있는 낱말로. 전에는 늘 전체 낱말이라, 이미지만 켠(앱 기본) 탈락 카드의
359
359
  정답·오답이 이미지 없는 낱말(관상 → 상·땅·탕)로 나와 글자를 숨긴 카드가 빈칸이 됐다. 음절 바꾸기와 같은 방식. */
360
- function 탈락낱말집합(opts) {
360
+ function droppedWordSet(opts) {
361
361
  const all = MVP.map(w => w.w);
362
362
  return opts.excludeNoImage ? filterByCachedImage(all) : new Set(all);
363
363
  }
@@ -368,7 +368,7 @@ async function genDrop1From2Syll(opts) {
368
368
  // 편집기와 동일한 대립쌍 오답을 item에 심는다(공유 코어 buildDropContrastProblem).
369
369
  // 러너(WordManipulationTrainingPagePopup)가 preset distractors를 그대로 쓰므로 자동생성도 편집기 품질이 된다.
370
370
  const pronMap = getPronMap();
371
- const wordSet = 탈락낱말집합(opts);
371
+ const wordSet = droppedWordSet(opts);
372
372
  const phonemeView = opts.phonemeView ?? 'char';
373
373
  const out = [];
374
374
  for (const e of shuffle(pool)) {
@@ -398,7 +398,7 @@ async function genDrop1From3Syll(opts) {
398
398
  const pool = (await buildUsablePool({ ...opts })).filter(e => e.word.s === 3);
399
399
  // 편집기와 동일한 대립쌍 오답을 item에 심는다(공유 코어 buildDropContrast3Problem).
400
400
  const pronMap = getPronMap();
401
- const wordSet = 탈락낱말집합(opts);
401
+ const wordSet = droppedWordSet(opts);
402
402
  const phonemeView = opts.phonemeView ?? 'char';
403
403
  const out = [];
404
404
  for (const e of shuffle(pool)) {
@@ -436,7 +436,7 @@ async function genDropCompound(opts) {
436
436
  // 2음절 낱말은 1음절 조각 둘로만 나뉘어 합성어가 될 수 없다(buildDropCompoundProblem) — 3음절부터
437
437
  const pool = (await buildUsablePool({ ...opts })).filter(e => e.word.s >= 3);
438
438
  const pronMap = getPronMap();
439
- const wordSet = 탈락낱말집합(opts);
439
+ const wordSet = droppedWordSet(opts);
440
440
  const phonemeView = opts.phonemeView ?? 'char';
441
441
  const out = [];
442
442
  for (const e of shuffle(pool)) {
@@ -4,7 +4,7 @@
4
4
  * 타입은 문자열이지만 서버에서는 **월·일이 null 로 오기도 한다**(연도만 적은 옛 기록). 그대로 끼우면 화면에
5
5
  * `2026.null.null` 이 찍혔고, 정렬 열쇠를 만들 때는 `null.padStart` 에서 표가 통째로 터졌다. 빈 값은 '' 로 다룬다.
6
6
  */
7
- type 칸값 = string | number | null | undefined;
7
+ type CellValue = string | number | null | undefined;
8
8
  /**
9
9
  * 화면에 적을 착용일.
10
10
  *
@@ -18,7 +18,7 @@ type 칸값 = string | number | null | undefined;
18
18
  * `lang` 을 안 주면 **예전 그대로** 점 꼴이다(`2026.09.09`) — 부르는 자리가 말을 모르는 곳도 있을
19
19
  * 수 있어 깨지지 않게 둔다. 화면에 그리는 자리는 주는 쪽이 맞다.
20
20
  */
21
- export declare function formatWornDate(year: 칸값, month: 칸값, day: 칸값, lang?: string): string;
21
+ export declare function formatWornDate(year: CellValue, month: CellValue, day: CellValue, lang?: string): string;
22
22
  /** 착용일 정렬 열쇠 — 자리수를 채워(`2026-05-02`) 글자 비교가 날짜 차례와 같게. 연도가 없으면 ''. */
23
- export declare function wornDateSortKey(year: 칸값, month: 칸값, day: 칸값): string;
23
+ export declare function wornDateSortKey(year: CellValue, month: CellValue, day: CellValue): string;
24
24
  export {};
@@ -1,5 +1,5 @@
1
1
  import { formatDateLocale } from './date';
2
- const 글자 = (v) => (v == null ? '' : String(v).trim());
2
+ const text = (v) => (v == null ? '' : String(v).trim());
3
3
  /**
4
4
  * 화면에 적을 착용일.
5
5
  *
@@ -14,7 +14,7 @@ const 글자 = (v) => (v == null ? '' : String(v).trim());
14
14
  * 수 있어 깨지지 않게 둔다. 화면에 그리는 자리는 주는 쪽이 맞다.
15
15
  */
16
16
  export function formatWornDate(year, month, day, lang) {
17
- const y = 글자(year), m = 글자(month), d = 글자(day);
17
+ const y = text(year), m = text(month), d = text(day);
18
18
  if (lang && y && m && d) {
19
19
  /* 자리수를 채워 ISO 로 만든다 — `formatDateLocale` 이 읽는 꼴. */
20
20
  const iso = `${y.padStart(4, '0')}-${m.padStart(2, '0')}-${d.padStart(2, '0')}`;
@@ -28,23 +28,23 @@ export function formatWornDate(year, month, day, lang) {
28
28
  * *이 가름은 못이 안 울어서 찾았다* — `&& m && d` 조건만 깨뜨려 봤을 때는 조용했다(그때는
29
29
  * `2026-00-00` 이 **못 읽는 날짜**라 저절로 떨어졌다). 못이 안 울면 **무엇이 막고 있나**를 묻는다.
30
30
  */
31
- const 날 = new Date(iso);
32
- const 되돌아옴 = !Number.isNaN(날.getTime()) && 날.toISOString().slice(0, 10) === iso;
33
- if (되돌아옴) {
34
- const 말대로 = formatDateLocale(iso, lang);
35
- if (말대로)
36
- return 말대로;
31
+ const date = new Date(iso);
32
+ const roundTrips = !Number.isNaN(date.getTime()) && date.toISOString().slice(0, 10) === iso;
33
+ if (roundTrips) {
34
+ const localized = formatDateLocale(iso, lang);
35
+ if (localized)
36
+ return localized;
37
37
  }
38
38
  }
39
- const 조각 = [y, m, d];
40
- while (조각.length > 0 && 조각[조각.length - 1] === '')
41
- 조각.pop();
42
- return 조각.join('.');
39
+ const parts = [y, m, d];
40
+ while (parts.length > 0 && parts[parts.length - 1] === '')
41
+ parts.pop();
42
+ return parts.join('.');
43
43
  }
44
44
  /** 착용일 정렬 열쇠 — 자리수를 채워(`2026-05-02`) 글자 비교가 날짜 차례와 같게. 연도가 없으면 ''. */
45
45
  export function wornDateSortKey(year, month, day) {
46
- const y = 글자(year);
46
+ const y = text(year);
47
47
  if (!y)
48
48
  return '';
49
- return `${y}-${글자(month).padStart(2, '0')}-${글자(day).padStart(2, '0')}`;
49
+ return `${y}-${text(month).padStart(2, '0')}-${text(day).padStart(2, '0')}`;
50
50
  }
@@ -46,4 +46,4 @@
46
46
  *
47
47
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
48
48
  */
49
- export declare const CORE_VERSION = "0.322.0";
49
+ export declare const CORE_VERSION = "0.324.0";
@@ -46,4 +46,4 @@
46
46
  *
47
47
  * 값은 손으로 적고 `test/coreVersion.test.ts` 가 package.json 과 어긋나면 운다.
48
48
  */
49
- export const CORE_VERSION = '0.322.0';
49
+ export const CORE_VERSION = '0.324.0';