: str_replace(): Passing null to parameter #2 ($replace) of type array|string is deprecated in
const RenderingStates = {
const PresentationModeState = {
const AutoPrintRegExp = /\bprint\s*\(/;
const pixelRatio = window.devicePixelRatio || 1;
return this.sx !== 1 || this.sy !== 1;
function scrollIntoView(element, spot, scrollMatches = false) {
let parent = element.offsetParent;
console.error("offsetParent is not set -- cannot scroll");
let offsetY = element.offsetTop + element.clientTop;
let offsetX = element.offsetLeft + element.clientLeft;
while (parent.clientHeight === parent.scrollHeight && parent.clientWidth === parent.scrollWidth || scrollMatches && (parent.classList.contains("markedContent") || getComputedStyle(parent).overflow === "hidden")) {
offsetY += parent.offsetTop;
offsetX += parent.offsetLeft;
parent = parent.offsetParent;
if (spot.top !== undefined) {
if (spot.left !== undefined) {
parent.scrollLeft = offsetX;
parent.scrollTop = offsetY;
function watchScroll(viewAreaElement, callback) {
const debounceScroll = function (evt) {
rAF = window.requestAnimationFrame(function viewAreaElementScrolled() {
const currentX = viewAreaElement.scrollLeft;
const lastX = state.lastX;
if (currentX !== lastX) {
state.right = currentX > lastX;
const currentY = viewAreaElement.scrollTop;
const lastY = state.lastY;
if (currentY !== lastY) {
state.down = currentY > lastY;
lastX: viewAreaElement.scrollLeft,
lastY: viewAreaElement.scrollTop,
_eventHandler: debounceScroll
viewAreaElement.addEventListener("scroll", debounceScroll, true);
function parseQueryString(query) {
const params = new Map();
for (const [key, value] of new URLSearchParams(query)) {
params.set(key.toLowerCase(), value);
const InvisibleCharsRegExp = /[\x00-\x1F]/g;
function removeNullCharacters(str, replaceInvisible = false) {
if (!InvisibleCharsRegExp.test(str)) {
return str.replaceAll(InvisibleCharsRegExp, m => m === "\x00" ? "" : " ");
return str.replaceAll("\x00", "");
function binarySearchFirstItem(items, condition, start = 0) {
let maxIndex = items.length - 1;
if (maxIndex < 0 || !condition(items[maxIndex])) {
if (condition(items[minIndex])) {
while (minIndex < maxIndex) {
const currentIndex = minIndex + maxIndex >> 1;
const currentItem = items[currentIndex];
if (condition(currentItem)) {
minIndex = currentIndex + 1;
function approximateFraction(x) {
if (Math.floor(x) === x) {
} else if (Math.floor(xinv) === xinv) {
const x_ = x > 1 ? xinv : x;
if (x_ - a / b < c / d - x_) {
result = x_ === x ? [a, b] : [b, a];
result = x_ === x ? [c, d] : [d, c];
function roundToDivide(x, div) {
return r === 0 ? x : Math.round(x - r + div);
function getPageSizeInches({
const [x1, y1, x2, y2] = view;
const changeOrientation = rotate % 180 !== 0;
const width = (x2 - x1) / 72 * userUnit;
const height = (y2 - y1) / 72 * userUnit;
width: changeOrientation ? height : width,
height: changeOrientation ? width : height
function backtrackBeforeAllVisibleElements(index, views, top) {
let elt = views[index].div;
let pageTop = elt.offsetTop + elt.clientTop;
elt = views[index - 1].div;
pageTop = elt.offsetTop + elt.clientTop;
for (let i = index - 2; i >= 0; --i) {
if (elt.offsetTop + elt.clientTop + elt.clientHeight <= pageTop) {
function getVisibleElements({
sortByVisibility = false,
const top = scrollEl.scrollTop,
bottom = top + scrollEl.clientHeight;
const left = scrollEl.scrollLeft,
right = left + scrollEl.clientWidth;
function isElementBottomAfterViewTop(view) {
const element = view.div;
const elementBottom = element.offsetTop + element.clientTop + element.clientHeight;
return elementBottom > top;
function isElementNextAfterViewHorizontally(view) {
const element = view.div;
const elementLeft = element.offsetLeft + element.clientLeft;
const elementRight = elementLeft + element.clientWidth;
return rtl ? elementLeft < right : elementRight > left;
let firstVisibleElementInd = binarySearchFirstItem(views, horizontal ? isElementNextAfterViewHorizontally : isElementBottomAfterViewTop);
if (firstVisibleElementInd > 0 && firstVisibleElementInd < numViews && !horizontal) {
firstVisibleElementInd = backtrackBeforeAllVisibleElements(firstVisibleElementInd, views, top);
let lastEdge = horizontal ? right : -1;
for (let i = firstVisibleElementInd; i < numViews; i++) {
const currentWidth = element.offsetLeft + element.clientLeft;
const currentHeight = element.offsetTop + element.clientTop;
const viewWidth = element.clientWidth,
viewHeight = element.clientHeight;
const viewRight = currentWidth + viewWidth;
const viewBottom = currentHeight + viewHeight;
if (viewBottom >= bottom) {
} else if ((horizontal ? currentWidth : currentHeight) > lastEdge) {
if (viewBottom <= top || currentHeight >= bottom || viewRight <= left || currentWidth >= right) {
const hiddenHeight = Math.max(0, top - currentHeight) + Math.max(0, viewBottom - bottom);
const hiddenWidth = Math.max(0, left - currentWidth) + Math.max(0, viewRight - right);
const fractionHeight = (viewHeight - hiddenHeight) / viewHeight,
fractionWidth = (viewWidth - hiddenWidth) / viewWidth;
const percent = fractionHeight * fractionWidth * 100 | 0;
widthPercent: fractionWidth * 100 | 0
const first = visible[0],
visible.sort(function (a, b) {
const pc = a.percent - b.percent;
if (Math.abs(pc) > 0.001) {
function normalizeWheelEventDirection(evt) {
let delta = Math.hypot(evt.deltaX, evt.deltaY);
const angle = Math.atan2(evt.deltaY, evt.deltaX);
if (-0.25 * Math.PI < angle && angle < 0.75 * Math.PI) {
function normalizeWheelEventDelta(evt) {
const deltaMode = evt.deltaMode;
let delta = normalizeWheelEventDirection(evt);
const MOUSE_PIXELS_PER_LINE = 30;
const MOUSE_LINES_PER_PAGE = 30;
if (deltaMode === WheelEvent.DOM_DELTA_PIXEL) {
delta /= MOUSE_PIXELS_PER_LINE * MOUSE_LINES_PER_PAGE;
} else if (deltaMode === WheelEvent.DOM_DELTA_LINE) {
delta /= MOUSE_LINES_PER_PAGE;
function isValidRotation(angle) {
return Number.isInteger(angle) && angle % 90 === 0;
function isValidScrollMode(mode) {
return Number.isInteger(mode) && Object.values(ScrollMode).includes(mode) && mode !== ScrollMode.UNKNOWN;
function isValidSpreadMode(mode) {
return Number.isInteger(mode) && Object.values(SpreadMode).includes(mode) && mode !== SpreadMode.UNKNOWN;
function isPortraitOrientation(size) {
return size.width <= size.height;
const animationStarted = new Promise(function (resolve) {
window.requestAnimationFrame(resolve);
const docStyle = document.documentElement.style;
function clamp(v, min, max) {
return Math.min(Math.max(v, min), max);
#disableAutoFetchTimeout = null;
this.#classList = bar.classList;
this.#percent = clamp(val, 0, 100);
this.#classList.add("indeterminate");
this.#classList.remove("indeterminate");
this.#style.setProperty("--progressBar-percent", `${this.#percent}%`);
const container = viewer.parentNode;
const scrollbarWidth = container.offsetWidth - viewer.offsetWidth;
if (scrollbarWidth > 0) {
this.#style.setProperty("--progressBar-end-offset", `${scrollbarWidth}px`);
setDisableAutoFetch(delay = 5000) {
if (isNaN(this.#percent)) {
if (this.#disableAutoFetchTimeout) {
clearTimeout(this.#disableAutoFetchTimeout);
this.#disableAutoFetchTimeout = setTimeout(() => {
this.#disableAutoFetchTimeout = null;
this.#classList.add("hidden");
this.#classList.remove("hidden");
function getActiveOrFocusedElement() {
let curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus");
while (curActiveOrFocused?.shadowRoot) {
curRoot = curActiveOrFocused.shadowRoot;
curActiveOrFocused = curRoot.activeElement || curRoot.querySelector(":focus");
return curActiveOrFocused;
function apiPageLayoutToViewerModes(layout) {
let scrollMode = ScrollMode.VERTICAL,
spreadMode = SpreadMode.NONE;
scrollMode = ScrollMode.PAGE;
scrollMode = ScrollMode.PAGE;
spreadMode = SpreadMode.ODD;
scrollMode = ScrollMode.PAGE;
spreadMode = SpreadMode.EVEN;
function apiPageModeToSidebarView(mode) {
return SidebarView.THUMBS;
return SidebarView.OUTLINE;
return SidebarView.ATTACHMENTS;
return SidebarView.LAYERS;
function toggleCheckedBtn(button, toggle, view = null) {
button.classList.toggle("toggled", toggle);
button.setAttribute("aria-checked", toggle);
view?.classList.toggle("hidden", !toggle);
function toggleExpandedBtn(button, toggle, view = null) {
button.classList.toggle("toggled", toggle);
button.setAttribute("aria-expanded", toggle);
view?.classList.toggle("hidden", !toggle);
;// CONCATENATED MODULE: ./web/app_options.js
var compatibilityParams = Object.create(null);
const userAgent = navigator.userAgent || "";
const platform = navigator.platform || "";
const maxTouchPoints = navigator.maxTouchPoints || 1;
const isAndroid = /Android/.test(userAgent);
const isIOS = /\b(iPad|iPhone|iPod)(?=;)/.test(userAgent) || platform === "MacIntel" && maxTouchPoints > 1;
(function checkCanvasSizeLimitation() {
if (isIOS || isAndroid) {
compatibilityParams.maxCanvasPixels = 5242880;
kind: OptionKind.BROWSER + OptionKind.API
supportsCaretBrowsingMode: {