@embedpdf/viewer-chrome 3.0.0-next.15 → 3.0.0-next.16
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{annotation-fonts-BqoLZ4Mp.js → annotation-fonts-DWjVOTP0.js} +2 -2
- package/dist/{annotation-fonts-BqoLZ4Mp.js.map → annotation-fonts-DWjVOTP0.js.map} +1 -1
- package/dist/{annotation-fonts-Dt0IQXhz.cjs → annotation-fonts-dpfVkhnq.cjs} +2 -2
- package/dist/{annotation-fonts-Dt0IQXhz.cjs.map → annotation-fonts-dpfVkhnq.cjs.map} +1 -1
- package/dist/{annotation-style-Bzvvp8-N.cjs → annotation-style-B3XKAyZ-.cjs} +3 -3
- package/dist/{annotation-style-Bzvvp8-N.cjs.map → annotation-style-B3XKAyZ-.cjs.map} +1 -1
- package/dist/{annotation-style--rPIZsuP.js → annotation-style-CXF3X47Z.js} +3 -3
- package/dist/{annotation-style--rPIZsuP.js.map → annotation-style-CXF3X47Z.js.map} +1 -1
- package/dist/{ar-DnEj5vbP.cjs → ar-B132r9bo.cjs} +93 -1
- package/dist/ar-B132r9bo.cjs.map +1 -0
- package/dist/{ar-D9XKAmDx.js → ar-BLWFJoA_.js} +93 -1
- package/dist/ar-BLWFJoA_.js.map +1 -0
- package/dist/attachments-panel-Cxln8xos.cjs +217 -0
- package/dist/attachments-panel-Cxln8xos.cjs.map +1 -0
- package/dist/attachments-panel-H1ucRbwo.js +217 -0
- package/dist/attachments-panel-H1ucRbwo.js.map +1 -0
- package/dist/chrome.cjs +21 -0
- package/dist/chrome.cjs.map +1 -1
- package/dist/chrome.js +21 -0
- package/dist/chrome.js.map +1 -1
- package/dist/{commands-BmgxhJ8B.js → commands-BkgLP3Om.js} +418 -23
- package/dist/commands-BkgLP3Om.js.map +1 -0
- package/dist/{commands-CYt4SFUX.cjs → commands-DL1gjZt7.cjs} +433 -20
- package/dist/commands-DL1gjZt7.cjs.map +1 -0
- package/dist/commands.cjs +2 -1
- package/dist/commands.d.cts +3 -1
- package/dist/commands.d.ts +3 -1
- package/dist/commands.js +2 -2
- package/dist/{comments-panel-pEcQg4Vs.cjs → comments-panel-BsnWedTh.cjs} +2 -2
- package/dist/{comments-panel-pEcQg4Vs.cjs.map → comments-panel-BsnWedTh.cjs.map} +1 -1
- package/dist/{comments-panel-MUVgLCBI.js → comments-panel-D7Eadws9.js} +2 -2
- package/dist/{comments-panel-MUVgLCBI.js.map → comments-panel-D7Eadws9.js.map} +1 -1
- package/dist/{de-Dv6zvbnd.cjs → de-7_MvFWzN.cjs} +93 -1
- package/dist/de-7_MvFWzN.cjs.map +1 -0
- package/dist/{de-Bdr4aWzm.js → de-BUhwc9-x.js} +93 -1
- package/dist/de-BUhwc9-x.js.map +1 -0
- package/dist/{dialog-B5GBisKv.js → dialog-BIb373cg.js} +3 -3
- package/dist/dialog-BIb373cg.js.map +1 -0
- package/dist/{dialog-t8F13BL_.cjs → dialog-CngKTnAM.cjs} +3 -3
- package/dist/dialog-CngKTnAM.cjs.map +1 -0
- package/dist/{es-BP09DR9w.cjs → es-DgYj-1L3.cjs} +93 -1
- package/dist/es-DgYj-1L3.cjs.map +1 -0
- package/dist/{es-BSXz5tBv.js → es-DoXTqFoO.js} +93 -1
- package/dist/es-DoXTqFoO.js.map +1 -0
- package/dist/{form-design-panel-vWWU9uB-.js → form-design-panel-CgV_5YWC.js} +3 -3
- package/dist/{form-design-panel-vWWU9uB-.js.map → form-design-panel-CgV_5YWC.js.map} +1 -1
- package/dist/{form-design-panel-B5MXTZ96.cjs → form-design-panel-D0FdmWXW.cjs} +3 -3
- package/dist/{form-design-panel-B5MXTZ96.cjs.map → form-design-panel-D0FdmWXW.cjs.map} +1 -1
- package/dist/{fr-Ckn3K9v1.js → fr-B-8NDhBA.js} +93 -1
- package/dist/fr-B-8NDhBA.js.map +1 -0
- package/dist/{fr-BBQQn7tJ.cjs → fr-C856dmQJ.cjs} +93 -1
- package/dist/fr-C856dmQJ.cjs.map +1 -0
- package/dist/{he-DRsG7bH7.cjs → he-BFTeNc4t.cjs} +93 -1
- package/dist/he-BFTeNc4t.cjs.map +1 -0
- package/dist/{he-wdGU5PkU.js → he-Dlh0fNXM.js} +93 -1
- package/dist/he-Dlh0fNXM.js.map +1 -0
- package/dist/{icons-x0Tc05bs.cjs → icons-1UfLUZ_y.cjs} +20 -1
- package/dist/icons-1UfLUZ_y.cjs.map +1 -0
- package/dist/{icons-BrK5iVL8.js → icons-7dB0Y1ct.js} +20 -1
- package/dist/icons-7dB0Y1ct.js.map +1 -0
- package/dist/index.cjs +740 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/index.js +727 -170
- package/dist/index.js.map +1 -1
- package/dist/{it-BuP4o0xQ.cjs → it-Bef-2Yxq.cjs} +93 -1
- package/dist/it-Bef-2Yxq.cjs.map +1 -0
- package/dist/{it-Us-VmvIu.js → it-BkirG7ol.js} +93 -1
- package/dist/it-BkirG7ol.js.map +1 -0
- package/dist/{ja-Cizj0-5O.js → ja-CGEjCE-s.js} +93 -1
- package/dist/ja-CGEjCE-s.js.map +1 -0
- package/dist/{ja-DovEd6ts.cjs → ja-DNw2zqSD.cjs} +93 -1
- package/dist/ja-DNw2zqSD.cjs.map +1 -0
- package/dist/{ko-DlrXliE1.js → ko-CTkl5vMh.js} +93 -1
- package/dist/ko-CTkl5vMh.js.map +1 -0
- package/dist/{ko-B-qJEol2.cjs → ko-YHzeBqP6.cjs} +93 -1
- package/dist/ko-YHzeBqP6.cjs.map +1 -0
- package/dist/{link-editor-CSjqPnj1.cjs → link-editor-CAS7MZM2.cjs} +2 -2
- package/dist/{link-editor-CSjqPnj1.cjs.map → link-editor-CAS7MZM2.cjs.map} +1 -1
- package/dist/{link-editor-SxM1nnJU.js → link-editor-CkwtqRvb.js} +2 -2
- package/dist/{link-editor-SxM1nnJU.js.map → link-editor-CkwtqRvb.js.map} +1 -1
- package/dist/{measurement-Bs61XWbJ.js → measurement-CQdbnIrn.js} +2 -2
- package/dist/{measurement-Bs61XWbJ.js.map → measurement-CQdbnIrn.js.map} +1 -1
- package/dist/{measurement-CcCsHPOX.cjs → measurement-Cxv1Ahxx.cjs} +2 -2
- package/dist/{measurement-CcCsHPOX.cjs.map → measurement-Cxv1Ahxx.cjs.map} +1 -1
- package/dist/{nl-D3KZDDiJ.cjs → nl-BjkbaLq3.cjs} +93 -1
- package/dist/nl-BjkbaLq3.cjs.map +1 -0
- package/dist/{nl-0aF7M_0h.js → nl-Dya4sR8_.js} +93 -1
- package/dist/nl-Dya4sR8_.js.map +1 -0
- package/dist/outline-panel-BpGtBdj0.cjs +707 -0
- package/dist/outline-panel-BpGtBdj0.cjs.map +1 -0
- package/dist/outline-panel-DO5_REYw.js +707 -0
- package/dist/outline-panel-DO5_REYw.js.map +1 -0
- package/dist/outline-properties-BCa2cc0t.js +330 -0
- package/dist/outline-properties-BCa2cc0t.js.map +1 -0
- package/dist/outline-properties-DT3FIxCw.cjs +330 -0
- package/dist/outline-properties-DT3FIxCw.cjs.map +1 -0
- package/dist/{pl-DSFhAUqx.cjs → pl-CKKdVnpZ.cjs} +93 -1
- package/dist/pl-CKKdVnpZ.cjs.map +1 -0
- package/dist/{pl-BW--AaCI.js → pl-DA9b5NVg.js} +93 -1
- package/dist/pl-DA9b5NVg.js.map +1 -0
- package/dist/print-dialog-BqIrHCBh.cjs +276 -0
- package/dist/print-dialog-BqIrHCBh.cjs.map +1 -0
- package/dist/print-dialog-DvcI2m2_.js +276 -0
- package/dist/print-dialog-DvcI2m2_.js.map +1 -0
- package/dist/{pt-C5S-8MC5.cjs → pt-DLcszlzi.cjs} +93 -1
- package/dist/pt-DLcszlzi.cjs.map +1 -0
- package/dist/{pt-DIhpU5pT.js → pt-Nm8yyjbX.js} +93 -1
- package/dist/pt-Nm8yyjbX.js.map +1 -0
- package/dist/{redact-confirm-CX_SY2ZN.cjs → redact-confirm-C6EiK8yN.cjs} +2 -2
- package/dist/{redact-confirm-CX_SY2ZN.cjs.map → redact-confirm-C6EiK8yN.cjs.map} +1 -1
- package/dist/{redact-confirm-B6j36TPw.js → redact-confirm-CKuv9iN_.js} +2 -2
- package/dist/{redact-confirm-B6j36TPw.js.map → redact-confirm-CKuv9iN_.js.map} +1 -1
- package/dist/{redaction-panel-IJDshSJI.js → redaction-panel-CgNZ-pQk.js} +2 -2
- package/dist/{redaction-panel-IJDshSJI.js.map → redaction-panel-CgNZ-pQk.js.map} +1 -1
- package/dist/{redaction-panel-BmoIl-Ll.cjs → redaction-panel-ZhX0dlMi.cjs} +2 -2
- package/dist/{redaction-panel-BmoIl-Ll.cjs.map → redaction-panel-ZhX0dlMi.cjs.map} +1 -1
- package/dist/{search-panel-HfIhJm1M.js → search-panel-BE4xzWlm.js} +4 -4
- package/dist/{search-panel-HfIhJm1M.js.map → search-panel-BE4xzWlm.js.map} +1 -1
- package/dist/{search-panel-s9IoiOtv.cjs → search-panel-wcbTNG1z.cjs} +4 -4
- package/dist/{search-panel-s9IoiOtv.cjs.map → search-panel-wcbTNG1z.cjs.map} +1 -1
- package/dist/{sheet-BDsa_Sup.cjs → sheet-DTBFiwde.cjs} +30 -11
- package/dist/sheet-DTBFiwde.cjs.map +1 -0
- package/dist/{sheet-R6XDgyEf.js → sheet-DyjKfAq0.js} +25 -12
- package/dist/sheet-DyjKfAq0.js.map +1 -0
- package/dist/{sign-dialog-CgnR7akj.cjs → sign-dialog-D5WGx-Yn.cjs} +2 -2
- package/dist/{sign-dialog-CgnR7akj.cjs.map → sign-dialog-D5WGx-Yn.cjs.map} +1 -1
- package/dist/{sign-dialog-GDqCoQhA.js → sign-dialog-DerNe8qT.js} +2 -2
- package/dist/{sign-dialog-GDqCoQhA.js.map → sign-dialog-DerNe8qT.js.map} +1 -1
- package/dist/{signature-inspector-DyO313Qf.cjs → signature-inspector-Bz6TAfZM.cjs} +4 -10
- package/dist/signature-inspector-Bz6TAfZM.cjs.map +1 -0
- package/dist/{signature-inspector-okFz8do6.js → signature-inspector-CsGr9EBk.js} +4 -10
- package/dist/signature-inspector-CsGr9EBk.js.map +1 -0
- package/dist/{signature-maker-BoYa8vgA.cjs → signature-maker-D_YfBXLn.cjs} +3 -3
- package/dist/{signature-maker-BoYa8vgA.cjs.map → signature-maker-D_YfBXLn.cjs.map} +1 -1
- package/dist/{signature-maker-BhCmYyHD.js → signature-maker-Dnth4rV4.js} +3 -3
- package/dist/{signature-maker-BhCmYyHD.js.map → signature-maker-Dnth4rV4.js.map} +1 -1
- package/dist/{signatures-panel-B56PC6d9.cjs → signatures-panel-Ci_LaI1C.cjs} +4 -10
- package/dist/signatures-panel-Ci_LaI1C.cjs.map +1 -0
- package/dist/{signatures-panel-CgnFfhFm.js → signatures-panel-DZ9ywrjz.js} +4 -10
- package/dist/signatures-panel-DZ9ywrjz.js.map +1 -0
- package/dist/{stamps-panel-CDO0FPyK.js → stamps-panel-BrczStaz.js} +4 -10
- package/dist/stamps-panel-BrczStaz.js.map +1 -0
- package/dist/{stamps-panel-B9NYGayn.cjs → stamps-panel-Cv9nJBwx.cjs} +4 -10
- package/dist/stamps-panel-Cv9nJBwx.cjs.map +1 -0
- package/dist/theme-Be0OZokZ.js +97 -0
- package/dist/theme-Be0OZokZ.js.map +1 -0
- package/dist/theme-FR26JI3r.cjs +126 -0
- package/dist/theme-FR26JI3r.cjs.map +1 -0
- package/dist/{toolbar-z9od3tKl.js → toolbar-DF361xWY.js} +7 -6
- package/dist/toolbar-DF361xWY.js.map +1 -0
- package/dist/{toolbar-CJu2wKTU.cjs → toolbar-ddvpsvTb.cjs} +7 -6
- package/dist/toolbar-ddvpsvTb.cjs.map +1 -0
- package/dist/{zh-cn-CxkUUBct.js → zh-cn-BMPPkLpL.js} +93 -1
- package/dist/zh-cn-BMPPkLpL.js.map +1 -0
- package/dist/{zh-cn-3tmMeHqv.cjs → zh-cn-CZOO3p4H.cjs} +93 -1
- package/dist/zh-cn-CZOO3p4H.cjs.map +1 -0
- package/package.json +4 -4
- package/src/styles.css +8 -0
- package/dist/ar-D9XKAmDx.js.map +0 -1
- package/dist/ar-DnEj5vbP.cjs.map +0 -1
- package/dist/commands-BmgxhJ8B.js.map +0 -1
- package/dist/commands-CYt4SFUX.cjs.map +0 -1
- package/dist/de-Bdr4aWzm.js.map +0 -1
- package/dist/de-Dv6zvbnd.cjs.map +0 -1
- package/dist/dialog-B5GBisKv.js.map +0 -1
- package/dist/dialog-t8F13BL_.cjs.map +0 -1
- package/dist/es-BP09DR9w.cjs.map +0 -1
- package/dist/es-BSXz5tBv.js.map +0 -1
- package/dist/fr-BBQQn7tJ.cjs.map +0 -1
- package/dist/fr-Ckn3K9v1.js.map +0 -1
- package/dist/he-DRsG7bH7.cjs.map +0 -1
- package/dist/he-wdGU5PkU.js.map +0 -1
- package/dist/icons-BrK5iVL8.js.map +0 -1
- package/dist/icons-x0Tc05bs.cjs.map +0 -1
- package/dist/it-BuP4o0xQ.cjs.map +0 -1
- package/dist/it-Us-VmvIu.js.map +0 -1
- package/dist/ja-Cizj0-5O.js.map +0 -1
- package/dist/ja-DovEd6ts.cjs.map +0 -1
- package/dist/ko-B-qJEol2.cjs.map +0 -1
- package/dist/ko-DlrXliE1.js.map +0 -1
- package/dist/nl-0aF7M_0h.js.map +0 -1
- package/dist/nl-D3KZDDiJ.cjs.map +0 -1
- package/dist/pl-BW--AaCI.js.map +0 -1
- package/dist/pl-DSFhAUqx.cjs.map +0 -1
- package/dist/pt-C5S-8MC5.cjs.map +0 -1
- package/dist/pt-DIhpU5pT.js.map +0 -1
- package/dist/sheet-BDsa_Sup.cjs.map +0 -1
- package/dist/sheet-R6XDgyEf.js.map +0 -1
- package/dist/signature-inspector-DyO313Qf.cjs.map +0 -1
- package/dist/signature-inspector-okFz8do6.js.map +0 -1
- package/dist/signatures-panel-B56PC6d9.cjs.map +0 -1
- package/dist/signatures-panel-CgnFfhFm.js.map +0 -1
- package/dist/stamps-panel-B9NYGayn.cjs.map +0 -1
- package/dist/stamps-panel-CDO0FPyK.js.map +0 -1
- package/dist/toolbar-CJu2wKTU.cjs.map +0 -1
- package/dist/toolbar-z9od3tKl.js.map +0 -1
- package/dist/zh-cn-3tmMeHqv.cjs.map +0 -1
- package/dist/zh-cn-CxkUUBct.js.map +0 -1
|
@@ -99,6 +99,7 @@ const pt = {
|
|
|
99
99
|
note: "Comentário",
|
|
100
100
|
link: "Link",
|
|
101
101
|
gotoLink: "Ir para o link",
|
|
102
|
+
saveFile: "Salvar arquivo",
|
|
102
103
|
removeLink: "Remover link",
|
|
103
104
|
delete: "Excluir",
|
|
104
105
|
group: "Agrupar",
|
|
@@ -155,12 +156,44 @@ const pt = {
|
|
|
155
156
|
"annotations-create": "Não é permitido adicionar anotações",
|
|
156
157
|
"doc-annotate-modify": "Não é permitido alterar anotações",
|
|
157
158
|
"doc-annotate-read": "Não é permitido exibir anotações",
|
|
159
|
+
"doc-attachments-modify": "Não é permitido adicionar arquivos",
|
|
158
160
|
"doc-download": "Não é permitido baixar",
|
|
159
161
|
"doc-forms-modify": "Não é permitido editar campos de formulário",
|
|
162
|
+
"doc-outline-modify": "Não é permitido alterar os marcadores",
|
|
163
|
+
"doc-pages-assemble": "Não é permitido alterar as páginas",
|
|
160
164
|
"doc-print": "Não é permitido imprimir",
|
|
161
165
|
"doc-text-copy": "Não é permitido copiar",
|
|
162
166
|
"doc-text-search": "Não é permitido pesquisar"
|
|
163
167
|
},
|
|
168
|
+
attachment: {
|
|
169
|
+
add: "Adicionar arquivo",
|
|
170
|
+
save: "Salvar",
|
|
171
|
+
goTo: "Ir para a página",
|
|
172
|
+
delete: "Excluir",
|
|
173
|
+
more: "Mais opções"
|
|
174
|
+
},
|
|
175
|
+
outline: {
|
|
176
|
+
add: "Adicionar marcador",
|
|
177
|
+
addChild: "Adicionar marcador filho",
|
|
178
|
+
rename: "Renomear",
|
|
179
|
+
setDestination: "Definir destino para a visualização atual",
|
|
180
|
+
properties: "Propriedades…",
|
|
181
|
+
delete: "Excluir",
|
|
182
|
+
expandAll: "Expandir tudo",
|
|
183
|
+
collapseAll: "Recolher tudo",
|
|
184
|
+
more: "Mais opções"
|
|
185
|
+
},
|
|
186
|
+
pages: {
|
|
187
|
+
rotateClockwise: "Girar página no sentido horário",
|
|
188
|
+
rotateCounterclockwise: "Girar página no sentido anti-horário",
|
|
189
|
+
delete: "Excluir páginas",
|
|
190
|
+
duplicate: "Duplicar páginas",
|
|
191
|
+
insertBlank: "Inserir página em branco",
|
|
192
|
+
insertFile: "Inserir de arquivo…",
|
|
193
|
+
extract: "Extrair páginas",
|
|
194
|
+
selectAll: "Selecionar todas as páginas",
|
|
195
|
+
more: "Opções da página"
|
|
196
|
+
},
|
|
164
197
|
turnedOff: "{label} não está disponível"
|
|
165
198
|
},
|
|
166
199
|
passwordPrompt: {
|
|
@@ -213,6 +246,25 @@ const pt = {
|
|
|
213
246
|
other: "Outros"
|
|
214
247
|
},
|
|
215
248
|
goToPage: { go: "Ir" },
|
|
249
|
+
print: {
|
|
250
|
+
title: "Imprimir",
|
|
251
|
+
pages: "Páginas",
|
|
252
|
+
allPages: "Todas as páginas",
|
|
253
|
+
currentPage: "Página atual",
|
|
254
|
+
range: "Personalizado",
|
|
255
|
+
rangeLabel: "Páginas a imprimir",
|
|
256
|
+
rangePlaceholder: "ex.: 1-3, 5",
|
|
257
|
+
rangeInvalid: "Números de página de 1 a {total}, como 1-3, 5",
|
|
258
|
+
annotations: "Imprimir anotações",
|
|
259
|
+
preparing: "Preparando…",
|
|
260
|
+
preparingPage: "Preparando a página {page} de {total}…",
|
|
261
|
+
ready: "Pronto para imprimir.",
|
|
262
|
+
images: "As páginas são impressas como imagens a {dpi} DPI.",
|
|
263
|
+
lowResolution: "Este documento só permite impressão em baixa resolução ({dpi} DPI).",
|
|
264
|
+
failed: "Não foi possível preparar a impressão.",
|
|
265
|
+
cancel: "Cancelar",
|
|
266
|
+
print: "Imprimir"
|
|
267
|
+
},
|
|
216
268
|
panels: {
|
|
217
269
|
thumbnails: "Miniaturas",
|
|
218
270
|
outline: "Marcadores",
|
|
@@ -408,6 +460,46 @@ const pt = {
|
|
|
408
460
|
noRotate: "Fica na vertical quando a página gira",
|
|
409
461
|
invisible: "Legado: ocultar subtipos desconhecidos"
|
|
410
462
|
},
|
|
463
|
+
attachments: {
|
|
464
|
+
loading: "Carregando anexos…",
|
|
465
|
+
failed: "Não foi possível ler os anexos.",
|
|
466
|
+
empty: "Este documento não tem arquivos anexados",
|
|
467
|
+
drop: "Solte arquivos para anexá-los",
|
|
468
|
+
dropHint: "Ou solte arquivos aqui",
|
|
469
|
+
adding: "Adicionando…",
|
|
470
|
+
onPage: "Página {page}",
|
|
471
|
+
count: "{count} arquivo",
|
|
472
|
+
countPlural: "{count} arquivos"
|
|
473
|
+
},
|
|
474
|
+
outline: {
|
|
475
|
+
filter: "Filtrar marcadores",
|
|
476
|
+
loading: "Carregando marcadores…",
|
|
477
|
+
failed: "Não foi possível ler os marcadores.",
|
|
478
|
+
empty: "Este documento não tem marcadores",
|
|
479
|
+
noMatches: "Nenhum marcador corresponde",
|
|
480
|
+
incomplete: "Não foi possível ler parte dos marcadores.",
|
|
481
|
+
untitled: "Sem título",
|
|
482
|
+
properties: {
|
|
483
|
+
title: "Propriedades do marcador",
|
|
484
|
+
name: "Título",
|
|
485
|
+
color: "Cor",
|
|
486
|
+
noColor: "Nenhuma",
|
|
487
|
+
customColor: "Cor personalizada",
|
|
488
|
+
bold: "Negrito",
|
|
489
|
+
italic: "Itálico",
|
|
490
|
+
open: "Expandido ao abrir o documento",
|
|
491
|
+
target: "Destino",
|
|
492
|
+
targetNone: "Nenhum",
|
|
493
|
+
targetView: "Visualização atual",
|
|
494
|
+
targetNamed: "Ação de página",
|
|
495
|
+
targetKept: "Mantido como está",
|
|
496
|
+
keptNote: "Este marcador executa um script ou abre outro arquivo. Ele não pode ser alterado aqui.",
|
|
497
|
+
fit: "Ajuste",
|
|
498
|
+
fitKept: "Como está",
|
|
499
|
+
save: "Salvar",
|
|
500
|
+
cancel: "Cancelar"
|
|
501
|
+
}
|
|
502
|
+
},
|
|
411
503
|
linkEditor: {
|
|
412
504
|
toUrl: "Link para uma URL",
|
|
413
505
|
url: "URL",
|
|
@@ -563,4 +655,4 @@ const pt = {
|
|
|
563
655
|
//#endregion
|
|
564
656
|
export { pt };
|
|
565
657
|
|
|
566
|
-
//# sourceMappingURL=pt-
|
|
658
|
+
//# sourceMappingURL=pt-Nm8yyjbX.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pt-Nm8yyjbX.js","names":[],"sources":["../src/locales/pt.ts"],"sourcesContent":["import type { Locale } from '@embedpdf/react/i18n';\n\n/**\n * Brazilian Portuguese pack, in the words Adobe Acrobat's Português (Brasil) edition uses.\n * Machine-translated from the English pack (`./en.ts`) and not yet reviewed by a native speaker.\n */\nexport const pt: Locale = {\n code: 'pt',\n name: 'Português',\n translations: {\n measurement: {\n title: 'Medições',\n distance: 'Distância',\n perimeter: 'Perímetro',\n area: 'Área',\n areaUnit: 'Unidade de área',\n resetLabel: 'Redefinir posição do rótulo',\n calibrate: 'Calibrar escala',\n scale: 'Escala',\n custom: 'Personalizada',\n unavailable: 'Indisponível',\n instructions:\n 'Arraste para medir uma distância e clique para posicionar a linha de cota. Clique nos vértices de um perímetro ou área e clique duas vezes para concluir. Os limites da área não podem se cruzar; uma visualização indisponível não pode ser concluída. Pressione Escape para cancelar. Arraste o próprio rótulo para movê-lo.',\n sessionOnly: 'Este mecanismo mantém a calibração da página somente nesta sessão.',\n allPages: 'Aplicar a todas as páginas',\n recalculate: 'Recalcular medições existentes',\n preset: 'Escala predefinida',\n choosePreset: 'Escolha uma predefinição',\n unit: 'Unidade',\n precision: 'Precisão',\n selection: 'Medições selecionadas',\n report: '{updated} atualizadas · {skipped} ignoradas · {failed} com falha',\n knownLength: 'Digite o comprimento real representado pela linha que você acabou de desenhar.',\n length: 'Comprimento conhecido',\n apply: 'Aplicar escala',\n applying: 'Aplicando…',\n },\n commands: {\n zoom: {\n in: 'Ampliar',\n out: 'Reduzir',\n fitPage: 'Ajustar à página',\n fitWidth: 'Ajustar à largura',\n automatic: 'Automático',\n menu: 'Zoom',\n level: 'Nível de zoom',\n p50: '50%',\n p100: '100%',\n p150: '150%',\n p200: '200%',\n p400: '400%',\n },\n pan: 'Deslocar',\n pointer: 'Selecionar',\n comment: 'Comentário',\n style: 'Estilo',\n menu: 'Menu',\n viewControls: 'Controles de exibição',\n open: 'Abrir',\n download: 'Baixar',\n print: 'Imprimir',\n fullscreen: 'Tela cheia',\n spread: {\n group: 'Exibição de página',\n none: 'Página única',\n odd: 'Duas páginas',\n even: 'Página de capa',\n },\n scroll: {\n group: 'Rolagem',\n vertical: 'Vertical',\n horizontal: 'Horizontal',\n },\n rotate: {\n group: 'Girar',\n clockwise: 'Girar no sentido horário',\n counterclockwise: 'Girar no sentido anti-horário',\n },\n mode: {\n measure: 'Medir',\n group: 'Modo',\n view: 'Exibir',\n annotate: 'Anotar',\n shapes: 'Formas',\n insert: 'Inserir',\n form: 'Formulário',\n redact: 'Tarjar',\n },\n annotate: {\n cancelCreation: 'Cancelar desenho',\n highlight: 'Realçar',\n strikeout: 'Tachar',\n underline: 'Sublinhar',\n squiggly: 'Ondulado',\n ink: 'Desenhar',\n inkHighlight: 'Marca-texto',\n text: 'Texto',\n insertText: 'Inserir texto',\n replaceText: 'Substituir texto',\n callout: 'Texto explicativo',\n note: 'Comentário',\n link: 'Link',\n gotoLink: 'Ir para o link',\n saveFile: 'Salvar arquivo',\n removeLink: 'Remover link',\n delete: 'Excluir',\n group: 'Agrupar',\n ungroup: 'Desagrupar',\n stampFromSelection: 'Criar carimbo',\n strip: 'Ações de anotação',\n },\n selection: {\n copy: 'Copiar',\n strip: 'Ações de seleção de texto',\n },\n shapes: {\n rectangle: 'Retângulo',\n circle: 'Círculo',\n line: 'Linha',\n arrow: 'Seta',\n polygon: 'Polígono',\n polyline: 'Polilinha',\n },\n insert: {\n stamp: 'Carimbo',\n attachment: 'Anexar arquivo',\n signature: 'Assinatura',\n image: 'Imagem',\n },\n form: {\n textfield: 'Campo de texto',\n checkbox: 'Caixa de seleção',\n radio: 'Botão de opção',\n select: 'Lista suspensa',\n listbox: 'Caixa de listagem',\n button: 'Botão',\n signature: 'Campo de assinatura',\n // The Form mode's design switch, which opens the form designer's sidebar.\n design: 'Design de formulário',\n },\n redact: {\n mark: 'Marcar para tarjar',\n applyAll: 'Aplicar tarjas',\n clearAll: 'Limpar marcações',\n },\n undo: 'Desfazer',\n redo: 'Refazer',\n page: {\n next: 'Próxima página',\n previous: 'Página anterior',\n first: 'Primeira página',\n last: 'Última página',\n goTo: 'Ir para a página',\n },\n find: 'Localizar',\n shortcuts: 'Atalhos de teclado',\n notAllowed: {\n default: 'Ação não permitida: {label}',\n 'annotations-create': 'Não é permitido adicionar anotações',\n 'doc-annotate-modify': 'Não é permitido alterar anotações',\n 'doc-annotate-read': 'Não é permitido exibir anotações',\n 'doc-attachments-modify': 'Não é permitido adicionar arquivos',\n 'doc-download': 'Não é permitido baixar',\n 'doc-forms-modify': 'Não é permitido editar campos de formulário',\n 'doc-outline-modify': 'Não é permitido alterar os marcadores',\n 'doc-pages-assemble': 'Não é permitido alterar as páginas',\n 'doc-print': 'Não é permitido imprimir',\n 'doc-text-copy': 'Não é permitido copiar',\n 'doc-text-search': 'Não é permitido pesquisar',\n },\n attachment: {\n add: 'Adicionar arquivo',\n save: 'Salvar',\n goTo: 'Ir para a página',\n delete: 'Excluir',\n more: 'Mais opções',\n },\n outline: {\n add: 'Adicionar marcador',\n addChild: 'Adicionar marcador filho',\n rename: 'Renomear',\n setDestination: 'Definir destino para a visualização atual',\n properties: 'Propriedades…',\n delete: 'Excluir',\n expandAll: 'Expandir tudo',\n collapseAll: 'Recolher tudo',\n more: 'Mais opções',\n },\n // The page commands, in the Pages mode and a page's menu.\n pages: {\n rotateClockwise: 'Girar página no sentido horário',\n rotateCounterclockwise: 'Girar página no sentido anti-horário',\n delete: 'Excluir páginas',\n duplicate: 'Duplicar páginas',\n insertBlank: 'Inserir página em branco',\n insertFile: 'Inserir de arquivo…',\n extract: 'Extrair páginas',\n selectAll: 'Selecionar todas as páginas',\n more: 'Opções da página',\n },\n turnedOff: '{label} não está disponível',\n },\n passwordPrompt: {\n title: 'Senha necessária',\n required: 'Este documento é protegido por senha. Digite a senha para abri-lo.',\n incorrect: 'A senha está incorreta. Tente novamente.',\n incorrectWarning: 'Senha incorreta',\n label: 'Senha',\n placeholder: 'Digite a senha',\n cancel: 'Cancelar',\n open: 'Abrir',\n opening: 'Abrindo…',\n },\n dropToOpen: {\n label: 'Solte um PDF para abri-lo',\n },\n documentError: {\n title: 'Não foi possível abrir o documento',\n unknown: 'O documento não pôde ser aberto.',\n notFound: 'O arquivo não foi encontrado.',\n notAllowed: 'Você não tem acesso a este documento.',\n damaged: 'Este arquivo não é um PDF ou está danificado.',\n unsupported: 'Este visualizador não pode abrir este tipo de documento.',\n retry: 'Tentar novamente',\n close: 'Fechar documento',\n },\n tabs: {\n close: 'Fechar {name}',\n loading: 'Carregando',\n untitled: 'Documento {id}',\n },\n closeUnsaved: {\n title: 'Fechar sem salvar?',\n body: '“{name}” tem alterações que não foram baixadas. Elas serão perdidas.',\n cancel: 'Cancelar',\n close: 'Fechar sem salvar',\n },\n viewOnly: {\n label: 'Somente leitura',\n turnedOff: 'As ferramentas que alteram este documento estão desativadas',\n notAllowed: 'Você pode ler este documento, mas não alterá-lo',\n },\n panel: {\n close: 'Fechar',\n resize: 'Redimensionar {title}',\n },\n menu: {\n back: 'Voltar',\n },\n shortcuts: {\n document: 'Documento',\n viewing: 'Visualização',\n editing: 'Edição',\n other: 'Outros',\n },\n goToPage: {\n go: 'Ir',\n },\n print: {\n title: 'Imprimir',\n pages: 'Páginas',\n allPages: 'Todas as páginas',\n currentPage: 'Página atual',\n range: 'Personalizado',\n rangeLabel: 'Páginas a imprimir',\n rangePlaceholder: 'ex.: 1-3, 5',\n rangeInvalid: 'Números de página de 1 a {total}, como 1-3, 5',\n annotations: 'Imprimir anotações',\n preparing: 'Preparando…',\n preparingPage: 'Preparando a página {page} de {total}…',\n ready: 'Pronto para imprimir.',\n images: 'As páginas são impressas como imagens a {dpi} DPI.',\n lowResolution: 'Este documento só permite impressão em baixa resolução ({dpi} DPI).',\n failed: 'Não foi possível preparar a impressão.',\n cancel: 'Cancelar',\n print: 'Imprimir',\n },\n panels: {\n thumbnails: 'Miniaturas',\n outline: 'Marcadores',\n attachments: 'Anexos',\n search: 'Pesquisar',\n comments: 'Comentários',\n style: 'Estilo',\n stamps: 'Carimbos',\n signatures: 'Assinaturas',\n redaction: 'Tarjas',\n measurement: 'Medições',\n formDesign: 'Design de formulário',\n switch: 'Trocar painel',\n },\n annotation: {\n comment: 'Comentário',\n highlight: 'Realce',\n underline: 'Sublinhado',\n squiggly: 'Ondulado',\n strikeout: 'Tachado',\n square: 'Quadrado',\n circle: 'Círculo',\n line: 'Linha',\n polygon: 'Polígono',\n polyline: 'Polilinha',\n ink: 'Desenho',\n freeText: 'Texto',\n stamp: 'Carimbo',\n caret: 'Sinal de inserção',\n redact: 'Tarja',\n fileAttachment: 'Anexo',\n // The style panel's labels, as the annotation kinds name them (`labelKey`), by wording:\n // one field is called different things by different kinds.\n style: {\n opacity: 'Opacidade',\n stroke: 'Traço',\n fill: 'Preenchimento',\n color: 'Cor',\n strokeWidth: 'Espessura do traço',\n border: 'Borda',\n borderStyle: 'Estilo da borda',\n borderColor: 'Cor da borda',\n borderWidth: 'Espessura da borda',\n background: 'Plano de fundo',\n outline: 'Contorno',\n lineEndings: 'Extremidades da linha',\n blendMode: 'Modo de mesclagem',\n font: 'Fonte',\n fontSize: 'Tamanho da fonte',\n textColor: 'Cor do texto',\n bold: 'Negrito',\n italic: 'Itálico',\n underline: 'Sublinhado',\n align: 'Alinhar',\n alignment: 'Alinhamento',\n label: 'Rótulo',\n labelFont: 'Fonte do rótulo',\n labelSize: 'Tamanho do rótulo',\n labelColor: 'Cor do rótulo',\n icon: 'Ícone',\n link: 'Link',\n },\n // The annotation flags (`/F`).\n flags: {\n print: 'Imprimir',\n hidden: 'Oculta',\n noView: 'Não exibir',\n toggleNoView: 'Alternar não exibir',\n readOnly: 'Somente leitura',\n locked: 'Bloqueada',\n lockedContents: 'Conteúdo bloqueado',\n noZoom: 'Sem zoom',\n noRotate: 'Sem rotação',\n invisible: 'Invisível',\n },\n borderStyles: { solid: 'Sólido', dashed: 'Tracejado', cloudy: 'Nuvem' },\n lineEndings: {\n none: 'Nenhuma',\n square: 'Quadrado',\n circle: 'Círculo',\n diamond: 'Losango',\n openArrow: 'Seta aberta',\n closedArrow: 'Seta fechada',\n butt: 'Barra',\n reverseOpenArrow: 'Seta aberta invertida',\n reverseClosedArrow: 'Seta fechada invertida',\n slash: 'Barra diagonal',\n },\n blendModes: {\n normal: 'Normal',\n multiply: 'Multiplicação',\n screen: 'Divisão',\n overlay: 'Sobrepor',\n darken: 'Escurecer',\n lighten: 'Clarear',\n colorDodge: 'Subexposição de cores',\n colorBurn: 'Superexposição de cores',\n hardLight: 'Luz direta',\n softLight: 'Luz indireta',\n difference: 'Diferença',\n exclusion: 'Exclusão',\n hue: 'Matiz',\n saturation: 'Saturação',\n color: 'Cor',\n luminosity: 'Luminosidade',\n },\n // The standard PDF fonts, by their names: a language may keep them as they are.\n fonts: {\n courier: 'Courier',\n courierBold: 'Courier Bold',\n courierBoldOblique: 'Courier Bold Oblique',\n courierOblique: 'Courier Oblique',\n helvetica: 'Helvetica',\n helveticaBold: 'Helvetica Bold',\n helveticaBoldOblique: 'Helvetica Bold Oblique',\n helveticaOblique: 'Helvetica Oblique',\n timesRoman: 'Times Roman',\n timesBold: 'Times Bold',\n timesBoldItalic: 'Times Bold Italic',\n timesItalic: 'Times Italic',\n symbol: 'Symbol',\n zapfDingbats: 'Zapf Dingbats',\n },\n alignments: { left: 'Esquerda', center: 'Centro', right: 'Direita' },\n noteIcons: {\n comment: 'Comentário',\n key: 'Chave',\n note: 'Nota',\n help: 'Ajuda',\n newParagraph: 'Novo parágrafo',\n paragraph: 'Parágrafo',\n insert: 'Inserir',\n },\n attachmentIcons: {\n pushPin: 'Tachinha',\n paperclip: 'Clipe de papel',\n graph: 'Gráfico',\n tag: 'Etiqueta',\n },\n },\n // A form field's settings, as the form plugin names them (`labelKey`).\n form: {\n settings: {\n name: 'Nome',\n tooltip: 'Dica de ferramenta',\n required: 'Obrigatório',\n readOnly: 'Somente leitura',\n noExport: 'Não exportar',\n defaultValue: 'Valor padrão',\n maxLength: 'Comprimento máximo',\n multiline: 'Várias linhas',\n password: 'Senha',\n comb: 'Um caractere por caixa',\n radiosInUnison: 'Botões com o mesmo valor são ativados juntos',\n keepOneOn: 'Manter um ativado',\n options: 'Opções',\n allowTyping: 'Permitir digitação',\n multiSelect: 'Várias escolhas',\n },\n },\n // A thumbnail's tooltip.\n thumbnails: { page: 'Página {page}' },\n // The form designer's sidebar: the fields by page, and the selected one's buttons.\n formDesign: {\n empty: 'Nenhum campo ainda. Escolha uma ferramenta de campo para adicionar um.',\n page: 'Página {page}',\n allFields: 'Todos os campos',\n buttons: 'Botões',\n boxes: 'Caixas',\n box: 'Caixa {number}',\n addButton: 'Adicionar um botão',\n addBox: 'Adicionar uma caixa',\n },\n // The style panel's own words around the properties.\n stylePanel: {\n mixed: '(misto)',\n // A color swatch that takes the color away.\n transparent: 'Transparente',\n lineStart: 'Início',\n lineEnd: 'Fim',\n empty:\n 'Escolha uma ferramenta de desenho ou selecione uma anotação para editar o estilo dela.',\n selected: 'Selecionados: {count}',\n toolDefaults: 'Padrões de {tool}',\n defaults: 'Padrões',\n },\n // The flags section of the style panel: its title, and what each flag does.\n annotationFlags: {\n title: 'Sinalizadores (/F)',\n print: 'Incluir quando a página for impressa',\n hidden: 'Some em todo lugar: tela, cliques, impressão',\n noView: 'Oculta na tela, ainda pode ser impressa',\n toggleNoView: 'Revelar uma anotação não exibida enquanto estiver selecionada',\n readOnly: 'Visível, mas não clicável',\n locked: 'Sem mover / redimensionar / excluir / mudar estilo',\n lockedContents: 'O texto não pode mudar; a geometria pode',\n noZoom: 'Tamanho constante na tela (ancorada no canto superior esquerdo)',\n noRotate: 'Fica na vertical quando a página gira',\n invisible: 'Legado: ocultar subtipos desconhecidos',\n },\n // The link editor over a selected annotation.\n attachments: {\n loading: 'Carregando anexos…',\n failed: 'Não foi possível ler os anexos.',\n empty: 'Este documento não tem arquivos anexados',\n drop: 'Solte arquivos para anexá-los',\n dropHint: 'Ou solte arquivos aqui',\n adding: 'Adicionando…',\n onPage: 'Página {page}',\n count: '{count} arquivo',\n countPlural: '{count} arquivos',\n },\n outline: {\n filter: 'Filtrar marcadores',\n loading: 'Carregando marcadores…',\n failed: 'Não foi possível ler os marcadores.',\n empty: 'Este documento não tem marcadores',\n noMatches: 'Nenhum marcador corresponde',\n incomplete: 'Não foi possível ler parte dos marcadores.',\n untitled: 'Sem título',\n properties: {\n title: 'Propriedades do marcador',\n name: 'Título',\n color: 'Cor',\n noColor: 'Nenhuma',\n customColor: 'Cor personalizada',\n bold: 'Negrito',\n italic: 'Itálico',\n open: 'Expandido ao abrir o documento',\n target: 'Destino',\n targetNone: 'Nenhum',\n targetView: 'Visualização atual',\n targetNamed: 'Ação de página',\n targetKept: 'Mantido como está',\n keptNote:\n 'Este marcador executa um script ou abre outro arquivo. Ele não pode ser alterado aqui.',\n fit: 'Ajuste',\n fitKept: 'Como está',\n save: 'Salvar',\n cancel: 'Cancelar',\n },\n },\n linkEditor: {\n toUrl: 'Link para uma URL',\n url: 'URL',\n toPage: 'Link para uma página',\n page: 'Página',\n urlPlaceholder: 'https://…',\n pagePlaceholder: 'Número da página',\n add: 'Adicionar link',\n update: 'Atualizar link',\n },\n demo: {\n starting: 'Iniciando o visualizador…',\n opening: 'Abrindo o documento…',\n more: 'Mais',\n searchPlaceholder: 'Pesquisar no documento…',\n searchCaseSensitive: 'Diferenciar maiúsculas',\n searchWholeWord: 'Palavra inteira',\n searchRegex: 'Expressão regular',\n searchSearching: 'Pesquisando…',\n searchResults: '{count} resultados encontrados',\n searchNoResults: 'Nenhum resultado',\n searchPrevious: 'Resultado anterior',\n searchNext: 'Próximo resultado',\n searchPage: 'Página {page}',\n commentsForbidden: 'Você não tem acesso aos comentários deste documento.',\n commentsLoading: 'Carregando comentários…',\n commentsError: 'Não foi possível carregar os comentários.',\n commentsRetry: 'Tentar novamente',\n commentsEmpty:\n 'Nenhum comentário ainda. Use a ferramenta de nota para iniciar uma discussão.',\n commentsEmptyReadOnly: 'Nenhum comentário neste documento.',\n commentsAnonymous: 'Desconhecido',\n commentsPage: 'Página {page}',\n commentCount: '{count} comentário',\n commentCountPlural: '{count} comentários',\n commentsReply: 'Responder',\n commentsReplyPlaceholder: 'Responder…',\n commentsAddPlaceholder: 'Adicionar um comentário…',\n commentsDelete: 'Excluir comentário',\n commentsDeleteThread: 'Excluir discussão',\n commentsEdit: 'Editar comentário',\n commentsStatus: 'Status',\n commentsStatusNone: 'Sem status',\n commentsStatusAccepted: 'Aceito',\n commentsStatusRejected: 'Rejeitado',\n commentsStatusCancelled: 'Cancelado',\n commentsStatusCompleted: 'Concluído',\n empty: 'Ainda não há nada neste painel de demonstração.',\n page: 'Página {current} de {total}',\n goToPage: 'Ir para a página',\n cancel: 'Cancelar',\n pageBadge: 'pág. {page}',\n redactionEmpty: 'Nenhuma tarja pendente. Use a ferramenta Tarjar para marcar texto ou áreas.',\n redactionArea: 'Marcação de área',\n redactionText: 'Marcação de texto',\n redactionRemove: 'Remover marcação',\n redactConfirmTitle: 'Aplicar tarjas?',\n redactConfirmBody:\n 'Remover permanentemente o conteúdo sob {count} marcações de tarja. Esta ação não pode ser desfeita.',\n redactConfirmCollateral: '{count} outras anotações também serão removidas.',\n redactApply: 'Aplicar',\n redactApplying: 'Aplicando…',\n formatLabel: 'Formato',\n fieldSettingsTitle: 'Campo',\n fieldOptionLabel: 'Rótulo',\n fieldOptionValue: 'Valor',\n fieldOptionAdd: 'Adicionar opção',\n fieldOptionRemove: 'Remover opção',\n fieldNone: 'Nenhum',\n redactLabelTitle: 'Rótulo da tarja',\n redactLabelPlaceholder: 'ex.: TARJADO',\n redactLabelRepeat: 'Repetir rótulo em toda a região',\n stampsAll: 'Todos os carimbos',\n stampsLoading: 'Carregando carimbos…',\n stampsEmpty:\n 'Nenhum carimbo ainda. Importe um PDF para transformar cada página dele em um carimbo.',\n stampsRemoveStamp: 'Remover carimbo',\n stampsArmedHint: 'Clique em uma página para posicionar o carimbo.',\n stampsImport: 'Importar PDF…',\n stampsImporting: 'Importando…',\n stampsImportHint: 'Importe um PDF como biblioteca de carimbos — cada página vira um carimbo.',\n stampsRemoveLibrary: 'Remover biblioteca',\n stampsExportLibrary: 'Exportar biblioteca como PDF',\n stampsCustomLibrary: 'Meus carimbos',\n stampsCustomLabel: 'Carimbo personalizado',\n stampsError: 'Não foi possível carregar os carimbos integrados.',\n stampsArmError: 'Não foi possível ativar esse carimbo.',\n stampsImportError: 'Não foi possível importar esse PDF como biblioteca de carimbos.',\n quickStampsLabel: 'Carimbos rápidos',\n signaturesEmpty: 'Nenhuma assinatura ainda. Crie uma para assinar.',\n signaturesNew: 'Nova assinatura…',\n signaturesArmedHint:\n 'Clique em um campo de assinatura para assiná-lo, ou em qualquer lugar de uma página para posicionar a marca.',\n signaturesTargetHint: 'Escolha uma marca para o campo selecionado.',\n signaturesInDocument: 'Neste documento',\n signaturesNone: 'Este documento não tem campos de assinatura.',\n signaturesValidate: 'Validar',\n signaturesValidating: 'Validando…',\n signaturesSigned: 'Assinado',\n signaturesUnsigned: 'Não assinado',\n signaturesRename: 'Renomear',\n signaturesRemove: 'Remover',\n signaturesExport: 'Exportar como PDF',\n signaturesAddInitials: 'Adicionar iniciais',\n signatureLabel: 'Assinatura',\n initialsLabel: 'Iniciais',\n makerTitle: 'Nova assinatura',\n makerName: 'Nome',\n makerNamePlaceholder: 'Seu nome',\n makerDraw: 'Desenhar',\n makerType: 'Digitar',\n makerUpload: 'Carregar',\n makerTypePlaceholder: 'Digite seu nome',\n makerFont: 'Fonte',\n makerUploadHint: 'Escolha um PNG, JPEG ou PDF de uma página',\n makerClear: 'Limpar',\n makerOptional: '(opcional)',\n makerSave: 'Salvar',\n makerSaving: 'Salvando…',\n makerError: 'Não foi possível salvar a assinatura.',\n signTitle: 'Assinar este campo',\n signReason: 'Motivo',\n signLocation: 'Local',\n signKind: 'O que pode mudar depois',\n signKindApproval:\n 'Assinatura de aprovação — o preenchimento de formulários e outras assinaturas continuam válidos',\n signKindCertifyAnnotate:\n 'Certificar — permitir comentários, preenchimento de formulários e assinaturas',\n signKindCertifyFill:\n 'Certificar — permitir somente preenchimento de formulários e assinaturas',\n signKindCertifyLocked: 'Certificar — não permitir alterações',\n signButton: 'Assinar',\n signSigning: 'Assinando…',\n signFill: 'Posicionar sem assinar',\n signError: 'Não foi possível assinar o campo.',\n inspectTitle: 'Assinatura',\n inspectSigner: 'Assinado por',\n inspectReason: 'Motivo',\n inspectLocation: 'Local',\n inspectTime: 'Data e hora',\n inspectIntegrity: 'Documento',\n inspectCryptography: 'Assinatura',\n inspectTrust: 'Signatário',\n inspectChanges: 'Alterações posteriores',\n inspectDownload: 'Baixar versão assinada',\n verdictValid: 'Válida',\n verdictValidUntrusted: 'Válida, signatário não confiável',\n verdictInvalid: 'Inválida — documento alterado após a assinatura',\n verdictWillInvalidate: 'Válida, inválida ao salvar',\n signaturesInvalidating:\n 'Esta alteração invalidará {field} quando o documento for salvo. Desfaça-a para manter a assinatura.',\n verdictIndeterminate: 'Não foi possível verificar',\n verdictUnchanged: 'Nenhuma',\n verdictRestored: 'Alterado e depois restaurado',\n inspectLaterRevisions: 'Revisões após a assinatura',\n verdictPermitted: 'Permitidas',\n verdictForbidden: 'Não permitidas',\n },\n },\n};\n"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_dialog = require("./dialog-
|
|
1
|
+
const require_dialog = require("./dialog-CngKTnAM.cjs");
|
|
2
2
|
let react = require("react");
|
|
3
3
|
let _embedpdf_react_redaction = require("@embedpdf/react/redaction");
|
|
4
4
|
let _embedpdf_react_i18n = require("@embedpdf/react/i18n");
|
|
@@ -80,4 +80,4 @@ function RedactConfirmModal() {
|
|
|
80
80
|
//#endregion
|
|
81
81
|
exports.RedactConfirmModal = RedactConfirmModal;
|
|
82
82
|
|
|
83
|
-
//# sourceMappingURL=redact-confirm-
|
|
83
|
+
//# sourceMappingURL=redact-confirm-C6EiK8yN.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact-confirm-
|
|
1
|
+
{"version":3,"file":"redact-confirm-C6EiK8yN.cjs","names":["Dialog"],"sources":["../src/ui/redact-confirm.tsx"],"sourcesContent":["import { useId, useState } from 'react';\nimport { useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Dialog } from './dialog';\n\n/**\n * The apply-all confirm modal (`redact-confirm` shell surface, `exclusive:\n * 'modal'` via the command router). Shows the pending count and the\n * client-side collateral estimate — other annotations the apply will destroy —\n * before anything irreversible happens. The authoritative collateral count\n * comes back on the result. Escape cancels, unless the apply is running.\n */\nexport function RedactConfirmModal() {\n const t = useT();\n const surface = useSurface('redact-confirm');\n const redaction = useRedaction();\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const titleId = useId();\n\n if (!surface.isOpen) return null;\n\n const count = redaction.getPendingCount();\n const collateral = redaction.estimateCollateral().count;\n\n const apply = async () => {\n setBusy(true);\n setError(null);\n try {\n await redaction.applyAll();\n surface.close();\n } catch (error) {\n setError(error instanceof Error ? error.message : String(error));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Dialog\n labelledBy={titleId}\n onClose={() => {\n if (!busy) surface.close();\n }}\n className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\"\n >\n <h2 id={titleId} className=\"text-fg text-base font-semibold\">\n {t('demo.redactConfirmTitle')}\n </h2>\n <p className=\"text-fg-muted mt-2 text-sm\">\n {t('demo.redactConfirmBody', { params: { count } })}\n </p>\n {collateral > 0 ? (\n <p className=\"mt-2 text-sm font-medium text-red-600\">\n {t('demo.redactConfirmCollateral', { params: { count: collateral } })}\n </p>\n ) : null}\n {error ? <p className=\"mt-2 text-sm text-red-600\">{error}</p> : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={busy}\n onClick={surface.close}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void apply()}\n className=\"rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-60\"\n >\n {busy ? t('demo.redactApplying') : t('demo.redactApply')}\n </button>\n </div>\n </Dialog>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,qBAAqB;CACnC,MAAM,KAAA,GAAA,qBAAA,KAAA,CAAS;CACf,MAAM,WAAA,GAAA,sBAAA,WAAA,CAAqB,gBAAgB;CAC3C,MAAM,aAAA,GAAA,0BAAA,aAAA,CAAyB;CAC/B,MAAM,CAAC,MAAM,YAAA,GAAA,MAAA,SAAA,CAAoB,KAAK;CACtC,MAAM,CAAC,OAAO,aAAA,GAAA,MAAA,SAAA,CAAoC,IAAI;CACtD,MAAM,WAAA,GAAA,MAAA,MAAA,CAAgB;CAEtB,IAAI,CAAC,QAAQ,QAAQ,OAAO;CAE5B,MAAM,QAAQ,UAAU,gBAAgB;CACxC,MAAM,aAAa,UAAU,mBAAmB,CAAC,CAAC;CAElD,MAAM,QAAQ,YAAY;EACxB,QAAQ,IAAI;EACZ,SAAS,IAAI;EACb,IAAI;GACF,MAAM,UAAU,SAAS;GACzB,QAAQ,MAAM;EAChB,SAAS,OAAO;GACd,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;EACjE,UAAU;GACR,QAAQ,KAAK;EACf;CACF;CAEA,OACE,iBAAA,GAAA,kBAAA,KAAA,CAACA,eAAAA,QAAD;EACE,YAAY;EACZ,eAAe;GACb,IAAI,CAAC,MAAM,QAAQ,MAAM;EAC3B;EACA,WAAU;EALZ,UAAA;GAOE,iBAAA,GAAA,kBAAA,IAAA,CAAC,MAAD;IAAI,IAAI;IAAS,WAAU;IACxB,UAAA,EAAE,yBAAyB;GAC1B,CAAA;GACJ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IAAG,WAAU;IACV,UAAA,EAAE,0BAA0B,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;GACjD,CAAA;GACF,aAAa,IACZ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IAAG,WAAU;IACV,UAAA,EAAE,gCAAgC,EAAE,QAAQ,EAAE,OAAO,WAAW,EAAE,CAAC;GACnE,CAAA,IACD;GACH,QAAQ,iBAAA,GAAA,kBAAA,IAAA,CAAC,KAAD;IAAG,WAAU;IAA6B,UAAA;GAAS,CAAA,IAAI;GAChE,iBAAA,GAAA,kBAAA,KAAA,CAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,SAAS,QAAQ;KACjB,WAAU;KAET,UAAA,EAAE,aAAa;IACV,CAAA,GACR,iBAAA,GAAA,kBAAA,IAAA,CAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,eAAe,KAAK,MAAM;KAC1B,WAAU;KAET,UAAA,OAAO,EAAE,qBAAqB,IAAI,EAAE,kBAAkB;IACjD,CAAA,CACL;;EACC;;AAEZ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as Dialog } from "./dialog-
|
|
1
|
+
import { t as Dialog } from "./dialog-BIb373cg.js";
|
|
2
2
|
import { useId, useState } from "react";
|
|
3
3
|
import { useRedaction } from "@embedpdf/react/redaction";
|
|
4
4
|
import { useT } from "@embedpdf/react/i18n";
|
|
@@ -80,4 +80,4 @@ function RedactConfirmModal() {
|
|
|
80
80
|
//#endregion
|
|
81
81
|
export { RedactConfirmModal };
|
|
82
82
|
|
|
83
|
-
//# sourceMappingURL=redact-confirm-
|
|
83
|
+
//# sourceMappingURL=redact-confirm-CKuv9iN_.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redact-confirm-
|
|
1
|
+
{"version":3,"file":"redact-confirm-CKuv9iN_.js","names":[],"sources":["../src/ui/redact-confirm.tsx"],"sourcesContent":["import { useId, useState } from 'react';\nimport { useRedaction } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Dialog } from './dialog';\n\n/**\n * The apply-all confirm modal (`redact-confirm` shell surface, `exclusive:\n * 'modal'` via the command router). Shows the pending count and the\n * client-side collateral estimate — other annotations the apply will destroy —\n * before anything irreversible happens. The authoritative collateral count\n * comes back on the result. Escape cancels, unless the apply is running.\n */\nexport function RedactConfirmModal() {\n const t = useT();\n const surface = useSurface('redact-confirm');\n const redaction = useRedaction();\n const [busy, setBusy] = useState(false);\n const [error, setError] = useState<string | null>(null);\n const titleId = useId();\n\n if (!surface.isOpen) return null;\n\n const count = redaction.getPendingCount();\n const collateral = redaction.estimateCollateral().count;\n\n const apply = async () => {\n setBusy(true);\n setError(null);\n try {\n await redaction.applyAll();\n surface.close();\n } catch (error) {\n setError(error instanceof Error ? error.message : String(error));\n } finally {\n setBusy(false);\n }\n };\n\n return (\n <Dialog\n labelledBy={titleId}\n onClose={() => {\n if (!busy) surface.close();\n }}\n className=\"border-border bg-surface w-96 rounded-lg border p-4 shadow-xl\"\n >\n <h2 id={titleId} className=\"text-fg text-base font-semibold\">\n {t('demo.redactConfirmTitle')}\n </h2>\n <p className=\"text-fg-muted mt-2 text-sm\">\n {t('demo.redactConfirmBody', { params: { count } })}\n </p>\n {collateral > 0 ? (\n <p className=\"mt-2 text-sm font-medium text-red-600\">\n {t('demo.redactConfirmCollateral', { params: { count: collateral } })}\n </p>\n ) : null}\n {error ? <p className=\"mt-2 text-sm text-red-600\">{error}</p> : null}\n <div className=\"mt-4 flex justify-end gap-2\">\n <button\n type=\"button\"\n disabled={busy}\n onClick={surface.close}\n className=\"border-border text-fg hover:bg-hover rounded-md border px-3 py-1.5 text-sm\"\n >\n {t('demo.cancel')}\n </button>\n <button\n type=\"button\"\n disabled={busy}\n onClick={() => void apply()}\n className=\"rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-60\"\n >\n {busy ? t('demo.redactApplying') : t('demo.redactApply')}\n </button>\n </div>\n </Dialog>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;AAaA,SAAgB,qBAAqB;CACnC,MAAM,IAAI,KAAK;CACf,MAAM,UAAU,WAAW,gBAAgB;CAC3C,MAAM,YAAY,aAAa;CAC/B,MAAM,CAAC,MAAM,WAAW,SAAS,KAAK;CACtC,MAAM,CAAC,OAAO,YAAY,SAAwB,IAAI;CACtD,MAAM,UAAU,MAAM;CAEtB,IAAI,CAAC,QAAQ,QAAQ,OAAO;CAE5B,MAAM,QAAQ,UAAU,gBAAgB;CACxC,MAAM,aAAa,UAAU,mBAAmB,CAAC,CAAC;CAElD,MAAM,QAAQ,YAAY;EACxB,QAAQ,IAAI;EACZ,SAAS,IAAI;EACb,IAAI;GACF,MAAM,UAAU,SAAS;GACzB,QAAQ,MAAM;EAChB,SAAS,OAAO;GACd,SAAS,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;EACjE,UAAU;GACR,QAAQ,KAAK;EACf;CACF;CAEA,OACE,qBAAC,QAAD;EACE,YAAY;EACZ,eAAe;GACb,IAAI,CAAC,MAAM,QAAQ,MAAM;EAC3B;EACA,WAAU;EALZ,UAAA;GAOE,oBAAC,MAAD;IAAI,IAAI;IAAS,WAAU;IACxB,UAAA,EAAE,yBAAyB;GAC1B,CAAA;GACJ,oBAAC,KAAD;IAAG,WAAU;IACV,UAAA,EAAE,0BAA0B,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;GACjD,CAAA;GACF,aAAa,IACZ,oBAAC,KAAD;IAAG,WAAU;IACV,UAAA,EAAE,gCAAgC,EAAE,QAAQ,EAAE,OAAO,WAAW,EAAE,CAAC;GACnE,CAAA,IACD;GACH,QAAQ,oBAAC,KAAD;IAAG,WAAU;IAA6B,UAAA;GAAS,CAAA,IAAI;GAChE,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,SAAS,QAAQ;KACjB,WAAU;KAET,UAAA,EAAE,aAAa;IACV,CAAA,GACR,oBAAC,UAAD;KACE,MAAK;KACL,UAAU;KACV,eAAe,KAAK,MAAM;KAC1B,WAAU;KAET,UAAA,OAAO,EAAE,qBAAqB,IAAI,EAAE,kBAAkB;IACjD,CAAA,CACL;;EACC;;AAEZ"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as Icon } from "./icons-
|
|
1
|
+
import { n as Icon } from "./icons-7dB0Y1ct.js";
|
|
2
2
|
import { useCapability } from "@embedpdf/react/runtime";
|
|
3
3
|
import { AnnotationToken, annotationKey } from "@embedpdf/react/annotation";
|
|
4
4
|
import { usePendingRedactions, useRedaction, useRedactionState } from "@embedpdf/react/redaction";
|
|
@@ -93,4 +93,4 @@ function RedactionPanel() {
|
|
|
93
93
|
//#endregion
|
|
94
94
|
export { RedactionPanel };
|
|
95
95
|
|
|
96
|
-
//# sourceMappingURL=redaction-panel-
|
|
96
|
+
//# sourceMappingURL=redaction-panel-CgNZ-pQk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redaction-panel-
|
|
1
|
+
{"version":3,"file":"redaction-panel-CgNZ-pQk.js","names":[],"sources":["../src/ui/redaction-panel.tsx"],"sourcesContent":["import { useCapability } from '@embedpdf/react/runtime';\nimport { AnnotationToken } from '@embedpdf/react/annotation';\nimport { annotationKey } from '@embedpdf/react/annotation';\nimport { usePendingRedactions, useRedaction, useRedactionState } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\n/**\n * The pending-redactions review panel (right sidebar). The list is a live view\n * over the annotation plane — deleting a mark here is deleting the annotation.\n * \"Apply all\" routes through the confirm modal: the apply is irreversible.\n */\nexport function RedactionPanel() {\n const t = useT();\n const redaction = useRedaction();\n const applying = useRedactionState((state) => state.applying);\n const pending = usePendingRedactions();\n const anno = useCapability(AnnotationToken);\n const confirm = useSurface('redact-confirm');\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {pending.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name=\"redactionSidebar\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.redactionEmpty')}</p>\n </div>\n ) : (\n <ul className=\"flex flex-col gap-1\">\n {pending.map((item) => (\n <li key={annotationKey(item.ref)}>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => anno.selection.set([item.ref])}\n onKeyDown={(event) => event.key === 'Enter' && anno.selection.set([item.ref])}\n className=\"hover:bg-hover group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-start\"\n >\n <Icon\n name={item.kind === 'area' ? 'redactArea' : 'redact'}\n size={16}\n className=\"text-fg-muted shrink-0\"\n />\n <span className=\"text-fg min-w-0 flex-1 truncate text-sm\">\n {item.overlayText ??\n t(item.kind === 'area' ? 'demo.redactionArea' : 'demo.redactionText')}\n </span>\n <span className=\"text-fg-muted shrink-0 text-xs\">\n {t('demo.pageBadge', {\n params: { page: item.pageIndex >= 0 ? String(item.pageIndex + 1) : '?' },\n })}\n </span>\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n void anno.delete(item.ref);\n }}\n className=\"text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded opacity-0 group-hover:opacity-100\"\n title={t('demo.redactionRemove')}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"border-border-subtle flex shrink-0 gap-2 border-t p-3\">\n <button\n type=\"button\"\n disabled={pending.length === 0}\n onClick={() => {\n for (const item of pending) void anno.delete(item.ref);\n }}\n className=\"border-border text-fg hover:bg-hover flex-1 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40\"\n >\n {t('commands.redact.clearAll')}\n </button>\n <button\n type=\"button\"\n disabled={pending.length === 0 || !redaction.canApply() || applying}\n onClick={() => confirm.open()}\n className=\"flex-1 rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-40\"\n >\n {t('commands.redact.applyAll')}\n </button>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,iBAAiB;CAC/B,MAAM,IAAI,KAAK;CACf,MAAM,YAAY,aAAa;CAC/B,MAAM,WAAW,mBAAmB,UAAU,MAAM,QAAQ;CAC5D,MAAM,UAAU,qBAAqB;CACrC,MAAM,OAAO,cAAc,eAAe;CAC1C,MAAM,UAAU,WAAW,gBAAgB;CAE3C,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA,QAAQ,WAAW,IAClB,qBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,oBAAC,MAAD;KAAM,MAAK;KAAmB,MAAM;KAAI,WAAU;IAAiB,CAAA,GACnE,oBAAC,KAAD;KAAG,WAAU;KAAyB,UAAA,EAAE,qBAAqB;IAAK,CAAA,CAC/D;GAEL,CAAA,IAAA,oBAAC,MAAD;IAAI,WAAU;IACX,UAAA,QAAQ,KAAK,SACZ,oBAAC,MAAD,EAAA,UACE,qBAAC,OAAD;KACE,MAAK;KACL,UAAU;KACV,eAAe,KAAK,UAAU,IAAI,CAAC,KAAK,GAAG,CAAC;KAC5C,YAAY,UAAU,MAAM,QAAQ,WAAW,KAAK,UAAU,IAAI,CAAC,KAAK,GAAG,CAAC;KAC5E,WAAU;KALZ,UAAA;MAOE,oBAAC,MAAD;OACE,MAAM,KAAK,SAAS,SAAS,eAAe;OAC5C,MAAM;OACN,WAAU;MACX,CAAA;MACD,oBAAC,QAAD;OAAM,WAAU;OACb,UAAA,KAAK,eACJ,EAAE,KAAK,SAAS,SAAS,uBAAuB,oBAAoB;MAClE,CAAA;MACN,oBAAC,QAAD;OAAM,WAAU;OACb,UAAA,EAAE,kBAAkB,EACnB,QAAQ,EAAE,MAAM,KAAK,aAAa,IAAI,OAAO,KAAK,YAAY,CAAC,IAAI,IAAI,EACzE,CAAC;MACG,CAAA;MACN,oBAAC,UAAD;OACE,MAAK;OACL,UAAU,UAAU;QAClB,MAAM,gBAAgB;QACtB,KAAU,OAAO,KAAK,GAAG;OAC3B;OACA,WAAU;OACV,OAAO,EAAE,sBAAsB;OAE/B,UAAA,oBAAC,MAAD;QAAM,MAAK;QAAQ,MAAM;OAAK,CAAA;MACxB,CAAA;KACL;IACH,CAAA,EAAA,GAlCK,cAAc,KAAK,GAAG,CAkC3B,CACL;GACC,CAAA;EAEH,CAAA,GACL,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACE,oBAAC,UAAD;IACE,MAAK;IACL,UAAU,QAAQ,WAAW;IAC7B,eAAe;KACb,KAAK,MAAM,QAAQ,SAAS,KAAU,OAAO,KAAK,GAAG;IACvD;IACA,WAAU;IAET,UAAA,EAAE,0BAA0B;GACvB,CAAA,GACR,oBAAC,UAAD;IACE,MAAK;IACL,UAAU,QAAQ,WAAW,KAAK,CAAC,UAAU,SAAS,KAAK;IAC3D,eAAe,QAAQ,KAAK;IAC5B,WAAU;IAET,UAAA,EAAE,0BAA0B;GACvB,CAAA,CACL;EACF,CAAA,CAAA;;AAET"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
const require_icons = require("./icons-
|
|
1
|
+
const require_icons = require("./icons-1UfLUZ_y.cjs");
|
|
2
2
|
let _embedpdf_react_runtime = require("@embedpdf/react/runtime");
|
|
3
3
|
let _embedpdf_react_annotation = require("@embedpdf/react/annotation");
|
|
4
4
|
let _embedpdf_react_redaction = require("@embedpdf/react/redaction");
|
|
@@ -93,4 +93,4 @@ function RedactionPanel() {
|
|
|
93
93
|
//#endregion
|
|
94
94
|
exports.RedactionPanel = RedactionPanel;
|
|
95
95
|
|
|
96
|
-
//# sourceMappingURL=redaction-panel-
|
|
96
|
+
//# sourceMappingURL=redaction-panel-ZhX0dlMi.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"redaction-panel-
|
|
1
|
+
{"version":3,"file":"redaction-panel-ZhX0dlMi.cjs","names":["AnnotationToken","Icon"],"sources":["../src/ui/redaction-panel.tsx"],"sourcesContent":["import { useCapability } from '@embedpdf/react/runtime';\nimport { AnnotationToken } from '@embedpdf/react/annotation';\nimport { annotationKey } from '@embedpdf/react/annotation';\nimport { usePendingRedactions, useRedaction, useRedactionState } from '@embedpdf/react/redaction';\nimport { useSurface } from '@embedpdf/react/shell';\nimport { useT } from '@embedpdf/react/i18n';\nimport { Icon } from './icons';\n\n/**\n * The pending-redactions review panel (right sidebar). The list is a live view\n * over the annotation plane — deleting a mark here is deleting the annotation.\n * \"Apply all\" routes through the confirm modal: the apply is irreversible.\n */\nexport function RedactionPanel() {\n const t = useT();\n const redaction = useRedaction();\n const applying = useRedactionState((state) => state.applying);\n const pending = usePendingRedactions();\n const anno = useCapability(AnnotationToken);\n const confirm = useSurface('redact-confirm');\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"min-h-0 flex-1 overflow-y-auto p-2\">\n {pending.length === 0 ? (\n <div className=\"flex flex-col items-center gap-3 px-4 py-10 text-center\">\n <Icon name=\"redactionSidebar\" size={32} className=\"text-fg-muted\" />\n <p className=\"text-fg-muted text-sm\">{t('demo.redactionEmpty')}</p>\n </div>\n ) : (\n <ul className=\"flex flex-col gap-1\">\n {pending.map((item) => (\n <li key={annotationKey(item.ref)}>\n <div\n role=\"button\"\n tabIndex={0}\n onClick={() => anno.selection.set([item.ref])}\n onKeyDown={(event) => event.key === 'Enter' && anno.selection.set([item.ref])}\n className=\"hover:bg-hover group flex w-full cursor-pointer items-center gap-2 rounded-md px-2 py-1.5 text-start\"\n >\n <Icon\n name={item.kind === 'area' ? 'redactArea' : 'redact'}\n size={16}\n className=\"text-fg-muted shrink-0\"\n />\n <span className=\"text-fg min-w-0 flex-1 truncate text-sm\">\n {item.overlayText ??\n t(item.kind === 'area' ? 'demo.redactionArea' : 'demo.redactionText')}\n </span>\n <span className=\"text-fg-muted shrink-0 text-xs\">\n {t('demo.pageBadge', {\n params: { page: item.pageIndex >= 0 ? String(item.pageIndex + 1) : '?' },\n })}\n </span>\n <button\n type=\"button\"\n onClick={(event) => {\n event.stopPropagation();\n void anno.delete(item.ref);\n }}\n className=\"text-fg-muted hover:text-fg grid h-6 w-6 shrink-0 place-items-center rounded opacity-0 group-hover:opacity-100\"\n title={t('demo.redactionRemove')}\n >\n <Icon name=\"trash\" size={14} />\n </button>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n <div className=\"border-border-subtle flex shrink-0 gap-2 border-t p-3\">\n <button\n type=\"button\"\n disabled={pending.length === 0}\n onClick={() => {\n for (const item of pending) void anno.delete(item.ref);\n }}\n className=\"border-border text-fg hover:bg-hover flex-1 rounded-md border px-3 py-1.5 text-sm disabled:opacity-40\"\n >\n {t('commands.redact.clearAll')}\n </button>\n <button\n type=\"button\"\n disabled={pending.length === 0 || !redaction.canApply() || applying}\n onClick={() => confirm.open()}\n className=\"flex-1 rounded-md bg-red-600 px-3 py-1.5 text-sm text-white hover:bg-red-700 disabled:opacity-40\"\n >\n {t('commands.redact.applyAll')}\n </button>\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { n as Icon } from "./icons-
|
|
2
|
-
import { r as buttonClass } from "./toolbar-
|
|
3
|
-
import { i as useCloseOnPick } from "./sheet-
|
|
1
|
+
import { n as Icon } from "./icons-7dB0Y1ct.js";
|
|
2
|
+
import { r as buttonClass } from "./toolbar-DF361xWY.js";
|
|
3
|
+
import { i as useCloseOnPick } from "./sheet-DyjKfAq0.js";
|
|
4
4
|
import { useEffect, useMemo, useRef, useState } from "react";
|
|
5
5
|
import { useSearch, useSearchHits, useSearchState, validateSearchQuery } from "@embedpdf/react/search";
|
|
6
6
|
import { useT } from "@embedpdf/react/i18n";
|
|
@@ -246,4 +246,4 @@ function SearchPanel() {
|
|
|
246
246
|
//#endregion
|
|
247
247
|
export { SearchPanel };
|
|
248
248
|
|
|
249
|
-
//# sourceMappingURL=search-panel-
|
|
249
|
+
//# sourceMappingURL=search-panel-BE4xzWlm.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-panel-HfIhJm1M.js","names":[],"sources":["../src/ui/search-panel.tsx"],"sourcesContent":["/**\n * The search panel — the search sidebar on the plugin-search capability. One\n * shape end to end: the flat `SearchQuery` {text, regex, matchCase, wholeWord}\n * is what the engine matches, what the plugin stores (document-scoped,\n * survives the sidebar closing), and what this box renders.\n * The panel keeps only a draft of it for keystroke/debounce echo.\n *\n * Data flow:\n * type / toggle → validateSearchQuery → (debounced) search(draftQuery)\n * useSearchState() → query / status / hitCount / activeHitIndex (reactive)\n * useSearchHits() → the streamed hit list\n * click a hit / prev / next → goTo/prev/next (capability reveals it on-page)\n *\n * The look: a magnifier input with a clear button, option checkboxes, a\n * results-found counter with prev/next, and a per-page grouped snippet list\n * with the match bolded and the active hit accented, in this app's semantic\n * tokens. matchDiacritics exists in the engine but is deliberately not\n * exposed here.\n */\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSearch,\n useSearchHits,\n useSearchState,\n validateSearchQuery,\n} from '@embedpdf/react/search';\nimport type { SearchHit, SearchQuery, SearchSnippet } from '@embedpdf/react/search';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useSurfaceFocus } from '@embedpdf/react/shell';\nimport { Icon } from './icons';\nimport { useCloseOnPick } from './panel-frame';\nimport { buttonClass } from './toolbar';\n\nconst DEBOUNCE_MS = 300;\n\n/** Field-wise equality on the flat query — the mount/echo no-op guard. */\nconst sameQuery = (left: SearchQuery | null, right: SearchQuery) =>\n left != null &&\n left.text === right.text &&\n !!left.regex === !!right.regex &&\n !!left.matchCase === !!right.matchCase &&\n !!left.wholeWord === !!right.wholeWord;\n\n// ── option checkbox (a peer-checked custom box) ───────────────────────────────\nfunction Checkbox({\n label,\n checked,\n onChange,\n}: {\n label: string;\n checked: boolean;\n onChange: (checked: boolean) => void;\n}) {\n return (\n <label className=\"text-fg-secondary flex cursor-pointer select-none items-center gap-2 text-xs font-medium\">\n <span className=\"relative flex h-4 w-4 items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(event) => onChange(event.target.checked)}\n className=\"border-border bg-surface checked:border-accent checked:bg-accent rounded-xs peer h-4 w-4 shrink-0 appearance-none border transition-colors\"\n />\n <svg\n viewBox=\"0 0 24 24\"\n className=\"text-on-accent pointer-events-none absolute h-3 w-3 opacity-0 peer-checked:opacity-100\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </span>\n {label}\n </label>\n );\n}\n\n// ── one result row: a snippet with the match bolded, active = accented ───────\nfunction renderSnippet(snippet: SearchSnippet | undefined) {\n if (!snippet) return null;\n return (\n <>\n {snippet.before}\n <span className=\"text-accent font-semibold\">{snippet.match}</span>\n {snippet.after}\n </>\n );\n}\n\nfunction HitLine({\n hit,\n active,\n onClick,\n}: {\n hit: SearchHit;\n active: boolean;\n onClick: () => void;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n // Keep the active hit visible as prev/next walks the list.\n useEffect(() => {\n if (active) ref.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, [active]);\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={`w-full rounded border p-2 text-left text-sm transition-colors ${\n active\n ? 'border-accent bg-accent-light text-fg'\n : 'border-border-subtle bg-surface text-fg-secondary hover:bg-hover'\n }`}\n >\n <span>{renderSnippet(hit.snippet)}</span>\n </button>\n );\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nexport function SearchPanel() {\n const t = useT();\n const search = useSearch();\n const { query, status, hitCount, activeHitIndex } = useSearchState();\n const hits = useSearchHits();\n // A sheet or an overlay closes once a match is picked, so you see it on its page.\n const closeOnPick = useCloseOnPick();\n\n // `query` is the document-scoped stored search (survives the sidebar\n // closing). The box is a controlled draft that starts from it; the panel is\n // keyed on the document (see panels.tsx), so this one-time seed is always\n // the right document's query — switching tabs remounts and reseeds.\n const [draft, setDraft] = useState(() => query?.text ?? '');\n const [matchCase, setMatchCase] = useState(() => query?.matchCase ?? false);\n const [wholeWord, setWholeWord] = useState(() => query?.wholeWord ?? false);\n const [regex, setRegex] = useState(() => query?.regex ?? false);\n const inputRef = useRef<HTMLInputElement>(null);\n // Find and the Search button ask for the cursor: it goes in the field, the text selected.\n useSurfaceFocus('search', inputRef, { select: true });\n\n // The draft is a SearchQuery — same shape the engine matches on.\n const draftQuery: SearchQuery = { text: draft, regex, matchCase, wholeWord };\n // Early feedback on keystroke: the same validator the engine enforces\n // (regex dialect). Invalid patterns never fire a query.\n const validation = draft && regex ? validateSearchQuery(draftQuery) : { ok: true as const };\n\n // Debounced query. The sameQuery guard makes the mount pass (and our own\n // echo coming back through state) a no-op — nothing re-runs until the user\n // actually changes the text or a toggle. Clearing the box clears results.\n useEffect(() => {\n // No-ops: invalid pattern, draft already the stored query (mount pass /\n // our own echo), or an empty box with nothing stored to clear.\n if (!validation.ok || sameQuery(query, draftQuery)) return;\n if (draft === '' && query === null) return;\n const id = setTimeout(() => search.search(draftQuery), DEBOUNCE_MS);\n return () => clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [draft, matchCase, wholeWord, regex, query, validation.ok, search]);\n\n // Group hits by page, preserving page order, for the sectioned list.\n const grouped = useMemo(() => {\n const map = new Map<number, { hit: SearchHit; index: number }[]>();\n hits.forEach((hit, index) => {\n const arr = map.get(hit.pageIndex);\n if (arr) arr.push({ hit, index });\n else map.set(hit.pageIndex, [{ hit, index }]);\n });\n return [...map.entries()].sort((left, right) => left[0] - right[0]);\n }, [hits]);\n\n const searching = status === 'searching';\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"p-3\">\n {/* input: magnifier + clear */}\n <div className=\"relative\">\n <div className=\"text-fg-muted pointer-events-none absolute inset-y-0 start-0 flex items-center ps-2.5\">\n <Icon name=\"search\" size={16} />\n </div>\n <input\n ref={inputRef}\n type=\"text\"\n value={draft}\n placeholder={t('demo.searchPlaceholder')}\n onChange={(event) => setDraft(event.target.value)}\n className={`bg-surface text-fg w-full rounded-md border py-1.5 pe-9 ps-8 text-sm outline-none focus:ring-1 ${\n validation.ok\n ? 'border-border focus:border-accent focus:ring-accent'\n : 'border-red-400 focus:border-red-400 focus:ring-red-400'\n }`}\n />\n {draft && (\n <button\n type=\"button\"\n onClick={() => {\n setDraft('');\n inputRef.current?.focus();\n }}\n className=\"text-fg-muted hover:text-fg-secondary absolute inset-y-0 end-0 flex items-center pe-2.5\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n )}\n </div>\n\n {/* the invalid-pattern message, straight from the shared validator */}\n {!validation.ok && <p className=\"mt-1.5 text-xs text-red-500\">{validation.message}</p>}\n\n {/* options — the three VS Code toggles, all composable */}\n <div className=\"mt-3 flex flex-col gap-2\">\n <Checkbox\n label={t('demo.searchCaseSensitive')}\n checked={matchCase}\n onChange={setMatchCase}\n />\n <Checkbox label={t('demo.searchWholeWord')} checked={wholeWord} onChange={setWholeWord} />\n <Checkbox label={t('demo.searchRegex')} checked={regex} onChange={setRegex} />\n </div>\n\n <hr className=\"border-border-subtle mb-2 mt-4\" />\n\n {/* results counter + prev/next */}\n {status !== 'idle' && (\n <div className=\"flex h-8 items-center justify-between\">\n <div className=\"text-fg-muted text-xs\">\n {hitCount === 0\n ? t(searching ? 'demo.searchSearching' : 'demo.searchNoResults')\n : t('demo.searchResults', { params: { count: hitCount } })}\n </div>\n {hitCount > 1 && (\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n title={t('demo.searchPrevious')}\n className={buttonClass(false)}\n onClick={() => search.previousHit()}\n >\n <Icon name=\"chevronLeft\" size={20} className=\"rtl:-scale-x-100\" />\n </button>\n <button\n type=\"button\"\n title={t('demo.searchNext')}\n className={buttonClass(false)}\n onClick={() => search.nextHit()}\n >\n <Icon name=\"chevronRight\" size={20} className=\"rtl:-scale-x-100\" />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* per-page grouped results */}\n <div className=\"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto px-3 pb-3\">\n {grouped.map(([pageIndex, items]) => (\n <div key={pageIndex} className=\"mt-2 first:mt-0\">\n <div className=\"bg-surface/80 text-fg-muted py-2 text-xs backdrop-blur\">\n {t('demo.searchPage', { params: { page: pageIndex + 1 } })}\n </div>\n <div className=\"flex flex-col gap-2\">\n {items.map(({ hit, index }) => (\n <HitLine\n key={index}\n hit={hit}\n active={index === activeHitIndex}\n onClick={() => {\n search.goToHit(index);\n closeOnPick();\n }}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"search-panel-BE4xzWlm.js","names":[],"sources":["../src/ui/search-panel.tsx"],"sourcesContent":["/**\n * The search panel — the search sidebar on the plugin-search capability. One\n * shape end to end: the flat `SearchQuery` {text, regex, matchCase, wholeWord}\n * is what the engine matches, what the plugin stores (document-scoped,\n * survives the sidebar closing), and what this box renders.\n * The panel keeps only a draft of it for keystroke/debounce echo.\n *\n * Data flow:\n * type / toggle → validateSearchQuery → (debounced) search(draftQuery)\n * useSearchState() → query / status / hitCount / activeHitIndex (reactive)\n * useSearchHits() → the streamed hit list\n * click a hit / prev / next → goTo/prev/next (capability reveals it on-page)\n *\n * The look: a magnifier input with a clear button, option checkboxes, a\n * results-found counter with prev/next, and a per-page grouped snippet list\n * with the match bolded and the active hit accented, in this app's semantic\n * tokens. matchDiacritics exists in the engine but is deliberately not\n * exposed here.\n */\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSearch,\n useSearchHits,\n useSearchState,\n validateSearchQuery,\n} from '@embedpdf/react/search';\nimport type { SearchHit, SearchQuery, SearchSnippet } from '@embedpdf/react/search';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useSurfaceFocus } from '@embedpdf/react/shell';\nimport { Icon } from './icons';\nimport { useCloseOnPick } from './panel-frame';\nimport { buttonClass } from './toolbar';\n\nconst DEBOUNCE_MS = 300;\n\n/** Field-wise equality on the flat query — the mount/echo no-op guard. */\nconst sameQuery = (left: SearchQuery | null, right: SearchQuery) =>\n left != null &&\n left.text === right.text &&\n !!left.regex === !!right.regex &&\n !!left.matchCase === !!right.matchCase &&\n !!left.wholeWord === !!right.wholeWord;\n\n// ── option checkbox (a peer-checked custom box) ───────────────────────────────\nfunction Checkbox({\n label,\n checked,\n onChange,\n}: {\n label: string;\n checked: boolean;\n onChange: (checked: boolean) => void;\n}) {\n return (\n <label className=\"text-fg-secondary flex cursor-pointer select-none items-center gap-2 text-xs font-medium\">\n <span className=\"relative flex h-4 w-4 items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(event) => onChange(event.target.checked)}\n className=\"border-border bg-surface checked:border-accent checked:bg-accent rounded-xs peer h-4 w-4 shrink-0 appearance-none border transition-colors\"\n />\n <svg\n viewBox=\"0 0 24 24\"\n className=\"text-on-accent pointer-events-none absolute h-3 w-3 opacity-0 peer-checked:opacity-100\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </span>\n {label}\n </label>\n );\n}\n\n// ── one result row: a snippet with the match bolded, active = accented ───────\nfunction renderSnippet(snippet: SearchSnippet | undefined) {\n if (!snippet) return null;\n return (\n <>\n {snippet.before}\n <span className=\"text-accent font-semibold\">{snippet.match}</span>\n {snippet.after}\n </>\n );\n}\n\nfunction HitLine({\n hit,\n active,\n onClick,\n}: {\n hit: SearchHit;\n active: boolean;\n onClick: () => void;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n // Keep the active hit visible as prev/next walks the list.\n useEffect(() => {\n if (active) ref.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, [active]);\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={`w-full rounded border p-2 text-left text-sm transition-colors ${\n active\n ? 'border-accent bg-accent-light text-fg'\n : 'border-border-subtle bg-surface text-fg-secondary hover:bg-hover'\n }`}\n >\n <span>{renderSnippet(hit.snippet)}</span>\n </button>\n );\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nexport function SearchPanel() {\n const t = useT();\n const search = useSearch();\n const { query, status, hitCount, activeHitIndex } = useSearchState();\n const hits = useSearchHits();\n // A sheet or an overlay closes once a match is picked, so you see it on its page.\n const closeOnPick = useCloseOnPick();\n\n // `query` is the document-scoped stored search (survives the sidebar\n // closing). The box is a controlled draft that starts from it; the panel is\n // keyed on the document (see panels.tsx), so this one-time seed is always\n // the right document's query — switching tabs remounts and reseeds.\n const [draft, setDraft] = useState(() => query?.text ?? '');\n const [matchCase, setMatchCase] = useState(() => query?.matchCase ?? false);\n const [wholeWord, setWholeWord] = useState(() => query?.wholeWord ?? false);\n const [regex, setRegex] = useState(() => query?.regex ?? false);\n const inputRef = useRef<HTMLInputElement>(null);\n // Find and the Search button ask for the cursor: it goes in the field, the text selected.\n useSurfaceFocus('search', inputRef, { select: true });\n\n // The draft is a SearchQuery — same shape the engine matches on.\n const draftQuery: SearchQuery = { text: draft, regex, matchCase, wholeWord };\n // Early feedback on keystroke: the same validator the engine enforces\n // (regex dialect). Invalid patterns never fire a query.\n const validation = draft && regex ? validateSearchQuery(draftQuery) : { ok: true as const };\n\n // Debounced query. The sameQuery guard makes the mount pass (and our own\n // echo coming back through state) a no-op — nothing re-runs until the user\n // actually changes the text or a toggle. Clearing the box clears results.\n useEffect(() => {\n // No-ops: invalid pattern, draft already the stored query (mount pass /\n // our own echo), or an empty box with nothing stored to clear.\n if (!validation.ok || sameQuery(query, draftQuery)) return;\n if (draft === '' && query === null) return;\n const id = setTimeout(() => search.search(draftQuery), DEBOUNCE_MS);\n return () => clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [draft, matchCase, wholeWord, regex, query, validation.ok, search]);\n\n // Group hits by page, preserving page order, for the sectioned list.\n const grouped = useMemo(() => {\n const map = new Map<number, { hit: SearchHit; index: number }[]>();\n hits.forEach((hit, index) => {\n const arr = map.get(hit.pageIndex);\n if (arr) arr.push({ hit, index });\n else map.set(hit.pageIndex, [{ hit, index }]);\n });\n return [...map.entries()].sort((left, right) => left[0] - right[0]);\n }, [hits]);\n\n const searching = status === 'searching';\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"p-3\">\n {/* input: magnifier + clear */}\n <div className=\"relative\">\n <div className=\"text-fg-muted pointer-events-none absolute inset-y-0 start-0 flex items-center ps-2.5\">\n <Icon name=\"search\" size={16} />\n </div>\n <input\n ref={inputRef}\n type=\"text\"\n value={draft}\n placeholder={t('demo.searchPlaceholder')}\n onChange={(event) => setDraft(event.target.value)}\n className={`bg-surface text-fg w-full rounded-md border py-1.5 pe-9 ps-8 text-sm outline-none focus:ring-1 ${\n validation.ok\n ? 'border-border focus:border-accent focus:ring-accent'\n : 'border-red-400 focus:border-red-400 focus:ring-red-400'\n }`}\n />\n {draft && (\n <button\n type=\"button\"\n onClick={() => {\n setDraft('');\n inputRef.current?.focus();\n }}\n className=\"text-fg-muted hover:text-fg-secondary absolute inset-y-0 end-0 flex items-center pe-2.5\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n )}\n </div>\n\n {/* the invalid-pattern message, straight from the shared validator */}\n {!validation.ok && <p className=\"mt-1.5 text-xs text-red-500\">{validation.message}</p>}\n\n {/* options — the three VS Code toggles, all composable */}\n <div className=\"mt-3 flex flex-col gap-2\">\n <Checkbox\n label={t('demo.searchCaseSensitive')}\n checked={matchCase}\n onChange={setMatchCase}\n />\n <Checkbox label={t('demo.searchWholeWord')} checked={wholeWord} onChange={setWholeWord} />\n <Checkbox label={t('demo.searchRegex')} checked={regex} onChange={setRegex} />\n </div>\n\n <hr className=\"border-border-subtle mb-2 mt-4\" />\n\n {/* results counter + prev/next */}\n {status !== 'idle' && (\n <div className=\"flex h-8 items-center justify-between\">\n <div className=\"text-fg-muted text-xs\">\n {hitCount === 0\n ? t(searching ? 'demo.searchSearching' : 'demo.searchNoResults')\n : t('demo.searchResults', { params: { count: hitCount } })}\n </div>\n {hitCount > 1 && (\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n title={t('demo.searchPrevious')}\n className={buttonClass(false)}\n onClick={() => search.previousHit()}\n >\n <Icon name=\"chevronLeft\" size={20} className=\"rtl:-scale-x-100\" />\n </button>\n <button\n type=\"button\"\n title={t('demo.searchNext')}\n className={buttonClass(false)}\n onClick={() => search.nextHit()}\n >\n <Icon name=\"chevronRight\" size={20} className=\"rtl:-scale-x-100\" />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* per-page grouped results */}\n <div className=\"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto px-3 pb-3\">\n {grouped.map(([pageIndex, items]) => (\n <div key={pageIndex} className=\"mt-2 first:mt-0\">\n <div className=\"bg-surface/80 text-fg-muted py-2 text-xs backdrop-blur\">\n {t('demo.searchPage', { params: { page: pageIndex + 1 } })}\n </div>\n <div className=\"flex flex-col gap-2\">\n {items.map(({ hit, index }) => (\n <HitLine\n key={index}\n hit={hit}\n active={index === activeHitIndex}\n onClick={() => {\n search.goToHit(index);\n closeOnPick();\n }}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,MAAM,cAAc;;AAGpB,MAAM,aAAa,MAA0B,UAC3C,QAAQ,QACR,KAAK,SAAS,MAAM,QACpB,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,MAAM,SACzB,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,MAAM,aAC7B,CAAC,CAAC,KAAK,cAAc,CAAC,CAAC,MAAM;AAG/B,SAAS,SAAS,EAChB,OACA,SACA,YAKC;CACD,OACE,qBAAC,SAAD;EAAO,WAAU;EAAjB,UAAA,CACE,qBAAC,QAAD;GAAM,WAAU;GAAhB,UAAA,CACE,oBAAC,SAAD;IACE,MAAK;IACI;IACT,WAAW,UAAU,SAAS,MAAM,OAAO,OAAO;IAClD,WAAU;GACX,CAAA,GACD,oBAAC,OAAD;IACE,SAAQ;IACR,WAAU;IACV,MAAK;IACL,QAAO;IACP,aAAa;IACb,eAAc;IACd,gBAAe;IAEf,UAAA,oBAAC,YAAD,EAAU,QAAO,iBAAkB,CAAA;GAChC,CAAA,CACD;EACL,CAAA,GAAA,KACI;;AAEX;AAGA,SAAS,cAAc,SAAoC;CACzD,IAAI,CAAC,SAAS,OAAO;CACrB,OACE,qBAAA,YAAA,EAAA,UAAA;EACG,QAAQ;EACT,oBAAC,QAAD;GAAM,WAAU;GAA6B,UAAA,QAAQ;EAAY,CAAA;EAChE,QAAQ;CACT,EAAA,CAAA;AAEN;AAEA,SAAS,QAAQ,EACf,KACA,QACA,WAKC;CACD,MAAM,MAAM,OAA0B,IAAI;CAE1C,gBAAgB;EACd,IAAI,QAAQ,IAAI,SAAS,eAAe;GAAE,UAAU;GAAU,OAAO;EAAU,CAAC;CAClF,GAAG,CAAC,MAAM,CAAC;CACX,OACE,oBAAC,UAAD;EACO;EACL,MAAK;EACI;EACT,WAAW,iEACT,SACI,0CACA;EAGN,UAAA,oBAAC,QAAD,EAAA,UAAO,cAAc,IAAI,OAAO,EAAQ,CAAA;CAClC,CAAA;AAEZ;AAGA,SAAgB,cAAc;CAC5B,MAAM,IAAI,KAAK;CACf,MAAM,SAAS,UAAU;CACzB,MAAM,EAAE,OAAO,QAAQ,UAAU,mBAAmB,eAAe;CACnE,MAAM,OAAO,cAAc;CAE3B,MAAM,cAAc,eAAe;CAMnC,MAAM,CAAC,OAAO,YAAY,eAAe,OAAO,QAAQ,EAAE;CAC1D,MAAM,CAAC,WAAW,gBAAgB,eAAe,OAAO,aAAa,KAAK;CAC1E,MAAM,CAAC,WAAW,gBAAgB,eAAe,OAAO,aAAa,KAAK;CAC1E,MAAM,CAAC,OAAO,YAAY,eAAe,OAAO,SAAS,KAAK;CAC9D,MAAM,WAAW,OAAyB,IAAI;CAE9C,gBAAgB,UAAU,UAAU,EAAE,QAAQ,KAAK,CAAC;CAGpD,MAAM,aAA0B;EAAE,MAAM;EAAO;EAAO;EAAW;CAAU;CAG3E,MAAM,aAAa,SAAS,QAAQ,oBAAoB,UAAU,IAAI,EAAE,IAAI,KAAc;CAK1F,gBAAgB;EAGd,IAAI,CAAC,WAAW,MAAM,UAAU,OAAO,UAAU,GAAG;EACpD,IAAI,UAAU,MAAM,UAAU,MAAM;EACpC,MAAM,KAAK,iBAAiB,OAAO,OAAO,UAAU,GAAG,WAAW;EAClE,aAAa,aAAa,EAAE;CAE9B,GAAG;EAAC;EAAO;EAAW;EAAW;EAAO;EAAO,WAAW;EAAI;CAAM,CAAC;CAGrE,MAAM,UAAU,cAAc;EAC5B,MAAM,sBAAM,IAAI,IAAiD;EACjE,KAAK,SAAS,KAAK,UAAU;GAC3B,MAAM,MAAM,IAAI,IAAI,IAAI,SAAS;GACjC,IAAI,KAAK,IAAI,KAAK;IAAE;IAAK;GAAM,CAAC;QAC3B,IAAI,IAAI,IAAI,WAAW,CAAC;IAAE;IAAK;GAAM,CAAC,CAAC;EAC9C,CAAC;EACD,OAAO,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,MAAM,UAAU,KAAK,KAAK,MAAM,EAAE;CACpE,GAAG,CAAC,IAAI,CAAC;CAET,MAAM,YAAY,WAAW;CAE7B,OACE,qBAAC,OAAD;EAAK,WAAU;EAAf,UAAA,CACE,qBAAC,OAAD;GAAK,WAAU;GAAf,UAAA;IAEE,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,oBAAC,OAAD;OAAK,WAAU;OACb,UAAA,oBAAC,MAAD;QAAM,MAAK;QAAS,MAAM;OAAK,CAAA;MAC5B,CAAA;MACL,oBAAC,SAAD;OACE,KAAK;OACL,MAAK;OACL,OAAO;OACP,aAAa,EAAE,wBAAwB;OACvC,WAAW,UAAU,SAAS,MAAM,OAAO,KAAK;OAChD,WAAW,kGACT,WAAW,KACP,wDACA;MAEP,CAAA;MACA,SACC,oBAAC,UAAD;OACE,MAAK;OACL,eAAe;QACb,SAAS,EAAE;QACX,SAAS,SAAS,MAAM;OAC1B;OACA,WAAU;OAEV,UAAA,oBAAC,MAAD;QAAM,MAAK;QAAI,MAAM;OAAK,CAAA;MACpB,CAAA;KAEP;;IAGJ,CAAC,WAAW,MAAM,oBAAC,KAAD;KAAG,WAAU;KAA+B,UAAA,WAAW;IAAW,CAAA;IAGrF,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,oBAAC,UAAD;OACE,OAAO,EAAE,0BAA0B;OACnC,SAAS;OACT,UAAU;MACX,CAAA;MACD,oBAAC,UAAD;OAAU,OAAO,EAAE,sBAAsB;OAAG,SAAS;OAAW,UAAU;MAAe,CAAA;MACzF,oBAAC,UAAD;OAAU,OAAO,EAAE,kBAAkB;OAAG,SAAS;OAAO,UAAU;MAAW,CAAA;KAC1E;;IAEL,oBAAC,MAAD,EAAI,WAAU,iCAAkC,CAAA;IAG/C,WAAW,UACV,qBAAC,OAAD;KAAK,WAAU;KAAf,UAAA,CACE,oBAAC,OAAD;MAAK,WAAU;MACZ,UAAA,aAAa,IACV,EAAE,YAAY,yBAAyB,sBAAsB,IAC7D,EAAE,sBAAsB,EAAE,QAAQ,EAAE,OAAO,SAAS,EAAE,CAAC;KACxD,CAAA,GACJ,WAAW,KACV,qBAAC,OAAD;MAAK,WAAU;MAAf,UAAA,CACE,oBAAC,UAAD;OACE,MAAK;OACL,OAAO,EAAE,qBAAqB;OAC9B,WAAW,YAAY,KAAK;OAC5B,eAAe,OAAO,YAAY;OAElC,UAAA,oBAAC,MAAD;QAAM,MAAK;QAAc,MAAM;QAAI,WAAU;OAAoB,CAAA;MAC3D,CAAA,GACR,oBAAC,UAAD;OACE,MAAK;OACL,OAAO,EAAE,iBAAiB;OAC1B,WAAW,YAAY,KAAK;OAC5B,eAAe,OAAO,QAAQ;OAE9B,UAAA,oBAAC,MAAD;QAAM,MAAK;QAAe,MAAM;QAAI,WAAU;OAAoB,CAAA;MAC5D,CAAA,CACL;KAEJ,CAAA,CAAA;;GAEJ;EAGL,CAAA,GAAA,oBAAC,OAAD;GAAK,WAAU;GACZ,UAAA,QAAQ,KAAK,CAAC,WAAW,WACxB,qBAAC,OAAD;IAAqB,WAAU;IAA/B,UAAA,CACE,oBAAC,OAAD;KAAK,WAAU;KACZ,UAAA,EAAE,mBAAmB,EAAE,QAAQ,EAAE,MAAM,YAAY,EAAE,EAAE,CAAC;IACtD,CAAA,GACL,oBAAC,OAAD;KAAK,WAAU;KACZ,UAAA,MAAM,KAAK,EAAE,KAAK,YACjB,oBAAC,SAAD;MAEO;MACL,QAAQ,UAAU;MAClB,eAAe;OACb,OAAO,QAAQ,KAAK;OACpB,YAAY;MACd;KACD,GAPM,KAON,CACF;IACE,CAAA,CACF;GAjBK,GAAA,SAiBL,CACN;EACE,CAAA,CACF;;AAET"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
const require_icons = require("./icons-
|
|
2
|
-
const require_toolbar = require("./toolbar-
|
|
3
|
-
const require_sheet = require("./sheet-
|
|
1
|
+
const require_icons = require("./icons-1UfLUZ_y.cjs");
|
|
2
|
+
const require_toolbar = require("./toolbar-ddvpsvTb.cjs");
|
|
3
|
+
const require_sheet = require("./sheet-DTBFiwde.cjs");
|
|
4
4
|
let react = require("react");
|
|
5
5
|
let _embedpdf_react_search = require("@embedpdf/react/search");
|
|
6
6
|
let _embedpdf_react_i18n = require("@embedpdf/react/i18n");
|
|
@@ -246,4 +246,4 @@ function SearchPanel() {
|
|
|
246
246
|
//#endregion
|
|
247
247
|
exports.SearchPanel = SearchPanel;
|
|
248
248
|
|
|
249
|
-
//# sourceMappingURL=search-panel-
|
|
249
|
+
//# sourceMappingURL=search-panel-wcbTNG1z.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"search-panel-s9IoiOtv.cjs","names":["useCloseOnPick","Icon","buttonClass"],"sources":["../src/ui/search-panel.tsx"],"sourcesContent":["/**\n * The search panel — the search sidebar on the plugin-search capability. One\n * shape end to end: the flat `SearchQuery` {text, regex, matchCase, wholeWord}\n * is what the engine matches, what the plugin stores (document-scoped,\n * survives the sidebar closing), and what this box renders.\n * The panel keeps only a draft of it for keystroke/debounce echo.\n *\n * Data flow:\n * type / toggle → validateSearchQuery → (debounced) search(draftQuery)\n * useSearchState() → query / status / hitCount / activeHitIndex (reactive)\n * useSearchHits() → the streamed hit list\n * click a hit / prev / next → goTo/prev/next (capability reveals it on-page)\n *\n * The look: a magnifier input with a clear button, option checkboxes, a\n * results-found counter with prev/next, and a per-page grouped snippet list\n * with the match bolded and the active hit accented, in this app's semantic\n * tokens. matchDiacritics exists in the engine but is deliberately not\n * exposed here.\n */\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSearch,\n useSearchHits,\n useSearchState,\n validateSearchQuery,\n} from '@embedpdf/react/search';\nimport type { SearchHit, SearchQuery, SearchSnippet } from '@embedpdf/react/search';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useSurfaceFocus } from '@embedpdf/react/shell';\nimport { Icon } from './icons';\nimport { useCloseOnPick } from './panel-frame';\nimport { buttonClass } from './toolbar';\n\nconst DEBOUNCE_MS = 300;\n\n/** Field-wise equality on the flat query — the mount/echo no-op guard. */\nconst sameQuery = (left: SearchQuery | null, right: SearchQuery) =>\n left != null &&\n left.text === right.text &&\n !!left.regex === !!right.regex &&\n !!left.matchCase === !!right.matchCase &&\n !!left.wholeWord === !!right.wholeWord;\n\n// ── option checkbox (a peer-checked custom box) ───────────────────────────────\nfunction Checkbox({\n label,\n checked,\n onChange,\n}: {\n label: string;\n checked: boolean;\n onChange: (checked: boolean) => void;\n}) {\n return (\n <label className=\"text-fg-secondary flex cursor-pointer select-none items-center gap-2 text-xs font-medium\">\n <span className=\"relative flex h-4 w-4 items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(event) => onChange(event.target.checked)}\n className=\"border-border bg-surface checked:border-accent checked:bg-accent rounded-xs peer h-4 w-4 shrink-0 appearance-none border transition-colors\"\n />\n <svg\n viewBox=\"0 0 24 24\"\n className=\"text-on-accent pointer-events-none absolute h-3 w-3 opacity-0 peer-checked:opacity-100\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </span>\n {label}\n </label>\n );\n}\n\n// ── one result row: a snippet with the match bolded, active = accented ───────\nfunction renderSnippet(snippet: SearchSnippet | undefined) {\n if (!snippet) return null;\n return (\n <>\n {snippet.before}\n <span className=\"text-accent font-semibold\">{snippet.match}</span>\n {snippet.after}\n </>\n );\n}\n\nfunction HitLine({\n hit,\n active,\n onClick,\n}: {\n hit: SearchHit;\n active: boolean;\n onClick: () => void;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n // Keep the active hit visible as prev/next walks the list.\n useEffect(() => {\n if (active) ref.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, [active]);\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={`w-full rounded border p-2 text-left text-sm transition-colors ${\n active\n ? 'border-accent bg-accent-light text-fg'\n : 'border-border-subtle bg-surface text-fg-secondary hover:bg-hover'\n }`}\n >\n <span>{renderSnippet(hit.snippet)}</span>\n </button>\n );\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nexport function SearchPanel() {\n const t = useT();\n const search = useSearch();\n const { query, status, hitCount, activeHitIndex } = useSearchState();\n const hits = useSearchHits();\n // A sheet or an overlay closes once a match is picked, so you see it on its page.\n const closeOnPick = useCloseOnPick();\n\n // `query` is the document-scoped stored search (survives the sidebar\n // closing). The box is a controlled draft that starts from it; the panel is\n // keyed on the document (see panels.tsx), so this one-time seed is always\n // the right document's query — switching tabs remounts and reseeds.\n const [draft, setDraft] = useState(() => query?.text ?? '');\n const [matchCase, setMatchCase] = useState(() => query?.matchCase ?? false);\n const [wholeWord, setWholeWord] = useState(() => query?.wholeWord ?? false);\n const [regex, setRegex] = useState(() => query?.regex ?? false);\n const inputRef = useRef<HTMLInputElement>(null);\n // Find and the Search button ask for the cursor: it goes in the field, the text selected.\n useSurfaceFocus('search', inputRef, { select: true });\n\n // The draft is a SearchQuery — same shape the engine matches on.\n const draftQuery: SearchQuery = { text: draft, regex, matchCase, wholeWord };\n // Early feedback on keystroke: the same validator the engine enforces\n // (regex dialect). Invalid patterns never fire a query.\n const validation = draft && regex ? validateSearchQuery(draftQuery) : { ok: true as const };\n\n // Debounced query. The sameQuery guard makes the mount pass (and our own\n // echo coming back through state) a no-op — nothing re-runs until the user\n // actually changes the text or a toggle. Clearing the box clears results.\n useEffect(() => {\n // No-ops: invalid pattern, draft already the stored query (mount pass /\n // our own echo), or an empty box with nothing stored to clear.\n if (!validation.ok || sameQuery(query, draftQuery)) return;\n if (draft === '' && query === null) return;\n const id = setTimeout(() => search.search(draftQuery), DEBOUNCE_MS);\n return () => clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [draft, matchCase, wholeWord, regex, query, validation.ok, search]);\n\n // Group hits by page, preserving page order, for the sectioned list.\n const grouped = useMemo(() => {\n const map = new Map<number, { hit: SearchHit; index: number }[]>();\n hits.forEach((hit, index) => {\n const arr = map.get(hit.pageIndex);\n if (arr) arr.push({ hit, index });\n else map.set(hit.pageIndex, [{ hit, index }]);\n });\n return [...map.entries()].sort((left, right) => left[0] - right[0]);\n }, [hits]);\n\n const searching = status === 'searching';\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"p-3\">\n {/* input: magnifier + clear */}\n <div className=\"relative\">\n <div className=\"text-fg-muted pointer-events-none absolute inset-y-0 start-0 flex items-center ps-2.5\">\n <Icon name=\"search\" size={16} />\n </div>\n <input\n ref={inputRef}\n type=\"text\"\n value={draft}\n placeholder={t('demo.searchPlaceholder')}\n onChange={(event) => setDraft(event.target.value)}\n className={`bg-surface text-fg w-full rounded-md border py-1.5 pe-9 ps-8 text-sm outline-none focus:ring-1 ${\n validation.ok\n ? 'border-border focus:border-accent focus:ring-accent'\n : 'border-red-400 focus:border-red-400 focus:ring-red-400'\n }`}\n />\n {draft && (\n <button\n type=\"button\"\n onClick={() => {\n setDraft('');\n inputRef.current?.focus();\n }}\n className=\"text-fg-muted hover:text-fg-secondary absolute inset-y-0 end-0 flex items-center pe-2.5\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n )}\n </div>\n\n {/* the invalid-pattern message, straight from the shared validator */}\n {!validation.ok && <p className=\"mt-1.5 text-xs text-red-500\">{validation.message}</p>}\n\n {/* options — the three VS Code toggles, all composable */}\n <div className=\"mt-3 flex flex-col gap-2\">\n <Checkbox\n label={t('demo.searchCaseSensitive')}\n checked={matchCase}\n onChange={setMatchCase}\n />\n <Checkbox label={t('demo.searchWholeWord')} checked={wholeWord} onChange={setWholeWord} />\n <Checkbox label={t('demo.searchRegex')} checked={regex} onChange={setRegex} />\n </div>\n\n <hr className=\"border-border-subtle mb-2 mt-4\" />\n\n {/* results counter + prev/next */}\n {status !== 'idle' && (\n <div className=\"flex h-8 items-center justify-between\">\n <div className=\"text-fg-muted text-xs\">\n {hitCount === 0\n ? t(searching ? 'demo.searchSearching' : 'demo.searchNoResults')\n : t('demo.searchResults', { params: { count: hitCount } })}\n </div>\n {hitCount > 1 && (\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n title={t('demo.searchPrevious')}\n className={buttonClass(false)}\n onClick={() => search.previousHit()}\n >\n <Icon name=\"chevronLeft\" size={20} className=\"rtl:-scale-x-100\" />\n </button>\n <button\n type=\"button\"\n title={t('demo.searchNext')}\n className={buttonClass(false)}\n onClick={() => search.nextHit()}\n >\n <Icon name=\"chevronRight\" size={20} className=\"rtl:-scale-x-100\" />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* per-page grouped results */}\n <div className=\"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto px-3 pb-3\">\n {grouped.map(([pageIndex, items]) => (\n <div key={pageIndex} className=\"mt-2 first:mt-0\">\n <div className=\"bg-surface/80 text-fg-muted py-2 text-xs backdrop-blur\">\n {t('demo.searchPage', { params: { page: pageIndex + 1 } })}\n </div>\n <div className=\"flex flex-col gap-2\">\n {items.map(({ hit, index }) => (\n <HitLine\n key={index}\n hit={hit}\n active={index === activeHitIndex}\n onClick={() => {\n search.goToHit(index);\n closeOnPick();\n }}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"search-panel-wcbTNG1z.cjs","names":["useCloseOnPick","Icon","buttonClass"],"sources":["../src/ui/search-panel.tsx"],"sourcesContent":["/**\n * The search panel — the search sidebar on the plugin-search capability. One\n * shape end to end: the flat `SearchQuery` {text, regex, matchCase, wholeWord}\n * is what the engine matches, what the plugin stores (document-scoped,\n * survives the sidebar closing), and what this box renders.\n * The panel keeps only a draft of it for keystroke/debounce echo.\n *\n * Data flow:\n * type / toggle → validateSearchQuery → (debounced) search(draftQuery)\n * useSearchState() → query / status / hitCount / activeHitIndex (reactive)\n * useSearchHits() → the streamed hit list\n * click a hit / prev / next → goTo/prev/next (capability reveals it on-page)\n *\n * The look: a magnifier input with a clear button, option checkboxes, a\n * results-found counter with prev/next, and a per-page grouped snippet list\n * with the match bolded and the active hit accented, in this app's semantic\n * tokens. matchDiacritics exists in the engine but is deliberately not\n * exposed here.\n */\nimport { useEffect, useMemo, useRef, useState } from 'react';\nimport {\n useSearch,\n useSearchHits,\n useSearchState,\n validateSearchQuery,\n} from '@embedpdf/react/search';\nimport type { SearchHit, SearchQuery, SearchSnippet } from '@embedpdf/react/search';\nimport { useT } from '@embedpdf/react/i18n';\nimport { useSurfaceFocus } from '@embedpdf/react/shell';\nimport { Icon } from './icons';\nimport { useCloseOnPick } from './panel-frame';\nimport { buttonClass } from './toolbar';\n\nconst DEBOUNCE_MS = 300;\n\n/** Field-wise equality on the flat query — the mount/echo no-op guard. */\nconst sameQuery = (left: SearchQuery | null, right: SearchQuery) =>\n left != null &&\n left.text === right.text &&\n !!left.regex === !!right.regex &&\n !!left.matchCase === !!right.matchCase &&\n !!left.wholeWord === !!right.wholeWord;\n\n// ── option checkbox (a peer-checked custom box) ───────────────────────────────\nfunction Checkbox({\n label,\n checked,\n onChange,\n}: {\n label: string;\n checked: boolean;\n onChange: (checked: boolean) => void;\n}) {\n return (\n <label className=\"text-fg-secondary flex cursor-pointer select-none items-center gap-2 text-xs font-medium\">\n <span className=\"relative flex h-4 w-4 items-center justify-center\">\n <input\n type=\"checkbox\"\n checked={checked}\n onChange={(event) => onChange(event.target.checked)}\n className=\"border-border bg-surface checked:border-accent checked:bg-accent rounded-xs peer h-4 w-4 shrink-0 appearance-none border transition-colors\"\n />\n <svg\n viewBox=\"0 0 24 24\"\n className=\"text-on-accent pointer-events-none absolute h-3 w-3 opacity-0 peer-checked:opacity-100\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={3}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n >\n <polyline points=\"20 6 9 17 4 12\" />\n </svg>\n </span>\n {label}\n </label>\n );\n}\n\n// ── one result row: a snippet with the match bolded, active = accented ───────\nfunction renderSnippet(snippet: SearchSnippet | undefined) {\n if (!snippet) return null;\n return (\n <>\n {snippet.before}\n <span className=\"text-accent font-semibold\">{snippet.match}</span>\n {snippet.after}\n </>\n );\n}\n\nfunction HitLine({\n hit,\n active,\n onClick,\n}: {\n hit: SearchHit;\n active: boolean;\n onClick: () => void;\n}) {\n const ref = useRef<HTMLButtonElement>(null);\n // Keep the active hit visible as prev/next walks the list.\n useEffect(() => {\n if (active) ref.current?.scrollIntoView({ behavior: 'smooth', block: 'nearest' });\n }, [active]);\n return (\n <button\n ref={ref}\n type=\"button\"\n onClick={onClick}\n className={`w-full rounded border p-2 text-left text-sm transition-colors ${\n active\n ? 'border-accent bg-accent-light text-fg'\n : 'border-border-subtle bg-surface text-fg-secondary hover:bg-hover'\n }`}\n >\n <span>{renderSnippet(hit.snippet)}</span>\n </button>\n );\n}\n\n// ── the panel ────────────────────────────────────────────────────────────────\nexport function SearchPanel() {\n const t = useT();\n const search = useSearch();\n const { query, status, hitCount, activeHitIndex } = useSearchState();\n const hits = useSearchHits();\n // A sheet or an overlay closes once a match is picked, so you see it on its page.\n const closeOnPick = useCloseOnPick();\n\n // `query` is the document-scoped stored search (survives the sidebar\n // closing). The box is a controlled draft that starts from it; the panel is\n // keyed on the document (see panels.tsx), so this one-time seed is always\n // the right document's query — switching tabs remounts and reseeds.\n const [draft, setDraft] = useState(() => query?.text ?? '');\n const [matchCase, setMatchCase] = useState(() => query?.matchCase ?? false);\n const [wholeWord, setWholeWord] = useState(() => query?.wholeWord ?? false);\n const [regex, setRegex] = useState(() => query?.regex ?? false);\n const inputRef = useRef<HTMLInputElement>(null);\n // Find and the Search button ask for the cursor: it goes in the field, the text selected.\n useSurfaceFocus('search', inputRef, { select: true });\n\n // The draft is a SearchQuery — same shape the engine matches on.\n const draftQuery: SearchQuery = { text: draft, regex, matchCase, wholeWord };\n // Early feedback on keystroke: the same validator the engine enforces\n // (regex dialect). Invalid patterns never fire a query.\n const validation = draft && regex ? validateSearchQuery(draftQuery) : { ok: true as const };\n\n // Debounced query. The sameQuery guard makes the mount pass (and our own\n // echo coming back through state) a no-op — nothing re-runs until the user\n // actually changes the text or a toggle. Clearing the box clears results.\n useEffect(() => {\n // No-ops: invalid pattern, draft already the stored query (mount pass /\n // our own echo), or an empty box with nothing stored to clear.\n if (!validation.ok || sameQuery(query, draftQuery)) return;\n if (draft === '' && query === null) return;\n const id = setTimeout(() => search.search(draftQuery), DEBOUNCE_MS);\n return () => clearTimeout(id);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [draft, matchCase, wholeWord, regex, query, validation.ok, search]);\n\n // Group hits by page, preserving page order, for the sectioned list.\n const grouped = useMemo(() => {\n const map = new Map<number, { hit: SearchHit; index: number }[]>();\n hits.forEach((hit, index) => {\n const arr = map.get(hit.pageIndex);\n if (arr) arr.push({ hit, index });\n else map.set(hit.pageIndex, [{ hit, index }]);\n });\n return [...map.entries()].sort((left, right) => left[0] - right[0]);\n }, [hits]);\n\n const searching = status === 'searching';\n\n return (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"p-3\">\n {/* input: magnifier + clear */}\n <div className=\"relative\">\n <div className=\"text-fg-muted pointer-events-none absolute inset-y-0 start-0 flex items-center ps-2.5\">\n <Icon name=\"search\" size={16} />\n </div>\n <input\n ref={inputRef}\n type=\"text\"\n value={draft}\n placeholder={t('demo.searchPlaceholder')}\n onChange={(event) => setDraft(event.target.value)}\n className={`bg-surface text-fg w-full rounded-md border py-1.5 pe-9 ps-8 text-sm outline-none focus:ring-1 ${\n validation.ok\n ? 'border-border focus:border-accent focus:ring-accent'\n : 'border-red-400 focus:border-red-400 focus:ring-red-400'\n }`}\n />\n {draft && (\n <button\n type=\"button\"\n onClick={() => {\n setDraft('');\n inputRef.current?.focus();\n }}\n className=\"text-fg-muted hover:text-fg-secondary absolute inset-y-0 end-0 flex items-center pe-2.5\"\n >\n <Icon name=\"x\" size={16} />\n </button>\n )}\n </div>\n\n {/* the invalid-pattern message, straight from the shared validator */}\n {!validation.ok && <p className=\"mt-1.5 text-xs text-red-500\">{validation.message}</p>}\n\n {/* options — the three VS Code toggles, all composable */}\n <div className=\"mt-3 flex flex-col gap-2\">\n <Checkbox\n label={t('demo.searchCaseSensitive')}\n checked={matchCase}\n onChange={setMatchCase}\n />\n <Checkbox label={t('demo.searchWholeWord')} checked={wholeWord} onChange={setWholeWord} />\n <Checkbox label={t('demo.searchRegex')} checked={regex} onChange={setRegex} />\n </div>\n\n <hr className=\"border-border-subtle mb-2 mt-4\" />\n\n {/* results counter + prev/next */}\n {status !== 'idle' && (\n <div className=\"flex h-8 items-center justify-between\">\n <div className=\"text-fg-muted text-xs\">\n {hitCount === 0\n ? t(searching ? 'demo.searchSearching' : 'demo.searchNoResults')\n : t('demo.searchResults', { params: { count: hitCount } })}\n </div>\n {hitCount > 1 && (\n <div className=\"flex items-center\">\n <button\n type=\"button\"\n title={t('demo.searchPrevious')}\n className={buttonClass(false)}\n onClick={() => search.previousHit()}\n >\n <Icon name=\"chevronLeft\" size={20} className=\"rtl:-scale-x-100\" />\n </button>\n <button\n type=\"button\"\n title={t('demo.searchNext')}\n className={buttonClass(false)}\n onClick={() => search.nextHit()}\n >\n <Icon name=\"chevronRight\" size={20} className=\"rtl:-scale-x-100\" />\n </button>\n </div>\n )}\n </div>\n )}\n </div>\n\n {/* per-page grouped results */}\n <div className=\"flex min-h-0 flex-1 flex-col gap-2 overflow-y-auto px-3 pb-3\">\n {grouped.map(([pageIndex, items]) => (\n <div key={pageIndex} className=\"mt-2 first:mt-0\">\n <div className=\"bg-surface/80 text-fg-muted py-2 text-xs backdrop-blur\">\n {t('demo.searchPage', { params: { page: pageIndex + 1 } })}\n </div>\n <div className=\"flex flex-col gap-2\">\n {items.map(({ hit, index }) => (\n <HitLine\n key={index}\n hit={hit}\n active={index === activeHitIndex}\n onClick={() => {\n search.goToHit(index);\n closeOnPick();\n }}\n />\n ))}\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":"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"}
|