IG Scroll Brake

Limit Instagram posts, reels, and comments and reveal more only when you choose.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         IG Scroll Brake
// @namespace    https://github.com/atharvj/ig-scroll-brake
// @version      1.1.1
// @description  Limit Instagram posts, reels, and comments and reveal more only when you choose.
// @author       Intellectual07
// @license      MIT
// @match        https://www.instagram.com/*
// @match        https://instagram.com/*
// @match        https://m.instagram.com/*
// @run-at       document-idle
// @grant        none
// @noframes
// ==/UserScript==

(function () {
  "use strict";

  const INITIAL_VISIBLE_ITEMS = 10;
  const INITIAL_VISIBLE_REELS = 5;
  const ITEMS_PER_CLICK = 5;

  const BRAKE_ID = "ig-scroll-brake";
  const STYLE_ID = "ig-scroll-brake-styles";
  const STORAGE_KEY = "ig-scroll-brake-items-per-click";
  const SCAN_DELAY_MS = 75;
  const ROUTE_SETTLE_DELAY_MS = 300;
  const EXPAND_LOCK_GRACE_MS = 1200;
  const BRAKE_PANEL_HEIGHT = 104;
  const TOP_RESET_SCROLL_Y = 120;
  const TOP_RESET_MIN_DISTANCE = 600;
  const MIN_ITEMS_PER_CLICK = 1;
  const MAX_ITEMS_PER_CLICK = 100;
  const MAX_SAVED_ROUTE_STATES = 12;
  const MIN_MEDIA_WIDTH = 80;
  const MIN_MEDIA_HEIGHT = 48;
  const MIN_COMMENT_WIDTH = 140;
  const MIN_COMMENT_HEIGHT = 20;

  const MEDIA_PATH_RE = /^\/(?:[^/]+\/)?(p|reel|tv)\/([^/?#]+)/i;
  const COMMENT_PATH_RE = /^\/(?:[^/]+\/)?(p|reel|tv)\/([^/?#]+)\/c\/([^/?#]+)/i;
  const PROFILE_PATH_RE = /^\/([A-Za-z0-9._]{1,30})(?:\/(?:reels|tagged))?\/?$/;
  const INACTIVE_ROUTE_RE = /^\/(?:about|accounts|ads|api|challenge|developer|direct|emails|legal|oauth|privacy|settings|stories|terms|web)(?:\/|$)/i;
  const RESERVED_PROFILE_SEGMENTS = new Set([
    "about",
    "accounts",
    "ads",
    "api",
    "challenge",
    "developer",
    "direct",
    "emails",
    "explore",
    "legal",
    "oauth",
    "p",
    "privacy",
    "reel",
    "reels",
    "settings",
    "stories",
    "terms",
    "tv",
    "web",
  ]);

  let visibleItemLimit = getInitialVisibleItemLimit();
  let itemsPerClick = readSavedItemsPerClick();
  let currentRouteKey = getRouteKey();
  let scanTimer = null;
  let routeSettlesAt = 0;
  let lastTouchY = null;
  let isLocked = false;
  let maxScrollPosition = null;
  let lockScroller = null;
  let lastScrollPosition = getScrollPosition(window);
  let minPositionForNextLock = null;
  let allowMaxIncreaseUntil = 0;
  let activeReelKey = "";
  let lastObservedHref = location.href;
  const orderedKeys = [];
  const routeStates = new Map();

  function addStyles() {
    if (document.getElementById(STYLE_ID)) {
      return;
    }

    const style = document.createElement("style");
    style.id = STYLE_ID;
    style.textContent = `
      #${BRAKE_ID} {
        --isb-accent: #0095f6;
        --isb-accent-hover: #1877f2;
        --isb-background: #ffffff;
        --isb-border: #dbdbdb;
        --isb-muted: #737373;
        --isb-text: #262626;
        position: fixed;
        left: 50%;
        bottom: max(18px, env(safe-area-inset-bottom));
        z-index: 2147483647;
        box-sizing: border-box;
        width: min(540px, calc(100vw - 28px));
        overflow: hidden;
        transform: translateX(-50%);
        border: 1px solid var(--isb-border);
        border-radius: 16px;
        background: var(--isb-background);
        color: var(--isb-text);
        box-shadow: 0 12px 40px rgba(0, 0, 0, 0.2);
        font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
        color-scheme: light dark;
      }

      #${BRAKE_ID}::before {
        position: absolute;
        top: 0;
        right: 0;
        left: 0;
        height: 3px;
        background: linear-gradient(90deg, #feda75, #fa7e1e 24%, #d62976 52%, #962fbf 76%, #4f5bd5);
        content: "";
      }

      #${BRAKE_ID}[hidden] {
        display: none !important;
      }

      #${BRAKE_ID} .isb-inner {
        display: grid;
        grid-template-columns: auto minmax(0, 1fr);
        gap: 8px 10px;
        align-items: center;
        padding: 13px 14px 11px;
      }

      #${BRAKE_ID} .isb-mark {
        display: grid;
        width: 34px;
        height: 34px;
        grid-row: 1 / span 2;
        place-items: center;
        border-radius: 10px;
        background: linear-gradient(145deg, #feda75, #fa7e1e 25%, #d62976 52%, #962fbf 76%, #4f5bd5);
        color: #ffffff;
        box-shadow: 0 2px 8px rgba(214, 41, 118, 0.24);
      }

      #${BRAKE_ID} .isb-mark svg {
        display: block;
        width: 21px;
        height: 21px;
      }

      #${BRAKE_ID} .isb-title {
        overflow: hidden;
        font-size: 14px;
        font-weight: 700;
        line-height: 18px;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      #${BRAKE_ID} .isb-status {
        overflow: hidden;
        color: var(--isb-muted);
        font-size: 12px;
        font-weight: 400;
        line-height: 16px;
        text-overflow: ellipsis;
        white-space: nowrap;
      }

      #${BRAKE_ID} .isb-controls {
        display: flex;
        grid-column: 1 / -1;
        align-items: center;
        justify-content: center;
        gap: 8px;
      }

      #${BRAKE_ID} button {
        min-height: 36px;
        flex: 1 1 auto;
        border: 0;
        border-radius: 9px;
        padding: 8px 14px;
        background: var(--isb-accent);
        color: #ffffff;
        font: 600 14px/18px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
        cursor: pointer;
      }

      #${BRAKE_ID} button:hover {
        background: var(--isb-accent-hover);
      }

      #${BRAKE_ID} button:active {
        opacity: 0.78;
      }

      #${BRAKE_ID} button:focus-visible,
      #${BRAKE_ID} input:focus-visible {
        outline: 3px solid rgba(0, 149, 246, 0.3);
        outline-offset: 2px;
      }

      #${BRAKE_ID} label {
        display: inline-flex;
        flex: 0 0 auto;
        align-items: center;
        gap: 6px;
        color: var(--isb-muted);
        font-size: 12px;
        font-weight: 600;
        white-space: nowrap;
      }

      #${BRAKE_ID} input {
        box-sizing: border-box;
        width: 58px;
        height: 36px;
        border: 1px solid var(--isb-border);
        border-radius: 9px;
        padding: 7px 6px;
        background: var(--isb-background);
        color: var(--isb-text);
        font: 600 14px/18px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
        text-align: center;
      }

      @media (max-width: 430px) {
        #${BRAKE_ID} {
          bottom: max(10px, env(safe-area-inset-bottom));
          width: calc(100vw - 20px);
        }

        #${BRAKE_ID} .isb-inner {
          padding: 12px 12px 10px;
        }

        #${BRAKE_ID} label span {
          position: absolute;
          width: 1px;
          height: 1px;
          overflow: hidden;
          clip: rect(0 0 0 0);
          white-space: nowrap;
          clip-path: inset(50%);
        }
      }

      @media (prefers-color-scheme: dark) {
        #${BRAKE_ID} {
          --isb-background: #000000;
          --isb-border: #363636;
          --isb-muted: #a8a8a8;
          --isb-text: #f5f5f5;
          box-shadow: 0 12px 42px rgba(0, 0, 0, 0.62);
        }
      }

      @media (prefers-reduced-motion: reduce) {
        #${BRAKE_ID},
        #${BRAKE_ID} * {
          scroll-behavior: auto !important;
          transition: none !important;
        }
      }
    `;

    (document.head || document.documentElement).appendChild(style);
  }

  function clampWholeNumber(value, fallback, min, max) {
    const number = Number(value);

    if (!Number.isFinite(number)) {
      return fallback;
    }

    return Math.min(max, Math.max(min, Math.floor(number)));
  }

  function getInitialVisibleItemLimit() {
    const initialLimit = getSurface().kind === "reels"
      ? INITIAL_VISIBLE_REELS
      : INITIAL_VISIBLE_ITEMS;

    return clampWholeNumber(initialLimit, 10, 1, Number.MAX_SAFE_INTEGER);
  }

  function normalizedPathname() {
    const pathname = location.pathname.replace(/\/{2,}/g, "/");
    return pathname === "/" ? pathname : pathname.replace(/\/$/, "");
  }

  function isContinuousReelsRoute() {
    return /^\/reels?(?:\/|$)/i.test(normalizedPathname());
  }

  function getRouteKey() {
    if (isContinuousReelsRoute()) {
      return "/reels/:continuous";
    }

    const pathname = normalizedPathname();

    if (pathname === "/") {
      const variant = new URLSearchParams(location.search).get("variant");
      return variant ? `/?variant=${encodeURIComponent(variant)}` : "/";
    }

    return pathname;
  }

  function readSavedItemsPerClick() {
    let savedValue = null;

    try {
      savedValue = window.localStorage.getItem(STORAGE_KEY);
    } catch {
      savedValue = null;
    }

    return clampWholeNumber(
      savedValue || ITEMS_PER_CLICK,
      ITEMS_PER_CLICK,
      MIN_ITEMS_PER_CLICK,
      MAX_ITEMS_PER_CLICK
    );
  }

  function saveItemsPerClick() {
    try {
      window.localStorage.setItem(STORAGE_KEY, String(itemsPerClick));
    } catch {
      // The control still works for the current page when storage is unavailable.
    }
  }

  function getSurface() {
    const pathname = normalizedPathname();

    if (INACTIVE_ROUTE_RE.test(pathname)) {
      return { active: false, kind: "inactive", singular: "item", plural: "items" };
    }

    if (/^\/(?:p|tv)\/[^/]+/i.test(pathname)) {
      return { active: true, kind: "comments", singular: "comment", plural: "comments" };
    }

    if (isContinuousReelsRoute()) {
      return { active: true, kind: "reels", singular: "reel", plural: "reels" };
    }

    return { active: true, kind: "media", singular: "post", plural: "posts" };
  }

  function getMainContent() {
    return (
      document.querySelector('main[role="main"]') ||
      document.querySelector("main") ||
      document.querySelector('[role="main"]') ||
      document.body
    );
  }

  function parseUrl(value) {
    try {
      return new URL(value, location.origin);
    } catch {
      return null;
    }
  }

  function getMediaInfoFromHref(href) {
    const url = parseUrl(href);

    if (!url || !/(^|\.)instagram\.com$/i.test(url.hostname)) {
      return null;
    }

    if (COMMENT_PATH_RE.test(url.pathname)) {
      return null;
    }

    const match = url.pathname.match(MEDIA_PATH_RE);

    if (!match) {
      return null;
    }

    return {
      kind: match[1].toLowerCase(),
      code: decodeURIComponent(match[2]),
      key: `media:${decodeURIComponent(match[2])}`,
    };
  }

  function getCommentInfoFromHref(href) {
    const url = parseUrl(href);

    if (!url || !/(^|\.)instagram\.com$/i.test(url.hostname)) {
      return null;
    }

    const pathMatch = url.pathname.match(COMMENT_PATH_RE);

    if (pathMatch) {
      return {
        mediaCode: decodeURIComponent(pathMatch[2]),
        commentId: decodeURIComponent(pathMatch[3]),
        key: `comment:${decodeURIComponent(pathMatch[2])}:${decodeURIComponent(pathMatch[3])}`,
      };
    }

    const mediaMatch = url.pathname.match(MEDIA_PATH_RE);
    const commentId = url.searchParams.get("comment_id");

    if (!mediaMatch || !commentId) {
      return null;
    }

    return {
      mediaCode: decodeURIComponent(mediaMatch[2]),
      commentId,
      key: `comment:${decodeURIComponent(mediaMatch[2])}:${commentId}`,
    };
  }

  function getAttributeValue(element, names) {
    if (!(element instanceof Element)) {
      return "";
    }

    for (const name of names) {
      const value = element.getAttribute(name);

      if (value) {
        return value;
      }
    }

    return "";
  }

  function hashText(value) {
    let hash = 2166136261;

    for (let index = 0; index < value.length; index += 1) {
      hash ^= value.charCodeAt(index);
      hash = Math.imul(hash, 16777619);
    }

    return (hash >>> 0).toString(36);
  }

  function normalizeText(value) {
    return String(value || "").replace(/\s+/g, " ").trim();
  }

  function getElementMediaKey(element) {
    if (!(element instanceof Element)) {
      return "";
    }

    const directId = getAttributeValue(element, [
      "data-media-id",
      "data-media-pk",
      "data-shortcode",
      "data-code",
    ]);

    if (directId) {
      return `media:${directId}`;
    }

    const links = element.matches("a[href]")
      ? [element]
      : Array.from(element.querySelectorAll("a[href]"));
    const timedLink = links.find((link) => link.querySelector("time") && getMediaInfoFromHref(link.getAttribute("href")));
    const mediaLink = timedLink || links.find((link) => getMediaInfoFromHref(link.getAttribute("href")));

    if (mediaLink) {
      return getMediaInfoFromHref(mediaLink.getAttribute("href")).key;
    }

    const video = element.matches("video") ? element : element.querySelector("video");

    if (!video) {
      return "";
    }

    const author = element.querySelector('a[href^="/"]:not([href^="/p/"]):not([href^="/reel/"])');
    const poster = video.getAttribute("poster") || video.currentSrc || video.getAttribute("src") || "";
    const posterUrl = parseUrl(poster);
    const stablePoster = posterUrl ? posterUrl.pathname : poster;
    const fingerprint = normalizeText(
      `${author ? author.getAttribute("href") : ""}|${stablePoster}|${element.getAttribute("aria-label") || ""}`
    );

    if (fingerprint.replace(/[|]/g, "")) {
      return `media-fallback:${hashText(fingerprint)}`;
    }

    const currentMedia = getMediaInfoFromHref(location.href);
    return currentMedia ? currentMedia.key : "";
  }

  function getDistinctMediaKeys(element) {
    const keys = new Set();

    if (!(element instanceof Element)) {
      return keys;
    }

    if (element.matches("a[href]")) {
      const info = getMediaInfoFromHref(element.getAttribute("href"));
      if (info) {
        keys.add(info.key);
      }
    }

    element.querySelectorAll("a[href]").forEach((link) => {
      const info = getMediaInfoFromHref(link.getAttribute("href"));
      if (info) {
        keys.add(info.key);
      }
    });

    return keys;
  }

  function isExcludedElement(element) {
    return Boolean(
      element.closest(
        `#${BRAKE_ID}, aside, nav, header, footer, dialog, [aria-modal="true"], [role="dialog"], [role="navigation"], [role="complementary"]`
      )
    );
  }

  function isCountableElement(element, minWidth, minHeight) {
    if (!(element instanceof Element) || isExcludedElement(element)) {
      return false;
    }

    if (element.closest('[hidden], [aria-hidden="true"]')) {
      return false;
    }

    const rect = element.getBoundingClientRect();

    if (rect.width < minWidth || rect.height < minHeight) {
      return false;
    }

    const style = window.getComputedStyle(element);
    return style.display !== "none" && style.visibility !== "hidden" && Number(style.opacity || 1) !== 0;
  }

  function findMediaContainerFromLink(link, root) {
    const article = link.closest("article");

    if (article && root.contains(article)) {
      return article;
    }

    let current = link;
    let best = link;
    let depth = 0;

    while (current && current !== root && current !== document.body && depth < 7) {
      const keys = getDistinctMediaKeys(current);

      if (keys.size > 1) {
        break;
      }

      if (keys.size === 1) {
        const rect = current.getBoundingClientRect();
        if (rect.width >= MIN_MEDIA_WIDTH && rect.height >= MIN_MEDIA_HEIGHT) {
          best = current;
        }
      }

      current = current.parentElement;
      depth += 1;
    }

    return best;
  }

  function findMediaContainerFromVideo(video, root) {
    const article = video.closest("article");

    if (article && root.contains(article)) {
      return article;
    }

    let current = video;
    let best = video;
    let depth = 0;

    while (current && current !== root && current !== document.body && depth < 8) {
      const videos = current.matches("video") ? 1 : current.querySelectorAll("video").length;

      if (videos > 1) {
        break;
      }

      const rect = current.getBoundingClientRect();

      if (rect.width >= MIN_MEDIA_WIDTH && rect.height >= MIN_MEDIA_HEIGHT) {
        best = current;
      }

      current = current.parentElement;
      depth += 1;
    }

    return best;
  }

  function sortRecordsInDocumentOrder(records) {
    return records.sort((left, right) => {
      if (left.item === right.item) {
        return 0;
      }

      const position = left.item.compareDocumentPosition(right.item);

      if (position & Node.DOCUMENT_POSITION_FOLLOWING) {
        return -1;
      }

      if (position & Node.DOCUMENT_POSITION_PRECEDING) {
        return 1;
      }

      return 0;
    });
  }

  function getMediaRecords() {
    const root = getMainContent();

    if (!root) {
      return [];
    }

    const seenKeys = new Set();
    const records = [];

    root.querySelectorAll("article").forEach((article) => {
      if (article.parentElement && article.parentElement.closest("article")) {
        return;
      }

      const key = getElementMediaKey(article);

      if (!key || seenKeys.has(key) || !isCountableElement(article, MIN_MEDIA_WIDTH, MIN_MEDIA_HEIGHT)) {
        return;
      }

      seenKeys.add(key);
      records.push({ item: article, key });
    });

    root.querySelectorAll('a[href*="/p/"], a[href*="/reel/"], a[href*="/tv/"]').forEach((link) => {
      const info = getMediaInfoFromHref(link.getAttribute("href"));

      if (!info || seenKeys.has(info.key)) {
        return;
      }

      const item = findMediaContainerFromLink(link, root);

      if (!isCountableElement(item, MIN_MEDIA_WIDTH, MIN_MEDIA_HEIGHT)) {
        return;
      }

      seenKeys.add(info.key);
      records.push({ item, key: info.key });
    });

    root.querySelectorAll("video").forEach((video) => {
      const item = findMediaContainerFromVideo(video, root);
      const key = getElementMediaKey(item);

      if (!key || seenKeys.has(key) || !isCountableElement(item, MIN_MEDIA_WIDTH, MIN_MEDIA_HEIGHT)) {
        return;
      }

      seenKeys.add(key);
      records.push({ item, key });
    });

    return sortRecordsInDocumentOrder(records);
  }

  function getCommentKey(comment) {
    const commentId = getAttributeValue(comment, [
      "data-comment-id",
      "data-comment-pk",
      "data-id",
    ]);
    const currentMedia = getMediaInfoFromHref(location.href);

    if (commentId) {
      return `comment:${currentMedia ? currentMedia.code : "unknown"}:${commentId}`;
    }

    const links = comment.matches("a[href]")
      ? [comment]
      : Array.from(comment.querySelectorAll("a[href]"));
    const commentLink = links.find((link) => getCommentInfoFromHref(link.getAttribute("href")));

    if (commentLink) {
      return getCommentInfoFromHref(commentLink.getAttribute("href")).key;
    }

    const time = comment.querySelector("time[datetime]");
    const author = Array.from(comment.querySelectorAll('a[href^="/"]')).find((link) => {
      const href = link.getAttribute("href") || "";
      const match = href.match(PROFILE_PATH_RE);
      return match && !RESERVED_PROFILE_SEGMENTS.has(match[1].toLowerCase());
    });
    const text = normalizeText(comment.textContent);

    const timeLink = time ? time.closest("a[href]") : null;

    if (
      !time ||
      !author ||
      text.length < 2 ||
      (timeLink && getMediaInfoFromHref(timeLink.getAttribute("href")))
    ) {
      return "";
    }

    const fingerprint = `${currentMedia ? currentMedia.code : "unknown"}|${author.getAttribute("href")}|${time.getAttribute("datetime")}|${text}`;
    return `comment-fallback:${hashText(fingerprint)}`;
  }

  function getCommentContainer(element, root) {
    return (
      element.closest("[data-comment-id], [data-comment-pk]") ||
      element.closest("li") ||
      element.closest('[role="article"]') ||
      (root.contains(element) ? element : null)
    );
  }

  function getCommentRecords() {
    const root = getMainContent();

    if (!root) {
      return [];
    }

    const candidates = new Set();

    root.querySelectorAll("[data-comment-id], [data-comment-pk]").forEach((element) => {
      candidates.add(element);
    });

    root.querySelectorAll('a[href*="/c/"], a[href*="comment_id="]').forEach((link) => {
      const comment = getCommentContainer(link, root);
      if (comment) {
        candidates.add(comment);
      }
    });

    root.querySelectorAll("li time[datetime]").forEach((time) => {
      const comment = getCommentContainer(time, root);
      if (comment) {
        candidates.add(comment);
      }
    });

    const seenItems = new Set();
    const seenKeys = new Set();
    const records = [];

    candidates.forEach((candidate) => {
      const item = getCommentContainer(candidate, root);

      if (
        !item ||
        seenItems.has(item) ||
        !isCountableElement(item, MIN_COMMENT_WIDTH, MIN_COMMENT_HEIGHT)
      ) {
        return;
      }

      seenItems.add(item);
      const key = getCommentKey(item);

      if (!key || seenKeys.has(key)) {
        return;
      }

      seenKeys.add(key);
      records.push({ item, key });
    });

    return sortRecordsInDocumentOrder(records);
  }

  function getCountableRecords() {
    const surface = getSurface();

    if (!surface.active) {
      return [];
    }

    return surface.kind === "comments" ? getCommentRecords() : getMediaRecords();
  }

  function rememberItemOrder(records) {
    records.forEach((record, index) => {
      if (orderedKeys.includes(record.key)) {
        return;
      }

      const previousKnownKey = findNearbyKnownKey(records, index - 1, -1);
      const nextKnownKey = findNearbyKnownKey(records, index + 1, 1);

      if (previousKnownKey) {
        orderedKeys.splice(orderedKeys.indexOf(previousKnownKey) + 1, 0, record.key);
      } else if (nextKnownKey) {
        orderedKeys.splice(orderedKeys.indexOf(nextKnownKey), 0, record.key);
      } else {
        orderedKeys.push(record.key);
      }
    });
  }

  function findNearbyKnownKey(records, startIndex, direction) {
    for (
      let index = startIndex;
      index >= 0 && index < records.length;
      index += direction
    ) {
      if (orderedKeys.includes(records[index].key)) {
        return records[index].key;
      }
    }

    return "";
  }

  function applyBrake() {
    resetAfterNavigation();

    const settleTimeLeft = routeSettlesAt - Date.now();

    if (settleTimeLeft > 0) {
      scheduleApplyBrake(settleTimeLeft);
      return;
    }

    const surface = getSurface();

    if (!surface.active) {
      unlockBrake();
      return;
    }

    if (surface.kind === "reels") {
      applyReelsBrake();
      return;
    }

    const records = getCountableRecords();
    rememberItemOrder(records);

    if (orderedKeys.length < visibleItemLimit) {
      unlockBrake();
      return;
    }

    const boundary = findBoundaryRecord(records);

    if (!boundary) {
      unlockBrake();
      updateBrakeText();
      return;
    }

    lockAtBoundary(boundary, records);
  }

  function getVisibleRecordScore(record, scroller) {
    const rect = record.item.getBoundingClientRect();
    const scrollerRect = scroller === window
      ? { top: 0, bottom: window.innerHeight }
      : scroller.getBoundingClientRect();
    const visibleTop = Math.max(rect.top, scrollerRect.top);
    const visibleBottom = Math.min(rect.bottom, scrollerRect.bottom);
    const visibleHeight = Math.max(0, visibleBottom - visibleTop);
    const viewportCenter = (scrollerRect.top + scrollerRect.bottom) / 2;
    const itemCenter = (rect.top + rect.bottom) / 2;

    return visibleHeight * 1000 - Math.abs(viewportCenter - itemCenter);
  }

  function findBestVisibleRecord(records) {
    let bestRecord = null;
    let bestScore = -Infinity;

    records.forEach((record) => {
      const scroller = findScrollContainer(record.item);
      const score = getVisibleRecordScore(record, scroller);

      if (score > bestScore) {
        bestRecord = record;
        bestScore = score;
      }
    });

    return bestRecord;
  }

  function getActiveReelRecord(records) {
    const routeMedia = getMediaInfoFromHref(location.href);
    const routeRecord = routeMedia
      ? records.find((record) => record.key === routeMedia.key)
      : null;
    const visibleRecord = routeRecord || findBestVisibleRecord(records);

    if (routeMedia) {
      return {
        item: visibleRecord ? visibleRecord.item : getMainContent(),
        key: routeMedia.key,
      };
    }

    return visibleRecord;
  }

  function rememberViewedReel(record) {
    activeReelKey = record ? record.key : activeReelKey;

    if (activeReelKey && !orderedKeys.includes(activeReelKey)) {
      orderedKeys.push(activeReelKey);
    }

  }

  function applyReelsBrake() {
    const records = getMediaRecords();
    const activeRecord = getActiveReelRecord(records);

    rememberViewedReel(activeRecord);

    if (orderedKeys.length < visibleItemLimit) {
      unlockBrake();
      return;
    }

    if (!activeRecord) {
      if (isLocked) {
        showBrake();
        updateBrakeText();
      }
      return;
    }

    const activeIndex = orderedKeys.indexOf(activeRecord.key);
    const boundaryIndex = visibleItemLimit - 1;

    if (isLocked && lockScroller && activeIndex < boundaryIndex) {
      showBrake();
      updateBrakeText();
      clampScrollToBrake(lockScroller);
      return;
    }

    if (activeIndex >= boundaryIndex) {
      lockAtCurrentReel(activeRecord);
    }
  }

  function lockAtCurrentReel(record) {
    const nextScroller = findScrollContainer(record.item);
    const scrollerChanged = lockScroller !== nextScroller;
    let nextMaxPosition = getScrollPosition(nextScroller);

    if (minPositionForNextLock !== null) {
      nextMaxPosition = Math.max(nextMaxPosition, minPositionForNextLock);
      minPositionForNextLock = null;
    }

    setMaxScrollPosition(nextMaxPosition, nextScroller);
    isLocked = true;
    lockScroller = nextScroller;

    if (scrollerChanged) {
      lastScrollPosition = getScrollPosition(nextScroller);
    }

    showBrake();
    updateBrakeText();
    clampScrollToBrake(nextScroller);
    pauseInactiveReelMedia(record.item);
  }

  function pauseInactiveReelMedia(activeItem) {
    const root = getMainContent();

    if (!root) {
      return;
    }

    root.querySelectorAll("video").forEach((video) => {
      if (video !== activeItem && !activeItem.contains(video)) {
        pauseMediaInElement(video);
      }
    });
  }

  function findBoundaryRecord(records) {
    const anchorKey = orderedKeys[visibleItemLimit - 1];
    const anchorRecord = records.find((record) => record.key === anchorKey);

    if (anchorRecord) {
      return { edge: "bottom", record: anchorRecord };
    }

    const firstHiddenRecord = records.find(
      (record) => orderedKeys.indexOf(record.key) >= visibleItemLimit
    );

    return firstHiddenRecord ? { edge: "top", record: firstHiddenRecord } : null;
  }

  function findScrollContainer(element) {
    let current = element.parentElement;

    while (current && current !== document.body && current !== document.documentElement) {
      const style = window.getComputedStyle(current);
      const overflowY = style.overflowY || style.overflow;

      if (/(auto|scroll|overlay)/.test(overflowY) && current.scrollHeight > current.clientHeight + 1) {
        return current;
      }

      current = current.parentElement;
    }

    return window;
  }

  function getScrollPosition(scroller) {
    return scroller === window ? window.scrollY : scroller.scrollTop;
  }

  function getViewportHeight(scroller) {
    return scroller === window ? window.innerHeight : scroller.clientHeight;
  }

  function getBoundaryPosition(boundary, scroller) {
    const rect = boundary.record.item.getBoundingClientRect();
    const edgePosition = boundary.edge === "top" ? rect.top : rect.bottom;

    if (scroller === window) {
      return window.scrollY + edgePosition;
    }

    const scrollerRect = scroller.getBoundingClientRect();
    return scroller.scrollTop + edgePosition - scrollerRect.top;
  }

  function lockAtBoundary(boundary, records) {
    const nextScroller = findScrollContainer(boundary.record.item);
    const scrollerChanged = lockScroller !== nextScroller;
    const boundaryPosition = getBoundaryPosition(boundary, nextScroller);
    let nextMaxPosition = Math.max(
      0,
      boundaryPosition - getViewportHeight(nextScroller) + BRAKE_PANEL_HEIGHT
    );

    if (minPositionForNextLock !== null) {
      nextMaxPosition = Math.max(nextMaxPosition, minPositionForNextLock);
      minPositionForNextLock = null;
    }

    setMaxScrollPosition(nextMaxPosition, nextScroller);
    isLocked = true;
    lockScroller = nextScroller;
    if (scrollerChanged) {
      lastScrollPosition = getScrollPosition(nextScroller);
    }
    showBrake();
    updateBrakeText();
    clampScrollToBrake(nextScroller);
    pauseMediaAfterLimit(records);
  }

  function setMaxScrollPosition(nextMaxPosition, nextScroller) {
    if (
      !isLocked ||
      maxScrollPosition === null ||
      lockScroller !== nextScroller ||
      nextMaxPosition < maxScrollPosition ||
      Date.now() <= allowMaxIncreaseUntil
    ) {
      maxScrollPosition = nextMaxPosition;
    }
  }

  function unlockBrake() {
    isLocked = false;
    maxScrollPosition = null;
    lockScroller = null;
    hideBrake();
  }

  function ensureBrake() {
    const existingBrake = document.getElementById(BRAKE_ID);

    if (existingBrake) {
      return existingBrake;
    }

    const brake = document.createElement("section");
    brake.id = BRAKE_ID;
    brake.hidden = true;
    brake.setAttribute("role", "region");
    brake.setAttribute("aria-label", "IG Scroll Brake controls");
    brake.innerHTML = `
      <div class="isb-inner">
        <div class="isb-mark" aria-hidden="true">
          <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
            <rect x="3" y="3" width="18" height="18" rx="5"></rect>
            <circle cx="12" cy="12" r="4"></circle>
            <circle cx="17.5" cy="6.5" r="1" fill="currentColor" stroke="none"></circle>
          </svg>
        </div>
        <div class="isb-title">You’ve reached your scroll brake</div>
        <div class="isb-status" aria-live="polite"></div>
        <div class="isb-controls">
          <button type="button">Load more</button>
          <label>
            <span>At a time</span>
            <input type="number" min="${MIN_ITEMS_PER_CLICK}" max="${MAX_ITEMS_PER_CLICK}" step="1" inputmode="numeric" aria-label="Items to load at a time">
          </label>
        </div>
      </div>
    `;

    const input = brake.querySelector("input");
    const button = brake.querySelector("button");

    input.value = String(itemsPerClick);
    input.addEventListener("change", syncItemsPerClickFromInput);
    input.addEventListener("blur", syncItemsPerClickFromInput);
    input.addEventListener("input", updateBrakeText);

    button.addEventListener("click", () => {
      resetAfterNavigation();
      clearScheduledScan();
      syncItemsPerClickFromInput();
      minPositionForNextLock = lockScroller ? getScrollPosition(lockScroller) : null;
      allowMaxIncreaseUntil = Date.now() + EXPAND_LOCK_GRACE_MS;
      visibleItemLimit += itemsPerClick;
      unlockBrake();
      scheduleApplyBrake(0);
    });

    document.body.appendChild(brake);
    return brake;
  }

  function showBrake() {
    ensureBrake().hidden = false;
  }

  function hideBrake() {
    const brake = document.getElementById(BRAKE_ID);

    if (brake) {
      brake.hidden = true;
    }
  }

  function syncItemsPerClickFromInput() {
    const input = document.querySelector(`#${BRAKE_ID} input`);

    if (!input) {
      return;
    }

    itemsPerClick = clampWholeNumber(
      input.value,
      itemsPerClick,
      MIN_ITEMS_PER_CLICK,
      MAX_ITEMS_PER_CLICK
    );
    input.value = String(itemsPerClick);
    saveItemsPerClick();
    updateBrakeText();
  }

  function updateBrakeText() {
    const brake = ensureBrake();
    const input = brake.querySelector("input");
    const button = brake.querySelector("button");
    const status = brake.querySelector(".isb-status");
    const surface = getSurface();
    const typedCount = input ? input.value : itemsPerClick;
    const previewCount = clampWholeNumber(
      typedCount,
      itemsPerClick,
      MIN_ITEMS_PER_CLICK,
      MAX_ITEMS_PER_CLICK
    );
    const shownCount = Math.min(visibleItemLimit, orderedKeys.length);
    const previewLabel = previewCount === 1 ? surface.singular : surface.plural;
    const shownLabel = shownCount === 1 ? surface.singular : surface.plural;
    const buttonText = `Load ${previewCount} more ${previewLabel}`;
    const statusText = `Showing ${shownCount} ${shownLabel} · scrolling paused`;

    if (button && button.textContent !== buttonText) {
      button.textContent = buttonText;
    }

    if (input && document.activeElement !== input) {
      input.value = String(itemsPerClick);
    }

    if (status && status.textContent !== statusText) {
      status.textContent = statusText;
    }
  }

  function pauseMediaAfterLimit(records) {
    records.forEach((record) => {
      const keyIndex = orderedKeys.indexOf(record.key);

      if (keyIndex >= visibleItemLimit) {
        pauseMediaInElement(record.item);
      }
    });
  }

  function pauseMediaInElement(element) {
    const mediaElements = element.matches("audio, video")
      ? [element]
      : Array.from(element.querySelectorAll("audio, video"));

    mediaElements.forEach((media) => {
      try {
        media.pause();
      } catch {
        // Some browser media shims throw when pause is unavailable.
      }
      media.autoplay = false;
      media.removeAttribute("autoplay");
    });
  }

  function scheduleApplyBrake(delay) {
    const routeChanged = resetAfterNavigation();

    if (scanTimer !== null) {
      return;
    }

    const wait = routeChanged
      ? ROUTE_SETTLE_DELAY_MS
      : clampWholeNumber(delay, SCAN_DELAY_MS, 0, ROUTE_SETTLE_DELAY_MS);

    scanTimer = window.setTimeout(() => {
      scanTimer = null;
      applyBrake();
    }, wait);
  }

  function clearScheduledScan() {
    if (scanTimer === null) {
      return;
    }

    window.clearTimeout(scanTimer);
    scanTimer = null;
  }

  function resetAfterNavigation() {
    const nextRouteKey = getRouteKey();

    if (nextRouteKey === currentRouteKey) {
      return false;
    }

    saveCurrentRouteState();
    currentRouteKey = nextRouteKey;

    if (!restoreRouteState(nextRouteKey)) {
      resetCurrentProgress();
    }

    return true;
  }

  function saveCurrentRouteState() {
    routeStates.delete(currentRouteKey);
    routeStates.set(currentRouteKey, {
      activeReelKey,
      visibleItemLimit,
      orderedKeys: orderedKeys.slice(),
    });

    while (routeStates.size > MAX_SAVED_ROUTE_STATES) {
      const oldestKey = routeStates.keys().next().value;
      routeStates.delete(oldestKey);
    }
  }

  function restoreRouteState(routeKey) {
    const state = routeStates.get(routeKey);

    if (!state) {
      return false;
    }

    visibleItemLimit = clampWholeNumber(
      state.visibleItemLimit,
      getInitialVisibleItemLimit(),
      1,
      Number.MAX_SAFE_INTEGER
    );
    activeReelKey = state.activeReelKey || "";
    orderedKeys.length = 0;
    state.orderedKeys.forEach((key) => {
      if (key && !orderedKeys.includes(key)) {
        orderedKeys.push(key);
      }
    });
    routeSettlesAt = Date.now() + ROUTE_SETTLE_DELAY_MS;
    minPositionForNextLock = null;
    allowMaxIncreaseUntil = 0;
    clearScheduledScan();
    unlockBrake();
    return true;
  }

  function resetCurrentProgress() {
    routeStates.delete(currentRouteKey);
    visibleItemLimit = getInitialVisibleItemLimit();
    activeReelKey = "";
    orderedKeys.length = 0;
    routeSettlesAt = Date.now() + ROUTE_SETTLE_DELAY_MS;
    minPositionForNextLock = null;
    allowMaxIncreaseUntil = 0;
    clearScheduledScan();
    unlockBrake();
  }

  function setScrollPosition(scroller, position) {
    if (scroller === window) {
      window.scrollTo({
        top: position,
        left: window.scrollX,
        behavior: "auto",
      });
      return;
    }

    if (typeof scroller.scrollTo === "function") {
      scroller.scrollTo({ top: position, left: scroller.scrollLeft, behavior: "auto" });
    } else {
      scroller.scrollTop = position;
    }
  }

  function clampScrollToBrake(eventOrScroller) {
    const eventTarget = eventOrScroller && eventOrScroller.target;
    const scroller = eventOrScroller instanceof Element || eventOrScroller === window
      ? eventOrScroller
      : lockScroller || window;

    if (eventTarget && lockScroller && lockScroller !== window && eventTarget !== lockScroller) {
      return;
    }

    const currentPosition = getScrollPosition(scroller);

    if (resetAfterNavigation()) {
      lastScrollPosition = currentPosition;
      scheduleApplyBrake(ROUTE_SETTLE_DELAY_MS);
      return;
    }

    if (getSurface().kind === "reels") {
      scheduleApplyBrake(0);
    }

    if (shouldResetAfterTopJump(currentPosition)) {
      resetCurrentProgress();
      lastScrollPosition = currentPosition;
      scheduleApplyBrake(ROUTE_SETTLE_DELAY_MS);
      return;
    }

    if (
      !isLocked ||
      maxScrollPosition === null ||
      scroller !== lockScroller ||
      currentPosition <= maxScrollPosition
    ) {
      lastScrollPosition = currentPosition;
      return;
    }

    setScrollPosition(scroller, maxScrollPosition);
    lastScrollPosition = maxScrollPosition;
  }

  function shouldResetAfterTopJump(currentPosition) {
    return (
      isLocked &&
      maxScrollPosition !== null &&
      currentPosition <= TOP_RESET_SCROLL_Y &&
      lastScrollPosition - currentPosition >= TOP_RESET_MIN_DISTANCE
    );
  }

  function isEditableTarget(target) {
    if (!(target instanceof Element)) {
      return false;
    }

    return Boolean(target.closest('input, textarea, select, [contenteditable="true"]'));
  }

  function isActivationKeyTarget(event) {
    if (event.type !== "keydown" || event.key !== " " || !(event.target instanceof Element)) {
      return false;
    }

    return Boolean(event.target.closest('button, summary, [role="button"], [role="menuitem"], [role="option"]'));
  }

  function getScrollDeltaY(event) {
    if (event.type === "wheel") {
      if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) {
        return event.deltaY * 16;
      }

      if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) {
        return event.deltaY * getViewportHeight(lockScroller || window);
      }

      return event.deltaY;
    }

    if (event.type === "touchmove") {
      const touch = event.touches[0];

      if (!touch || lastTouchY === null) {
        return 0;
      }

      return lastTouchY - touch.clientY;
    }

    if (event.type !== "keydown") {
      return 0;
    }

    const viewportHeight = getViewportHeight(lockScroller || window);
    const keyDeltas = {
      ArrowDown: 40,
      PageDown: viewportHeight * 0.85,
      End: Number.MAX_SAFE_INTEGER,
      " ": viewportHeight * 0.85,
    };

    return keyDeltas[event.key] || 0;
  }

  function findNestedScrollableTarget(target, deltaY) {
    if (!(target instanceof Element)) {
      return null;
    }

    let current = target;

    while (current && current !== document.body && current !== document.documentElement) {
      if (current === lockScroller) {
        return null;
      }

      const style = window.getComputedStyle(current);
      const overflowY = style.overflowY || style.overflow;

      if (/(auto|scroll|overlay)/.test(overflowY) && current.scrollHeight > current.clientHeight + 1) {
        const canScrollDown = current.scrollTop + current.clientHeight < current.scrollHeight - 1;
        const canScrollUp = current.scrollTop > 0;

        if ((deltaY > 0 && canScrollDown) || (deltaY < 0 && canScrollUp)) {
          return current;
        }
      }

      current = current.parentElement;
    }

    return null;
  }

  function eventCanAffectLockScroller(event, deltaY) {
    if (!lockScroller) {
      return false;
    }

    if (lockScroller !== window) {
      return event.target instanceof Node && lockScroller.contains(event.target);
    }

    return !findNestedScrollableTarget(event.target, deltaY);
  }

  function preventScrollPastBrake(event) {
    if (resetAfterNavigation()) {
      scheduleApplyBrake(ROUTE_SETTLE_DELAY_MS);
      return;
    }

    if (
      !isLocked ||
      maxScrollPosition === null ||
      isEditableTarget(event.target) ||
      isActivationKeyTarget(event) ||
      isBeforeActiveReelBoundary()
    ) {
      return;
    }

    const deltaY = getScrollDeltaY(event);

    if (
      deltaY <= 0 ||
      !eventCanAffectLockScroller(event, deltaY) ||
      getScrollPosition(lockScroller) + deltaY <= maxScrollPosition
    ) {
      return;
    }

    event.preventDefault();

    if (getScrollPosition(lockScroller) < maxScrollPosition) {
      setScrollPosition(lockScroller, maxScrollPosition);
    }
  }

  function rememberTouchPosition(event) {
    const touch = event.touches[0];
    lastTouchY = touch ? touch.clientY : null;
  }

  function forgetTouchPosition() {
    lastTouchY = null;
  }

  function isAtActiveReelBoundary() {
    const activeIndex = orderedKeys.indexOf(activeReelKey);
    return getSurface().kind === "reels" && activeIndex >= visibleItemLimit - 1;
  }

  function isBeforeActiveReelBoundary() {
    const activeIndex = orderedKeys.indexOf(activeReelKey);
    return getSurface().kind === "reels" && activeIndex >= 0 && activeIndex < visibleItemLimit - 1;
  }

  function preventReelAdvanceClick(event) {
    if (!isLocked || !isAtActiveReelBoundary() || !(event.target instanceof Element)) {
      return;
    }

    const control = event.target.closest('button, [role="button"]');

    if (!control || control.closest(`#${BRAKE_ID}`)) {
      return;
    }

    const labelledChild = control.querySelector("[aria-label]");
    const label = normalizeText(
      `${control.getAttribute("aria-label") || ""} ${control.getAttribute("title") || ""} ${labelledChild ? labelledChild.getAttribute("aria-label") : ""} ${control.textContent || ""}`
    );

    if (!/\b(next(?: reel)?|down)\b/i.test(label)) {
      return;
    }

    event.preventDefault();
    event.stopImmediatePropagation();
  }

  function shouldResetProgressForClick(target) {
    if (!(target instanceof Element) || target.closest(`#${BRAKE_ID}`)) {
      return false;
    }

    const control = target.closest('a[href], button, [role="button"]');

    if (!control) {
      return false;
    }

    if (control.matches("a[href]")) {
      const url = parseUrl(control.getAttribute("href"));

      if (url && getRouteKeyForUrl(url) === currentRouteKey) {
        return true;
      }
    }

    const label = normalizeText(
      `${control.getAttribute("aria-label") || ""} ${control.textContent || ""}`
    );
    return /\b(new posts?|refresh|scroll to top|back to top)\b/i.test(label);
  }

  function getRouteKeyForUrl(url) {
    const pathname = url.pathname === "/" ? "/" : url.pathname.replace(/\/$/, "");

    if (/^\/reels?(?:\/|$)/i.test(pathname)) {
      return "/reels/:continuous";
    }

    if (pathname === "/") {
      const variant = url.searchParams.get("variant");
      return variant ? `/?variant=${encodeURIComponent(variant)}` : "/";
    }

    return pathname;
  }

  function handleProgressResetClick(event) {
    if (!shouldResetProgressForClick(event.target)) {
      return;
    }

    resetCurrentProgress();
    scheduleApplyBrake(ROUTE_SETTLE_DELAY_MS);
  }

  function handleTopResetShortcut(event) {
    if (isEditableTarget(event.target)) {
      return;
    }

    if (event.key !== "Home" && !((event.metaKey || event.ctrlKey) && event.key === "ArrowUp")) {
      return;
    }

    resetCurrentProgress();
    scheduleApplyBrake(ROUTE_SETTLE_DELAY_MS);
  }

  function installNavigationHooks() {
    const notifyNavigation = () => {
      const hrefChanged = location.href !== lastObservedHref;
      lastObservedHref = location.href;

      if (resetAfterNavigation()) {
        scheduleApplyBrake(ROUTE_SETTLE_DELAY_MS);
      } else if (hrefChanged && isContinuousReelsRoute()) {
        scheduleApplyBrake(0);
      }
    };

    ["pushState", "replaceState"].forEach((methodName) => {
      const originalMethod = history[methodName];

      if (typeof originalMethod !== "function" || originalMethod.__igScrollBrakeWrapped) {
        return;
      }

      const wrappedMethod = function () {
        const result = originalMethod.apply(this, arguments);
        window.setTimeout(notifyNavigation, 0);
        return result;
      };
      Object.defineProperty(wrappedMethod, "__igScrollBrakeWrapped", { value: true });
      history[methodName] = wrappedMethod;
    });

    window.addEventListener("popstate", notifyNavigation);
    window.setInterval(notifyNavigation, 200);
  }

  function mutationsNeedScan(mutations) {
    return mutations.some((mutation) => {
      if (mutation.target instanceof Element && mutation.target.closest(`#${BRAKE_ID}`)) {
        return false;
      }

      const changedNodes = [...mutation.addedNodes, ...mutation.removedNodes];
      return !changedNodes.length || changedNodes.some((node) => {
        if (node instanceof Element && node.id === BRAKE_ID) {
          return !node.isConnected;
        }

        return !(node instanceof Element) || !node.closest(`#${BRAKE_ID}`);
      });
    });
  }

  function boot() {
    addStyles();
    ensureBrake();
    installNavigationHooks();
    applyBrake();

    const observer = new MutationObserver((mutations) => {
      if (mutationsNeedScan(mutations)) {
        scheduleApplyBrake();
      }
    });
    observer.observe(document.body, {
      attributes: true,
      attributeFilter: ["aria-hidden", "data-comment-id", "data-media-id", "hidden", "href", "poster", "src"],
      childList: true,
      subtree: true,
    });

    window.addEventListener("scroll", clampScrollToBrake, { passive: true });
    document.addEventListener("scroll", clampScrollToBrake, { capture: true, passive: true });
    window.addEventListener("click", preventReelAdvanceClick, { capture: true, passive: false });
    window.addEventListener("click", handleProgressResetClick, { capture: true, passive: true });
    window.addEventListener("wheel", preventScrollPastBrake, { capture: true, passive: false });
    window.addEventListener("keydown", handleTopResetShortcut, { capture: true });
    window.addEventListener("keydown", preventScrollPastBrake, { capture: true });
    window.addEventListener("touchstart", rememberTouchPosition, { capture: true, passive: true });
    window.addEventListener("touchmove", preventScrollPastBrake, { capture: true, passive: false });
    window.addEventListener("touchmove", rememberTouchPosition, { capture: true, passive: true });
    window.addEventListener("touchend", forgetTouchPosition, { capture: true, passive: true });
    window.addEventListener("touchcancel", forgetTouchPosition, { capture: true, passive: true });
  }

  if (document.readyState === "loading") {
    document.addEventListener("DOMContentLoaded", boot, { once: true });
  } else {
    boot();
  }
})();