PageSourceSearch

https://traderzen.app/assets/store-breakout.js

js traderzen.app collected 2026-10-02 01:15:15 UTC 7,640 bytes, 192 lines download raw bytes

1/**
2 * Instagram in-app browser: App Store links are blocked on iOS.
3 * Show a tap-to-copy modal when IG users tap iOS store CTAs only.
4 */
5(function () {
6  var GET_URL = "https://traderzen.app/get";
7
8  var IG_ICON =
9    '<svg class="tz-ig-icon" viewBox="0 0 24 24" width="44" height="44" aria-hidden="true">' +
10    '<defs><linearGradient id="tz-ig-grad" x1="0%" y1="100%" x2="100%" y2="0%">' +
11    '<stop offset="0%" stop-color="#feda75"/><stop offset="25%" stop-color="#fa7e1e"/>' +
12    '<stop offset="50%" stop-color="#d62976"/><stop offset="75%" stop-color="#962fbf"/>' +
13    '<stop offset="100%" stop-color="#4f5bd5"/></linearGradient></defs>' +
14    '<rect x="2" y="2" width="20" height="20" rx="6" fill="url(#tz-ig-grad)"/>' +
15    '<rect x="5.5" y="5.5" width="13" height="13" rx="3.5" fill="none" stroke="#fff" stroke-width="1.6"/>' +
16    '<circle cx="12" cy="12" r="3.2" fill="none" stroke="#fff" stroke-width="1.6"/>' +
17    '<circle cx="17.2" cy="6.8" r="1.1" fill="#fff"/></svg>';
18
19  function ua() {
20    return navigator.userAgent || "";
21  }
22
23  function isInstagram() {
24    return /Instagram/i.test(ua());
25  }
26
27  function isInAppBrowser() {
28    var u = ua();
29    return /Instagram|FBAN|FBAV|FB_IAB|FBIOS|TikTok|BytedanceWebview|musical_ly/i.test(u);
30  }
31
32  function copyText(text) {
33    if (navigator.clipboard && navigator.clipboard.writeText) {
34      return navigator.clipboard.writeText(text).catch(function () {
35        return Promise.resolve(fallbackCopy(text));
36      });
37    }
38    return Promise.resolve(fallbackCopy(text));
39  }
40
41  function fallbackCopy(text) {
42    try {
43      var ta = document.createElement("textarea");
44      ta.value = text;
45      ta.setAttribute("readonly", "");
46      ta.style.cssText = "position:fixed;left:-9999px;top:0";
47      document.body.appendChild(ta);
48      ta.select();
49      document.execCommand("copy");
50      document.body.removeChild(ta);
51      return true;
52    } catch (e) {
53      return false;
54    }
55  }
56
57  function ensureStyles() {
58    if (document.getElementById("tz-ig-css")) return;
59    var s = document.createElement("style");
60    s.id = "tz-ig-css";
61    s.textContent = [
62      "#tz-ig-modal{position:fixed;inset:0;z-index:2147483000;background:rgba(2,4,8,.88);",
63      "display:flex;align-items:center;justify-content:center;padding:20px;",
64      "font-family:system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}",
65      "#tz-ig-modal *{box-sizing:border-box}",
66      "#tz-ig-modal .card{width:100%;max-width:380px;background:#0a101f;border:1px solid rgba(0,242,255,.25);",
67      "padding:24px 20px 20px;text-align:center;color:#e0fbfc;position:relative;",
68      "box-shadow:0 24px 60px rgba(0,0,0,.55)}",
69      "#tz-ig-modal .tz-ig-icon{display:block;margin:0 auto 14px}",
70      "#tz-ig-modal h2{margin:0 0 8px;font-size:1.25rem;line-height:1.25;font-weight:800}",
71      "#tz-ig-modal .sub{margin:0 0 16px;color:#8a9bb0;font-size:15px;line-height:1.45}",
72      "#tz-ig-modal .url-tap{width:100%;margin:0 0 10px;padding:14px 12px;",
73      "border:1px dashed rgba(0,242,255,.5);background:#05070c;color:#00f2ff;",
74      "font-size:14px;font-weight:700;line-height:1.35;word-break:break-all;",
75      "cursor:pointer;text-align:left;border-radius:0}",
76      "#tz-ig-modal .url-tap:active{background:#0d1525}",
77      "#tz-ig-modal .hint{font-size:12px;color:#6b7c8f;margin:0 0 14px}",
78      "#tz-ig-modal .ok{min-height:20px;font-size:14px;font-weight:700;color:#28c840;margin:0 0 12px}",
79      "#tz-ig-modal .btn{width:100%;appearance:none;border:0;padding:14px;font-size:15px;",
80      "font-weight:800;cursor:pointer;margin-bottom:8px}",
81      "#tz-ig-modal .btn-copy{background:#00f2ff;color:#020408}",
82      "#tz-ig-modal .btn-close{background:transparent;color:#8a9bb0;border:1px solid rgba(255,255,255,.12)}",
83      "#tz-ig-modal .close-x{position:absolute;top:8px;right:10px;width:36px;height:36px;",
84      "border:0;background:transparent;color:#8a9bb0;font-size:22px;line-height:1;cursor:pointer}",
85    ].join("");
86    document.head.appendChild(s);
87  }
88
89  function showInstructions(opts) {
90    opts = opts || {};
91    ensureStyles();
92
93    var existing = document.getElementById("tz-ig-modal");
94    if (existing) existing.remove();
95
96    var link = opts.copyUrl || GET_URL;
97    var fromIg = isInstagram();
98
99    var modal = document.createElement("div");
100    modal.id = "tz-ig-modal";
101    modal.setAttribute("role", "dialog");
102    modal.setAttribute("aria-modal", "true");
103    modal.setAttribute("aria-labelledby", "tz-ig-title");
104    modal.innerHTML =
105      '<div class="card">' +
106      '<button type="button" class="close-x" aria-label="Close">&times;</button>' +
107      (fromIg ? IG_ICON : "") +
108      '<h2 id="tz-ig-title">' +
109      (fromIg ? "Instagram blocks App Store links" : "Open in your mobile browser") +
110      "</h2>" +
111      '<p class="sub">' +
112      (fromIg
113        ? "Links from Instagram can’t open the App Store. Copy this URL, paste it in <strong>Safari</strong>, then tap download."
114        : "This in-app browser blocks App Store links. Copy the URL below and paste it in Safari.") +
115      "</p>" +
116      '<button type="button" class="url-tap" id="tz-ig-url">' + link + "</button>" +
117      '<p class="hint">Tap the link above to copy</p>' +
118      '<div class="ok" id="tz-ig-ok"></div>' +
119      '<button type="button" class="btn btn-copy" data-act="copy">Tap to copy URL</button>' +
120      '<button type="button" class="btn btn-close" data-act="close">Close</button>' +
121      "</div>";
122
123    document.body.appendChild(modal);
124    document.documentElement.style.overflow = "hidden";
125
126    function closeModal() {
127      modal.remove();
128      document.documentElement.style.overflow = "";
129    }
130
131    function doCopy() {
132      copyText(link).then(function () {
133        var el = modal.querySelector("#tz-ig-ok");
134        if (el) {
135          el.textContent = "Now open Safari and paste the URL.";
136        }
137      });
138    }
139
140    modal.querySelector(".close-x").onclick = closeModal;
141    modal.querySelector('[data-act="close"]').onclick = closeModal;
142    modal.querySelector('[data-act="copy"]').onclick = doCopy;
143    modal.querySelector("#tz-ig-url").onclick = doCopy;
144    modal.addEventListener("click", function (e) {
145      if (e.target === modal) closeModal();
146    });
147  }
148
149  function isIosStoreCta(el) {
150    if (!el || el.tagName !== "A") return false;
151    var href = el.getAttribute("href") || "";
152    var text = (el.textContent || "").toLowerCase();
153    if (/play\.google|platform=android|platform=play|platform=google/i.test(href)) return false;
154    if (/google play|\bandroid\b/i.test(text)) return false;
155    if (/apps\.apple|itunes\.apple/i.test(href)) return true;
156    if (/platform=ios|platform=iphone|platform=apple/i.test(href)) return true;
157    if (/app store|\bios\b/i.test(text)) return true;
158    return false;
159  }
160
161  function bindStoreClicks() {
162    document.querySelectorAll("a").forEach(function (a) {
163      if (a.dataset.tzIgBound || !isIosStoreCta(a)) return;
164      a.dataset.tzIgBound = "1";
165      a.addEventListener("click", function (e) {
166        if (!isInAppBrowser()) return;
167        e.preventDefault();
168        showInstructions({ copyUrl: GET_URL });
169      });
170    });
171  }
172
173  function init() {
174    if (!isInAppBrowser()) return;
175    bindStoreClicks();
176    setTimeout(bindStoreClicks, 600);
177  }
178
179  window.TZStoreBreakout = {
180    isInstagram: isInstagram,
181    isInAppBrowser: isInAppBrowser,
182    isIosStoreCta: isIosStoreCta,
183    showInstructions: showInstructions,
184    GET_URL: GET_URL,
185  };
186
187  if (document.readyState === "loading") {
188    document.addEventListener("DOMContentLoaded", init);
189  } else {
190    init();
191  }
192})();

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.