@mushi-mushi/core 1.29.0 → 1.30.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.
@@ -0,0 +1,475 @@
1
+ 'use strict';
2
+
3
+ // src/reporter-ui.ts
4
+ var REPORTER_CANONICAL_STATUSES = [
5
+ "new",
6
+ "pending",
7
+ "submitted",
8
+ "queued",
9
+ "classified",
10
+ "grouped",
11
+ "fixing",
12
+ "fixed",
13
+ "dismissed",
14
+ "triaged",
15
+ "in_progress",
16
+ "resolved",
17
+ "verified",
18
+ "reopened"
19
+ ];
20
+ var REPORTER_LOCALES = ["en", "ja", "es", "th"];
21
+ var REPORTER_CATEGORIES = ["bug", "slow", "visual", "confusing", "idea"];
22
+ var REPORTER_CLOSED_REASONS = [
23
+ "duplicate",
24
+ "not_reproducible",
25
+ "wont_fix",
26
+ "working_as_intended",
27
+ "spam"
28
+ ];
29
+ var BASE_STATE = {
30
+ new: "received",
31
+ pending: "received",
32
+ submitted: "received",
33
+ queued: "received",
34
+ classified: "reviewing",
35
+ triaged: "reviewing",
36
+ grouped: "reviewing",
37
+ reopened: "reviewing_again",
38
+ fixing: "fixing",
39
+ in_progress: "fixing",
40
+ verified: "verified",
41
+ fixed: "fixed_next",
42
+ resolved: "fixed",
43
+ dismissed: "closed"
44
+ };
45
+ var TONE = {
46
+ received: "neutral",
47
+ reviewing: "info",
48
+ reviewing_again: "info",
49
+ fixing: "progress",
50
+ verified: "success-muted",
51
+ fixed_next: "success",
52
+ fixed_version: "success",
53
+ fixed: "success",
54
+ closed: "muted",
55
+ waiting: "attention"
56
+ };
57
+ var REPORTER_TIMELINE_KINDS = [
58
+ "received",
59
+ "reviewing",
60
+ "duplicate_linked",
61
+ "info_requested",
62
+ "comment",
63
+ "reporter_comment",
64
+ "fix_started",
65
+ "fixed",
66
+ "released",
67
+ "verified",
68
+ "reopened",
69
+ "closed"
70
+ ];
71
+ var EN = {
72
+ status: {
73
+ received: "Received",
74
+ reviewing: "Looking into it",
75
+ reviewing_again: "Looking into it again",
76
+ fixing: "Fix in progress",
77
+ verified: "Confirmed fixed",
78
+ fixed_next: "Fixed \u2014 coming in the next update",
79
+ fixed_version: "Fixed in v{version}",
80
+ fixed: "Fixed",
81
+ closed: "Closed",
82
+ waiting: "Waiting on you"
83
+ },
84
+ detail: {
85
+ received: "We got it.",
86
+ reviewing: "The developer has it on their list.",
87
+ reviewing_again: "Thanks \u2014 we reopened it.",
88
+ fixing: "A fix is being worked on.",
89
+ verified: "You confirmed the fix. Thank you!",
90
+ fixed_next: "It ships in the next release.",
91
+ fixed_version: "Update to v{version}. Does it work for you now?",
92
+ fixed: "Does it work for you now?",
93
+ closed: "Closed.",
94
+ waiting: "The developer asked a question \u2014 reply below."
95
+ },
96
+ idea: {
97
+ received: "Thanks for the idea",
98
+ reviewing: "Under consideration",
99
+ fixing: "Being built",
100
+ shipped: "Shipped",
101
+ shippedVersion: "Shipped in v{version}"
102
+ },
103
+ closedReason: {
104
+ duplicate: "Same as an earlier report \u2014 we'll update you there.",
105
+ not_reproducible: "We couldn't reproduce it. Reply if it happens again.",
106
+ wont_fix: "We decided not to change this.",
107
+ working_as_intended: "This is expected behaviour.",
108
+ none: "Closed."
109
+ },
110
+ others: {
111
+ few: "You and a few others reported this",
112
+ many: "Many people reported this"
113
+ },
114
+ timeline: {
115
+ received: "You reported this",
116
+ reviewing: "The developer is looking into it",
117
+ duplicate_linked: "Same as an existing report \u2014 we'll update you there",
118
+ info_requested: "The developer asked: {text}",
119
+ reporter_comment: "You",
120
+ fix_started: "A fix is in progress",
121
+ fixed: "Fixed \u2014 coming in the next update",
122
+ released: "Shipped in v{version} \u2014 update to get it",
123
+ verified: "You confirmed it's fixed",
124
+ reopened: "Reopened"
125
+ },
126
+ categories: {
127
+ bug: "Bug",
128
+ slow: "Slow",
129
+ visual: "Looks wrong",
130
+ confusing: "Confusing",
131
+ idea: "Idea"
132
+ },
133
+ ui: {
134
+ yes: "Yes",
135
+ notYet: "Not yet",
136
+ empty: "Nothing yet \u2014 your reports will show up here with updates.",
137
+ loadError: "Couldn't load updates",
138
+ retry: "Retry",
139
+ sending: "Sending\u2026",
140
+ sent: "Sent",
141
+ sendFailed: "Failed",
142
+ noReplies: "No developer replies yet.",
143
+ you: "You",
144
+ developer: "Developer",
145
+ addWords: "Add a few words",
146
+ developerReplied: "Developer replied: \u201C{text}\u201D",
147
+ updates: "{n} updates on your reports"
148
+ }
149
+ };
150
+ var JA = {
151
+ status: {
152
+ received: "\u53D7\u3051\u4ED8\u3051\u307E\u3057\u305F",
153
+ reviewing: "\u78BA\u8A8D\u4E2D",
154
+ reviewing_again: "\u518D\u78BA\u8A8D\u4E2D",
155
+ fixing: "\u4FEE\u6B63\u4E2D",
156
+ verified: "\u4FEE\u6B63\u3092\u78BA\u8A8D\u6E08\u307F",
157
+ fixed_next: "\u4FEE\u6B63\u6E08\u307F \u2014 \u6B21\u306E\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3067\u53CD\u6620",
158
+ fixed_version: "v{version} \u3067\u4FEE\u6B63\u6E08\u307F",
159
+ fixed: "\u4FEE\u6B63\u6E08\u307F",
160
+ closed: "\u7D42\u4E86",
161
+ waiting: "\u3042\u306A\u305F\u306E\u8FD4\u4FE1\u5F85\u3061"
162
+ },
163
+ detail: {
164
+ received: "\u5831\u544A\u3092\u53D7\u3051\u53D6\u308A\u307E\u3057\u305F\u3002",
165
+ reviewing: "\u958B\u767A\u8005\u304C\u5BFE\u5FDC\u30EA\u30B9\u30C8\u306B\u5165\u308C\u307E\u3057\u305F\u3002",
166
+ reviewing_again: "\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\u3002\u518D\u5EA6\u78BA\u8A8D\u3057\u3066\u3044\u307E\u3059\u3002",
167
+ fixing: "\u4FEE\u6B63\u306B\u53D6\u308A\u7D44\u3093\u3067\u3044\u307E\u3059\u3002",
168
+ verified: "\u4FEE\u6B63\u3092\u78BA\u8A8D\u3044\u305F\u3060\u304D\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059\uFF01",
169
+ fixed_next: "\u6B21\u306E\u30EA\u30EA\u30FC\u30B9\u3067\u53CD\u6620\u3055\u308C\u307E\u3059\u3002",
170
+ fixed_version: "v{version} \u306B\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3057\u3066\u304F\u3060\u3055\u3044\u3002\u89E3\u6C7A\u3057\u307E\u3057\u305F\u304B\uFF1F",
171
+ fixed: "\u89E3\u6C7A\u3057\u307E\u3057\u305F\u304B\uFF1F",
172
+ closed: "\u7D42\u4E86\u3057\u307E\u3057\u305F\u3002",
173
+ waiting: "\u958B\u767A\u8005\u304B\u3089\u8CEA\u554F\u304C\u3042\u308A\u307E\u3059\u3002\u4E0B\u304B\u3089\u8FD4\u4FE1\u3057\u3066\u304F\u3060\u3055\u3044\u3002"
174
+ },
175
+ idea: {
176
+ received: "\u30A2\u30A4\u30C7\u30A2\u3092\u3042\u308A\u304C\u3068\u3046\u3054\u3056\u3044\u307E\u3059",
177
+ reviewing: "\u691C\u8A0E\u4E2D",
178
+ fixing: "\u958B\u767A\u4E2D",
179
+ shipped: "\u30EA\u30EA\u30FC\u30B9\u6E08\u307F",
180
+ shippedVersion: "v{version} \u3067\u30EA\u30EA\u30FC\u30B9\u6E08\u307F"
181
+ },
182
+ closedReason: {
183
+ duplicate: "\u4EE5\u524D\u306E\u5831\u544A\u3068\u540C\u3058\u5185\u5BB9\u3067\u3059\u3002\u305D\u3061\u3089\u3067\u9032\u6357\u3092\u304A\u77E5\u3089\u305B\u3057\u307E\u3059\u3002",
184
+ not_reproducible: "\u518D\u73FE\u3067\u304D\u307E\u305B\u3093\u3067\u3057\u305F\u3002\u518D\u767A\u3057\u305F\u3089\u8FD4\u4FE1\u3057\u3066\u304F\u3060\u3055\u3044\u3002",
185
+ wont_fix: "\u3053\u306E\u70B9\u306F\u5909\u66F4\u3057\u306A\u3044\u3053\u3068\u306B\u3057\u307E\u3057\u305F\u3002",
186
+ working_as_intended: "\u3053\u308C\u306F\u60F3\u5B9A\u3069\u304A\u308A\u306E\u52D5\u4F5C\u3067\u3059\u3002",
187
+ none: "\u7D42\u4E86\u3057\u307E\u3057\u305F\u3002"
188
+ },
189
+ others: {
190
+ few: "\u3042\u306A\u305F\u3092\u542B\u3081\u6570\u4EBA\u304C\u5831\u544A\u3057\u3066\u3044\u307E\u3059",
191
+ many: "\u591A\u304F\u306E\u4EBA\u304C\u5831\u544A\u3057\u3066\u3044\u307E\u3059"
192
+ },
193
+ timeline: {
194
+ received: "\u3042\u306A\u305F\u304C\u5831\u544A\u3057\u307E\u3057\u305F",
195
+ reviewing: "\u958B\u767A\u8005\u304C\u78BA\u8A8D\u3057\u3066\u3044\u307E\u3059",
196
+ duplicate_linked: "\u65E2\u5B58\u306E\u5831\u544A\u3068\u540C\u3058\u5185\u5BB9\u3067\u3059\u3002\u305D\u3061\u3089\u3067\u9032\u6357\u3092\u304A\u77E5\u3089\u305B\u3057\u307E\u3059",
197
+ info_requested: "\u958B\u767A\u8005\u304B\u3089\u306E\u8CEA\u554F: {text}",
198
+ reporter_comment: "\u3042\u306A\u305F",
199
+ fix_started: "\u4FEE\u6B63\u4E2D\u3067\u3059",
200
+ fixed: "\u4FEE\u6B63\u6E08\u307F \u2014 \u6B21\u306E\u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3067\u53CD\u6620",
201
+ released: "v{version} \u3067\u30EA\u30EA\u30FC\u30B9 \u2014 \u30A2\u30C3\u30D7\u30C7\u30FC\u30C8\u3057\u3066\u304F\u3060\u3055\u3044",
202
+ verified: "\u4FEE\u6B63\u3092\u78BA\u8A8D\u3057\u307E\u3057\u305F",
203
+ reopened: "\u518D\u30AA\u30FC\u30D7\u30F3\u3057\u307E\u3057\u305F"
204
+ },
205
+ categories: {
206
+ bug: "\u30D0\u30B0",
207
+ slow: "\u9045\u3044",
208
+ visual: "\u8868\u793A\u304C\u304A\u304B\u3057\u3044",
209
+ confusing: "\u308F\u304B\u308A\u306B\u304F\u3044",
210
+ idea: "\u30A2\u30A4\u30C7\u30A2"
211
+ },
212
+ ui: {
213
+ yes: "\u306F\u3044",
214
+ notYet: "\u307E\u3060",
215
+ empty: "\u307E\u3060\u3042\u308A\u307E\u305B\u3093\u3002\u5831\u544A\u3059\u308B\u3068\u3053\u3053\u306B\u9032\u6357\u304C\u8868\u793A\u3055\u308C\u307E\u3059\u3002",
216
+ loadError: "\u66F4\u65B0\u3092\u8AAD\u307F\u8FBC\u3081\u307E\u305B\u3093\u3067\u3057\u305F",
217
+ retry: "\u518D\u8A66\u884C",
218
+ sending: "\u9001\u4FE1\u4E2D\u2026",
219
+ sent: "\u9001\u4FE1\u3057\u307E\u3057\u305F",
220
+ sendFailed: "\u9001\u4FE1\u5931\u6557",
221
+ noReplies: "\u958B\u767A\u8005\u304B\u3089\u306E\u8FD4\u4FE1\u306F\u307E\u3060\u3042\u308A\u307E\u305B\u3093\u3002",
222
+ you: "\u3042\u306A\u305F",
223
+ developer: "\u958B\u767A\u8005",
224
+ addWords: "\u3082\u3046\u5C11\u3057\u8A73\u3057\u304F\u66F8\u3044\u3066\u304F\u3060\u3055\u3044",
225
+ developerReplied: "\u958B\u767A\u8005\u304B\u3089\u306E\u8FD4\u4FE1:\u300C{text}\u300D",
226
+ updates: "\u3042\u306A\u305F\u306E\u5831\u544A\u306B {n} \u4EF6\u306E\u66F4\u65B0\u304C\u3042\u308A\u307E\u3059"
227
+ }
228
+ };
229
+ var ES = {
230
+ status: {
231
+ received: "Recibido",
232
+ reviewing: "Lo estamos revisando",
233
+ reviewing_again: "Lo revisamos de nuevo",
234
+ fixing: "Correcci\xF3n en curso",
235
+ verified: "Correcci\xF3n confirmada",
236
+ fixed_next: "Corregido \u2014 llega en la pr\xF3xima actualizaci\xF3n",
237
+ fixed_version: "Corregido en v{version}",
238
+ fixed: "Corregido",
239
+ closed: "Cerrado",
240
+ waiting: "Esperando tu respuesta"
241
+ },
242
+ detail: {
243
+ received: "Lo recibimos.",
244
+ reviewing: "El desarrollador lo tiene en su lista.",
245
+ reviewing_again: "Gracias, lo reabrimos.",
246
+ fixing: "Se est\xE1 trabajando en una correcci\xF3n.",
247
+ verified: "Confirmaste la correcci\xF3n. \xA1Gracias!",
248
+ fixed_next: "Llega en la pr\xF3xima versi\xF3n.",
249
+ fixed_version: "Actualiza a v{version}. \xBFYa funciona?",
250
+ fixed: "\xBFYa funciona?",
251
+ closed: "Cerrado.",
252
+ waiting: "El desarrollador hizo una pregunta: responde abajo."
253
+ },
254
+ idea: {
255
+ received: "Gracias por la idea",
256
+ reviewing: "En consideraci\xF3n",
257
+ fixing: "En desarrollo",
258
+ shipped: "Publicado",
259
+ shippedVersion: "Publicado en v{version}"
260
+ },
261
+ closedReason: {
262
+ duplicate: "Es igual a un reporte anterior; te avisaremos all\xED.",
263
+ not_reproducible: "No pudimos reproducirlo. Responde si vuelve a pasar.",
264
+ wont_fix: "Decidimos no cambiar esto.",
265
+ working_as_intended: "Este es el comportamiento esperado.",
266
+ none: "Cerrado."
267
+ },
268
+ others: {
269
+ few: "T\xFA y algunas personas m\xE1s reportaron esto",
270
+ many: "Muchas personas reportaron esto"
271
+ },
272
+ timeline: {
273
+ received: "Reportaste esto",
274
+ reviewing: "El desarrollador lo est\xE1 revisando",
275
+ duplicate_linked: "Es igual a un reporte existente; te avisaremos all\xED",
276
+ info_requested: "El desarrollador pregunt\xF3: {text}",
277
+ reporter_comment: "T\xFA",
278
+ fix_started: "Hay una correcci\xF3n en curso",
279
+ fixed: "Corregido \u2014 llega en la pr\xF3xima actualizaci\xF3n",
280
+ released: "Publicado en v{version}: actualiza para tenerlo",
281
+ verified: "Confirmaste que est\xE1 corregido",
282
+ reopened: "Reabierto"
283
+ },
284
+ categories: {
285
+ bug: "Error",
286
+ slow: "Lento",
287
+ visual: "Se ve mal",
288
+ confusing: "Confuso",
289
+ idea: "Idea"
290
+ },
291
+ ui: {
292
+ yes: "S\xED",
293
+ notYet: "Todav\xEDa no",
294
+ empty: "Nada todav\xEDa: tus reportes aparecer\xE1n aqu\xED con novedades.",
295
+ loadError: "No se pudieron cargar las novedades",
296
+ retry: "Reintentar",
297
+ sending: "Enviando\u2026",
298
+ sent: "Enviado",
299
+ sendFailed: "Error al enviar",
300
+ noReplies: "El desarrollador a\xFAn no ha respondido.",
301
+ you: "T\xFA",
302
+ developer: "Desarrollador",
303
+ addWords: "Agrega algunas palabras",
304
+ developerReplied: "El desarrollador respondi\xF3: \u201C{text}\u201D",
305
+ updates: "{n} novedades en tus reportes"
306
+ }
307
+ };
308
+ var TH = {
309
+ status: {
310
+ received: "\u0E44\u0E14\u0E49\u0E23\u0E31\u0E1A\u0E41\u0E25\u0E49\u0E27",
311
+ reviewing: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A",
312
+ reviewing_again: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07",
313
+ fixing: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E41\u0E01\u0E49\u0E44\u0E02",
314
+ verified: "\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E27\u0E48\u0E32\u0E41\u0E01\u0E49\u0E41\u0E25\u0E49\u0E27",
315
+ fixed_next: "\u0E41\u0E01\u0E49\u0E41\u0E25\u0E49\u0E27 \u2014 \u0E08\u0E30\u0E21\u0E32\u0E43\u0E19\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E16\u0E31\u0E14\u0E44\u0E1B",
316
+ fixed_version: "\u0E41\u0E01\u0E49\u0E41\u0E25\u0E49\u0E27\u0E43\u0E19 v{version}",
317
+ fixed: "\u0E41\u0E01\u0E49\u0E41\u0E25\u0E49\u0E27",
318
+ closed: "\u0E1B\u0E34\u0E14\u0E41\u0E25\u0E49\u0E27",
319
+ waiting: "\u0E23\u0E2D\u0E04\u0E33\u0E15\u0E2D\u0E1A\u0E08\u0E32\u0E01\u0E04\u0E38\u0E13"
320
+ },
321
+ detail: {
322
+ received: "\u0E40\u0E23\u0E32\u0E44\u0E14\u0E49\u0E23\u0E31\u0E1A\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E41\u0E25\u0E49\u0E27",
323
+ reviewing: "\u0E19\u0E31\u0E01\u0E1E\u0E31\u0E12\u0E19\u0E32\u0E43\u0E2A\u0E48\u0E44\u0E27\u0E49\u0E43\u0E19\u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E41\u0E25\u0E49\u0E27",
324
+ reviewing_again: "\u0E02\u0E2D\u0E1A\u0E04\u0E38\u0E13 \u2014 \u0E40\u0E23\u0E32\u0E40\u0E1B\u0E34\u0E14\u0E40\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E19\u0E35\u0E49\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07\u0E41\u0E25\u0E49\u0E27",
325
+ fixing: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E14\u0E33\u0E40\u0E19\u0E34\u0E19\u0E01\u0E32\u0E23\u0E41\u0E01\u0E49\u0E44\u0E02",
326
+ verified: "\u0E04\u0E38\u0E13\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E01\u0E32\u0E23\u0E41\u0E01\u0E49\u0E44\u0E02\u0E41\u0E25\u0E49\u0E27 \u0E02\u0E2D\u0E1A\u0E04\u0E38\u0E13!",
327
+ fixed_next: "\u0E08\u0E30\u0E21\u0E32\u0E43\u0E19\u0E23\u0E38\u0E48\u0E19\u0E16\u0E31\u0E14\u0E44\u0E1B",
328
+ fixed_version: "\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E40\u0E1B\u0E47\u0E19 v{version} \u0E15\u0E2D\u0E19\u0E19\u0E35\u0E49\u0E43\u0E0A\u0E49\u0E44\u0E14\u0E49\u0E2B\u0E23\u0E37\u0E2D\u0E22\u0E31\u0E07?",
329
+ fixed: "\u0E15\u0E2D\u0E19\u0E19\u0E35\u0E49\u0E43\u0E0A\u0E49\u0E44\u0E14\u0E49\u0E2B\u0E23\u0E37\u0E2D\u0E22\u0E31\u0E07?",
330
+ closed: "\u0E1B\u0E34\u0E14\u0E41\u0E25\u0E49\u0E27",
331
+ waiting: "\u0E19\u0E31\u0E01\u0E1E\u0E31\u0E12\u0E19\u0E32\u0E21\u0E35\u0E04\u0E33\u0E16\u0E32\u0E21 \u2014 \u0E15\u0E2D\u0E1A\u0E14\u0E49\u0E32\u0E19\u0E25\u0E48\u0E32\u0E07"
332
+ },
333
+ idea: {
334
+ received: "\u0E02\u0E2D\u0E1A\u0E04\u0E38\u0E13\u0E2A\u0E33\u0E2B\u0E23\u0E31\u0E1A\u0E44\u0E2D\u0E40\u0E14\u0E35\u0E22",
335
+ reviewing: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E1E\u0E34\u0E08\u0E32\u0E23\u0E13\u0E32",
336
+ fixing: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2A\u0E23\u0E49\u0E32\u0E07",
337
+ shipped: "\u0E40\u0E1B\u0E34\u0E14\u0E43\u0E0A\u0E49\u0E41\u0E25\u0E49\u0E27",
338
+ shippedVersion: "\u0E40\u0E1B\u0E34\u0E14\u0E43\u0E0A\u0E49\u0E41\u0E25\u0E49\u0E27\u0E43\u0E19 v{version}"
339
+ },
340
+ closedReason: {
341
+ duplicate: "\u0E40\u0E2B\u0E21\u0E37\u0E2D\u0E19\u0E01\u0E31\u0E1A\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E01\u0E48\u0E2D\u0E19\u0E2B\u0E19\u0E49\u0E32 \u2014 \u0E40\u0E23\u0E32\u0E08\u0E30\u0E41\u0E08\u0E49\u0E07\u0E04\u0E27\u0E32\u0E21\u0E04\u0E37\u0E1A\u0E2B\u0E19\u0E49\u0E32\u0E17\u0E35\u0E48\u0E19\u0E31\u0E48\u0E19",
342
+ not_reproducible: "\u0E40\u0E23\u0E32\u0E17\u0E33\u0E43\u0E2B\u0E49\u0E40\u0E01\u0E34\u0E14\u0E0B\u0E49\u0E33\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49 \u0E15\u0E2D\u0E1A\u0E01\u0E25\u0E31\u0E1A\u0E2B\u0E32\u0E01\u0E40\u0E01\u0E34\u0E14\u0E02\u0E36\u0E49\u0E19\u0E2D\u0E35\u0E01",
343
+ wont_fix: "\u0E40\u0E23\u0E32\u0E15\u0E31\u0E14\u0E2A\u0E34\u0E19\u0E43\u0E08\u0E44\u0E21\u0E48\u0E40\u0E1B\u0E25\u0E35\u0E48\u0E22\u0E19\u0E2A\u0E48\u0E27\u0E19\u0E19\u0E35\u0E49",
344
+ working_as_intended: "\u0E19\u0E35\u0E48\u0E40\u0E1B\u0E47\u0E19\u0E01\u0E32\u0E23\u0E17\u0E33\u0E07\u0E32\u0E19\u0E15\u0E32\u0E21\u0E17\u0E35\u0E48\u0E15\u0E31\u0E49\u0E07\u0E43\u0E08\u0E44\u0E27\u0E49",
345
+ none: "\u0E1B\u0E34\u0E14\u0E41\u0E25\u0E49\u0E27"
346
+ },
347
+ others: {
348
+ few: "\u0E04\u0E38\u0E13\u0E41\u0E25\u0E30\u0E2D\u0E35\u0E01\u0E44\u0E21\u0E48\u0E01\u0E35\u0E48\u0E04\u0E19\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E40\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E19\u0E35\u0E49",
349
+ many: "\u0E21\u0E35\u0E2B\u0E25\u0E32\u0E22\u0E04\u0E19\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E40\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E19\u0E35\u0E49"
350
+ },
351
+ timeline: {
352
+ received: "\u0E04\u0E38\u0E13\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E40\u0E23\u0E37\u0E48\u0E2D\u0E07\u0E19\u0E35\u0E49",
353
+ reviewing: "\u0E19\u0E31\u0E01\u0E1E\u0E31\u0E12\u0E19\u0E32\u0E01\u0E33\u0E25\u0E31\u0E07\u0E15\u0E23\u0E27\u0E08\u0E2A\u0E2D\u0E1A",
354
+ duplicate_linked: "\u0E40\u0E2B\u0E21\u0E37\u0E2D\u0E19\u0E01\u0E31\u0E1A\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E17\u0E35\u0E48\u0E21\u0E35\u0E2D\u0E22\u0E39\u0E48 \u2014 \u0E40\u0E23\u0E32\u0E08\u0E30\u0E41\u0E08\u0E49\u0E07\u0E04\u0E27\u0E32\u0E21\u0E04\u0E37\u0E1A\u0E2B\u0E19\u0E49\u0E32\u0E17\u0E35\u0E48\u0E19\u0E31\u0E48\u0E19",
355
+ info_requested: "\u0E19\u0E31\u0E01\u0E1E\u0E31\u0E12\u0E19\u0E32\u0E16\u0E32\u0E21\u0E27\u0E48\u0E32: {text}",
356
+ reporter_comment: "\u0E04\u0E38\u0E13",
357
+ fix_started: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E41\u0E01\u0E49\u0E44\u0E02",
358
+ fixed: "\u0E41\u0E01\u0E49\u0E41\u0E25\u0E49\u0E27 \u2014 \u0E08\u0E30\u0E21\u0E32\u0E43\u0E19\u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E16\u0E31\u0E14\u0E44\u0E1B",
359
+ released: "\u0E40\u0E1B\u0E34\u0E14\u0E43\u0E0A\u0E49\u0E43\u0E19 v{version} \u2014 \u0E2D\u0E31\u0E1B\u0E40\u0E14\u0E15\u0E40\u0E1E\u0E37\u0E48\u0E2D\u0E23\u0E31\u0E1A\u0E01\u0E32\u0E23\u0E41\u0E01\u0E49\u0E44\u0E02",
360
+ verified: "\u0E04\u0E38\u0E13\u0E22\u0E37\u0E19\u0E22\u0E31\u0E19\u0E27\u0E48\u0E32\u0E41\u0E01\u0E49\u0E41\u0E25\u0E49\u0E27",
361
+ reopened: "\u0E40\u0E1B\u0E34\u0E14\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07"
362
+ },
363
+ categories: {
364
+ bug: "\u0E1A\u0E31\u0E4A\u0E01",
365
+ slow: "\u0E0A\u0E49\u0E32",
366
+ visual: "\u0E41\u0E2A\u0E14\u0E07\u0E1C\u0E25\u0E1C\u0E34\u0E14",
367
+ confusing: "\u0E2A\u0E31\u0E1A\u0E2A\u0E19",
368
+ idea: "\u0E44\u0E2D\u0E40\u0E14\u0E35\u0E22"
369
+ },
370
+ ui: {
371
+ yes: "\u0E43\u0E0A\u0E48",
372
+ notYet: "\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48",
373
+ empty: "\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35 \u2014 \u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13\u0E08\u0E30\u0E41\u0E2A\u0E14\u0E07\u0E17\u0E35\u0E48\u0E19\u0E35\u0E48\u0E1E\u0E23\u0E49\u0E2D\u0E21\u0E04\u0E27\u0E32\u0E21\u0E04\u0E37\u0E1A\u0E2B\u0E19\u0E49\u0E32",
374
+ loadError: "\u0E42\u0E2B\u0E25\u0E14\u0E04\u0E27\u0E32\u0E21\u0E04\u0E37\u0E1A\u0E2B\u0E19\u0E49\u0E32\u0E44\u0E21\u0E48\u0E44\u0E14\u0E49",
375
+ retry: "\u0E25\u0E2D\u0E07\u0E2D\u0E35\u0E01\u0E04\u0E23\u0E31\u0E49\u0E07",
376
+ sending: "\u0E01\u0E33\u0E25\u0E31\u0E07\u0E2A\u0E48\u0E07\u2026",
377
+ sent: "\u0E2A\u0E48\u0E07\u0E41\u0E25\u0E49\u0E27",
378
+ sendFailed: "\u0E2A\u0E48\u0E07\u0E44\u0E21\u0E48\u0E2A\u0E33\u0E40\u0E23\u0E47\u0E08",
379
+ noReplies: "\u0E22\u0E31\u0E07\u0E44\u0E21\u0E48\u0E21\u0E35\u0E04\u0E33\u0E15\u0E2D\u0E1A\u0E08\u0E32\u0E01\u0E19\u0E31\u0E01\u0E1E\u0E31\u0E12\u0E19\u0E32",
380
+ you: "\u0E04\u0E38\u0E13",
381
+ developer: "\u0E19\u0E31\u0E01\u0E1E\u0E31\u0E12\u0E19\u0E32",
382
+ addWords: "\u0E40\u0E1E\u0E34\u0E48\u0E21\u0E23\u0E32\u0E22\u0E25\u0E30\u0E40\u0E2D\u0E35\u0E22\u0E14\u0E2D\u0E35\u0E01\u0E40\u0E25\u0E47\u0E01\u0E19\u0E49\u0E2D\u0E22",
383
+ developerReplied: "\u0E19\u0E31\u0E01\u0E1E\u0E31\u0E12\u0E19\u0E32\u0E15\u0E2D\u0E1A\u0E27\u0E48\u0E32: \u201C{text}\u201D",
384
+ updates: "\u0E21\u0E35\u0E04\u0E27\u0E32\u0E21\u0E04\u0E37\u0E1A\u0E2B\u0E19\u0E49\u0E32 {n} \u0E23\u0E32\u0E22\u0E01\u0E32\u0E23\u0E43\u0E19\u0E23\u0E32\u0E22\u0E07\u0E32\u0E19\u0E02\u0E2D\u0E07\u0E04\u0E38\u0E13"
385
+ }
386
+ };
387
+ var COPY = { en: EN, ja: JA, es: ES, th: TH };
388
+ function resolveReporterLocale(tag) {
389
+ const base = (tag ?? "").toLowerCase().split(/[-_]/)[0];
390
+ return REPORTER_LOCALES.includes(base) ? base : "en";
391
+ }
392
+ function reporterCopy(locale = "en") {
393
+ return COPY[resolveReporterLocale(locale)];
394
+ }
395
+ function fillReporterTemplate(template, params = {}) {
396
+ return template.replace(/\{(\w+)\}/g, (_, key) => {
397
+ const value = params[key];
398
+ return value === null || value === void 0 ? "" : String(value);
399
+ });
400
+ }
401
+ var OPEN_KEYS = /* @__PURE__ */ new Set([
402
+ "received",
403
+ "reviewing",
404
+ "reviewing_again",
405
+ "fixing"
406
+ ]);
407
+ function isCanonical(status) {
408
+ return REPORTER_CANONICAL_STATUSES.includes(status);
409
+ }
410
+ function isReporterIdea(input) {
411
+ const cat = (input.user_category ?? "").trim().toLowerCase().replace(/[\s-]+/g, "_");
412
+ return cat === "feature_request" || cat === "idea";
413
+ }
414
+ function reporterStatus(input, locale = "en") {
415
+ const copy = reporterCopy(locale);
416
+ const status = (input.status ?? "").trim();
417
+ let key = isCanonical(status) ? BASE_STATE[status] : "received";
418
+ const version = input.fixed_in_version?.trim() || null;
419
+ if ((status === "fixed" || status === "resolved") && version) key = "fixed_version";
420
+ const awaiting = Boolean(input.awaiting_reporter) || Boolean(input.awaiting_reporter_at);
421
+ if (awaiting && OPEN_KEYS.has(key)) key = "waiting";
422
+ const idea = isReporterIdea(input);
423
+ let label = copy.status[key];
424
+ let detail = copy.detail[key];
425
+ if (idea) {
426
+ if (key === "received") label = copy.idea.received;
427
+ else if (key === "reviewing" || key === "reviewing_again") label = copy.idea.reviewing;
428
+ else if (key === "fixing") label = copy.idea.fixing;
429
+ else if (key === "fixed_version") label = copy.idea.shippedVersion;
430
+ else if (key === "fixed_next" || key === "fixed") label = copy.idea.shipped;
431
+ }
432
+ const reason = input.closed_reason ?? null;
433
+ if (key === "closed") {
434
+ detail = reason && reason !== "spam" && reason in copy.closedReason ? copy.closedReason[reason] : copy.closedReason.none;
435
+ }
436
+ const bucket = input.group_bucket ?? "none";
437
+ const othersNote = OPEN_KEYS.has(key) || key === "waiting" ? bucket === "few" ? copy.others.few : bucket === "many" ? copy.others.many : null : null;
438
+ return {
439
+ key,
440
+ label: fillReporterTemplate(label, { version }),
441
+ tone: TONE[key],
442
+ detail: fillReporterTemplate(detail, { version }),
443
+ canVerify: key === "fixed_next" || key === "fixed_version" || key === "fixed",
444
+ othersNote,
445
+ hidden: key === "closed" && reason === "spam"
446
+ };
447
+ }
448
+ function reporterTimelineText(kind, params = {}, locale = "en") {
449
+ const copy = reporterCopy(locale);
450
+ if (kind === "comment") return params.text ?? "";
451
+ if (kind === "closed") {
452
+ const reason = params.closed_reason ?? "";
453
+ return reason && reason !== "spam" && reason in copy.closedReason ? copy.closedReason[reason] : copy.closedReason.none;
454
+ }
455
+ if (kind === "reporter_comment") return params.text ?? copy.timeline.reporter_comment;
456
+ return fillReporterTemplate(copy.timeline[kind], { text: params.text, version: params.version });
457
+ }
458
+ function reporterCategoryLabel(category, locale = "en") {
459
+ return reporterCopy(locale).categories[category];
460
+ }
461
+
462
+ exports.REPORTER_CANONICAL_STATUSES = REPORTER_CANONICAL_STATUSES;
463
+ exports.REPORTER_CATEGORIES = REPORTER_CATEGORIES;
464
+ exports.REPORTER_CLOSED_REASONS = REPORTER_CLOSED_REASONS;
465
+ exports.REPORTER_LOCALES = REPORTER_LOCALES;
466
+ exports.REPORTER_TIMELINE_KINDS = REPORTER_TIMELINE_KINDS;
467
+ exports.fillReporterTemplate = fillReporterTemplate;
468
+ exports.isReporterIdea = isReporterIdea;
469
+ exports.reporterCategoryLabel = reporterCategoryLabel;
470
+ exports.reporterCopy = reporterCopy;
471
+ exports.reporterStatus = reporterStatus;
472
+ exports.reporterTimelineText = reporterTimelineText;
473
+ exports.resolveReporterLocale = resolveReporterLocale;
474
+ //# sourceMappingURL=reporter-ui.cjs.map
475
+ //# sourceMappingURL=reporter-ui.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/reporter-ui.ts"],"names":[],"mappings":"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","file":"reporter-ui.cjs","sourcesContent":["// SPDX-License-Identifier: MIT\n// Copyright (c) 2024–2026 Kenji Sakuramoto (kensaurus) — Mushi Mushi\n/**\n * FILE: reporter-ui.ts\n * PURPOSE: The one reporter-facing vocabulary shared by every SDK widget\n * (web, React Native, Capacitor): report categories, the end-user\n * status table, the timeline kinds and their copy in en/ja/es/th.\n *\n * OVERVIEW:\n * - `reporterStatus(report, locale)` maps all 14 internal `reports.status`\n * values (plus the `awaiting_reporter` and duplicate-group overlays and the\n * feature-request variants) onto eight end-user states. There is no branch\n * that echoes the raw status: an unknown value reads as \"Received\".\n * - `reporterTimelineText(kind, params, locale)` renders pipeline events from\n * a fixed template per kind. Stored notification payload text is never\n * shown, so internal category / severity can not leak to a reporter.\n *\n * USAGE:\n * - `import { reporterStatus } from '@mushi-mushi/core/reporter-ui'`\n * - Shipped as a subpath so the main `@mushi-mushi/core` entry stays within\n * its size budget; nothing here is re-exported from `index.ts`.\n *\n * Plan 018 (docs/execplans/reporter-loop-v2.md) §2.1 and §2.3.\n */\n\n/** Every value `reports_status_check` allows. Pinned to the server list by a test. */\nexport const REPORTER_CANONICAL_STATUSES = [\n 'new',\n 'pending',\n 'submitted',\n 'queued',\n 'classified',\n 'grouped',\n 'fixing',\n 'fixed',\n 'dismissed',\n 'triaged',\n 'in_progress',\n 'resolved',\n 'verified',\n 'reopened',\n] as const;\n\nexport type ReporterCanonicalStatus = (typeof REPORTER_CANONICAL_STATUSES)[number];\n\nexport const REPORTER_LOCALES = ['en', 'ja', 'es', 'th'] as const;\nexport type ReporterLocale = (typeof REPORTER_LOCALES)[number];\n\n/** Optional type chips on the one-screen report form, in display order. */\nexport const REPORTER_CATEGORIES = ['bug', 'slow', 'visual', 'confusing', 'idea'] as const;\nexport type ReporterCategory = (typeof REPORTER_CATEGORIES)[number];\n\n/** `closed_reason` values the `reports_closed_reason_check` constraint allows. */\nexport const REPORTER_CLOSED_REASONS = [\n 'duplicate',\n 'not_reproducible',\n 'wont_fix',\n 'working_as_intended',\n 'spam',\n] as const;\nexport type ReporterClosedReason = (typeof REPORTER_CLOSED_REASONS)[number];\n\nexport type ReporterTone =\n | 'neutral'\n | 'info'\n | 'attention'\n | 'progress'\n | 'success'\n | 'success-muted'\n | 'muted';\n\n/** The end-user state a report is shown in. */\nexport type ReporterStatusKey =\n | 'received'\n | 'reviewing'\n | 'reviewing_again'\n | 'fixing'\n | 'verified'\n | 'fixed_next'\n | 'fixed_version'\n | 'fixed'\n | 'closed'\n | 'waiting';\n\n/** Base state per internal status, before overlays. Exhaustive by type. */\nconst BASE_STATE: Record<ReporterCanonicalStatus, ReporterStatusKey> = {\n new: 'received',\n pending: 'received',\n submitted: 'received',\n queued: 'received',\n classified: 'reviewing',\n triaged: 'reviewing',\n grouped: 'reviewing',\n reopened: 'reviewing_again',\n fixing: 'fixing',\n in_progress: 'fixing',\n verified: 'verified',\n fixed: 'fixed_next',\n resolved: 'fixed',\n dismissed: 'closed',\n};\n\nconst TONE: Record<ReporterStatusKey, ReporterTone> = {\n received: 'neutral',\n reviewing: 'info',\n reviewing_again: 'info',\n fixing: 'progress',\n verified: 'success-muted',\n fixed_next: 'success',\n fixed_version: 'success',\n fixed: 'success',\n closed: 'muted',\n waiting: 'attention',\n};\n\n/** Timeline entry kinds the reporter detail view renders (§2.3). */\nexport const REPORTER_TIMELINE_KINDS = [\n 'received',\n 'reviewing',\n 'duplicate_linked',\n 'info_requested',\n 'comment',\n 'reporter_comment',\n 'fix_started',\n 'fixed',\n 'released',\n 'verified',\n 'reopened',\n 'closed',\n] as const;\nexport type ReporterTimelineKind = (typeof REPORTER_TIMELINE_KINDS)[number];\n\nexport interface ReporterCopy {\n status: Record<ReporterStatusKey, string>;\n detail: Record<ReporterStatusKey, string>;\n idea: { received: string; reviewing: string; fixing: string; shipped: string; shippedVersion: string };\n closedReason: Record<Exclude<ReporterClosedReason, 'spam'>, string> & { none: string };\n others: { few: string; many: string };\n timeline: Record<Exclude<ReporterTimelineKind, 'comment' | 'closed'>, string>;\n categories: Record<ReporterCategory, string>;\n ui: {\n yes: string;\n notYet: string;\n empty: string;\n loadError: string;\n retry: string;\n sending: string;\n sent: string;\n sendFailed: string;\n noReplies: string;\n you: string;\n developer: string;\n addWords: string;\n developerReplied: string;\n updates: string;\n };\n}\n\nconst EN: ReporterCopy = {\n status: {\n received: 'Received',\n reviewing: 'Looking into it',\n reviewing_again: 'Looking into it again',\n fixing: 'Fix in progress',\n verified: 'Confirmed fixed',\n fixed_next: 'Fixed — coming in the next update',\n fixed_version: 'Fixed in v{version}',\n fixed: 'Fixed',\n closed: 'Closed',\n waiting: 'Waiting on you',\n },\n detail: {\n received: 'We got it.',\n reviewing: 'The developer has it on their list.',\n reviewing_again: 'Thanks — we reopened it.',\n fixing: 'A fix is being worked on.',\n verified: 'You confirmed the fix. Thank you!',\n fixed_next: 'It ships in the next release.',\n fixed_version: 'Update to v{version}. Does it work for you now?',\n fixed: 'Does it work for you now?',\n closed: 'Closed.',\n waiting: 'The developer asked a question — reply below.',\n },\n idea: {\n received: 'Thanks for the idea',\n reviewing: 'Under consideration',\n fixing: 'Being built',\n shipped: 'Shipped',\n shippedVersion: 'Shipped in v{version}',\n },\n closedReason: {\n duplicate: \"Same as an earlier report — we'll update you there.\",\n not_reproducible: \"We couldn't reproduce it. Reply if it happens again.\",\n wont_fix: 'We decided not to change this.',\n working_as_intended: 'This is expected behaviour.',\n none: 'Closed.',\n },\n others: {\n few: 'You and a few others reported this',\n many: 'Many people reported this',\n },\n timeline: {\n received: 'You reported this',\n reviewing: 'The developer is looking into it',\n duplicate_linked: \"Same as an existing report — we'll update you there\",\n info_requested: 'The developer asked: {text}',\n reporter_comment: 'You',\n fix_started: 'A fix is in progress',\n fixed: 'Fixed — coming in the next update',\n released: 'Shipped in v{version} — update to get it',\n verified: \"You confirmed it's fixed\",\n reopened: 'Reopened',\n },\n categories: {\n bug: 'Bug',\n slow: 'Slow',\n visual: 'Looks wrong',\n confusing: 'Confusing',\n idea: 'Idea',\n },\n ui: {\n yes: 'Yes',\n notYet: 'Not yet',\n empty: 'Nothing yet — your reports will show up here with updates.',\n loadError: \"Couldn't load updates\",\n retry: 'Retry',\n sending: 'Sending…',\n sent: 'Sent',\n sendFailed: 'Failed',\n noReplies: 'No developer replies yet.',\n you: 'You',\n developer: 'Developer',\n addWords: 'Add a few words',\n developerReplied: 'Developer replied: “{text}”',\n updates: '{n} updates on your reports',\n },\n};\n\nconst JA: ReporterCopy = {\n status: {\n received: '受け付けました',\n reviewing: '確認中',\n reviewing_again: '再確認中',\n fixing: '修正中',\n verified: '修正を確認済み',\n fixed_next: '修正済み — 次のアップデートで反映',\n fixed_version: 'v{version} で修正済み',\n fixed: '修正済み',\n closed: '終了',\n waiting: 'あなたの返信待ち',\n },\n detail: {\n received: '報告を受け取りました。',\n reviewing: '開発者が対応リストに入れました。',\n reviewing_again: 'ありがとうございます。再度確認しています。',\n fixing: '修正に取り組んでいます。',\n verified: '修正を確認いただきありがとうございます!',\n fixed_next: '次のリリースで反映されます。',\n fixed_version: 'v{version} にアップデートしてください。解決しましたか?',\n fixed: '解決しましたか?',\n closed: '終了しました。',\n waiting: '開発者から質問があります。下から返信してください。',\n },\n idea: {\n received: 'アイデアをありがとうございます',\n reviewing: '検討中',\n fixing: '開発中',\n shipped: 'リリース済み',\n shippedVersion: 'v{version} でリリース済み',\n },\n closedReason: {\n duplicate: '以前の報告と同じ内容です。そちらで進捗をお知らせします。',\n not_reproducible: '再現できませんでした。再発したら返信してください。',\n wont_fix: 'この点は変更しないことにしました。',\n working_as_intended: 'これは想定どおりの動作です。',\n none: '終了しました。',\n },\n others: {\n few: 'あなたを含め数人が報告しています',\n many: '多くの人が報告しています',\n },\n timeline: {\n received: 'あなたが報告しました',\n reviewing: '開発者が確認しています',\n duplicate_linked: '既存の報告と同じ内容です。そちらで進捗をお知らせします',\n info_requested: '開発者からの質問: {text}',\n reporter_comment: 'あなた',\n fix_started: '修正中です',\n fixed: '修正済み — 次のアップデートで反映',\n released: 'v{version} でリリース — アップデートしてください',\n verified: '修正を確認しました',\n reopened: '再オープンしました',\n },\n categories: {\n bug: 'バグ',\n slow: '遅い',\n visual: '表示がおかしい',\n confusing: 'わかりにくい',\n idea: 'アイデア',\n },\n ui: {\n yes: 'はい',\n notYet: 'まだ',\n empty: 'まだありません。報告するとここに進捗が表示されます。',\n loadError: '更新を読み込めませんでした',\n retry: '再試行',\n sending: '送信中…',\n sent: '送信しました',\n sendFailed: '送信失敗',\n noReplies: '開発者からの返信はまだありません。',\n you: 'あなた',\n developer: '開発者',\n addWords: 'もう少し詳しく書いてください',\n developerReplied: '開発者からの返信:「{text}」',\n updates: 'あなたの報告に {n} 件の更新があります',\n },\n};\n\nconst ES: ReporterCopy = {\n status: {\n received: 'Recibido',\n reviewing: 'Lo estamos revisando',\n reviewing_again: 'Lo revisamos de nuevo',\n fixing: 'Corrección en curso',\n verified: 'Corrección confirmada',\n fixed_next: 'Corregido — llega en la próxima actualización',\n fixed_version: 'Corregido en v{version}',\n fixed: 'Corregido',\n closed: 'Cerrado',\n waiting: 'Esperando tu respuesta',\n },\n detail: {\n received: 'Lo recibimos.',\n reviewing: 'El desarrollador lo tiene en su lista.',\n reviewing_again: 'Gracias, lo reabrimos.',\n fixing: 'Se está trabajando en una corrección.',\n verified: 'Confirmaste la corrección. ¡Gracias!',\n fixed_next: 'Llega en la próxima versión.',\n fixed_version: 'Actualiza a v{version}. ¿Ya funciona?',\n fixed: '¿Ya funciona?',\n closed: 'Cerrado.',\n waiting: 'El desarrollador hizo una pregunta: responde abajo.',\n },\n idea: {\n received: 'Gracias por la idea',\n reviewing: 'En consideración',\n fixing: 'En desarrollo',\n shipped: 'Publicado',\n shippedVersion: 'Publicado en v{version}',\n },\n closedReason: {\n duplicate: 'Es igual a un reporte anterior; te avisaremos allí.',\n not_reproducible: 'No pudimos reproducirlo. Responde si vuelve a pasar.',\n wont_fix: 'Decidimos no cambiar esto.',\n working_as_intended: 'Este es el comportamiento esperado.',\n none: 'Cerrado.',\n },\n others: {\n few: 'Tú y algunas personas más reportaron esto',\n many: 'Muchas personas reportaron esto',\n },\n timeline: {\n received: 'Reportaste esto',\n reviewing: 'El desarrollador lo está revisando',\n duplicate_linked: 'Es igual a un reporte existente; te avisaremos allí',\n info_requested: 'El desarrollador preguntó: {text}',\n reporter_comment: 'Tú',\n fix_started: 'Hay una corrección en curso',\n fixed: 'Corregido — llega en la próxima actualización',\n released: 'Publicado en v{version}: actualiza para tenerlo',\n verified: 'Confirmaste que está corregido',\n reopened: 'Reabierto',\n },\n categories: {\n bug: 'Error',\n slow: 'Lento',\n visual: 'Se ve mal',\n confusing: 'Confuso',\n idea: 'Idea',\n },\n ui: {\n yes: 'Sí',\n notYet: 'Todavía no',\n empty: 'Nada todavía: tus reportes aparecerán aquí con novedades.',\n loadError: 'No se pudieron cargar las novedades',\n retry: 'Reintentar',\n sending: 'Enviando…',\n sent: 'Enviado',\n sendFailed: 'Error al enviar',\n noReplies: 'El desarrollador aún no ha respondido.',\n you: 'Tú',\n developer: 'Desarrollador',\n addWords: 'Agrega algunas palabras',\n developerReplied: 'El desarrollador respondió: “{text}”',\n updates: '{n} novedades en tus reportes',\n },\n};\n\nconst TH: ReporterCopy = {\n status: {\n received: 'ได้รับแล้ว',\n reviewing: 'กำลังตรวจสอบ',\n reviewing_again: 'กำลังตรวจสอบอีกครั้ง',\n fixing: 'กำลังแก้ไข',\n verified: 'ยืนยันว่าแก้แล้ว',\n fixed_next: 'แก้แล้ว — จะมาในอัปเดตถัดไป',\n fixed_version: 'แก้แล้วใน v{version}',\n fixed: 'แก้แล้ว',\n closed: 'ปิดแล้ว',\n waiting: 'รอคำตอบจากคุณ',\n },\n detail: {\n received: 'เราได้รับรายงานแล้ว',\n reviewing: 'นักพัฒนาใส่ไว้ในรายการแล้ว',\n reviewing_again: 'ขอบคุณ — เราเปิดเรื่องนี้อีกครั้งแล้ว',\n fixing: 'กำลังดำเนินการแก้ไข',\n verified: 'คุณยืนยันการแก้ไขแล้ว ขอบคุณ!',\n fixed_next: 'จะมาในรุ่นถัดไป',\n fixed_version: 'อัปเดตเป็น v{version} ตอนนี้ใช้ได้หรือยัง?',\n fixed: 'ตอนนี้ใช้ได้หรือยัง?',\n closed: 'ปิดแล้ว',\n waiting: 'นักพัฒนามีคำถาม — ตอบด้านล่าง',\n },\n idea: {\n received: 'ขอบคุณสำหรับไอเดีย',\n reviewing: 'กำลังพิจารณา',\n fixing: 'กำลังสร้าง',\n shipped: 'เปิดใช้แล้ว',\n shippedVersion: 'เปิดใช้แล้วใน v{version}',\n },\n closedReason: {\n duplicate: 'เหมือนกับรายงานก่อนหน้า — เราจะแจ้งความคืบหน้าที่นั่น',\n not_reproducible: 'เราทำให้เกิดซ้ำไม่ได้ ตอบกลับหากเกิดขึ้นอีก',\n wont_fix: 'เราตัดสินใจไม่เปลี่ยนส่วนนี้',\n working_as_intended: 'นี่เป็นการทำงานตามที่ตั้งใจไว้',\n none: 'ปิดแล้ว',\n },\n others: {\n few: 'คุณและอีกไม่กี่คนรายงานเรื่องนี้',\n many: 'มีหลายคนรายงานเรื่องนี้',\n },\n timeline: {\n received: 'คุณรายงานเรื่องนี้',\n reviewing: 'นักพัฒนากำลังตรวจสอบ',\n duplicate_linked: 'เหมือนกับรายงานที่มีอยู่ — เราจะแจ้งความคืบหน้าที่นั่น',\n info_requested: 'นักพัฒนาถามว่า: {text}',\n reporter_comment: 'คุณ',\n fix_started: 'กำลังแก้ไข',\n fixed: 'แก้แล้ว — จะมาในอัปเดตถัดไป',\n released: 'เปิดใช้ใน v{version} — อัปเดตเพื่อรับการแก้ไข',\n verified: 'คุณยืนยันว่าแก้แล้ว',\n reopened: 'เปิดอีกครั้ง',\n },\n categories: {\n bug: 'บั๊ก',\n slow: 'ช้า',\n visual: 'แสดงผลผิด',\n confusing: 'สับสน',\n idea: 'ไอเดีย',\n },\n ui: {\n yes: 'ใช่',\n notYet: 'ยังไม่',\n empty: 'ยังไม่มี — รายงานของคุณจะแสดงที่นี่พร้อมความคืบหน้า',\n loadError: 'โหลดความคืบหน้าไม่ได้',\n retry: 'ลองอีกครั้ง',\n sending: 'กำลังส่ง…',\n sent: 'ส่งแล้ว',\n sendFailed: 'ส่งไม่สำเร็จ',\n noReplies: 'ยังไม่มีคำตอบจากนักพัฒนา',\n you: 'คุณ',\n developer: 'นักพัฒนา',\n addWords: 'เพิ่มรายละเอียดอีกเล็กน้อย',\n developerReplied: 'นักพัฒนาตอบว่า: “{text}”',\n updates: 'มีความคืบหน้า {n} รายการในรายงานของคุณ',\n },\n};\n\nconst COPY: Record<ReporterLocale, ReporterCopy> = { en: EN, ja: JA, es: ES, th: TH };\n\n/** Resolve a BCP-47 tag (`ja-JP`, `es-419`) to a supported locale; English otherwise. */\nexport function resolveReporterLocale(tag: string | null | undefined): ReporterLocale {\n const base = (tag ?? '').toLowerCase().split(/[-_]/)[0];\n return (REPORTER_LOCALES as readonly string[]).includes(base) ? (base as ReporterLocale) : 'en';\n}\n\n/** The full copy table for a locale (unknown tags fall back to English). */\nexport function reporterCopy(locale: string = 'en'): ReporterCopy {\n return COPY[resolveReporterLocale(locale)];\n}\n\n/** Replace `{name}` placeholders; a missing value leaves an empty string. */\nexport function fillReporterTemplate(\n template: string,\n params: Record<string, string | number | null | undefined> = {},\n): string {\n return template.replace(/\\{(\\w+)\\}/g, (_, key: string) => {\n const value = params[key];\n return value === null || value === undefined ? '' : String(value);\n });\n}\n\n/** Fields of a reporter-list row `reporterStatus` reads. All but `status` are optional. */\nexport interface ReporterStatusInput {\n status: string;\n /** True (or a timestamp) while the developer waits for the reporter. */\n awaiting_reporter?: boolean | null;\n awaiting_reporter_at?: string | null;\n fixed_in_version?: string | null;\n closed_reason?: string | null;\n /** Bucketed duplicate count; never a raw number. */\n group_bucket?: 'none' | 'few' | 'many' | null;\n /** `user_category`; \"Feature request\" / \"idea\" selects the idea labels. */\n user_category?: string | null;\n}\n\nexport interface ReporterStatusView {\n key: ReporterStatusKey;\n label: string;\n tone: ReporterTone;\n detail: string;\n /** Show the Yes / Not yet verification buttons. */\n canVerify: boolean;\n /** \"You and a few others reported this\", or null. */\n othersNote: string | null;\n /** `closed_reason = 'spam'`: hide the report from the reporter entirely. */\n hidden: boolean;\n}\n\nconst OPEN_KEYS: ReadonlySet<ReporterStatusKey> = new Set([\n 'received',\n 'reviewing',\n 'reviewing_again',\n 'fixing',\n]);\n\nfunction isCanonical(status: string): status is ReporterCanonicalStatus {\n return (REPORTER_CANONICAL_STATUSES as readonly string[]).includes(status);\n}\n\n/** True when the row is a feature request rather than a bug. */\nexport function isReporterIdea(input: Pick<ReporterStatusInput, 'user_category'>): boolean {\n const cat = (input.user_category ?? '').trim().toLowerCase().replace(/[\\s-]+/g, '_');\n return cat === 'feature_request' || cat === 'idea';\n}\n\n/**\n * The end-user view of a report. Overlays are checked before the base\n * status: \"Waiting on you\" wins for any open report, and the duplicate-group\n * note is added on top of whatever the base state is.\n */\nexport function reporterStatus(input: ReporterStatusInput, locale: string = 'en'): ReporterStatusView {\n const copy = reporterCopy(locale);\n const status = (input.status ?? '').trim();\n // No raw passthrough: anything the table does not know reads as Received.\n let key: ReporterStatusKey = isCanonical(status) ? BASE_STATE[status] : 'received';\n\n const version = input.fixed_in_version?.trim() || null;\n if ((status === 'fixed' || status === 'resolved') && version) key = 'fixed_version';\n\n const awaiting = Boolean(input.awaiting_reporter) || Boolean(input.awaiting_reporter_at);\n if (awaiting && OPEN_KEYS.has(key)) key = 'waiting';\n\n const idea = isReporterIdea(input);\n let label = copy.status[key];\n let detail = copy.detail[key];\n if (idea) {\n if (key === 'received') label = copy.idea.received;\n else if (key === 'reviewing' || key === 'reviewing_again') label = copy.idea.reviewing;\n else if (key === 'fixing') label = copy.idea.fixing;\n else if (key === 'fixed_version') label = copy.idea.shippedVersion;\n else if (key === 'fixed_next' || key === 'fixed') label = copy.idea.shipped;\n }\n\n const reason = input.closed_reason ?? null;\n if (key === 'closed') {\n detail =\n reason && reason !== 'spam' && reason in copy.closedReason\n ? copy.closedReason[reason as keyof ReporterCopy['closedReason']]\n : copy.closedReason.none;\n }\n\n const bucket = input.group_bucket ?? 'none';\n const othersNote =\n OPEN_KEYS.has(key) || key === 'waiting'\n ? bucket === 'few'\n ? copy.others.few\n : bucket === 'many'\n ? copy.others.many\n : null\n : null;\n\n return {\n key,\n label: fillReporterTemplate(label, { version }),\n tone: TONE[key],\n detail: fillReporterTemplate(detail, { version }),\n canVerify: key === 'fixed_next' || key === 'fixed_version' || key === 'fixed',\n othersNote,\n hidden: key === 'closed' && reason === 'spam',\n };\n}\n\n/** Parameters a timeline template may interpolate. */\nexport interface ReporterTimelineParams {\n /** Verbatim developer text for `comment` and `info_requested`; the reporter's own for `reporter_comment`. */\n text?: string | null;\n version?: string | null;\n closed_reason?: string | null;\n}\n\n/**\n * Render one timeline entry. Pipeline kinds always come from the template for\n * their kind; only the developer's own words (`comment`, `info_requested`) are\n * passed through, verbatim.\n */\nexport function reporterTimelineText(\n kind: ReporterTimelineKind,\n params: ReporterTimelineParams = {},\n locale: string = 'en',\n): string {\n const copy = reporterCopy(locale);\n if (kind === 'comment') return params.text ?? '';\n if (kind === 'closed') {\n const reason = params.closed_reason ?? '';\n return reason && reason !== 'spam' && reason in copy.closedReason\n ? copy.closedReason[reason as keyof ReporterCopy['closedReason']]\n : copy.closedReason.none;\n }\n if (kind === 'reporter_comment') return params.text ?? copy.timeline.reporter_comment;\n return fillReporterTemplate(copy.timeline[kind], { text: params.text, version: params.version });\n}\n\n/** Reporter-facing label for a category chip. */\nexport function reporterCategoryLabel(category: ReporterCategory, locale: string = 'en'): string {\n return reporterCopy(locale).categories[category];\n}\n"]}