oh-my-oop 0.2.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 (660) hide show
  1. package/MCP_STRUCTURE.md +301 -0
  2. package/README.md +167 -0
  3. package/SCOPE.md +27 -0
  4. package/dist/application/discovery.d.ts +133 -0
  5. package/dist/application/discovery.js +62 -0
  6. package/dist/application/discovery.js.map +1 -0
  7. package/dist/cli.d.ts +2 -0
  8. package/dist/cli.js +80 -0
  9. package/dist/cli.js.map +1 -0
  10. package/dist/config.d.ts +16 -0
  11. package/dist/config.js +32 -0
  12. package/dist/config.js.map +1 -0
  13. package/dist/domain/collaborators.d.ts +2 -0
  14. package/dist/domain/collaborators.js +26 -0
  15. package/dist/domain/collaborators.js.map +1 -0
  16. package/dist/domain/ids.d.ts +4 -0
  17. package/dist/domain/ids.js +23 -0
  18. package/dist/domain/ids.js.map +1 -0
  19. package/dist/domain/model.d.ts +71 -0
  20. package/dist/domain/model.js +2 -0
  21. package/dist/domain/model.js.map +1 -0
  22. package/dist/domain/schemas.d.ts +213 -0
  23. package/dist/domain/schemas.js +79 -0
  24. package/dist/domain/schemas.js.map +1 -0
  25. package/dist/domain/stereotypes.d.ts +7 -0
  26. package/dist/domain/stereotypes.js +65 -0
  27. package/dist/domain/stereotypes.js.map +1 -0
  28. package/dist/index.d.ts +2 -0
  29. package/dist/index.js +21 -0
  30. package/dist/index.js.map +1 -0
  31. package/dist/io/classStore.d.ts +9 -0
  32. package/dist/io/classStore.js +39 -0
  33. package/dist/io/classStore.js.map +1 -0
  34. package/dist/io/collaborationStore.d.ts +7 -0
  35. package/dist/io/collaborationStore.js +32 -0
  36. package/dist/io/collaborationStore.js.map +1 -0
  37. package/dist/io/design.d.ts +3 -0
  38. package/dist/io/design.js +22 -0
  39. package/dist/io/design.js.map +1 -0
  40. package/dist/io/designIndex.d.ts +6 -0
  41. package/dist/io/designIndex.js +49 -0
  42. package/dist/io/designIndex.js.map +1 -0
  43. package/dist/io/frontmatter.d.ts +8 -0
  44. package/dist/io/frontmatter.js +31 -0
  45. package/dist/io/frontmatter.js.map +1 -0
  46. package/dist/io/history.d.ts +10 -0
  47. package/dist/io/history.js +38 -0
  48. package/dist/io/history.js.map +1 -0
  49. package/dist/io/useCaseStore.d.ts +8 -0
  50. package/dist/io/useCaseStore.js +36 -0
  51. package/dist/io/useCaseStore.js.map +1 -0
  52. package/dist/io/workspace.d.ts +14 -0
  53. package/dist/io/workspace.js +82 -0
  54. package/dist/io/workspace.js.map +1 -0
  55. package/dist/oop/commands.d.ts +446 -0
  56. package/dist/oop/commands.js +319 -0
  57. package/dist/oop/commands.js.map +1 -0
  58. package/dist/oop/conformance.d.ts +16 -0
  59. package/dist/oop/conformance.js +30 -0
  60. package/dist/oop/conformance.js.map +1 -0
  61. package/dist/prompts/discovery.d.ts +2 -0
  62. package/dist/prompts/discovery.js +41 -0
  63. package/dist/prompts/discovery.js.map +1 -0
  64. package/dist/prompts/imagineWithoutController.d.ts +2 -0
  65. package/dist/prompts/imagineWithoutController.js +75 -0
  66. package/dist/prompts/imagineWithoutController.js.map +1 -0
  67. package/dist/prompts/index.d.ts +2 -0
  68. package/dist/prompts/index.js +17 -0
  69. package/dist/prompts/index.js.map +1 -0
  70. package/dist/prompts/phasePressureTest.d.ts +2 -0
  71. package/dist/prompts/phasePressureTest.js +69 -0
  72. package/dist/prompts/phasePressureTest.js.map +1 -0
  73. package/dist/prompts/rddIntro.d.ts +2 -0
  74. package/dist/prompts/rddIntro.js +53 -0
  75. package/dist/prompts/rddIntro.js.map +1 -0
  76. package/dist/prompts/review.d.ts +2 -0
  77. package/dist/prompts/review.js +45 -0
  78. package/dist/prompts/review.js.map +1 -0
  79. package/dist/prompts/stateMachineIntrospect.d.ts +2 -0
  80. package/dist/prompts/stateMachineIntrospect.js +80 -0
  81. package/dist/prompts/stateMachineIntrospect.js.map +1 -0
  82. package/dist/prompts/tellDontAskRephrase.d.ts +2 -0
  83. package/dist/prompts/tellDontAskRephrase.js +66 -0
  84. package/dist/prompts/tellDontAskRephrase.js.map +1 -0
  85. package/dist/render/diff.d.ts +21 -0
  86. package/dist/render/diff.js +84 -0
  87. package/dist/render/diff.js.map +1 -0
  88. package/dist/render/mermaid.d.ts +24 -0
  89. package/dist/render/mermaid.js +53 -0
  90. package/dist/render/mermaid.js.map +1 -0
  91. package/dist/render/sideBySide.d.ts +14 -0
  92. package/dist/render/sideBySide.js +91 -0
  93. package/dist/render/sideBySide.js.map +1 -0
  94. package/dist/resources/index.d.ts +2 -0
  95. package/dist/resources/index.js +349 -0
  96. package/dist/resources/index.js.map +1 -0
  97. package/dist/server.d.ts +2 -0
  98. package/dist/server.js +22 -0
  99. package/dist/server.js.map +1 -0
  100. package/dist/tools/alternatives.d.ts +2 -0
  101. package/dist/tools/alternatives.js +9 -0
  102. package/dist/tools/alternatives.js.map +1 -0
  103. package/dist/tools/classes.d.ts +2 -0
  104. package/dist/tools/classes.js +13 -0
  105. package/dist/tools/classes.js.map +1 -0
  106. package/dist/tools/collaborations.d.ts +2 -0
  107. package/dist/tools/collaborations.js +8 -0
  108. package/dist/tools/collaborations.js.map +1 -0
  109. package/dist/tools/compare.d.ts +2 -0
  110. package/dist/tools/compare.js +9 -0
  111. package/dist/tools/compare.js.map +1 -0
  112. package/dist/tools/conformance.d.ts +3 -0
  113. package/dist/tools/conformance.js +11 -0
  114. package/dist/tools/conformance.js.map +1 -0
  115. package/dist/tools/diagram.d.ts +2 -0
  116. package/dist/tools/diagram.js +9 -0
  117. package/dist/tools/diagram.js.map +1 -0
  118. package/dist/tools/discovery.d.ts +2 -0
  119. package/dist/tools/discovery.js +23 -0
  120. package/dist/tools/discovery.js.map +1 -0
  121. package/dist/tools/index.d.ts +2 -0
  122. package/dist/tools/index.js +27 -0
  123. package/dist/tools/index.js.map +1 -0
  124. package/dist/tools/init.d.ts +2 -0
  125. package/dist/tools/init.js +9 -0
  126. package/dist/tools/init.js.map +1 -0
  127. package/dist/tools/oop.d.ts +9 -0
  128. package/dist/tools/oop.js +26 -0
  129. package/dist/tools/oop.js.map +1 -0
  130. package/dist/tools/responsibilities.d.ts +2 -0
  131. package/dist/tools/responsibilities.js +13 -0
  132. package/dist/tools/responsibilities.js.map +1 -0
  133. package/dist/tools/state.d.ts +2 -0
  134. package/dist/tools/state.js +8 -0
  135. package/dist/tools/state.js.map +1 -0
  136. package/dist/tools/useCases.d.ts +2 -0
  137. package/dist/tools/useCases.js +18 -0
  138. package/dist/tools/useCases.js.map +1 -0
  139. package/dist/tools/validate.d.ts +2 -0
  140. package/dist/tools/validate.js +9 -0
  141. package/dist/tools/validate.js.map +1 -0
  142. package/dist/tradeoff/engine.d.ts +61 -0
  143. package/dist/tradeoff/engine.js +171 -0
  144. package/dist/tradeoff/engine.js.map +1 -0
  145. package/dist/tradeoff/heuristics/classSplit.d.ts +3 -0
  146. package/dist/tradeoff/heuristics/classSplit.js +94 -0
  147. package/dist/tradeoff/heuristics/classSplit.js.map +1 -0
  148. package/dist/tradeoff/heuristics/collaborationShape.d.ts +2 -0
  149. package/dist/tradeoff/heuristics/collaborationShape.js +82 -0
  150. package/dist/tradeoff/heuristics/collaborationShape.js.map +1 -0
  151. package/dist/tradeoff/heuristics/collectionShape.d.ts +2 -0
  152. package/dist/tradeoff/heuristics/collectionShape.js +113 -0
  153. package/dist/tradeoff/heuristics/collectionShape.js.map +1 -0
  154. package/dist/tradeoff/heuristics/dualSubjectComparison.d.ts +2 -0
  155. package/dist/tradeoff/heuristics/dualSubjectComparison.js +114 -0
  156. package/dist/tradeoff/heuristics/dualSubjectComparison.js.map +1 -0
  157. package/dist/tradeoff/heuristics/errorHandling.d.ts +2 -0
  158. package/dist/tradeoff/heuristics/errorHandling.js +110 -0
  159. package/dist/tradeoff/heuristics/errorHandling.js.map +1 -0
  160. package/dist/tradeoff/heuristics/responsibilitySplit.d.ts +23 -0
  161. package/dist/tradeoff/heuristics/responsibilitySplit.js +183 -0
  162. package/dist/tradeoff/heuristics/responsibilitySplit.js.map +1 -0
  163. package/dist/tradeoff/heuristics/stereotypeChoice.d.ts +2 -0
  164. package/dist/tradeoff/heuristics/stereotypeChoice.js +23 -0
  165. package/dist/tradeoff/heuristics/stereotypeChoice.js.map +1 -0
  166. package/dist/tradeoff/heuristics/strategyOrPolicy.d.ts +2 -0
  167. package/dist/tradeoff/heuristics/strategyOrPolicy.js +110 -0
  168. package/dist/tradeoff/heuristics/strategyOrPolicy.js.map +1 -0
  169. package/dist/tradeoff/heuristics/valueObjectShape.d.ts +2 -0
  170. package/dist/tradeoff/heuristics/valueObjectShape.js +111 -0
  171. package/dist/tradeoff/heuristics/valueObjectShape.js.map +1 -0
  172. package/dist/tradeoff/templates.d.ts +2 -0
  173. package/dist/tradeoff/templates.js +33 -0
  174. package/dist/tradeoff/templates.js.map +1 -0
  175. package/dist/util/log.d.ts +1 -0
  176. package/dist/util/log.js +7 -0
  177. package/dist/util/log.js.map +1 -0
  178. package/dist/util/mcp.d.ts +4 -0
  179. package/dist/util/mcp.js +18 -0
  180. package/dist/util/mcp.js.map +1 -0
  181. package/dist/validate/cohesion.d.ts +3 -0
  182. package/dist/validate/cohesion.js +88 -0
  183. package/dist/validate/cohesion.js.map +1 -0
  184. package/dist/validate/collectionWrapper.d.ts +3 -0
  185. package/dist/validate/collectionWrapper.js +131 -0
  186. package/dist/validate/collectionWrapper.js.map +1 -0
  187. package/dist/validate/coupling.d.ts +3 -0
  188. package/dist/validate/coupling.js +47 -0
  189. package/dist/validate/coupling.js.map +1 -0
  190. package/dist/validate/cycle.d.ts +3 -0
  191. package/dist/validate/cycle.js +101 -0
  192. package/dist/validate/cycle.js.map +1 -0
  193. package/dist/validate/dataDuplication.d.ts +3 -0
  194. package/dist/validate/dataDuplication.js +150 -0
  195. package/dist/validate/dataDuplication.js.map +1 -0
  196. package/dist/validate/dependencyDirection.d.ts +3 -0
  197. package/dist/validate/dependencyDirection.js +106 -0
  198. package/dist/validate/dependencyDirection.js.map +1 -0
  199. package/dist/validate/dualUseKnowing.d.ts +3 -0
  200. package/dist/validate/dualUseKnowing.js +137 -0
  201. package/dist/validate/dualUseKnowing.js.map +1 -0
  202. package/dist/validate/emptyObjectFill.d.ts +3 -0
  203. package/dist/validate/emptyObjectFill.js +119 -0
  204. package/dist/validate/emptyObjectFill.js.map +1 -0
  205. package/dist/validate/findings.d.ts +22 -0
  206. package/dist/validate/findings.js +12 -0
  207. package/dist/validate/findings.js.map +1 -0
  208. package/dist/validate/functionDecompositionExcess.d.ts +3 -0
  209. package/dist/validate/functionDecompositionExcess.js +120 -0
  210. package/dist/validate/functionDecompositionExcess.js.map +1 -0
  211. package/dist/validate/functionNotObject.d.ts +3 -0
  212. package/dist/validate/functionNotObject.js +80 -0
  213. package/dist/validate/functionNotObject.js.map +1 -0
  214. package/dist/validate/godObject.d.ts +6 -0
  215. package/dist/validate/godObject.js +76 -0
  216. package/dist/validate/godObject.js.map +1 -0
  217. package/dist/validate/presentationInDomain.d.ts +3 -0
  218. package/dist/validate/presentationInDomain.js +57 -0
  219. package/dist/validate/presentationInDomain.js.map +1 -0
  220. package/dist/validate/primitiveWrapper.d.ts +3 -0
  221. package/dist/validate/primitiveWrapper.js +106 -0
  222. package/dist/validate/primitiveWrapper.js.map +1 -0
  223. package/dist/validate/rules.d.ts +24 -0
  224. package/dist/validate/rules.js +269 -0
  225. package/dist/validate/rules.js.map +1 -0
  226. package/dist/validate/singletonStatefulHolder.d.ts +3 -0
  227. package/dist/validate/singletonStatefulHolder.js +128 -0
  228. package/dist/validate/singletonStatefulHolder.js.map +1 -0
  229. package/dist/validate/strategyAsymmetry.d.ts +3 -0
  230. package/dist/validate/strategyAsymmetry.js +131 -0
  231. package/dist/validate/strategyAsymmetry.js.map +1 -0
  232. package/dist/validate/testability.d.ts +5 -0
  233. package/dist/validate/testability.js +157 -0
  234. package/dist/validate/testability.js.map +1 -0
  235. package/dist/validate/vagueName.d.ts +3 -0
  236. package/dist/validate/vagueName.js +136 -0
  237. package/dist/validate/vagueName.js.map +1 -0
  238. package/dist/validate/validationLocation.d.ts +3 -0
  239. package/dist/validate/validationLocation.js +120 -0
  240. package/dist/validate/validationLocation.js.map +1 -0
  241. package/lessons/STYLE_GUIDE.md +304 -0
  242. package/lessons/woowacourse-kotlin-blackjack/2chang5/33-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +293 -0
  243. package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/52-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +106 -0
  244. package/lessons/woowacourse-kotlin-blackjack/Choisehyeon/9-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
  245. package/lessons/woowacourse-kotlin-blackjack/DYGames/14-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +182 -0
  246. package/lessons/woowacourse-kotlin-blackjack/DYGames/37-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +122 -0
  247. package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/12-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +117 -0
  248. package/lessons/woowacourse-kotlin-blackjack/EmilyCh0/38-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +291 -0
  249. package/lessons/woowacourse-kotlin-blackjack/HANDOVER.md +1475 -0
  250. package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/119-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +251 -0
  251. package/lessons/woowacourse-kotlin-blackjack/HamBeomJoon/137-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +459 -0
  252. package/lessons/woowacourse-kotlin-blackjack/Hevton/100-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +282 -0
  253. package/lessons/woowacourse-kotlin-blackjack/Hevton/82-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +303 -0
  254. package/lessons/woowacourse-kotlin-blackjack/Hogu59/71-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +134 -0
  255. package/lessons/woowacourse-kotlin-blackjack/Hogu59/96-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +323 -0
  256. package/lessons/woowacourse-kotlin-blackjack/JoYehyun99/66-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +210 -0
  257. package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/101-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +191 -0
  258. package/lessons/woowacourse-kotlin-blackjack/Junyoung-WON/80-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
  259. package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/108-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +516 -0
  260. package/lessons/woowacourse-kotlin-blackjack/Leeyerin0210/133-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +541 -0
  261. package/lessons/woowacourse-kotlin-blackjack/RightHennessy/22-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
  262. package/lessons/woowacourse-kotlin-blackjack/RightHennessy/48-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
  263. package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/16-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +228 -0
  264. package/lessons/woowacourse-kotlin-blackjack/SeongHoonC/54-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +227 -0
  265. package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/76-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
  266. package/lessons/woowacourse-kotlin-blackjack/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +203 -0
  267. package/lessons/woowacourse-kotlin-blackjack/aprilgom/105-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +162 -0
  268. package/lessons/woowacourse-kotlin-blackjack/aprilgom/64-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
  269. package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/18-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
  270. package/lessons/woowacourse-kotlin-blackjack/boogi-woogi/36-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +769 -0
  271. package/lessons/woowacourse-kotlin-blackjack/briandr97/19-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +226 -0
  272. package/lessons/woowacourse-kotlin-blackjack/briandr97/59-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +193 -0
  273. package/lessons/woowacourse-kotlin-blackjack/chaehyuns/70-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
  274. package/lessons/woowacourse-kotlin-blackjack/chaehyuns/98-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
  275. package/lessons/woowacourse-kotlin-blackjack/chanho0908/123-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +277 -0
  276. package/lessons/woowacourse-kotlin-blackjack/chanho0908/150-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
  277. package/lessons/woowacourse-kotlin-blackjack/chws0508/26-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +259 -0
  278. package/lessons/woowacourse-kotlin-blackjack/chws0508/43-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +189 -0
  279. package/lessons/woowacourse-kotlin-blackjack/cucumber99/109-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +351 -0
  280. package/lessons/woowacourse-kotlin-blackjack/cucumber99/149-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +147 -0
  281. package/lessons/woowacourse-kotlin-blackjack/devfeijoa/121-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +168 -0
  282. package/lessons/woowacourse-kotlin-blackjack/devfeijoa/153-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +116 -0
  283. package/lessons/woowacourse-kotlin-blackjack/doabletuple/126-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +680 -0
  284. package/lessons/woowacourse-kotlin-blackjack/doabletuple/142-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +739 -0
  285. package/lessons/woowacourse-kotlin-blackjack/donghyun81/116-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
  286. package/lessons/woowacourse-kotlin-blackjack/donghyun81/147-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +244 -0
  287. package/lessons/woowacourse-kotlin-blackjack/dpcks0509/78-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +232 -0
  288. package/lessons/woowacourse-kotlin-blackjack/dpcks0509/88-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +137 -0
  289. package/lessons/woowacourse-kotlin-blackjack/etama123/112-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
  290. package/lessons/woowacourse-kotlin-blackjack/etama123/148-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +240 -0
  291. package/lessons/woowacourse-kotlin-blackjack/gaeun5744/102-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +146 -0
  292. package/lessons/woowacourse-kotlin-blackjack/gaeun5744/69-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
  293. package/lessons/woowacourse-kotlin-blackjack/gahyunkim/118-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +397 -0
  294. package/lessons/woowacourse-kotlin-blackjack/gahyunkim/141-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +215 -0
  295. package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/106-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +395 -0
  296. package/lessons/woowacourse-kotlin-blackjack/giovannijunseokim/134-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +219 -0
  297. package/lessons/woowacourse-kotlin-blackjack/haeum808/62-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +230 -0
  298. package/lessons/woowacourse-kotlin-blackjack/haeum808/89-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +169 -0
  299. package/lessons/woowacourse-kotlin-blackjack/hwannow/110-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
  300. package/lessons/woowacourse-kotlin-blackjack/hwannow/132-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +573 -0
  301. package/lessons/woowacourse-kotlin-blackjack/hxeyexn/103-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +188 -0
  302. package/lessons/woowacourse-kotlin-blackjack/hxeyexn/81-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +301 -0
  303. package/lessons/woowacourse-kotlin-blackjack/hyemdooly/21-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +613 -0
  304. package/lessons/woowacourse-kotlin-blackjack/hyemdooly/35-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +691 -0
  305. package/lessons/woowacourse-kotlin-blackjack/hyunji1203/13-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +206 -0
  306. package/lessons/woowacourse-kotlin-blackjack/ii2001/79-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +153 -0
  307. package/lessons/woowacourse-kotlin-blackjack/ii2001/85-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +318 -0
  308. package/lessons/woowacourse-kotlin-blackjack/ijh1298/128-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
  309. package/lessons/woowacourse-kotlin-blackjack/ijh1298/135-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +269 -0
  310. package/lessons/woowacourse-kotlin-blackjack/inseonyun/28-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +346 -0
  311. package/lessons/woowacourse-kotlin-blackjack/inseonyun/49-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +360 -0
  312. package/lessons/woowacourse-kotlin-blackjack/ippnsj/30-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +152 -0
  313. package/lessons/woowacourse-kotlin-blackjack/ippnsj/42-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +213 -0
  314. package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/73-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +247 -0
  315. package/lessons/woowacourse-kotlin-blackjack/jaeyeongjo/87-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +900 -0
  316. package/lessons/woowacourse-kotlin-blackjack/jerry8282/125-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +248 -0
  317. package/lessons/woowacourse-kotlin-blackjack/jerry8282/151-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +243 -0
  318. package/lessons/woowacourse-kotlin-blackjack/jinuemong/63-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +281 -0
  319. package/lessons/woowacourse-kotlin-blackjack/jinuemong/92-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +283 -0
  320. package/lessons/woowacourse-kotlin-blackjack/jiyuneel/113-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +348 -0
  321. package/lessons/woowacourse-kotlin-blackjack/jiyuneel/140-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
  322. package/lessons/woowacourse-kotlin-blackjack/junjange/61-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +270 -0
  323. package/lessons/woowacourse-kotlin-blackjack/junjange/93-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +465 -0
  324. package/lessons/woowacourse-kotlin-blackjack/junseo511/107-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +296 -0
  325. package/lessons/woowacourse-kotlin-blackjack/junseo511/145-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +316 -0
  326. package/lessons/woowacourse-kotlin-blackjack/ki960213/11-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +175 -0
  327. package/lessons/woowacourse-kotlin-blackjack/kimhm0728/72-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +458 -0
  328. package/lessons/woowacourse-kotlin-blackjack/kimhm0728/97-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +225 -0
  329. package/lessons/woowacourse-kotlin-blackjack/kkosang/68-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +221 -0
  330. package/lessons/woowacourse-kotlin-blackjack/kkosang/94-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +158 -0
  331. package/lessons/woowacourse-kotlin-blackjack/kmkim2689/65-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +252 -0
  332. package/lessons/woowacourse-kotlin-blackjack/kmkim2689/90-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +460 -0
  333. package/lessons/woowacourse-kotlin-blackjack/krrong/32-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
  334. package/lessons/woowacourse-kotlin-blackjack/krrong/46-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +285 -0
  335. package/lessons/woowacourse-kotlin-blackjack/m6z1/122-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +177 -0
  336. package/lessons/woowacourse-kotlin-blackjack/m6z1/144-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +155 -0
  337. package/lessons/woowacourse-kotlin-blackjack/medAndro/130-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
  338. package/lessons/woowacourse-kotlin-blackjack/medAndro/143-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +678 -0
  339. package/lessons/woowacourse-kotlin-blackjack/moondev03/114-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +262 -0
  340. package/lessons/woowacourse-kotlin-blackjack/moondev03/131-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +498 -0
  341. package/lessons/woowacourse-kotlin-blackjack/murjune/77-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +287 -0
  342. package/lessons/woowacourse-kotlin-blackjack/murjune/91-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +280 -0
  343. package/lessons/woowacourse-kotlin-blackjack/no1msh/31-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +250 -0
  344. package/lessons/woowacourse-kotlin-blackjack/otter66/24-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +302 -0
  345. package/lessons/woowacourse-kotlin-blackjack/otter66/58-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +391 -0
  346. package/lessons/woowacourse-kotlin-blackjack/oungsi2000/111-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
  347. package/lessons/woowacourse-kotlin-blackjack/oungsi2000/136-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +540 -0
  348. package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/117-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +819 -0
  349. package/lessons/woowacourse-kotlin-blackjack/parkjiminnnn/139-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +683 -0
  350. package/lessons/woowacourse-kotlin-blackjack/pingu244/20-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +258 -0
  351. package/lessons/woowacourse-kotlin-blackjack/pingu244/41-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +171 -0
  352. package/lessons/woowacourse-kotlin-blackjack/re4rk/34-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +289 -0
  353. package/lessons/woowacourse-kotlin-blackjack/re4rk/8-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +297 -0
  354. package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/17-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +279 -0
  355. package/lessons/woowacourse-kotlin-blackjack/rhkrwngud445/50-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +145 -0
  356. package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/23-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +253 -0
  357. package/lessons/woowacourse-kotlin-blackjack/rhthrhrl0/39-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
  358. package/lessons/woowacourse-kotlin-blackjack/rosemin928/129-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +726 -0
  359. package/lessons/woowacourse-kotlin-blackjack/rosemin928/138-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +845 -0
  360. package/lessons/woowacourse-kotlin-blackjack/s6m1n/67-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +220 -0
  361. package/lessons/woowacourse-kotlin-blackjack/s6m1n/99-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +229 -0
  362. package/lessons/woowacourse-kotlin-blackjack/s9hn/10-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +284 -0
  363. package/lessons/woowacourse-kotlin-blackjack/sh1mj1/75-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +224 -0
  364. package/lessons/woowacourse-kotlin-blackjack/songpink/74-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +238 -0
  365. package/lessons/woowacourse-kotlin-blackjack/songpink/95-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +216 -0
  366. package/lessons/woowacourse-kotlin-blackjack/sujin9/15-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +132 -0
  367. package/lessons/woowacourse-kotlin-blackjack/sujin9/47-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +265 -0
  368. package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/29-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
  369. package/lessons/woowacourse-kotlin-blackjack/tmdgh1592/51-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +278 -0
  370. package/lessons/woowacourse-kotlin-blackjack/tobae-time/115-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +305 -0
  371. package/lessons/woowacourse-kotlin-blackjack/tobae-time/154-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +298 -0
  372. package/lessons/woowacourse-kotlin-blackjack/whk06061/25-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +235 -0
  373. package/lessons/woowacourse-kotlin-blackjack/whk06061/53-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +130 -0
  374. package/lessons/woowacourse-kotlin-blackjack/wondroid-world/124-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +486 -0
  375. package/lessons/woowacourse-kotlin-blackjack/wondroid-world/152-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +482 -0
  376. package/lessons/woowacourse-kotlin-blackjack/yrsel/120-1/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +194 -0
  377. package/lessons/woowacourse-kotlin-blackjack/yrsel/146-2/353/213/250/352/263/204-/353/270/224/353/236/231/354/236/255.md +444 -0
  378. package/lessons/woowacourse-kotlin-lotto/2chang5/27-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  379. package/lessons/woowacourse-kotlin-lotto/2chang5/52-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +187 -0
  380. package/lessons/woowacourse-kotlin-lotto/Choisehyeon/14-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +206 -0
  381. package/lessons/woowacourse-kotlin-lotto/Choisehyeon/47-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
  382. package/lessons/woowacourse-kotlin-lotto/DYGames/2-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
  383. package/lessons/woowacourse-kotlin-lotto/DYGames/34-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +88 -0
  384. package/lessons/woowacourse-kotlin-lotto/EmilyCh0/12-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  385. package/lessons/woowacourse-kotlin-lotto/EmilyCh0/40-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +135 -0
  386. package/lessons/woowacourse-kotlin-lotto/HANDOVER.md +217 -0
  387. package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/121-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  388. package/lessons/woowacourse-kotlin-lotto/HamBeomJoon/139-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +75 -0
  389. package/lessons/woowacourse-kotlin-lotto/Hevton/76-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  390. package/lessons/woowacourse-kotlin-lotto/Hevton/92-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +122 -0
  391. package/lessons/woowacourse-kotlin-lotto/Hogu59/100-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +110 -0
  392. package/lessons/woowacourse-kotlin-lotto/Hogu59/68-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +84 -0
  393. package/lessons/woowacourse-kotlin-lotto/JoYehyun99/60-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
  394. package/lessons/woowacourse-kotlin-lotto/JoYehyun99/96-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
  395. package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/61-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  396. package/lessons/woowacourse-kotlin-lotto/Junyoung-WON/93-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +16 -0
  397. package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/109-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +57 -0
  398. package/lessons/woowacourse-kotlin-lotto/Leeyerin0210/135-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
  399. package/lessons/woowacourse-kotlin-lotto/PROGRESS.md +160 -0
  400. package/lessons/woowacourse-kotlin-lotto/README.md +77 -0
  401. package/lessons/woowacourse-kotlin-lotto/RightHennessy/32-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  402. package/lessons/woowacourse-kotlin-lotto/RightHennessy/5-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  403. package/lessons/woowacourse-kotlin-lotto/SUMMARY.md +369 -0
  404. package/lessons/woowacourse-kotlin-lotto/SeongHoonC/25-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  405. package/lessons/woowacourse-kotlin-lotto/SeongHoonC/37-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +27 -0
  406. package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/72-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +137 -0
  407. package/lessons/woowacourse-kotlin-lotto/Yunseok-Nam/86-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +17 -0
  408. package/lessons/woowacourse-kotlin-lotto/aprilgom/102-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +62 -0
  409. package/lessons/woowacourse-kotlin-lotto/aprilgom/64-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
  410. package/lessons/woowacourse-kotlin-lotto/boogi-woogi/11-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  411. package/lessons/woowacourse-kotlin-lotto/boogi-woogi/29-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  412. package/lessons/woowacourse-kotlin-lotto/briandr97/26-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  413. package/lessons/woowacourse-kotlin-lotto/briandr97/51-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +123 -0
  414. package/lessons/woowacourse-kotlin-lotto/chaehyuns/71-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +115 -0
  415. package/lessons/woowacourse-kotlin-lotto/chaehyuns/97-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  416. package/lessons/woowacourse-kotlin-lotto/chanho0908/124-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
  417. package/lessons/woowacourse-kotlin-lotto/chanho0908/129-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  418. package/lessons/woowacourse-kotlin-lotto/chws0508/24-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +117 -0
  419. package/lessons/woowacourse-kotlin-lotto/chws0508/50-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +167 -0
  420. package/lessons/woowacourse-kotlin-lotto/cucumber99/116-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  421. package/lessons/woowacourse-kotlin-lotto/cucumber99/147-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +223 -0
  422. package/lessons/woowacourse-kotlin-lotto/devfeijoa/125-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
  423. package/lessons/woowacourse-kotlin-lotto/devfeijoa/153-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +107 -0
  424. package/lessons/woowacourse-kotlin-lotto/doabletuple/119-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
  425. package/lessons/woowacourse-kotlin-lotto/doabletuple/138-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +77 -0
  426. package/lessons/woowacourse-kotlin-lotto/donghyun81/111-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
  427. package/lessons/woowacourse-kotlin-lotto/donghyun81/152-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  428. package/lessons/woowacourse-kotlin-lotto/dpcks0509/80-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
  429. package/lessons/woowacourse-kotlin-lotto/dpcks0509/87-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +134 -0
  430. package/lessons/woowacourse-kotlin-lotto/etama123/112-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +170 -0
  431. package/lessons/woowacourse-kotlin-lotto/etama123/148-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +183 -0
  432. package/lessons/woowacourse-kotlin-lotto/gaeun5744/101-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  433. package/lessons/woowacourse-kotlin-lotto/gaeun5744/78-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
  434. package/lessons/woowacourse-kotlin-lotto/gahyunkim/107-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +83 -0
  435. package/lessons/woowacourse-kotlin-lotto/gahyunkim/136-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +51 -0
  436. package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/106-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
  437. package/lessons/woowacourse-kotlin-lotto/giovannijunseokim/137-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +111 -0
  438. package/lessons/woowacourse-kotlin-lotto/haeum808/67-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  439. package/lessons/woowacourse-kotlin-lotto/haeum808/95-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  440. package/lessons/woowacourse-kotlin-lotto/hwannow/113-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +235 -0
  441. package/lessons/woowacourse-kotlin-lotto/hwannow/132-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  442. package/lessons/woowacourse-kotlin-lotto/hxeyexn/77-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +141 -0
  443. package/lessons/woowacourse-kotlin-lotto/hxeyexn/98-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +162 -0
  444. package/lessons/woowacourse-kotlin-lotto/hyemdooly/17-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
  445. package/lessons/woowacourse-kotlin-lotto/hyemdooly/28-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +23 -0
  446. package/lessons/woowacourse-kotlin-lotto/hyunji1203/15-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +171 -0
  447. package/lessons/woowacourse-kotlin-lotto/hyunji1203/48-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
  448. package/lessons/woowacourse-kotlin-lotto/ii2001/62-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  449. package/lessons/woowacourse-kotlin-lotto/ii2001/88-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  450. package/lessons/woowacourse-kotlin-lotto/ijh1298/122-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
  451. package/lessons/woowacourse-kotlin-lotto/ijh1298/133-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
  452. package/lessons/woowacourse-kotlin-lotto/inseonyun/3-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +222 -0
  453. package/lessons/woowacourse-kotlin-lotto/inseonyun/49-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +166 -0
  454. package/lessons/woowacourse-kotlin-lotto/ippnsj/16-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +154 -0
  455. package/lessons/woowacourse-kotlin-lotto/ippnsj/55-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  456. package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/59-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +68 -0
  457. package/lessons/woowacourse-kotlin-lotto/jaeyeongjo/83-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +53 -0
  458. package/lessons/woowacourse-kotlin-lotto/jerry8282/115-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  459. package/lessons/woowacourse-kotlin-lotto/jerry8282/134-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  460. package/lessons/woowacourse-kotlin-lotto/jinuemong/63-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +144 -0
  461. package/lessons/woowacourse-kotlin-lotto/jinuemong/89-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
  462. package/lessons/woowacourse-kotlin-lotto/jiyuneel/128-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +52 -0
  463. package/lessons/woowacourse-kotlin-lotto/jiyuneel/144-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +149 -0
  464. package/lessons/woowacourse-kotlin-lotto/junjange/58-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +148 -0
  465. package/lessons/woowacourse-kotlin-lotto/junjange/81-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  466. package/lessons/woowacourse-kotlin-lotto/junseo511/120-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +153 -0
  467. package/lessons/woowacourse-kotlin-lotto/junseo511/131-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +188 -0
  468. package/lessons/woowacourse-kotlin-lotto/ki960213/43-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +24 -0
  469. package/lessons/woowacourse-kotlin-lotto/ki960213/8-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +159 -0
  470. package/lessons/woowacourse-kotlin-lotto/kimhm0728/74-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +50 -0
  471. package/lessons/woowacourse-kotlin-lotto/kimhm0728/94-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +176 -0
  472. package/lessons/woowacourse-kotlin-lotto/kkosang/85-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +145 -0
  473. package/lessons/woowacourse-kotlin-lotto/kmkim2689/70-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +97 -0
  474. package/lessons/woowacourse-kotlin-lotto/kmkim2689/82-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +157 -0
  475. package/lessons/woowacourse-kotlin-lotto/krrong/19-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +161 -0
  476. package/lessons/woowacourse-kotlin-lotto/krrong/41-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +73 -0
  477. package/lessons/woowacourse-kotlin-lotto/m6z1/105-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +67 -0
  478. package/lessons/woowacourse-kotlin-lotto/m6z1/151-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  479. package/lessons/woowacourse-kotlin-lotto/medAndro/127-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +186 -0
  480. package/lessons/woowacourse-kotlin-lotto/medAndro/130-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +132 -0
  481. package/lessons/woowacourse-kotlin-lotto/moondev03/110-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  482. package/lessons/woowacourse-kotlin-lotto/moondev03/141-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +155 -0
  483. package/lessons/woowacourse-kotlin-lotto/murjune/69-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  484. package/lessons/woowacourse-kotlin-lotto/murjune/90-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +177 -0
  485. package/lessons/woowacourse-kotlin-lotto/no1msh/20-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +69 -0
  486. package/lessons/woowacourse-kotlin-lotto/no1msh/46-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  487. package/lessons/woowacourse-kotlin-lotto/otter66/13-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +178 -0
  488. package/lessons/woowacourse-kotlin-lotto/otter66/53-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +160 -0
  489. package/lessons/woowacourse-kotlin-lotto/oungsi2000/126-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +71 -0
  490. package/lessons/woowacourse-kotlin-lotto/oungsi2000/149-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +56 -0
  491. package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/117-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  492. package/lessons/woowacourse-kotlin-lotto/parkjiminnnn/146-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +173 -0
  493. package/lessons/woowacourse-kotlin-lotto/pingu244/33-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  494. package/lessons/woowacourse-kotlin-lotto/pingu244/54-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
  495. package/lessons/woowacourse-kotlin-lotto/pingu244/7-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +19 -0
  496. package/lessons/woowacourse-kotlin-lotto/re4rk/31-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +143 -0
  497. package/lessons/woowacourse-kotlin-lotto/re4rk/4-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +66 -0
  498. package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/23-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +26 -0
  499. package/lessons/woowacourse-kotlin-lotto/rhkrwngud445/38-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +129 -0
  500. package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/21-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +146 -0
  501. package/lessons/woowacourse-kotlin-lotto/rhthrhrl0/36-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +150 -0
  502. package/lessons/woowacourse-kotlin-lotto/rosemin928/123-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +179 -0
  503. package/lessons/woowacourse-kotlin-lotto/rosemin928/140-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +126 -0
  504. package/lessons/woowacourse-kotlin-lotto/s6m1n/103-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +119 -0
  505. package/lessons/woowacourse-kotlin-lotto/s6m1n/66-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +118 -0
  506. package/lessons/woowacourse-kotlin-lotto/s9hn/18-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +112 -0
  507. package/lessons/woowacourse-kotlin-lotto/sh1mj1/75-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +104 -0
  508. package/lessons/woowacourse-kotlin-lotto/sh1mj1/91-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +140 -0
  509. package/lessons/woowacourse-kotlin-lotto/songpink/65-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +96 -0
  510. package/lessons/woowacourse-kotlin-lotto/songpink/99-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +64 -0
  511. package/lessons/woowacourse-kotlin-lotto/sujin9/10-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  512. package/lessons/woowacourse-kotlin-lotto/sujin9/35-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  513. package/lessons/woowacourse-kotlin-lotto/tmdgh1592/22-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +30 -0
  514. package/lessons/woowacourse-kotlin-lotto/tmdgh1592/30-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +20 -0
  515. package/lessons/woowacourse-kotlin-lotto/tobae-time/114-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +158 -0
  516. package/lessons/woowacourse-kotlin-lotto/tobae-time/145-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +120 -0
  517. package/lessons/woowacourse-kotlin-lotto/whk06061/42-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +21 -0
  518. package/lessons/woowacourse-kotlin-lotto/whk06061/9-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +89 -0
  519. package/lessons/woowacourse-kotlin-lotto/wondroid-world/118-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +100 -0
  520. package/lessons/woowacourse-kotlin-lotto/wondroid-world/150-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +142 -0
  521. package/lessons/woowacourse-kotlin-lotto/yrsel/108-1/353/213/250/352/263/204-/353/241/234/353/230/220.md +124 -0
  522. package/lessons/woowacourse-kotlin-lotto/yrsel/143-2/353/213/250/352/263/204-/353/241/234/353/230/220.md +108 -0
  523. package/lessons/woowacourse-racingcar/2chang5/33-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  524. package/lessons/woowacourse-racingcar/2chang5/75-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  525. package/lessons/woowacourse-racingcar/CFalws/85-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  526. package/lessons/woowacourse-racingcar/Choisehyeon/46-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  527. package/lessons/woowacourse-racingcar/DYGames/49-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
  528. package/lessons/woowacourse-racingcar/EmilyCh0/40-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +64 -0
  529. package/lessons/woowacourse-racingcar/EmilyCh0/57-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  530. package/lessons/woowacourse-racingcar/HamBeomJoon/137-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  531. package/lessons/woowacourse-racingcar/HamBeomJoon/170-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  532. package/lessons/woowacourse-racingcar/Hevton/106-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  533. package/lessons/woowacourse-racingcar/Hevton/118-/353/246/254/355/214/251/355/204/260/353/247/201.md +51 -0
  534. package/lessons/woowacourse-racingcar/Hogu59/108-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  535. package/lessons/woowacourse-racingcar/Hogu59/125-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  536. package/lessons/woowacourse-racingcar/JoYehyun99/111-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  537. package/lessons/woowacourse-racingcar/JoYehyun99/88-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
  538. package/lessons/woowacourse-racingcar/Junyoung-WON/127-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  539. package/lessons/woowacourse-racingcar/Junyoung-WON/90-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  540. package/lessons/woowacourse-racingcar/Leeyerin0210/133-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  541. package/lessons/woowacourse-racingcar/Leeyerin0210/159-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  542. package/lessons/woowacourse-racingcar/PROGRESS.md +94 -0
  543. package/lessons/woowacourse-racingcar/README.md +69 -0
  544. package/lessons/woowacourse-racingcar/RightHennessy/51-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  545. package/lessons/woowacourse-racingcar/RightHennessy/58-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  546. package/lessons/woowacourse-racingcar/RunaNam/81-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
  547. package/lessons/woowacourse-racingcar/SUMMARY.md +339 -0
  548. package/lessons/woowacourse-racingcar/SeongHoonC/37-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  549. package/lessons/woowacourse-racingcar/SeongHoonC/66-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  550. package/lessons/woowacourse-racingcar/Songusika/84-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  551. package/lessons/woowacourse-racingcar/Yunseok-Nam/114-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  552. package/lessons/woowacourse-racingcar/Yunseok-Nam/96-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  553. package/lessons/woowacourse-racingcar/aprilgom/130-/353/246/254/355/214/251/355/204/260/353/247/201.md +52 -0
  554. package/lessons/woowacourse-racingcar/aprilgom/97-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  555. package/lessons/woowacourse-racingcar/awesomeo184/23-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  556. package/lessons/woowacourse-racingcar/boogi-woogi/35-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
  557. package/lessons/woowacourse-racingcar/boogi-woogi/59-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  558. package/lessons/woowacourse-racingcar/briandr97/54-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  559. package/lessons/woowacourse-racingcar/chaehyuns/131-/353/246/254/355/214/251/355/204/260/353/247/201.md +49 -0
  560. package/lessons/woowacourse-racingcar/chaehyuns/99-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  561. package/lessons/woowacourse-racingcar/chanho0908/147-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  562. package/lessons/woowacourse-racingcar/chanho0908/160-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  563. package/lessons/woowacourse-racingcar/chws0508/45-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  564. package/lessons/woowacourse-racingcar/chws0508/73-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
  565. package/lessons/woowacourse-racingcar/cucumber99/132-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  566. package/lessons/woowacourse-racingcar/cucumber99/177-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  567. package/lessons/woowacourse-racingcar/devfeijoa/146-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  568. package/lessons/woowacourse-racingcar/doabletuple/149-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  569. package/lessons/woowacourse-racingcar/doabletuple/175-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  570. package/lessons/woowacourse-racingcar/donghyun81/154-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  571. package/lessons/woowacourse-racingcar/dpcks0509/103-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  572. package/lessons/woowacourse-racingcar/dpcks0509/112-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  573. package/lessons/woowacourse-racingcar/drunkenhw/82-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  574. package/lessons/woowacourse-racingcar/etama123/145-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  575. package/lessons/woowacourse-racingcar/gaeun5744/124-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
  576. package/lessons/woowacourse-racingcar/gaeun5744/93-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  577. package/lessons/woowacourse-racingcar/gahyunkim/134-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  578. package/lessons/woowacourse-racingcar/gahyunkim/164-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  579. package/lessons/woowacourse-racingcar/giovannijunseokim/140-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  580. package/lessons/woowacourse-racingcar/haeum808/101-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  581. package/lessons/woowacourse-racingcar/haeum808/129-/353/246/254/355/214/251/355/204/260/353/247/201.md +46 -0
  582. package/lessons/woowacourse-racingcar/hwannow/141-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  583. package/lessons/woowacourse-racingcar/hwannow/157-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +45 -0
  584. package/lessons/woowacourse-racingcar/hxeyexn/109-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  585. package/lessons/woowacourse-racingcar/hxeyexn/128-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  586. package/lessons/woowacourse-racingcar/hyemdooly/50-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  587. package/lessons/woowacourse-racingcar/hyemdooly/68-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  588. package/lessons/woowacourse-racingcar/hyunji1203/29-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  589. package/lessons/woowacourse-racingcar/hyunji1203/60-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  590. package/lessons/woowacourse-racingcar/ii2001/102-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
  591. package/lessons/woowacourse-racingcar/ii2001/122-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  592. package/lessons/woowacourse-racingcar/ijh1298/144-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  593. package/lessons/woowacourse-racingcar/injoon2019/24-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  594. package/lessons/woowacourse-racingcar/inseonyun/44-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  595. package/lessons/woowacourse-racingcar/inseonyun/76-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  596. package/lessons/woowacourse-racingcar/ippnsj/36-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  597. package/lessons/woowacourse-racingcar/ippnsj/67-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  598. package/lessons/woowacourse-racingcar/jaeyeongjo/110-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
  599. package/lessons/woowacourse-racingcar/jaeyeongjo/89-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +46 -0
  600. package/lessons/woowacourse-racingcar/jinuemong/104-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  601. package/lessons/woowacourse-racingcar/jinuemong/117-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +42 -0
  602. package/lessons/woowacourse-racingcar/jiyuneel/142-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  603. package/lessons/woowacourse-racingcar/junjange/113-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +41 -0
  604. package/lessons/woowacourse-racingcar/junjange/87-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +39 -0
  605. package/lessons/woowacourse-racingcar/junseo511/148-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  606. package/lessons/woowacourse-racingcar/junseo511/165-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  607. package/lessons/woowacourse-racingcar/ki960213/32-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  608. package/lessons/woowacourse-racingcar/ki960213/63-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  609. package/lessons/woowacourse-racingcar/kimhm0728/100-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  610. package/lessons/woowacourse-racingcar/kimhm0728/116-/353/246/254/355/214/251/355/204/260/353/247/201.md +54 -0
  611. package/lessons/woowacourse-racingcar/kkosang/105-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  612. package/lessons/woowacourse-racingcar/kkosang/126-/353/246/254/355/214/251/355/204/260/353/247/201.md +53 -0
  613. package/lessons/woowacourse-racingcar/kmkim2689/123-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  614. package/lessons/woowacourse-racingcar/kmkim2689/92-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  615. package/lessons/woowacourse-racingcar/krrong/34-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +63 -0
  616. package/lessons/woowacourse-racingcar/m6z1/150-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  617. package/lessons/woowacourse-racingcar/m6z1/156-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +40 -0
  618. package/lessons/woowacourse-racingcar/medAndro/153-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  619. package/lessons/woowacourse-racingcar/moondev03/135-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +57 -0
  620. package/lessons/woowacourse-racingcar/moondev03/161-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  621. package/lessons/woowacourse-racingcar/murjune/121-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  622. package/lessons/woowacourse-racingcar/murjune/95-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  623. package/lessons/woowacourse-racingcar/no1msh/43-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  624. package/lessons/woowacourse-racingcar/no1msh/69-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  625. package/lessons/woowacourse-racingcar/otter66/48-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  626. package/lessons/woowacourse-racingcar/otter66/77-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +52 -0
  627. package/lessons/woowacourse-racingcar/oungsi2000/152-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +56 -0
  628. package/lessons/woowacourse-racingcar/oungsi2000/187-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  629. package/lessons/woowacourse-racingcar/parkjiminnnn/143-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  630. package/lessons/woowacourse-racingcar/parkjiminnnn/158-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  631. package/lessons/woowacourse-racingcar/pingu244/38-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  632. package/lessons/woowacourse-racingcar/pingu244/62-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  633. package/lessons/woowacourse-racingcar/re4rk/28-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +60 -0
  634. package/lessons/woowacourse-racingcar/re4rk/55-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  635. package/lessons/woowacourse-racingcar/rhkrwngud445/42-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  636. package/lessons/woowacourse-racingcar/rhkrwngud445/74-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
  637. package/lessons/woowacourse-racingcar/rhthrhrl0/31-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  638. package/lessons/woowacourse-racingcar/rosemin928/138-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  639. package/lessons/woowacourse-racingcar/rosemin928/171-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +38 -0
  640. package/lessons/woowacourse-racingcar/s6m1n/120-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +54 -0
  641. package/lessons/woowacourse-racingcar/s6m1n/91-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +62 -0
  642. package/lessons/woowacourse-racingcar/s9hn/53-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +44 -0
  643. package/lessons/woowacourse-racingcar/s9hn/78-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  644. package/lessons/woowacourse-racingcar/sh1mj1/107-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  645. package/lessons/woowacourse-racingcar/sh1mj1/115-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +61 -0
  646. package/lessons/woowacourse-racingcar/songpink/119-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  647. package/lessons/woowacourse-racingcar/songpink/98-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +55 -0
  648. package/lessons/woowacourse-racingcar/sujin9/52-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +48 -0
  649. package/lessons/woowacourse-racingcar/sujin9/61-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +47 -0
  650. package/lessons/woowacourse-racingcar/tmdgh1592/47-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  651. package/lessons/woowacourse-racingcar/tmdgh1592/64-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  652. package/lessons/woowacourse-racingcar/tobae-time/151-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +51 -0
  653. package/lessons/woowacourse-racingcar/tobae-time/167-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +43 -0
  654. package/lessons/woowacourse-racingcar/whk06061/41-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +58 -0
  655. package/lessons/woowacourse-racingcar/wondroid-world/136-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +49 -0
  656. package/lessons/woowacourse-racingcar/wondroid-world/166-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +50 -0
  657. package/lessons/woowacourse-racingcar/yrsel/139-1/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +53 -0
  658. package/lessons/woowacourse-racingcar/yujamint/83-2/353/213/250/352/263/204-/354/236/220/353/217/231/354/260/250-/352/262/275/354/243/274.md +59 -0
  659. package/package.json +46 -0
  660. package/skills/oh-my-oop/SKILL.md +39 -0
@@ -0,0 +1,131 @@
1
+ import { assertHasMultipleRemedies } from "./findings.js";
2
+ // 전략(Strategy) 인터페이스의 *공통 시그니처*에 *분기 인자*가 섞이는 안티패턴.
3
+ // 대표 사례: interface LottoMachine { fun generate(count, lottoNumbers: List<List<Int>>? = null) }
4
+ // → ManualLottoMachine은 lottoNumbers를 쓰고, AutomaticLottoMachine은 항상 null을 받음.
5
+ // 설계 모델만으로는 메서드 시그니처를 볼 수 없으므로,
6
+ // "같은 *전략 suffix*를 공유하는 2개 이상의 ServiceProvider가 *knowing의 비대칭*을 보일 때"를 프록시로 잡는다.
7
+ // 근거: @krrong (lotto PR #144) — "공통 인터페이스 = 공통 시그니처. 분기 인자는 생성자".
8
+ const STRATEGY_SUFFIXES = [
9
+ "Machine",
10
+ "Generator",
11
+ "Strategy",
12
+ "Policy",
13
+ "Provider",
14
+ "Handler",
15
+ "Resolver",
16
+ "Selector",
17
+ ];
18
+ function endsWithStrategySuffix(name) {
19
+ for (const s of STRATEGY_SUFFIXES) {
20
+ if (name.length > s.length && name.endsWith(s))
21
+ return s;
22
+ }
23
+ return null;
24
+ }
25
+ function isStrategyStereotype(card) {
26
+ return card.stereotype === "ServiceProvider" || card.stereotype === "Coordinator";
27
+ }
28
+ export function checkStrategyAsymmetry(design) {
29
+ const out = [];
30
+ // suffix 별로 카드 그룹핑
31
+ const groups = new Map();
32
+ for (const card of design.classes) {
33
+ if (!isStrategyStereotype(card))
34
+ continue;
35
+ const suffix = endsWithStrategySuffix(card.name);
36
+ if (!suffix)
37
+ continue;
38
+ const list = groups.get(suffix) ?? [];
39
+ list.push(card);
40
+ groups.set(suffix, list);
41
+ }
42
+ for (const [suffix, members] of groups) {
43
+ if (members.length < 2)
44
+ continue;
45
+ const knowingCounts = members.map((m) => m.responsibilities.knowing.length);
46
+ const minK = Math.min(...knowingCounts);
47
+ const maxK = Math.max(...knowingCounts);
48
+ // 모두 같은 knowing 갯수면 대칭 — 통과.
49
+ if (minK === maxK)
50
+ continue;
51
+ // 한쪽이 0, 다른쪽이 ≥1 이어야 *분기 인자가 인터페이스에 새는* 시그널.
52
+ if (minK !== 0)
53
+ continue;
54
+ const withData = members.filter((m) => m.responsibilities.knowing.length > 0);
55
+ const empty = members.filter((m) => m.responsibilities.knowing.length === 0);
56
+ out.push(assertHasMultipleRemedies({
57
+ rule_id: "strategy-default-param-pollution",
58
+ severity: "warn",
59
+ target: { kind: "design", id: `strategy-group-${suffix}` },
60
+ message: `${suffix} 전략 그룹(${members.map((m) => m.name).join(", ")})에서 knowing이 *비대칭*입니다. ` +
61
+ `한 구현체(${withData.map((m) => m.name).join(", ")})는 데이터를 보유하지만 ` +
62
+ `다른 구현체(${empty.map((m) => m.name).join(", ")})는 비어 있습니다. ` +
63
+ `공통 인터페이스 메서드가 이 비대칭을 흡수하려고 *nullable 분기 인자*나 *default = emptyList()* 같은 시그니처 오염을 만들 가능성이 높습니다.`,
64
+ evidence: {
65
+ suffix,
66
+ members: members.map((m) => ({
67
+ name: m.name,
68
+ knowing_count: m.responsibilities.knowing.length,
69
+ knowing_sample: m.responsibilities.knowing[0] ?? null,
70
+ })),
71
+ guideline: "@krrong (lotto PR #144): \"수동 발매기의 생성자를 통해 넘겨주는 방식\" — " +
72
+ "공통 인터페이스 = 공통 시그니처. 분기 인자는 *메서드 default*가 아니라 *생성자*로 받아야 한다.",
73
+ },
74
+ remedies: [
75
+ {
76
+ label: "분기 데이터를 *생성자*로 옮기기 (인터페이스 정화)",
77
+ summary: `메서드 시그니처에서 일부 구현체에만 의미 있는 파라미터를 제거하고, ` +
78
+ `해당 데이터는 ${withData[0]?.name ?? "ManualX"}의 *생성자*에서 받는다. ` +
79
+ `인터페이스는 모든 구현체가 *공통으로* 필요한 인자만 노출한다.`,
80
+ tradeoffs: {
81
+ pros: [
82
+ "인터페이스 호출자가 *어떤 구현체인지* 신경 쓰지 않아도 됨",
83
+ "nullable/default 값으로 의미를 *우회 표현*하는 코드 소멸",
84
+ "각 구현체의 *생성 시점*에 자기 의존을 명시 (생성자가 invariant)",
85
+ ],
86
+ cons: [
87
+ "구현체 생성 지점에서 인자를 *미리 알아야* 함 (지연 입력이 어려워질 수 있음)",
88
+ "테스트에서 매 구현체마다 생성자 stub 패턴이 달라짐",
89
+ ],
90
+ },
91
+ },
92
+ {
93
+ label: "함수형 인터페이스로 *지연 입력* 끌어올림",
94
+ summary: `인터페이스를 \`(input) -> Output\` 같은 함수형으로 단순화하거나, ` +
95
+ `${withData[0]?.name ?? "ManualX"}의 생성자에 \`() -> List<...>\` 같은 함수를 주입해 ` +
96
+ `*입력 시점*을 호출 컨텍스트로 끌어올린다. @krrong 후속 제안.`,
97
+ tradeoffs: {
98
+ pros: [
99
+ "*매 호출마다 다른 입력*이 필요한 경우 자연스럽게 표현",
100
+ "구현체 생성 시점에 데이터를 알 필요 없음",
101
+ "Kotlin functional interface로 호출자 쪽이 간결",
102
+ ],
103
+ cons: [
104
+ "*호출 순서/사이드이펙트*가 함수 내부에 숨음 — 디버깅 비용 증가",
105
+ "함수형 의존이 늘면 *진짜 객체 협력*이 보이지 않게 됨",
106
+ ],
107
+ },
108
+ },
109
+ {
110
+ label: "전략 분리 폐기 + sealed class로 *합치기*",
111
+ summary: `구현체 간 차이가 정말 *데이터의 유무*뿐이라면 인터페이스 대신 sealed class로 합쳐 ` +
112
+ `데이터 보유 케이스와 무보유 케이스를 *타입으로* 표현한다. when 표현식이 모든 케이스를 컴파일 단계에서 강제.`,
113
+ tradeoffs: {
114
+ pros: [
115
+ "케이스가 *닫혀 있음*이 타입에 드러나 when exhaustive 보장",
116
+ "각 케이스가 자기 데이터만 가짐 — 비대칭이 사라짐",
117
+ "*전략이 1~2종에서 끝날* 도메인에 가벼움",
118
+ ],
119
+ cons: [
120
+ "변형 추가가 모든 when 분기 수정 비용을 유발 (OCP 약화)",
121
+ "*다형성으로 풀 일을* sealed when으로 풀어 객체지향 의도가 약해짐",
122
+ "외부 라이브러리/외부 의존 주입이 어려워질 수 있음",
123
+ ],
124
+ },
125
+ },
126
+ ],
127
+ }));
128
+ }
129
+ return out;
130
+ }
131
+ //# sourceMappingURL=strategyAsymmetry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"strategyAsymmetry.js","sourceRoot":"","sources":["../../src/validate/strategyAsymmetry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ import type { Design } from "../domain/model.js";
2
+ import type { Finding } from "./findings.js";
3
+ export declare function checkNonNewable(design: Design): Finding[];
4
+ export declare function checkSideEffectInHolder(design: Design): Finding[];
5
+ export declare function checkMockingPressure(design: Design, maxNonNewable: number): Finding[];
@@ -0,0 +1,157 @@
1
+ import { assertHasMultipleRemedies } from "./findings.js";
2
+ const NON_NEWABLE_RE = /(Repository|Client|Gateway|Random|Clock|System|Http|Db|Connection)/;
3
+ const STRATEGY_HINT_RE = /(Strategy|Policy|Provider|Source|Generator)/;
4
+ const SIDE_EFFECT_VERBS = /(save|store|persist|send|publish|emit|print|log|write|delete|fetch|call)/i;
5
+ function isNonNewableName(name) {
6
+ return NON_NEWABLE_RE.test(name);
7
+ }
8
+ function hasStrategySeam(card) {
9
+ return card.collaborators.some((c) => STRATEGY_HINT_RE.test(c.name));
10
+ }
11
+ export function checkNonNewable(design) {
12
+ const out = [];
13
+ for (const card of design.classes) {
14
+ const offenders = card.collaborators.filter((c) => isNonNewableName(c.name));
15
+ if (offenders.length === 0)
16
+ continue;
17
+ if (hasStrategySeam(card))
18
+ continue;
19
+ out.push(assertHasMultipleRemedies({
20
+ rule_id: "non-newable",
21
+ severity: "warn",
22
+ target: { kind: "class", id: card.id },
23
+ message: `${card.name}이(가) 외부 자원성 협력자(${offenders
24
+ .map((o) => o.name)
25
+ .join(", ")})를 직접 사용해 단위테스트에서 단순히 \`new\`로 생성하기 어렵습니다.`,
26
+ evidence: {
27
+ offenders: offenders.map((o) => o.name),
28
+ guideline: "조영호님 기준: new로 생성 가능한가, 사이드이펙트 의존을 강제하는가",
29
+ },
30
+ remedies: [
31
+ {
32
+ label: "Strategy/Provider 인터페이스로 추출",
33
+ summary: "외부 자원 호출을 인터페이스 뒤로 감추고, 테스트에서는 페이크 구현을 주입한다.",
34
+ tradeoffs: {
35
+ pros: ["테스트가 단순해지고 모킹 부담이 사라짐", "구현 교체 용이"],
36
+ cons: ["인터페이스 1개 추가로 코드 표면적 증가"],
37
+ },
38
+ },
39
+ {
40
+ label: "값(결과)을 파라미터로 받기",
41
+ summary: "자원에서 얻은 값(예: 현재 시각, 난수)을 호출 시점에 파라미터로 받아 객체를 순수하게 유지한다.",
42
+ tradeoffs: {
43
+ pros: ["객체가 완전히 순수해져 테스트 자유도 최고"],
44
+ cons: ["호출자가 값을 준비해야 해서 유스케이스 진입점이 무거워짐"],
45
+ },
46
+ },
47
+ {
48
+ label: "Interfacer로 위임 + 경계에서만 자원 사용",
49
+ summary: "외부 자원 호출 책임을 별도 Interfacer로 모으고, 도메인 객체는 그 결과만 받는다.",
50
+ tradeoffs: {
51
+ pros: ["도메인-인프라 경계가 명확", "교체 가능한 구조"],
52
+ cons: ["계층이 늘어 학습 곡선 상승"],
53
+ },
54
+ },
55
+ ],
56
+ }));
57
+ }
58
+ return out;
59
+ }
60
+ // UI 표현 문자열이 도메인 데이터에 박혀 있는지 검출. PR #78 (s9hn): DriverDecision.distance="-"
61
+ // UI 변경이 도메인 변경으로 번지는 안티패턴.
62
+ const UI_LITERAL_RE = /["'`]\s*[-|│:\\n→←↑↓\s]+\s*["'`]|["'`]\s*[-=*]{2,}\s*["'`]/;
63
+ export function checkSideEffectInHolder(design) {
64
+ const out = [];
65
+ for (const card of design.classes) {
66
+ if (card.stereotype !== "InformationHolder")
67
+ continue;
68
+ const offenders = card.responsibilities.doing.filter((d) => SIDE_EFFECT_VERBS.test(d));
69
+ const uiLiterals = card.responsibilities.knowing.filter((k) => UI_LITERAL_RE.test(k));
70
+ if (offenders.length === 0 && uiLiterals.length === 0)
71
+ continue;
72
+ const reasons = [];
73
+ if (offenders.length > 0)
74
+ reasons.push(`사이드이펙트성 동사(저장/전송/기록 등) doing 책임 (${offenders.join(", ")})`);
75
+ if (uiLiterals.length > 0)
76
+ reasons.push(`UI 표현 문자열을 knowing에 보유 (${uiLiterals.join(", ")}). ` +
77
+ `UI 변경이 도메인 변경으로 번질 위험이 있습니다.`);
78
+ out.push(assertHasMultipleRemedies({
79
+ rule_id: "side-effect-in-holder",
80
+ severity: "warn",
81
+ target: { kind: "class", id: card.id },
82
+ message: `${card.name}은(는) InformationHolder인데 ${reasons.join(" · ")}.`,
83
+ evidence: { offenders, ui_literals: uiLiterals },
84
+ remedies: [
85
+ {
86
+ label: "Stereotype을 ServiceProvider로 재분류",
87
+ summary: "사이드이펙트 책임이 본질이라면 Stereotype을 맞게 바꾼다.",
88
+ tradeoffs: {
89
+ pros: ["역할이 정확히 표현됨"],
90
+ cons: ["원래 정보 표현 목적이라면 정체성이 흐려짐"],
91
+ },
92
+ },
93
+ {
94
+ label: "사이드이펙트를 새 ServiceProvider/Interfacer로 추출",
95
+ summary: "정보를 보유하는 책임은 남기고, 저장/전송 등은 새 협력자에게 위임한다.",
96
+ tradeoffs: {
97
+ pros: ["순수한 도메인 정보 보존", "테스트 용이"],
98
+ cons: ["클래스 수 증가"],
99
+ },
100
+ },
101
+ {
102
+ label: "이벤트로 바꾸고 Interfacer가 처리",
103
+ summary: "사이드이펙트를 이벤트 발행으로 바꾸고 경계에서 Interfacer가 실제 동작을 수행한다.",
104
+ tradeoffs: {
105
+ pros: ["도메인이 인프라를 모름", "확장 용이"],
106
+ cons: ["이벤트 추적이 어려워질 수 있음"],
107
+ },
108
+ },
109
+ ],
110
+ }));
111
+ }
112
+ return out;
113
+ }
114
+ export function checkMockingPressure(design, maxNonNewable) {
115
+ const out = [];
116
+ for (const card of design.classes) {
117
+ const nonNewable = card.collaborators.filter((c) => isNonNewableName(c.name));
118
+ if (nonNewable.length <= maxNonNewable)
119
+ continue;
120
+ out.push(assertHasMultipleRemedies({
121
+ rule_id: "mocking-pressure",
122
+ severity: "info",
123
+ target: { kind: "class", id: card.id },
124
+ message: `${card.name}이(가) 외부 자원성 협력자 ${nonNewable.length}개에 의존합니다. ` +
125
+ `테스트에서 모킹 부담이 커집니다.`,
126
+ evidence: { nonNewable: nonNewable.map((n) => n.name), max: maxNonNewable },
127
+ remedies: [
128
+ {
129
+ label: "테스트 더블 seam 도입",
130
+ summary: "모든 외부 의존을 한두 개의 Strategy 인터페이스 뒤로 모은다.",
131
+ tradeoffs: {
132
+ pros: ["모킹 지점이 줄어든다"],
133
+ cons: ["seam 설계에 시간 필요"],
134
+ },
135
+ },
136
+ {
137
+ label: "조합 책임을 바깥(경계)으로 밀어내기",
138
+ summary: "유스케이스 경계에서 의존성 조립을 하고 도메인 코어는 순수하게 둔다.",
139
+ tradeoffs: {
140
+ pros: ["코어를 표준 단위테스트로 검증 가능"],
141
+ cons: ["조립 책임이 한곳에 집중되어 비대해질 수 있음"],
142
+ },
143
+ },
144
+ {
145
+ label: "순수 코어 / 인프라 어댑터 분리",
146
+ summary: "도메인 규칙은 순수 객체로, 외부 호출은 어댑터로 나눠 클래스를 둘로 쪼갠다.",
147
+ tradeoffs: {
148
+ pros: ["테스트 피라미드 하단(단위) 비중 증가"],
149
+ cons: ["객체 수 증가, 호출 흐름 길어짐"],
150
+ },
151
+ },
152
+ ],
153
+ }));
154
+ }
155
+ return out;
156
+ }
157
+ //# sourceMappingURL=testability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"testability.js","sourceRoot":"","sources":["../../src/validate/testability.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Design } from "../domain/model.js";
2
+ import type { Finding } from "./findings.js";
3
+ export declare function checkVagueClassName(design: Design): Finding[];
@@ -0,0 +1,136 @@
1
+ import { assertHasMultipleRemedies } from "./findings.js";
2
+ // "Manager", "Util", "Helper" 등 일반 어휘만으로 이루어진 클래스명은 책임 회피의 신호.
3
+ // woowacourse/kotlin-racingcar 133 PR 리뷰에서 가장 빈번하게 지적된 안티패턴 중 하나.
4
+ // 단, 의미 있는 도메인 어휘가 *앞에* 붙으면 책임이 좁혀지므로 허용한다.
5
+ const SUSPECT_SUFFIXES = [
6
+ "Manager",
7
+ "Helper",
8
+ "Util",
9
+ "Utils",
10
+ "Service",
11
+ "Handler",
12
+ "Processor",
13
+ "Worker",
14
+ // 가상 객체 어휘 — 행동을 자기 객체가 아닌 *외부 명사*로 분리하려는 신호.
15
+ // 도메인 객체가 그 책임을 이미 가져야 하는 경우가 대부분.
16
+ "Calculator",
17
+ "Picker",
18
+ "Distributor",
19
+ "Decider",
20
+ "Information",
21
+ "Info",
22
+ ];
23
+ // 클래스명 단독으로도 모호한 어휘
24
+ const SUSPECT_STANDALONE = new Set([
25
+ "Validator",
26
+ "Validation",
27
+ "Exception",
28
+ "Common",
29
+ "Const",
30
+ "Constants",
31
+ "Util",
32
+ "Utils",
33
+ "Helper",
34
+ "Manager",
35
+ "Service",
36
+ "Handler",
37
+ // 가상 객체 어휘 (단독 사용 시 god-object 거의 확실)
38
+ "Calculator",
39
+ "Picker",
40
+ "Distributor",
41
+ "Judge",
42
+ "Decider",
43
+ "Information",
44
+ "Info",
45
+ "Rule",
46
+ ]);
47
+ function classify(name) {
48
+ if (SUSPECT_STANDALONE.has(name)) {
49
+ return { reason: "suspect-standalone", matched: name };
50
+ }
51
+ for (const suf of SUSPECT_SUFFIXES) {
52
+ if (name === suf)
53
+ return { reason: "suspect-standalone", matched: suf };
54
+ if (name.endsWith(suf)) {
55
+ const prefix = name.slice(0, name.length - suf.length);
56
+ // 의미 있는 prefix (3자 이상의 도메인 단어)는 허용
57
+ if (prefix.length < 3) {
58
+ return { reason: "suspect-suffix-only", matched: suf };
59
+ }
60
+ }
61
+ }
62
+ return null;
63
+ }
64
+ export function checkVagueClassName(design) {
65
+ const out = [];
66
+ for (const card of design.classes) {
67
+ const hit = classify(card.name);
68
+ if (!hit)
69
+ continue;
70
+ const message = hit.reason === "suspect-standalone"
71
+ ? `${card.name}이라는 이름은 무엇을 하는지 모호합니다. ` +
72
+ `네이밍 모호함은 god-object 안티패턴의 신호일 수 있습니다.`
73
+ : `${card.name}은 "${hit.matched}" 접미사 외에 의미 있는 도메인 어휘가 부족합니다. ` +
74
+ `클래스의 책임이 모호하면 god-object가 될 위험이 있습니다.`;
75
+ out.push(assertHasMultipleRemedies({
76
+ rule_id: "vague-class-name",
77
+ severity: "warn",
78
+ target: { kind: "class", id: card.id },
79
+ message,
80
+ evidence: {
81
+ name: card.name,
82
+ matched_pattern: hit.matched,
83
+ stereotype: card.stereotype,
84
+ guideline: "@vagabond95 (woowacourse-racingcar): \"네이밍이 모호하다는 것은 곧 해당 클래스/함수의 역할이 모호하거나 모호해질 수 있다는 신호\". " +
85
+ "@laco-dev (woowacourse-kotlin-blackjack tobae-time/115): \"현실세계라면 블랙잭 게임의 규칙이지만, 객체지향 세계에서 객체는 모두 스스로 일을 합니다\" — Picker/Distributor/Calculator/Judge 같은 *가상 객체*는 행동을 외부 명사로 분리하려는 신호이며, 도메인 객체가 그 책임을 이미 가져야 한다. " +
86
+ "@ghojeong (woowacourse-kotlin-blackjack kimhm0728/72): \"해당 역할을 컴퓨터가 아니라 사람에게 시키려고 했을 때, 사람이 한 명 더 필요한가\" — 같은 사람이 할 수 있다면 별도 객체로 분리하지 않는다.",
87
+ },
88
+ remedies: [
89
+ {
90
+ label: "무엇을 + 행위로 도메인 어휘 추가",
91
+ summary: `현재 클래스가 *무엇을* 검증/관리/돕는지 이름에 명시한다. ` +
92
+ `예: Validator → InputValidator, Manager → RacingGame, Helper → CarsHelper(여전히 모호하면 다음 안).`,
93
+ tradeoffs: {
94
+ pros: [
95
+ "이름만 보고도 책임 범위가 명확해짐",
96
+ "동료가 IDE 자동완성에서 빠르게 찾을 수 있음",
97
+ ],
98
+ cons: [
99
+ "이름이 길어질 수 있음",
100
+ "도메인이 진화하면 이름 갱신 비용",
101
+ ],
102
+ },
103
+ },
104
+ {
105
+ label: "Stereotype에 맞는 역할 이름으로 재명명",
106
+ summary: `현재 stereotype(${card.stereotype})에 맞는 역할 어휘로 바꾼다. ` +
107
+ `Coordinator → "${card.name}Coordinator/Service", InformationHolder → 도메인 명사 단독, Interfacer → "${card.name}View/Adapter".`,
108
+ tradeoffs: {
109
+ pros: [
110
+ "Wirfs-Brock stereotype과 이름이 일치해 협력 패턴 예측 가능",
111
+ "리뷰 시 책임 누수 판단이 쉬워짐",
112
+ ],
113
+ cons: [
114
+ "stereotype 자체가 잘못 설정됐다면 잘못된 방향으로 재명명될 위험",
115
+ ],
116
+ },
117
+ },
118
+ {
119
+ label: "협력자에게 책임 이전 후 클래스 삭제",
120
+ summary: `이 클래스가 *얇은 위임 계층*에 그친다면, 책임을 진짜 소유자(데이터를 가진 객체)에게 옮기고 클래스 자체를 제거한다.`,
121
+ tradeoffs: {
122
+ pros: [
123
+ "객체 수 감소 + Tell-Don't-Ask 강화",
124
+ "god-folder 안티패턴 회피",
125
+ ],
126
+ cons: [
127
+ "협력자가 비대해질 위험 (다음 라운드에서 god-object 가능성)",
128
+ ],
129
+ },
130
+ },
131
+ ],
132
+ }));
133
+ }
134
+ return out;
135
+ }
136
+ //# sourceMappingURL=vagueName.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vagueName.js","sourceRoot":"","sources":["../../src/validate/vagueName.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { Design } from "../domain/model.js";
2
+ import type { Finding } from "./findings.js";
3
+ export declare function checkValidationLocation(design: Design): Finding[];
@@ -0,0 +1,120 @@
1
+ import { assertHasMultipleRemedies } from "./findings.js";
2
+ // 검증/유효성 책임이 여러 stereotype에 분산되어 있으면 경고한다.
3
+ // 우아한테크코스 racing-car 미션에서 가장 흔하게 학생들이 헷갈리는 주제.
4
+ //
5
+ // 권장 3분류:
6
+ // - UI 형식 검증 (빈 문자열, 숫자 아님) → Interfacer
7
+ // - 사용자 입력 정책 (재입력 흐름) → Coordinator
8
+ // - 도메인 무결성 invariant (길이/중복/범위) → InformationHolder / Structurer 의 init
9
+ const VALIDATION_RE = /(검증|유효성|확인|검사|validate|valid|check|verify)/i;
10
+ function hasValidationResponsibility(card) {
11
+ const all = [...card.responsibilities.knowing, ...card.responsibilities.doing];
12
+ return all.some((r) => VALIDATION_RE.test(r));
13
+ }
14
+ function tokenize(text) {
15
+ return new Set(text
16
+ .toLowerCase()
17
+ .replace(/[()\[\]{}.,;:!?]/g, " ")
18
+ .split(/\s+/)
19
+ .filter((t) => t.length > 1));
20
+ }
21
+ function sharedDomainTokens(a, b) {
22
+ const at = tokenize([...a.responsibilities.knowing, ...a.responsibilities.doing].join(" "));
23
+ const bt = tokenize([...b.responsibilities.knowing, ...b.responsibilities.doing].join(" "));
24
+ const out = [];
25
+ for (const t of at)
26
+ if (bt.has(t))
27
+ out.push(t);
28
+ return out;
29
+ }
30
+ export function checkValidationLocation(design) {
31
+ const validators = design.classes.filter(hasValidationResponsibility);
32
+ if (validators.length < 2)
33
+ return [];
34
+ const out = [];
35
+ const seen = new Set();
36
+ for (let i = 0; i < validators.length; i++) {
37
+ for (let j = i + 1; j < validators.length; j++) {
38
+ const a = validators[i];
39
+ const b = validators[j];
40
+ const shared = sharedDomainTokens(a, b).filter((t) => !VALIDATION_RE.test(t));
41
+ if (shared.length < 2)
42
+ continue; // 같은 도메인 개념 공유가 약하면 분산이 아님
43
+ // 두 카드의 stereotype 조합으로 분산 패턴 판정
44
+ const stPair = [a.stereotype, b.stereotype].sort().join("+");
45
+ // 같은 stereotype이면 중복일 수 있으나 다른 stereotype이면 분산
46
+ if (a.stereotype === b.stereotype)
47
+ continue;
48
+ const key = `${a.id}+${b.id}`;
49
+ if (seen.has(key))
50
+ continue;
51
+ seen.add(key);
52
+ out.push(assertHasMultipleRemedies({
53
+ rule_id: "validation-misplacement",
54
+ severity: "warn",
55
+ target: { kind: "class", id: a.id },
56
+ message: `${a.name}(${a.stereotype})과 ${b.name}(${b.stereotype})이 같은 도메인 개념(${shared
57
+ .slice(0, 3)
58
+ .join(", ")})의 검증을 양쪽에서 수행합니다. ` +
59
+ `검증 책임이 분산되어 있어 변경 시 양쪽 모두 수정해야 할 위험이 있습니다.`,
60
+ evidence: {
61
+ paired_with: b.name,
62
+ paired_stereotype: b.stereotype,
63
+ shared_concepts: shared,
64
+ stereotype_pair: stPair,
65
+ guideline: "권장 3분류 — UI 형식: Interfacer / 입력 정책: Coordinator / 도메인 invariant: InformationHolder·Structurer init",
66
+ },
67
+ remedies: [
68
+ {
69
+ label: "도메인 invariant를 InformationHolder/Structurer init으로 통합",
70
+ summary: `검증의 *최종 진실*을 도메인 객체에 두고, 외부 검증은 제거한다. ` +
71
+ `호출 측은 도메인 생성 시점에 require/init으로 보호받는다.`,
72
+ tradeoffs: {
73
+ pros: [
74
+ "검증 위치가 단일 (이중 검증 제거)",
75
+ "도메인 진입점이 곧 검증 경계",
76
+ "리뷰어 다수가 권장한 표준 패턴",
77
+ ],
78
+ cons: [
79
+ "도메인 init이 무거워질 수 있음",
80
+ "재입력 흐름과 도메인 예외를 호출 측이 어떻게 처리할지 결정 필요",
81
+ ],
82
+ },
83
+ },
84
+ {
85
+ label: "Interfacer는 형식만, 도메인은 무결성만 (책임 분할)",
86
+ summary: `${a.name}/${b.name} 중 하나는 UI 형식 검증(빈 문자열, 숫자 아님)만, ` +
87
+ `다른 하나는 도메인 invariant(길이/중복/범위)만 갖도록 책임을 갈라낸다. ` +
88
+ `같은 토큰을 다루더라도 *검증의 종류*가 다르면 분산이 아님.`,
89
+ tradeoffs: {
90
+ pros: [
91
+ "각 stereotype에 맞는 검증만 남음",
92
+ "Interfacer 변경(UI 형식 변경)이 도메인에 영향 없음",
93
+ ],
94
+ cons: [
95
+ "같은 입력값이 두 단계를 거치므로 호출 흐름이 복잡해짐",
96
+ "어디까지가 \"형식\"이고 어디부터가 \"무결성\"인지 팀 합의 필요",
97
+ ],
98
+ },
99
+ },
100
+ {
101
+ label: "Coordinator가 재입력 흐름만 담당하도록 분리",
102
+ summary: `Coordinator는 \"검증 실패 시 재입력\" 같은 사용자 입력 정책만 갖고, ` +
103
+ `실제 검증 로직은 Interfacer(형식) 또는 도메인(무결성)이 담당한다.`,
104
+ tradeoffs: {
105
+ pros: [
106
+ "Coordinator가 검증 규칙을 *알지 않게* 됨",
107
+ "흐름 변경(재입력 vs 종료)이 검증 로직 변경과 분리됨",
108
+ ],
109
+ cons: [
110
+ "단순 미션에서는 과한 분리일 수 있음",
111
+ ],
112
+ },
113
+ },
114
+ ],
115
+ }));
116
+ }
117
+ }
118
+ return out;
119
+ }
120
+ //# sourceMappingURL=validationLocation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validationLocation.js","sourceRoot":"","sources":["../../src/validate/validationLocation.ts"],"names":[],"mappings":"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"}