kordoc 4.14.2 → 4.14.4

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 (151) hide show
  1. package/README.md +51 -6
  2. package/dist/{-AQKXLFIM.js → -Z4TJ3QGK.js} +13 -11
  3. package/dist/{chunk-QOMNEWCQ.cjs → chunk-5LAZQCUJ.cjs} +305 -31
  4. package/dist/chunk-5LAZQCUJ.cjs.map +1 -0
  5. package/dist/{chunk-7IAQ4HOK.js → chunk-6BWU6SQX.js} +1 -1
  6. package/dist/chunk-6BWU6SQX.js.map +1 -0
  7. package/dist/{chunk-FOJZNMMK.js → chunk-6CUIXJOC.js} +1 -1
  8. package/dist/chunk-6CUIXJOC.js.map +1 -0
  9. package/dist/{chunk-ZWD734EY.js → chunk-7SE4EZ45.js} +2 -2
  10. package/dist/{chunk-TSFS5VKD.js → chunk-D4U2TXDC.js} +332 -141
  11. package/dist/chunk-D4U2TXDC.js.map +1 -0
  12. package/dist/chunk-DPWWXUOG.js +2222 -0
  13. package/dist/chunk-DPWWXUOG.js.map +1 -0
  14. package/dist/{chunk-GDW4YP7K.js → chunk-GLSBEEZJ.js} +2 -2
  15. package/dist/{chunk-JQEFP45L.js → chunk-GUJ4Q73I.js} +2 -2
  16. package/dist/{chunk-ZWOFQRIB.js → chunk-HIJUKZHM.js} +3 -3
  17. package/dist/chunk-IMAAFSAX.cjs +1352 -0
  18. package/dist/chunk-IMAAFSAX.cjs.map +1 -0
  19. package/dist/{chunk-TNCKOL2O.js → chunk-LCW7SEPG.js} +2 -2
  20. package/dist/chunk-LFSQAMSM.js +1352 -0
  21. package/dist/chunk-LFSQAMSM.js.map +1 -0
  22. package/dist/chunk-MG6DJEX4.js +1299 -0
  23. package/dist/chunk-MG6DJEX4.js.map +1 -0
  24. package/dist/{chunk-QC5T6D4J.js → chunk-NLU6LBLY.js} +299 -25
  25. package/dist/chunk-NLU6LBLY.js.map +1 -0
  26. package/dist/{chunk-EQZI77PP.cjs → chunk-QEJUY6SK.cjs} +3 -3
  27. package/dist/{chunk-EQZI77PP.cjs.map → chunk-QEJUY6SK.cjs.map} +1 -1
  28. package/dist/{chunk-VQ5W4MYO.js → chunk-QIF2VXBQ.js} +298 -24
  29. package/dist/chunk-QIF2VXBQ.js.map +1 -0
  30. package/dist/{chunk-UET462HB.js → chunk-TITDJWVZ.js} +2 -2
  31. package/dist/{chunk-247ANM72.cjs → chunk-USHQCF5T.cjs} +870 -147
  32. package/dist/chunk-USHQCF5T.cjs.map +1 -0
  33. package/dist/{chunk-C7FQBSON.js → chunk-V3DX4DUF.js} +2 -2
  34. package/dist/{chunk-DOGPOY4B.js → chunk-VDN7LMPL.js} +2 -2
  35. package/dist/{chunk-EDNJLUSE.js → chunk-VJIL6PIL.js} +2 -2
  36. package/dist/{chunk-L7DMSMAG.cjs → chunk-VWUYVEFN.cjs} +1 -1
  37. package/dist/chunk-VWUYVEFN.cjs.map +1 -0
  38. package/dist/{chunk-HR2XNERB.cjs → chunk-WJHAU73B.cjs} +2 -2
  39. package/dist/{chunk-HR2XNERB.cjs.map → chunk-WJHAU73B.cjs.map} +1 -1
  40. package/dist/{chunk-NS55SM7A.js → chunk-WJJGW5PL.js} +2 -2
  41. package/dist/{chunk-EISO3POT.js → chunk-XVXHXQIO.js} +788 -194
  42. package/dist/chunk-XVXHXQIO.js.map +1 -0
  43. package/dist/{chunk-ILU76UF3.js → chunk-YAKC46HZ.js} +2 -2
  44. package/dist/chunk-YAKC46HZ.js.map +1 -0
  45. package/dist/{chunk-3DUADAY2.js → chunk-YAVHVFRY.js} +851 -128
  46. package/dist/chunk-YAVHVFRY.js.map +1 -0
  47. package/dist/{chunk-A7QC2ZVP.js → chunk-YT3GC62E.js} +851 -128
  48. package/dist/chunk-YT3GC62E.js.map +1 -0
  49. package/dist/chunks-CCMRL4MJ.js +10 -0
  50. package/dist/cli.js +228 -97
  51. package/dist/cli.js.map +1 -1
  52. package/dist/{formula-PJJ6S3Z2.cjs → formula-5LOVHAKE.cjs} +9 -9
  53. package/dist/{formula-PJJ6S3Z2.cjs.map → formula-5LOVHAKE.cjs.map} +1 -1
  54. package/dist/{formula-JGFTXWYT.js → formula-7RANCW5L.js} +3 -3
  55. package/dist/{formula-5S7WWXGH.js → formula-7UYJOVTB.js} +4 -4
  56. package/dist/{image-ocr-WCAYXLOA.js → image-ocr-I6JOCATS.js} +34 -16
  57. package/dist/image-ocr-I6JOCATS.js.map +1 -0
  58. package/dist/{image-ocr-ZTYAGV3W.cjs → image-ocr-NYBJEOH2.cjs} +36 -18
  59. package/dist/image-ocr-NYBJEOH2.cjs.map +1 -0
  60. package/dist/{image-ocr-FLIL7MGN.js → image-ocr-ZV6PDBUQ.js} +32 -14
  61. package/dist/image-ocr-ZV6PDBUQ.js.map +1 -0
  62. package/dist/index.cjs +4048 -1216
  63. package/dist/index.cjs.map +1 -1
  64. package/dist/index.d.cts +66 -28
  65. package/dist/index.d.ts +66 -28
  66. package/dist/index.js +3487 -655
  67. package/dist/index.js.map +1 -1
  68. package/dist/mcp.js +74 -53
  69. package/dist/mcp.js.map +1 -1
  70. package/dist/{model-bundle-FSPZZ2EM.js → model-bundle-2C5IYDLE.js} +5 -5
  71. package/dist/{models-CJPAQK5R.js → models-SEQZHZFT.js} +5 -5
  72. package/dist/{parser-SCUTZAIJ.js → parser-3FNXEP6T.js} +708 -250
  73. package/dist/parser-3FNXEP6T.js.map +1 -0
  74. package/dist/{parser-A4TMPJAM.js → parser-FJBJXRJK.js} +708 -250
  75. package/dist/parser-FJBJXRJK.js.map +1 -0
  76. package/dist/{parser-VCXE4I5A.cjs → parser-HVEKF73B.cjs} +733 -275
  77. package/dist/parser-HVEKF73B.cjs.map +1 -0
  78. package/dist/pdf-ocr-JRDBJ6TA.cjs +14 -0
  79. package/dist/{pdf-ocr-MBZZ57LD.cjs.map → pdf-ocr-JRDBJ6TA.cjs.map} +1 -1
  80. package/dist/pdf-ocr-UUBWBEHL.js +16 -0
  81. package/dist/pdf-ocr-VJSF2SQC.js +13 -0
  82. package/dist/{profile-io-LBM263K7.js → profile-io-RUFZOZO6.js} +3 -3
  83. package/dist/{rasterize-46RG4ZF6.js → rasterize-IOYXR5SI.js} +3 -3
  84. package/dist/redact-NMIKVHMP.js +18 -0
  85. package/dist/redact-doc-QBHNJ2BU.js +1284 -0
  86. package/dist/redact-doc-QBHNJ2BU.js.map +1 -0
  87. package/dist/{render-NGP5T24S.js → render-YZ2TEC3N.js} +7 -7
  88. package/dist/seal-ECV44TUH.js +10 -0
  89. package/dist/{setup-AU4OCHNH.js → setup-MPIEP6XT.js} +3 -3
  90. package/dist/visual-ICMOWUCR.js +19 -0
  91. package/dist/{watch-MKPUCPXM.js → watch-RYO7MN5B.js} +12 -12
  92. package/package.json +2 -2
  93. package/dist/chunk-247ANM72.cjs.map +0 -1
  94. package/dist/chunk-3DUADAY2.js.map +0 -1
  95. package/dist/chunk-422427XJ.cjs +0 -571
  96. package/dist/chunk-422427XJ.cjs.map +0 -1
  97. package/dist/chunk-7IAQ4HOK.js.map +0 -1
  98. package/dist/chunk-A7QC2ZVP.js.map +0 -1
  99. package/dist/chunk-DZIXKL7E.js +0 -145
  100. package/dist/chunk-DZIXKL7E.js.map +0 -1
  101. package/dist/chunk-EISO3POT.js.map +0 -1
  102. package/dist/chunk-EP7KOI2V.js +0 -571
  103. package/dist/chunk-EP7KOI2V.js.map +0 -1
  104. package/dist/chunk-FOJZNMMK.js.map +0 -1
  105. package/dist/chunk-ILU76UF3.js.map +0 -1
  106. package/dist/chunk-KVWV4ULP.js +0 -516
  107. package/dist/chunk-KVWV4ULP.js.map +0 -1
  108. package/dist/chunk-L7DMSMAG.cjs.map +0 -1
  109. package/dist/chunk-QC5T6D4J.js.map +0 -1
  110. package/dist/chunk-QOMNEWCQ.cjs.map +0 -1
  111. package/dist/chunk-TSFS5VKD.js.map +0 -1
  112. package/dist/chunk-VQ5W4MYO.js.map +0 -1
  113. package/dist/chunks-SX77P5CV.js +0 -10
  114. package/dist/image-ocr-FLIL7MGN.js.map +0 -1
  115. package/dist/image-ocr-WCAYXLOA.js.map +0 -1
  116. package/dist/image-ocr-ZTYAGV3W.cjs.map +0 -1
  117. package/dist/parser-A4TMPJAM.js.map +0 -1
  118. package/dist/parser-SCUTZAIJ.js.map +0 -1
  119. package/dist/parser-VCXE4I5A.cjs.map +0 -1
  120. package/dist/pdf-ocr-76SAUXMZ.js +0 -13
  121. package/dist/pdf-ocr-CPU55CVF.js +0 -16
  122. package/dist/pdf-ocr-MBZZ57LD.cjs +0 -14
  123. package/dist/redact-7ILEAUTS.js +0 -12
  124. package/dist/seal-RGUPOLXD.js +0 -10
  125. package/dist/visual-NZLYIYEM.js +0 -19
  126. /package/dist/{-AQKXLFIM.js.map → -Z4TJ3QGK.js.map} +0 -0
  127. /package/dist/{chunk-ZWD734EY.js.map → chunk-7SE4EZ45.js.map} +0 -0
  128. /package/dist/{chunk-GDW4YP7K.js.map → chunk-GLSBEEZJ.js.map} +0 -0
  129. /package/dist/{chunk-JQEFP45L.js.map → chunk-GUJ4Q73I.js.map} +0 -0
  130. /package/dist/{chunk-ZWOFQRIB.js.map → chunk-HIJUKZHM.js.map} +0 -0
  131. /package/dist/{chunk-TNCKOL2O.js.map → chunk-LCW7SEPG.js.map} +0 -0
  132. /package/dist/{chunk-UET462HB.js.map → chunk-TITDJWVZ.js.map} +0 -0
  133. /package/dist/{chunk-C7FQBSON.js.map → chunk-V3DX4DUF.js.map} +0 -0
  134. /package/dist/{chunk-DOGPOY4B.js.map → chunk-VDN7LMPL.js.map} +0 -0
  135. /package/dist/{chunk-EDNJLUSE.js.map → chunk-VJIL6PIL.js.map} +0 -0
  136. /package/dist/{chunk-NS55SM7A.js.map → chunk-WJJGW5PL.js.map} +0 -0
  137. /package/dist/{chunks-SX77P5CV.js.map → chunks-CCMRL4MJ.js.map} +0 -0
  138. /package/dist/{formula-JGFTXWYT.js.map → formula-7RANCW5L.js.map} +0 -0
  139. /package/dist/{formula-5S7WWXGH.js.map → formula-7UYJOVTB.js.map} +0 -0
  140. /package/dist/{model-bundle-FSPZZ2EM.js.map → model-bundle-2C5IYDLE.js.map} +0 -0
  141. /package/dist/{models-CJPAQK5R.js.map → models-SEQZHZFT.js.map} +0 -0
  142. /package/dist/{pdf-ocr-76SAUXMZ.js.map → pdf-ocr-UUBWBEHL.js.map} +0 -0
  143. /package/dist/{pdf-ocr-CPU55CVF.js.map → pdf-ocr-VJSF2SQC.js.map} +0 -0
  144. /package/dist/{profile-io-LBM263K7.js.map → profile-io-RUFZOZO6.js.map} +0 -0
  145. /package/dist/{rasterize-46RG4ZF6.js.map → rasterize-IOYXR5SI.js.map} +0 -0
  146. /package/dist/{redact-7ILEAUTS.js.map → redact-NMIKVHMP.js.map} +0 -0
  147. /package/dist/{render-NGP5T24S.js.map → render-YZ2TEC3N.js.map} +0 -0
  148. /package/dist/{seal-RGUPOLXD.js.map → seal-ECV44TUH.js.map} +0 -0
  149. /package/dist/{setup-AU4OCHNH.js.map → setup-MPIEP6XT.js.map} +0 -0
  150. /package/dist/{visual-NZLYIYEM.js.map → visual-ICMOWUCR.js.map} +0 -0
  151. /package/dist/{watch-MKPUCPXM.js.map → watch-RYO7MN5B.js.map} +0 -0
@@ -0,0 +1,2222 @@
1
+ #!/usr/bin/env node
2
+
3
+ // src/redact-name-address.ts
4
+ var alt = (words) => [...words].sort((a, b) => b.length - a.length).join("|");
5
+ var spaced = (words) => alt(words.map((w) => w.split("").join("\\s?")));
6
+ var SIDO = [
7
+ "\uC11C\uC6B8\uD2B9\uBCC4\uC2DC",
8
+ "\uBD80\uC0B0\uAD11\uC5ED\uC2DC",
9
+ "\uB300\uAD6C\uAD11\uC5ED\uC2DC",
10
+ "\uC778\uCC9C\uAD11\uC5ED\uC2DC",
11
+ "\uAD11\uC8FC\uAD11\uC5ED\uC2DC",
12
+ "\uB300\uC804\uAD11\uC5ED\uC2DC",
13
+ "\uC6B8\uC0B0\uAD11\uC5ED\uC2DC",
14
+ "\uC138\uC885\uD2B9\uBCC4\uC790\uCE58\uC2DC",
15
+ "\uACBD\uAE30\uB3C4",
16
+ "\uAC15\uC6D0\uD2B9\uBCC4\uC790\uCE58\uB3C4",
17
+ "\uAC15\uC6D0\uB3C4",
18
+ "\uCDA9\uCCAD\uBD81\uB3C4",
19
+ "\uCDA9\uCCAD\uB0A8\uB3C4",
20
+ "\uC804\uBD81\uD2B9\uBCC4\uC790\uCE58\uB3C4",
21
+ "\uC804\uB77C\uBD81\uB3C4",
22
+ "\uC804\uB77C\uB0A8\uB3C4",
23
+ "\uACBD\uC0C1\uBD81\uB3C4",
24
+ "\uACBD\uC0C1\uB0A8\uB3C4",
25
+ "\uC81C\uC8FC\uD2B9\uBCC4\uC790\uCE58\uB3C4",
26
+ "\uC81C\uC8FC\uB3C4",
27
+ "\uC804\uB0A8\uAD11\uC8FC\uD1B5\uD569\uD2B9\uBCC4\uC2DC",
28
+ "\uC11C\uC6B8\uC2DC",
29
+ "\uBD80\uC0B0\uC2DC",
30
+ "\uB300\uAD6C\uC2DC",
31
+ "\uC778\uCC9C\uC2DC",
32
+ "\uAD11\uC8FC\uC2DC",
33
+ "\uB300\uC804\uC2DC",
34
+ "\uC6B8\uC0B0\uC2DC",
35
+ "\uC138\uC885\uC2DC",
36
+ "\uC11C\uC6B8",
37
+ "\uBD80\uC0B0",
38
+ "\uB300\uAD6C",
39
+ "\uC778\uCC9C",
40
+ "\uAD11\uC8FC",
41
+ "\uB300\uC804",
42
+ "\uC6B8\uC0B0",
43
+ "\uC138\uC885",
44
+ "\uACBD\uAE30",
45
+ "\uAC15\uC6D0",
46
+ "\uCDA9\uBD81",
47
+ "\uCDA9\uB0A8",
48
+ "\uC804\uBD81",
49
+ "\uC804\uB0A8",
50
+ "\uACBD\uBD81",
51
+ "\uACBD\uB0A8",
52
+ "\uC81C\uC8FC"
53
+ ];
54
+ var SIGUNGU = [
55
+ // 서울
56
+ "\uC885\uB85C\uAD6C",
57
+ "\uC911\uAD6C",
58
+ "\uC6A9\uC0B0\uAD6C",
59
+ "\uC131\uB3D9\uAD6C",
60
+ "\uAD11\uC9C4\uAD6C",
61
+ "\uB3D9\uB300\uBB38\uAD6C",
62
+ "\uC911\uB791\uAD6C",
63
+ "\uC131\uBD81\uAD6C",
64
+ "\uAC15\uBD81\uAD6C",
65
+ "\uB3C4\uBD09\uAD6C",
66
+ "\uB178\uC6D0\uAD6C",
67
+ "\uC740\uD3C9\uAD6C",
68
+ "\uC11C\uB300\uBB38\uAD6C",
69
+ "\uB9C8\uD3EC\uAD6C",
70
+ "\uC591\uCC9C\uAD6C",
71
+ "\uAC15\uC11C\uAD6C",
72
+ "\uAD6C\uB85C\uAD6C",
73
+ "\uAE08\uCC9C\uAD6C",
74
+ "\uC601\uB4F1\uD3EC\uAD6C",
75
+ "\uB3D9\uC791\uAD6C",
76
+ "\uAD00\uC545\uAD6C",
77
+ "\uC11C\uCD08\uAD6C",
78
+ "\uAC15\uB0A8\uAD6C",
79
+ "\uC1A1\uD30C\uAD6C",
80
+ "\uAC15\uB3D9\uAD6C",
81
+ // 부산·대구·인천·광주·대전·울산
82
+ "\uC11C\uAD6C",
83
+ "\uB3D9\uAD6C",
84
+ "\uB0A8\uAD6C",
85
+ "\uBD81\uAD6C",
86
+ "\uC601\uB3C4\uAD6C",
87
+ "\uBD80\uC0B0\uC9C4\uAD6C",
88
+ "\uB3D9\uB798\uAD6C",
89
+ "\uD574\uC6B4\uB300\uAD6C",
90
+ "\uC0AC\uD558\uAD6C",
91
+ "\uAE08\uC815\uAD6C",
92
+ "\uC5F0\uC81C\uAD6C",
93
+ "\uC218\uC601\uAD6C",
94
+ "\uC0AC\uC0C1\uAD6C",
95
+ "\uAE30\uC7A5\uAD70",
96
+ "\uC218\uC131\uAD6C",
97
+ "\uB2EC\uC11C\uAD6C",
98
+ "\uB2EC\uC131\uAD70",
99
+ "\uAD70\uC704\uAD70",
100
+ "\uC81C\uBB3C\uD3EC\uAD6C",
101
+ "\uC601\uC885\uAD6C",
102
+ "\uBBF8\uCD94\uD640\uAD6C",
103
+ "\uC5F0\uC218\uAD6C",
104
+ "\uB0A8\uB3D9\uAD6C",
105
+ "\uBD80\uD3C9\uAD6C",
106
+ "\uACC4\uC591\uAD6C",
107
+ "\uC11C\uD574\uAD6C",
108
+ "\uAC80\uB2E8\uAD6C",
109
+ "\uAC15\uD654\uAD70",
110
+ "\uC639\uC9C4\uAD70",
111
+ "\uAD11\uC0B0\uAD6C",
112
+ "\uC720\uC131\uAD6C",
113
+ "\uB300\uB355\uAD6C",
114
+ "\uC6B8\uC8FC\uAD70",
115
+ // 경기
116
+ "\uC218\uC6D0\uC2DC",
117
+ "\uC131\uB0A8\uC2DC",
118
+ "\uC758\uC815\uBD80\uC2DC",
119
+ "\uC548\uC591\uC2DC",
120
+ "\uAD11\uBA85\uC2DC",
121
+ "\uD3C9\uD0DD\uC2DC",
122
+ "\uB3D9\uB450\uCC9C\uC2DC",
123
+ "\uC548\uC0B0\uC2DC",
124
+ "\uACE0\uC591\uC2DC",
125
+ "\uACFC\uCC9C\uC2DC",
126
+ "\uAD6C\uB9AC\uC2DC",
127
+ "\uB0A8\uC591\uC8FC\uC2DC",
128
+ "\uC624\uC0B0\uC2DC",
129
+ "\uC2DC\uD765\uC2DC",
130
+ "\uAD70\uD3EC\uC2DC",
131
+ "\uC758\uC655\uC2DC",
132
+ "\uD558\uB0A8\uC2DC",
133
+ "\uC6A9\uC778\uC2DC",
134
+ "\uD30C\uC8FC\uC2DC",
135
+ "\uC774\uCC9C\uC2DC",
136
+ "\uC548\uC131\uC2DC",
137
+ "\uAE40\uD3EC\uC2DC",
138
+ "\uD654\uC131\uC2DC",
139
+ "\uAD11\uC8FC\uC2DC",
140
+ "\uC591\uC8FC\uC2DC",
141
+ "\uD3EC\uCC9C\uC2DC",
142
+ "\uC5EC\uC8FC\uC2DC",
143
+ "\uBD80\uCC9C\uC2DC",
144
+ "\uC5F0\uCC9C\uAD70",
145
+ "\uAC00\uD3C9\uAD70",
146
+ "\uC591\uD3C9\uAD70",
147
+ "\uC5EC\uC8FC\uAD70",
148
+ "\uC7A5\uC548\uAD6C",
149
+ "\uAD8C\uC120\uAD6C",
150
+ "\uD314\uB2EC\uAD6C",
151
+ "\uC601\uD1B5\uAD6C",
152
+ "\uC218\uC815\uAD6C",
153
+ "\uC911\uC6D0\uAD6C",
154
+ "\uBD84\uB2F9\uAD6C",
155
+ "\uB9CC\uC548\uAD6C",
156
+ "\uB3D9\uC548\uAD6C",
157
+ "\uC0C1\uB85D\uAD6C",
158
+ "\uB2E8\uC6D0\uAD6C",
159
+ "\uB355\uC591\uAD6C",
160
+ "\uC77C\uC0B0\uB3D9\uAD6C",
161
+ "\uC77C\uC0B0\uC11C\uAD6C",
162
+ "\uCC98\uC778\uAD6C",
163
+ "\uAE30\uD765\uAD6C",
164
+ "\uC218\uC9C0\uAD6C",
165
+ "\uD6A8\uD589\uAD6C",
166
+ "\uB9CC\uC138\uAD6C",
167
+ "\uB3D9\uD0C4\uAD6C",
168
+ "\uBCD1\uC810\uAD6C",
169
+ "\uC6D0\uBBF8\uAD6C",
170
+ "\uC18C\uC0AC\uAD6C",
171
+ "\uC624\uC815\uAD6C",
172
+ // 강원
173
+ "\uCD98\uCC9C\uC2DC",
174
+ "\uC6D0\uC8FC\uC2DC",
175
+ "\uAC15\uB989\uC2DC",
176
+ "\uB3D9\uD574\uC2DC",
177
+ "\uD0DC\uBC31\uC2DC",
178
+ "\uC18D\uCD08\uC2DC",
179
+ "\uC0BC\uCC99\uC2DC",
180
+ "\uD64D\uCC9C\uAD70",
181
+ "\uD6A1\uC131\uAD70",
182
+ "\uC601\uC6D4\uAD70",
183
+ "\uD3C9\uCC3D\uAD70",
184
+ "\uC815\uC120\uAD70",
185
+ "\uCCA0\uC6D0\uAD70",
186
+ "\uD654\uCC9C\uAD70",
187
+ "\uC591\uAD6C\uAD70",
188
+ "\uC778\uC81C\uAD70",
189
+ "\uACE0\uC131\uAD70",
190
+ "\uC591\uC591\uAD70",
191
+ // 충북·충남
192
+ "\uCDA9\uC8FC\uC2DC",
193
+ "\uC81C\uCC9C\uC2DC",
194
+ "\uCCAD\uC8FC\uC2DC",
195
+ "\uBCF4\uC740\uAD70",
196
+ "\uC625\uCC9C\uAD70",
197
+ "\uC601\uB3D9\uAD70",
198
+ "\uC9C4\uCC9C\uAD70",
199
+ "\uAD34\uC0B0\uAD70",
200
+ "\uC74C\uC131\uAD70",
201
+ "\uB2E8\uC591\uAD70",
202
+ "\uC99D\uD3C9\uAD70",
203
+ "\uCCAD\uC6D0\uAD70",
204
+ "\uC0C1\uB2F9\uAD6C",
205
+ "\uC11C\uC6D0\uAD6C",
206
+ "\uD765\uB355\uAD6C",
207
+ "\uCCAD\uC6D0\uAD6C",
208
+ "\uCC9C\uC548\uC2DC",
209
+ "\uACF5\uC8FC\uC2DC",
210
+ "\uBCF4\uB839\uC2DC",
211
+ "\uC544\uC0B0\uC2DC",
212
+ "\uC11C\uC0B0\uC2DC",
213
+ "\uB17C\uC0B0\uC2DC",
214
+ "\uACC4\uB8E1\uC2DC",
215
+ "\uB2F9\uC9C4\uC2DC",
216
+ "\uAE08\uC0B0\uAD70",
217
+ "\uBD80\uC5EC\uAD70",
218
+ "\uC11C\uCC9C\uAD70",
219
+ "\uCCAD\uC591\uAD70",
220
+ "\uD64D\uC131\uAD70",
221
+ "\uC608\uC0B0\uAD70",
222
+ "\uD0DC\uC548\uAD70",
223
+ "\uB2F9\uC9C4\uAD70",
224
+ "\uC5F0\uAE30\uAD70",
225
+ "\uB3D9\uB0A8\uAD6C",
226
+ "\uC11C\uBD81\uAD6C",
227
+ // 전북·전남
228
+ "\uC804\uC8FC\uC2DC",
229
+ "\uAD70\uC0B0\uC2DC",
230
+ "\uC775\uC0B0\uC2DC",
231
+ "\uC815\uC74D\uC2DC",
232
+ "\uB0A8\uC6D0\uC2DC",
233
+ "\uAE40\uC81C\uC2DC",
234
+ "\uC644\uC8FC\uAD70",
235
+ "\uC9C4\uC548\uAD70",
236
+ "\uBB34\uC8FC\uAD70",
237
+ "\uC7A5\uC218\uAD70",
238
+ "\uC784\uC2E4\uAD70",
239
+ "\uC21C\uCC3D\uAD70",
240
+ "\uACE0\uCC3D\uAD70",
241
+ "\uBD80\uC548\uAD70",
242
+ "\uC644\uC0B0\uAD6C",
243
+ "\uB355\uC9C4\uAD6C",
244
+ "\uBAA9\uD3EC\uC2DC",
245
+ "\uC5EC\uC218\uC2DC",
246
+ "\uC21C\uCC9C\uC2DC",
247
+ "\uB098\uC8FC\uC2DC",
248
+ "\uAD11\uC591\uC2DC",
249
+ "\uB2F4\uC591\uAD70",
250
+ "\uACE1\uC131\uAD70",
251
+ "\uAD6C\uB840\uAD70",
252
+ "\uACE0\uD765\uAD70",
253
+ "\uBCF4\uC131\uAD70",
254
+ "\uD654\uC21C\uAD70",
255
+ "\uC7A5\uD765\uAD70",
256
+ "\uAC15\uC9C4\uAD70",
257
+ "\uD574\uB0A8\uAD70",
258
+ "\uC601\uC554\uAD70",
259
+ "\uBB34\uC548\uAD70",
260
+ "\uD568\uD3C9\uAD70",
261
+ "\uC601\uAD11\uAD70",
262
+ "\uC7A5\uC131\uAD70",
263
+ "\uC644\uB3C4\uAD70",
264
+ "\uC9C4\uB3C4\uAD70",
265
+ "\uC2E0\uC548\uAD70",
266
+ // 경북·경남
267
+ "\uD3EC\uD56D\uC2DC",
268
+ "\uACBD\uC8FC\uC2DC",
269
+ "\uAE40\uCC9C\uC2DC",
270
+ "\uC548\uB3D9\uC2DC",
271
+ "\uAD6C\uBBF8\uC2DC",
272
+ "\uC601\uC8FC\uC2DC",
273
+ "\uC601\uCC9C\uC2DC",
274
+ "\uC0C1\uC8FC\uC2DC",
275
+ "\uBB38\uACBD\uC2DC",
276
+ "\uACBD\uC0B0\uC2DC",
277
+ "\uC758\uC131\uAD70",
278
+ "\uCCAD\uC1A1\uAD70",
279
+ "\uC601\uC591\uAD70",
280
+ "\uC601\uB355\uAD70",
281
+ "\uCCAD\uB3C4\uAD70",
282
+ "\uACE0\uB839\uAD70",
283
+ "\uC131\uC8FC\uAD70",
284
+ "\uCE60\uACE1\uAD70",
285
+ "\uC608\uCC9C\uAD70",
286
+ "\uBD09\uD654\uAD70",
287
+ "\uC6B8\uC9C4\uAD70",
288
+ "\uC6B8\uB989\uAD70",
289
+ "\uCC3D\uC6D0\uC2DC",
290
+ "\uC9C4\uC8FC\uC2DC",
291
+ "\uD1B5\uC601\uC2DC",
292
+ "\uC0AC\uCC9C\uC2DC",
293
+ "\uAE40\uD574\uC2DC",
294
+ "\uBC00\uC591\uC2DC",
295
+ "\uAC70\uC81C\uC2DC",
296
+ "\uC591\uC0B0\uC2DC",
297
+ "\uC758\uB839\uAD70",
298
+ "\uD568\uC548\uAD70",
299
+ "\uCC3D\uB155\uAD70",
300
+ "\uB0A8\uD574\uAD70",
301
+ "\uD558\uB3D9\uAD70",
302
+ "\uC0B0\uCCAD\uAD70",
303
+ "\uD568\uC591\uAD70",
304
+ "\uAC70\uCC3D\uAD70",
305
+ "\uD569\uCC9C\uAD70",
306
+ "\uC758\uCC3D\uAD6C",
307
+ "\uC131\uC0B0\uAD6C",
308
+ "\uB9C8\uC0B0\uD569\uD3EC\uAD6C",
309
+ "\uB9C8\uC0B0\uD68C\uC6D0\uAD6C",
310
+ "\uC9C4\uD574\uAD6C",
311
+ "\uB9C8\uC0B0\uC2DC",
312
+ "\uC9C4\uD574\uC2DC",
313
+ // 제주·세종
314
+ "\uC81C\uC8FC\uC2DC",
315
+ "\uC11C\uADC0\uD3EC\uC2DC",
316
+ "\uC138\uC885\uC2DC"
317
+ ];
318
+ var REGION = `(?:(?:${alt(SIDO)})(?:\\s{0,2}(?:${alt(SIGUNGU)})){0,2}|(?:${alt(SIGUNGU)})(?:\\s{0,2}(?:${alt(SIGUNGU)}))?)`;
319
+ var EUPMYEON = "[\uAC00-\uD7A3]{1,4}(?:\uC74D|\uBA74)";
320
+ var DONGRI = "[\uAC00-\uD7A3]{1,6}(?:\\d{0,2}(?:\uB3D9|\uB9AC)|\\d{1,2}\uAC00)";
321
+ var ROAD = "[\uAC00-\uD7A30-9]{1,15}(?<!\uC73C)(?:\uB85C|\uAE38)(?:\\s\\d{1,4}(?:\uBC88|[\uAC00-\uD7A3])?\uAE38)?";
322
+ var ADDR_END = "(?![0-9])(?!-\\d)(?![.,]\\d)(?![%\uFF05\u33A1\u339E\u339D\u339C\u33CA\u2103\xB0])(?=$|[^\uAC00-\uD7A3A-Za-z]|(?:\uC5D0\uC11C|\uC5D0\uAC8C|\uC5D0|\uC758|\uC740|\uB294|\uC774|\uAC00|\uC744|\uB97C|\uC640|\uACFC|\uB85C|\uC73C\uB85C|\uAE4C\uC9C0|\uBD80\uD130|\uBC88\uC9C0|\uC785\uB2C8\uB2E4|\uC774\uB2E4|\uC774\uBA70|\uC774\uACE0|\uC678|\uC77C\uB300|\uC77C\uC6D0|\uBD80\uADFC|\uC778\uADFC|\uC18C\uC7AC|\uC8FC\uBCC0|\uB0B4|\uC55E|\uC606|\uCABD))";
323
+ var DETAIL = "(?:(?:\\s?,\\s?|\\s)(?:[\uAC00-\uD7A3A-Za-z0-9]{1,20}\\s){0,2}(?:\uC81C|\uC9C0\uD558|B)?\\s?\\d{1,5}(?:-\\d{1,4})?(?:\uD638|\uCE35)" + ADDR_END + ")?";
324
+ var BLDG = "(?:\uC9C0\uD558\\s?)?\\d{1,5}(?:-\\d{1,5})?";
325
+ var LOT = "(?:\uC0B0\\s?)?\\d{1,5}(?:-\\d{1,5})?(?:\\s?\uBC88\uC9C0)?";
326
+ var ADDR_LABEL = spaced(["\uC8FC\uC18C", "\uC8FC\uC18C\uC9C0", "\uD604\uC8FC\uC18C", "\uAC70\uC8FC\uC9C0", "\uC18C\uC7AC\uC9C0", "\uBCF8\uC810", "\uC0AC\uC5C5\uC7A5", "\uC601\uC5C5\uC18C"]);
327
+ var PLACEHOLDER_NO = /(?<![\d-])0+(?![\d])/;
328
+ var realNumber = (x) => !PLACEHOLDER_NO.test(x.m.groups?.rest ?? "");
329
+ var ADDRESS_VARIANTS = [
330
+ {
331
+ // 도로명 주소
332
+ re: new RegExp(`(?<![\uAC00-\uD7A3])(?<region>${REGION})\\s{1,2}(?<rest>(?:${EUPMYEON}\\s{1,2})?${ROAD}\\s{0,2}${BLDG}${ADDR_END}${DETAIL})`, "dg"),
333
+ mask: ["rest"],
334
+ ok: realNumber
335
+ },
336
+ {
337
+ // 지번 주소 (동·리 + 번지)
338
+ re: new RegExp(`(?<![\uAC00-\uD7A3])(?<region>${REGION})\\s{1,2}(?<rest>(?:${EUPMYEON}\\s{1,2})?${DONGRI}\\s{1,2}${LOT}${ADDR_END}${DETAIL})`, "dg"),
339
+ mask: ["rest"],
340
+ ok: realNumber
341
+ },
342
+ {
343
+ // 동 + 건물 이름 + N동 N호 (번지 없이 공동주택만 적은 꼴)
344
+ re: new RegExp(`(?<![\uAC00-\uD7A3])(?<region>${REGION})\\s{1,2}(?<rest>(?:${EUPMYEON}\\s{1,2})?${DONGRI}\\s{1,2}(?:[\uAC00-\uD7A3A-Za-z0-9]{2,20}\\s)?\\d{1,4}\uB3D9\\s?\\d{1,5}\uD638${ADDR_END})`, "dg"),
345
+ mask: ["rest"],
346
+ ok: realNumber
347
+ },
348
+ {
349
+ // 라벨 뒤 — 행정구역 없이 도로명·동리부터 ("주소: 자양로 117", "소재지 구월동 1138")
350
+ re: new RegExp(`(?:${ADDR_LABEL})\\s{0,2}[:\uFF1A]?\\s{0,2}(?<rest>(?:${EUPMYEON}\\s{1,2})?(?:${ROAD}\\s{0,2}${BLDG}|${DONGRI}\\s{1,2}${LOT})${ADDR_END}${DETAIL})`, "dg"),
351
+ span: "rest",
352
+ mask: ["rest"],
353
+ ok: realNumber
354
+ }
355
+ ];
356
+ var DOUBLE_SURNAMES = ["\uB0A8\uAD81", "\uD669\uBCF4", "\uC81C\uAC08", "\uC120\uC6B0", "\uB3C5\uACE0", "\uC0AC\uACF5", "\uC11C\uBB38", "\uB3D9\uBC29"];
357
+ var COMMON_SURNAMES = "\uAE40\uC774\uBC15\uCD5C\uC815\uAC15\uC870\uC724\uC7A5\uC784\uD55C\uC624\uC11C\uC2E0\uAD8C\uD669\uC548\uC1A1\uC804\uD64D\uC720\uACE0\uBB38\uC591\uC190\uBC30\uBC31\uD5C8\uB0A8\uC2EC\uB178\uD558\uACFD\uC131\uCC28\uC8FC\uC6B0\uAD6C\uBBFC\uB958\uB098\uC9C4\uC9C0\uC5C4\uCC44\uC6D0\uCC9C\uBC29\uACF5\uD604\uD568\uBCC0\uC5FC\uC5EC\uCD94\uB3C4\uC18C\uC11D\uC120\uC124\uB9C8\uAE38\uC5F0\uC704\uD45C\uBA85";
358
+ var RARE_SURNAMES = "\uAE30\uBC18\uB77C\uC655\uAE08\uC625\uC721\uC778\uB9F9\uC81C\uBAA8\uD0C1\uAD6D\uC5B4\uC740\uD3B8\uC6A9\uC608\uACBD\uBD09\uBCF5\uD0DC\uBAA9\uD615\uD53C\uB450\uAC10\uC74C\uBE48\uB3D9\uC628\uD638\uBC94\uC88C\uD33D\uC2B9\uAC04\uAC08\uB2E8\uACAC\uB2F9\uD654\uCC3D\uC639\uD3C9\uBE59\uB9AC";
359
+ var ALL_SURNAMES = COMMON_SURNAMES + RARE_SURNAMES;
360
+ var PARTICLE_ALWAYS = [
361
+ "\uC5D0\uAC8C\uC11C",
362
+ "\uAED8\uC11C\uB294",
363
+ "\uAED8\uC11C\uB3C4",
364
+ "\uAED8\uC11C",
365
+ "\uC5D0\uAC8C\uB294",
366
+ "\uC5D0\uAC8C\uB3C4",
367
+ "\uC5D0\uAC8C",
368
+ "\uD55C\uD14C",
369
+ "\uC73C\uB85C\uC11C",
370
+ "\uC73C\uB85C\uC368",
371
+ "\uC73C\uB85C",
372
+ "\uB85C\uC11C",
373
+ "\uB85C\uC368",
374
+ "\uC774\uB77C\uACE0",
375
+ "\uC774\uB77C\uB294",
376
+ "\uC774\uB77C\uBA70",
377
+ "\uC774\uB791",
378
+ "\uC774\uBA70",
379
+ "\uC774\uACE0",
380
+ "\uC774\uB2E4",
381
+ "\uC774\uC5C8",
382
+ "\uC600\uB2E4",
383
+ "\uC785\uB2C8\uB2E4",
384
+ "\uB77C\uACE0",
385
+ "\uB77C\uB294",
386
+ "\uC5D0\uC11C",
387
+ "\uBD80\uD130",
388
+ "\uAE4C\uC9C0",
389
+ "\uCC98\uB7FC",
390
+ "\uBCF4\uB2E4",
391
+ "\uC870\uCC28",
392
+ "\uB9C8\uC800",
393
+ "\uBC16\uC5D0",
394
+ "\uC5D0\uB294",
395
+ "\uC5D0\uB3C4",
396
+ "\uC640\uB294",
397
+ "\uACFC\uB294",
398
+ "\uC640\uC758",
399
+ "\uACFC\uC758",
400
+ "\uC758",
401
+ "\uC744",
402
+ "\uB97C",
403
+ "\uB294",
404
+ "\uC640",
405
+ "\uACFC",
406
+ "\uAED8",
407
+ "\uC5D0",
408
+ "\uB85C",
409
+ "\uB9CC",
410
+ "\uAC00",
411
+ "\uB3C4",
412
+ "\uB791"
413
+ ];
414
+ var PARTICLE_COND = ["\uC740", "\uC774", "\uB098"];
415
+ var P_ALL = alt([...PARTICLE_ALWAYS, ...PARTICLE_COND]);
416
+ var P_ALWAYS = alt(PARTICLE_ALWAYS);
417
+ var NAME_AFTER_RE = new RegExp(`^(?:\uC528|\uB2D8)?(?:${P_ALL})?(?![\uAC00-\uD7A3])`);
418
+ var nameParticleAt = (s, i) => NAME_AFTER_RE.test(s.slice(i, i + 6));
419
+ var NOT_NAME_FINAL = "\uC758\uC744\uB97C\uB294\uC640\uACFC\uC5D0\uAED8\uB85C\uC73C\uB41C\uB2E4\uBC1B\uB4E4\uD588\uBA74\uD574\uC5C6\uC788";
420
+ function hangulName(surnames, tail) {
421
+ return `(?:(?<dsur>${alt(DOUBLE_SURNAMES)})(?<dgiven>[\uAC00-\uD7A3]{1,2}?)(?=${tail(P_ALL)})|(?<sur>[${surnames}])(?:(?<given>[\uAC00-\uD7A3]{2})(?<![${NOT_NAME_FINAL}])(?=${tail(P_ALL)})|(?<given1>(?![${NOT_NAME_FINAL}])[\uAC00-\uD7A3])(?=${tail(P_ALWAYS)})))`;
422
+ }
423
+ var SURNAME_HANJA = {
424
+ \u91D1: "\uAE40",
425
+ \u674E: "\uC774\uB9AC",
426
+ \u6734: "\uBC15",
427
+ \u5D14: "\uCD5C",
428
+ \u912D: "\uC815",
429
+ \u4E01: "\uC815",
430
+ \u7A0B: "\uC815",
431
+ \u59DC: "\uAC15",
432
+ \u5EB7: "\uAC15",
433
+ \u6C5F: "\uAC15",
434
+ \u8D99: "\uC870",
435
+ \u66FA: "\uC870",
436
+ \u66F9: "\uC870",
437
+ \u5C39: "\uC724",
438
+ \u5F35: "\uC7A5",
439
+ \u8523: "\uC7A5",
440
+ \u7AE0: "\uC7A5",
441
+ \u6797: "\uC784",
442
+ \u4EFB: "\uC784",
443
+ \u97D3: "\uD55C",
444
+ \u5433: "\uC624",
445
+ \u5F90: "\uC11C",
446
+ \u7533: "\uC2E0",
447
+ \u8F9B: "\uC2E0",
448
+ \u613C: "\uC2E0",
449
+ \u6B0A: "\uAD8C",
450
+ \u9EC3: "\uD669",
451
+ \u5B89: "\uC548",
452
+ \u5B8B: "\uC1A1",
453
+ \u5168: "\uC804",
454
+ \u7530: "\uC804",
455
+ \u9322: "\uC804",
456
+ \u6D2A: "\uD64D",
457
+ \u67F3: "\uC720\uB958",
458
+ \u5289: "\uC720\uB958",
459
+ \u516A: "\uC720",
460
+ \u5EBE: "\uC720",
461
+ \u9AD8: "\uACE0",
462
+ \u6587: "\uBB38",
463
+ \u6881: "\uC591",
464
+ \u694A: "\uC591",
465
+ \u5B6B: "\uC190",
466
+ \u88F5: "\uBC30",
467
+ \u88F4: "\uBC30",
468
+ \u767D: "\uBC31",
469
+ \u8A31: "\uD5C8",
470
+ \u5357: "\uB0A8",
471
+ \u6C88: "\uC2EC",
472
+ \u76E7: "\uB178\uB85C",
473
+ \u9B6F: "\uB178",
474
+ \u6CB3: "\uD558",
475
+ \u90ED: "\uACFD",
476
+ \u6210: "\uC131",
477
+ \u8ECA: "\uCC28",
478
+ \u6731: "\uC8FC",
479
+ \u5468: "\uC8FC",
480
+ \u79B9: "\uC6B0",
481
+ \u5177: "\uAD6C",
482
+ \u4E18: "\uAD6C",
483
+ \u9594: "\uBBFC",
484
+ \u7F85: "\uB098\uB77C",
485
+ \u9673: "\uC9C4",
486
+ \u79E6: "\uC9C4",
487
+ \u664B: "\uC9C4",
488
+ \u6C60: "\uC9C0",
489
+ \u56B4: "\uC5C4",
490
+ \u8521: "\uCC44",
491
+ \u5143: "\uC6D0",
492
+ \u5343: "\uCC9C",
493
+ \u65B9: "\uBC29",
494
+ \u623F: "\uBC29",
495
+ \u5B54: "\uACF5",
496
+ \u7384: "\uD604",
497
+ \u54B8: "\uD568",
498
+ \u535E: "\uBCC0",
499
+ \u908A: "\uBCC0",
500
+ \u5EC9: "\uC5FC",
501
+ \u5442: "\uC5EC",
502
+ \u4F59: "\uC5EC",
503
+ \u79CB: "\uCD94",
504
+ \u90FD: "\uB3C4",
505
+ \u8607: "\uC18C",
506
+ \u77F3: "\uC11D",
507
+ \u5BA3: "\uC120",
508
+ \u859B: "\uC124",
509
+ \u99AC: "\uB9C8",
510
+ \u5409: "\uAE38",
511
+ \u5EF6: "\uC5F0",
512
+ \u9B4F: "\uC704",
513
+ \u97CB: "\uC704",
514
+ \u8868: "\uD45C",
515
+ \u660E: "\uBA85",
516
+ \u5947: "\uAE30",
517
+ \u6F58: "\uBC18",
518
+ \u738B: "\uC655",
519
+ \u7434: "\uAE08",
520
+ \u7389: "\uC625",
521
+ \u9678: "\uC721",
522
+ \u5370: "\uC778",
523
+ \u5B5F: "\uB9F9",
524
+ \u8AF8: "\uC81C",
525
+ \u725F: "\uBAA8",
526
+ \u6BDB: "\uBAA8",
527
+ \u5353: "\uD0C1",
528
+ \u97A0: "\uAD6D",
529
+ \u570B: "\uAD6D",
530
+ \u9B5A: "\uC5B4",
531
+ \u6BB7: "\uC740",
532
+ \u7247: "\uD3B8",
533
+ \u9F8D: "\uC6A9",
534
+ \u82AE: "\uC608",
535
+ \u6176: "\uACBD",
536
+ \u666F: "\uACBD",
537
+ \u5949: "\uBD09",
538
+ \u535C: "\uBCF5",
539
+ \u592A: "\uD0DC",
540
+ \u7766: "\uBAA9",
541
+ \u90A2: "\uD615",
542
+ \u76AE: "\uD53C",
543
+ \u675C: "\uB450",
544
+ \u7518: "\uAC10",
545
+ \u9670: "\uC74C",
546
+ \u8CD3: "\uBE48",
547
+ \u8463: "\uB3D9",
548
+ \u6EAB: "\uC628",
549
+ \u6248: "\uD638",
550
+ \u8303: "\uBC94",
551
+ \u5DE6: "\uC88C",
552
+ \u5F6D: "\uD33D",
553
+ \u627F: "\uC2B9",
554
+ \u7C21: "\uAC04",
555
+ \u845B: "\uAC08",
556
+ \u6BB5: "\uB2E8",
557
+ \u7504: "\uACAC",
558
+ \u5510: "\uB2F9",
559
+ \u660C: "\uCC3D",
560
+ \u9095: "\uC639",
561
+ \u5E73: "\uD3C9",
562
+ \u6C37: "\uBE59"
563
+ };
564
+ var DOUBLE_SURNAME_HANJA = {
565
+ \u5357\u5BAE: "\uB0A8\uAD81",
566
+ \u7687\u752B: "\uD669\uBCF4",
567
+ \u8AF8\u845B: "\uC81C\uAC08",
568
+ \u9BAE\u4E8E: "\uC120\uC6B0",
569
+ \u7368\u5B64: "\uB3C5\uACE0",
570
+ \u53F8\u7A7A: "\uC0AC\uACF5",
571
+ \u897F\u9580: "\uC11C\uBB38",
572
+ \u6771\u65B9: "\uB3D9\uBC29"
573
+ };
574
+ var LATIN_NAME = "(?<latin>(?<l1>[A-Z])(?<lrest>[a-z]{1,15}(?:[ -][A-Z][a-z]{1,15}){1,2}))";
575
+ var CJK_NAME = "(?<cjk>(?<c1>[\\u4E00-\\u9FFF])(?<crest>[\\u4E00-\\u9FFF]{1,3}))";
576
+ var FOREIGN_FOLLOW = `(?![A-Za-z\\u4E00-\\u9FFF])(?=(?:${P_ALL})?(?![\uAC00-\uD7A3]))`;
577
+ var PARTY_ROLES = [
578
+ "\uD53C\uACE0\uC778",
579
+ "\uD53C\uC758\uC790",
580
+ "\uD53C\uD574\uC790",
581
+ "\uAC00\uD574\uC790",
582
+ "\uC6D0\uACE0",
583
+ "\uD53C\uACE0",
584
+ "\uCC38\uACE0\uC778",
585
+ "\uC99D\uC778",
586
+ "\uACE0\uC18C\uC778",
587
+ "\uD53C\uACE0\uC18C\uC778",
588
+ "\uACE0\uBC1C\uC778",
589
+ "\uD53C\uACE0\uBC1C\uC778",
590
+ "\uC9C4\uC815\uC778",
591
+ "\uD53C\uC9C4\uC815\uC778",
592
+ "\uC2E0\uACE0\uC778",
593
+ "\uC2E0\uACE0\uC790",
594
+ "\uC81C\uBCF4\uC790",
595
+ "\uBBFC\uC6D0\uC778",
596
+ "\uC2E0\uCCAD\uC778",
597
+ "\uD53C\uC2E0\uCCAD\uC778",
598
+ "\uCCAD\uAD6C\uC778",
599
+ "\uD53C\uCCAD\uAD6C\uC778",
600
+ "\uCCAD\uC6D0\uC778",
601
+ "\uD56D\uACE0\uC778",
602
+ "\uD56D\uC18C\uC778",
603
+ "\uC0C1\uACE0\uC778",
604
+ "\uCC44\uAD8C\uC790",
605
+ "\uCC44\uBB34\uC790",
606
+ "\uC784\uCC28\uC778",
607
+ "\uC784\uB300\uC778",
608
+ "\uB9E4\uB3C4\uC778",
609
+ "\uB9E4\uC218\uC778",
610
+ "\uC0C1\uC18D\uC778",
611
+ "\uD53C\uC0C1\uC18D\uC778",
612
+ "\uD6C4\uACAC\uC778",
613
+ "\uD53C\uD6C4\uACAC\uC778",
614
+ "\uBC95\uC815\uB300\uB9AC\uC778",
615
+ "\uC18C\uC1A1\uB300\uB9AC\uC778",
616
+ "\uB300\uB9AC\uC778",
617
+ "\uBCC0\uD638\uC778",
618
+ "\uBCC0\uD638\uC0AC",
619
+ "\uBC95\uBB34\uC0AC",
620
+ "\uAC10\uC815\uC778",
621
+ "\uAC10\uC815\uC758",
622
+ "\uB2F4\uB2F9\uC758",
623
+ "\uC8FC\uCE58\uC758",
624
+ "\uD658\uC790",
625
+ "\uBCF4\uD638\uC790",
626
+ "\uD53C\uBCF4\uD5D8\uC790",
627
+ "\uBCF4\uD5D8\uACC4\uC57D\uC790",
628
+ "\uBCF4\uD5D8\uC218\uC775\uC790",
629
+ "\uC218\uC775\uC790",
630
+ "\uC0AC\uACE0\uC790",
631
+ "\uC6B4\uC804\uC790",
632
+ "\uBAA9\uACA9\uC790",
633
+ "\uC138\uB300\uC8FC",
634
+ "\uC608\uAE08\uC8FC",
635
+ "\uC218\uB839\uC778",
636
+ "\uC218\uCDE8\uC778",
637
+ "\uC791\uC131\uC790",
638
+ "\uB300\uD45C\uC790",
639
+ "\uB300\uD45C\uC774\uC0AC",
640
+ "\uC18C\uC720\uC790",
641
+ "\uBCF4\uC99D\uC778",
642
+ "\uC5F0\uB300\uBCF4\uC99D\uC778",
643
+ "\uC785\uD68C\uC778",
644
+ "\uB2F4\uB2F9\uC790"
645
+ ];
646
+ var TITLES = [
647
+ "\uD68C\uC7A5",
648
+ "\uBD80\uD68C\uC7A5",
649
+ "\uC0AC\uC7A5",
650
+ "\uBD80\uC0AC\uC7A5",
651
+ "\uC774\uC0AC\uC7A5",
652
+ "\uC774\uC0AC",
653
+ "\uAC10\uC0AC",
654
+ "\uC758\uC7A5",
655
+ "\uBD80\uC758\uC7A5",
656
+ "\uACF5\uB3D9\uC758\uC7A5",
657
+ "\uC704\uC6D0\uC7A5",
658
+ "\uBD80\uC704\uC6D0\uC7A5",
659
+ "\uC704\uC6D0",
660
+ "\uB300\uD45C",
661
+ "\uB300\uD45C\uC774\uC0AC",
662
+ "\uC7A5\uAD00",
663
+ "\uCC28\uAD00",
664
+ "\uCCAD\uC7A5",
665
+ "\uCC98\uC7A5",
666
+ "\uC2E4\uC7A5",
667
+ "\uAD6D\uC7A5",
668
+ "\uACFC\uC7A5",
669
+ "\uD300\uC7A5",
670
+ "\uACC4\uC7A5",
671
+ "\uBD80\uC7A5",
672
+ "\uCC28\uC7A5",
673
+ "\uB300\uB9AC",
674
+ "\uC8FC\uC784",
675
+ "\uC8FC\uBB34\uAD00",
676
+ "\uC0AC\uBB34\uAD00",
677
+ "\uC11C\uAE30\uAD00",
678
+ "\uC5F0\uAD6C\uAD00",
679
+ "\uC5F0\uAD6C\uC0AC",
680
+ "\uC5F0\uAD6C\uC6D0",
681
+ "\uC9C0\uB3C4\uC0AC",
682
+ "\uB2F4\uB2F9",
683
+ "\uB2F4\uB2F9\uC790",
684
+ "\uAD50\uC218",
685
+ "\uBD80\uAD50\uC218",
686
+ "\uC870\uAD50\uC218",
687
+ "\uAC15\uC0AC",
688
+ "\uAD50\uC0AC",
689
+ "\uAD50\uC7A5",
690
+ "\uAD50\uAC10",
691
+ "\uC6D0\uC7A5",
692
+ "\uC18C\uC7A5",
693
+ "\uC13C\uD130\uC7A5",
694
+ "\uAD00\uC7A5",
695
+ "\uCD1D\uC7A5",
696
+ "\uD559\uC7A5",
697
+ "\uC758\uC6D0",
698
+ "\uAD70\uC218",
699
+ "\uAD6C\uCCAD\uC7A5",
700
+ "\uB3C4\uC9C0\uC0AC",
701
+ "\uBA74\uC7A5",
702
+ "\uC74D\uC7A5",
703
+ "\uB3D9\uC7A5",
704
+ "\uC774\uC7A5",
705
+ "\uAE30\uC790",
706
+ "\uD2B9\uD30C\uC6D0",
707
+ "\uBC15\uC0AC",
708
+ "\uC120\uC0DD",
709
+ "\uC120\uC0DD\uB2D8",
710
+ "\uAC04\uD638\uC0AC",
711
+ "\uC57D\uC0AC",
712
+ "\uD310\uC0AC",
713
+ "\uC218\uC0AC\uAD00",
714
+ "\uC870\uC0AC\uAD00",
715
+ "\uBE44\uC11C\uAD00",
716
+ "\uBCF4\uC88C\uAD00",
717
+ "\uC0C1\uBB34",
718
+ "\uC804\uBB34",
719
+ "\uB300\uBCC0\uC778",
720
+ "\uC0AC\uBB34\uAD6D\uC7A5",
721
+ "\uC0AC\uBB34\uCD1D\uC7A5",
722
+ "\uBCF8\uBD80\uC7A5",
723
+ "\uC870\uD569\uC7A5",
724
+ "\uC9C0\uC810\uC7A5",
725
+ "\uC815\uCC45\uAD00",
726
+ "\uC2EC\uC758\uAD00",
727
+ "\uAE30\uD68D\uAD00",
728
+ "\uB2F4\uB2F9\uAD00",
729
+ "\uC870\uC815\uAD00",
730
+ "\uD611\uB825\uAD00"
731
+ ];
732
+ var RANKS = [
733
+ "\uC804\uBB38\uC704\uC6D0",
734
+ "\uC9C0\uB3C4\uAD00",
735
+ "\uC804\uBB38\uAD00",
736
+ "\uD589\uC815\uAD00",
737
+ "\uC870\uC815\uAD00",
738
+ "\uD611\uB825\uAD00",
739
+ "\uC18C\uBC29\uC704",
740
+ "\uC18C\uBC29\uACBD",
741
+ "\uC18C\uBC29\uC7A5",
742
+ "\uC18C\uBC29\uAD50",
743
+ "\uC18C\uBC29\uC0AC",
744
+ "\uC18C\uBC29\uB839",
745
+ "\uC18C\uBC29\uC815",
746
+ "\uACBD\uC815",
747
+ "\uACBD\uAC10",
748
+ "\uACBD\uC704",
749
+ "\uACBD\uC0AC",
750
+ "\uACBD\uC7A5",
751
+ "\uC21C\uACBD",
752
+ "\uCD1D\uACBD",
753
+ "\uAC80\uC0AC",
754
+ "\uC758\uC0AC",
755
+ "\uC2DC\uC7A5",
756
+ "\uC9C0\uC0AC",
757
+ "\uD1B5\uC7A5",
758
+ "\uBC18\uC7A5",
759
+ "\uACE0\uBB38",
760
+ "\uC218\uC11D",
761
+ "\uB2E8\uC7A5",
762
+ "\uB178\uBB34\uC0AC",
763
+ "\uC138\uBB34\uC0AC",
764
+ "\uD68C\uACC4\uC0AC",
765
+ "\uBCC0\uB9AC\uC0AC",
766
+ "\uAC04\uC0AC",
767
+ "\uBAA9\uC0AC",
768
+ "\uC2E0\uBD80",
769
+ "\uAE30\uC0AC",
770
+ "\uC8FC\uC0AC",
771
+ "\uC11C\uAE30",
772
+ "\uC8FC\uBB34",
773
+ "\uC120\uC784",
774
+ "\uAD8C\uC0AC",
775
+ "\uC7A5\uB85C",
776
+ "\uC9D1\uC0AC",
777
+ "\uC7A5\uD559\uAD00",
778
+ "\uC7A5\uD559\uC0AC",
779
+ "\uC2EC\uC0AC\uAD00",
780
+ "\uAC10\uB3C5\uAD00",
781
+ "\uAC10\uC0AC\uAD00"
782
+ ];
783
+ var STOP_WORDS = /* @__PURE__ */ new Set([
784
+ // 서식 라벨·항목
785
+ "\uC131\uBA85",
786
+ "\uC131\uD568",
787
+ "\uC131\uBCC4",
788
+ "\uC8FC\uC18C",
789
+ "\uC8FC\uC18C\uC9C0",
790
+ "\uC18C\uC7AC\uC9C0",
791
+ "\uC5F0\uB77D\uCC98",
792
+ "\uC804\uD654",
793
+ "\uC804\uC1A1",
794
+ "\uD734\uB300\uD3F0",
795
+ "\uC774\uBA54\uC77C",
796
+ "\uC774\uB984",
797
+ "\uC8FC\uBBFC",
798
+ "\uC0DD\uB144",
799
+ "\uC11C\uBA85",
800
+ "\uB0A0\uC778",
801
+ "\uC18C\uC18D",
802
+ "\uC9C1\uC704",
803
+ "\uC9C1\uAE09",
804
+ "\uC9C1\uCC45",
805
+ "\uBA85\uC758",
806
+ "\uBA85\uCE6D",
807
+ "\uC0C1\uD638",
808
+ "\uB3C4\uC7A5",
809
+ "\uAE30\uD0C0",
810
+ "\uAE30\uAD00",
811
+ "\uBD80\uC11C",
812
+ "\uAD6D\uC801",
813
+ "\uB098\uC774",
814
+ "\uC5F0\uB839",
815
+ "\uD559\uB144",
816
+ "\uD559\uAD50",
817
+ "\uD559\uACFC",
818
+ "\uBC88\uD638",
819
+ "\uBCF8\uC778",
820
+ "\uADC0\uD558",
821
+ "\uC5EC\uB7EC\uBD84",
822
+ "\uC77C\uB3D9",
823
+ "\uC804\uC6D0",
824
+ "\uBAA8\uB450",
825
+ "\uAC01\uAC01",
826
+ "\uBA85\uB2E8",
827
+ "\uC815\uBCF4",
828
+ "\uD604\uD669",
829
+ "\uAD00\uACC4",
830
+ "\uD55C\uAE00",
831
+ "\uC601\uBB38",
832
+ "\uAD6D\uBB38",
833
+ "\uD55C\uC790",
834
+ "\uAD6C\uBD84",
835
+ "\uC804\uACF5",
836
+ "\uC8FC\uAC70",
837
+ "\uD604\uBB3C",
838
+ "\uD604\uAE08",
839
+ "\uC124\uC815",
840
+ "\uBB38\uC790\uC5F4",
841
+ "\uB9AC\uC2A4\uD2B8",
842
+ "\uD558\uB098",
843
+ "\uAC15\uC81C",
844
+ "\uCD5C\uCD08",
845
+ "\uC5EC\uB7EC",
846
+ "\uC870\uD569\uBA85",
847
+ "\uC740\uD589\uBA85",
848
+ "\uAE30\uC7AC\uB780",
849
+ "\uC2E0\uBD84\uC99D",
850
+ "\uC9C0\uC815\uC11C",
851
+ "\uC81C\uCD9C\uC778",
852
+ "\uC704\uC784\uC778",
853
+ "\uC815\uADDC\uC9C1",
854
+ "\uC815\uB144",
855
+ "\uC131\uB144\uC790",
856
+ "\uC720\uC120",
857
+ "\uC608\uC81C",
858
+ "\uC9C0\uCD9C\uC6D0",
859
+ "\uC774\uC0AC\uD68C",
860
+ "\uC5F0\uAD6C\uC9C1",
861
+ "\uACF5\uBB34\uC9C1",
862
+ "\uC784\uAE30\uC81C",
863
+ "\uC804\uBB38\uC9C1",
864
+ // 역할어·호칭 자리 명사
865
+ "\uACE0\uAC1D",
866
+ "\uD68C\uC6D0",
867
+ "\uAD6D\uBBFC",
868
+ "\uC2DC\uBBFC",
869
+ "\uAD6C\uBBFC",
870
+ "\uB3C4\uBBFC",
871
+ "\uAD70\uBBFC",
872
+ "\uD559\uC0DD",
873
+ "\uD559\uBD80\uBAA8",
874
+ "\uBD80\uBAA8",
875
+ "\uC120\uC0DD",
876
+ "\uAD50\uC0AC",
877
+ "\uACF5\uBB34\uC6D0",
878
+ "\uC9C1\uC6D0",
879
+ "\uAD00\uB9AC\uC790",
880
+ "\uC774\uC6A9\uC790",
881
+ "\uC0AC\uC6A9\uC790",
882
+ "\uC2E0\uCCAD\uC790",
883
+ "\uC2E0\uACE0\uC790",
884
+ "\uC18C\uC720\uC790",
885
+ "\uBCF4\uD638\uC790",
886
+ "\uC804\uBB38\uAC00",
887
+ "\uC9C0\uC6D0\uC790",
888
+ "\uC81C\uCD9C\uC790",
889
+ "\uC870\uD569\uC6D0",
890
+ "\uC784\uC6D0",
891
+ "\uC7A5\uC560\uC778",
892
+ "\uB178\uC778",
893
+ "\uB178\uC57D\uC790",
894
+ "\uACE0\uB839\uC790",
895
+ "\uBC30\uC6B0\uC790",
896
+ "\uC720\uC871",
897
+ "\uC720\uAC00\uC871",
898
+ "\uAC00\uC871",
899
+ "\uC790\uB140",
900
+ "\uC544\uB3D9",
901
+ "\uC5EC\uC131",
902
+ "\uB0A8\uC131",
903
+ "\uCCAD\uB144",
904
+ "\uC8FC\uC8FC",
905
+ "\uD558\uB290",
906
+ "\uD558\uB098\uB2D8",
907
+ "\uB3C4\uB828",
908
+ "\uB9C8\uC74C",
909
+ "\uD615\uC218",
910
+ "\uC81C\uC218",
911
+ "\uC8FC\uC778",
912
+ "\uACF5\uC8FC",
913
+ "\uC655\uC790",
914
+ "\uB3C4\uB839",
915
+ "\uC7A5\uAD70",
916
+ "\uC870\uC0C1",
917
+ "\uBC29\uC7A5",
918
+ "\uC120\uBC30",
919
+ "\uAE30\uC0AC",
920
+ "\uAC04\uD638\uC0AC",
921
+ "\uBAA9\uC0AC",
922
+ // 직함·역할어를 꾸미는 말 (정책 과장·국회 의원·명예 교수·지역 주민·교장 공모제)
923
+ "\uAD6D\uD68C",
924
+ "\uC9C0\uBC29",
925
+ "\uC9C0\uC5ED",
926
+ "\uC815\uBD80",
927
+ "\uC815\uCC45",
928
+ "\uAE30\uD68D",
929
+ "\uD64D\uBCF4",
930
+ "\uC778\uC0AC",
931
+ "\uBBFC\uC6D0",
932
+ "\uCD1D\uBB34",
933
+ "\uBB38\uD654",
934
+ "\uB3C4\uC2DC",
935
+ "\uC8FC\uD0DD",
936
+ "\uAD50\uD1B5",
937
+ "\uC548\uC804",
938
+ "\uC18C\uBC29",
939
+ "\uACBD\uC81C",
940
+ "\uAD6D\uC81C",
941
+ "\uC870\uC0AC",
942
+ "\uC870\uC9C1",
943
+ "\uC9C0\uC6D0",
944
+ "\uACF5\uC6D0",
945
+ "\uACF5\uBCF4",
946
+ "\uC608\uC0B0",
947
+ "\uACC4\uC57D",
948
+ "\uC9C4\uD765",
949
+ "\uC815\uBCF4\uD654",
950
+ "\uC804\uC0B0",
951
+ "\uD1B5\uACC4",
952
+ "\uBC95\uBB34",
953
+ "\uAC10\uCC30",
954
+ "\uD3C9\uAC00",
955
+ "\uC6B4\uC601",
956
+ "\uAD00\uB9AC",
957
+ "\uC2DC\uC124",
958
+ "\uC790\uCE58",
959
+ "\uD589\uC815",
960
+ "\uC7AC\uBB34",
961
+ "\uD68C\uACC4",
962
+ "\uC138\uBB34",
963
+ "\uBCF5\uC9C0",
964
+ "\uBCF4\uAC74",
965
+ "\uD658\uACBD",
966
+ "\uC704\uC0DD",
967
+ "\uC0B0\uB9BC",
968
+ "\uB179\uC9C0",
969
+ "\uAC74\uC124",
970
+ "\uAC74\uCD95",
971
+ "\uB3C4\uB85C",
972
+ "\uD558\uCC9C",
973
+ "\uB18D\uC5C5",
974
+ "\uCD95\uC0B0",
975
+ "\uD574\uC591",
976
+ "\uC218\uC0B0",
977
+ "\uAD00\uAD11",
978
+ "\uCCB4\uC721",
979
+ "\uAD50\uC721",
980
+ "\uAE30\uC220",
981
+ "\uC5F0\uAD6C",
982
+ "\uAC1C\uBC1C",
983
+ "\uAE30\uC5C5",
984
+ "\uC0B0\uC5C5",
985
+ "\uD22C\uC790",
986
+ "\uB178\uB3D9",
987
+ "\uACE0\uC6A9",
988
+ "\uC778\uAD8C",
989
+ "\uAE30\uB85D",
990
+ "\uC815\uC6D0",
991
+ "\uC7A5\uD559",
992
+ "\uC804\uD1B5",
993
+ "\uC8FC\uC2DD",
994
+ "\uAE08\uC735",
995
+ "\uAD6D\uB0B4",
996
+ "\uAD6D\uC678",
997
+ "\uD574\uC678",
998
+ "\uACF5\uC124",
999
+ "\uC2E0\uADDC",
1000
+ "\uC815\uAE30",
1001
+ "\uC784\uC2DC",
1002
+ "\uD2B9\uBCC4",
1003
+ "\uC77C\uBC18",
1004
+ "\uC804\uCCB4",
1005
+ "\uACF5\uACF5",
1006
+ "\uBBFC\uAC04",
1007
+ "\uACF5\uC775",
1008
+ "\uACF5\uB3D9",
1009
+ "\uBA85\uC608",
1010
+ "\uC804\uC784",
1011
+ "\uC0C1\uC784",
1012
+ "\uACF5\uBAA8",
1013
+ "\uACF5\uBAA8\uC81C",
1014
+ "\uC784\uC6A9",
1015
+ "\uC784\uC6A9\uC81C",
1016
+ "\uC8FC\uC7AC",
1017
+ "\uC804\uCCB4\uD68C",
1018
+ "\uC870\uC0AC\uACB0",
1019
+ "\uC548\uC804\uC131",
1020
+ "\uC804\uBB38\uC131",
1021
+ "\uD3B8\uC758\uC131",
1022
+ "\uC720\uC0AC\uB3C4",
1023
+ "\uC704\uD558\uC5EC",
1024
+ "\uD558\uB294\uB370",
1025
+ // 역할어 뒤에 흔히 오는 명사
1026
+ "\uC0AC\uC774",
1027
+ "\uBCF8\uC810",
1028
+ "\uC9C0\uC810",
1029
+ "\uD68C\uC0AC",
1030
+ "\uBC95\uC778",
1031
+ "\uB2E8\uCCB4",
1032
+ "\uC804\uACB0",
1033
+ "\uC120\uCD9C",
1034
+ "\uC120\uAC70",
1035
+ "\uC120\uC815",
1036
+ "\uC2B9\uC778",
1037
+ "\uC9C0\uC815",
1038
+ "\uBCC0\uACBD",
1039
+ "\uAD50\uCCB4",
1040
+ "\uC784\uBA85",
1041
+ "\uC704\uCD09",
1042
+ "\uD574\uCD09",
1043
+ "\uD574\uC784",
1044
+ "\uC0AC\uC784",
1045
+ "\uC0AC\uD1F4",
1046
+ "\uCDE8\uC784",
1047
+ "\uD1F4\uC784",
1048
+ "\uACB0\uACFC",
1049
+ "\uBCF4\uACE0",
1050
+ "\uC758\uACAC",
1051
+ "\uC9C4\uC220",
1052
+ "\uB3D9\uC758",
1053
+ "\uD655\uC778",
1054
+ "\uC81C\uCD9C",
1055
+ "\uC2E0\uCCAD",
1056
+ "\uC2E0\uACE0",
1057
+ "\uCCAD\uAD6C",
1058
+ "\uC811\uC218",
1059
+ "\uCC98\uB9AC",
1060
+ "\uC870\uCE58",
1061
+ "\uAC80\uD1A0",
1062
+ "\uD1B5\uBCF4",
1063
+ "\uC548\uB0B4",
1064
+ "\uC5F0\uB77D",
1065
+ "\uBB38\uC758",
1066
+ "\uBB38\uC758\uCC98",
1067
+ "\uC0C1\uB2F4",
1068
+ "\uBA74\uB2F4",
1069
+ "\uBC29\uBB38",
1070
+ "\uCD9C\uC11D",
1071
+ "\uCC38\uC11D",
1072
+ "\uC18C\uD658",
1073
+ "\uC870\uC11C",
1074
+ "\uC9C4\uB2E8",
1075
+ "\uCE58\uB8CC",
1076
+ "\uC785\uC6D0",
1077
+ "\uD1F4\uC6D0",
1078
+ "\uC218\uC220",
1079
+ "\uC9C4\uB8CC",
1080
+ "\uC0C1\uD0DC",
1081
+ "\uBD80\uB2F4",
1082
+ "\uCC45\uC784",
1083
+ "\uC758\uBB34",
1084
+ "\uAD8C\uB9AC",
1085
+ "\uAD8C\uD55C",
1086
+ "\uC790\uACA9",
1087
+ "\uC694\uAC74",
1088
+ "\uC5EC\uBD80",
1089
+ "\uB300\uC0C1",
1090
+ "\uD574\uB2F9",
1091
+ "\uACBD\uC6B0",
1092
+ "\uAD00\uB828",
1093
+ "\uB0B4\uC6A9",
1094
+ "\uC0AC\uD56D",
1095
+ "\uBAA9\uB85D",
1096
+ "\uC11C\uB958",
1097
+ "\uC99D\uBA85",
1098
+ "\uC99D\uBE59",
1099
+ "\uC6D0\uBCF8",
1100
+ "\uC0AC\uBCF8",
1101
+ "\uC8FC\uC7A5",
1102
+ "\uCCAD\uAD6C\uC11C",
1103
+ "\uC2E0\uCCAD\uC11C",
1104
+ "\uC2E0\uACE0\uC11C",
1105
+ "\uB3D9\uC758\uC11C",
1106
+ "\uD655\uC778\uC11C",
1107
+ "\uC704\uC784\uC7A5",
1108
+ "\uACE0\uC18C\uC7A5",
1109
+ "\uC18C\uC7A5",
1110
+ "\uC815\uB3C4",
1111
+ "\uC774\uC0C1",
1112
+ "\uC774\uD558",
1113
+ "\uC774\uB0B4",
1114
+ "\uC774\uD6C4",
1115
+ "\uC774\uC804",
1116
+ "\uC774\uC678",
1117
+ "\uACF5\uACE0",
1118
+ "\uACF5\uBB38",
1119
+ "\uACF5\uAC1C",
1120
+ "\uACF5\uC720",
1121
+ "\uACF5\uC9C0",
1122
+ "\uACF5\uAE09",
1123
+ "\uACF5\uC0AC",
1124
+ "\uACF5\uB2E8",
1125
+ "\uC8FC\uAD00",
1126
+ "\uC8FC\uCD5C",
1127
+ "\uC8FC\uC694",
1128
+ "\uC8FC\uC758",
1129
+ "\uC18C\uAD00",
1130
+ "\uC18C\uD1B5",
1131
+ "\uC18C\uAC1C",
1132
+ "\uC11D\uC0AC",
1133
+ "\uBC15\uC0AC",
1134
+ "\uD559\uC0AC",
1135
+ "\uC131\uACFC",
1136
+ "\uC131\uC801",
1137
+ "\uC5F0\uC218",
1138
+ "\uC5F0\uC7A5",
1139
+ "\uC5F0\uAC04",
1140
+ "\uC5F0\uB3C4",
1141
+ "\uC804\uB144",
1142
+ "\uC804\uC6D4",
1143
+ "\uC804\uC77C",
1144
+ "\uC804\uC785",
1145
+ "\uC804\uCD9C",
1146
+ "\uAE30\uAC04",
1147
+ "\uAE30\uC900",
1148
+ "\uAE30\uD55C",
1149
+ "\uC815\uC0B0",
1150
+ "\uC815\uB9AC",
1151
+ "\uC815\uC9C0",
1152
+ "\uC815\uBE44",
1153
+ "\uC870\uC815",
1154
+ "\uC870\uD68C",
1155
+ "\uC870\uB840",
1156
+ "\uC870\uD56D",
1157
+ "\uC9C0\uAE09",
1158
+ "\uC9C0\uCD9C",
1159
+ "\uC9C0\uCE68",
1160
+ "\uC9C0\uC2DC",
1161
+ "\uC9C0\uB3C4",
1162
+ "\uC9C4\uD589",
1163
+ "\uC9C4\uC815",
1164
+ "\uCC28\uB7C9",
1165
+ "\uCC28\uC6D0",
1166
+ "\uAC15\uD654",
1167
+ "\uAC15\uC870",
1168
+ "\uAC15\uC758",
1169
+ "\uC7A5\uC18C",
1170
+ "\uC7A5\uAE30",
1171
+ "\uC7A5\uBE44",
1172
+ "\uC7A5\uBD80",
1173
+ "\uC7A5\uC560",
1174
+ "\uC784\uB300",
1175
+ "\uC784\uAE08",
1176
+ "\uC784\uAE30",
1177
+ "\uC784\uBB34",
1178
+ "\uD55C\uB3C4",
1179
+ "\uD55C\uACC4",
1180
+ "\uD55C\uAD6D",
1181
+ "\uD5C8\uAC00",
1182
+ "\uD5C8\uC704",
1183
+ "\uC2EC\uC0AC",
1184
+ "\uC2EC\uC758",
1185
+ "\uC2EC\uB9AC",
1186
+ "\uBC29\uBC95",
1187
+ "\uBC29\uC548",
1188
+ "\uBC29\uCE68",
1189
+ "\uACF5\uBB34",
1190
+ "\uACF5\uAC04",
1191
+ "\uD604\uC7A5",
1192
+ "\uD604\uC7AC",
1193
+ "\uD604\uD589",
1194
+ "\uD568\uAED8",
1195
+ "\uBCC0\uB3D9",
1196
+ "\uBCC0\uB3D9\uC774",
1197
+ "\uC5EC\uAC74",
1198
+ "\uCD94\uC9C4",
1199
+ "\uCD94\uAC00",
1200
+ "\uCD94\uCC9C",
1201
+ "\uB3C4\uC785",
1202
+ "\uB3C4\uC6C0",
1203
+ "\uB3C4\uC11C",
1204
+ "\uB3C4\uC11C\uAD00",
1205
+ "\uC18C\uB4DD",
1206
+ "\uC18C\uC720",
1207
+ "\uC18C\uC7AC",
1208
+ "\uC120\uD0DD",
1209
+ "\uC120\uBC1C",
1210
+ "\uC124\uBA85",
1211
+ "\uC124\uCE58",
1212
+ "\uC124\uACC4",
1213
+ "\uC124\uB9BD",
1214
+ "\uB9C8\uB828",
1215
+ "\uB9C8\uC744",
1216
+ "\uB9C8\uAC10",
1217
+ "\uC5F0\uACC4",
1218
+ "\uC704\uBC18",
1219
+ "\uC704\uD5D8",
1220
+ "\uC704\uCE58",
1221
+ "\uC704\uD0C1",
1222
+ "\uC704\uC784",
1223
+ "\uD45C\uC2DC",
1224
+ "\uD45C\uC900",
1225
+ "\uD45C\uCC3D",
1226
+ "\uD45C\uD604",
1227
+ "\uBA85\uC2DC",
1228
+ "\uBC18\uC601",
1229
+ "\uBC18\uB0A9",
1230
+ "\uAE08\uC561",
1231
+ "\uAE08\uC9C0",
1232
+ "\uC778\uAC00",
1233
+ "\uC778\uC6D0",
1234
+ "\uC778\uC815",
1235
+ "\uC778\uC99D",
1236
+ "\uC778\uAD6C",
1237
+ "\uC778\uADFC",
1238
+ "\uC778\uC218",
1239
+ "\uC778\uC7AC",
1240
+ "\uC81C\uACF5",
1241
+ "\uC81C\uB3C4",
1242
+ "\uC81C\uD55C",
1243
+ "\uC81C\uC678",
1244
+ "\uC81C\uC2DC",
1245
+ "\uC81C\uC548",
1246
+ "\uBAA8\uC9D1",
1247
+ "\uAD6D\uAC00",
1248
+ "\uC740\uD589",
1249
+ "\uD3B8\uC758",
1250
+ "\uC6A9\uB3C4",
1251
+ "\uC6A9\uC5ED",
1252
+ "\uC608\uC815",
1253
+ "\uC608\uC678",
1254
+ "\uC608\uBC29",
1255
+ "\uACBD\uCC30",
1256
+ "\uACBD\uCC30\uC11C",
1257
+ "\uC18C\uBC29\uC11C",
1258
+ "\uBCF5\uC9C0\uAD00",
1259
+ "\uCCB4\uC721\uAD00",
1260
+ "\uBB38\uD654\uC6D0",
1261
+ "\uC720\uCE58\uC6D0",
1262
+ "\uC5F0\uAD6C\uC18C",
1263
+ "\uC9C4\uB8CC\uC18C",
1264
+ "\uC6B0\uCCB4\uAD6D",
1265
+ "\uBD09\uC0AC",
1266
+ "\uD53C\uD574",
1267
+ "\uAC10\uB3C5",
1268
+ "\uB3D9\uC548",
1269
+ "\uB3D9\uC77C",
1270
+ "\uBC94\uC704",
1271
+ "\uBC94\uC8C4",
1272
+ "\uAC04\uB2F4\uD68C",
1273
+ "\uAC04\uBD80",
1274
+ "\uB2E8\uACC4",
1275
+ "\uB2E8\uC704",
1276
+ "\uB2E8\uC18D",
1277
+ "\uB2F9\uC2DC",
1278
+ "\uB2F9\uD574",
1279
+ "\uB2F9\uC0AC\uC790",
1280
+ "\uD3C9\uC77C",
1281
+ "\uAD6C\uC81C",
1282
+ "\uC774\uC1A1",
1283
+ "\uBC30\uCE58",
1284
+ "\uBC30\uC11D",
1285
+ "\uAC04\uC758",
1286
+ "\uC8FC\uC2DD\uD68C\uC0AC",
1287
+ "\uC720\uD55C\uD68C\uC0AC",
1288
+ "\uC774\uC6A9",
1289
+ "\uC774\uC775",
1290
+ "\uC5F0\uAD6C\uC790",
1291
+ "\uBC29\uC2DD",
1292
+ "\uC720\uD615",
1293
+ "\uC9C0\uD45C",
1294
+ "\uBD84\uC57C",
1295
+ "\uD604\uC9C0",
1296
+ "\uC804\uBB38",
1297
+ "\uC774\uB3D9",
1298
+ "\uC5F0\uACB0",
1299
+ "\uBB38\uD559",
1300
+ "\uC774\uBBF8\uC9C0",
1301
+ "\uACF5\uBB34\uC9C1",
1302
+ "\uC6D0\uC5B4\uBBFC",
1303
+ "\uC11C\uBA85\uC11C",
1304
+ "\uAE38\uC774",
1305
+ "\uCC44\uC6A9",
1306
+ "\uC5EC\uAE30\uC11C",
1307
+ "\uD558\uBC18\uAE30",
1308
+ "\uC0C1\uBC18\uAE30",
1309
+ "\uC124\uBA85\uD68C",
1310
+ "\uC2EC\uC758\uD68C",
1311
+ "\uD611\uC758\uD68C",
1312
+ "\uACF5\uCCAD\uD68C",
1313
+ "\uD1A0\uB860\uD68C",
1314
+ "\uBC15\uB78C\uD68C",
1315
+ "\uC5F0\uCC2C\uD68C",
1316
+ "\uCD94\uBAA8\uC2DD",
1317
+ "\uBC29\uACFC\uD6C4",
1318
+ "\uC9C4\uC785\uB3C4",
1319
+ "\uAE30\uC7AC",
1320
+ "\uAE30\uC548",
1321
+ "\uC9C0\uC790\uCCB4",
1322
+ "\uACE0\uBB38\uC11C",
1323
+ "\uC120\uAC70\uAD8C",
1324
+ "\uC774\uC2DD\uC220",
1325
+ "\uB178\uC219",
1326
+ "\uC2E0\uC120",
1327
+ "\uAD6C\uC758\uD68C",
1328
+ "\uB3C4\uC758\uD68C",
1329
+ "\uC2DC\uC758\uD68C",
1330
+ "\uC704\uC6D0\uD68C",
1331
+ "\uC870\uC808",
1332
+ "\uD604\uC9C1",
1333
+ "\uC18C\uC9C0",
1334
+ "\uC5B4\uBA38",
1335
+ "\uC608\uC218",
1336
+ "\uD669\uC81C",
1337
+ "\uC6B0\uC8FC",
1338
+ "\uD604\uC218\uB9C9",
1339
+ "\uBC15\uBB3C\uAD00",
1340
+ "\uBBF8\uC220\uAD00",
1341
+ "\uAE30\uB150\uAD00",
1342
+ "\uC804\uC2DC\uAD00",
1343
+ "\uD68C\uAD00",
1344
+ "\uC131\uACF5\uD68C",
1345
+ "\uC5F0\uAD6C\uC9C4",
1346
+ "\uB0A8\uD574\uC548",
1347
+ "\uB2F9\uC5F0\uC9C1",
1348
+ "\uC5F0\uD569",
1349
+ "\uC1A1\uB2EC",
1350
+ "\uCD5C\uC885",
1351
+ "\uB3C4\uCCAD"
1352
+ ]);
1353
+ var PARTICLE_GIVEN = /* @__PURE__ */ new Set(["\uC5D0\uC11C", "\uC5D0\uAC8C", "\uBD80\uD130", "\uAE4C\uC9C0", "\uB77C\uB3C4", "\uCC98\uB7FC", "\uBCF4\uB2E4", "\uAED8\uC11C", "\uD55C\uD14C", "\uC73C\uB85C", "\uC774\uB2E4", "\uC5D0\uB294", "\uC5D0\uB3C4", "\uC774\uB098", "\uC774\uB791"]);
1354
+ var SUFFIX_FINAL = "\uC740\uB294\uC774\uAC00\uC744\uB97C\uC758\uC640\uACFC\uB3C4\uB9CC\uC5D0\uB85C\uB098\uB791\uAED8\uD558\uD55C\uB420\uD560\uBCC4\uC801\uD654\uB960\uC728\uCE35\uACC4\uB825\uBC95\uD615\uC81C\uB300\uC778\uC790\uC2DC\uAD70\uAD6C\uC131\uAD8C\uC77C\uBCF8\uD6C4\uC11C\uB8CC\uC232\uC18D";
1355
+ var ORG_FINAL = /(?:과|팀|실|계|처|청|단|반|부|장|시|군|센터|협회|조합|공단|공사|재단|법인|병원|학교|대학|회사|은행|위원회|사무소|지청|본부)$/;
1356
+ var REGION_WORDS = /* @__PURE__ */ new Set([...SIDO, ...SIGUNGU, ...SIGUNGU.filter((w) => w.length >= 3).map((w) => w.slice(0, -1))]);
1357
+ var NON_NAME_END = /(?:적|하여|하는|하고|하며|하게|하기|하면|하다|한다|했다|는데|니다|습니|다고|해야|해서|되는|되어|된다|지만|니까|와서|워서)$/;
1358
+ var FOREIGN_SYLLABLE = /[스트크드브프즈츠끄뜨쁘쓰쯔플클블러케퍼커터텔톤튼픈핀펜헨앤엔엠켓렛]/;
1359
+ var TITLE_SET = /* @__PURE__ */ new Set([...TITLES, ...RANKS, ...PARTY_ROLES]);
1360
+ var g = (x, name) => x.m.groups?.[name] ?? "";
1361
+ var nameOf = (x) => g(x, "dsur") + g(x, "dgiven") + g(x, "sur") + g(x, "given") + g(x, "given1");
1362
+ var span = (x) => x.m.indices?.groups?.n;
1363
+ var nextIs = (x, re) => {
1364
+ const n = span(x);
1365
+ return !!n && re.test(x.m.input.slice(n[1], n[1] + 1));
1366
+ };
1367
+ var closedAfter = (x) => nextIs(x, /^[가-힣,,))((]/);
1368
+ var parenAfter = (x) => nextIs(x, /^[((]/);
1369
+ function nameOk(x, level, two = false) {
1370
+ if (g(x, "latin") || g(x, "cjk")) return level === 2;
1371
+ const n = nameOf(x);
1372
+ const given = g(x, "dgiven") + g(x, "given") + g(x, "given1");
1373
+ if (STOP_WORDS.has(n) || TITLE_SET.has(n) || REGION_WORDS.has(n) || ORG_FINAL.test(n) || NON_NAME_END.test(n) || FOREIGN_SYLLABLE.test(given) || PARTICLE_GIVEN.has(given)) return false;
1374
+ if (n.length === 3 && SUFFIX_FINAL.includes(n[2]) && (STOP_WORDS.has(n.slice(0, 2)) || TITLE_SET.has(n.slice(0, 2)) || REGION_WORDS.has(n.slice(0, 2)))) return false;
1375
+ if (g(x, "dsur")) return true;
1376
+ if (g(x, "given1")) return level === 2 || two && COMMON_SURNAMES.includes(g(x, "sur"));
1377
+ return level > 0 || COMMON_SURNAMES.includes(g(x, "sur"));
1378
+ }
1379
+ var NB = "(?<![\uAC00-\uD7A3A-Za-z0-9])(?<!(?:\\(\uC8FC\\)|\u321C)\\s?)";
1380
+ var NOT_ORG_AFTER = "(?!\\s?(?:\uC8FC\uC2DD\uD68C\uC0AC|\uC720\uD55C\uD68C\uC0AC|\\(\uC8FC\\)|\u321C|\\(\uC720\\)|\uBC95\uC778|\uC7AC\uB2E8|\uD611\uD68C|\uC870\uD569|\uACF5\uC0AC|\uACF5\uB2E8|\uC740\uD589|\uBCD1\uC6D0))";
1381
+ var NO_SPACING = /* @__PURE__ */ new Set(["\uC774\uC7A5", "\uB3D9\uC7A5", "\uBA74\uC7A5", "\uC74D\uC7A5"]);
1382
+ var titleAlt = (ts) => alt(ts.map((t) => NO_SPACING.has(t) ? t : t.split("").join("\\s?")));
1383
+ var ORG_TITLE = `[\uAC00-\uD7A3]{1,12}(?:${alt([
1384
+ "\uC7A5\uAD00",
1385
+ "\uCC28\uAD00",
1386
+ "\uCCAD\uC7A5",
1387
+ "\uCC98\uC7A5",
1388
+ "\uC2E4\uC7A5",
1389
+ "\uAD6D\uC7A5",
1390
+ "\uACFC\uC7A5",
1391
+ "\uD300\uC7A5",
1392
+ "\uACC4\uC7A5",
1393
+ "\uBD80\uC7A5",
1394
+ "\uC6D0\uC7A5",
1395
+ "\uC18C\uC7A5",
1396
+ "\uC13C\uD130\uC7A5",
1397
+ "\uAD00\uC7A5",
1398
+ "\uCD1D\uC7A5",
1399
+ "\uD559\uC7A5",
1400
+ "\uB2E8\uC7A5",
1401
+ "\uBCF8\uBD80\uC7A5",
1402
+ "\uC704\uC6D0\uC7A5",
1403
+ "\uC704\uC6D0",
1404
+ "\uC815\uCC45\uAD00",
1405
+ "\uC2EC\uC758\uAD00",
1406
+ "\uAE30\uD68D\uAD00",
1407
+ "\uB2F4\uB2F9\uAD00",
1408
+ "\uC870\uC815\uAD00",
1409
+ "\uD611\uB825\uAD00",
1410
+ "\uBE44\uC11C\uAD00",
1411
+ "\uB300\uBCC0\uC778",
1412
+ "\uC8FC\uBB34\uAD00",
1413
+ "\uC0AC\uBB34\uAD00",
1414
+ "\uC11C\uAE30\uAD00",
1415
+ "\uC5F0\uAD6C\uAD00",
1416
+ "\uC5F0\uAD6C\uC0AC",
1417
+ "\uC870\uC0AC\uAD00",
1418
+ "\uC218\uC0AC\uAD00",
1419
+ "\uAC10\uB3C5\uAD00",
1420
+ "\uC2EC\uC0AC\uAD00",
1421
+ "\uB2F4\uB2F9",
1422
+ "\uB2F4\uB2F9\uC790"
1423
+ ])})`;
1424
+ var NEXT_OK = `${titleAlt(TITLES)}|${ORG_TITLE}|${alt([...PARTY_ROLES, "\uC528", "\uB2D8", "\uC0AC\uC774", "\uB4F1", "\uC678", "\uBCF8\uC778", "\uBA85\uC758", "\uCE21", "\uADC0\uD558"])}`;
1425
+ var tailPlain = (p) => `(?:${p})?(?![\uAC00-\uD7A3])${NOT_ORG_AFTER}`;
1426
+ var tailRole = () => `(?:(?:${P_ALL})(?![\uAC00-\uD7A3])|(?![\uAC00-\uD7A3])(?![ \\t]+[\uAC00-\uD7A3])|[ \\t]+(?:${NEXT_OK})(?:${P_ALL})?(?![\uAC00-\uD7A3]))${NOT_ORG_AFTER}`;
1427
+ var PHONE_NEXT = "(?:\\s{0,3}|\\s*(?:\\||<\\/t[dh]>\\s*<t[dh][^>]*>)\\s*)[(\uFF08]?\\s?(?:\u260E|\u260F|TEL|Tel|tel|\uC804\uD654|\uC5F0\uB77D\uCC98|H\\.?P|\uD734\uB300\uD3F0|\uD578\uB4DC\uD3F0)?\\s?[:.]?\\s?(?:0\\d{1,2}[-)\uFF0E. ]\\s?\\d{3,4}[-\uFF0E. ]\\d{4}|\\+82|1[568]\\d\\d-\\d{4})";
1428
+ var SEP = "(?<sep>\\s{0,2}[:\uFF1A]\\s{0,2}|\\s{1,3})";
1429
+ var CELL_SEP = "(?<sep>\\s{0,2}[:\uFF1A]\\s{0,2}|\\s{1,3}|\\s*(?:\\||<\\/t[dh]>\\s*<t[dh][^>]*>)\\s*)";
1430
+ var NOT_PERSON_OF = alt([
1431
+ "\uADF8\uB9BC\uC758",
1432
+ "\uD504\uB85C\uADF8\uB7A8",
1433
+ "\uD30C\uC77C",
1434
+ "\uBAA8\uB378",
1435
+ "\uAE00\uAF34",
1436
+ "\uD544\uB4DC",
1437
+ "\uAC1C\uCCB4",
1438
+ "\uCE74\uBA54\uB77C",
1439
+ "\uC81C\uC870\uC0AC",
1440
+ "\uC7A5\uCE58",
1441
+ "\uAE30\uAE30",
1442
+ "\uD3F4\uB354",
1443
+ "\uBB38\uC11C",
1444
+ "\uC591\uC2DD",
1445
+ "\uC11C\uC2DD",
1446
+ "\uD56D\uBAA9",
1447
+ "\uC81C\uD488",
1448
+ "\uC0C1\uD488",
1449
+ "\uD68C\uC0AC",
1450
+ "\uC5C5\uCCB4",
1451
+ "\uAE30\uAD00",
1452
+ "\uB2E8\uCCB4",
1453
+ "\uC2DC\uD2B8",
1454
+ "\uBCC0\uC218",
1455
+ "\uD568\uC218",
1456
+ "\uB3C4\uBA54\uC778",
1457
+ "\uC11C\uBC84",
1458
+ "\uACC4\uC815"
1459
+ ]);
1460
+ var NAME_LABEL = `(?:(?:${spaced(["\uC131\uBA85", "\uC131\uD568", "\uD55C\uAE00\uC131\uBA85", "\uB300\uD45C\uC790\uC131\uBA85"])})(?:\\s?\\(\\s?\uD55C\\s?\uAE00\\s?\\))?${CELL_SEP}|(?<!(?:${NOT_PERSON_OF})\\s?)(?:${spaced(["\uC774\uB984"])})(?<sep2>\\s{0,2}[:\uFF1A]\\s{0,2}|\\s*(?:\\||<\\/t[dh]>\\s*<t[dh][^>]*>)\\s*))`;
1461
+ var TITLES_AFTER = TITLES.filter((t) => !["\uAD50\uC7A5", "\uAD50\uAC10", "\uAD50\uC0AC", "\uAC15\uC0AC", "\uB2F4\uB2F9", "\uB2F4\uB2F9\uC790", "\uC704\uC6D0", "\uC774\uC0AC", "\uAC10\uC0AC", "\uC120\uC0DD", "\uC120\uC0DD\uB2D8", "\uAC04\uD638\uC0AC", "\uC57D\uC0AC", "\uC5F0\uAD6C\uC6D0", "\uC8FC\uC784"].includes(t));
1462
+ var NAME_MASK = ["dgiven", "given", "given1", "lrest", "crest"];
1463
+ var ROLE_RE = alt(PARTY_ROLES);
1464
+ var TITLE_RE = titleAlt(TITLES);
1465
+ var TITLE_AFTER_RE = `(?:\uC81C\\d{1,2}\\s?)?(?:${titleAlt(TITLES_AFTER)})`;
1466
+ var NAME_HEADER_RE = new RegExp(`^\\s*(?:${spaced(["\uC131\uBA85", "\uC774\uB984", "\uC131\uD568", "\uB2F4\uB2F9\uC790", "\uB300\uD45C\uC790", "\uC608\uAE08\uC8FC", "\uC791\uC131\uC790", "\uC2E0\uCCAD\uC778", "\uCCAD\uAD6C\uC778", "\uBBFC\uC6D0\uC778", "\uC18C\uC720\uC790", "\uC218\uB839\uC778", "\uB300\uB9AC\uC778", "\uBCF4\uD638\uC790", "\uC138\uB300\uC8FC", "\uCC38\uC11D\uC790"])})(?:\\s*\\([^)]*\\))?\\s*$`);
1467
+ var LIST_GAP_RE = /^(?:와|과|이나|나|이랑|랑)?\s{0,2}[,、·]?\s{0,2}$/;
1468
+ var hanjaMatches = (x) => {
1469
+ const han = g(x, "h1") + g(x, "hrest");
1470
+ if (han.length !== nameOf(x).length) return false;
1471
+ if (g(x, "dsur")) return DOUBLE_SURNAME_HANJA[han.slice(0, 2)] === g(x, "dsur");
1472
+ return (SURNAME_HANJA[han[0]] ?? "").includes(g(x, "sur"));
1473
+ };
1474
+ var clanName = (x) => {
1475
+ const n = nameOf(x);
1476
+ return n.length === 3 && ALL_SURNAMES.includes(n[2]) && REGION_WORDS.has(n.slice(0, 2)) && nextIs(x, /^\s?씨/);
1477
+ };
1478
+ var NOT_TITLE_TAIL = /(?:세면장|운동장|주차장|수영장|경기장|공연장|시험장|작업장|사업장|회의장|행사장|전시장|선착장|정류장|야영장)$/;
1479
+ var sepHasColon = (x) => /[::]/.test(g(x, "sep"));
1480
+ var colonAfter = (x) => {
1481
+ const n = span(x);
1482
+ return !!n && new RegExp(`^(?:${P_ALL})?\\s?[:\uFF1A]`).test(x.m.input.slice(n[1], n[1] + 6));
1483
+ };
1484
+ var NAME_VARIANTS = [
1485
+ {
1486
+ // 직함·역할어 뒤 한자 병기 — "검찰연구관 박서진(朴瑞辰)", "검사 최하준(崔夏俊)" (인사 발령·판결문의 인명 표기).
1487
+ // 한자도 같은 이름이라 스팬에 넣고 첫 글자(성)만 남긴다 — "박●●(朴●●)". 병기만으로는 문맥이 아니다 — 한자어 병기
1488
+ // ("고층(高層)"·"황하(黃河)"·"표출(表出)")도 첫 한자가 성씨 한자다(코퍼스 실측). 맨 앞 — 직함 변형이 한글만 먼저 잡지 않게
1489
+ re: new RegExp(`(?:${TITLE_RE}|${ROLE_RE}|${spaced(RANKS)})${SEP}(?<n>${hangulName(ALL_SURNAMES, () => "\\s?[(\uFF08][\\u4E00-\\u9FFF]{2,4}[)\uFF09]")}\\s?[(\uFF08](?<h1>[\\u4E00-\\u9FFF])(?<hrest>[\\u4E00-\\u9FFF]{1,3})[)\uFF09])`, "dg"),
1490
+ span: "n",
1491
+ mask: [...NAME_MASK, "hrest"],
1492
+ ok: (x) => hanjaMatches(x) && nameOk(x, 2)
1493
+ },
1494
+ {
1495
+ // 라벨 뒤 — "성명: 홍길동", "| 성명 | 홍길동 |", "이름: 남궁현"
1496
+ re: new RegExp(`${NAME_LABEL}(?<n>${hangulName(ALL_SURNAMES, tailPlain)}|${LATIN_NAME}${FOREIGN_FOLLOW}|${CJK_NAME}${FOREIGN_FOLLOW})`, "dg"),
1497
+ span: "n",
1498
+ mask: NAME_MASK,
1499
+ ok: (x) => nameOk(x, /[::]/.test(g(x, "sep") + g(x, "sep2")) ? 2 : 1)
1500
+ },
1501
+ {
1502
+ // 당사자 역할어 뒤 — "피고인 최지훈은", "대표이사 오세진)", "작성자 한서율,"
1503
+ re: new RegExp(`(?:${ROLE_RE})${SEP}(?<n>${hangulName(ALL_SURNAMES, tailRole)}|${LATIN_NAME}${FOREIGN_FOLLOW}|${CJK_NAME}${FOREIGN_FOLLOW})`, "dg"),
1504
+ span: "n",
1505
+ mask: NAME_MASK,
1506
+ ok: (x) => nameOk(x, g(x, "latin") || g(x, "cjk") ? 2 : 1, closedAfter(x))
1507
+ },
1508
+ {
1509
+ // 직함 뒤 — "과장 홍길동", "회장 : 도서연"(쌍점·발언자 쌍점이면 강한 문맥). 직함이 다른 낱말 꼬리인 자리
1510
+ // ("세면장 조도임"의 면장, "주차장"의 차장)는 직함이 아니다
1511
+ re: new RegExp(`(?<t>${TITLE_RE})${SEP}(?<n>${hangulName(ALL_SURNAMES, tailRole)})`, "dg"),
1512
+ span: "n",
1513
+ mask: NAME_MASK,
1514
+ ok: (x) => !NOT_TITLE_TAIL.test(x.m.input.slice(Math.max(0, x.m.index - 3), x.m.index + g(x, "t").length)) && nameOk(x, sepHasColon(x) || colonAfter(x) ? 1 : 0)
1515
+ },
1516
+ {
1517
+ // 호칭 앞 — "홍길동 씨", "홍길동님께", "Daniel Brown 씨". "기업날씨"·"솜씨"·"글씨" 같은 씨 낱말은 호칭이 아니다
1518
+ re: new RegExp(`${NB}(?<n>${hangulName(ALL_SURNAMES, () => `(?:(?<![\uB0A0\uC19C\uB9D0\uAE00\uBD88\uB9D8])\\s?\uC528|\\s?\uB2D8)(?:${P_ALL})?(?![\uAC00-\uD7A3])(?!\\s?(?:\u321C|\\(\uC8FC\\)))`)}|${LATIN_NAME}(?=\\s?(?:\uC528|\uB2D8)(?![\uAC00-\uD7A3]))|${CJK_NAME}(?=\\s?(?:\uC528|\uB2D8)(?![\uAC00-\uD7A3])))`, "dg"),
1519
+ span: "n",
1520
+ mask: NAME_MASK,
1521
+ ok: (x) => nameOk(x, 2) && !clanName(x)
1522
+ },
1523
+ {
1524
+ // 연락처 앞 — "유다온(010-…)", "홍길동 ☎ 02-…", "| 김지유 | (051-…) |". 두 글자는 괄호가 바로 붙을 때만 —
1525
+ // 기관 안내 표의 "마음상담센터 한별 | 031-…" 같은 기관 이름 칸(코퍼스 실측)
1526
+ re: new RegExp(`${NB}(?<n>${hangulName(ALL_SURNAMES, () => PHONE_NEXT)})`, "dg"),
1527
+ span: "n",
1528
+ mask: NAME_MASK,
1529
+ ok: (x) => nameOk(x, 1, parenAfter(x))
1530
+ },
1531
+ {
1532
+ // 나이·성별 괄호 앞 — "박도현(만 52세)", "서하(여, 31세)"
1533
+ re: new RegExp(`${NB}(?<n>${hangulName(ALL_SURNAMES, () => "\\s?[(\uFF08]\\s?(?:\uB9CC\\s?\\d{1,3}\\s?\uC138|\\d{1,3}\\s?\uC138|\uC5EC|\uB0A8|\u5973|\u7537)\\s?[,\uFF0C)\uFF09]")})`, "dg"),
1534
+ span: "n",
1535
+ mask: NAME_MASK,
1536
+ ok: (x) => nameOk(x, 2)
1537
+ },
1538
+ {
1539
+ // 직함 앞 — "홍길동 과장", "김민수 국장에게"(약한 문맥). 직함 뒤에 연락처가 이어지면 강한 문맥("편도윤 담당자(☎ …)")
1540
+ re: new RegExp(`${NB}(?<n>${hangulName(ALL_SURNAMES, () => `\\s(?:\uC81C\\d{1,2}\\s?)?(?:${TITLE_RE})(?:\uB2D8)?(?:${P_ALL})?(?![\uAC00-\uD7A3])`)})(?:(?<after>\\s(?:${TITLE_RE})${PHONE_NEXT})|(?<weak>\\s(?:${TITLE_AFTER_RE})(?:\uB2D8)?(?:${P_ALL})?(?![\uAC00-\uD7A3])))`, "dg"),
1541
+ span: "n",
1542
+ mask: NAME_MASK,
1543
+ ok: (x) => nameOk(x, g(x, "after") ? 1 : 0)
1544
+ },
1545
+ {
1546
+ // 당사자 번호 나열 — "피고 1. ○○은행(대표자 오세진) 2. 윤지호는"
1547
+ re: new RegExp(`(?:${ROLE_RE})\\s{1,2}(?:1[.)]\\s?[^\\n]{1,60}?\\s)?\\d{1,2}[.)]\\s?(?<n>${hangulName(ALL_SURNAMES, tailRole)})`, "dg"),
1548
+ span: "n",
1549
+ mask: NAME_MASK,
1550
+ ok: (x) => nameOk(x, 1)
1551
+ },
1552
+ {
1553
+ // 표 칸 전체가 이름 — 열 머리글이 성명·담당자·대표자 …
1554
+ re: new RegExp(`(?:^|\\||<t[dh][^>]*>)\\s*(?<n>${hangulName(ALL_SURNAMES, () => "\\s*(?:\\||<\\/t[dh]>|$)")})`, "dg"),
1555
+ span: "n",
1556
+ mask: NAME_MASK,
1557
+ ok: (x) => NAME_HEADER_RE.test(x.header() ?? "") && nameOk(x, 1)
1558
+ },
1559
+ {
1560
+ // 직함 칸 바로 옆 칸이 이름 하나 — 결재란 "<td>주무관</td><td>김서준</td><td>복지기획팀장</td><td>유재민</td>".
1561
+ // 두 칸 모두 그 낱말뿐일 때만, 약한 문맥(흔한 성 + 세 글자)으로 — 옆 칸은 "귀하"·"직인"·"성명"·"사무관" 같은 서식 낱말이
1562
+ // 흔하다. 머리글 행은 이름 칸이 아니다 — HTML 은 <th>, GFM 은 첫 행(열 머리글이 없는 자리): "| 치과의원 | 한의원 |"
1563
+ re: new RegExp(`(?:^|\\||<t[dh][^>]*>)\\s*(?:${TITLE_RE}|${ORG_TITLE})\\s*(?:(?<pipe>\\|)|<\\/t[dh]>\\s*<td[^>]*>)\\s*(?<n>${hangulName(ALL_SURNAMES, () => "\\s*(?:\\||<\\/td>)")})`, "dg"),
1564
+ span: "n",
1565
+ mask: NAME_MASK,
1566
+ ok: (x) => (!g(x, "pipe") || x.header() !== void 0) && nameOk(x, 0)
1567
+ },
1568
+ {
1569
+ // 나열 — 앞에서 찾은 이름에 쉼표·와/과로 이어진 이름 ("문가윤, 방시우, 엄다인 등")
1570
+ re: new RegExp(`(?:[,\u3001\xB7]|(?<=[\uAC00-\uD7A3])(?:\uC640|\uACFC))\\s{0,2}(?<n>${hangulName(ALL_SURNAMES, tailRole)})`, "dg"),
1571
+ span: "n",
1572
+ mask: NAME_MASK,
1573
+ ok: (x) => {
1574
+ const p = x.prev();
1575
+ const n = span(x);
1576
+ return !!p && !!n && p.rule === "name" && LIST_GAP_RE.test(x.m.input.slice(p.end, n[0])) && nameOk(x, 0);
1577
+ }
1578
+ }
1579
+ ];
1580
+
1581
+ // src/redact-rules.ts
1582
+ var RULE_PRIORITY = [
1583
+ "crn",
1584
+ "rrn",
1585
+ "email",
1586
+ "card",
1587
+ "brn",
1588
+ "phone",
1589
+ "driver",
1590
+ "passport",
1591
+ "account",
1592
+ "ip",
1593
+ "address",
1594
+ "name"
1595
+ ];
1596
+ function luhnValid(digits) {
1597
+ let sum = 0;
1598
+ for (let i = 0; i < digits.length; i++) {
1599
+ let d = digits.charCodeAt(digits.length - 1 - i) - 48;
1600
+ if (i % 2 === 1) {
1601
+ d *= 2;
1602
+ if (d > 9) d -= 9;
1603
+ }
1604
+ sum += d;
1605
+ }
1606
+ return sum % 10 === 0;
1607
+ }
1608
+ var DAYS_IN_MONTH = [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
1609
+ function birthdateValid(front6, genderDigit) {
1610
+ const yy = Number(front6.slice(0, 2));
1611
+ const mm = Number(front6.slice(2, 4));
1612
+ const dd = Number(front6.slice(4, 6));
1613
+ if (mm < 1 || mm > 12 || dd < 1) return false;
1614
+ const g3 = Number(genderDigit);
1615
+ const year = (g3 === 3 || g3 === 4 || g3 === 7 || g3 === 8 ? 2e3 : 1900) + yy;
1616
+ if (year > (/* @__PURE__ */ new Date()).getFullYear()) return false;
1617
+ const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
1618
+ const max = mm === 2 ? leap ? 29 : 28 : DAYS_IN_MONTH[mm - 1];
1619
+ return dd <= max;
1620
+ }
1621
+ function brnChecksumValid(d) {
1622
+ const w = [1, 3, 7, 1, 3, 7, 1, 3, 5];
1623
+ let sum = 0;
1624
+ for (let i = 0; i < 9; i++) sum += w[i] * (d.charCodeAt(i) - 48);
1625
+ sum += Math.floor((d.charCodeAt(8) - 48) * 5 / 10);
1626
+ return (10 - sum % 10) % 10 === d.charCodeAt(9) - 48;
1627
+ }
1628
+ function crnChecksumValid(d) {
1629
+ let sum = 0;
1630
+ for (let i = 0; i < 12; i++) sum += (i % 2 === 0 ? 1 : 2) * (d.charCodeAt(i) - 48);
1631
+ return (10 - sum % 10) % 10 === d.charCodeAt(12) - 48;
1632
+ }
1633
+ var digitsOf = (s) => s.replace(/\D/g, "");
1634
+ var allSameDigit = (d) => d.length > 0 && /^(\d)\1*$/.test(d);
1635
+ var LABELS = [
1636
+ ["crn", /법\s*인\s*(?:등\s*록\s*)?번\s*호/g],
1637
+ ["rrn", /주\s*민\s*(?:등\s*록\s*)?번\s*호|주\s*민\s*등\s*록|외\s*국\s*인\s*(?:등\s*록\s*)?번\s*호|거\s*소\s*신\s*고\s*번\s*호|생\s*년\s*월\s*일|resident\s*registration|\bRRN\b/gi],
1638
+ ["brn", /사\s*업\s*자\s*(?:등\s*록\s*)?번\s*호|고\s*유\s*번\s*호|business\s*registration/gi],
1639
+ ["account", /계\s*좌|예\s*금\s*주|입\s*금|은\s*행|뱅\s*크|농\s*협|신\s*협|수\s*협|우\s*체\s*국|금\s*고|bank\s*account|account\s*(?:no|number)/gi],
1640
+ ["card", /카\s*드|credit\s*card|card\s*(?:no|number)/gi],
1641
+ ["phone", /전\s*화|연\s*락\s*처|휴\s*대|핸\s*드\s*폰|팩\s*스|☎|☏|콜\s*센\s*터|고\s*객\s*센\s*터|대\s*표\s*번\s*호|상\s*담|문\s*의|\b(?:tel|fax|mobile|phone|h\.?p|ARS)\b/gi],
1642
+ ["passport", /여\s*권|passport/gi],
1643
+ ["driver", /운\s*전\s*면\s*허|면\s*허\s*번\s*호|driver'?s?\s*licen[cs]e/gi],
1644
+ ["ip", /\bIP\b|아\s*이\s*피/g],
1645
+ ["other", /출\s*원\s*번\s*호|과\s*제\s*번\s*호|사\s*업\s*번\s*호|접\s*수\s*번\s*호|민\s*원\s*번\s*호|신\s*청\s*번\s*호|문\s*서\s*번\s*호|관\s*리\s*번\s*호|주\s*문\s*번\s*호|일\s*련\s*번\s*호|발\s*간\s*등\s*록|등\s*록\s*번\s*호\s*\(\s*기\s*록|ISBN|ISSN|예\s*산|과\s*목|코\s*드|모\s*델|제\s*품|부\s*품|시\s*리\s*얼|serial|model|\bS\/N\b|바\s*코\s*드|기\s*록\s*물|사\s*건\s*번\s*호/gi]
1646
+ ];
1647
+ var CELL_SEP_RE = /(?<!\\)\||<\/t[dh]>/gi;
1648
+ var PREV_VALUE_RE = /\d[\d\-.\s]{4,}\d/g;
1649
+ function labelsIn(s) {
1650
+ const out = /* @__PURE__ */ new Set();
1651
+ for (const [ctx, re] of LABELS) {
1652
+ re.lastIndex = 0;
1653
+ if (re.test(s)) out.add(ctx);
1654
+ }
1655
+ return out;
1656
+ }
1657
+ function labelsBefore(norm, start) {
1658
+ let win = norm.slice(Math.max(0, start - 120), start);
1659
+ const seps = [...win.matchAll(CELL_SEP_RE)];
1660
+ if (seps.length >= 2) {
1661
+ const s = seps[seps.length - 2];
1662
+ win = win.slice(s.index + s[0].length);
1663
+ }
1664
+ win = win.replace(/<[^>]*>/g, " ").slice(-40);
1665
+ const prev = [...win.matchAll(PREV_VALUE_RE)].pop();
1666
+ if (prev) win = win.slice(prev.index + prev[0].length);
1667
+ return labelsIn(win);
1668
+ }
1669
+ var OTHER_AFTER_RE = /^\s{0,2}[(\[]?\s{0,2}(?:접\s*수|신\s*청|주\s*문|사\s*건|과\s*제|문\s*서|관\s*리|부\s*품|제\s*품|모\s*델|코\s*드|시\s*리\s*얼|serial|model)/i;
1670
+ var g2 = (x, name) => x.m.groups?.[name] ?? "";
1671
+ var has = (x, c) => x.ctx().has(c);
1672
+ var crnOnly = (x) => has(x, "crn") && !has(x, "rrn");
1673
+ var after = (x, n = 16) => {
1674
+ const end = x.m.index + x.m[0].length;
1675
+ return x.m.input.slice(end, end + n);
1676
+ };
1677
+ var before = (x, n = 2) => {
1678
+ const start = x.m.index;
1679
+ return x.m.input.slice(Math.max(0, start - n), start);
1680
+ };
1681
+ var otherCtx = (x, own) => has(x, "other") && !has(x, own) || OTHER_AFTER_RE.test(after(x));
1682
+ var SERIAL_BEFORE_RE = /(?:\bS\/N|\bserial(?:\s*(?:no|number))?|시\s*리\s*얼(?:\s*번\s*호)?|일\s*련\s*번\s*호|바\s*코\s*드)\s*[:.]?\s*$/i;
1683
+ var serialBefore = (x) => SERIAL_BEFORE_RE.test(before(x, 20)) && !has(x, "phone");
1684
+ var PHONE_PREFIX = "0(?:1[016789]|2|3[1-3]|4[1-4]|5[1-5]|6[1-4]|70|80|60|50[2-8])";
1685
+ var PHONE_AREA = "0(?:1[016789]|2|3[1-3]|4[1-4]|5[1-5]|6[1-4]|70|80|50[2-8])";
1686
+ var PHONE_SEP = "(?: {0,2}- {0,2}| {1,2}|\\.)";
1687
+ var PHONE_END = "(?![\\w@-])";
1688
+ function phoneSepsOk(x, s1, s2) {
1689
+ if (s1 === "" !== (s2 === "")) return false;
1690
+ if (s1 === "." !== (s2 === ".")) return false;
1691
+ return s1 !== "." || !/^\.\d/.test(after(x, 2));
1692
+ }
1693
+ function phoneDigitsOk(pre, mid, last, bare) {
1694
+ if (/^0+$/.test(mid + last)) return false;
1695
+ return !bare || !/^0(?:2|3[1-3]|4[1-4]|5[1-5]|6[1-4])$/.test(pre) || mid[0] !== "0";
1696
+ }
1697
+ var EMAIL_START = "(?<![\\w%+])(?<!\\w[.\\-])(?<![A-Za-z0-9][*\u25CF\u25CB\u25EF\xD7#]+)";
1698
+ var EMAIL_DOMAIN = "(?<domain>[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?(?:\\.[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?)*\\.(?<tld>[A-Za-z]{2,24}))(?![\\w-])";
1699
+ var FILE_EXT_TLD = /^(?:png|jpe?g|gif|bmp|svg|webp|tiff?|hwpx?|hwp|pdf|docx?|xlsx?|pptx?|txt|zip|csv|json|xml|html?|js|css|mp[34]|wav|avi|exe)$/i;
1700
+ var RULES = {
1701
+ // 주민·외국인등록번호 — 앞 6자리(생년월일) 유지, 뒤 7자리 마스크
1702
+ rrn: [
1703
+ {
1704
+ // 하이픈형 (앞뒤 공백 0~2칸, 유니코드 대시는 정규화로 흡수). 뒤에 "-글자"는 허용, "-숫자"는 더 긴 코드.
1705
+ // 법인 라벨만 있으면 제외
1706
+ re: /(?<![\w-])(?<front>\d{6})(?<sep> {0,2}- {0,2})(?<back>[1-8]\d{6})(?![\w])(?!-\d)/dg,
1707
+ ok: (x) => birthdateValid(g2(x, "front"), g2(x, "back")[0]) && !crnOnly(x),
1708
+ mask: ["back"]
1709
+ },
1710
+ {
1711
+ // 뒷자리 일부만 가린 형태 (900101-1******, 900101-1694***) — 남은 숫자를 가린다
1712
+ re: /(?<![\w-])(?<front>\d{6})(?<sep> {0,2}- {0,2})(?<back>[1-8][0-9*●○◯×xX#]{6})(?![\w*●○◯×#])(?!-\d)/dg,
1713
+ ok: (x) => /[*●○◯×xX#]/.test(g2(x, "back")) && birthdateValid(g2(x, "front"), g2(x, "back")[0]) && !crnOnly(x),
1714
+ mask: ["back"]
1715
+ },
1716
+ {
1717
+ // 구분자 없음·공백/온점/가운뎃점/빗금/물결 구분 — 주민/외국인등록번호(생년월일) 라벨이 있을 때만
1718
+ re: /(?<![\w@.-])(?<front>\d{6})(?<sep>[ .·/~]?)(?<back>[1-8]\d{6})(?![\w@-])/dg,
1719
+ needs: "rrn",
1720
+ ok: (x) => birthdateValid(g2(x, "front"), g2(x, "back")[0]),
1721
+ mask: ["back"]
1722
+ }
1723
+ ],
1724
+ // 법인등록번호 (opt-in) — 법인 라벨이 있거나, 뒷자리가 0으로 시작(주민번호 불가)하고 체크섬 유효
1725
+ crn: [
1726
+ {
1727
+ re: /(?<![\w-])(?<front>\d{6})(?<sep> {0,2}- {0,2})(?<back>\d{7})(?![\w-])/dg,
1728
+ ok: (x) => !allSameDigit(g2(x, "front") + g2(x, "back")) && (crnOnly(x) || g2(x, "back")[0] === "0" && crnChecksumValid(g2(x, "front") + g2(x, "back"))),
1729
+ mask: ["back"]
1730
+ },
1731
+ {
1732
+ re: /(?<![\w@.-])(?<front>\d{6})(?<back>\d{7})(?![\w@-])/dg,
1733
+ needs: "crn",
1734
+ ok: (x) => !allSameDigit(g2(x, "front") + g2(x, "back")) && !has(x, "rrn"),
1735
+ mask: ["back"]
1736
+ }
1737
+ ],
1738
+ // 이메일 — 로컬파트 첫 글자만 남기고 마스크, 도메인 유지. 파일명(image@2x.png)은 제외
1739
+ // 이미 가린 로컬파트(j*********5@…) 뒤꼬리에서 시작하지 않는다 — 가림표 바로 뒤 매치 금지
1740
+ email: [
1741
+ {
1742
+ re: new RegExp(`${EMAIL_START}(?<l1>[A-Za-z0-9])(?<lrest>[A-Za-z0-9._%+-]+)@${EMAIL_DOMAIN}`, "dg"),
1743
+ ok: (x) => !FILE_EXT_TLD.test(g2(x, "tld")),
1744
+ mask: ["lrest"],
1745
+ maskAll: true
1746
+ },
1747
+ {
1748
+ // 한 글자 로컬파트 — 첫 글자를 남기면 가린 게 없으므로 전부 가린다
1749
+ re: new RegExp(`${EMAIL_START}(?<l1>[A-Za-z0-9])@${EMAIL_DOMAIN}`, "dg"),
1750
+ ok: (x) => !FILE_EXT_TLD.test(g2(x, "tld")),
1751
+ mask: ["l1"]
1752
+ }
1753
+ ],
1754
+ // 카드번호 — 가운데 마스크 + Luhn. 구분자 없는 15~16자리는 카드 라벨이 있을 때만
1755
+ card: [
1756
+ {
1757
+ // 4-4-4-4 (같은 구분자 강제)
1758
+ re: /(?<![\w-])(?<g1>\d{4})(?<sep>[- ])(?<g2>\d{4})\k<sep>(?<g3>\d{4})\k<sep>(?<g4>\d{4})(?![\w-])(?![- ]\d)/dg,
1759
+ ok: (x) => {
1760
+ const d = digitsOf(x.m[0]);
1761
+ return luhnValid(d) && !allSameDigit(d);
1762
+ },
1763
+ mask: ["g2", "g3"]
1764
+ },
1765
+ {
1766
+ // AMEX 4-6-5
1767
+ re: /(?<![\w-])(?<g1>3[47]\d{2})(?<sep>[- ])(?<g2>\d{6})\k<sep>(?<g3a>\d)(?<g3b>\d{4})(?![\w-])(?![- ]\d)/dg,
1768
+ ok: (x) => luhnValid(digitsOf(x.m[0])),
1769
+ mask: ["g2", "g3a"]
1770
+ },
1771
+ {
1772
+ // 온점 구분 4.4.4.4 — 카드 라벨 필요 (버전·좌표 모양과 겹침)
1773
+ re: /(?<![\w.-])(?<g1>\d{4})\.(?<g2>\d{4})\.(?<g3>\d{4})\.(?<g4>\d{4})(?![\w-])(?!\.\d)/dg,
1774
+ needs: "card",
1775
+ ok: (x) => {
1776
+ const d = digitsOf(x.m[0]);
1777
+ return luhnValid(d) && !allSameDigit(d);
1778
+ },
1779
+ mask: ["g2", "g3"]
1780
+ },
1781
+ {
1782
+ // 무구분 15~16자리 — 카드 라벨 필요
1783
+ re: /(?<![\w@.-])(?<g1>\d{4})(?<mid>\d{7,8})(?<g4>\d{4})(?![\w@-])/dg,
1784
+ needs: "card",
1785
+ ok: (x) => {
1786
+ const d = digitsOf(x.m[0]);
1787
+ return luhnValid(d) && !allSameDigit(d);
1788
+ },
1789
+ mask: ["mid"]
1790
+ }
1791
+ ],
1792
+ // 사업자등록번호 3-2-5 — 체크섬 유효 또는 사업자 라벨. 뒤 5자리(일련·검증번호) 마스크
1793
+ brn: [
1794
+ {
1795
+ re: /(?<![\w-])(?<a>\d{3})-(?<b>\d{2})-(?<c>\d{5})(?![\w-])/dg,
1796
+ ok: (x) => {
1797
+ const d = digitsOf(x.m[0]);
1798
+ if (allSameDigit(d)) return false;
1799
+ return has(x, "brn") || brnChecksumValid(d) && !has(x, "account") && !otherCtx(x, "brn");
1800
+ },
1801
+ mask: ["c"]
1802
+ },
1803
+ {
1804
+ re: /(?<![\w@.-])(?<a>\d{3})(?<b>\d{2})(?<c>\d{5})(?![\w@-])/dg,
1805
+ needs: "brn",
1806
+ ok: (x) => !allSameDigit(digitsOf(x.m[0])),
1807
+ mask: ["c"]
1808
+ }
1809
+ ],
1810
+ // 전화번호 — 가운데 자리만 마스크 (대표번호는 뒤 4자리).
1811
+ // 뒤에 "-"가 붙으면 더 긴 코드(예산과목 064-1100-1131-301-210)의 일부라 제외.
1812
+ phone: [
1813
+ {
1814
+ // 국내 일반: 휴대폰·지역·070/080/060·050x 안심번호. 구분자 -·공백·온점(PHONE_SEP) 또는 무구분
1815
+ re: new RegExp(`(?<![\\w@+-])(?<pre>${PHONE_PREFIX})(?<s1>${PHONE_SEP}?)(?<mid>\\d{3,4})(?<s2>${PHONE_SEP}?)(?<last>\\d{4})${PHONE_END}`, "dg"),
1816
+ ok: (x) => {
1817
+ const pre = g2(x, "pre");
1818
+ const bare = g2(x, "s1") === "";
1819
+ if (!phoneSepsOk(x, g2(x, "s1"), g2(x, "s2"))) return false;
1820
+ if (!phoneDigitsOk(pre, g2(x, "mid"), g2(x, "last"), bare)) return false;
1821
+ if (serialBefore(x)) return false;
1822
+ if (!bare) return true;
1823
+ if (/\d\.$/.test(before(x))) return false;
1824
+ if (pre.startsWith("01")) return true;
1825
+ return !/\d,$/.test(before(x)) && !/^,\d/.test(after(x, 2));
1826
+ },
1827
+ mask: ["mid"]
1828
+ },
1829
+ {
1830
+ // 괄호 지역번호: (02) 123-4567, (042)481-6300
1831
+ re: new RegExp(`(?<![\\w@])\\((?<pre>${PHONE_AREA})\\) ?(?<mid>\\d{3,4})(?<s2>${PHONE_SEP}?)(?<last>\\d{4})${PHONE_END}`, "dg"),
1832
+ ok: (x) => phoneDigitsOk(g2(x, "pre"), g2(x, "mid"), g2(x, "last"), false) && (g2(x, "s2") !== "." || !/^\.\d/.test(after(x, 2))),
1833
+ mask: ["mid"]
1834
+ },
1835
+ {
1836
+ // 지역번호 뒤 닫는 괄호: 02)450-1234
1837
+ re: new RegExp(`(?<![\\w@(+-])(?<!\\d\\.)(?<pre>${PHONE_AREA})\\) ?(?<mid>\\d{3,4})(?<s2>${PHONE_SEP})(?<last>\\d{4})${PHONE_END}`, "dg"),
1838
+ ok: (x) => phoneDigitsOk(g2(x, "pre"), g2(x, "mid"), g2(x, "last"), false) && (g2(x, "s2") !== "." || !/^\.\d/.test(after(x, 2))),
1839
+ mask: ["mid"]
1840
+ },
1841
+ {
1842
+ // 국제 표기: +82 10-1234-5678, +82-2-123-4567, +82 (0)10 1234 5678, +821012345678
1843
+ re: new RegExp(`(?<![\\w@+])(?<cc>\\+82)(?<s0>[-. ]?)(?:\\(0\\) ?)?(?<pre>1[016789]|2|3[1-3]|4[1-4]|5[1-5]|6[1-4]|70|80)(?<s1>${PHONE_SEP}?)(?<mid>\\d{3,4})(?<s2>${PHONE_SEP}?)(?<last>\\d{4})${PHONE_END}`, "dg"),
1844
+ ok: (x) => phoneSepsOk(x, g2(x, "s1"), g2(x, "s2")) && phoneDigitsOk("0" + g2(x, "pre"), g2(x, "mid"), g2(x, "last"), g2(x, "s1") === ""),
1845
+ mask: ["mid"]
1846
+ },
1847
+ {
1848
+ // 대표번호 15xx·16xx·18xx — 구분자 필수. 연도 범위 모양(1592-1598)·온점/공백 구분은 전화 라벨이 있을 때만.
1849
+ // 뒤 4자리 0000 은 자리표시자
1850
+ re: new RegExp(`(?<![\\w@+-])(?<!\\d\\.)(?<pre>1(?:5[2-9]\\d|6\\d\\d|8\\d\\d))(?<sep> {0,2}- {0,2}| {1,2}|\\.)(?<last>\\d{4})${PHONE_END}`, "dg"),
1851
+ ok: (x) => {
1852
+ if (g2(x, "last") === "0000" || serialBefore(x)) return false;
1853
+ if (g2(x, "sep") === "." && /^\.\d/.test(after(x, 2))) return false;
1854
+ const a = Number(g2(x, "pre"));
1855
+ const b = Number(g2(x, "last"));
1856
+ const yearRange = b >= a && b <= (/* @__PURE__ */ new Date()).getFullYear();
1857
+ return g2(x, "sep").trim() === "-" && !yearRange || has(x, "phone");
1858
+ },
1859
+ mask: ["last"]
1860
+ }
1861
+ ],
1862
+ // 운전면허번호 — 지역코드(11~28)-연도-일련6-검증2 / 구형 지역명 + 2-6-2. 뒤 8자리 마스크
1863
+ driver: [
1864
+ {
1865
+ // 신형 — 무문맥이지만 비개인 식별번호 문맥("(접수)" 등)이면 아님
1866
+ re: /(?<![\w-])(?<r>1[1-9]|2[0-8])-(?<y>\d{2})-(?<s>\d{6})-(?<c>\d{2})(?![\w-])/dg,
1867
+ ok: (x) => has(x, "driver") || !otherCtx(x, "driver"),
1868
+ mask: ["s", "c"]
1869
+ },
1870
+ {
1871
+ re: /(?<rn>서울|부산|경기|강원|충북|충남|전북|전남|경북|경남|제주|대구|인천|광주|대전|울산) ?(?<y>\d{2})-(?<s>\d{6})-(?<c>\d{2})(?![\w-])/dg,
1872
+ mask: ["s", "c"]
1873
+ },
1874
+ {
1875
+ re: /(?<![\w@.-])(?<r>1[1-9]|2[0-8])(?<y>\d{2})(?<s>\d{6})(?<c>\d{2})(?![\w@-])/dg,
1876
+ needs: "driver",
1877
+ mask: ["s", "c"]
1878
+ }
1879
+ ],
1880
+ // 여권번호 — 신형 복수여권(M123A4567)은 무문맥, 그 밖의 종류 글자(S·R·O·D·G)와 구형(M12345678)은 여권 라벨
1881
+ // 필요 ("S123A4567 부품" 같은 제품 코드). 첫 글자만 남김
1882
+ passport: [
1883
+ {
1884
+ re: /(?<![A-Za-z0-9])(?<l>[MSRODG])(?<num>\d{3}[A-Z]\d{4})(?![A-Za-z0-9])/dg,
1885
+ ok: (x) => has(x, "passport") || g2(x, "l") === "M" && !otherCtx(x, "passport"),
1886
+ mask: ["num"]
1887
+ },
1888
+ {
1889
+ re: /(?<![A-Za-z0-9])(?<l>[MSRODG])(?<num>\d{8})(?![A-Za-z0-9])/dg,
1890
+ needs: "passport",
1891
+ mask: ["num"]
1892
+ },
1893
+ {
1894
+ // 소문자로 친 여권번호(m123a4567) — 여권 라벨이 있을 때만
1895
+ re: /(?<![A-Za-z0-9])(?<l>[msrodg])(?<num>\d{3}[a-z]\d{4}|\d{8})(?![A-Za-z0-9])/dg,
1896
+ needs: "passport",
1897
+ mask: ["num"]
1898
+ }
1899
+ ],
1900
+ // 계좌번호 — 하이픈 3~4그룹, 총 11~16자리 (10자리는 계좌 라벨 필요). 마지막 그룹 빼고 마스크.
1901
+ // 무구분 10~14자리는 계좌·은행 라벨이 있을 때만 (뒤 4자리 유지)
1902
+ account: [
1903
+ {
1904
+ // 마지막 그룹 1자리 허용 — 새마을금고 9002-1234-5678-9, 3-2-6-1·3-3-6-1 형식
1905
+ re: /(?<![\w-])(?<!\d\.)(?<head>\d{2,6}(?:-\d{2,6}){1,2})-(?<last>\d{1,8})(?![\w-])(?!\.\d)/dg,
1906
+ ok: (x) => {
1907
+ const s = x.m[0];
1908
+ const d = digitsOf(s);
1909
+ const acct = has(x, "account");
1910
+ if (allSameDigit(d) || !acct && otherCtx(x, "account")) return false;
1911
+ if (!acct && (/\d,$/.test(before(x)) || /^,\d/.test(after(x, 2)))) return false;
1912
+ if (/^\d+(?:-0+)+$/.test(s)) return false;
1913
+ if (d.length < 10 || d.length > 16 || d.length === 10 && !acct) return false;
1914
+ if (/^\s*원/.test(after(x, 3))) return false;
1915
+ if (acct) return true;
1916
+ if (/^(?:10|20|30|40)-(?:19|20)\d\d-\d{6,7}$/.test(s)) return false;
1917
+ if (/^(?:19|20)\d\d-(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])?-/.test(s)) return false;
1918
+ if (s.split("-").filter((p) => /^(?:19|20)\d\d$/.test(p)).length >= 2) return false;
1919
+ if (/^\d{3}-\d{2}-\d{5}$/.test(s) && brnChecksumValid(d)) return false;
1920
+ return true;
1921
+ },
1922
+ mask: ["head"]
1923
+ },
1924
+ {
1925
+ re: /(?<![\w@.-])(?<!\d,)(?<head>\d{6,10})(?<last>\d{4})(?![\w@-])(?!,\d)/dg,
1926
+ needs: "account",
1927
+ ok: (x) => !allSameDigit(x.m[0]),
1928
+ mask: ["head"]
1929
+ }
1930
+ ],
1931
+ // IPv4 (opt-in) — 옥텟 0~255, 첫 옥텟 10 이상(1.2.3.4 절 번호·버전 제외) 또는 IP 라벨. 뒤 두 옥텟 마스크
1932
+ ip: [
1933
+ {
1934
+ re: /(?<![\w.])(?<a>\d{1,3})\.(?<b>\d{1,3})\.(?<c>\d{1,3})\.(?<d>\d{1,3})(?![\w])(?!\.\d)/dg,
1935
+ ok: (x) => {
1936
+ const oct = [g2(x, "a"), g2(x, "b"), g2(x, "c"), g2(x, "d")];
1937
+ if (oct.some((o) => Number(o) > 255 || o.length > 1 && o[0] === "0")) return false;
1938
+ return Number(oct[0]) >= 10 || has(x, "ip");
1939
+ },
1940
+ mask: ["c", "d"]
1941
+ }
1942
+ ],
1943
+ // 주소·인명 (opt-in) — 사전 + 문맥 게이트, redact-name-address.ts
1944
+ address: ADDRESS_VARIANTS,
1945
+ name: NAME_VARIANTS
1946
+ };
1947
+
1948
+ // src/redact.ts
1949
+ var DEFAULT_REDACT_RULES = [
1950
+ "rrn",
1951
+ "phone",
1952
+ "email",
1953
+ "card",
1954
+ "account",
1955
+ "brn",
1956
+ "passport",
1957
+ "driver"
1958
+ ];
1959
+ var ALL_REDACT_RULES = [...DEFAULT_REDACT_RULES, "crn", "ip", "name", "address"];
1960
+ var DASHES = /* @__PURE__ */ new Set([8208, 8209, 8210, 8211, 8212, 8213, 8722, 65112, 65123, 65293, 9472, 9473, 12641, 12540]);
1961
+ var SPACES = /* @__PURE__ */ new Set([160, 8194, 8195, 8196, 8197, 8198, 8199, 8200, 8201, 8202, 8239, 12288]);
1962
+ function normalizeForDetect(text) {
1963
+ let out = "";
1964
+ let changed = false;
1965
+ for (let i = 0; i < text.length; i++) {
1966
+ const c = text.charCodeAt(i);
1967
+ let r = c;
1968
+ if (c >= 65281 && c <= 65374) r = c - 65248;
1969
+ if (DASHES.has(c)) r = 45;
1970
+ else if (SPACES.has(c)) r = 32;
1971
+ if (r !== c) changed = true;
1972
+ out += r === c ? text[i] : String.fromCharCode(r);
1973
+ }
1974
+ return changed ? out : text;
1975
+ }
1976
+ function maskMatch(orig, norm, start, x, v, maskChar) {
1977
+ const chars = orig.split("");
1978
+ const idx = x.m.indices?.groups;
1979
+ for (const name of v.mask) {
1980
+ const r = idx?.[name];
1981
+ if (!r) continue;
1982
+ for (let i = r[0] - start; i < r[1] - start; i++) {
1983
+ if (v.maskAll || /[\p{L}\p{N}]/u.test(norm[start + i])) chars[i] = maskChar;
1984
+ }
1985
+ }
1986
+ return chars.join("");
1987
+ }
1988
+ function assertMaskChar(maskChar) {
1989
+ const n = normalizeForDetect(maskChar);
1990
+ if (maskChar.length !== 1 || /[0-9A-Za-z|\\<>&"'._\-@+:/,;]/.test(n) || /[\p{Z}\p{C}\p{M}]/u.test(maskChar) || /[\uFDD0-\uFDEF\uFFFE\uFFFF]/.test(maskChar)) {
1991
+ throw new Error(`maskChar\uB294 \uC601\uC22B\uC790\xB7\uACF5\uBC31\xB7\uC81C\uC5B4/\uACB0\uD569 \uBB38\uC790\xB7\uAD6C\uBD84 \uAE30\uD638(|\\<>&"'._-@+:/,;)\uAC00 \uC544\uB2CC \uBCF4\uC774\uB294 1\uAE00\uC790\uC5EC\uC57C \uD568: ${JSON.stringify(maskChar)}`);
1992
+ }
1993
+ }
1994
+ var LIST_SEP_RE = /^\s{0,2}(?:[,;/·、]|및|또는)?\s{0,2}$/;
1995
+ function detect(text, rules, maskChar, headerAt) {
1996
+ const norm = normalizeForDetect(text);
1997
+ const hits = [];
1998
+ const occupied = [];
1999
+ for (const rule of RULE_PRIORITY) {
2000
+ if (!rules.includes(rule)) continue;
2001
+ for (const v of RULES[rule]) {
2002
+ const re = v.re;
2003
+ re.lastIndex = 0;
2004
+ for (let m = re.exec(norm); m !== null; m = re.exec(norm)) {
2005
+ const sg = v.span ? m.indices?.groups?.[v.span] : void 0;
2006
+ const start = sg ? sg[0] : m.index;
2007
+ const end = sg ? sg[1] : start + m[0].length;
2008
+ const retry = () => {
2009
+ if (sg) re.lastIndex = Math.max(m.index + 1, start);
2010
+ };
2011
+ if (occupied.some((o) => start < o.end && end > o.start)) {
2012
+ retry();
2013
+ continue;
2014
+ }
2015
+ let cached;
2016
+ const ctx = () => {
2017
+ if (!cached) {
2018
+ let c = labelsBefore(norm, start);
2019
+ if (c.size === 0) {
2020
+ const prev = occupied.find((o) => o.end < start && start - o.end <= 6 && LIST_SEP_RE.test(norm.slice(o.end, start)));
2021
+ if (prev) c = prev.rule === "email" ? prev.ctx() : /* @__PURE__ */ new Set([...prev.ctx(), prev.rule]);
2022
+ }
2023
+ if (c.size === 0 && headerAt) {
2024
+ const h = headerAt(start);
2025
+ if (h) c = labelsIn(normalizeForDetect(h));
2026
+ }
2027
+ cached = c;
2028
+ }
2029
+ return cached;
2030
+ };
2031
+ const x = {
2032
+ m,
2033
+ ctx,
2034
+ header: () => headerAt?.(start),
2035
+ prev: () => {
2036
+ let best;
2037
+ for (const o of occupied) if (o.end <= start && (!best || o.end > best.end)) best = o;
2038
+ return best;
2039
+ }
2040
+ };
2041
+ if (v.needs && !ctx().has(v.needs) || v.ok && !v.ok(x)) {
2042
+ retry();
2043
+ continue;
2044
+ }
2045
+ occupied.push({ start, end, ctx, rule });
2046
+ hits.push({ rule, masked: maskMatch(text.slice(start, end), norm, start, x, v, maskChar), index: start, length: end - start });
2047
+ }
2048
+ }
2049
+ }
2050
+ return hits.sort((a, b) => a.index - b.index);
2051
+ }
2052
+ function applyHits(text, hits) {
2053
+ let out = "";
2054
+ let cursor = 0;
2055
+ for (const h of hits) {
2056
+ out += text.slice(cursor, h.index) + h.masked;
2057
+ cursor = h.index + h.length;
2058
+ }
2059
+ return out + text.slice(cursor);
2060
+ }
2061
+ function redactText(text, options) {
2062
+ const maskChar = options?.maskChar ?? "\u25CF";
2063
+ assertMaskChar(maskChar);
2064
+ const rules = options?.rules ?? DEFAULT_REDACT_RULES;
2065
+ if (text === "" || rules.length === 0) return { text, hits: [] };
2066
+ const hits = detect(text, rules, maskChar);
2067
+ return { text: applyHits(text, hits), hits };
2068
+ }
2069
+ function pipePositions(line) {
2070
+ const out = [];
2071
+ for (let i = 0; i < line.length; i++) {
2072
+ if (line[i] === "|" && line[i - 1] !== "\\") out.push(i);
2073
+ }
2074
+ return out;
2075
+ }
2076
+ var isGfmRow = (l) => /^\s*\|.*\|\s*$/.test(l);
2077
+ var isGfmSep = (l) => /^\s*\|(?:\s*:?-{3,}:?\s*\|)+\s*$/.test(l);
2078
+ function htmlCells(line) {
2079
+ const out = [];
2080
+ let col = 0;
2081
+ for (const m of line.matchAll(/<t([dh])\b([^>]*)>([\s\S]*?)<\/t\1>/gi)) {
2082
+ const span2 = Math.max(1, Number(m[2].match(/colspan="?(\d+)/i)?.[1] ?? 1));
2083
+ out.push({ start: m.index, end: m.index + m[0].length, col, span: span2, text: m[3].replace(/<[^>]*>/g, " ") });
2084
+ col += span2;
2085
+ }
2086
+ return out;
2087
+ }
2088
+ function tableHeaderContext(lines) {
2089
+ const out = /* @__PURE__ */ new Map();
2090
+ for (let i = 0; i < lines.length; i++) {
2091
+ if (isGfmRow(lines[i]) && i + 1 < lines.length && isGfmSep(lines[i + 1])) {
2092
+ const head = lines[i];
2093
+ const hp = pipePositions(head);
2094
+ const headers = hp.slice(0, -1).map((p, k) => head.slice(p + 1, hp[k + 1]));
2095
+ let j = i + 2;
2096
+ for (; j < lines.length && isGfmRow(lines[j]); j++) {
2097
+ const rp = pipePositions(lines[j]);
2098
+ out.set(j, (off) => {
2099
+ let k = -1;
2100
+ for (const p of rp) {
2101
+ if (p < off) k++;
2102
+ else break;
2103
+ }
2104
+ return k >= 0 ? headers[k] : void 0;
2105
+ });
2106
+ }
2107
+ i = j - 1;
2108
+ continue;
2109
+ }
2110
+ if (/<table\b/i.test(lines[i])) {
2111
+ let headers = null;
2112
+ let depth = 0;
2113
+ for (let j = i; j < lines.length; j++) {
2114
+ depth += (lines[j].match(/<table\b/gi) ?? []).length;
2115
+ if (/<tr\b/i.test(lines[j]) && depth === 1) {
2116
+ const cells = htmlCells(lines[j]);
2117
+ if (!headers) headers = cells;
2118
+ else if (cells.length > 0) {
2119
+ const hdr = headers;
2120
+ out.set(j, (off) => {
2121
+ const c = cells.find((x) => off >= x.start && off < x.end);
2122
+ if (!c) return void 0;
2123
+ const h = hdr.find((x) => c.col >= x.col && c.col < x.col + x.span);
2124
+ return h?.text;
2125
+ });
2126
+ }
2127
+ }
2128
+ depth -= (lines[j].match(/<\/table>/gi) ?? []).length;
2129
+ if (depth <= 0) {
2130
+ i = j;
2131
+ break;
2132
+ }
2133
+ }
2134
+ }
2135
+ }
2136
+ return out;
2137
+ }
2138
+ var MD_ALWAYS_MARKER_RE = new RegExp([
2139
+ "(?<!\\*)\\*\\*(?!\\*)",
2140
+ "(?<!_)__(?!_)",
2141
+ "(?<!~)~~(?!~)",
2142
+ "<\\/?(?:u|b|i|s|em|strong|sup|sub|del|span|mark|small|big|ins|strike|tt|code|kbd|samp|var|q|cite|abbr|dfn)>",
2143
+ "\\\\(?=[\\\\`*_{}[\\]()#+\\-.!|~>])"
2144
+ ].join("|"), "g");
2145
+ var MD_OPEN_RE = /(?<![\w*\\])(\*\*\*|\*|_)(?=[0-9A-Za-z0-9])/g;
2146
+ var MD_CLOSE_RE = /(?<=[0-9A-Za-z0-9])(\*\*\*|\*|_)(?![\w*])/g;
2147
+ function mdMarkerRanges(line) {
2148
+ const out = [];
2149
+ for (const m of line.matchAll(MD_ALWAYS_MARKER_RE)) out.push([m.index, m.index + m[0].length]);
2150
+ const taken = (a, b) => out.some(([s, e]) => a < e && b > s);
2151
+ const closes = [...line.matchAll(MD_CLOSE_RE)].filter((m) => !taken(m.index, m.index + m[0].length));
2152
+ let from = 0;
2153
+ for (const o of line.matchAll(MD_OPEN_RE)) {
2154
+ const os = o.index;
2155
+ const oe = os + o[0].length;
2156
+ if (os < from || taken(os, oe)) continue;
2157
+ const c = closes.find((m) => m.index >= oe && m[0] === o[0]);
2158
+ if (!c) continue;
2159
+ out.push([os, oe], [c.index, c.index + c[0].length]);
2160
+ from = c.index + c[0].length;
2161
+ }
2162
+ return out.sort((a, b) => a[0] - b[0]);
2163
+ }
2164
+ function detectMarkdownLine(line, rules, maskChar, headerAt) {
2165
+ const markers = mdMarkerRanges(line);
2166
+ if (markers.length === 0) return detect(line, rules, maskChar, headerAt);
2167
+ let clean = "";
2168
+ const map = [];
2169
+ let cursor = 0;
2170
+ const keep = (to) => {
2171
+ for (let i = cursor; i < to; i++) {
2172
+ clean += line[i];
2173
+ map.push(i);
2174
+ }
2175
+ };
2176
+ for (const [ms, me] of markers) {
2177
+ keep(ms);
2178
+ cursor = me;
2179
+ }
2180
+ keep(line.length);
2181
+ const hits = detect(clean, rules, maskChar, headerAt ? (i) => headerAt(map[i] ?? i) : void 0);
2182
+ return hits.map((h) => {
2183
+ const start = map[h.index];
2184
+ const end = map[h.index + h.length - 1] + 1;
2185
+ const chars = line.slice(start, end).split("");
2186
+ for (let k = 0; k < h.length; k++) {
2187
+ if (h.masked[k] !== clean[h.index + k]) chars[map[h.index + k] - start] = maskChar;
2188
+ }
2189
+ return { rule: h.rule, masked: chars.join(""), index: start, length: end - start };
2190
+ });
2191
+ }
2192
+ function redactMarkdown(markdown, options) {
2193
+ const maskChar = options?.maskChar ?? "\u25CF";
2194
+ assertMaskChar(maskChar);
2195
+ const rules = options?.rules ?? DEFAULT_REDACT_RULES;
2196
+ const lines = markdown.split("\n");
2197
+ const headers = tableHeaderContext(lines);
2198
+ const hits = [];
2199
+ let offset = 0;
2200
+ const outLines = lines.map((line, i) => {
2201
+ if (line.includes("data:image/") || line === "" || rules.length === 0) {
2202
+ offset += line.length + 1;
2203
+ return line;
2204
+ }
2205
+ const lineHits = detectMarkdownLine(line, rules, maskChar, headers.get(i));
2206
+ for (const h of lineHits) hits.push({ ...h, index: h.index + offset });
2207
+ offset += line.length + 1;
2208
+ return applyHits(line, lineHits);
2209
+ });
2210
+ return { text: outLines.join("\n"), hits };
2211
+ }
2212
+
2213
+ export {
2214
+ nameParticleAt,
2215
+ DEFAULT_REDACT_RULES,
2216
+ ALL_REDACT_RULES,
2217
+ normalizeForDetect,
2218
+ redactText,
2219
+ mdMarkerRanges,
2220
+ redactMarkdown
2221
+ };
2222
+ //# sourceMappingURL=chunk-DPWWXUOG.js.map