PageSourceSearch

https://kyn-care.com/src/hooks/useScrollRestoration.ts

js kyn-care.com collected 2026-10-08 11:36:28 UTC 15,411 bytes, 122 lines download raw bytes

1import __vite__cjsImport0_react from "/@fs/home/runner/workspace/node_modules/.vite/deps/react.js?v=9ce4103e"; const useEffect = __vite__cjsImport0_react["useEffect"]; const useRef = __vite__cjsImport0_react["useRef"]; const useCallback = __vite__cjsImport0_react["useCallback"];
2import { useLocation } from "/@fs/home/runner/workspace/node_modules/.vite/deps/wouter.js?v=9ce4103e";
3const SCROLL_KEY_PREFIX = "kyn_scroll:";
4export function useScrollRestoration() {
5  const [location] = useLocation();
6  const prevLocation = useRef(null);
7  const navigationTypeRef = useRef("initial");
8  const saveScrollPosition = useCallback((path) => {
9    const scrollData = {
10      x: window.scrollX,
11      y: window.scrollY,
12      timestamp: Date.now()
13    };
14    sessionStorage.setItem(SCROLL_KEY_PREFIX + path, JSON.stringify(scrollData));
15  }, []);
16  const restoreScrollPosition = useCallback((path) => {
17    const saved = sessionStorage.getItem(SCROLL_KEY_PREFIX + path);
18    if (saved) {
19      try {
20        const { x, y } = JSON.parse(saved);
21        setTimeout(() => {
22          window.scrollTo(x, y);
23        }, 100);
24        return true;
25      } catch (e) {
26        return false;
27      }
28    }
29    return false;
30  }, []);
31  useEffect(() => {
32    if ("scrollRestoration" in window.history) {
33      window.history.scrollRestoration = "manual";
34    }
35    const handlePopState = () => {
36      navigationTypeRef.current = "pop";
37    };
38    window.addEventListener("popstate", handlePopState);
39    return () => {
40      window.removeEventListener("popstate", handlePopState);
41    };
42  }, []);
43  useEffect(() => {
44    const handleClick = (e) => {
45      const target = e.target;
46      const link = target.closest("a");
47      if (link) {
48        const href = link.getAttribute("href");
49        if (href && href.startsWith("/") && !href.startsWith("//")) {
50          const currentPath = window.location.pathname + window.location.hash;
51          saveScrollPosition(currentPath);
52          navigationTypeRef.current = "push";
53        }
54      }
55    };
56    document.addEventListener("click", handleClick, { capture: true });
57    return () => {
58      document.removeEventListener("click", handleClick, { capture: true });
59    };
60  }, [saveScrollPosition]);
61  useEffect(() => {
62    const currentPath = location + window.location.hash;
63    if (prevLocation.current === null) {
64      prevLocation.current = currentPath;
65      const saved = sessionStorage.getItem(SCROLL_KEY_PREFIX + currentPath);
66      if (saved) {
67        try {
68          const { x, y } = JSON.parse(saved);
69          setTimeout(() => {
70            window.scrollTo(x, y);
71          }, 150);
72        } catch (e) {
73        }
74      }
75      return;
76    }
77    if (prevLocation.current !== currentPath) {
78      saveScrollPosition(prevLocation.current);
79    }
80    if (navigationTypeRef.current === "pop") {
81      restoreScrollPosition(currentPath);
82    } else {
83      if (window.location.hash) {
84        setTimeout(() => {
85          const element = document.getElementById(window.location.hash.slice(1));
86          if (element) {
87            const navHeight = 118;
88            const elementPosition = element.getBoundingClientRect().top + window.scrollY;
89            window.scrollTo({ top: elementPosition - navHeight, behavior: "smooth" });
90          }
91        }, 100);
92      } else {
93        window.scrollTo(0, 0);
94      }
95    }
96    navigationTypeRef.current = "push";
97    prevLocation.current = currentPath;
98  }, [location, saveScrollPosition, restoreScrollPosition]);
99  useEffect(() => {
100    let scrollTimeout;
101    const handleScroll = () => {
102      clearTimeout(scrollTimeout);
103      scrollTimeout = setTimeout(() => {
104        const currentPath = window.location.pathname + window.location.hash;
105        saveScrollPosition(currentPath);
106      }, 150);
107    };
108    window.addEventListener("scroll", handleScroll, { passive: true });
109    const handleBeforeUnload = () => {
110      const currentPath = window.location.pathname + window.location.hash;
111      saveScrollPosition(currentPath);
112    };
113    window.addEventListener("beforeunload", handleBeforeUnload);
114    return () => {
115      window.removeEventListener("scroll", handleScroll);
116      window.removeEventListener("beforeunload", handleBeforeUnload);
117      clearTimeout(scrollTimeout);
118    };
119  }, [saveScrollPosition]);
120}
121
122//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInVzZVNjcm9sbFJlc3RvcmF0aW9uLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7
122IHVzZUVmZmVjdCwgdXNlUmVmLCB1c2VDYWxsYmFjayB9IGZyb20gJ3JlYWN0JztcbmltcG9ydCB7IHVzZUxvY2F0aW9uIH0gZnJvbSAnd291dGVyJztcblxuY29uc3QgU0NST0xMX0tFWV9QUkVGSVggPSAna3luX3Njcm9sbDonO1xuXG5leHBvcnQgZnVuY3Rpb24gdXNlU2Nyb2xsUmVzdG9yYXRpb24oKSB7XG4gIGNvbnN0IFtsb2NhdGlvbl0gPSB1c2VMb2NhdGlvbigpO1xuICBjb25zdCBwcmV2TG9jYXRpb24gPSB1c2VSZWY8c3RyaW5nIHwgbnVsbD4obnVsbCk7XG4gIGNvbnN0IG5hdmlnYXRpb25UeXBlUmVmID0gdXNlUmVmPCdwdXNoJyB8ICdwb3AnIHwgJ2luaXRpYWwnPignaW5pdGlhbCcpO1xuXG4gIC8vIFNhdmUgc2Nyb2xsIHBvc2l0aW9uIGZvciBjdXJyZW50IHBhZ2VcbiAgY29uc3Qgc2F2ZVNjcm9sbFBvc2l0aW9uID0gdXNlQ2FsbGJhY2soKHBhdGg6IHN0cmluZykgPT4ge1xuICAgIGNvbnN0IHNjcm9sbERhdGEgPSB7XG4gICAgICB4OiB3aW5kb3cuc2Nyb2xsWCxcbiAgICAgIHk6IHdpbmRvdy5zY3JvbGxZLFxuICAgICAgdGltZXN0YW1wOiBEYXRlLm5vdygpXG4gICAgfTtcbiAgICBzZXNzaW9uU3RvcmFnZS5zZXRJdGVtKFNDUk9MTF9LRVlfUFJFRklYICsgcGF0aCwgSlNPTi5zdHJpbmdpZnkoc2Nyb2xsRGF0YSkpO1xuICB9LCBbXSk7XG5cbiAgLy8gUmVzdG9yZSBzY3JvbGwgcG9zaXRpb24gZm9yIGEgcGFnZVxuICBjb25zdCByZXN0b3JlU2Nyb2xsUG9zaXRpb24gPSB1c2VDYWxsYmFjaygocGF0aDogc3RyaW5nKSA9PiB7XG4gICAgY29uc3Qgc2F2ZWQgPSBzZXNzaW9uU3RvcmFnZS5nZXRJdGVtKFNDUk9MTF9LRVlfUFJFRklYICsgcGF0aCk7XG4gICAgaWYgKHNhdmVkKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCB7IHgsIHkgfSA9IEpTT04ucGFyc2Uoc2F2ZWQpO1xuICAgICAgICAvLyBVc2UgbG9uZ2VyIGRlbGF5IHRvIGVuc3VyZSBjb250ZW50IGlzIGZ1bGx5IHJlbmRlcmVkXG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIHdpbmRvdy5zY3JvbGxUbyh4LCB5KTtcbiAgICAgICAgfSwgMTAwKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9LCBbXSk7XG5cbiAgLy8gRGV0ZWN0IG5hdmlnYXRpb24gdHlwZSAoYmFjay9mb3J3YXJkIHZzIGZyZXNoIG5hdmlnYXRpb24pXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgLy8gRGlzYWJsZSBicm93c2VyJ3MgYXV0b21hdGljIHNjcm9sbCByZXN0b3JhdGlvblxuICAgIGlmICgnc2Nyb2xsUmVzdG9yYXRpb24nIGluIHdpbmRvdy5oaXN0b3J5KSB7XG4gICAgICB3aW5kb3cuaGlzdG9yeS5zY3JvbGxSZXN0b3JhdGlvbiA9ICdtYW51YWwnO1xuICAgIH1cblxuICAgIGNvbnN0IGhhbmRsZVBvcFN0YXRlID0gKCkgPT4ge1xuICAgICAgbmF2aWdhdGlvblR5cGVSZWYuY3VycmVudCA9ICdwb3AnO1xuICAgIH07XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcigncG9wc3RhdGUnLCBoYW5kbGVQb3BTdGF0ZSk7XG5cbiAgICByZXR1cm4gKCkgPT4ge1xuICAgICAgd2luZG93LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvcHN0YXRlJywgaGFuZGxlUG9wU3RhdGUpO1xuICAgIH07XG4gIH0sIFtdKTtcblxuICAvLyBTYXZlIHNjcm9sbCBwb3NpdGlvbiB3aGVuIGNsaWNraW5nIGFueSBpbnRlcm5hbCBsaW5rXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgaGFuZGxlQ2xpY2sgPSAoZTogTW91c2VFdmVudCkgPT4ge1xuICAgICAgY29uc3QgdGFyZ2V0ID0gZS50YXJnZXQgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICBjb25zdCBsaW5rID0gdGFyZ2V0LmNsb3Nlc3QoJ2EnKTtcbiAgICAgIFxuICAgICAgaWYgKGxpbmspIHtcbiAgICAgICAgY29uc3QgaHJlZiA9IGxpbmsuZ2V0QXR0cmlidXRlKCdocmVmJyk7XG4gICAgICAgIC8vIENoZWNrIGlmIGl0J3MgYW4gaW50ZXJuYWwgbmF2aWdhdGlvbiBsaW5rIChub3QgZXh0ZXJuYWwsIG5vdCBhbmNob3Itb25seSlcbiAgICAgICAgaWYgKGhyZWYgJiYgaHJlZi5zdGFydHNXaXRoKCcvJykgJiYgIWhyZWYuc3RhcnRzV2l0aCgnLy8nKSkge1xuICAgICAgICAgIC8vIFNhdmUgY3VycmVudCBzY3JvbGwgcG9zaXRpb24gYmVmb3JlIG5hdmlnYXRpbmdcbiAgICAgICAgICBjb25zdCBjdXJyZW50UGF0aCA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSArIHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuICAgICAgICAgIHNhdmVTY3JvbGxQb3NpdGlvbihjdXJyZW50UGF0aCk7XG4gICAgICAgICAgbmF2aWdhdGlvblR5cGVSZWYuY3VycmVudCA9ICdwdXNoJztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH07XG5cbiAgICAvLyBDYXB0dXJlIHBoYXNlIHRvIHJ1biBiZWZvcmUgbmF2aWdhdGlvblxuICAgIGRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgaGFuZGxlQ2xpY2ssIHsgY2FwdHVyZTogdHJ1ZSB9KTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICBkb2
122N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIGhhbmRsZUNsaWNrLCB7IGNhcHR1cmU6IHRydWUgfSk7XG4gICAgfTtcbiAgfSwgW3NhdmVTY3JvbGxQb3NpdGlvbl0pO1xuXG4gIC8vIEhhbmRsZSBzY3JvbGwgYmVoYXZpb3Igb24gbG9jYXRpb24gY2hhbmdlXG4gIHVzZUVmZmVjdCgoKSA9PiB7XG4gICAgY29uc3QgY3VycmVudFBhdGggPSBsb2NhdGlvbiArIHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuICAgIFxuICAgIC8vIE9uIGluaXRpYWwgcGFnZSBsb2FkLCB0cnkgdG8gcmVzdG9yZSBzY3JvbGwgcG9zaXRpb24gKGZvciBwYWdlIHJlZnJlc2gpXG4gICAgaWYgKHByZXZMb2NhdGlvbi5jdXJyZW50ID09PSBudWxsKSB7XG4gICAgICBwcmV2TG9jYXRpb24uY3VycmVudCA9IGN1cnJlbnRQYXRoO1xuICAgICAgLy8gQ2hlY2sgaWYgdGhlcmUncyBhIHNhdmVkIHBvc2l0aW9uIGZvciB0aGlzIHJvdXRlIChwYWdlIHdhcyByZWZyZXNoZWQpXG4gICAgICBjb25zdCBzYXZlZCA9IHNlc3Npb25TdG9yYWdlLmdldEl0ZW0oU0NST0xMX0tFWV9QUkVGSVggKyBjdXJyZW50UGF0aCk7XG4gICAgICBpZiAoc2F2ZWQpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCB7IHgsIHkgfSA9IEpTT04ucGFyc2Uoc2F2ZWQpO1xuICAgICAgICAgIC8vIERlbGF5IHRvIGVuc3VyZSBjb250ZW50IGlzIHJlbmRlcmVkXG4gICAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oeCwgeSk7XG4gICAgICAgICAgfSwgMTUwKTtcbiAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgIC8vIElnbm9yZSBwYXJzZSBlcnJvcnNcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFNhdmUgc2Nyb2xsIHBvc2l0aW9uIGZvciB0aGUgcGFnZSB3ZSdyZSBsZWF2aW5nXG4gICAgaWYgKHByZXZMb2NhdGlvbi5jdXJyZW50ICE9PSBjdXJyZW50UGF0aCkge1xuICAgICAgc2F2ZVNjcm9sbFBvc2l0aW9uKHByZXZMb2NhdGlvbi5jdXJyZW50KTtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgbmF2aWdhdGlvblxuICAgIGlmIChuYXZpZ2F0aW9uVHlwZVJlZi5jdXJyZW50ID09PSAncG9wJykge1xuICAgICAgLy8gQmFjay9mb3J3YXJkIGJ1dHRvbiAtIHJlc3RvcmUgc2Nyb2xsIHBvc2l0aW9uXG4gICAgICByZXN0b3JlU2Nyb2xsUG9zaXRpb24oY3VycmVudFBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBGcmVzaCBuYXZpZ2F0aW9uIC0gc2Nyb2xsIHRvIHRvcCBvciBoYXNoIHRhcmdldFxuICAgICAgaWYgKHdpbmRvdy5sb2NhdGlvbi5oYXNoKSB7XG4gICAgICAgIHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGVsZW1lbnQgPSBkb2N1bWVudC5nZXRFbGVtZW50QnlJZCh3aW5kb3cubG9jYXRpb24uaGFzaC5zbGljZSgxKSk7XG4gICAgICAgICAgaWYgKGVsZW1lbnQpIHtcbiAgICAgICAgICAgIGNvbnN0IG5hdkhlaWdodCA9IDExODtcbiAgICAgICAgICAgIGNvbnN0IGVsZW1lbnRQb3NpdGlvbiA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkudG9wICsgd2luZG93LnNjcm9sbFk7XG4gICAgICAgICAgICB3aW5kb3cuc2Nyb2xsVG8oeyB0b3A6IGVsZW1lbnRQb3NpdGlvbiAtIG5hdkhlaWdodCwgYmVoYXZpb3I6ICdzbW9vdGgnIH0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfSwgMTAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHdpbmRvdy5zY3JvbGxUbygwLCAwKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBSZXNldCBuYXZpZ2F0aW9uIHR5cGUgZm9yIG5leHQgbmF2aWdhdGlvblxuICAgIG5hdmlnYXRpb25UeXBlUmVmLmN1cnJlbnQgPSAncHVzaCc7XG4gICAgcHJldkxvY2F0aW9uLmN1cnJlbnQgPSBjdXJyZW50UGF0aDtcbiAgfSwgW2xvY2F0aW9uLCBzYXZlU2Nyb2xsUG9zaXRpb24sIHJlc3RvcmVTY3JvbGxQb3NpdGlvbl0pO1xuXG4gIC8vIFNhdmUgc2Nyb2xsIHBvc2l0aW9uIHBlcmlvZGljYWxseSB3aGlsZSB1c2VyIHNjcm9sbHNcbiAgdXNlRWZmZWN0KCgpID0+IHtcbiAgICBsZXQgc2Nyb2xsVGltZW91dDogTm9kZUpTLlRpbWVvdXQ7XG4gICAgXG4gICAgY29uc3QgaGFuZGxlU2Nyb2xsID0gKCkgPT4ge1xuICAgICAgY2xlYXJUaW1lb3V0KHNjcm9sbFRpbWVvdXQpO1xuICAgICAgc2Nyb2xsVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4ge1xuICAgICAgICBjb25zdCBjdXJyZW50UGF0aCA9IHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSArIHdpbmRvdy5sb2NhdGlvbi5oYXNoO1xuICAgICAgICBzYXZlU2Nyb2xsUG9zaXRpb24oY3VycmVudFBhdGgpO1xuICAgICAgfSwgMTUwKTtcbiAgICB9O1xuXG4gICAgd2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Njcm9sbCcsIGhhbmRsZVNjcm9sbCwgeyBwYXNzaXZlOiB0cnVlIH0pO1xuXG4gICAgLy8gQWxzbyBzYXZlIHdoZW4gdXNlciBpcyBhYm91dCB0byBsZWF2ZSB0aGUgcGFnZVxuICAgIGNvbnN0IGhhbmRsZUJlZm9yZVVubG9hZCA9ICgpID0+IHtcbiAgICAgIGNvbnN0IGN1cnJlbnRQYXRoID0gd2luZG93LmxvY2F0aW9uLnBhdGhuYW1lICsgd2luZG93LmxvY2F0aW9uLmhhc2g7XG4gICAgICBzYXZlU2Nyb2xsUG9zaXRpb24oY3VycmVudFBhdGgpO1xuICAgIH07XG5cbiAgICB3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignYmVmb3JldW5sb2FkJywgaGFuZGxlQmVmb3JlVW5sb2FkKTtcblxuICAgIHJldHVybiAoKSA9PiB7XG4gICAgICB3aW5kb3cucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgaGFuZGxlU2Nyb2xsKTtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdiZWZvcmV1bmxvYWQnLCBoYW5kbGVCZWZvcmVVbmxvYWQpO1xuICAgICAgY2xlYXJUaW1lb3V0KHNjcm9sbFRpbWVvdXQpO1xuICAgIH07XG4gIH0sIFtzYXZlU2Nyb2xsUG9zaXRpb25dKTtcbn1cbiJdLCJtYXBwaW5ncyI6IkFBQUEsU0FBUyxXQUFXLFFBQVEsbUJBQW1CO0FBQy9DLFNBQVMsbUJBQW1CO0FBRTVCLE1BQU0sb0JBQW9CO0FBRW5CLGdCQUFTLHVCQUF1QjtBQUNyQyxRQUFNLENBQUMsUUFBUSxJQUFJLFlBQVk7QUFDL0IsUUFBTSxlQUFlLE9BQXNCLElBQUk7QUFDL0MsUUFBTSxvQkFBb0IsT0FBbUMsU0FBUztBQUd0RSxRQUFNLHFCQUFxQixZQUFZLENBQUMsU0FBaUI7QUFDdkQsVUFBT
122SxhQUFhO0FBQUEsTUFDakIsR0FBRyxPQUFPO0FBQUEsTUFDVixHQUFHLE9BQU87QUFBQSxNQUNWLFdBQVcsS0FBSyxJQUFJO0FBQUEsSUFDdEI7QUFDQSxtQkFBZSxRQUFRLG9CQUFvQixNQUFNLEtBQUssVUFBVSxVQUFVLENBQUM7QUFBQSxFQUM3RSxHQUFHLENBQUMsQ0FBQztBQUdMLFFBQU0sd0JBQXdCLFlBQVksQ0FBQyxTQUFpQjtBQUMxRCxVQUFNLFFBQVEsZUFBZSxRQUFRLG9CQUFvQixJQUFJO0FBQzdELFFBQUksT0FBTztBQUNULFVBQUk7QUFDRixjQUFNLEVBQUUsR0FBRyxFQUFFLElBQUksS0FBSyxNQUFNLEtBQUs7QUFFakMsbUJBQVcsTUFBTTtBQUNmLGlCQUFPLFNBQVMsR0FBRyxDQUFDO0FBQUEsUUFDdEIsR0FBRyxHQUFHO0FBQ04sZUFBTztBQUFBLE1BQ1QsU0FBUyxHQUFHO0FBQ1YsZUFBTztBQUFBLE1BQ1Q7QUFBQSxJQUNGO0FBQ0EsV0FBTztBQUFBLEVBQ1QsR0FBRyxDQUFDLENBQUM7QUFHTCxZQUFVLE1BQU07QUFFZCxRQUFJLHVCQUF1QixPQUFPLFNBQVM7QUFDekMsYUFBTyxRQUFRLG9CQUFvQjtBQUFBLElBQ3JDO0FBRUEsVUFBTSxpQkFBaUIsTUFBTTtBQUMzQix3QkFBa0IsVUFBVTtBQUFBLElBQzlCO0FBRUEsV0FBTyxpQkFBaUIsWUFBWSxjQUFjO0FBRWxELFdBQU8sTUFBTTtBQUNYLGFBQU8sb0JBQW9CLFlBQVksY0FBYztBQUFBLElBQ3ZEO0FBQUEsRUFDRixHQUFHLENBQUMsQ0FBQztBQUdMLFlBQVUsTUFBTTtBQUNkLFVBQU0sY0FBYyxDQUFDLE1BQWtCO0FBQ3JDLFlBQU0sU0FBUyxFQUFFO0FBQ2pCLFlBQU0sT0FBTyxPQUFPLFFBQVEsR0FBRztBQUUvQixVQUFJLE1BQU07QUFDUixjQUFNLE9BQU8sS0FBSyxhQUFhLE1BQU07QUFFckMsWUFBSSxRQUFRLEtBQUssV0FBVyxHQUFHLEtBQUssQ0FBQyxLQUFLLFdBQVcsSUFBSSxHQUFHO0FBRTFELGdCQUFNLGNBQWMsT0FBTyxTQUFTLFdBQVcsT0FBTyxTQUFTO0FBQy9ELDZCQUFtQixXQUFXO0FBQzlCLDRCQUFrQixVQUFVO0FBQUEsUUFDOUI7QUFBQSxNQUNGO0FBQUEsSUFDRjtBQUdBLGFBQVMsaUJBQWlCLFNBQVMsYUFBYSxFQUFFLFNBQVMsS0FBSyxDQUFDO0FBRWpFLFdBQU8sTUFBTTtBQUNYLGVBQVMsb0JBQW9CLFNBQVMsYUFBYSxFQUFFLFNBQVMsS0FBSyxDQUFDO0FBQUEsSUFDdEU7QUFBQSxFQUNGLEdBQUcsQ0FBQyxrQkFBa0IsQ0FBQztBQUd2QixZQUFVLE1BQU07QUFDZCxVQUFNLGNBQWMsV0FBVyxPQUFPLFNBQVM7QUFHL0MsUUFBSSxhQUFhLFlBQVksTUFBTTtBQUNqQyxtQkFBYSxVQUFVO0FBRXZCLFlBQU0sUUFBUSxlQUFlLFFBQVEsb0JBQW9CLFdBQVc7QUFDcEUsVUFBSSxPQUFPO0FBQ1QsWUFBSTtBQUNGLGdCQUFNLEVBQUUsR0FBRyxFQUFFLElBQUksS0FBSyxNQUFNLEtBQUs7QUFFakMscUJBQVcsTUFBTTtBQUNmLG1CQUFPLFNBQVMsR0FBRyxDQUFDO0FBQUEsVUFDdEIsR0FBRyxHQUFHO0FBQUEsUUFDUixTQUFTLEdBQUc7QUFBQSxRQUVaO0FBQUEsTUFDRjtBQUNBO0FBQUEsSUFDRjtBQUdBLFFBQUksYUFBYSxZQUFZLGFBQWE7QUFDeEMseUJBQW1CLGFBQWEsT0FBTztBQUFBLElBQ3pDO0FBR0EsUUFBSSxrQkFBa0IsWUFBWSxPQUFPO0FBRXZDLDRCQUFzQixXQUFXO0FBQUEsSUFDbkMsT0FBTztBQUVMLFVBQUksT0FBTyxTQUFTLE1BQU07QUFDeEIsbUJBQVcsTUFBTTtBQUNmLGdCQUFNLFVBQVUsU0FBUyxlQUFlLE9BQU8sU0FBUyxLQUFLLE1BQU0sQ0FBQyxDQUFDO0FBQ3JFLGNBQUksU0FBUztBQUNYLGtCQUFNLFlBQVk7QUFDbEIsa0JBQU0sa0JBQWtCLFFBQVEsc0JBQXNCLEVBQUUsTUFBTSxPQUFPO0FBQ3JFLG1CQUFPLFNBQVMsRUFBRSxLQUFLLGtCQUFrQixXQUFXLFVBQVUsU0FBUyxDQUFDO0FBQUEsVUFDMUU7QUFBQSxRQUNGLEdBQUcsR0FBRztBQUFBLE1BQ1IsT0FBTztBQUNMLGVBQU8sU0FBUyxHQUFHLENBQUM7QUFBQSxNQUN0QjtBQUFBLElBQ0Y7QUFHQSxzQkFBa0IsVUFBVTtBQUM1QixpQkFBYSxVQUFVO0FBQUEsRUFDekIsR0FBRyxDQUFDLFVBQVUsb0JBQW9CLHFCQUFxQixDQUFDO0FBR3hELFlBQVUsTUFBTTtBQUNkLFFBQUk7QUFFSixVQUFNLGVBQWUsTUFBTTtBQUN6QixtQkFBYSxhQUFhO0FBQzFCLHNCQUFnQixXQUFXLE1BQU07QUFDL0IsY0FBTSxjQUFjLE9BQU8sU0FBUyxXQUFXLE9BQU8sU0FBUztBQUMvRCwyQkFBbUIsV0FBVztBQUFBLE1BQ2hDLEdBQUcsR0FBRztBQUFBLElBQ1I7QUFFQSxXQUFPLGlCQUFpQixVQUFVLGNBQWMsRUFBRSxTQUFTLEtBQUssQ0FBQztBQUdqRSxVQUFNLHFCQUFxQixNQUFNO0FBQy9CLFlBQU0sY0FBYyxPQUFPLFNBQVMsV0FBVyxPQUFPLFNBQVM7QUFDL0QseUJBQW1CLFdBQVc7QUFBQSxJQUNoQztBQUVBLFdBQU8saUJBQWlCLGdCQUFnQixrQkFBa0I7QUFFMUQsV0FBTyxNQUFNO0FBQ1gsYUFBTyxvQkFBb0IsVUFBVSxZQU
122FZO0FBQ2pELGFBQU8sb0JBQW9CLGdCQUFnQixrQkFBa0I7QUFDN0QsbUJBQWEsYUFBYTtBQUFBLElBQzVCO0FBQUEsRUFDRixHQUFHLENBQUMsa0JBQWtCLENBQUM7QUFDekI7IiwibmFtZXMiOltdfQ==

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.