diff --git a/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java b/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java index fdbc7015f50..07ebadb1a9f 100644 --- a/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java +++ b/src/main/java/stirling/software/SPDF/config/EndpointConfiguration.java @@ -135,6 +135,7 @@ public void init() { addEndpointToGroup("Security", "remove-cert-sign"); addEndpointToGroup("Security", "sanitize-pdf"); addEndpointToGroup("Security", "auto-redact"); + addEndpointToGroup("Security", "redact"); // Adding endpoints to "Other" group addEndpointToGroup("Other", "ocr-pdf"); @@ -234,6 +235,7 @@ public void init() { addEndpointToGroup("Java", "markdown-to-pdf"); addEndpointToGroup("Java", "show-javascript"); addEndpointToGroup("Java", "auto-redact"); + addEndpointToGroup("Java", "redact"); addEndpointToGroup("Java", "pdf-to-csv"); addEndpointToGroup("Java", "split-by-size-or-count"); addEndpointToGroup("Java", "overlay-pdf"); diff --git a/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java b/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java index b5220454457..d123e2ef8d5 100644 --- a/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java +++ b/src/main/java/stirling/software/SPDF/controller/api/security/RedactController.java @@ -3,13 +3,18 @@ import java.awt.*; import java.io.ByteArrayOutputStream; import java.io.IOException; +import java.util.Collections; import java.util.List; import org.apache.pdfbox.pdmodel.PDDocument; +import org.apache.pdfbox.pdmodel.PDPage; import org.apache.pdfbox.pdmodel.PDPageContentStream; +import org.apache.pdfbox.pdmodel.PDPageTree; import org.apache.pdfbox.pdmodel.common.PDRectangle; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.WebDataBinder; +import org.springframework.web.bind.annotation.InitBinder; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; @@ -21,12 +26,17 @@ import io.swagger.v3.oas.annotations.tags.Tag; import lombok.extern.slf4j.Slf4j; + import stirling.software.SPDF.model.PDFText; +import stirling.software.SPDF.model.api.security.ManualRedactPdfRequest; import stirling.software.SPDF.model.api.security.RedactPdfRequest; +import stirling.software.SPDF.model.api.security.RedactionArea; import stirling.software.SPDF.pdf.TextFinder; import stirling.software.SPDF.service.CustomPDDocumentFactory; +import stirling.software.SPDF.utils.GeneralUtils; import stirling.software.SPDF.utils.PdfUtils; import stirling.software.SPDF.utils.WebResponseUtils; +import stirling.software.SPDF.utils.propertyeditor.StringToArrayListPropertyEditor; @RestController @RequestMapping("/api/v1/security") @@ -41,6 +51,107 @@ public RedactController(CustomPDDocumentFactory pdfDocumentFactory) { this.pdfDocumentFactory = pdfDocumentFactory; } + @InitBinder + public void initBinder(WebDataBinder binder) { + binder.registerCustomEditor(List.class, "redactions", new StringToArrayListPropertyEditor()); + } + + @PostMapping(value = "/redact", consumes = "multipart/form-data") + @Operation(summary = "Redacts areas and pages in a PDF document", description = "This operation takes an input PDF file with a list of areas, page number(s)/range(s)/function(s) to redact. Input:PDF, Output:PDF, Type:SISO") + public ResponseEntity redactPDF(@ModelAttribute ManualRedactPdfRequest request) throws IOException { + MultipartFile file = request.getFileInput(); + List redactionAreas = request.getRedactions(); + + PDDocument document = pdfDocumentFactory.load(file); + + PDPageTree allPages = document.getDocumentCatalog().getPages(); + + redactPages(request, document, allPages); + redactAreas(redactionAreas, document, allPages); + + if (request.isConvertPDFToImage()) { + PDDocument convertedPdf = PdfUtils.convertPdfToPdfImage(document); + document.close(); + document = convertedPdf; + } + + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + document.save(baos); + document.close(); + + byte[] pdfContent = baos.toByteArray(); + return WebResponseUtils.bytesToWebResponse( + pdfContent, + Filenames.toSimpleFileName(file.getOriginalFilename()).replaceFirst("[.][^.]+$", "") + + "_redacted.pdf"); + } + + private void redactAreas(List redactionAreas, PDDocument document, PDPageTree allPages) + throws IOException { + Color redactColor = null; + for (RedactionArea redactionArea : redactionAreas) { + if (redactionArea.getPage() == null || redactionArea.getPage() <= 0 + || redactionArea.getHeight() == null || redactionArea.getHeight() <= 0.0D + || redactionArea.getWidth() == null || redactionArea.getWidth() <= 0.0D) + continue; + PDPage page = allPages.get(redactionArea.getPage() - 1); + + PDPageContentStream contentStream = new PDPageContentStream( + document, page, PDPageContentStream.AppendMode.APPEND, true, true); + redactColor = decodeOrDefault(redactionArea.getColor(), Color.BLACK); + contentStream.setNonStrokingColor(redactColor); + + float x = redactionArea.getX().floatValue(); + float y = redactionArea.getY().floatValue(); + float width = redactionArea.getWidth().floatValue(); + float height = redactionArea.getHeight().floatValue(); + + PDRectangle box = page.getBBox(); + + contentStream.addRect(x, box.getHeight() - y - height, width, height); + contentStream.fill(); + contentStream.close(); + } + } + + private void redactPages(ManualRedactPdfRequest request, PDDocument document, PDPageTree allPages) + throws IOException { + Color redactColor = decodeOrDefault(request.getPageRedactionColor(), Color.BLACK); + List pageNumbers = getPageNumbers(request, allPages.getCount()); + for (Integer pageNumber : pageNumbers) { + PDPage page = allPages.get(pageNumber); + + PDPageContentStream contentStream = new PDPageContentStream( + document, page, PDPageContentStream.AppendMode.APPEND, true, true); + contentStream.setNonStrokingColor(redactColor); + + PDRectangle box = page.getBBox(); + + contentStream.addRect(0, 0, box.getWidth(), box.getHeight()); + contentStream.fill(); + contentStream.close(); + } + } + + private Color decodeOrDefault(String hex, Color defaultColor) { + Color color = null; + try { + color = Color.decode(hex); + } catch (Exception e) { + color = defaultColor; + } + + return color; + } + + private List getPageNumbers(ManualRedactPdfRequest request, int pagesCount) { + String pageNumbersInput = request.getPageNumbers(); + String[] parsedPageNumbers = pageNumbersInput != null ? pageNumbersInput.split(",") : new String[0]; + List pageNumbers = GeneralUtils.parsePageList(parsedPageNumbers, pagesCount, false); + Collections.sort(pageNumbers); + return pageNumbers; + } + @PostMapping(value = "/auto-redact", consumes = "multipart/form-data") @Operation( summary = "Redacts listOfText in a PDF document", diff --git a/src/main/java/stirling/software/SPDF/controller/web/SecurityWebController.java b/src/main/java/stirling/software/SPDF/controller/web/SecurityWebController.java index 5793fa4e974..eb7245e5ad8 100644 --- a/src/main/java/stirling/software/SPDF/controller/web/SecurityWebController.java +++ b/src/main/java/stirling/software/SPDF/controller/web/SecurityWebController.java @@ -18,6 +18,12 @@ public String autoRedactForm(Model model) { return "security/auto-redact"; } + @GetMapping("/redact") + public String redactForm(Model model) { + model.addAttribute("currentPage", "redact"); + return "security/redact"; + } + @GetMapping("/add-password") @Hidden public String addPasswordForm(Model model) { diff --git a/src/main/java/stirling/software/SPDF/model/api/security/ManualRedactPdfRequest.java b/src/main/java/stirling/software/SPDF/model/api/security/ManualRedactPdfRequest.java new file mode 100644 index 00000000000..cb98499e037 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/model/api/security/ManualRedactPdfRequest.java @@ -0,0 +1,21 @@ +package stirling.software.SPDF.model.api.security; + +import java.util.List; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; +import lombok.EqualsAndHashCode; +import stirling.software.SPDF.model.api.PDFWithPageNums; + +@Data +@EqualsAndHashCode(callSuper = true) +public class ManualRedactPdfRequest extends PDFWithPageNums { + @Schema(description = "A list of areas that should be redacted") + private List redactions; + + @Schema(description = "Convert the redacted PDF to an image", defaultValue = "false") + private boolean convertPDFToImage; + + @Schema(description = "The color used to fully redact certain pages") + private String pageRedactionColor; +} diff --git a/src/main/java/stirling/software/SPDF/model/api/security/RedactionArea.java b/src/main/java/stirling/software/SPDF/model/api/security/RedactionArea.java new file mode 100644 index 00000000000..5157d415d97 --- /dev/null +++ b/src/main/java/stirling/software/SPDF/model/api/security/RedactionArea.java @@ -0,0 +1,23 @@ +package stirling.software.SPDF.model.api.security; + +import io.swagger.v3.oas.annotations.media.Schema; +import lombok.Data; + +@Data +public class RedactionArea { + @Schema(description = "The left edge point of the area to be redacted.") + private Double x; + @Schema(description = "The top edge point of the area to be redacted.") + private Double y; + + @Schema(description = "The height of the area to be redacted.") + private Double height; + @Schema(description = "The width of the area to be redacted.") + private Double width; + + @Schema(description = "The page on which the area should be redacted.") + private Integer page; + + @Schema(description = "The color used to redact the specified area.") + private String color; +} diff --git a/src/main/java/stirling/software/SPDF/utils/propertyeditor/StringToArrayListPropertyEditor.java b/src/main/java/stirling/software/SPDF/utils/propertyeditor/StringToArrayListPropertyEditor.java new file mode 100644 index 00000000000..cbcb617210f --- /dev/null +++ b/src/main/java/stirling/software/SPDF/utils/propertyeditor/StringToArrayListPropertyEditor.java @@ -0,0 +1,37 @@ +package stirling.software.SPDF.utils.propertyeditor; + +import java.beans.PropertyEditorSupport; +import java.util.ArrayList; +import java.util.List; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; + +import lombok.extern.slf4j.Slf4j; +import stirling.software.SPDF.model.api.security.RedactionArea; + +@Slf4j +public class StringToArrayListPropertyEditor extends PropertyEditorSupport { + + private final ObjectMapper objectMapper = new ObjectMapper(); + + @Override + public void setAsText(String text) throws IllegalArgumentException { + if (text == null || text.trim().isEmpty()) { + setValue(new ArrayList<>()); + return; + } + try { + objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + TypeReference> typeRef = new TypeReference>() { + }; + List list = objectMapper.readValue(text, typeRef); + setValue(list); + } catch (Exception e) { + log.error("Exception while converting {}", e); + throw new IllegalArgumentException( + "Failed to convert java.lang.String to java.util.List"); + } + } +} diff --git a/src/main/resources/messages_en_GB.properties b/src/main/resources/messages_en_GB.properties index a14cc332bc8..4a27fa77e5e 100644 --- a/src/main/resources/messages_en_GB.properties +++ b/src/main/resources/messages_en_GB.properties @@ -82,6 +82,7 @@ pages=Pages loading=Loading... addToDoc=Add to Document reset=Reset +apply=Apply legal.privacy=Privacy Policy legal.terms=Terms and Conditions @@ -474,6 +475,10 @@ home.autoRedact.title=Auto Redact home.autoRedact.desc=Auto Redacts(Blacks out) text in a PDF based on input text autoRedact.tags=Redact,Hide,black out,black,marker,hidden +home.redact.title=Manual Redaction +home.redact.desc=Redacts a PDF based on selected text, drawn shapes and/or selected page(s) +redact.tags=Redact,Hide,black out,black,marker,hidden,manual + home.tableExtraxt.title=PDF to CSV home.tableExtraxt.desc=Extracts Tables from a PDF converting it to CSV tableExtraxt.tags=CSV,Table Extraction,extract,convert @@ -579,6 +584,15 @@ autoRedact.customPaddingLabel=Custom Extra Padding autoRedact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box) autoRedact.submitButton=Submit +#redact +redact.title=Manual Redaction +redact.header=Manual Redaction +redact.submit=Redact +redact.pageBasedRedaction=Page-based Redaction +redact.convertPDFToImageLabel=Convert PDF to PDF-Image (Used to remove text behind the box) +redact.pageRedactionNumbers.title=Pages +redact.pageRedactionNumbers.placeholder=(e.g. 1,2,8 or 4,7,12-16 or 2n-1) +redact.redactionColor.title=Redaction Color #showJS showJS.title=Show Javascript diff --git a/src/main/resources/static/css/redact.css b/src/main/resources/static/css/redact.css new file mode 100644 index 00000000000..4c9a8d749ab --- /dev/null +++ b/src/main/resources/static/css/redact.css @@ -0,0 +1,322 @@ +:root { + --page-redaction-color: #000000; +} + +.textLayer span::selection, +.textLayer span::-moz-selection { + background-color: rgba(0, 100, 0, 0.26); +} + +.selected-wrapper { + position: absolute; + outline: 2px solid darkgreen; + outline-offset: -2px; + z-index: 10; +} + +.selected-wrapper:hover:not(:has(.redaction-overlay:hover)) { + outline-color: var(--palette-color, #000000); + background-color: var(--palette-color, #000000); + z-index: 10; + transition: background-color 0.065s linear; + + cursor: pointer; +} + +.redaction-overlay { + display: flex; + position: absolute; + + left: 50%; + top: 100%; + + min-width: 25px; + max-width: 90px; + + min-height: 25px; + + flex-wrap: nowrap; + + column-gap: 5px; + row-gap: 2px; + + border-radius: 2px; + padding: 2px; + + box-sizing: border-box; + + background-color: rgb(0 96 170); + outline: 1px solid gray; + translate: -50% -100%; +} + +.redaction-overlay svg { + height: 25px; + width: 25px; + + max-width: 35px; + max-height: 35px; + + fill: rgba(255, 255, 255, 0.904); + user-select: none; +} + +.redaction-overlay svg:hover { + cursor: pointer; + background-color: rgb(3, 63, 109); + fill: rgba(226, 226, 226, 0.904); +} + +.textLayer div, +.textLayer div > * { + user-select: none; +} + +.rectangle { + border: 2px solid #ff0000; + position: absolute; +} + +html { + --textLayer-pointer-events: auto; + --textLayer-user-select: auto; +} + +.textLayer * { + pointer-events: var(--textLayer-pointer-events); + user-select: var(--textLayer-user-select); +} + +#showMoreBtnIcon::before { + left: 5px; + top: 5px; +} + +#showMoreBtn { + display: flex; + justify-content: center; + align-items: center; +} + +#man-text-select-redact, #man-shape-redact, #downloadBtn, #uploadBtn, #pageBasedRedactionBtn, #pdfToImageBtn, #showMoreBtn { + height: var(--toolButton-height); + width: var(--toolButton-width); + + border-radius: var(--toolButton-border-radius); + transition: color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; + user-select: none; +} + +#text-selection, #shape-selection, #downloadBtnIcon, #uploadBtnIcon, #pageBasedRedactionBtnIcon, #pdfToImageBtnIcon, #showMoreBtnIcon { + position: relative; + font-size: var(--toolButton-icon-font-size); +} + +:is(#man-shape-redact, #man-text-select-redact, #sidebarToggle, #viewThumbnail, #viewOutline, #showMoreBtn).toggled { + background-color: rgb(50, 159, 243); + color: rgb(255 255 255); + outline:rgb(50, 159, 243) !important; + border-color: rgb(50, 159, 243) !important; +} + +:is(#man-shape-redact, #man-text-select-redact, #redactionsPaletteContainer, #downloadBtn, #uploadBtn, #pageBasedRedactionBtn, #pdfToImageBtn, #showMoreBtn):hover { + background-color: rgba(6, 114, 197, 0.82); + color: rgb(255 255 255); + outline:rgba(6, 114, 197, 0.82) !important; + border-color: rgba(6, 114, 197, 0.82) !important; +} + +#redactionsPaletteContainer { + height: var(--toolButton-height); + width: var(--toolButton-width); + + border-radius: var(--toolButton-border-radius); + overflow: hidden; +} + +#redactionsPaletteContainer *, #showMoreBtn * { + user-select: none; + pointer-events: none; +} + +#redactions-palette { + display: inline; + position: relative; + + border-bottom: 8px solid var(--palette-color); + border-radius: inherit; + border-bottom-left-radius: 0; + border-bottom-right-radius: 0; + font-size: var(--toolButton-icon-font-size); +} + +#redactions-palette::before { + position: absolute; + content: ''; + height: 6px; + width: 100%; + left: 0; + bottom: 0px; + background-color: var(--palette-color); +} + +#redactions-palette > input[type=color] { + visibility: hidden; + position: absolute; + left: 0; + top: var(--toolButton-height); + height: 0; +} + +#apply-redaction { + height: var(--toolButton-height); + width: var(--toolButton-width); + + border-radius: var(--toolButton-border-radius); +} + +#apply-redaction[disabled=true], #apply-redaction:disabled:not([disabled=false]) { + color: rgb(147, 149, 153); + box-shadow: none !important; +} + +#apply-redaction:is(:hover):not([disabled=true], :disabled:not([disabled=false])) { + cursor: pointer; + background-color: rgba(6, 114, 197, 0.82); + color: rgb(255 255 255); + outline:rgba(6, 114, 197, 0.82) !important; + border-color: rgba(6, 114, 197, 0.82) !important; +} + +.toolbar-btn-hover:hover { + cursor: pointer; + background-color: rgba(6, 114, 197, 0.82) !important; + color: rgb(255 255 255) !important; + outline:rgba(6, 114, 197, 0.82) !important; + border-color: rgba(6, 114, 197, 0.82) !important; +} + +#apply-redaction-icon { + font-size: var(--toolButton-icon-font-size); +} + +#apply-redaction > span { + user-select: none; + pointer-events: none; +} + +#pageRedactColor, input[data-for=pageRedactColor] { + flex: 1; + padding: 1px; +} + +#pageRedactColor:is(:hover, :focus-within), input[data-for=pageRedactColor]:is(:hover, :focus-within) { + cursor: pointer; +} + +.palette-color { + border-bottom: 3px solid var(--palette-color); +} + +.palette-color:is(:hover, :focus-within) { + cursor: pointer; + background-color: var(--button-hover-color); +} + +.splitToolbarButton > .btn-primary, .splitToolbarButton > .btn-secondary, .splitToolbarButton > .toolbarButton { + margin-left: 3px; + margin-right: 3px; +} + +.spin-animation { + -webkit-animation: spin 2s linear infinite; /* Safari */ + -moz-animation: spin 2s linear infinite; + -o-animation: spin 2s linear infinite; + animation: spin 2s linear infinite; +} + +@-webkit-keyframes spin { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); } +} + +@-moz-keyframes spin { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); } +} + +@-o-keyframes spin { + 0% { -webkit-transform: rotate(0deg); } + 100% { -webkit-transform: rotate(360deg); } +} + +@keyframes spin { + 0% { transform: rotate(0deg); } + 100% { transform: rotate(360deg); } +} + +.active-redaction { + z-index: 30 !important; +} + +#pageBasedRedactionOverlay { + position: absolute; + left: 50%; + top: 50%; + background-color: var(--md-sys-color-surface); + color: var(--md-sys-color-on-surface); + border-radius: 3rem; + z-index: 100; + transform: translate(-50%, -50%); +} + +.list-styling { + display: list-item !important; + margin-left: 15px; + list-style-type: disc; +} + +.redacted-page { + --page-redaction-color: none; +} + +.redacted-page-preview { + border: 2px solid blue; +} + +.redacted-page-preview:hover { + background-color: var(--page-redaction-color) !important; +} + +.redacted-page-preview * { + user-select: none; + pointer-events: none; +} + +.overlay-colorpicker-window { + position: absolute; + left: 0; + top: 24px; + height: 0; + visibility: hidden; +} + +.redacted-thumbnail-image-preview { + border: 2px solid blue; +} + +.redacted-thumbnail-preview { + position: relative; +} + +.redacted-thumbnail-preview:hover::after { + content: ''; + background-color: var(--page-redaction-color); + + position: absolute; + left: 0; + top: 0; + + height: var(--thumbnail-height); + width: var(--thumbnail-width); +} diff --git a/src/main/resources/static/js/redact.js b/src/main/resources/static/js/redact.js new file mode 100644 index 00000000000..3fdc4c3fca4 --- /dev/null +++ b/src/main/resources/static/js/redact.js @@ -0,0 +1,1206 @@ +import { PDFViewerApplication } from "../pdfjs-legacy/js/viewer.mjs"; +import UUID from "./uuid.js"; + +let zoomScaleValue = 1.0; + +let activeOverlay; +let drawingLayer = null; + +const doNothing = () => {}; + +function addRedactedPagePreview(pagesSelector) { + document.querySelectorAll(pagesSelector).forEach((page) => { + let textLayer = page.querySelector(".textLayer"); + if (textLayer) textLayer.classList.add("redacted-page-preview"); + }); +} + +function addRedactedThumbnailPreview(sidebarPagesSelector) { + document.querySelectorAll(sidebarPagesSelector).forEach((thumbnail) => { + thumbnail.classList.add("redacted-thumbnail-preview"); + let thumbnailImage = thumbnail.querySelector(".thumbnailImage"); + if (thumbnailImage) + thumbnailImage.classList.add("redacted-thumbnail-image-preview"); + }); +} + +function removeRedactedPagePreview() { + document + .querySelectorAll(".textLayer") + .forEach((textLayer) => + textLayer.classList.remove("redacted-page-preview") + ); + document + .querySelectorAll("#thumbnailView > a > div.thumbnail") + .forEach((thumbnail) => { + thumbnail.classList.remove("redacted-thumbnail-preview"); + let thumbnailImage = thumbnail.querySelector(".thumbnailImage"); + if (thumbnailImage) + thumbnailImage.classList.remove("redacted-thumbnail-image-preview"); + }); +} + +function extractPagesDetailed(pagesInput, totalPageCount) { + let parts = pagesInput.split(",").filter((s) => s); + let pagesDetailed = { + numbers: new Set(), + functions: new Set(), + ranges: new Set(), + all: false, + }; + for (let part of parts) { + let trimmedPart = part.trim(); + if ("all" == trimmedPart) { + pagesDetailed.all = true; + return pagesDetailed; + } else if (isValidFunction(trimmedPart)) { + pagesDetailed.functions.add(formatNFunction(trimmedPart)); + } else if (trimmedPart.includes("-")) { + let range = trimmedPart + .replaceAll(" ", "") + .split("-") + .filter((s) => s); + if ( + range && + range.length == 2 && + range[0].trim() > 0 && + range[1].trim() > 0 + ) + pagesDetailed.ranges.add({ + low: range[0].trim(), + high: range[1].trim(), + }); + } else if (isPageNumber(trimmedPart)) { + pagesDetailed.numbers.add( + trimmedPart <= totalPageCount ? trimmedPart : totalPageCount + ); + } + } + + return pagesDetailed; +} + +function formatNFunction(expression) { + let result = insertMultiplicationBeforeN(expression.replaceAll(" ", "")); + let multiplyByOpeningRoundBracketPattern = /([0-9n)])\(/g; // example: n(n-1), 9(n-1), (n-1)(n-2) + result = result.replaceAll(multiplyByOpeningRoundBracketPattern, "$1*("); + + let multiplyByClosingRoundBracketPattern = /\)([0-9n)])/g; // example: (n-1)n, (n-1)9, (n-1)(n-2) + result = result.replaceAll(multiplyByClosingRoundBracketPattern, ")*$1"); + return result; +} + +function insertMultiplicationBeforeN(expression) { + let result = expression.replaceAll(/(\d)n/g, "$1*n"); + while (result.match(/nn/)) { + result = result.replaceAll(/nn/g, "n*n"); // From nn -> n*n + } + return result; +} + +function validatePages(pages) { + let parts = pages.split(",").filter((s) => s); + let errors = []; + for (let part of parts) { + let trimmedPart = part.trim(); + if ("all" == trimmedPart) continue; + else if (trimmedPart.includes("n")) { + if (!isValidFunction(trimmedPart)) + errors.push( + `${trimmedPart} is an invalid function, it should consist of digits 0-9, n, *, -, /, (, ), \\.` + ); + } else if (trimmedPart.includes("-")) { + let range = trimmedPart.split("-").filter((s) => s); + if (!range || range.length != 2) + errors.push( + `${trimmedPart} is an invalid range, it should consist of from-to, example: 1-5` + ); + else if (range[0].trim() <= 0 || range[1].trim() <= 0) + errors.push( + `${trimmedPart} has invalid range(s), page numbers should be positive.` + ); + } else if (!isPageNumber(trimmedPart)) { + errors.push( + `${trimmedPart} is invalid, it should either be a function, page number or a range.` + ); + } + } + + return { errors }; +} + +function isPageNumber(page) { + return /^[0-9]*$/.test(page); +} + +function isValidFunction(part) { + return part.includes("n") && /[0-9n+\-*/() ]+$/.test(part); +} + +function hideContainer(container) { + container?.classList.add("d-none"); +} + +const RedactionModes = Object.freeze({ + DRAWING: Symbol("drawing"), + TEXT: Symbol("text"), + NONE: Symbol("none"), +}); + +function removePDFJSButtons() { + document.getElementById("print")?.remove(); + document.getElementById("download")?.remove(); + document.getElementById("editorStamp")?.remove(); + document.getElementById("editorFreeText")?.remove(); + document.getElementById("editorInk")?.remove(); + document.getElementById("secondaryToolbarToggle")?.remove(); + document.getElementById("openFile")?.remove(); +} + +function hideInitialPage() { + document.body.style.overflowY = "hidden"; + let redactionsFormContainer = document.getElementById( + "redactionFormContainer" + ); + for ( + let el = redactionsFormContainer.previousElementSibling; + el && el instanceof HTMLBRElement; + el = el.previousElementSibling + ) { + el.classList.add("d-none"); + } + redactionsFormContainer.classList.add("d-none"); + document.getElementsByTagName("footer")[0].classList.add("d-none"); +} + +window.addEventListener("load", (e) => { + let isChromium = + !!window.chrome || + (!!navigator.userAgentData && + navigator.userAgentData.brands.some((data) => data.brand == "Chromium")); + + let isSafari = + /constructor/i.test(window.HTMLElement) || + (function (p) { + return p.toString() === "[object SafariRemoteNotification]"; + })( + !window["safari"] || + (typeof safari !== "undefined" && window["safari"].pushNotification) + ); + let isWebkit = navigator.userAgent.search(/webkit/i) > 0; + let isGecko = navigator.userAgent.search(/gecko/i) > 0; + let isFirefox = typeof InstallTrigger !== "undefined"; + + let hiddenInput = document.getElementById("fileInput"); + let outerContainer = document.getElementById("outerContainer"); + let printContainer = document.getElementById("printContainer"); + + let toolbarViewerRight = document.getElementById("toolbarViewerRight"); + let showMoreBtn = document.getElementById("showMoreBtn"); + + window.onresize = (e) => { + if (window.innerWidth > 1125 && showMoreBtn.classList.contains("toggled")) { + showMoreBtn.click(); + } else if ( + window.innerWidth > 1125 && + toolbarViewerRight.hasAttribute("style") + ) { + toolbarViewerRight.style.removeProperty("display"); + } + }; + + showMoreBtn.onclick = (e) => { + if (showMoreBtn.classList.contains("toggled")) { + toolbarViewerRight.style.display = "none"; + showMoreBtn.classList.remove("toggled"); + } else { + toolbarViewerRight.style.display = "flex"; + showMoreBtn.classList.add("toggled"); + } + }; + + let viewer = document.getElementById("viewer"); + + hiddenInput.files = undefined; + let redactionMode = RedactionModes.NONE; + + let redactions = []; + + let redactionsInput = document.getElementById("redactions-input"); + + let redactionsPalette = document.getElementById("redactions-palette"); + let redactionsPaletteInput = redactionsPalette.querySelector("input"); + + let redactionsPaletteContainer = document.getElementById( + "redactionsPaletteContainer" + ); + + let applyRedactionBtn = document.getElementById("apply-redaction"); + + let redactedPagesDetails = { + numbers: new Set(), + ranges: new Set(), + functions: new Set(), + all: false, + }; + let pageBasedRedactionBtn = document.getElementById("pageBasedRedactionBtn"); + let pageBasedRedactionOverlay = document.getElementById( + "pageBasedRedactionOverlay" + ); + pageBasedRedactionBtn.onclick = (e) => + pageBasedRedactionOverlay.classList.remove("d-none"); + + pageBasedRedactionOverlay.querySelector("input[type=text]").onchange = ( + e + ) => { + let input = e.target; + let parentElement = input.parentElement; + + resetFieldFeedbackMessages(input, parentElement); + + let value = input.value.trim(); + let { errors } = validatePages(value); + if (errors && errors.length > 0) { + applyPageRedactionBtn.disabled = "true"; + displayFieldErrorMessages(input, errors); + } else { + applyPageRedactionBtn.removeAttribute("disabled"); + input.classList.add("is-valid"); + } + }; + + let applyPageRedactionBtn = document.getElementById("applyPageRedactionBtn"); + applyPageRedactionBtn.onclick = (e) => { + pageBasedRedactionOverlay.querySelectorAll("input").forEach((input) => { + const id = input.getAttribute("data-for"); + if (id == "pageNumbers") { + let { errors } = validatePages(input.value); + + resetFieldFeedbackMessages(input, input.parentElement); + + if (errors?.length > 0) { + applyPageRedactionBtn.disabled = true; + displayFieldErrorMessages(input, errors); + } else { + pageBasedRedactionOverlay.classList.add("d-none"); + applyRedactionBtn.removeAttribute("disabled"); + input.classList.remove("is-valid"); + + let totalPagesCount = PDFViewerApplication.pdfViewer.pagesCount; + let pagesDetailed = extractPagesDetailed( + input.value, + totalPagesCount + ); + redactedPagesDetails = pagesDetailed; + addPageRedactionPreviewToPages(pagesDetailed, totalPagesCount); + } + } else if (id == "pageRedactColor") setPageRedactionColor(input.value); + let formInput = document.getElementById(id); + if (formInput) formInput.value = input.value; + }); + }; + + let closePageRedactionBtn = document.getElementById("closePageRedactionBtn"); + closePageRedactionBtn.onclick = (e) => { + pageBasedRedactionOverlay.classList.add("d-none"); + pageBasedRedactionOverlay.querySelectorAll("input").forEach((input) => { + const id = input.getAttribute("data-for"); + if (id == "pageNumbers") { + resetFieldFeedbackMessages(input, input.parentElement); + } + let formInput = document.getElementById(id); + if (formInput) input.value = formInput.value; + }); + }; + + let pdfToImageCheckbox = document.getElementById("convertPDFToImage"); + + let pdfToImageBtn = document.getElementById("pdfToImageBtn"); + pdfToImageBtn.onclick = (e) => { + pdfToImageBtn.classList.toggle("btn-success"); + pdfToImageBtn.classList.toggle("btn-danger"); + pdfToImageCheckbox.checked = !pdfToImageCheckbox.checked; + }; + + let fileChooser = document.getElementsByClassName("custom-file-chooser")[0]; + let fileChooserInput = fileChooser.querySelector( + `#${fileChooser.getAttribute("data-bs-element-id")}` + ); + + let uploadButton = document.getElementById("uploadBtn"); + uploadButton.onclick = (e) => fileChooserInput.click(); + + document.addEventListener("file-input-change", (e) => { + redactions = []; + _setRedactionsInput(redactions); + }); + + let submitBtn = document.getElementById("submitBtn"); + + let downloadBtn = document.getElementById("downloadBtn"); + let downloadBtnIcon = document.getElementById("downloadBtnIcon"); + + downloadBtn.onclick = (e) => { + submitBtn.click(); + setTimeout(_showOrHideLoadingSpinner, 100); // wait 100 milliseconds so that submitBtn would be disabled + }; + + function _showOrHideLoadingSpinner() { + if (!submitBtn.disabled) { + downloadBtnIcon.innerHTML = "download"; + downloadBtnIcon.classList.remove("spin-animation"); + return; + } + + downloadBtnIcon.innerHTML = "progress_activity"; + downloadBtnIcon.classList.add("spin-animation"); + setTimeout(_showOrHideLoadingSpinner, 500); + } + + redactionsPaletteContainer.onclick = (e) => redactionsPalette.click(); + + viewer.onmouseup = (e) => { + if (redactionMode !== RedactionModes.TEXT) return; + const containsText = + window.getSelection() && window.getSelection().toString() != ""; + applyRedactionBtn.disabled = !containsText; + }; + + applyRedactionBtn.onclick = (e) => { + if (redactionMode !== RedactionModes.TEXT) { + applyRedactionBtn.disabled = true; + return; + } + redactTextSelection(); + applyRedactionBtn.disabled = true; + }; + + redactionsPaletteInput.onchange = (e) => { + let color = e.target.value; + redactionsPalette.style.setProperty("--palette-color", color); + }; + + document.addEventListener("file-input-change", (e) => { + let fileChooser = document.getElementsByClassName("custom-file-chooser")[0]; + let fileChooserInput = fileChooser.querySelector( + `#${fileChooser.getAttribute("data-bs-element-id")}` + ); + + hiddenInput.files = fileChooserInput.files; + if (!hiddenInput.files || hiddenInput.files.length === 0) { + hideContainer(outerContainer); + hideContainer(printContainer); + } else { + outerContainer?.classList.remove("d-none"); + printContainer?.classList.remove("d-none"); + hideInitialPage(); + } + + hiddenInput.dispatchEvent(new Event("change", { bubbles: true })); + }); + + PDFViewerApplication.downloadOrSave = doNothing; + PDFViewerApplication.triggerPrinting = doNothing; + + let redactionContainersDivs = {}; + PDFViewerApplication.eventBus.on("pagerendered", (e) => { + removePDFJSButtons(); + + let textSelectionRedactionBtn = document.getElementById( + "man-text-select-redact" + ); + let drawRedactionBtn = document.getElementById("man-shape-redact"); + + textSelectionRedactionBtn.onclick = _handleTextSelectionRedactionBtnClick; + drawRedactionBtn.onclick = _handleDrawRedactionBtnClick; + + let layer = e.source.textLayer.div; + layer.setAttribute("data-page", e.pageNumber); + if ( + redactedPagesDetails.all || + redactedPagesDetails.numbers.has(e.pageNumber) + ) { + layer.classList.add("redacted-page-preview"); + } else { + layer.classList.remove("redacted-page-preview"); + } + + zoomScaleValue = e.source.scale ? e.source.scale : e.source.pageScale; + document.documentElement.style.setProperty("--zoom-scale", zoomScaleValue); + + let redactionsContainer = document.getElementById( + `redactions-container-${e.pageNumber}` + ); + if (!redactionsContainer && !redactionContainersDivs[`${e.pageNumber}`]) { + redactionsContainer = document.createElement("div"); + redactionsContainer.style.position = "relative"; + redactionsContainer.style.height = "100%"; + redactionsContainer.style.width = "100%"; + redactionsContainer.id = `redactions-container-${e.pageNumber}`; + redactionsContainer.style.setProperty("z-index", "unset"); + + layer.appendChild(redactionsContainer); + redactionContainersDivs[`${e.pageNumber}`] = redactionsContainer; + } else if ( + !redactionsContainer && + redactionContainersDivs[`${e.pageNumber}`] + ) { + redactionsContainer = redactionContainersDivs[`${e.pageNumber}`]; + + layer.appendChild(redactionsContainer); + // Dispatch event to update text layer references for elements' events + redactionsContainer + .querySelectorAll(".selected-wrapper") + .forEach((area) => + area.dispatchEvent( + new CustomEvent("textLayer-reference-changed", { + bubbles: true, + detail: { textLayer: layer }, + }) + ) + ); + } + + document.onpointerup = (e) => { + if (drawingLayer && e.target != drawingLayer && e.button == 0) + drawingLayer.dispatchEvent(new Event("external-pointerup")); + }; + + initDraw(layer, redactionsContainer); + + function _handleTextSelectionRedactionBtnClick(e) { + if (textSelectionRedactionBtn.classList.contains("toggled")) { + resetTextSelection(); + } else { + resetDrawRedactions(); + textSelectionRedactionBtn.classList.add("toggled"); + redactionMode = RedactionModes.TEXT; + const containsText = + window.getSelection() && window.getSelection().toString() != ""; + applyRedactionBtn.disabled = !containsText; + applyRedactionBtn.classList.remove("d-none"); + } + } + + function resetTextSelection() { + textSelectionRedactionBtn.classList.remove("toggled"); + redactionMode = RedactionModes.NONE; + clearSelection(); + applyRedactionBtn.disabled = true; + applyRedactionBtn.classList.add("d-none"); + } + + function clearSelection() { + if (window.getSelection) { + if (window.getSelection().empty) { + // Chrome + window.getSelection().empty(); + } else if (window.getSelection().removeAllRanges) { + // Firefox + window.getSelection().removeAllRanges(); + } + } else if (document.selection) { + // IE? + document.selection.empty(); + } + } + + function _handleDrawRedactionBtnClick(e) { + if (drawRedactionBtn.classList.contains("toggled")) { + resetDrawRedactions(); + } else { + resetTextSelection(); + drawRedactionBtn.classList.add("toggled"); + document.documentElement.style.setProperty( + "--textLayer-pointer-events", + "none" + ); + document.documentElement.style.setProperty( + "--textLayer-user-select", + "none" + ); + redactionMode = RedactionModes.DRAWING; + } + } + + function resetDrawRedactions() { + redactionMode = RedactionModes.NONE; + drawRedactionBtn.classList.remove("toggled"); + document.documentElement.style.setProperty( + "--textLayer-pointer-events", + "auto" + ); + document.documentElement.style.setProperty( + "--textLayer-user-select", + "auto" + ); + window.dispatchEvent(new CustomEvent("reset-drawing", { bubbles: true })); + } + + function initDraw(canvas, redactionsContainer) { + let mouse = { + x: 0, + y: 0, + startX: 0, + startY: 0, + }; + let element = null; + let drawnRedaction = null; + + window.addEventListener("reset-drawing", (e) => { + _clearDrawing(); + canvas.style.cursor = "default"; + document.documentElement.style.setProperty( + "--textLayer-pointer-events", + "auto" + ); + document.documentElement.style.setProperty( + "--textLayer-user-select", + "auto" + ); + }); + + window.addEventListener("drawing-entered", (e) => { + let target = e.detail?.target; + if (canvas === target) return; + _clearDrawing(); + }); + + window.addEventListener("cancel-drawing", (e) => { + _clearDrawing(); + canvas.style.cursor = "default"; + }); + + function setMousePosition(e) { + if (isChromium || isSafari || isWebkit) { + mouse.x = e.offsetX; + mouse.y = e.offsetY; + } else if (isFirefox || isGecko) { + mouse.x = e.layerX; + mouse.y = e.layerY; + } else { + let rect = (e.target || e.srcElement).getBoundingClientRect(); + mouse.x = e.clientX - rect.left; + mouse.y = e.clientY - rect.top; + } + } + + window.onkeydown = (e) => { + if (e.key === "Escape" && redactionMode === RedactionModes.DRAWING) { + window.dispatchEvent( + new CustomEvent("cancel-drawing", { bubbles: true }) + ); + } + }; + + canvas.onpointerenter = (e) => { + window.dispatchEvent( + new CustomEvent("drawing-entered", { + bubbles: true, + detail: { target: canvas }, + }) + ); + }; + + canvas.onpointerup = (e) => { + let isLeftClick = e.button == 0; + if (!isLeftClick) return; + + if (element !== null) { + _saveAndResetDrawnRedaction(); + console.log("finished."); + } + }; + + canvas.addEventListener("external-pointerup", (e) => { + if (element != null) { + _saveAndResetDrawnRedaction(); + } + }); + + canvas.onpointerleave = (e) => { + let ev = copyEvent(e, "pointerleave"); + let { left, top } = calculateMouseCoordinateToRotatedBox(canvas, e); + + ev.layerX = left; + ev.offsetX = left; + + ev.layerY = top; + ev.offsetY = top; + + setMousePosition(ev); + if (element !== null) { + draw(); + } + }; + + canvas.onpointerdown = (e) => { + let isLeftClick = e.button == 0; + if (!isLeftClick) return; + + if (element == null) { + if (redactionMode !== RedactionModes.DRAWING) { + console.warn( + "Drawing attempt when redaction mode is", + redactionMode.description + ); + return; + } + console.log("begun."); + _captureAndDrawStartingPointOfDrawnRedaction(); + } + }; + + canvas.onpointermove = function (e) { + setMousePosition(e); + if (element !== null) { + draw(); + } + }; + + function draw() { + let scaleFactor = _getScaleFactor(); + + let width = Math.abs(mouse.x - mouse.startX); + element.style.width = _toCalcZoomPx(_scaleToDisplay(width)); + + let height = Math.abs(mouse.y - mouse.startY); + element.style.height = _toCalcZoomPx(_scaleToDisplay(height)); + + let left = mouse.x - mouse.startX < 0 ? mouse.x : mouse.startX; + element.style.left = _toCalcZoomPx(_scaleToDisplay(left)); + + let top = mouse.y - mouse.startY < 0 ? mouse.y : mouse.startY; + element.style.top = _toCalcZoomPx(_scaleToDisplay(top)); + + if (drawnRedaction) { + drawnRedaction.left = _scaleToPDF(left, scaleFactor); + drawnRedaction.top = _scaleToPDF(top, scaleFactor); + drawnRedaction.width = _scaleToPDF(width, scaleFactor); + drawnRedaction.height = _scaleToPDF(height, scaleFactor); + } + } + + function _clearDrawing() { + if (element) element.remove(); + if (drawingLayer == canvas) drawingLayer = null; + element = null; + drawnRedaction = null; + } + + function _saveAndResetDrawnRedaction() { + if (!element) return; + if ( + !element.style.height || + element.style.height.includes("(0px * var") || + !element.style.width || + element.style.width.includes("(0px * var") + ) { + element.remove(); + } else { + element.classList.add("selected-wrapper"); + element.classList.remove("rectangle"); + + addRedactionOverlay(element, drawnRedaction, canvas); + redactions.push(drawnRedaction); + _setRedactionsInput(redactions); + } + drawingLayer = null; + element = null; + drawnRedaction = null; + canvas.style.cursor = "default"; + } + + function _captureAndDrawStartingPointOfDrawnRedaction() { + mouse.startX = mouse.x; + mouse.startY = mouse.y; + + element = document.createElement("div"); + element.className = "rectangle"; + drawingLayer = canvas; + + let left = mouse.x; + let top = mouse.y; + + element.style.left = _toCalcZoomPx(_scaleToDisplay(left)); + element.style.top = _toCalcZoomPx(_scaleToDisplay(top)); + + let scaleFactor = _getScaleFactor(); + let color = redactionsPalette.style.getPropertyValue("--palette-color"); + + element.style.setProperty("--palette-color", color); + + drawnRedaction = { + left: _scaleToPDF(left, scaleFactor), + top: _scaleToPDF(top, scaleFactor), + width: 0.0, + height: 0.0, + color: color, + pageNumber: parseInt(canvas.getAttribute("data-page")), + element: element, + id: UUID.uuidv4(), + }; + + redactionsContainer.appendChild(element); + canvas.style.cursor = "crosshair"; + } + } + }); + + PDFViewerApplication.eventBus.on("rotationchanging", (e) => { + if (!activeOverlay) return; + hideOverlay(); + }); + + function _getScaleFactor() { + return parseFloat(viewer.style.getPropertyValue("--scale-factor")); + } + + function getTextLayer(element) { + let current = element; + while (current) { + if ( + current instanceof HTMLDivElement && + current.classList.contains("textLayer") + ) + return current; + current = current.parentElement; + } + + return current; + } + + document.onclick = (e) => { + if ( + (e.target && + e.target.classList.contains("selected-wrapper") && + e.target.firstChild == activeOverlay) || + e.target == activeOverlay + ) + return; + if (activeOverlay) hideOverlay(); + }; + + document.addEventListener("keydown", (e) => { + if (e.key === "Delete" && activeOverlay) { + activeOverlay + .querySelector(".delete-icon") + ?.dispatchEvent(new Event("click", { bubbles: true })); + return; + } + const isRedactionShortcut = + e.ctrlKey && (e.key == "s" || e.key == "S" || e.code == "KeyS"); + if (!isRedactionShortcut || redactionMode !== RedactionModes.TEXT) return; + + redactTextSelection(); + }); + + function rotateTextBox(rect, textLayerRect, angle) { + let left, top, width, height; + if (!angle || angle == 0) { + left = rect.left - textLayerRect.left; + top = rect.top - textLayerRect.top; + width = rect.width; + height = rect.height; + } else if (angle == 90) { + left = rect.top - textLayerRect.top; + top = textLayerRect.right - rect.right; + width = rect.height; + height = rect.width; + } else if (angle == 180) { + left = textLayerRect.right - rect.right; + top = textLayerRect.bottom - rect.bottom; + width = rect.width; + height = rect.height; + } else if (angle == 270) { + left = textLayerRect.bottom - rect.bottom; + top = rect.left - textLayerRect.left; + width = rect.height; + height = rect.width; + } + + return { left, top, width, height }; + } + + function redactTextSelection() { + let selection = window.getSelection(); + if (!selection || selection.rangeCount <= 0) return; + let range = selection.getRangeAt(0); + + let textLayer = getTextLayer(range.startContainer); + if (!textLayer) return; + + const pageNumber = textLayer.getAttribute("data-page"); + let redactionsArea = textLayer.querySelector( + `#redactions-container-${pageNumber}` + ); + let textLayerRect = textLayer.getBoundingClientRect(); + + let rects = range.getClientRects(); + let scaleFactor = _getScaleFactor(); + + let color = redactionsPalette.style.getPropertyValue("--palette-color"); + + let angle = textLayer.getAttribute("data-main-rotation"); + for (const rect of rects) { + if (!rect || !rect.width || !rect.height) continue; + let redactionElement = document.createElement("div"); + redactionElement.classList.add("selected-wrapper"); + + let { left, top, width, height } = rotateTextBox( + rect, + textLayerRect, + angle + ); + + let leftDisplayScaled = _scaleToDisplay(left); + let topDisplayScaled = _scaleToDisplay(top); + let widthDisplayScaled = _scaleToDisplay(width); + let heightDisplayScaled = _scaleToDisplay(height); + + let redactionInfo = { + left: _scaleToPDF(left, scaleFactor), + top: _scaleToPDF(top, scaleFactor), + width: _scaleToPDF(width, scaleFactor), + height: _scaleToPDF(height, scaleFactor), + pageNumber: parseInt(pageNumber), + color: color, + element: redactionElement, + id: UUID.uuidv4(), + }; + + redactions.push(redactionInfo); + + redactionElement.style.left = _toCalcZoomPx(leftDisplayScaled); + redactionElement.style.top = _toCalcZoomPx(topDisplayScaled); + + redactionElement.style.width = _toCalcZoomPx(widthDisplayScaled); + redactionElement.style.height = _toCalcZoomPx(heightDisplayScaled); + redactionElement.style.setProperty("--palette-color", color); + + redactionsArea.appendChild(redactionElement); + + addRedactionOverlay(redactionElement, redactionInfo, textLayer); + } + + _setRedactionsInput(redactions); + applyRedactionBtn.disabled = true; + } + + function _scaleToDisplay(value) { + return value / zoomScaleValue; + } + + function _scaleToPDF(value, scaleFactor) { + if (!scaleFactor) + scaleFactor = document.documentElement.getPropertyValue("--scale-factor"); + return value / scaleFactor; + } + + function _toCalcZoomPx(val) { + return `calc(${val}px * var(--zoom-scale))`; + } + + function _setRedactionsInput(redactions) { + let stringifiedRedactions = JSON.stringify( + redactions.filter(_nonEmptyRedaction).map((red) => ({ + x: red.left, + y: red.top, + width: red.width, + height: red.height, + color: red.color, + page: red.pageNumber, + })) + ); + redactionsInput.value = stringifiedRedactions; + } + + function addRedactionOverlay(redactionElement, redactionInfo, textLayer) { + let redactionOverlay = document.createElement("div"); + + let deleteBtn = $( + `` + )[0]; + + deleteBtn.onclick = (e) => { + redactions = redactions.filter((red) => redactionInfo.id != red.id); + redactionElement.remove(); + _setRedactionsInput(redactions); + activeOverlay = null; + }; + + let colorPaletteLabel = $( + `` + )[0]; + + let colorPaletteInput = $(` + + `)[0]; + + colorPaletteLabel.appendChild(colorPaletteInput); + + colorPaletteLabel.onclick = (e) => { + if (colorPaletteLabel === e.target) { + e.stopPropagation(); + } + }; + + colorPaletteInput.onchange = (e) => { + let color = e.target.value; + redactionElement.style.setProperty("--palette-color", color); + let redactionIdx = redactions.findIndex( + (red) => redactionInfo.id === red.id + ); + if (redactionIdx < 0) return; + redactions[redactionIdx].color = color; + _setRedactionsInput(redactions); + }; + + redactionOverlay.appendChild(deleteBtn); + redactionOverlay.appendChild(colorPaletteLabel); + + redactionOverlay.classList.add("redaction-overlay"); + redactionOverlay.style.display = "none"; + + redactionElement.addEventListener("textLayer-reference-changed", (e) => { + textLayer = e.detail.textLayer; + }); + + redactionElement.onclick = (e) => { + if (e.target != redactionElement) return; + if (activeOverlay) hideOverlay(); + redactionElement.classList.add("active-redaction"); + activeOverlay = redactionOverlay; + _adjustActiveOverlayCoordinates(); + }; + + redactionElement.appendChild(redactionOverlay); + + // Adjust active overlay coordinates to avoid placing the overlay out of page bounds + function _adjustActiveOverlayCoordinates() { + activeOverlay.style.visibility = "hidden"; + activeOverlay.style.display = "flex"; + textLayer = textLayer || getTextLayer(redactionElement); + let angle = parseInt(textLayer.getAttribute("data-main-rotation")); + if (textLayer) + redactionOverlay.style.transform = `rotate(${angle * -1}deg)`; + + activeOverlay.style.removeProperty("left"); + activeOverlay.style.removeProperty("top"); + + let textRect = textLayer.getBoundingClientRect(); + let overlayRect = redactionOverlay.getBoundingClientRect(); + + let leftOffset = 0, + topOffset = 0; + if (overlayRect.right > textRect.right) { + leftOffset = textRect.right - overlayRect.right; + } else if (overlayRect.left < textRect.left) { + leftOffset = textRect.left - overlayRect.left; + } + + if (overlayRect.top < textRect.top) { + topOffset = textRect.top - overlayRect.top; + } else if (overlayRect.bottom > textRect.bottom) { + topOffset = textRect.bottom - overlayRect.bottom; + } + + switch (angle) { + case 90: + [leftOffset, topOffset] = [topOffset, -leftOffset]; + break; + case 180: + [leftOffset, topOffset] = [-leftOffset, -topOffset]; + break; + case 270: + [leftOffset, topOffset] = [-topOffset, leftOffset]; + break; + } + + if (leftOffset != 0) + activeOverlay.style.left = `calc(50% + ${leftOffset}px`; + if (topOffset != 0) + activeOverlay.style.top = `calc(100% + ${topOffset}px`; + activeOverlay.style.visibility = "unset"; + } + } +}); + +function calculateMouseCoordinateToRotatedBox(canvas, e) { + let textRect = canvas.getBoundingClientRect(); + let left, + top = 0; + let angle = parseInt(canvas.getAttribute("data-main-rotation")); + switch (angle) { + case 0: + left = clamp(e.pageX - textRect.left, 0, textRect.width); + top = clamp(e.pageY - textRect.top, 0, textRect.height); + break; + + case 90: + left = clamp(e.pageY - textRect.top, 0, textRect.height); + top = clamp(textRect.right - e.pageX, 0, textRect.width); + break; + case 180: + left = clamp(textRect.right - e.pageX, 0, textRect.width); + top = clamp(textRect.bottom - e.pageY, 0, textRect.width); + break; + case 270: + left = clamp(textRect.bottom - e.pageY, 0, textRect.height); + top = clamp(e.pageX - textRect.left, 0, textRect.width); + break; + } + return { left, top }; +} + +function clamp(value, min, max) { + return Math.max(min, Math.min(value, max)); +} + +function addPageRedactionPreviewToPages(pagesDetailed, totalPagesCount) { + if (pagesDetailed.all) { + addRedactedPagePreview("#viewer > .page"); + addRedactedThumbnailPreview("#thumbnailView > a > div.thumbnail"); + } else { + removeRedactedPagePreview(); + + setPageNumbersFromRange(pagesDetailed, totalPagesCount); + setPageNumbersFromNFunctions(pagesDetailed, totalPagesCount); + + let pageNumbers = Array.from(pagesDetailed.numbers); + if (pageNumbers?.length > 0) { + let pagesSelector = pageNumbers + .map((number) => `#viewer > .page[data-page-number="${number}"]`) + .join(","); + addRedactedPagePreview(pagesSelector); + let thumbnailSelector = pageNumbers + .map( + (number) => + `#thumbnailView > a > div.thumbnail[data-page-number="${number}"]` + ) + .join(","); + addRedactedThumbnailPreview(thumbnailSelector); + } + } +} + +function resetFieldFeedbackMessages(input, parentElement) { + if (parentElement) + parentElement + .querySelectorAll(".invalid-feedback") + .forEach((feedback) => feedback.remove()); + if (input) { + input.classList.remove("is-invalid"); + input.classList.remove("is-valid"); + } +} + +function displayFieldErrorMessages(input, errors) { + input.classList.add("is-invalid"); + errors.forEach((error) => { + let element = document.createElement("div"); + element.classList.add("invalid-feedback"); + element.classList.add("list-styling"); + element.textContent = error; + input.parentElement.appendChild(element); + }); +} + +function setPageRedactionColor(color) { + document.documentElement.style.setProperty("--page-redaction-color", color); +} + +function setPageNumbersFromNFunctions(pagesDetailed, totalPagesCount) { + pagesDetailed.functions.forEach((fun) => { + if (!isValidFunction(fun)) return; + for (let n = 1; n <= totalPagesCount; n++) { + let pageNumber = eval(fun); + if (!pageNumber || pageNumber <= 0 || pageNumber > totalPagesCount) + continue; + pagesDetailed.numbers.add(pageNumber); + } + }); +} + +function setPageNumbersFromRange(pagesDetailed, totalPagesCount) { + pagesDetailed.ranges.forEach((range) => { + for (let i = range.low; i <= range.high && i <= totalPagesCount; i++) { + pagesDetailed.numbers.add(i); + } + }); +} + +function hideOverlay() { + activeOverlay.style.display = "none"; + activeOverlay.parentElement.classList.remove("active-redaction"); + activeOverlay = null; +} + +function _isEmptyRedaction(redaction) { + return ( + redaction.left == null || + redaction.top == null || + redaction.width == null || + redaction.height == null || + redaction.pageNumber == null + ); +} + +function _nonEmptyRedaction(redaction) { + return !_isEmptyRedaction(redaction); +} + +function copyEvent(e, type) { + if (type == "pointerleave") + return { + layerX: e.layerX, + layerY: e.layerY, + pageX: e.pageX, + pageY: e.pageY, + clientX: e.clientX, + clientY: e.clientY, + button: e.button, + height: e.height, + width: e.width, + offsetX: e.offsetX, + offsetY: e.offsetY, + pointerId: e.pointerId, + pointerType: e.pointerType, + type: e.type, + screenX: e.screenX, + screenY: e.screenY, + tiltX: e.tiltX, + tiltY: e.tiltY, + x: e.x, + y: e.y, + altKey: e.altKey, + ctrlKey: e.ctrlKey, + isPrimary: e.isPrimary, + isTrusted: e.isTrusted, + metaKey: e.metaKey, + pressure: e.pressure, + returnValue: e.returnValue, + shiftKey: e.shiftKey, + timeStamp: e.timeStamp, + which: e.which, + twist: e.twist, + tangentialPressure: e.tangentialPressure, + target: e.target, + srcElement: e.srcElement, + relatedTarget: e.relatedTarget, + rangeOffset: e.rangeOffset, + rangeParent: e.rangeParent, + explicitOriginalTarget: e.explicitOriginalTarget, + eventPhase: e.eventPhase, + detail: e.detail, + defaultPrevented: e.defaultPrevented, + currentTarget: e.currentTarget, + buttons: e.buttons, + azimuthAngle: e.azimuthAngle, + altitudeAngle: e.altitudeAngle, + }; + + return {}; +} diff --git a/src/main/resources/static/pdfjs-legacy/css/viewer-redact.css b/src/main/resources/static/pdfjs-legacy/css/viewer-redact.css new file mode 100644 index 00000000000..c8ba631ffa7 --- /dev/null +++ b/src/main/resources/static/pdfjs-legacy/css/viewer-redact.css @@ -0,0 +1,5084 @@ +/* Copyright 2014 Mozilla Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +.dialog { + --dialog-bg-color: white; + --dialog-border-color: white; + --dialog-shadow: 0 2px 14px 0 rgb(58 57 68 / 0.2); + --text-primary-color: #15141a; + --text-secondary-color: #5b5b66; + --hover-filter: brightness(0.9); + --focus-ring-color: #0060df; + --focus-ring-outline: 2px solid var(--focus-ring-color); + + --textarea-border-color: #8f8f9d; + --textarea-bg-color: white; + --textarea-fg-color: var(--text-secondary-color); + + --radio-bg-color: #f0f0f4; + --radio-checked-bg-color: #fbfbfe; + --radio-border-color: #8f8f9d; + --radio-checked-border-color: #0060df; + + --button-secondary-bg-color: #f0f0f4; + --button-secondary-fg-color: var(--text-primary-color); + --button-secondary-border-color: var(--button-secondary-bg-color); + --button-secondary-hover-bg-color: var(--button-secondary-bg-color); + --button-secondary-hover-fg-color: var(--button-secondary-fg-color); + --button-secondary-hover-border-color: var(--button-secondary-hover-bg-color); + + --button-primary-bg-color: #0060df; + --button-primary-fg-color: #fbfbfe; + --button-primary-hover-bg-color: var(--button-primary-bg-color); + --button-primary-hover-fg-color: var(--button-primary-fg-color); + --button-primary-hover-border-color: var(--button-primary-hover-bg-color); + + font: message-box; + font-size: 13px; + font-weight: 400; + line-height: 150%; + border-radius: 4px; + padding: 12px 16px; + border: 1px solid var(--dialog-border-color); + background: var(--dialog-bg-color); + color: var(--text-primary-color); + box-shadow: var(--dialog-shadow); +} + +@media (prefers-color-scheme: dark) { + :where(html:not(.is-light)) .dialog { + --dialog-bg-color: #1c1b22; + --dialog-border-color: #1c1b22; + --dialog-shadow: 0 2px 14px 0 #15141a; + --text-primary-color: #fbfbfe; + --text-secondary-color: #cfcfd8; + --focus-ring-color: #0df; + --hover-filter: brightness(1.4); + + --textarea-bg-color: #42414d; + + --radio-bg-color: #2b2a33; + --radio-checked-bg-color: #15141a; + --radio-checked-border-color: #0df; + + --button-secondary-bg-color: #2b2a33; + --button-primary-bg-color: #0df; + --button-primary-fg-color: #15141a; + } +} + +:where(html.is-dark) .dialog { + --dialog-bg-color: #1c1b22; + --dialog-border-color: #1c1b22; + --dialog-shadow: 0 2px 14px 0 #15141a; + --text-primary-color: #fbfbfe; + --text-secondary-color: #cfcfd8; + --focus-ring-color: #0df; + --hover-filter: brightness(1.4); + + --textarea-bg-color: #42414d; + + --radio-bg-color: #2b2a33; + --radio-checked-bg-color: #15141a; + --radio-checked-border-color: #0df; + + --button-secondary-bg-color: #2b2a33; + --button-primary-bg-color: #0df; + --button-primary-fg-color: #15141a; +} + +@media screen and (forced-colors: active) { + .dialog { + --dialog-bg-color: Canvas; + --dialog-border-color: CanvasText; + --dialog-shadow: none; + --text-primary-color: CanvasText; + --text-secondary-color: CanvasText; + --hover-filter: none; + --focus-ring-color: ButtonBorder; + + --textarea-border-color: ButtonBorder; + --textarea-bg-color: Field; + --textarea-fg-color: ButtonText; + + --radio-bg-color: ButtonFace; + --radio-checked-bg-color: ButtonFace; + --radio-border-color: ButtonText; + --radio-checked-border-color: ButtonText; + + --button-secondary-bg-color: ButtonFace; + --button-secondary-fg-color: ButtonText; + --button-secondary-border-color: ButtonText; + --button-secondary-hover-bg-color: AccentColor; + --button-secondary-hover-fg-color: AccentColorText; + + --button-primary-bg-color: ButtonText; + --button-primary-fg-color: ButtonFace; + --button-primary-hover-bg-color: AccentColor; + --button-primary-hover-fg-color: AccentColorText; + } +} + +.dialog .mainContainer *:focus-visible { + outline: var(--focus-ring-outline); + outline-offset: 2px; +} + +.dialog .mainContainer .radio { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 4px; +} + +.dialog .mainContainer .radio > .radioButton { + display: flex; + gap: 8px; + align-self: stretch; + align-items: center; +} + +.dialog .mainContainer .radio > .radioButton input { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + box-sizing: border-box; + width: 16px; + height: 16px; + border-radius: 50%; + background-color: var(--radio-bg-color); + border: 1px solid var(--radio-border-color); +} + +.dialog .mainContainer .radio > .radioButton input:hover { + filter: var(--hover-filter); +} + +.dialog .mainContainer .radio > .radioButton input:checked { + background-color: var(--radio-checked-bg-color); + border: 4px solid var(--radio-checked-border-color); +} + +.dialog .mainContainer .radio > .radioLabel { + display: flex; + padding-inline-start: 24px; + align-items: flex-start; + gap: 10px; + align-self: stretch; +} + +.dialog .mainContainer .radio > .radioLabel > span { + flex: 1 0 0; + font-size: 11px; + color: var(--text-secondary-color); +} + +.dialog .mainContainer button { + border-radius: 4px; + border: 1px solid; + font: menu; + font-weight: 600; + padding: 4px 16px; + width: auto; + height: 32px; +} + +.dialog .mainContainer button:hover { + cursor: pointer; + filter: var(--hover-filter); +} + +.dialog .mainContainer button.secondaryButton { + color: var(--button-secondary-fg-color); + background-color: var(--button-secondary-bg-color); + border-color: var(--button-secondary-border-color); +} + +.dialog .mainContainer button.secondaryButton:hover { + color: var(--button-secondary-hover-fg-color); + background-color: var(--button-secondary-hover-bg-color); + border-color: var(--button-secondary-hover-border-color); +} + +.dialog .mainContainer button.primaryButton { + color: var(--button-primary-hover-fg-color); + background-color: var(--button-primary-hover-bg-color); + border-color: var(--button-primary-hover-border-color); + opacity: 1; +} + +.dialog .mainContainer button.primaryButton:hover { + color: var(--button-primary-hover-fg-color); + background-color: var(--button-primary-hover-bg-color); + border-color: var(--button-primary-hover-border-color); +} + +.dialog .mainContainer textarea { + font: inherit; + padding: 8px; + resize: none; + margin: 0; + box-sizing: border-box; + border-radius: 4px; + border: 1px solid var(--textarea-border-color); + background: var(--textarea-bg-color); + color: var(--textarea-fg-color); +} + +.dialog .mainContainer textarea:focus { + outline-offset: 0; + border-color: transparent; +} + +.dialog .mainContainer textarea:disabled { + pointer-events: none; + opacity: 0.4; +} + +.textLayer { + position: absolute; + text-align: initial; + inset: 0; + overflow: clip; + opacity: 1; + line-height: 1; + -webkit-text-size-adjust: none; + -moz-text-size-adjust: none; + text-size-adjust: none; + forced-color-adjust: none; + transform-origin: 0 0; + caret-color: CanvasText; + z-index: 0; +} + +.textLayer.highlighting { + touch-action: none; +} + +.textLayer :is(span, br) { + color: transparent; + position: absolute; + white-space: pre; + cursor: text; + transform-origin: 0% 0%; +} + +.textLayer > :not(.markedContent), +.textLayer .markedContent span:not(.markedContent) { + z-index: 1; +} + +.textLayer span.markedContent { + top: 0; + height: 0; +} + +.textLayer .highlight { + --highlight-bg-color: rgb(180 0 170 / 0.25); + --highlight-selected-bg-color: rgb(0 100 0 / 0.25); + --highlight-backdrop-filter: none; + --highlight-selected-backdrop-filter: none; + + margin: -1px; + padding: 1px; + background-color: var(--highlight-bg-color); + -webkit-backdrop-filter: var(--highlight-backdrop-filter); + backdrop-filter: var(--highlight-backdrop-filter); + border-radius: 4px; +} + +@media screen and (forced-colors: active) { + .textLayer .highlight { + --highlight-bg-color: transparent; + --highlight-selected-bg-color: transparent; + --highlight-backdrop-filter: var(--hcm-highlight-filter); + --highlight-selected-backdrop-filter: var(--hcm-highlight-selected-filter); + } +} + +.textLayer .highlight.appended { + position: initial; +} + +.textLayer .highlight.begin { + border-radius: 4px 0 0 4px; +} + +.textLayer .highlight.end { + border-radius: 0 4px 4px 0; +} + +.textLayer .highlight.middle { + border-radius: 0; +} + +.textLayer .highlight.selected { + background-color: var(--highlight-selected-bg-color); + -webkit-backdrop-filter: var(--highlight-selected-backdrop-filter); + backdrop-filter: var(--highlight-selected-backdrop-filter); +} + +.textLayer ::-moz-selection { + background: rgba(0 0 255 / 0.25); + background: color-mix(in srgb, AccentColor, transparent 75%); +} + +.textLayer ::selection { + background: rgba(0 0 255 / 0.25); + background: color-mix(in srgb, AccentColor, transparent 75%); +} + +.textLayer br::-moz-selection { + background: transparent; +} + +.textLayer br::selection { + background: transparent; +} + +.textLayer .endOfContent { + display: block; + position: absolute; + inset: 100% 0 0; + z-index: 0; + cursor: default; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.textLayer .endOfContent.active { + top: 0; +} + +.annotationLayer { + --annotation-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); + --input-focus-border-color: Highlight; + --input-focus-outline: 1px solid Canvas; + --input-unfocused-border-color: transparent; + --input-disabled-border-color: transparent; + --input-hover-border-color: black; + --link-outline: none; + + position: absolute; + top: 0; + left: 0; + pointer-events: none; + transform-origin: 0 0; +} + +@media screen and (forced-colors: active) { + .annotationLayer { + --input-focus-border-color: CanvasText; + --input-unfocused-border-color: ActiveText; + --input-disabled-border-color: GrayText; + --input-hover-border-color: Highlight; + --link-outline: 1.5px solid LinkText; + } + + .annotationLayer .textWidgetAnnotation :is(input, textarea):required, + .annotationLayer .choiceWidgetAnnotation select:required, + .annotationLayer + .buttonWidgetAnnotation:is(.checkBox, .radioButton) + input:required { + outline: 1.5px solid selectedItem; + } + + .annotationLayer .linkAnnotation { + outline: var(--link-outline); + } + + .annotationLayer .linkAnnotation:hover { + -webkit-backdrop-filter: var(--hcm-highlight-filter); + backdrop-filter: var(--hcm-highlight-filter); + } + + .annotationLayer .linkAnnotation > a:hover { + opacity: 0 !important; + background: none !important; + box-shadow: none; + } + + .annotationLayer .popupAnnotation .popup { + outline: calc(1.5px * var(--scale-factor)) solid CanvasText !important; + background-color: ButtonFace !important; + color: ButtonText !important; + } + + .annotationLayer .highlightArea:hover::after { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + -webkit-backdrop-filter: var(--hcm-highlight-filter); + backdrop-filter: var(--hcm-highlight-filter); + content: ""; + pointer-events: none; + } + + .annotationLayer .popupAnnotation.focused .popup { + outline: calc(3px * var(--scale-factor)) solid Highlight !important; + } +} + +.annotationLayer[data-main-rotation="90"] .norotate { + transform: rotate(270deg) translateX(-100%); +} + +.annotationLayer[data-main-rotation="180"] .norotate { + transform: rotate(180deg) translate(-100%, -100%); +} + +.annotationLayer[data-main-rotation="270"] .norotate { + transform: rotate(90deg) translateY(-100%); +} + +.annotationLayer.disabled section, +.annotationLayer.disabled .popup { + pointer-events: none; +} + +.annotationLayer .annotationContent { + position: absolute; + width: 100%; + height: 100%; + pointer-events: none; +} + +.annotationLayer .annotationContent.freetext { + background: transparent; + border: none; + inset: 0; + overflow: visible; + white-space: nowrap; + font: 10px sans-serif; + line-height: 1.35; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.annotationLayer section { + position: absolute; + text-align: initial; + pointer-events: auto; + box-sizing: border-box; + transform-origin: 0 0; +} + +.annotationLayer section:has(div.annotationContent) canvas.annotationContent { + display: none; +} + +.annotationLayer :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton) > a { + position: absolute; + font-size: 1em; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.annotationLayer + :is(.linkAnnotation, .buttonWidgetAnnotation.pushButton):not(.hasBorder) + > a:hover { + opacity: 0.2; + background-color: rgb(255 255 0); + box-shadow: 0 2px 10px rgb(255 255 0); +} + +.annotationLayer .linkAnnotation.hasBorder:hover { + background-color: rgb(255 255 0 / 0.2); +} + +.annotationLayer .hasBorder { + background-size: 100% 100%; +} + +.annotationLayer .textAnnotation img { + position: absolute; + cursor: pointer; + width: 100%; + height: 100%; + top: 0; + left: 0; +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea), +.annotationLayer .choiceWidgetAnnotation select, +.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input { + background-image: var(--annotation-unfocused-field-background); + border: 2px solid var(--input-unfocused-border-color); + box-sizing: border-box; + font: calc(9px * var(--scale-factor)) sans-serif; + height: 100%; + margin: 0; + vertical-align: top; + width: 100%; +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea):required, +.annotationLayer .choiceWidgetAnnotation select:required, +.annotationLayer + .buttonWidgetAnnotation:is(.checkBox, .radioButton) + input:required { + outline: 1.5px solid red; +} + +.annotationLayer .choiceWidgetAnnotation select option { + padding: 0; +} + +.annotationLayer .buttonWidgetAnnotation.radioButton input { + border-radius: 50%; +} + +.annotationLayer .textWidgetAnnotation textarea { + resize: none; +} + +.annotationLayer .textWidgetAnnotation [disabled]:is(input, textarea), +.annotationLayer .choiceWidgetAnnotation select[disabled], +.annotationLayer + .buttonWidgetAnnotation:is(.checkBox, .radioButton) + input[disabled] { + background: none; + border: 2px solid var(--input-disabled-border-color); + cursor: not-allowed; +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea):hover, +.annotationLayer .choiceWidgetAnnotation select:hover, +.annotationLayer + .buttonWidgetAnnotation:is(.checkBox, .radioButton) + input:hover { + border: 2px solid var(--input-hover-border-color); +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea):hover, +.annotationLayer .choiceWidgetAnnotation select:hover, +.annotationLayer .buttonWidgetAnnotation.checkBox input:hover { + border-radius: 2px; +} + +.annotationLayer .textWidgetAnnotation :is(input, textarea):focus, +.annotationLayer .choiceWidgetAnnotation select:focus { + background: none; + border: 2px solid var(--input-focus-border-color); + border-radius: 2px; + outline: var(--input-focus-outline); +} + +.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) :focus { + background-image: none; + background-color: transparent; +} + +.annotationLayer .buttonWidgetAnnotation.checkBox :focus { + border: 2px solid var(--input-focus-border-color); + border-radius: 2px; + outline: var(--input-focus-outline); +} + +.annotationLayer .buttonWidgetAnnotation.radioButton :focus { + border: 2px solid var(--input-focus-border-color); + outline: var(--input-focus-outline); +} + +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before, +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after, +.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before { + background-color: CanvasText; + content: ""; + display: block; + position: absolute; +} + +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before, +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after { + height: 80%; + left: 45%; + width: 1px; +} + +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::before { + transform: rotate(45deg); +} + +.annotationLayer .buttonWidgetAnnotation.checkBox input:checked::after { + transform: rotate(-45deg); +} + +.annotationLayer .buttonWidgetAnnotation.radioButton input:checked::before { + border-radius: 50%; + height: 50%; + left: 25%; + top: 25%; + width: 50%; +} + +.annotationLayer .textWidgetAnnotation input.comb { + font-family: monospace; + padding-left: 2px; + padding-right: 0; +} + +.annotationLayer .textWidgetAnnotation input.comb:focus { + width: 103%; +} + +.annotationLayer .buttonWidgetAnnotation:is(.checkBox, .radioButton) input { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; +} + +.annotationLayer .fileAttachmentAnnotation .popupTriggerArea { + height: 100%; + width: 100%; +} + +.annotationLayer .popupAnnotation { + position: absolute; + font-size: calc(9px * var(--scale-factor)); + pointer-events: none; + width: -moz-max-content; + width: max-content; + max-width: 45%; + height: auto; +} + +.annotationLayer .popup { + background-color: rgb(255 255 153); + box-shadow: 0 calc(2px * var(--scale-factor)) calc(5px * var(--scale-factor)) + rgb(136 136 136); + border-radius: calc(2px * var(--scale-factor)); + outline: 1.5px solid rgb(255 255 74); + padding: calc(6px * var(--scale-factor)); + cursor: pointer; + font: message-box; + white-space: normal; + word-wrap: break-word; + pointer-events: auto; +} + +.annotationLayer .popupAnnotation.focused .popup { + outline-width: 3px; +} + +.annotationLayer .popup * { + font-size: calc(9px * var(--scale-factor)); +} + +.annotationLayer .popup > .header { + display: inline-block; +} + +.annotationLayer .popup > .header h1 { + display: inline; +} + +.annotationLayer .popup > .header .popupDate { + display: inline-block; + margin-left: calc(5px * var(--scale-factor)); + width: -moz-fit-content; + width: fit-content; +} + +.annotationLayer .popupContent { + border-top: 1px solid rgb(51 51 51); + margin-top: calc(2px * var(--scale-factor)); + padding-top: calc(2px * var(--scale-factor)); +} + +.annotationLayer .richText > * { + white-space: pre-wrap; + font-size: calc(9px * var(--scale-factor)); +} + +.annotationLayer .popupTriggerArea { + cursor: pointer; +} + +.annotationLayer section svg { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; +} + +.annotationLayer .annotationTextContent { + position: absolute; + width: 100%; + height: 100%; + opacity: 0; + color: transparent; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + pointer-events: none; +} + +.annotationLayer .annotationTextContent span { + width: 100%; + display: inline-block; +} + +.annotationLayer svg.quadrilateralsContainer { + contain: strict; + width: 0; + height: 0; + position: absolute; + top: 0; + left: 0; + z-index: -1; +} + +:root { + --xfa-unfocused-field-background: url("data:image/svg+xml;charset=UTF-8,"); + --xfa-focus-outline: auto; +} + +@media screen and (forced-colors: active) { + :root { + --xfa-focus-outline: 2px solid CanvasText; + } + .xfaLayer *:required { + outline: 1.5px solid selectedItem; + } +} + +.xfaLayer { + background-color: transparent; +} + +.xfaLayer .highlight { + margin: -1px; + padding: 1px; + background-color: rgb(239 203 237); + border-radius: 4px; +} + +.xfaLayer .highlight.appended { + position: initial; +} + +.xfaLayer .highlight.begin { + border-radius: 4px 0 0 4px; +} + +.xfaLayer .highlight.end { + border-radius: 0 4px 4px 0; +} + +.xfaLayer .highlight.middle { + border-radius: 0; +} + +.xfaLayer .highlight.selected { + background-color: rgb(203 223 203); +} + +.xfaPage { + overflow: hidden; + position: relative; +} + +.xfaContentarea { + position: absolute; +} + +.xfaPrintOnly { + display: none; +} + +.xfaLayer { + position: absolute; + text-align: initial; + top: 0; + left: 0; + transform-origin: 0 0; + line-height: 1.2; +} + +.xfaLayer * { + color: inherit; + font: inherit; + font-style: inherit; + font-weight: inherit; + font-kerning: inherit; + letter-spacing: -0.01px; + text-align: inherit; + text-decoration: inherit; + box-sizing: border-box; + background-color: transparent; + padding: 0; + margin: 0; + pointer-events: auto; + line-height: inherit; +} + +.xfaLayer *:required { + outline: 1.5px solid red; +} + +.xfaLayer div, +.xfaLayer svg, +.xfaLayer svg * { + pointer-events: none; +} + +.xfaLayer a { + color: blue; +} + +.xfaRich li { + margin-left: 3em; +} + +.xfaFont { + color: black; + font-weight: normal; + font-kerning: none; + font-size: 10px; + font-style: normal; + letter-spacing: 0; + text-decoration: none; + vertical-align: 0; +} + +.xfaCaption { + overflow: hidden; + flex: 0 0 auto; +} + +.xfaCaptionForCheckButton { + overflow: hidden; + flex: 1 1 auto; +} + +.xfaLabel { + height: 100%; + width: 100%; +} + +.xfaLeft { + display: flex; + flex-direction: row; + align-items: center; +} + +.xfaRight { + display: flex; + flex-direction: row-reverse; + align-items: center; +} + +:is(.xfaLeft, .xfaRight) > :is(.xfaCaption, .xfaCaptionForCheckButton) { + max-height: 100%; +} + +.xfaTop { + display: flex; + flex-direction: column; + align-items: flex-start; +} + +.xfaBottom { + display: flex; + flex-direction: column-reverse; + align-items: flex-start; +} + +:is(.xfaTop, .xfaBottom) > :is(.xfaCaption, .xfaCaptionForCheckButton) { + width: 100%; +} + +.xfaBorder { + background-color: transparent; + position: absolute; + pointer-events: none; +} + +.xfaWrapped { + width: 100%; + height: 100%; +} + +:is(.xfaTextfield, .xfaSelect):focus { + background-image: none; + background-color: transparent; + outline: var(--xfa-focus-outline); + outline-offset: -1px; +} + +:is(.xfaCheckbox, .xfaRadio):focus { + outline: var(--xfa-focus-outline); +} + +.xfaTextfield, +.xfaSelect { + height: 100%; + width: 100%; + flex: 1 1 auto; + border: none; + resize: none; + background-image: var(--xfa-unfocused-field-background); +} + +.xfaSelect { + padding-inline: 2px; +} + +:is(.xfaTop, .xfaBottom) > :is(.xfaTextfield, .xfaSelect) { + flex: 0 1 auto; +} + +.xfaButton { + cursor: pointer; + width: 100%; + height: 100%; + border: none; + text-align: center; +} + +.xfaLink { + width: 100%; + height: 100%; + position: absolute; + top: 0; + left: 0; +} + +.xfaCheckbox, +.xfaRadio { + width: 100%; + height: 100%; + flex: 0 0 auto; + border: none; +} + +.xfaRich { + white-space: pre-wrap; + width: 100%; + height: 100%; +} + +.xfaImage { + -o-object-position: left top; + object-position: left top; + -o-object-fit: contain; + object-fit: contain; + width: 100%; + height: 100%; +} + +.xfaLrTb, +.xfaRlTb, +.xfaTb { + display: flex; + flex-direction: column; + align-items: stretch; +} + +.xfaLr { + display: flex; + flex-direction: row; + align-items: stretch; +} + +.xfaRl { + display: flex; + flex-direction: row-reverse; + align-items: stretch; +} + +.xfaTb > div { + justify-content: left; +} + +.xfaPosition { + position: relative; +} + +.xfaArea { + position: relative; +} + +.xfaValignMiddle { + display: flex; + align-items: center; +} + +.xfaTable { + display: flex; + flex-direction: column; + align-items: stretch; +} + +.xfaTable .xfaRow { + display: flex; + flex-direction: row; + align-items: stretch; +} + +.xfaTable .xfaRlRow { + display: flex; + flex-direction: row-reverse; + align-items: stretch; + flex: 1; +} + +.xfaTable .xfaRlRow > div { + flex: 1; +} + +:is(.xfaNonInteractive, .xfaDisabled, .xfaReadOnly) :is(input, textarea) { + background: initial; +} + +@media print { + .xfaTextfield, + .xfaSelect { + background: transparent; + } + + .xfaSelect { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + text-indent: 1px; + text-overflow: ""; + } +} + +.canvasWrapper svg { + transform: none; +} + +.canvasWrapper svg[data-main-rotation="90"] mask, +.canvasWrapper svg[data-main-rotation="90"] use:not(.clip, .mask) { + transform: matrix(0, 1, -1, 0, 1, 0); +} + +.canvasWrapper svg[data-main-rotation="180"] mask, +.canvasWrapper svg[data-main-rotation="180"] use:not(.clip, .mask) { + transform: matrix(-1, 0, 0, -1, 1, 1); +} + +.canvasWrapper svg[data-main-rotation="270"] mask, +.canvasWrapper svg[data-main-rotation="270"] use:not(.clip, .mask) { + transform: matrix(0, -1, 1, 0, 0, 1); +} + +.canvasWrapper svg.highlight { + --blend-mode: multiply; + + position: absolute; + mix-blend-mode: var(--blend-mode); +} + +@media screen and (forced-colors: active) { + .canvasWrapper svg.highlight { + --blend-mode: difference; + } +} + +.canvasWrapper svg.highlight:not(.free) { + fill-rule: evenodd; +} + +.canvasWrapper svg.highlightOutline { + position: absolute; + mix-blend-mode: normal; + fill-rule: evenodd; + fill: none; +} + +.canvasWrapper svg.highlightOutline.hovered:not(.free):not(.selected) { + stroke: var(--hover-outline-color); + stroke-width: var(--outline-width); +} + +.canvasWrapper svg.highlightOutline.selected:not(.free) .mainOutline { + stroke: var(--outline-around-color); + stroke-width: calc(var(--outline-width) + 2 * var(--outline-around-width)); +} + +.canvasWrapper svg.highlightOutline.selected:not(.free) .secondaryOutline { + stroke: var(--outline-color); + stroke-width: var(--outline-width); +} + +.canvasWrapper svg.highlightOutline.free.hovered:not(.selected) { + stroke: var(--hover-outline-color); + stroke-width: calc(2 * var(--outline-width)); +} + +.canvasWrapper svg.highlightOutline.free.selected .mainOutline { + stroke: var(--outline-around-color); + stroke-width: calc(2 * (var(--outline-width) + var(--outline-around-width))); +} + +.canvasWrapper svg.highlightOutline.free.selected .secondaryOutline { + stroke: var(--outline-color); + stroke-width: calc(2 * var(--outline-width)); +} + +.toggle-button { + --button-background-color: #f0f0f4; + --button-background-color-hover: #e0e0e6; + --button-background-color-active: #cfcfd8; + --color-accent-primary: #0060df; + --color-accent-primary-hover: #0250bb; + --color-accent-primary-active: #054096; + --border-interactive-color: #8f8f9d; + --border-radius-circle: 9999px; + --border-width: 1px; + --size-item-small: 16px; + --size-item-large: 32px; + --color-canvas: white; + + --toggle-background-color: var(--button-background-color); + --toggle-background-color-hover: var(--button-background-color-hover); + --toggle-background-color-active: var(--button-background-color-active); + --toggle-background-color-pressed: var(--color-accent-primary); + --toggle-background-color-pressed-hover: var(--color-accent-primary-hover); + --toggle-background-color-pressed-active: var(--color-accent-primary-active); + --toggle-border-color: var(--border-interactive-color); + --toggle-border-color-hover: var(--toggle-border-color); + --toggle-border-color-active: var(--toggle-border-color); + --toggle-border-radius: var(--border-radius-circle); + --toggle-border-width: var(--border-width); + --toggle-height: var(--size-item-small); + --toggle-width: var(--size-item-large); + --toggle-dot-background-color: var(--toggle-border-color); + --toggle-dot-background-color-hover: var(--toggle-dot-background-color); + --toggle-dot-background-color-active: var(--toggle-dot-background-color); + --toggle-dot-background-color-on-pressed: var(--color-canvas); + --toggle-dot-margin: 1px; + --toggle-dot-height: calc( + var(--toggle-height) - 2 * var(--toggle-dot-margin) - 2 * + var(--toggle-border-width) + ); + --toggle-dot-width: var(--toggle-dot-height); + --toggle-dot-transform-x: calc( + var(--toggle-width) - 4 * var(--toggle-dot-margin) - var(--toggle-dot-width) + ); + + -webkit-appearance: none; + + -moz-appearance: none; + + appearance: none; + padding: 0; + margin: 0; + border: var(--toggle-border-width) solid var(--toggle-border-color); + height: var(--toggle-height); + width: var(--toggle-width); + border-radius: var(--toggle-border-radius); + background: var(--toggle-background-color); + box-sizing: border-box; + flex-shrink: 0; +} + +@media (prefers-color-scheme: dark) { + :where(html:not(.is-light)) .toggle-button { + --button-background-color: color-mix(in srgb, currentColor 7%, transparent); + --button-background-color-hover: color-mix( + in srgb, + currentColor 14%, + transparent + ); + --button-background-color-active: color-mix( + in srgb, + currentColor 21%, + transparent + ); + --color-accent-primary: #0df; + --color-accent-primary-hover: #80ebff; + --color-accent-primary-active: #aaf2ff; + --border-interactive-color: #bfbfc9; + --color-canvas: #1c1b22; + } +} + +:where(html.is-dark) .toggle-button { + --button-background-color: color-mix(in srgb, currentColor 7%, transparent); + --button-background-color-hover: color-mix( + in srgb, + currentColor 14%, + transparent + ); + --button-background-color-active: color-mix( + in srgb, + currentColor 21%, + transparent + ); + --color-accent-primary: #0df; + --color-accent-primary-hover: #80ebff; + --color-accent-primary-active: #aaf2ff; + --border-interactive-color: #bfbfc9; + --color-canvas: #1c1b22; +} + +@media (forced-colors: active) { + .toggle-button { + --color-accent-primary: ButtonText; + --color-accent-primary-hover: SelectedItem; + --color-accent-primary-active: SelectedItem; + --border-interactive-color: ButtonText; + --button-background-color: ButtonFace; + --border-interactive-color-hover: SelectedItem; + --border-interactive-color-active: SelectedItem; + --border-interactive-color-disabled: GrayText; + --color-canvas: ButtonText; + } +} + +.toggle-button:focus-visible { + outline: var(--focus-outline); + outline-offset: var(--focus-outline-offset); +} + +.toggle-button:enabled:hover { + background: var(--toggle-background-color-hover); + border-color: var(--toggle-border-color); +} + +.toggle-button:enabled:active { + background: var(--toggle-background-color-active); + border-color: var(--toggle-border-color); +} + +.toggle-button[aria-pressed="true"] { + background: var(--toggle-background-color-pressed); + border-color: transparent; +} + +.toggle-button[aria-pressed="true"]:enabled:hover { + background: var(--toggle-background-color-pressed-hover); + border-color: transparent; +} + +.toggle-button[aria-pressed="true"]:enabled:active { + background: var(--toggle-background-color-pressed-active); + border-color: transparent; +} + +.toggle-button::before { + display: block; + content: ""; + background-color: var(--toggle-dot-background-color); + height: var(--toggle-dot-height); + width: var(--toggle-dot-width); + margin: var(--toggle-dot-margin); + border-radius: var(--toggle-border-radius); + translate: 0; +} + +.toggle-button[aria-pressed="true"]::before { + translate: var(--toggle-dot-transform-x); + background-color: var(--toggle-dot-background-color-on-pressed); +} + +.toggle-button[aria-pressed="true"]:enabled:hover::before, +.toggle-button[aria-pressed="true"]:enabled:active::before { + background-color: var(--toggle-dot-background-color-on-pressed); +} + +[dir="rtl"] .toggle-button[aria-pressed="true"]::before { + translate: calc(-1 * var(--toggle-dot-transform-x)); +} + +@media (prefers-reduced-motion: no-preference) { + .toggle-button::before { + transition: translate 100ms; + } +} + +@media (prefers-contrast) { + .toggle-button:enabled:hover { + border-color: var(--toggle-border-color-hover); + } + + .toggle-button:enabled:active { + border-color: var(--toggle-border-color-active); + } + + .toggle-button[aria-pressed="true"]:enabled { + border-color: var(--toggle-border-color); + position: relative; + } + + .toggle-button[aria-pressed="true"]:enabled:hover, + .toggle-button[aria-pressed="true"]:enabled:hover:active { + border-color: var(--toggle-border-color-hover); + } + + .toggle-button[aria-pressed="true"]:enabled:active { + background-color: var(--toggle-dot-background-color-active); + border-color: var(--toggle-dot-background-color-hover); + } + + .toggle-button:hover::before, + .toggle-button:active::before { + background-color: var(--toggle-dot-background-color-hover); + } +} + +@media (forced-colors) { + .toggle-button { + --toggle-dot-background-color: var(--color-accent-primary); + --toggle-dot-background-color-hover: var(--color-accent-primary-hover); + --toggle-dot-background-color-active: var(--color-accent-primary-active); + --toggle-dot-background-color-on-pressed: var(--button-background-color); + --toggle-background-color-disabled: var(--button-background-color-disabled); + --toggle-border-color-hover: var(--border-interactive-color-hover); + --toggle-border-color-active: var(--border-interactive-color-active); + --toggle-border-color-disabled: var(--border-interactive-color-disabled); + } + + .toggle-button[aria-pressed="true"]:enabled::after { + border: 1px solid var(--button-background-color); + content: ""; + position: absolute; + height: var(--toggle-height); + width: var(--toggle-width); + display: block; + border-radius: var(--toggle-border-radius); + inset: -2px; + } + + .toggle-button[aria-pressed="true"]:enabled:active::after { + border-color: var(--toggle-border-color-active); + } +} + +:root { + --navbar-height: 64px; + --outline-width: 2px; + --outline-color: #0060df; + --outline-around-width: 1px; + --outline-around-color: #f0f0f4; + --hover-outline-around-color: var(--outline-around-color); + --focus-outline: solid var(--outline-width) var(--outline-color); + --unfocus-outline: solid var(--outline-width) transparent; + --focus-outline-around: solid var(--outline-around-width) + var(--outline-around-color); + --hover-outline-color: #8f8f9d; + --hover-outline: solid var(--outline-width) var(--hover-outline-color); + --hover-outline-around: solid var(--outline-around-width) + var(--hover-outline-around-color); + --freetext-line-height: 1.35; + --freetext-padding: 2px; + --resizer-bg-color: var(--outline-color); + --resizer-size: 6px; + --resizer-shift: calc( + 0px - (var(--outline-width) + var(--resizer-size)) / 2 - + var(--outline-around-width) + ); + --editorFreeText-editing-cursor: text; + --editorInk-editing-cursor: url(../images/cursor-editorInk.svg) 0 16, pointer; + --editorHighlight-editing-cursor: url(../images/cursor-editorTextHighlight.svg) + 24 24, + text; + --editorFreeHighlight-editing-cursor: url(../images/cursor-editorFreeHighlight.svg) + 1 18, + pointer; +} +.visuallyHidden { + position: absolute; + top: 0; + left: 0; + border: 0; + margin: 0; + padding: 0; + width: 0; + height: 0; + overflow: hidden; + white-space: nowrap; + font-size: 0; +} + +.textLayer.highlighting { + cursor: var(--editorFreeHighlight-editing-cursor); +} + +.textLayer.highlighting:not(.free) span { + cursor: var(--editorHighlight-editing-cursor); +} + +.textLayer.highlighting.free span { + cursor: var(--editorFreeHighlight-editing-cursor); +} + +@media (min-resolution: 1.1dppx) { + :root { + --editorFreeText-editing-cursor: url(../images/cursor-editorFreeText.svg) 0 + 16, + text; + } +} + +@media screen and (forced-colors: active) { + :root { + --outline-color: CanvasText; + --outline-around-color: ButtonFace; + --resizer-bg-color: ButtonText; + --hover-outline-color: Highlight; + --hover-outline-around-color: SelectedItemText; + } +} + +[data-editor-rotation="90"] { + transform: rotate(90deg); +} + +[data-editor-rotation="180"] { + transform: rotate(180deg); +} + +[data-editor-rotation="270"] { + transform: rotate(270deg); +} + +.annotationEditorLayer { + background: transparent; + position: absolute; + inset: 0; + font-size: calc(100px * var(--scale-factor)); + transform-origin: 0 0; + cursor: auto; +} + +.annotationEditorLayer.waiting { + content: ""; + cursor: wait; + position: absolute; + inset: 0; + width: 100%; + height: 100%; +} + +.annotationEditorLayer.disabled { + pointer-events: none; +} + +.annotationEditorLayer.freetextEditing { + cursor: var(--editorFreeText-editing-cursor); +} + +.annotationEditorLayer.inkEditing { + cursor: var(--editorInk-editing-cursor); +} + +.annotationEditorLayer :is(.freeTextEditor, .inkEditor, .stampEditor) { + position: absolute; + background: transparent; + z-index: 1; + transform-origin: 0 0; + cursor: auto; + max-width: 100%; + max-height: 100%; + border: var(--unfocus-outline); +} + +.annotationEditorLayer + .draggable.selectedEditor:is(.freeTextEditor, .inkEditor, .stampEditor) { + cursor: move; +} + +.annotationEditorLayer .moving:is(.freeTextEditor, .inkEditor, .stampEditor) { + touch-action: none; +} + +.annotationEditorLayer + .selectedEditor:is(.freeTextEditor, .inkEditor, .stampEditor) { + border: var(--focus-outline); + outline: var(--focus-outline-around); +} + +.annotationEditorLayer + .selectedEditor:is(.freeTextEditor, .inkEditor, .stampEditor)::before { + content: ""; + position: absolute; + inset: 0; + border: var(--focus-outline-around); + pointer-events: none; +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor):hover:not(.selectedEditor) { + border: var(--hover-outline); + outline: var(--hover-outline-around); +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor):hover:not( + .selectedEditor + )::before { + content: ""; + position: absolute; + inset: 0; + border: var(--focus-outline-around); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar { + --editor-toolbar-delete-image: url(../images/editor-toolbar-delete.svg); + --editor-toolbar-bg-color: #f0f0f4; + --editor-toolbar-highlight-image: url(../images/toolbarButton-editorHighlight.svg); + --editor-toolbar-fg-color: #2e2e56; + --editor-toolbar-border-color: #8f8f9d; + --editor-toolbar-hover-border-color: var(--editor-toolbar-border-color); + --editor-toolbar-hover-bg-color: #e0e0e6; + --editor-toolbar-hover-fg-color: var(--editor-toolbar-fg-color); + --editor-toolbar-hover-outline: none; + --editor-toolbar-focus-outline-color: #0060df; + --editor-toolbar-shadow: 0 2px 6px 0 rgb(58 57 68 / 0.2); + --editor-toolbar-vert-offset: 6px; + --editor-toolbar-height: 28px; + --editor-toolbar-padding: 2px; + + display: flex; + width: -moz-fit-content; + width: fit-content; + height: var(--editor-toolbar-height); + flex-direction: column; + justify-content: center; + align-items: center; + cursor: default; + pointer-events: auto; + box-sizing: content-box; + padding: var(--editor-toolbar-padding); + + position: absolute; + inset-inline-end: 0; + inset-block-start: calc(100% + var(--editor-toolbar-vert-offset)); + + border-radius: 6px; + background-color: var(--editor-toolbar-bg-color); + border: 1px solid var(--editor-toolbar-border-color); + box-shadow: var(--editor-toolbar-shadow); +} + +@media (prefers-color-scheme: dark) { + :where(html:not(.is-light)) + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar { + --editor-toolbar-bg-color: #2b2a33; + --editor-toolbar-fg-color: #fbfbfe; + --editor-toolbar-hover-bg-color: #52525e; + --editor-toolbar-focus-outline-color: #0df; + } +} + +:where(html.is-dark) + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar { + --editor-toolbar-bg-color: #2b2a33; + --editor-toolbar-fg-color: #fbfbfe; + --editor-toolbar-hover-bg-color: #52525e; + --editor-toolbar-focus-outline-color: #0df; +} + +@media screen and (forced-colors: active) { + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar { + --editor-toolbar-bg-color: ButtonFace; + --editor-toolbar-fg-color: ButtonText; + --editor-toolbar-border-color: ButtonText; + --editor-toolbar-hover-border-color: AccentColor; + --editor-toolbar-hover-bg-color: ButtonFace; + --editor-toolbar-hover-fg-color: AccentColor; + --editor-toolbar-hover-outline: 2px solid + var(--editor-toolbar-hover-border-color); + --editor-toolbar-focus-outline-color: ButtonBorder; + --editor-toolbar-shadow: none; + } +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar.hidden { + display: none; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar:has(:focus-visible) { + border-color: transparent; +} + +[dir="ltr"] + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar { + transform-origin: 100% 0; +} + +[dir="rtl"] + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar { + transform-origin: 0 0; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons { + display: flex; + justify-content: center; + align-items: center; + gap: 0; + height: 100%; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .divider { + width: 1px; + height: calc( + 2 * var(--editor-toolbar-padding) + var(--editor-toolbar-height) + ); + background-color: var(--editor-toolbar-border-color); + display: inline-block; + margin-inline: 2px; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .highlightButton { + width: var(--editor-toolbar-height); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .highlightButton::before { + content: ""; + -webkit-mask-image: var(--editor-toolbar-highlight-image); + mask-image: var(--editor-toolbar-highlight-image); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + display: inline-block; + background-color: var(--editor-toolbar-fg-color); + width: 100%; + height: 100%; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .highlightButton:hover::before { + background-color: var(--editor-toolbar-hover-fg-color); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .delete { + width: var(--editor-toolbar-height); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .delete::before { + content: ""; + -webkit-mask-image: var(--editor-toolbar-delete-image); + mask-image: var(--editor-toolbar-delete-image); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + display: inline-block; + background-color: var(--editor-toolbar-fg-color); + width: 100%; + height: 100%; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .delete:hover::before { + background-color: var(--editor-toolbar-hover-fg-color); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + > * { + height: var(--editor-toolbar-height); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + > :not(.divider) { + border: none; + background-color: transparent; + cursor: pointer; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + > :not(.divider):hover { + border-radius: 2px; + background-color: var(--editor-toolbar-hover-bg-color); + color: var(--editor-toolbar-hover-fg-color); + outline: var(--editor-toolbar-hover-outline); + outline-offset: 1px; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + > :not(.divider):hover:active { + outline: none; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + > :not(.divider):focus-visible { + border-radius: 2px; + outline: 2px solid var(--editor-toolbar-focus-outline-color); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText { + --alt-text-add-image: url(../images/altText_add.svg); + --alt-text-done-image: url(../images/altText_done.svg); + + display: flex; + align-items: center; + justify-content: center; + width: -moz-max-content; + width: max-content; + padding-inline: 8px; + pointer-events: all; + font: menu; + font-weight: 590; + font-size: 12px; + color: var(--editor-toolbar-fg-color); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText:disabled { + pointer-events: none; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText::before { + content: ""; + -webkit-mask-image: var(--alt-text-add-image); + mask-image: var(--alt-text-add-image); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + display: inline-block; + width: 12px; + height: 13px; + background-color: var(--editor-toolbar-fg-color); + margin-inline-end: 4px; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText:hover::before { + background-color: var(--editor-toolbar-hover-fg-color); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText.done::before { + -webkit-mask-image: var(--alt-text-done-image); + mask-image: var(--alt-text-done-image); +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText + .tooltip { + display: none; +} + +:is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText + .tooltip.show { + --alt-text-tooltip-bg: #f0f0f4; + --alt-text-tooltip-fg: #15141a; + --alt-text-tooltip-border: #8f8f9d; + --alt-text-tooltip-shadow: 0px 2px 6px 0px rgb(58 57 68 / 0.2); + + display: inline-flex; + flex-direction: column; + align-items: center; + justify-content: center; + position: absolute; + top: calc(100% + 2px); + inset-inline-start: 0; + padding-block: 2px 3px; + padding-inline: 3px; + max-width: 300px; + width: -moz-max-content; + width: max-content; + height: auto; + font-size: 12px; + + border: 0.5px solid var(--alt-text-tooltip-border); + background: var(--alt-text-tooltip-bg); + box-shadow: var(--alt-text-tooltip-shadow); + color: var(--alt-text-tooltip-fg); + + pointer-events: none; +} + +@media (prefers-color-scheme: dark) { + :where(html:not(.is-light)) + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText + .tooltip.show { + --alt-text-tooltip-bg: #1c1b22; + --alt-text-tooltip-fg: #fbfbfe; + --alt-text-tooltip-shadow: 0px 2px 6px 0px #15141a; + } +} + +:where(html.is-dark) + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText + .tooltip.show { + --alt-text-tooltip-bg: #1c1b22; + --alt-text-tooltip-fg: #fbfbfe; + --alt-text-tooltip-shadow: 0px 2px 6px 0px #15141a; +} + +@media screen and (forced-colors: active) { + :is( + .annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor, .highlightEditor), + .textLayer + ) + .editToolbar + .buttons + .altText + .tooltip.show { + --alt-text-tooltip-bg: Canvas; + --alt-text-tooltip-fg: CanvasText; + --alt-text-tooltip-border: CanvasText; + --alt-text-tooltip-shadow: none; + } +} + +.annotationEditorLayer .freeTextEditor { + padding: calc(var(--freetext-padding) * var(--scale-factor)); + width: auto; + height: auto; + touch-action: none; +} + +.annotationEditorLayer .freeTextEditor .internal { + background: transparent; + border: none; + inset: 0; + overflow: visible; + white-space: nowrap; + font: 10px sans-serif; + line-height: var(--freetext-line-height); + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.annotationEditorLayer .freeTextEditor .overlay { + position: absolute; + display: none; + background: transparent; + inset: 0; + width: 100%; + height: 100%; +} + +.annotationEditorLayer freeTextEditor .overlay.enabled { + display: block; +} + +.annotationEditorLayer .freeTextEditor .internal:empty::before { + content: attr(default-content); + color: gray; +} + +.annotationEditorLayer .freeTextEditor .internal:focus { + outline: none; + -webkit-user-select: auto; + -moz-user-select: auto; + user-select: auto; +} + +.annotationEditorLayer .inkEditor { + width: 100%; + height: 100%; +} + +.annotationEditorLayer .inkEditor.editing { + cursor: inherit; +} + +.annotationEditorLayer .inkEditor .inkEditorCanvas { + position: absolute; + inset: 0; + width: 100%; + height: 100%; + touch-action: none; +} + +.annotationEditorLayer .stampEditor { + width: auto; + height: auto; +} + +.annotationEditorLayer .stampEditor canvas { + position: absolute; + width: 100%; + height: 100%; + margin: 0; +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers { + position: absolute; + inset: 0; +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers.hidden { + display: none; +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers + > .resizer { + width: var(--resizer-size); + height: var(--resizer-size); + background: content-box var(--resizer-bg-color); + border: var(--focus-outline-around); + border-radius: 2px; + position: absolute; +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers + > .resizer.topLeft { + top: var(--resizer-shift); + left: var(--resizer-shift); +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers + > .resizer.topMiddle { + top: var(--resizer-shift); + left: calc(50% + var(--resizer-shift)); +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers + > .resizer.topRight { + top: var(--resizer-shift); + right: var(--resizer-shift); +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers + > .resizer.middleRight { + top: calc(50% + var(--resizer-shift)); + right: var(--resizer-shift); +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers + > .resizer.bottomRight { + bottom: var(--resizer-shift); + right: var(--resizer-shift); +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers + > .resizer.bottomMiddle { + bottom: var(--resizer-shift); + left: calc(50% + var(--resizer-shift)); +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers + > .resizer.bottomLeft { + bottom: var(--resizer-shift); + left: var(--resizer-shift); +} + +.annotationEditorLayer + :is(.freeTextEditor, .inkEditor, .stampEditor) + > .resizers + > .resizer.middleLeft { + top: calc(50% + var(--resizer-shift)); + left: var(--resizer-shift); +} + +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.topLeft, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.topLeft, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.topLeft, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.topLeft, +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.bottomRight, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.bottomRight, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.bottomRight, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.bottomRight { + cursor: nwse-resize; +} + +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.topMiddle, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.topMiddle, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.topMiddle, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.topMiddle, +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.bottomMiddle, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.bottomMiddle, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.bottomMiddle, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.bottomMiddle { + cursor: ns-resize; +} + +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.topRight, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.topRight, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.topRight, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.topRight, +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.bottomLeft, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.bottomLeft, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.bottomLeft, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.bottomLeft { + cursor: nesw-resize; +} + +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.middleRight, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.middleRight, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.middleRight, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.middleRight, +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.middleLeft, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.middleLeft, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.middleLeft, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.middleLeft { + cursor: ew-resize; +} + +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.topLeft, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.topLeft, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.topLeft, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.topLeft, +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.bottomRight, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.bottomRight, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.bottomRight, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.bottomRight { + cursor: nesw-resize; +} + +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.topMiddle, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.topMiddle, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.topMiddle, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.topMiddle, +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.bottomMiddle, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.bottomMiddle, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.bottomMiddle, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.bottomMiddle { + cursor: ew-resize; +} + +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.topRight, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.topRight, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.topRight, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.topRight, +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.bottomLeft, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.bottomLeft, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.bottomLeft, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.bottomLeft { + cursor: nwse-resize; +} + +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.middleRight, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.middleRight, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.middleRight, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.middleRight, +.annotationEditorLayer[data-main-rotation="0"] + :is([data-editor-rotation="90"], [data-editor-rotation="270"]) + > .resizers + > .resizer.middleLeft, +.annotationEditorLayer[data-main-rotation="90"] + :is([data-editor-rotation="0"], [data-editor-rotation="180"]) + > .resizers + > .resizer.middleLeft, +.annotationEditorLayer[data-main-rotation="180"] + :is([data-editor-rotation="270"], [data-editor-rotation="90"]) + > .resizers + > .resizer.middleLeft, +.annotationEditorLayer[data-main-rotation="270"] + :is([data-editor-rotation="180"], [data-editor-rotation="0"]) + > .resizers + > .resizer.middleLeft { + cursor: ns-resize; +} + +.annotationEditorLayer + :is( + [data-main-rotation="0"] [data-editor-rotation="90"], + [data-main-rotation="90"] [data-editor-rotation="0"], + [data-main-rotation="180"] [data-editor-rotation="270"], + [data-main-rotation="270"] [data-editor-rotation="180"] + ) + .editToolbar { + rotate: 270deg; +} + +[dir="ltr"] + .annotationEditorLayer + :is( + [data-main-rotation="0"] [data-editor-rotation="90"], + [data-main-rotation="90"] [data-editor-rotation="0"], + [data-main-rotation="180"] [data-editor-rotation="270"], + [data-main-rotation="270"] [data-editor-rotation="180"] + ) + .editToolbar { + inset-inline-end: calc(0px - var(--editor-toolbar-vert-offset)); + inset-block-start: 0; +} + +[dir="rtl"] + .annotationEditorLayer + :is( + [data-main-rotation="0"] [data-editor-rotation="90"], + [data-main-rotation="90"] [data-editor-rotation="0"], + [data-main-rotation="180"] [data-editor-rotation="270"], + [data-main-rotation="270"] [data-editor-rotation="180"] + ) + .editToolbar { + inset-inline-end: calc(100% + var(--editor-toolbar-vert-offset)); + inset-block-start: 0; +} + +.annotationEditorLayer + :is( + [data-main-rotation="0"] [data-editor-rotation="180"], + [data-main-rotation="90"] [data-editor-rotation="90"], + [data-main-rotation="180"] [data-editor-rotation="0"], + [data-main-rotation="270"] [data-editor-rotation="270"] + ) + .editToolbar { + rotate: 180deg; + inset-inline-end: 100%; + inset-block-start: calc(0pc - var(--editor-toolbar-vert-offset)); +} + +.annotationEditorLayer + :is( + [data-main-rotation="0"] [data-editor-rotation="270"], + [data-main-rotation="90"] [data-editor-rotation="180"], + [data-main-rotation="180"] [data-editor-rotation="90"], + [data-main-rotation="270"] [data-editor-rotation="0"] + ) + .editToolbar { + rotate: 90deg; +} + +[dir="ltr"] + .annotationEditorLayer + :is( + [data-main-rotation="0"] [data-editor-rotation="270"], + [data-main-rotation="90"] [data-editor-rotation="180"], + [data-main-rotation="180"] [data-editor-rotation="90"], + [data-main-rotation="270"] [data-editor-rotation="0"] + ) + .editToolbar { + inset-inline-end: calc(100% + var(--editor-toolbar-vert-offset)); + inset-block-start: 100%; +} + +[dir="rtl"] + .annotationEditorLayer + :is( + [data-main-rotation="0"] [data-editor-rotation="270"], + [data-main-rotation="90"] [data-editor-rotation="180"], + [data-main-rotation="180"] [data-editor-rotation="90"], + [data-main-rotation="270"] [data-editor-rotation="0"] + ) + .editToolbar { + inset-inline-start: calc(0px - var(--editor-toolbar-vert-offset)); + inset-block-start: 0; +} + +.dialog.altText::backdrop { + -webkit-mask: url(#alttext-manager-mask); + mask: url(#alttext-manager-mask); +} + +.dialog.altText.positioned { + margin: 0; +} + +.dialog.altText #altTextContainer { + width: 300px; + height: -moz-fit-content; + height: fit-content; + display: inline-flex; + flex-direction: column; + align-items: flex-start; + gap: 16px; +} + +.dialog.altText #altTextContainer #overallDescription { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 4px; + align-self: stretch; +} + +.dialog.altText #altTextContainer #overallDescription span { + align-self: stretch; +} + +.dialog.altText #altTextContainer #overallDescription .title { + font-size: 13px; + font-style: normal; + font-weight: 590; +} + +.dialog.altText #altTextContainer #addDescription { + display: flex; + flex-direction: column; + align-items: stretch; + gap: 8px; +} + +.dialog.altText #altTextContainer #addDescription .descriptionArea { + flex: 1; + padding-inline: 24px 10px; +} + +.dialog.altText #altTextContainer #addDescription .descriptionArea textarea { + width: 100%; + min-height: 75px; +} + +.dialog.altText #altTextContainer #buttons { + display: flex; + justify-content: flex-end; + align-items: flex-start; + gap: 8px; + align-self: stretch; +} + +.colorPicker { + --hover-outline-color: #0250bb; + --selected-outline-color: #0060df; + --swatch-border-color: #cfcfd8; +} + +@media (prefers-color-scheme: dark) { + :where(html:not(.is-light)) .colorPicker { + --hover-outline-color: #80ebff; + --selected-outline-color: #aaf2ff; + --swatch-border-color: #52525e; + } +} + +:where(html.is-dark) .colorPicker { + --hover-outline-color: #80ebff; + --selected-outline-color: #aaf2ff; + --swatch-border-color: #52525e; +} + +@media screen and (forced-colors: active) { + .colorPicker { + --hover-outline-color: Highlight; + --selected-outline-color: var(--hover-outline-color); + --swatch-border-color: ButtonText; + } +} + +.colorPicker .swatch { + width: 16px; + height: 16px; + border: 1px solid var(--swatch-border-color); + border-radius: 100%; + outline-offset: 2px; + box-sizing: border-box; + forced-color-adjust: none; +} + +.colorPicker button:is(:hover, .selected) > .swatch { + border: none; +} + +.annotationEditorLayer[data-main-rotation="0"] + .highlightEditor:not(.free) + > .editToolbar { + rotate: 0deg; +} + +.annotationEditorLayer[data-main-rotation="90"] + .highlightEditor:not(.free) + > .editToolbar { + rotate: 270deg; +} + +.annotationEditorLayer[data-main-rotation="180"] + .highlightEditor:not(.free) + > .editToolbar { + rotate: 180deg; +} + +.annotationEditorLayer[data-main-rotation="270"] + .highlightEditor:not(.free) + > .editToolbar { + rotate: 90deg; +} + +.annotationEditorLayer .highlightEditor { + position: absolute; + background: transparent; + z-index: 1; + cursor: auto; + max-width: 100%; + max-height: 100%; + border: none; + outline: none; + pointer-events: none; + transform-origin: 0 0; +} + +.annotationEditorLayer .highlightEditor:not(.free) { + transform: none; +} + +.annotationEditorLayer .highlightEditor .internal { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + pointer-events: auto; +} + +.annotationEditorLayer .highlightEditor.disabled .internal { + pointer-events: none; +} + +.annotationEditorLayer .highlightEditor.selectedEditor .internal { + cursor: pointer; +} + +.annotationEditorLayer .highlightEditor .editToolbar { + --editor-toolbar-colorpicker-arrow-image: url(../images/toolbarButton-menuArrow.svg); + + transform-origin: center !important; +} + +.annotationEditorLayer .highlightEditor .editToolbar .buttons .colorPicker { + position: relative; + width: auto; + display: flex; + justify-content: center; + align-items: center; + gap: 4px; + padding: 4px; +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker::after { + content: ""; + -webkit-mask-image: var(--editor-toolbar-colorpicker-arrow-image); + mask-image: var(--editor-toolbar-colorpicker-arrow-image); + -webkit-mask-repeat: no-repeat; + mask-repeat: no-repeat; + -webkit-mask-position: center; + mask-position: center; + display: inline-block; + background-color: var(--editor-toolbar-fg-color); + width: 12px; + height: 12px; +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker:hover::after { + background-color: var(--editor-toolbar-hover-fg-color); +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker:has(.dropdown:not(.hidden)) { + background-color: var(--editor-toolbar-hover-bg-color); +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker:has(.dropdown:not(.hidden))::after { + scale: -1; +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker + .dropdown { + position: absolute; + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + gap: 11px; + padding-block: 8px; + border-radius: 6px; + background-color: var(--editor-toolbar-bg-color); + border: 1px solid var(--editor-toolbar-border-color); + box-shadow: var(--editor-toolbar-shadow); + inset-block-start: calc(100% + 4px); + width: calc(100% + 2 * var(--editor-toolbar-padding)); +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker + .dropdown + button { + width: 100%; + height: auto; + border: none; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + background: none; +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker + .dropdown + button:is(:active, :focus-visible) { + outline: none; +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker + .dropdown + button + > .swatch { + outline-offset: 2px; +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker + .dropdown + button[aria-selected="true"] + > .swatch { + outline: 2px solid var(--selected-outline-color); +} + +.annotationEditorLayer + .highlightEditor + .editToolbar + .buttons + .colorPicker + .dropdown + button:is(:hover, :active, :focus-visible) + > .swatch { + outline: 2px solid var(--hover-outline-color); +} + +.editorParamsToolbar:has(#highlightParamsToolbarContainer) { + padding: unset; +} + +#highlightParamsToolbarContainer { + height: auto; + padding-inline: 10px; + padding-block: 10px 16px; + gap: 16px; + display: flex; + flex-direction: column; + box-sizing: border-box; +} + +#highlightParamsToolbarContainer .editorParamsLabel { + width: -moz-fit-content; + width: fit-content; + inset-inline-start: 0; +} + +#highlightParamsToolbarContainer .colorPicker { + display: flex; + flex-direction: column; + gap: 8px; +} + +#highlightParamsToolbarContainer .colorPicker .dropdown { + display: flex; + justify-content: space-between; + align-items: center; + flex-direction: row; + height: auto; +} + +#highlightParamsToolbarContainer .colorPicker .dropdown button { + width: auto; + height: auto; + border: none; + cursor: pointer; + display: flex; + justify-content: center; + align-items: center; + background: none; + flex: 0 0 auto; +} + +#highlightParamsToolbarContainer .colorPicker .dropdown button .swatch { + width: 24px; + height: 24px; +} + +#highlightParamsToolbarContainer + .colorPicker + .dropdown + button:is(:active, :focus-visible) { + outline: none; +} + +#highlightParamsToolbarContainer + .colorPicker + .dropdown + button[aria-selected="true"] + > .swatch { + outline: 2px solid var(--selected-outline-color); +} + +#highlightParamsToolbarContainer + .colorPicker + .dropdown + button:is(:hover, :active, :focus-visible) + > .swatch { + outline: 2px solid var(--hover-outline-color); +} + +#highlightParamsToolbarContainer #editorHighlightThickness { + display: flex; + flex-direction: column; + align-items: center; + gap: 4px; + align-self: stretch; +} + +#highlightParamsToolbarContainer #editorHighlightThickness .editorParamsLabel { + width: 100%; + height: auto; + align-self: stretch; +} + +#highlightParamsToolbarContainer #editorHighlightThickness .thicknessPicker { + display: flex; + justify-content: space-between; + align-items: center; + align-self: stretch; + + --example-color: #bfbfc9; +} + +@media (prefers-color-scheme: dark) { + :where(html:not(.is-light)) + #highlightParamsToolbarContainer + #editorHighlightThickness + .thicknessPicker { + --example-color: #80808e; + } +} + +:where(html.is-dark) + #highlightParamsToolbarContainer + #editorHighlightThickness + .thicknessPicker { + --example-color: #80808e; +} + +@media screen and (forced-colors: active) { + #highlightParamsToolbarContainer #editorHighlightThickness .thicknessPicker { + --example-color: CanvasText; + } +} + +:is( + #highlightParamsToolbarContainer + #editorHighlightThickness + .thicknessPicker + > .editorParamsSlider[disabled] + ) { + opacity: 0.4; +} + +#highlightParamsToolbarContainer + #editorHighlightThickness + .thicknessPicker::before, +#highlightParamsToolbarContainer + #editorHighlightThickness + .thicknessPicker::after { + content: ""; + width: 8px; + aspect-ratio: 1; + display: block; + border-radius: 100%; + background-color: var(--example-color); +} + +#highlightParamsToolbarContainer + #editorHighlightThickness + .thicknessPicker::after { + width: 24px; +} + +#highlightParamsToolbarContainer + #editorHighlightThickness + .thicknessPicker + .editorParamsSlider { + width: unset; + height: 14px; +} + +#highlightParamsToolbarContainer #editorHighlightVisibility { + display: flex; + flex-direction: column; + align-items: flex-start; + gap: 8px; + align-self: stretch; +} + +#highlightParamsToolbarContainer #editorHighlightVisibility .divider { + --divider-color: #d7d7db; + + margin-block: 4px; + width: 100%; + height: 1px; + background-color: var(--divider-color); +} + +@media (prefers-color-scheme: dark) { + :where(html:not(.is-light)) + #highlightParamsToolbarContainer + #editorHighlightVisibility + .divider { + --divider-color: #8f8f9d; + } +} + +:where(html.is-dark) + #highlightParamsToolbarContainer + #editorHighlightVisibility + .divider { + --divider-color: #8f8f9d; +} + +@media screen and (forced-colors: active) { + #highlightParamsToolbarContainer #editorHighlightVisibility .divider { + --divider-color: CanvasText; + } +} + +#highlightParamsToolbarContainer #editorHighlightVisibility .toggler { + display: flex; + justify-content: space-between; + align-items: center; + align-self: stretch; +} + +:root { + --viewer-container-height: 0; + --pdfViewer-padding-bottom: 0; + --page-margin: 10px auto; + --page-border: 9px solid transparent; + --spreadHorizontalWrapped-margin-LR: -3.5px; + --loading-icon-delay: 400ms; +} + +@media screen and (forced-colors: active) { + :root { + --pdfViewer-padding-bottom: 9px; + --page-margin: 10px auto; + --page-border: 1px solid CanvasText; + --spreadHorizontalWrapped-margin-LR: 3.5px; + } +} + +[data-main-rotation="90"] { + transform: rotate(90deg) translateY(-100%); +} +[data-main-rotation="180"] { + transform: rotate(180deg) translate(-100%, -100%); +} +[data-main-rotation="270"] { + transform: rotate(270deg) translateX(-100%); +} + +#hiddenCopyElement, +.hiddenCanvasElement { + position: absolute; + top: 0; + left: 0; + width: 0; + height: 0; + display: none; +} + +.pdfViewer { + --scale-factor: 1; + + padding-bottom: var(--pdfViewer-padding-bottom); + + --hcm-highlight-filter: none; + --hcm-highlight-selected-filter: none; +} + +@media screen and (forced-colors: active) { + .pdfViewer { + --hcm-highlight-filter: invert(100%); + } +} + +.pdfViewer .canvasWrapper { + width: 100%; + height: 100%; +} + +.pdfViewer .canvasWrapper canvas { + margin: 0; + display: block; +} + +.pdfViewer .canvasWrapper canvas[hidden] { + display: none; +} + +.pdfViewer .canvasWrapper canvas[zooming] { + width: 100%; + height: 100%; +} + +.pdfViewer .canvasWrapper canvas .structTree { + contain: strict; +} + +.pdfViewer .page { + direction: ltr; + width: 816px; + height: 1056px; + margin: var(--page-margin); + position: relative; + overflow: visible; + border: var(--page-border); + background-clip: content-box; + background-color: rgb(255 255 255); +} + +.pdfViewer .dummyPage { + position: relative; + width: 0; + height: var(--viewer-container-height); +} + +.pdfViewer.noUserSelect { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.pdfViewer.removePageBorders .page { + margin: 0 auto 10px; + border: none; +} + +.pdfViewer:is(.scrollHorizontal, .scrollWrapped), +.spread { + margin-inline: 3.5px; + text-align: center; +} + +.pdfViewer.scrollHorizontal, +.spread { + white-space: nowrap; +} + +.pdfViewer.removePageBorders, +.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .spread { + margin-inline: 0; +} + +.spread :is(.page, .dummyPage), +.pdfViewer:is(.scrollHorizontal, .scrollWrapped) :is(.page, .spread) { + display: inline-block; + vertical-align: middle; +} + +.spread .page, +.pdfViewer:is(.scrollHorizontal, .scrollWrapped) .page { + margin-inline: var(--spreadHorizontalWrapped-margin-LR); +} + +.pdfViewer.removePageBorders .spread .page, +.pdfViewer.removePageBorders:is(.scrollHorizontal, .scrollWrapped) .page { + margin-inline: 5px; +} + +.pdfViewer .page.loadingIcon::after { + position: absolute; + top: 0; + left: 0; + content: ""; + width: 100%; + height: 100%; + background: url("../images/loading-icon.gif") center no-repeat; + display: none; + transition-property: display; + transition-delay: var(--loading-icon-delay); + z-index: 5; + contain: strict; +} + +.pdfViewer .page.loading::after { + display: block; +} + +.pdfViewer .page:not(.loading)::after { + transition-property: none; + display: none; +} + +.pdfPresentationMode .pdfViewer { + padding-bottom: 0; +} + +.pdfPresentationMode .spread { + margin: 0; +} + +.pdfPresentationMode .pdfViewer .page { + margin: 0 auto; + border: 2px solid transparent; +} + +html[data-toolbar-density="compact"] { + --toolbar-height: 1.875rem; +} + +html[data-toolbar-density="touch"] { + --toolbar-height: 2.75rem; +} + +:root { + --dir-factor: 1; + --inline-start: left; + --inline-end: right; + + --sidebar-width: 200px; + --sidebar-transition-duration: 200ms; + --sidebar-transition-timing-function: ease; + + --toolbar-height: 3.75rem; + --toolButton-height: 3rem; + --toolButton-width: 3rem; + --toolButton-icon-font-size: 2.5rem; + --toolButton-border-radius: 15px; + + --toolbar-icon-opacity: 0.7; + --doorhanger-icon-opacity: 0.9; + --editor-toolbar-base-offset: 105px; + + --main-color: rgb(12 12 13); + --body-bg-color: rgb(212 212 215); + --progressBar-color: rgb(10 132 255); + --progressBar-bg-color: rgb(221 221 222); + --progressBar-blend-color: rgb(116 177 239); + --scrollbar-color: auto; + --scrollbar-bg-color: auto; + --toolbar-icon-bg-color: rgb(0 0 0); + --toolbar-icon-hover-bg-color: rgb(0 0 0); + + --sidebar-narrow-bg-color: rgb(212 212 215 / 0.9); + --sidebar-toolbar-bg-color: rgb(245 246 247); + --toolbar-bg-color: rgb(249 249 250); + --toolbar-border-color: rgb(184 184 184); + --toolbar-box-shadow: 0 1px 0 var(--toolbar-border-color); + --toolbar-border-bottom: none; + --toolbarSidebar-box-shadow: inset calc(-1px * var(--dir-factor)) 0 0 + rgb(0 0 0 / 0.25), + 0 1px 0 rgb(0 0 0 / 0.15), 0 0 1px rgb(0 0 0 / 0.1); + --toolbarSidebar-border-bottom: none; + --button-hover-color: rgb(221 222 223); + --toggled-btn-color: rgb(0 0 0); + --toggled-btn-bg-color: rgb(0 0 0 / 0.3); + --toggled-hover-active-btn-color: rgb(0 0 0 / 0.4); + --toggled-hover-btn-outline: none; + --dropdown-btn-bg-color: rgb(215 215 219); + --dropdown-btn-border: none; + --separator-color: rgb(0 0 0 / 0.3); + --field-color: rgb(6 6 6); + --field-bg-color: rgb(255 255 255); + --field-border-color: rgb(187 187 188); + --treeitem-color: rgb(0 0 0 / 0.8); + --treeitem-bg-color: rgb(0 0 0 / 0.15); + --treeitem-hover-color: rgb(0 0 0 / 0.9); + --treeitem-selected-color: rgb(0 0 0 / 0.9); + --treeitem-selected-bg-color: rgb(0 0 0 / 0.25); + --thumbnail-hover-color: rgb(0 0 0 / 0.1); + --thumbnail-selected-color: rgb(0 0 0 / 0.2); + --doorhanger-bg-color: rgb(255 255 255); + --doorhanger-border-color: rgb(12 12 13 / 0.2); + --doorhanger-hover-color: rgb(12 12 13); + --doorhanger-hover-bg-color: rgb(237 237 237); + --doorhanger-separator-color: rgb(222 222 222); + --dialog-button-border: none; + --dialog-button-bg-color: rgb(12 12 13 / 0.1); + --dialog-button-hover-bg-color: rgb(12 12 13 / 0.3); + + --loading-icon: url(../images/loading.svg); + --treeitem-expanded-icon: url(../images/treeitem-expanded.svg); + --treeitem-collapsed-icon: url(../images/treeitem-collapsed.svg); + --toolbarButton-editorFreeText-icon: url(../images/toolbarButton-editorFreeText.svg); + --toolbarButton-editorHighlight-icon: url(../images/toolbarButton-editorHighlight.svg); + --toolbarButton-editorInk-icon: url(../images/toolbarButton-editorInk.svg); + --toolbarButton-editorStamp-icon: url(../images/toolbarButton-editorStamp.svg); + --toolbarButton-menuArrow-icon: url(../images/toolbarButton-menuArrow.svg); + --toolbarButton-sidebarToggle-icon: url(../images/toolbarButton-sidebarToggle.svg); + --toolbarButton-secondaryToolbarToggle-icon: url(../images/toolbarButton-secondaryToolbarToggle.svg); + --toolbarButton-pageUp-icon: url(../images/toolbarButton-pageUp.svg); + --toolbarButton-pageDown-icon: url(../images/toolbarButton-pageDown.svg); + --toolbarButton-zoomOut-icon: url(../images/toolbarButton-zoomOut.svg); + --toolbarButton-zoomIn-icon: url(../images/toolbarButton-zoomIn.svg); + --toolbarButton-presentationMode-icon: url(../images/toolbarButton-presentationMode.svg); + --toolbarButton-print-icon: url(../images/toolbarButton-print.svg); + --toolbarButton-openFile-icon: url(../images/toolbarButton-openFile.svg); + --toolbarButton-download-icon: url(../images/toolbarButton-download.svg); + --toolbarButton-bookmark-icon: url(../images/toolbarButton-bookmark.svg); + --toolbarButton-viewThumbnail-icon: url(../images/toolbarButton-viewThumbnail.svg); + --toolbarButton-viewOutline-icon: url(../images/toolbarButton-viewOutline.svg); + --toolbarButton-viewAttachments-icon: url(../images/toolbarButton-viewAttachments.svg); + --toolbarButton-viewLayers-icon: url(../images/toolbarButton-viewLayers.svg); + --toolbarButton-currentOutlineItem-icon: url(../images/toolbarButton-currentOutlineItem.svg); + --toolbarButton-search-icon: url(../images/toolbarButton-search.svg); + --toolbarButton-backToHome-icon: url(../images/toolbarButton-home.svg); + --findbarButton-previous-icon: url(../images/findbarButton-previous.svg); + --findbarButton-next-icon: url(../images/findbarButton-next.svg); + --secondaryToolbarButton-firstPage-icon: url(../images/secondaryToolbarButton-firstPage.svg); + --secondaryToolbarButton-lastPage-icon: url(../images/secondaryToolbarButton-lastPage.svg); + --secondaryToolbarButton-rotateCcw-icon: url(../images/secondaryToolbarButton-rotateCcw.svg); + --secondaryToolbarButton-rotateCw-icon: url(../images/secondaryToolbarButton-rotateCw.svg); + --secondaryToolbarButton-selectTool-icon: url(../images/secondaryToolbarButton-selectTool.svg); + --secondaryToolbarButton-handTool-icon: url(../images/secondaryToolbarButton-handTool.svg); + --secondaryToolbarButton-scrollPage-icon: url(../images/secondaryToolbarButton-scrollPage.svg); + --secondaryToolbarButton-scrollVertical-icon: url(../images/secondaryToolbarButton-scrollVertical.svg); + --secondaryToolbarButton-scrollHorizontal-icon: url(../images/secondaryToolbarButton-scrollHorizontal.svg); + --secondaryToolbarButton-scrollWrapped-icon: url(../images/secondaryToolbarButton-scrollWrapped.svg); + --secondaryToolbarButton-spreadNone-icon: url(../images/secondaryToolbarButton-spreadNone.svg); + --secondaryToolbarButton-spreadOdd-icon: url(../images/secondaryToolbarButton-spreadOdd.svg); + --secondaryToolbarButton-spreadEven-icon: url(../images/secondaryToolbarButton-spreadEven.svg); + --secondaryToolbarButton-documentProperties-icon: url(../images/secondaryToolbarButton-documentProperties.svg); + --editorParams-stampAddImage-icon: url(../images/toolbarButton-zoomIn.svg); +} + +[dir="rtl"]:root { + --dir-factor: -1; + --inline-start: right; + --inline-end: left; +} + +@media (prefers-color-scheme: dark) { + :root:where(:not(.is-light)) { + --main-color: rgb(249 249 250); + --body-bg-color: rgb(42 42 46); + --progressBar-color: rgb(0 96 223); + --progressBar-bg-color: rgb(40 40 43); + --progressBar-blend-color: rgb(20 68 133); + --scrollbar-color: rgb(121 121 123); + --scrollbar-bg-color: rgb(35 35 39); + --toolbar-icon-bg-color: rgb(255 255 255); + --toolbar-icon-hover-bg-color: rgb(255 255 255); + + --sidebar-narrow-bg-color: rgb(42 42 46 / 0.9); + --sidebar-toolbar-bg-color: rgb(50 50 52); + --toolbar-bg-color: rgb(56 56 61); + --toolbar-border-color: rgb(12 12 13); + --button-hover-color: rgb(102 102 103); + --toggled-btn-color: rgb(255 255 255); + --toggled-btn-bg-color: rgb(0 0 0 / 0.3); + --toggled-hover-active-btn-color: rgb(0 0 0 / 0.4); + --dropdown-btn-bg-color: rgb(74 74 79); + --separator-color: rgb(0 0 0 / 0.3); + --field-color: rgb(250 250 250); + --field-bg-color: rgb(64 64 68); + --field-border-color: rgb(115 115 115); + --treeitem-color: rgb(255 255 255 / 0.8); + --treeitem-bg-color: rgb(255 255 255 / 0.15); + --treeitem-hover-color: rgb(255 255 255 / 0.9); + --treeitem-selected-color: rgb(255 255 255 / 0.9); + --treeitem-selected-bg-color: rgb(255 255 255 / 0.25); + --thumbnail-hover-color: rgb(255 255 255 / 0.1); + --thumbnail-selected-color: rgb(255 255 255 / 0.2); + --doorhanger-bg-color: rgb(74 74 79); + --doorhanger-border-color: rgb(39 39 43); + --doorhanger-hover-color: rgb(249 249 250); + --doorhanger-hover-bg-color: rgb(93 94 98); + --doorhanger-separator-color: rgb(92 92 97); + --dialog-button-bg-color: rgb(92 92 97); + --dialog-button-hover-bg-color: rgb(115 115 115); + } +} + +:root:where(.is-dark) { + --main-color: rgb(249 249 250); + --body-bg-color: rgb(42 42 46); + --progressBar-color: rgb(0 96 223); + --progressBar-bg-color: rgb(40 40 43); + --progressBar-blend-color: rgb(20 68 133); + --scrollbar-color: rgb(121 121 123); + --scrollbar-bg-color: rgb(35 35 39); + --toolbar-icon-bg-color: rgb(255 255 255); + --toolbar-icon-hover-bg-color: rgb(255 255 255); + + --sidebar-narrow-bg-color: rgb(42 42 46 / 0.9); + --sidebar-toolbar-bg-color: rgb(50 50 52); + --toolbar-bg-color: rgb(56 56 61); + --toolbar-border-color: rgb(12 12 13); + --button-hover-color: rgb(102 102 103); + --toggled-btn-color: rgb(255 255 255); + --toggled-btn-bg-color: rgb(0 0 0 / 0.3); + --toggled-hover-active-btn-color: rgb(0 0 0 / 0.4); + --dropdown-btn-bg-color: rgb(74 74 79); + --separator-color: rgb(0 0 0 / 0.3); + --field-color: rgb(250 250 250); + --field-bg-color: rgb(64 64 68); + --field-border-color: rgb(115 115 115); + --treeitem-color: rgb(255 255 255 / 0.8); + --treeitem-bg-color: rgb(255 255 255 / 0.15); + --treeitem-hover-color: rgb(255 255 255 / 0.9); + --treeitem-selected-color: rgb(255 255 255 / 0.9); + --treeitem-selected-bg-color: rgb(255 255 255 / 0.25); + --thumbnail-hover-color: rgb(255 255 255 / 0.1); + --thumbnail-selected-color: rgb(255 255 255 / 0.2); + --doorhanger-bg-color: rgb(74 74 79); + --doorhanger-border-color: rgb(39 39 43); + --doorhanger-hover-color: rgb(249 249 250); + --doorhanger-hover-bg-color: rgb(93 94 98); + --doorhanger-separator-color: rgb(92 92 97); + --dialog-button-bg-color: rgb(92 92 97); + --dialog-button-hover-bg-color: rgb(115 115 115); +} + +@media screen and (forced-colors: active) { + :root { + --button-hover-color: Highlight; + --doorhanger-hover-bg-color: Highlight; + --toolbar-icon-opacity: 1; + --toolbar-icon-bg-color: ButtonText; + --toolbar-icon-hover-bg-color: ButtonFace; + --toggled-hover-active-btn-color: ButtonText; + --toggled-hover-btn-outline: 2px solid ButtonBorder; + --toolbar-border-color: CanvasText; + --toolbar-border-bottom: 1px solid var(--toolbar-border-color); + --toolbar-box-shadow: none; + --toggled-btn-color: HighlightText; + --toggled-btn-bg-color: LinkText; + --doorhanger-hover-color: ButtonFace; + --doorhanger-border-color-whcm: 1px solid ButtonText; + --doorhanger-triangle-opacity-whcm: 0; + --dialog-button-border: 1px solid Highlight; + --dialog-button-hover-bg-color: Highlight; + --dialog-button-hover-color: ButtonFace; + --dropdown-btn-border: 1px solid ButtonText; + --field-border-color: ButtonText; + --main-color: CanvasText; + --separator-color: GrayText; + --doorhanger-separator-color: GrayText; + --toolbarSidebar-box-shadow: none; + --toolbarSidebar-border-bottom: 1px solid var(--toolbar-border-color); + } +} + +@media screen and (prefers-reduced-motion: reduce) { + :root { + --sidebar-transition-duration: 0; + } +} + +* { + padding: 0; + margin: 0; +} + +html, +body { + height: 100%; + width: 100%; +} + +.hidden, +[hidden] { + display: none !important; +} + +#viewerContainer.pdfPresentationMode:fullscreen { + top: 0; + background-color: rgb(0 0 0); + width: 100%; + height: 100%; + overflow: hidden; + cursor: none; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.pdfPresentationMode:fullscreen section:not([data-internal-link]) { + pointer-events: none; +} + +.pdfPresentationMode:fullscreen .textLayer span { + cursor: none; +} + +.pdfPresentationMode.pdfPresentationModeControls > *, +.pdfPresentationMode.pdfPresentationModeControls .textLayer span { + cursor: default; +} + +#outerContainer { + width: 100%; + height: calc(100% - var(--navbar-height)); + position: relative; +} + +#sidebarContainer { + position: absolute; + inset-block: var(--toolbar-height) 0; + inset-inline-start: calc(-1 * var(--sidebar-width)); + width: var(--sidebar-width); + visibility: hidden; + z-index: 100; + font: message-box; + border-top: 1px solid rgb(51 51 51); + border-inline-end: var(--doorhanger-border-color-whcm); + transition-property: inset-inline-start; + transition-duration: var(--sidebar-transition-duration); + transition-timing-function: var(--sidebar-transition-timing-function); +} + +#outerContainer:is(.sidebarMoving, .sidebarOpen) #sidebarContainer { + visibility: visible; +} +#outerContainer.sidebarOpen #sidebarContainer { + inset-inline-start: 0; +} + +#mainContainer { + position: absolute; + inset: 0; + min-width: 350px; +} + +#sidebarContent { + inset-block: var(--toolbar-height) 0; + inset-inline-start: 0; + overflow: auto; + position: absolute; + width: 100%; + box-shadow: inset calc(-1px * var(--dir-factor)) 0 0 rgb(0 0 0 / 0.25); +} + +#viewerContainer { + overflow: auto; + position: absolute; + inset: var(--toolbar-height) 0 0; + outline: none; +} +#viewerContainer:not(.pdfPresentationMode) { + transition-duration: var(--sidebar-transition-duration); + transition-timing-function: var(--sidebar-transition-timing-function); +} + +#outerContainer.sidebarOpen #viewerContainer:not(.pdfPresentationMode) { + inset-inline-start: var(--sidebar-width); + transition-property: inset-inline-start; +} + +.toolbar { + position: relative; + inset-inline: 0; + z-index: 20; + cursor: default; + font: message-box; +} + +:is(.toolbar, .editorParamsToolbar, .findbar, #sidebarContainer) + :is(input, button, select), +.secondaryToolbar :is(input, button, a, select) { + outline: none; + font: message-box; +} + +#toolbarContainer { + width: 100%; + border-radius: 5px; +} + +#toolbarSidebar { + width: 100%; + height: var(--toolbar-height); + background-color: var(--sidebar-toolbar-bg-color); + box-shadow: var(--toolbarSidebar-box-shadow); + border-bottom: var(--toolbarSidebar-border-bottom); +} + +#sidebarResizer { + position: absolute; + inset-block: 0; + inset-inline-end: -6px; + width: 6px; + z-index: 200; + cursor: ew-resize; +} + +#toolbarContainer, +.findbar, +.secondaryToolbar, +.editorParamsToolbar { + position: relative; + height: var(--toolbar-height); + /* background-color:var(--toolbar-bg-color); */ + background-color: var(--md-sys-color-surface-5); + box-shadow: var(--toolbar-box-shadow); + border-bottom: var(--toolbar-border-bottom); +} + +#toolbarViewer { + height: var(--toolbar-height); + display: flex; + flex-wrap: wrap; + justify-content: space-between; +} + +#loadingBar { + --progressBar-percent: 0%; + --progressBar-end-offset: 0; + + position: absolute; + inset-inline: 0 var(--progressBar-end-offset); + height: 4px; + background-color: var(--progressBar-bg-color); + border-bottom: 1px solid var(--toolbar-border-color); + transition-property: inset-inline-start; + transition-duration: var(--sidebar-transition-duration); + transition-timing-function: var(--sidebar-transition-timing-function); +} + +#outerContainer.sidebarOpen #loadingBar { + inset-inline-start: var(--sidebar-width); +} + +#loadingBar .progress { + position: absolute; + top: 0; + inset-inline-start: 0; + width: 100%; + transform: scaleX(var(--progressBar-percent)); + transform-origin: calc(50% - 50% * var(--dir-factor)) 0; + height: 100%; + background-color: var(--progressBar-color); + overflow: hidden; + transition: transform 200ms; +} + +@keyframes progressIndeterminate { + 0% { + transform: translateX(calc(-142px * var(--dir-factor))); + } + 100% { + transform: translateX(0); + } +} + +#loadingBar.indeterminate .progress { + transform: none; + background-color: var(--progressBar-bg-color); + transition: none; +} + +#loadingBar.indeterminate .progress .glimmer { + position: absolute; + top: 0; + inset-inline-start: 0; + height: 100%; + width: calc(100% + 150px); + background: repeating-linear-gradient( + 135deg, + var(--progressBar-blend-color) 0, + var(--progressBar-bg-color) 5px, + var(--progressBar-bg-color) 45px, + var(--progressBar-color) 55px, + var(--progressBar-color) 95px, + var(--progressBar-blend-color) 100px + ); + animation: progressIndeterminate 1s linear infinite; +} + +#outerContainer.sidebarResizing + :is(#sidebarContainer, #viewerContainer, #loadingBar) { + transition-duration: 0s; +} + +.findbar, +.secondaryToolbar, +.editorParamsToolbar { + top: 32px; + position: absolute; + z-index: 30000; + height: auto; + padding: 0 4px; + margin: 4px 2px; + font: message-box; + font-size: 12px; + line-height: 14px; + text-align: left; + cursor: default; +} + +.findbar { + inset-inline-start: 64px; + min-width: 300px; + background-color: var(--toolbar-bg-color); +} +.findbar > div { + /* height:32px; */ + height: var(--toolbar-height); +} +.findbar > div#findbarInputContainer { + margin-inline-end: 4px; +} +.findbar.wrapContainers > div, +.findbar.wrapContainers > div#findbarMessageContainer > * { + clear: both; +} +.findbar.wrapContainers > div#findbarMessageContainer { + height: auto; +} + +.findbar input[type="checkbox"] { + pointer-events: none; +} + +.findbar label { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} + +.findbar label:hover, +.findbar input:focus-visible + label { + color: var(--toggled-btn-color); + background-color: var(--button-hover-color); +} + +.findbar .toolbarField[type="checkbox"]:checked + .toolbarLabel { + background-color: var(--toggled-btn-bg-color) !important; + color: var(--toggled-btn-color); +} + +#findInput { + width: 200px; +} + +#findInput::-moz-placeholder { + font-style: normal; +} + +#findInput::placeholder { + font-style: normal; +} + +.loadingInput:has(> #findInput[data-status="pending"])::after { + display: block; + visibility: visible; +} + +#findInput[data-status="notFound"] { + background-color: rgb(255 102 102); +} + +.secondaryToolbar, +.editorParamsToolbar { + padding: 6px 0 10px; + inset-inline-end: 4px; + height: auto; + background-color: var(--doorhanger-bg-color); +} + +.editorParamsToolbarContainer { + width: 220px; + margin-bottom: -4px; +} + +.editorParamsToolbarContainer > .editorParamsSetter { + min-height: 26px; + display: flex; + align-items: center; + justify-content: space-between; + padding-inline: 10px; +} + +.editorParamsToolbarContainer .editorParamsLabel { + padding-inline-end: 10px; + flex: none; + font: menu; + font-size: 13px; + font-style: normal; + font-weight: 400; + line-height: 150%; + color: var(--main-color); +} + +.editorParamsToolbarContainer .editorParamsColor { + width: 32px; + height: 32px; + flex: none; +} + +.editorParamsToolbarContainer .editorParamsSlider { + background-color: transparent; + width: 90px; + flex: 0 1 0; +} + +.editorParamsToolbarContainer .editorParamsSlider::-moz-range-progress { + background-color: black; +} + +.editorParamsToolbarContainer + .editorParamsSlider::-webkit-slider-runnable-track, +.editorParamsToolbarContainer .editorParamsSlider::-moz-range-track { + background-color: black; +} + +.editorParamsToolbarContainer .editorParamsSlider::-webkit-slider-thumb, +.editorParamsToolbarContainer .editorParamsSlider::-moz-range-thumb { + background-color: white; +} + +#secondaryToolbarButtonContainer { + max-width: 220px; + min-height: 26px; + max-height: calc(var(--viewer-container-height) - 40px); + overflow-y: auto; + margin-bottom: -4px; +} + +#editorStampParamsToolbar { + inset-inline-end: calc(var(--editor-toolbar-base-offset) + 0px); +} + +#editorInkParamsToolbar { + inset-inline-end: calc(var(--editor-toolbar-base-offset) + 28px); +} + +#editorFreeTextParamsToolbar { + inset-inline-end: calc(var(--editor-toolbar-base-offset) + 56px); +} + +#editorHighlightParamsToolbar { + inset-inline-end: calc(var(--editor-toolbar-base-offset) + 84px); +} + +#editorStampAddImage::before { + -webkit-mask-image: var(--editorParams-stampAddImage-icon); + mask-image: var(--editorParams-stampAddImage-icon); +} + +.doorHanger, +.doorHangerRight { + border-radius: 2px; + box-shadow: 0 1px 5px var(--doorhanger-border-color), + 0 0 0 1px var(--doorhanger-border-color); + border: var(--doorhanger-border-color-whcm); +} +:is(.doorHanger, .doorHangerRight)::after, +:is(.doorHanger, .doorHangerRight)::before { + bottom: 100%; + border: 8px solid rgb(0 0 0 / 0); + content: " "; + height: 0; + width: 0; + position: absolute; + pointer-events: none; + opacity: var(--doorhanger-triangle-opacity-whcm); +} +.doorHanger::after { + inset-inline-start: 10px; + margin-inline-start: -8px; + border-bottom-color: var(--toolbar-bg-color); +} +.doorHangerRight::after { + inset-inline-end: 10px; + margin-inline-end: -8px; + border-bottom-color: var(--doorhanger-bg-color); +} +:is(.doorHanger, .doorHangerRight)::before { + border-bottom-color: var(--doorhanger-border-color); + border-width: 9px; +} +.doorHanger::before { + inset-inline-start: 10px; + margin-inline-start: -9px; +} +.doorHangerRight::before { + inset-inline-end: 10px; + margin-inline-end: -9px; +} + +#findResultsCount { + background-color: rgb(217 217 217); + color: rgb(82 82 82); + text-align: center; + padding: 4px 5px; + margin: 5px; +} + +#findMsg[data-status="notFound"] { + font-weight: bold; +} + +:is(#findResultsCount, #findMsg):empty { + display: none; +} + +#toolbarViewerMiddle { + display: flex; + flex-wrap: wrap; + order: 2; +} + +#toolbarViewerLeft, +#toolbarSidebarLeft { + float: var(--inline-start); +} +#toolbarViewerRight, +#toolbarSidebarRight { + float: var(--inline-end); +} + +#toolbarViewerLeft > *, +#toolbarViewerMiddle > *, +#toolbarViewerRight > *, +#toolbarSidebarLeft *, +#toolbarSidebarRight *, +.findbar * { + position: relative; + float: var(--inline-start); +} + +#redactionsToolbarViewer { + order: 3; + column-gap: 3px; +} + +#toolbarViewerLeft { + order: 1; + margin-right: auto; + padding-inline-start: 1px; +} +#toolbarViewerRight { + display: flex; + margin-left: auto; + column-gap: 3px; + order: 4; + padding-inline-end: 1px; +} +#toolbarSidebarRight { + padding-inline-end: 2px; +} + +.splitToolbarButton { + margin: 2px; + display: inline-block; + padding-top: 5px; +} +.splitToolbarButton > .toolbarButton { + float: var(--inline-start); +} + +.toolbarButton, +.secondaryToolbarButton, +.dialogButton { + border: none; + background: none; + width: 28px; + height: 28px; + outline: none; + + background-color: var(--md-sys-color-secondary); + color: var(--md-sys-color-on-secondary); + border-color: var(--md-sys-color-secondary); + box-shadow: var(--md-sys-elevation-3) !important; +} + +.toolbarButton { + height: var(--toolButton-height); + width: var(--toolButton-width); + border-radius: var(--toolButton-border-radius) !important; +} + +.dialogButton:is(:hover, :focus-visible) { + background-color: var(--dialog-button-hover-bg-color); +} + +.dialogButton:is(:hover, :focus-visible) > span { + color: var(--dialog-button-hover-color); +} + +.toolbarButton > span { + display: inline-block; + width: 0; + height: 0; + overflow: hidden; +} + +:is(.toolbarButton, .secondaryToolbarButton, .dialogButton)[disabled] { + opacity: 0.5; +} + +.splitToolbarButton > .toolbarButton:is(:hover, :focus-visible), +.dropdownToolbarButton:hover { + background-color: var(--button-hover-color); +} +.splitToolbarButton > .toolbarButton { + position: relative; + margin: 0; + height: var(--toolButton-height); + width: var(--toolButton-width); +} +#toolbarSidebar .splitToolbarButton > .toolbarButton { + margin-inline-end: 2px; +} + +.splitToolbarButtonSeparator { + float: var(--inline-start); + margin: 4px 3px; + width: 1px; + height: 20px; + background-color: var(--separator-color); + height: var(--toolButton-height); +} + +#scaleSelectContainer { + height: 3.125rem; + inset: 4px 0 0 0; + border-radius: var(--toolButton-border-radius); +} + +#scaleSelectContainer::after { + width: 1.875rem; + height: 1.875rem; +} + +#scaleSelect { + font-size: 1.25rem !important; + height: 100%; + border-radius: inherit; +} + +.toolbarButton, +.dropdownToolbarButton, +.secondaryToolbarButton, +.dialogButton { + min-width: 16px; + margin: 2px 3px; + padding: 2px 6px 0; + border: none; + border-radius: 2px; + color: var(--main-color); + font-size: 12px; + line-height: 14px; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + cursor: default; + box-sizing: border-box; +} + +.toolbarButton:is(:hover, :focus-visible) { + background-color: var(--button-hover-color); +} +.secondaryToolbarButton:is(:hover, :focus-visible) { + background-color: var(--doorhanger-hover-bg-color); + color: var(--doorhanger-hover-color); +} + +:is(.toolbarButton, .secondaryToolbarButton).toggled, +.splitToolbarButton.toggled > .toolbarButton.toggled { + background-color: var(--toggled-btn-bg-color); + color: var(--toggled-btn-color); +} + +:is(.toolbarButton, .secondaryToolbarButton).toggled:hover, +.splitToolbarButton.toggled > .toolbarButton.toggled:hover { + outline: var(--toggled-hover-btn-outline) !important; +} + +:is(.toolbarButton, .secondaryToolbarButton).toggled::before { + background-color: var(--toggled-btn-color); +} + +:is(.toolbarButton, .secondaryToolbarButton).toggled:hover:active, +.splitToolbarButton.toggled > .toolbarButton.toggled:hover:active { + background-color: var(--toggled-hover-active-btn-color); +} + +.dropdownToolbarButton { + display: flex; + width: -moz-fit-content; + width: fit-content; + min-width: 140px; + padding: 0; + background-color: var(--dropdown-btn-bg-color); + border: var(--dropdown-btn-border); +} +.dropdownToolbarButton::after { + top: 10px; + inset-inline-end: 6px; + pointer-events: none; + -webkit-mask-image: var(--toolbarButton-menuArrow-icon); + mask-image: var(--toolbarButton-menuArrow-icon); +} + +.dropdownToolbarButton > select { + -webkit-appearance: none; + -moz-appearance: none; + appearance: none; + width: inherit; + min-width: inherit; + height: 28px; + font-size: 12px; + color: var(--main-color); + margin: 0; + padding-block: 1px 2px; + padding-inline: 6px 38px; + border: none; + background-color: var(--dropdown-btn-bg-color); +} +.dropdownToolbarButton > select:is(:hover, :focus-visible) { + background-color: var(--button-hover-color); + color: var(--toggled-btn-color); +} +.dropdownToolbarButton > select > option { + background: var(--doorhanger-bg-color); + color: var(--main-color); +} + +.toolbarButtonSpacer { + width: 30px; + display: inline-block; + height: 1px; +} + +:is(.toolbarButton, .secondaryToolbarButton, .treeItemToggler)::before, +.dropdownToolbarButton::after { + position: absolute; + display: inline-block; + width: 16px; + height: 16px; + + content: ""; + background-color: var(--toolbar-icon-bg-color); + -webkit-mask-size: cover; + mask-size: cover; +} + +.dropdownToolbarButton:is(:hover, :focus-visible, :active)::after { + background-color: var(--toolbar-icon-hover-bg-color); +} + +.toolbarButton::before { + opacity: var(--toolbar-icon-opacity); + top: 8px; + left: 10px; + height: 1.875rem; + width: 1.875rem; + background-color: var(--md-sys-color-on-secondary); +} + +.toolbarButton:is(:hover, :focus-visible)::before, +.secondaryToolbarButton:is(:hover, :focus-visible)::before { + background-color: var(--toolbar-icon-hover-bg-color); +} + +.secondaryToolbarButton::before { + opacity: var(--doorhanger-icon-opacity); + top: 5px; + inset-inline-start: 12px; +} + +#sidebarToggle { + height: var(--toolButton-height); + width: var(--toolButton-width); +} + +#sidebarToggle::before { + -webkit-mask-image: var(--toolbarButton-sidebarToggle-icon); + mask-image: var(--toolbarButton-sidebarToggle-icon); + transform: scaleX(var(--dir-factor)); + + height: 1.875rem; + width: 1.875rem; +} + +#secondaryToolbarToggle::before { + -webkit-mask-image: var(--toolbarButton-secondaryToolbarToggle-icon); + mask-image: var(--toolbarButton-secondaryToolbarToggle-icon); + transform: scaleX(var(--dir-factor)); +} + +#backToHome::before { + -webkit-mask-image: var(--toolbarButton-backToHome-icon); + mask-image: var(--toolbarButton-backToHome-icon); + transform: scaleX(var(--dir-factor)); +} + +#findPrevious::before { + -webkit-mask-image: var(--findbarButton-previous-icon); + mask-image: var(--findbarButton-previous-icon); +} + +#findNext::before { + -webkit-mask-image: var(--findbarButton-next-icon); + mask-image: var(--findbarButton-next-icon); +} + +#previous::before { + -webkit-mask-image: var(--toolbarButton-pageUp-icon); + mask-image: var(--toolbarButton-pageUp-icon); +} + +#next::before { + -webkit-mask-image: var(--toolbarButton-pageDown-icon); + mask-image: var(--toolbarButton-pageDown-icon); +} + +#zoomOut::before { + -webkit-mask-image: var(--toolbarButton-zoomOut-icon); + mask-image: var(--toolbarButton-zoomOut-icon); +} + +#zoomIn::before { + -webkit-mask-image: var(--toolbarButton-zoomIn-icon); + mask-image: var(--toolbarButton-zoomIn-icon); +} + +#presentationMode::before { + -webkit-mask-image: var(--toolbarButton-presentationMode-icon); + mask-image: var(--toolbarButton-presentationMode-icon); +} + +#editorFreeText::before { + -webkit-mask-image: var(--toolbarButton-editorFreeText-icon); + mask-image: var(--toolbarButton-editorFreeText-icon); +} + +#editorHighlight::before { + -webkit-mask-image: var(--toolbarButton-editorHighlight-icon); + mask-image: var(--toolbarButton-editorHighlight-icon); +} + +#editorInk::before { + -webkit-mask-image: var(--toolbarButton-editorInk-icon); + mask-image: var(--toolbarButton-editorInk-icon); +} + +#editorStamp::before { + -webkit-mask-image: var(--toolbarButton-editorStamp-icon); + mask-image: var(--toolbarButton-editorStamp-icon); +} + +:is(#print, #secondaryPrint)::before { + -webkit-mask-image: var(--toolbarButton-print-icon); + mask-image: var(--toolbarButton-print-icon); +} + +#secondaryOpenFile::before, +#openFile::before { + -webkit-mask-image: var(--toolbarButton-openFile-icon); + mask-image: var(--toolbarButton-openFile-icon); +} + +:is(#download, #secondaryDownload)::before { + -webkit-mask-image: var(--toolbarButton-download-icon); + mask-image: var(--toolbarButton-download-icon); +} + +a.secondaryToolbarButton { + padding-top: 5px; + text-decoration: none; +} +a:is(.toolbarButton, .secondaryToolbarButton)[href="#"] { + opacity: 0.5; + pointer-events: none; +} + +#viewBookmark::before { + -webkit-mask-image: var(--toolbarButton-bookmark-icon); + mask-image: var(--toolbarButton-bookmark-icon); +} + +#viewThumbnail::before { + -webkit-mask-image: var(--toolbarButton-viewThumbnail-icon); + mask-image: var(--toolbarButton-viewThumbnail-icon); +} + +#viewOutline::before { + -webkit-mask-image: var(--toolbarButton-viewOutline-icon); + mask-image: var(--toolbarButton-viewOutline-icon); + transform: scaleX(var(--dir-factor)); +} + +#viewAttachments::before { + -webkit-mask-image: var(--toolbarButton-viewAttachments-icon); + mask-image: var(--toolbarButton-viewAttachments-icon); +} + +#viewLayers::before { + -webkit-mask-image: var(--toolbarButton-viewLayers-icon); + mask-image: var(--toolbarButton-viewLayers-icon); +} + +#currentOutlineItem::before { + -webkit-mask-image: var(--toolbarButton-currentOutlineItem-icon); + mask-image: var(--toolbarButton-currentOutlineItem-icon); + transform: scaleX(var(--dir-factor)); +} + +#viewFind::before { + -webkit-mask-image: var(--toolbarButton-search-icon); + mask-image: var(--toolbarButton-search-icon); +} + +.pdfSidebarNotification::after { + position: absolute; + display: inline-block; + top: 2px; + inset-inline-end: 2px; + content: ""; + background-color: rgb(112 219 85); + height: 9px; + width: 9px; + border-radius: 50%; +} + +.secondaryToolbarButton { + position: relative; + margin: 0; + padding: 0 0 1px; + padding-inline-start: 36px; + height: auto; + min-height: 26px; + width: auto; + min-width: 100%; + text-align: start; + white-space: normal; + border-radius: 0; + box-sizing: border-box; + display: inline-block; +} +.secondaryToolbarButton > span { + padding-inline-end: 4px; +} + +#firstPage::before { + -webkit-mask-image: var(--secondaryToolbarButton-firstPage-icon); + mask-image: var(--secondaryToolbarButton-firstPage-icon); +} + +#lastPage::before { + -webkit-mask-image: var(--secondaryToolbarButton-lastPage-icon); + mask-image: var(--secondaryToolbarButton-lastPage-icon); +} + +#pageRotateCcw::before { + -webkit-mask-image: var(--secondaryToolbarButton-rotateCcw-icon); + mask-image: var(--secondaryToolbarButton-rotateCcw-icon); +} + +#pageRotateCw::before { + -webkit-mask-image: var(--secondaryToolbarButton-rotateCw-icon); + mask-image: var(--secondaryToolbarButton-rotateCw-icon); +} + +#cursorSelectTool::before { + -webkit-mask-image: var(--secondaryToolbarButton-selectTool-icon); + mask-image: var(--secondaryToolbarButton-selectTool-icon); +} + +#cursorHandTool::before { + -webkit-mask-image: var(--secondaryToolbarButton-handTool-icon); + mask-image: var(--secondaryToolbarButton-handTool-icon); +} + +#scrollPage::before { + -webkit-mask-image: var(--secondaryToolbarButton-scrollPage-icon); + mask-image: var(--secondaryToolbarButton-scrollPage-icon); +} + +#scrollVertical::before { + -webkit-mask-image: var(--secondaryToolbarButton-scrollVertical-icon); + mask-image: var(--secondaryToolbarButton-scrollVertical-icon); +} + +#scrollHorizontal::before { + -webkit-mask-image: var(--secondaryToolbarButton-scrollHorizontal-icon); + mask-image: var(--secondaryToolbarButton-scrollHorizontal-icon); +} + +#scrollWrapped::before { + -webkit-mask-image: var(--secondaryToolbarButton-scrollWrapped-icon); + mask-image: var(--secondaryToolbarButton-scrollWrapped-icon); +} + +#spreadNone::before { + -webkit-mask-image: var(--secondaryToolbarButton-spreadNone-icon); + mask-image: var(--secondaryToolbarButton-spreadNone-icon); +} + +#spreadOdd::before { + -webkit-mask-image: var(--secondaryToolbarButton-spreadOdd-icon); + mask-image: var(--secondaryToolbarButton-spreadOdd-icon); +} + +#spreadEven::before { + -webkit-mask-image: var(--secondaryToolbarButton-spreadEven-icon); + mask-image: var(--secondaryToolbarButton-spreadEven-icon); +} + +#documentProperties::before { + -webkit-mask-image: var(--secondaryToolbarButton-documentProperties-icon); + mask-image: var(--secondaryToolbarButton-documentProperties-icon); +} + +.verticalToolbarSeparator { + display: block; + margin: 5px 2px; + width: 1px; + height: 22px; + background-color: var(--separator-color); +} +.horizontalToolbarSeparator { + display: block; + margin: 6px 0; + height: 1px; + width: 100%; + background-color: var(--doorhanger-separator-color); +} + +.toolbarField { + padding: 4px 7px; + margin: 3px 0; + border-radius: 2px; + background-color: var(--field-bg-color); + background-clip: padding-box; + border: 1px solid var(--field-border-color); + box-shadow: none; + color: var(--field-color); + font-size: 12px; + line-height: 16px; + outline: none; +} + +.toolbarField[type="checkbox"] { + opacity: 0; + position: absolute !important; + left: 0; + margin: 10px 0 3px; + margin-inline-start: 7px; +} + +#pageNumber { + -moz-appearance: textfield; + text-align: end; + width: var(--toolButton-width); + height: var(--toolButton-height); + font-size: 1.25rem !important; + background-size: 0 0; + transition-property: none; + border-radius: 10px; +} + +#pageNumber::-webkit-inner-spin-button { + -webkit-appearance: none; +} + +.loadingInput:has(> #pageNumber.loading)::after { + display: block; + visibility: visible; + + transition-property: visibility; + transition-delay: var(--loading-icon-delay); +} + +.loadingInput::after { + position: absolute; + visibility: hidden; + display: none; + top: calc(50% - 12px); + width: 16px; + height: 16px; + + content: ""; + background-color: var(--toolbar-icon-bg-color); + -webkit-mask-size: cover; + mask-size: cover; + -webkit-mask-image: var(--loading-icon); + mask-image: var(--loading-icon); +} + +.loadingInput.start { + height: var(--toolButton-height); + width: var(--toolButton-width); + padding-top: 5px; +} + +.loadingInput.start::after { + inset-inline-start: 4px; +} + +.loadingInput.end::after { + inset-inline-end: 4px; +} + +.toolbarField:focus { + border-color: #0a84ff; +} + +.toolbarLabel { + min-width: 16px; + padding: 7px; + margin: 2px; + border-radius: 2px; + color: var(--md-sys-color-on-surface); + font-size: 12px; + line-height: 14px; + text-align: left; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + cursor: default; +} + +#numPages { + font-size: 1.25rem; + line-height: 2.812rem; +} + +#numPages.toolbarLabel { + padding-inline-start: 3px; +} + +#thumbnailView, +#outlineView, +#attachmentsView, +#layersView { + position: absolute; + width: calc(100% - 12px); + inset-block: 0; + padding: 4px 4px 0; + overflow: auto; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; +} +#thumbnailView { + width: calc(100% - 60px); + padding: 10px 30px 0; +} + +#thumbnailView > a:is(:active, :focus) { + outline: 0; +} + +.thumbnail { + --thumbnail-width: 0; + --thumbnail-height: 0; + + float: var(--inline-start); + width: var(--thumbnail-width); + height: var(--thumbnail-height); + margin: 0 10px 5px; + padding: 1px; + border: 7px solid transparent; + border-radius: 2px; +} + +#thumbnailView > a:last-of-type > .thumbnail { + margin-bottom: 10px; +} + +a:focus > .thumbnail, +.thumbnail:hover { + border-color: var(--thumbnail-hover-color); +} +.thumbnail.selected { + border-color: var(--thumbnail-selected-color) !important; +} + +.thumbnailImage { + width: var(--thumbnail-width); + height: var(--thumbnail-height); + opacity: 0.9; +} +a:focus > .thumbnail > .thumbnailImage, +.thumbnail:hover > .thumbnailImage { + opacity: 0.95; +} +.thumbnail.selected > .thumbnailImage { + opacity: 1 !important; +} + +.thumbnail:not([data-loaded]) > .thumbnailImage { + width: calc(var(--thumbnail-width) - 2px); + height: calc(var(--thumbnail-height) - 2px); + border: 1px dashed rgb(132 132 132); +} + +.treeWithDeepNesting > .treeItem, +.treeItem > .treeItems { + margin-inline-start: 20px; +} + +.treeItem > a { + text-decoration: none; + display: inline-block; + min-width: calc(100% - 4px); + height: auto; + margin-bottom: 1px; + padding: 2px 0 5px; + padding-inline-start: 4px; + border-radius: 2px; + color: var(--treeitem-color); + font-size: 13px; + line-height: 15px; + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + white-space: normal; + cursor: pointer; +} + +#layersView .treeItem > a * { + cursor: pointer; +} +#layersView .treeItem > a > label { + padding-inline-start: 4px; +} +#layersView .treeItem > a > label > input { + float: var(--inline-start); + margin-top: 1px; +} + +.treeItemToggler { + position: relative; + float: var(--inline-start); + height: 0; + width: 0; + color: rgb(255 255 255 / 0.5); +} +.treeItemToggler::before { + inset-inline-end: 4px; + -webkit-mask-image: var(--treeitem-expanded-icon); + mask-image: var(--treeitem-expanded-icon); +} +.treeItemToggler.treeItemsHidden::before { + -webkit-mask-image: var(--treeitem-collapsed-icon); + mask-image: var(--treeitem-collapsed-icon); + transform: scaleX(var(--dir-factor)); +} +.treeItemToggler.treeItemsHidden ~ .treeItems { + display: none; +} + +.treeItem.selected > a { + background-color: var(--treeitem-selected-bg-color); + color: var(--treeitem-selected-color); +} + +.treeItemToggler:hover, +.treeItemToggler:hover + a, +.treeItemToggler:hover ~ .treeItems, +.treeItem > a:hover { + background-color: var(--treeitem-bg-color); + background-clip: padding-box; + border-radius: 2px; + color: var(--treeitem-hover-color); +} + +#outlineOptionsContainer { + display: none; +} + +#sidebarContainer:has(#outlineView:not(.hidden)) #outlineOptionsContainer { + display: inherit; +} + +.dialogButton { + width: auto; + margin: 3px 4px 2px !important; + padding: 2px 11px; + color: var(--main-color); + background-color: var(--dialog-button-bg-color); + border: var(--dialog-button-border) !important; +} + +dialog { + margin: auto; + padding: 15px; + border-spacing: 4px; + color: var(--main-color); + font: message-box; + font-size: 12px; + line-height: 14px; + background-color: var(--doorhanger-bg-color); + border: 1px solid rgb(0 0 0 / 0.5); + border-radius: 4px; + box-shadow: 0 1px 4px rgb(0 0 0 / 0.3); +} +dialog::backdrop { + background-color: rgb(0 0 0 / 0.2); +} + +dialog > .row { + display: table-row; +} + +dialog > .row > * { + display: table-cell; +} + +dialog .toolbarField { + margin: 5px 0; +} + +dialog .separator { + display: block; + margin: 4px 0; + height: 1px; + width: 100%; + background-color: var(--separator-color); +} + +dialog .buttonRow { + text-align: center; + vertical-align: middle; +} + +dialog :link { + color: rgb(255 255 255); +} + +#passwordDialog { + text-align: center; +} +#passwordDialog .toolbarField { + width: 200px; +} + +#documentPropertiesDialog { + text-align: left; +} +#documentPropertiesDialog .row > * { + min-width: 100px; + text-align: start; +} +#documentPropertiesDialog .row > span { + width: 125px; + word-wrap: break-word; +} +#documentPropertiesDialog .row > p { + max-width: 225px; + word-wrap: break-word; +} +#documentPropertiesDialog .buttonRow { + margin-top: 10px; +} + +.grab-to-pan-grab { + cursor: grab !important; +} +.grab-to-pan-grab + *:not(input):not(textarea):not(button):not(select):not(:link) { + cursor: inherit !important; +} +.grab-to-pan-grab:active, +.grab-to-pan-grabbing { + cursor: grabbing !important; +} +.grab-to-pan-grabbing { + position: fixed; + background: rgb(0 0 0 / 0); + display: block; + inset: 0; + overflow: hidden; + z-index: 50000; +} + +@page { + margin: 0; +} + +#printContainer { + display: none; +} + +@media print { + body { + background: rgb(0 0 0 / 0) none; + } + body[data-pdfjsprinting] #outerContainer { + display: none; + } + body[data-pdfjsprinting] #printContainer { + display: block; + } + #printContainer { + height: 100%; + } + #printContainer > .printedPage { + page-break-after: always; + page-break-inside: avoid; + height: 100%; + width: 100%; + + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + } + + #printContainer > .xfaPrintedPage .xfaPage { + position: absolute; + } + + #printContainer > .xfaPrintedPage { + page-break-after: always; + page-break-inside: avoid; + width: 100%; + height: 100%; + position: relative; + } + + #printContainer > .printedPage :is(canvas, img) { + max-width: 100%; + max-height: 100%; + + direction: ltr; + display: block; + } +} + +.visibleMediumView { + display: none; +} + +@media all and (max-width: 840px) { + #sidebarContainer { + background-color: var(--sidebar-narrow-bg-color); + } + #outerContainer.sidebarOpen #viewerContainer { + inset-inline-start: 0 !important; + } +} + +@media all and (max-width: 750px) { + :root { + --editor-toolbar-base-offset: 40px; + } + #outerContainer .hiddenMediumView { + display: none; + } + #outerContainer .visibleMediumView { + display: inherit; + } +} + +@media all and (max-width: 690px) { + .hiddenSmallView, + .hiddenSmallView * { + display: none; + } + .toolbarButtonSpacer { + width: 0; + } + .findbar { + inset-inline-start: 34px; + } +} +/* +@media all and (max-width: 560px){ + #scaleSelectContainer{ + display:none; + } +} */ + +#showMoreBtnContainer { + display: none; +} +.toolbar img.main-icon { + height: 3.375rem; + width: 3.375rem; + inset: 5px; +} + +@media (max-width: 1125px) { + #showMoreBtnContainer { + display: flex; + } + + #toolbarViewerMiddle > .splitToolbarButton { + display: flex; + } + + #toolbarViewerRight { + display: none; + margin-left: 0; + } + + #toolbarViewerRight > div.splitToolbarButton { + display: flex; + flex-direction: column; + align-items: center; + row-gap: 3px; + + position: absolute; + left: 3px; + top: var(--toolbar-height); + } +} + +@media (max-width: 885px) { + #toolbarViewerMiddle { + order: 3; + position: fixed; + display: flex; + flex-wrap: nowrap; + bottom: 15px; + left: 50%; + transform: translate(-50%); + } + + #toolbarViewerMiddle .splitToolbarButton .splitToolbarButtonSeparator { + display: none; + } + + #redactionsToolbarViewer { + order: 2; + } + + + #pageBasedRedactionOverlay > .bg-card { + padding: 1.5rem; + } + + #pageBasedRedactionOverlay > .bg-card > div.tool-header { + display: flex; + column-gap: 10px; + } + + #pageBasedRedactionOverlay > .bg-card > div.tool-header > span:nth-child(1) { + margin: auto; + height: 3.5rem; + width: 3.5rem; + border-radius: 15px; + font-size: 2.5rem; + } + + #pageBasedRedactionOverlay > .bg-card > div.tool-header > span:nth-child(2) { + font-size: 1.5rem; + } + + #pageBasedRedactionOverlay > .bg-card > div:nth-child(3) { + flex-direction: column; + row-gap: 3px; + } + + #pageBasedRedactionOverlay > .bg-card > div:nth-child(3) > input { + width: 100%; + height: 30px; + margin-left: 0 !important; + flex: none; + } +} + +@media (max-width: 510px) { + .toolbar img.main-icon { + display: none; + } +} + +@media (max-width: 450px) { + :root { + --toolButton-height: 2.5rem; + --toolButton-width: 2.5rem; + --toolButton-icon-font-size: 1.8rem; + } + + #pageNumber { + font-size: 1rem !important; + } + + #numPages { + font-size: 1rem; + line-height: 2.512rem; + } + + .toolbarButton::before { + left: 5px; + top: 5px; + } + + #redactionsToolbarViewer { + order: 2; + } + + #toolbarViewerMiddle { + position: fixed; + display: flex; + flex-wrap: nowrap; + order: 3; + bottom: 15px; + left: 50%; + transform: translate(-50%); + } + + #scaleSelectContainer { + height: 2.825rem; + } + + html, + body { + overflow: hidden !important; + } + + .splitToolbarButton { + display: flex !important; + } + + .toolbar img.main-icon { + height: var(--toolButton-height); + width: var(--toolButton-width); + inset: 10px 0 0 0; + } +} + +@media (max-width: 390px) { + #toolbarViewerLeft { + display: grid; + } + + #toolbarViewerLeft #showMoreBtnContainer { + grid-row: 1; + grid-column: 1; + } + + #sidebarToggle { + grid-row: 1; + grid-column: 2; + } + + #toolbarViewerLeft .loadingInput.start { + grid-row: 1; + grid-column: 3; + + margin-bottom: auto; + margin-top: -2px + } + + #pageNumber { + height: 1.9rem; + } + + #numPages { + grid-row: 1; + grid-column: 3; + + line-height: 0; + + margin-top: auto; + margin-bottom: -4px + } + +} diff --git a/src/main/resources/static/pdfjs-legacy/pdf.mjs b/src/main/resources/static/pdfjs-legacy/pdf.mjs index e38f4c38a52..da8e401480e 100644 --- a/src/main/resources/static/pdfjs-legacy/pdf.mjs +++ b/src/main/resources/static/pdfjs-legacy/pdf.mjs @@ -4630,7 +4630,7 @@ if (DESCRIPTORS && !('size' in URLSearchParamsPrototype)) { /************************************************************************/ /******/ // The module cache /******/ var __webpack_module_cache__ = {}; -/******/ +/******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ // Check if module is in cache @@ -4644,14 +4644,14 @@ if (DESCRIPTORS && !('size' in URLSearchParamsPrototype)) { /******/ // no module.loaded needed /******/ exports: {} /******/ }; -/******/ +/******/ /******/ // Execute the module function /******/ __webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__); -/******/ +/******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } -/******/ +/******/ /************************************************************************/ /******/ /* webpack/runtime/define property getters */ /******/ (() => { @@ -4664,12 +4664,12 @@ if (DESCRIPTORS && !('size' in URLSearchParamsPrototype)) { /******/ } /******/ }; /******/ })(); -/******/ +/******/ /******/ /* webpack/runtime/hasOwnProperty shorthand */ /******/ (() => { /******/ __webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop)) /******/ })(); -/******/ +/******/ /************************************************************************/ var __webpack_exports__ = globalThis.pdfjsLib = {}; // This entry need to be wrapped in an IIFE because it need to be isolated against other modules in the chunk. @@ -6385,8 +6385,8 @@ function setLayerDimensions(div, viewport, mustFlip = false, mustRotate = true) const useRound = util_FeatureTest.isCSSRoundSupported; const w = `var(--scale-factor) * ${pageWidth}px`, h = `var(--scale-factor) * ${pageHeight}px`; - const widthStr = useRound ? `round(${w}, 1px)` : `calc(${w})`, - heightStr = useRound ? `round(${h}, 1px)` : `calc(${h})`; + const widthStr = useRound ? `round(up, ${w}, 1px)` : `calc(${w})`, + heightStr = useRound ? `round(up, ${h}, 1px)` : `calc(${h})`; if (!mustFlip || viewport.rotation % 180 === 0) { style.width = widthStr; style.height = heightStr; @@ -24317,4 +24317,4 @@ var __webpack_exports__updateTextLayer = __webpack_exports__.updateTextLayer; var __webpack_exports__version = __webpack_exports__.version; export { __webpack_exports__AbortException as AbortException, __webpack_exports__AnnotationEditorLayer as AnnotationEditorLayer, __webpack_exports__AnnotationEditorParamsType as AnnotationEditorParamsType, __webpack_exports__AnnotationEditorType as AnnotationEditorType, __webpack_exports__AnnotationEditorUIManager as AnnotationEditorUIManager, __webpack_exports__AnnotationLayer as AnnotationLayer, __webpack_exports__AnnotationMode as AnnotationMode, __webpack_exports__CMapCompressionType as CMapCompressionType, __webpack_exports__ColorPicker as ColorPicker, __webpack_exports__DOMSVGFactory as DOMSVGFactory, __webpack_exports__DrawLayer as DrawLayer, __webpack_exports__FeatureTest as FeatureTest, __webpack_exports__GlobalWorkerOptions as GlobalWorkerOptions, __webpack_exports__ImageKind as ImageKind, __webpack_exports__InvalidPDFException as InvalidPDFException, __webpack_exports__MissingPDFException as MissingPDFException, __webpack_exports__OPS as OPS, __webpack_exports__Outliner as Outliner, __webpack_exports__PDFDataRangeTransport as PDFDataRangeTransport, __webpack_exports__PDFDateString as PDFDateString, __webpack_exports__PDFWorker as PDFWorker, __webpack_exports__PasswordResponses as PasswordResponses, __webpack_exports__PermissionFlag as PermissionFlag, __webpack_exports__PixelsPerInch as PixelsPerInch, __webpack_exports__RenderingCancelledException as RenderingCancelledException, __webpack_exports__TextLayer as TextLayer, __webpack_exports__UnexpectedResponseException as UnexpectedResponseException, __webpack_exports__Util as Util, __webpack_exports__VerbosityLevel as VerbosityLevel, __webpack_exports__XfaLayer as XfaLayer, __webpack_exports__build as build, __webpack_exports__createValidAbsoluteUrl as createValidAbsoluteUrl, __webpack_exports__fetchData as fetchData, __webpack_exports__getDocument as getDocument, __webpack_exports__getFilenameFromUrl as getFilenameFromUrl, __webpack_exports__getPdfFilenameFromUrl as getPdfFilenameFromUrl, __webpack_exports__getXfaPageViewport as getXfaPageViewport, __webpack_exports__isDataScheme as isDataScheme, __webpack_exports__isPdfFile as isPdfFile, __webpack_exports__noContextMenu as noContextMenu, __webpack_exports__normalizeUnicode as normalizeUnicode, __webpack_exports__renderTextLayer as renderTextLayer, __webpack_exports__setLayerDimensions as setLayerDimensions, __webpack_exports__shadow as shadow, __webpack_exports__updateTextLayer as updateTextLayer, __webpack_exports__version as version }; -//# sourceMappingURL=pdf.mjs.map \ No newline at end of file +//# sourceMappingURL=pdf.mjs.map diff --git a/src/main/resources/templates/fragments/navbar.html b/src/main/resources/templates/fragments/navbar.html index d4cdebbe252..b89f60a0de8 100644 --- a/src/main/resources/templates/fragments/navbar.html +++ b/src/main/resources/templates/fragments/navbar.html @@ -170,6 +170,9 @@
+
+
diff --git a/src/main/resources/templates/home.html b/src/main/resources/templates/home.html index 02b6699c7c7..f8f1901ab1e 100644 --- a/src/main/resources/templates/home.html +++ b/src/main/resources/templates/home.html @@ -227,6 +227,9 @@
+
+
diff --git a/src/main/resources/templates/security/redact.html b/src/main/resources/templates/security/redact.html new file mode 100644 index 00000000000..f060211b9c8 --- /dev/null +++ b/src/main/resources/templates/security/redact.html @@ -0,0 +1,708 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+
+
+
+
+ ink_eraser + +
+
+
+
+
+ + +
+
+ + +
+
+ + +
+ + +
+
+
+
+ +
+
+
+ document_scanner + +
+
+ + +
+
+ + +
+ + +
+
+
+
+
+
+
+ + + + +
+
+ +
+
+
+ + +
+
+
+
+
+
+ + + +
+
+
+ +
+ + + + + + + + + + + + +
+
+
+
+
+ +
+ +
+ +
+ +
+ +
+ + + + + icon +
+
+
+ +
+ +
+ + + +
+
+ + + + +
+
+
+ + + + +
+
+ + + + + +
+ +
+ + + + + +
+ + +
+
+
+
+
+
+
+
+
+
+ +
+
+
+
+ +
+ +
+ +
+
+ +
+
+ + +
+
+ +
+ File name: +

-

+
+
+ File size: +

-

+
+
+
+ Title: +

-

+
+
+ Author: +

-

+
+
+ Subject: +

-

+
+
+ Keywords: +

-

+
+
+ Creation + Date: +

-

+
+
+ Modification + Date: +

-

+
+
+ Creator: +

-

+
+
+
+ PDF Producer: +

-

+
+
+ PDF Version: +

-

+
+
+ Page Count: +

-

+
+
+ Page Size: +

-

+
+
+
+ Fast Web View: +

-

+
+
+ +
+
+ +
+
+ Choose an + option + + Alt text (alternative text) helps when people can’t see the image or when it doesn’t load. + +
+
+
+
+ + +
+
+ + Aim for 1-2 sentences that describe the subject, setting, or actions. + +
+
+
+ +
+
+
+
+
+ + +
+
+ + This is used for ornamental images, like borders or watermarks. + +
+
+
+
+ + +
+
+
+ +
+ Preparing document for printing… +
+
+ + 0% +
+
+ +
+
+
+ +
+
+ + + + + \ No newline at end of file