{
  "version": 3,
  "sources": ["/cdn/shop/t/1064/assets/blanks-dtf-handoff.js?auto=format%2Ccompress"],
  "sourcesContent": ["/* Blanks \u2192 DTF upload handoff (Owen 2026-07-02)\n   ---------------------------------------------------------------------------\n   Any file upload on a blanks PDP no longer opens the blanks multiupload\n   modal \u2014 the files are uploaded to S3 and the shopper is sent to\n   /products/dtf-transfers, where the existing handoff consumers boot the\n   canonical DTF flow with them.\n\n   HOW: capture-phase document listeners intercept the upload-box `change` +\n   `drop` BEFORE __blanksUploadHelper.js's bubble-phase delegated handlers\n   (capture always precedes bubble, so load order doesn't matter), upload via\n   the site's presign endpoint (same one bysize-popup.liquid uses), write the\n   SAME sessionStorage stash the AI-image-creator handoff uses\n   (`dtf:pending-ai-uploads:v1`, ai-chat-sandbox.js stashAndHandoff), and\n   navigate. bySize_popular.js's rehydrateAiHandoffStash() converts the stash\n   into `?file=` (single) / `?my_designs_selection=` (multi) on arrival \u2014\n   ZERO dtf-side changes needed.\n\n   The blanks engine stays loaded (it still drives the Free-Transfers view and\n   previous-designs paths); only the file-upload entry is intercepted.\n   ROLLBACK: remove this script tag from __uploadBoxBlock.liquid. */\n(function () {\n  if (window.__ntBlanksDtfHandoff) return;\n  window.__ntBlanksDtfHandoff = true;\n\n  /* Same endpoint + bucket as bysize-popup.liquid's popup_uploadFile. */\n  var PRESIGN_URL = 'https://hpz51rjda5.execute-api.us-east-1.amazonaws.com/production/uploads/getPresignedUploadUrl';\n  var S3_HOST = 'https://ninja-services-production-ninjauploadss3bucket-zks2mguobhe4.s3.amazonaws.com/';\n  var STASH_KEY = 'dtf:pending-ai-uploads:v1';\n  var DTF_URL = '/products/dtf-transfers';\n  /* Mirrors the #fileInput accept list (drop bypasses the input's filter). This\n     is the REAL type gate on the blanks pass-through: files failing it are\n     silently dropped before handoff. Kept in sync with the by-size-v4 accepted\n     set \u2014 v4 (the target page) renders/sizes/quotes, so we only gate here to\n     avoid handing off a type v4 can't take. Owen 2026-09-28: +webp/heic/heif/\n     avif/gif/bmp/psd/jfif. (.heic/.heif carry an empty MIME in Chrome, so the\n     extension test \u2014 not MIME \u2014 is what lets them through.) */\n  var OK_EXT = /\\.(png|jpe?g|jfif|eps|ai|pdf|tiff?|svg|webp|heic|heif|avif|gif|bmp|psd)$/i;\n\n  /* Keep the sandbox/staging preview session across the handoff navigation\n     (same helper dash-prev-design-modal.liquid uses). */\n  function withPreview(url) {\n    try {\n      var cur = new URLSearchParams(window.location.search);\n      if (cur.has('preview_theme_id')) url += (url.indexOf('?') >= 0 ? '&' : '?') + 'preview_theme_id=' + encodeURIComponent(cur.get('preview_theme_id'));\n    } catch (_) {}\n    return url;\n  }\n\n  function randomName(file) {\n    /* Same shape bysize-popup generates so downstream tooling sees familiar names. */\n    var base = (file.name.split('.')[0] || 'design')\n      .replace(/[^a-z0-9\\s]/gi, '')\n      .replace(/[_\\s]/g, '-');\n    // Dotless/garbage filenames: a bare split(\".\").pop() returns the WHOLE name as\n    // the \"extension\" (spaces included) \u2014 imgix still serves it (MIME-based), but\n    // the production API rejects extensions >10 chars. Keep a valid dotted ext;\n    // else derive from the MIME type; else png. (2026-08-18)\n    var ext = /\\.[a-z0-9]{1,5}$/i.test(file.name) ? file.name.split('.').pop() : ({ 'image/png': 'png', 'image/jpeg': 'jpg', 'image/webp': 'webp', 'image/gif': 'gif', 'image/svg+xml': 'svg', 'application/pdf': 'pdf', 'application/postscript': 'eps', 'image/heic': 'heic', 'image/heif': 'heif', 'image/avif': 'avif', 'image/bmp': 'bmp', 'image/tiff': 'tif', 'image/vnd.adobe.photoshop': 'psd' }[file.type] || 'png');\n    return base + '____image_' + Date.now() + '_' + Math.floor(Math.random() * 1000) + '.' + ext;\n  }\n\n  var toastEl = null;\n  function toast(msg) {\n    if (!toastEl) {\n      toastEl = document.createElement('div');\n      toastEl.style.cssText = 'position:fixed;left:50%;bottom:32px;transform:translateX(-50%);background:#0f172a;color:#fff;font:600 14px/1.2 \"DM Sans\",system-ui,sans-serif;padding:14px 22px;border-radius:999px;box-shadow:0 12px 32px rgba(15,23,42,0.25);z-index:99999;pointer-events:none;';\n      document.body.appendChild(toastEl);\n    }\n    toastEl.textContent = msg;\n  }\n  function killToast() { if (toastEl) { toastEl.remove(); toastEl = null; } }\n\n  function presign(name, type) {\n    return fetch(PRESIGN_URL + '?file_name=' + encodeURIComponent(name) + '&file_type=' + encodeURIComponent(type))\n      .then(function (r) { return r.json(); });\n  }\n\n  function putFile(url, file, onProgress) {\n    return new Promise(function (resolve, reject) {\n      var xhr = new XMLHttpRequest();\n      xhr.open('PUT', url, true);\n      xhr.upload.addEventListener('progress', function (e) {\n        if (e.lengthComputable && onProgress) onProgress(e.loaded / e.total);\n      });\n      xhr.onload = function () { xhr.status === 200 ? resolve() : reject(new Error('PUT ' + xhr.status)); };\n      xhr.onerror = function () { reject(new Error('PUT network error')); };\n      xhr.send(file);\n    });\n  }\n\n  var busy = false;\n  async function handoff(fileList) {\n    if (busy) return;\n    var files = Array.prototype.slice.call(fileList).filter(function (f) { return OK_EXT.test(f.name); });\n    if (!files.length) return;\n    busy = true;\n    var label = files.length === 1 ? 'design' : files.length + ' designs';\n    try {\n      var items = [];\n      var progress = files.map(function () { return 0; });\n      var paint = function () {\n        var total = progress.reduce(function (a, b) { return a + b; }, 0) / files.length;\n        toast('Sending your ' + label + ' to DTF Transfers\u2026 ' + Math.round(total * 100) + '%');\n      };\n      paint();\n      for (var i = 0; i < files.length; i++) {\n        var f = files[i];\n        var name = randomName(f);\n        var p = await presign(name, f.type || 'application/octet-stream');\n        if (!p || !p.url) throw new Error('presign failed');\n        await putFile(p.url, f, (function (idx) {\n          return function (frac) { progress[idx] = frac; paint(); };\n        })(i));\n        progress[i] = 1; paint();\n        items.push({ url: S3_HOST + name, fileName: f.name });\n      }\n      sessionStorage.setItem(STASH_KEY, JSON.stringify({ items: items, ts: Date.now() }));\n      toast('Opening your DTF order\u2026');\n      window.location.assign(withPreview(DTF_URL));\n    } catch (err) {\n      busy = false;\n      killToast();\n      console.log('ERROR blanks-dtf-handoff', err && err.message);\n      alert('Upload failed \u2014 please try again.');\n    }\n  }\n\n  /* Capture-phase interceptors \u2014 fire before __blanksUploadHelper.js's\n     bubble-phase delegated handlers and stop the event so the blanks modal\n     never engages. Scoped to the on-page upload box only (same selectors the\n     engine delegates on); popups/modals keep their own behavior. */\n  document.addEventListener('change', function (e) {\n    var t = e.target;\n    if (!t || !t.matches || !t.matches('.uploadBox #fileInput')) return;\n    if (!t.files || !t.files.length) return;\n    e.stopImmediatePropagation();\n    /* Snapshot BEFORE clearing value \u2014 t.files is a LIVE FileList and\n       `t.value = ''` empties it, which would hand handoff() zero files. */\n    var files = Array.prototype.slice.call(t.files);\n    t.value = '';\n    handoff(files);\n  }, true);\n\n  document.addEventListener('drop', function (e) {\n    var area = e.target && e.target.closest && e.target.closest('.uploadBox .uploadBox__layout');\n    if (!area) return;\n    e.preventDefault();\n    e.stopImmediatePropagation();\n    area.classList.remove('drop-zone--over');\n    if (e.dataTransfer && e.dataTransfer.files && e.dataTransfer.files.length) {\n      handoff(e.dataTransfer.files);\n    }\n  }, true);\n\n  /* Previous-designs picker \u2192 DTF too. The my-designs picker dispatches\n     md-picker:use-designs (bubbles); the blanks engine's bridge is a\n     bubble-phase document listener that fetches each design into the blanks\n     modal \u2014 this capture-phase listener beats it and redirects instead.\n     Designs are already hosted, so no upload: single \u2192 ?file= (same as a\n     fresh handoff), multi \u2192 ?my_designs_selection= with orderName preserved\n     for the design-reuse cart attribution. Payload mapping mirrors\n     dash-prev-design-modal.liquid (incl. the flat s3File fallback for\n     AI/EPS/PDF/PSD whose imgix URLs can't be fetched raw). */\n  document.addEventListener('md-picker:use-designs', function (e) {\n    var items = (e.detail && e.detail.items) || [];\n    if (!items.length) return;\n    e.stopImmediatePropagation();\n    var overlay = document.querySelector('.customTabelPopup__overlay-3');\n    if (overlay) overlay.style.setProperty('display', 'none', 'important');\n    var dest = null;\n    if (items.length === 1) {\n      var u = items[0] && items[0].file;\n      if (u) dest = withPreview(DTF_URL + '?file=' + encodeURIComponent(u) + '&src=blanks_pdp');\n    } else {\n      var payload = items.map(function (it) {\n        var f = it.file || '';\n        var ext = (f.split('?')[0].split('.').pop() || '').toLowerCase();\n        if (['ai', 'eps', 'pdf', 'psd'].indexOf(ext) > -1 && it.s3File) f = it.s3File;\n        var p = { id: String(it.id || ''), name: it.fileName || '', fileURL: f.split('?')[0] };\n        if (it.orderName) p.orderName = String(it.orderName);\n        return p;\n      }).filter(function (p) { return p.fileURL; });\n      if (payload.length) dest = withPreview(DTF_URL + '?my_designs_selection=' + encodeURIComponent(JSON.stringify(payload)));\n    }\n    if (!dest) return;\n    toast(items.length === 1 ? 'Opening your design in DTF Transfers\u2026' : 'Opening your designs in DTF Transfers\u2026');\n    /* setTimeout, NOT the dash modal's double-rAF: rAF never fires in a\n       background/occluded window (Chrome throttles it indefinitely), which\n       silently killed the navigation. A timer paints the toast just as well. */\n    setTimeout(function () { window.location.href = dest; }, 80);\n  }, true);\n})();\n"],
  "mappings": "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",
  "names": ["f"]
}
