rampkit-expo-dev 0.0.82 → 0.0.84

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,8 +2,8 @@ import { RampKitContext, NavigationData } from "./types";
2
2
  export declare const injectedHardening = "\n(function(){\n try {\n var meta = document.querySelector('meta[name=\"viewport\"]');\n if (!meta) { meta = document.createElement('meta'); meta.name = 'viewport'; document.head.appendChild(meta); }\n meta.setAttribute('content','width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, viewport-fit=cover');\n var style = document.createElement('style');\n style.textContent='html,body{overflow-x:hidden!important;} html,body,*{-webkit-user-select:none!important;user-select:none!important;-webkit-touch-callout:none!important;-ms-user-select:none!important;touch-action: pan-y;} *{-webkit-tap-highlight-color: rgba(0,0,0,0)!important;} ::selection{background: transparent!important;} ::-moz-selection{background: transparent!important;} a,img{-webkit-user-drag:none!important;user-drag:none!important;-webkit-touch-callout:none!important} input,textarea{caret-color:transparent!important;-webkit-user-select:none!important;user-select:none!important}';\n document.head.appendChild(style);\n var prevent=function(e){e.preventDefault&&e.preventDefault();};\n document.addEventListener('gesturestart',prevent,{passive:false});\n document.addEventListener('gesturechange',prevent,{passive:false});\n document.addEventListener('gestureend',prevent,{passive:false});\n document.addEventListener('dblclick',prevent,{passive:false});\n document.addEventListener('wheel',function(e){ if(e.ctrlKey) e.preventDefault(); },{passive:false});\n document.addEventListener('touchmove',function(e){ if(e.scale && e.scale !== 1) e.preventDefault(); },{passive:false});\n document.addEventListener('selectstart',prevent,{passive:false,capture:true});\n document.addEventListener('contextmenu',prevent,{passive:false,capture:true});\n document.addEventListener('copy',prevent,{passive:false,capture:true});\n document.addEventListener('cut',prevent,{passive:false,capture:true});\n document.addEventListener('paste',prevent,{passive:false,capture:true});\n document.addEventListener('dragstart',prevent,{passive:false,capture:true});\n // Belt-and-suspenders: aggressively clear any attempted selection\n var clearSel=function(){\n try{var sel=window.getSelection&&window.getSelection(); if(sel&&sel.removeAllRanges) sel.removeAllRanges();}catch(_){} }\n document.addEventListener('selectionchange',clearSel,{passive:true,capture:true});\n document.onselectstart=function(){ clearSel(); return false; };\n try{ document.documentElement.style.webkitUserSelect='none'; document.documentElement.style.userSelect='none'; }catch(_){ }\n try{ document.body.style.webkitUserSelect='none'; document.body.style.userSelect='none'; }catch(_){ }\n var __selTimer = setInterval(clearSel, 160);\n window.addEventListener('pagehide',function(){ try{ clearInterval(__selTimer); }catch(_){} });\n // Continuously enforce no-select on all elements and new nodes\n var enforceNoSelect = function(el){\n try{\n el.style && (el.style.webkitUserSelect='none', el.style.userSelect='none', el.style.webkitTouchCallout='none');\n el.setAttribute && (el.setAttribute('unselectable','on'), el.setAttribute('contenteditable','false'));\n }catch(_){}\n }\n try{\n var all=document.getElementsByTagName('*');\n for(var i=0;i<all.length;i++){ enforceNoSelect(all[i]); }\n var obs = new MutationObserver(function(muts){\n for(var j=0;j<muts.length;j++){\n var m=muts[j];\n if(m.type==='childList'){\n m.addedNodes && m.addedNodes.forEach && m.addedNodes.forEach(function(n){ if(n && n.nodeType===1){ enforceNoSelect(n); var q=n.getElementsByTagName? n.getElementsByTagName('*'): []; for(var k=0;k<q.length;k++){ enforceNoSelect(q[k]); }}});\n } else if(m.type==='attributes'){\n enforceNoSelect(m.target);\n }\n }\n });\n obs.observe(document.documentElement,{ childList:true, subtree:true, attributes:true, attributeFilter:['contenteditable','style'] });\n }catch(_){ }\n } catch(_) {}\n})(); true;\n";
3
3
  export declare const injectedNoSelect = "\n(function(){\n try {\n if (window.__rkNoSelectApplied) return true;\n window.__rkNoSelectApplied = true;\n var style = document.getElementById('rk-no-select-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'rk-no-select-style';\n style.innerHTML = \"\n * {\n user-select: none !important;\n -webkit-user-select: none !important;\n -webkit-touch-callout: none !important;\n }\n ::selection {\n background: transparent !important;\n }\n \";\n document.head.appendChild(style);\n }\n var prevent = function(e){ if(e && e.preventDefault) e.preventDefault(); return false; };\n document.addEventListener('contextmenu', prevent, { passive: false, capture: true });\n document.addEventListener('selectstart', prevent, { passive: false, capture: true });\n } catch (_) {}\n true;\n})();\n";
4
4
  export declare const injectedVarsHandler = "\n(function(){\n try {\n if (window.__rkVarsHandlerApplied) return true;\n window.__rkVarsHandlerApplied = true;\n \n // Handler function that updates variables and notifies the page\n window.__rkHandleVarsUpdate = function(vars) {\n if (!vars || typeof vars !== 'object') return;\n // Update the global variables object\n window.__rampkitVariables = vars;\n // Dispatch a custom event that the page's JS can listen to for re-rendering\n try {\n document.dispatchEvent(new CustomEvent('rampkit:vars-updated', { detail: vars }));\n } catch(e) {}\n // Also try calling a global handler if the page defined one\n try {\n if (typeof window.onRampkitVarsUpdate === 'function') {\n window.onRampkitVarsUpdate(vars);\n }\n } catch(e) {}\n };\n \n // Listen for message events from React Native\n document.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n \n // Also listen on window for compatibility\n window.addEventListener('message', function(event) {\n try {\n var data = event.data;\n if (data && data.type === 'rampkit:variables' && data.vars) {\n window.__rkHandleVarsUpdate(data.vars);\n }\n } catch(e) {}\n }, false);\n } catch (_) {}\n true;\n})();\n";
5
- export declare const injectedDynamicTapHandler = "\n(function() {\n if (window.__rampkitClickInterceptorInstalled) return;\n window.__rampkitClickInterceptorInstalled = true;\n\n // ========== DEBUG: Screen 19 specific logging (REMOVE AFTER BUG FIX) ==========\n var isScreen19Dynamic = function() {\n var screenId = window.__rampkitScreenId || '';\n var screenIndex = window.__rampkitScreenIndex;\n return screenId.indexOf('19') !== -1 ||\n screenId.toLowerCase().indexOf('screen 19') !== -1 ||\n screenId.toLowerCase().indexOf('screen19') !== -1 ||\n screenIndex === 19 ||\n screenIndex === 18;\n };\n\n var debugScreen19Dynamic = function(msg, data) {\n if (isScreen19Dynamic()) {\n console.log('[SCREEN19-DEBUG][DynamicTap] ' + msg, JSON.stringify(data || {}));\n }\n };\n // ========== END DEBUG ==========\n\n // Decode HTML entities\n function decodeHtml(str) {\n if (!str) return str;\n return str.replace(/&quot;/g, '\"').replace(/&#34;/g, '\"').replace(/&#x22;/g, '\"')\n .replace(/&apos;/g, \"'\").replace(/&#39;/g, \"'\").replace(/&#x27;/g, \"'\")\n .replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');\n }\n\n // Find dynamic tap config on element or ancestors\n function findDynamicTap(el) {\n var current = el;\n var depth = 0;\n var attrNames = ['data-tap-dynamic', 'data-tapdynamic', 'tapDynamic', 'data-dynamic-tap'];\n var searchTrail = []; // DEBUG: Track search path\n\n while (current && current !== document.body && current !== document.documentElement && depth < 20) {\n // DEBUG: Build search trail for Screen 19\n var trailInfo = {\n depth: depth,\n tag: current.tagName,\n id: current.id || '(none)',\n class: (current.className && typeof current.className === 'string') ? current.className.substring(0,50) : '(none)'\n };\n searchTrail.push(trailInfo);\n\n if (current.getAttribute) {\n for (var i = 0; i < attrNames.length; i++) {\n var attr = current.getAttribute(attrNames[i]);\n if (attr && attr.length > 2) {\n var rect = current.getBoundingClientRect ? current.getBoundingClientRect() : {};\n debugScreen19Dynamic('FOUND data-tap-dynamic', {\n attrName: attrNames[i],\n depth: depth,\n element: trailInfo,\n size: rect.width + 'x' + rect.height,\n configPreview: attr.substring(0, 100) + '...',\n trail: searchTrail\n });\n return { element: current, config: attr };\n }\n }\n if (current.dataset && current.dataset.tapDynamic) {\n var rect2 = current.getBoundingClientRect ? current.getBoundingClientRect() : {};\n debugScreen19Dynamic('FOUND dataset.tapDynamic', {\n depth: depth,\n element: trailInfo,\n size: rect2.width + 'x' + rect2.height,\n trail: searchTrail\n });\n return { element: current, config: current.dataset.tapDynamic };\n }\n }\n current = current.parentElement;\n depth++;\n }\n debugScreen19Dynamic('NO data-tap-dynamic found', { trail: searchTrail });\n return null;\n }\n \n // Get variables for condition evaluation - check ALL possible sources\n function getVars() {\n var vars = {};\n if (window.__rampkitVariables) {\n Object.keys(window.__rampkitVariables).forEach(function(k) {\n vars[k] = window.__rampkitVariables[k];\n });\n }\n if (window.__rampkitVars) {\n Object.keys(window.__rampkitVars).forEach(function(k) {\n vars[k] = window.__rampkitVars[k];\n });\n }\n if (window.RK_VARS) {\n Object.keys(window.RK_VARS).forEach(function(k) {\n vars[k] = window.RK_VARS[k];\n });\n }\n return vars;\n }\n \n // Evaluate a single rule\n function evalRule(rule, vars) {\n if (!rule || !rule.key) return false;\n var left = vars[rule.key];\n var right = rule.value;\n var op = rule.op || '=';\n if (left === undefined || left === null) left = '';\n if (right === undefined || right === null) right = '';\n var leftStr = String(left);\n var rightStr = String(right);\n var result = false;\n switch (op) {\n case '=': case '==': result = leftStr === rightStr; break;\n case '!=': case '<>': result = leftStr !== rightStr; break;\n case '>': result = parseFloat(left) > parseFloat(right); break;\n case '<': result = parseFloat(left) < parseFloat(right); break;\n case '>=': result = parseFloat(left) >= parseFloat(right); break;\n case '<=': result = parseFloat(left) <= parseFloat(right); break;\n default: result = false;\n }\n return result;\n }\n \n // Evaluate all rules (AND logic)\n function evalRules(rules, vars) {\n if (!rules || !rules.length) return true;\n for (var i = 0; i < rules.length; i++) {\n if (!evalRule(rules[i], vars)) return false;\n }\n return true;\n }\n \n // Execute an action\n function execAction(action) {\n if (!action || !action.type) return;\n var msg = null;\n var actionType = action.type.toLowerCase();\n \n switch (actionType) {\n case 'navigate':\n msg = { type: 'rampkit:navigate', targetScreenId: action.targetScreenId || '__continue__', animation: action.animation || 'fade' };\n break;\n case 'continue':\n msg = { type: 'rampkit:navigate', targetScreenId: '__continue__', animation: action.animation || 'fade' };\n break;\n case 'goback':\n msg = { type: 'rampkit:goBack', animation: action.animation || 'fade' };\n break;\n case 'close':\n msg = { type: 'rampkit:close' };\n break;\n case 'haptic':\n msg = { type: 'rampkit:haptic', hapticType: action.hapticType || 'impact', impactStyle: action.impactStyle || 'Medium', notificationType: action.notificationType };\n break;\n case 'showpaywall':\n msg = { type: 'rampkit:show-paywall', payload: action.payload || { paywallId: action.paywallId } };\n break;\n case 'requestreview':\n msg = { type: 'rampkit:request-review' };\n break;\n case 'requestnotificationpermission':\n msg = { type: 'rampkit:request-notification-permission' };\n break;\n case 'onboardingfinished':\n msg = { type: 'rampkit:onboarding-finished', payload: action.payload };\n break;\n case 'setvariable':\n case 'setstate':\n case 'updatevariable':\n case 'set':\n case 'assign':\n var varKey = action.key || action.variableName || action.name || action.variable;\n var varValue = action.variableValue !== undefined ? action.variableValue :\n action.value !== undefined ? action.value :\n action.newValue !== undefined ? action.newValue : undefined;\n if (varKey && varValue !== undefined) {\n if (window.__rampkitVariables) window.__rampkitVariables[varKey] = varValue;\n if (window.__rampkitVars) window.__rampkitVars[varKey] = varValue;\n var updateVars = {};\n updateVars[varKey] = varValue;\n msg = { type: 'rampkit:variables', vars: updateVars };\n }\n break;\n }\n if (msg) {\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify(msg));\n }\n } catch(e) {}\n }\n }\n \n // Evaluate dynamic tap config\n function evalDynamicTap(config) {\n if (!config || !config.values) return false;\n var vars = getVars();\n var conditions = config.values;\n for (var i = 0; i < conditions.length; i++) {\n var cond = conditions[i];\n var condType = cond.conditionType || 'if';\n var rules = cond.rules || [];\n var actions = cond.actions || [];\n if (condType === 'else' || evalRules(rules, vars)) {\n for (var j = 0; j < actions.length; j++) {\n execAction(actions[j]);\n }\n return true;\n }\n }\n return false;\n }\n \n // Click interceptor - capture phase, runs BEFORE onclick handlers\n function interceptClick(event) {\n // ========== DEBUG: Screen 19 click logging ==========\n if (isScreen19Dynamic()) {\n var clickX = event.clientX;\n var clickY = event.clientY;\n var originalTarget = event.target;\n var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};\n console.log('[SCREEN19-DEBUG][Click] Click at (' + clickX + ',' + clickY + ')', JSON.stringify({\n originalTarget: {\n tag: originalTarget.tagName,\n id: originalTarget.id || '(none)',\n class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',\n size: originalRect.width + 'x' + originalRect.height\n }\n }));\n }\n // ========== END DEBUG ==========\n\n var result = findDynamicTap(event.target);\n if (!result) return;\n\n // ========== DEBUG: Screen 19 - log when dynamic tap is found ==========\n if (isScreen19Dynamic()) {\n var rect = result.element.getBoundingClientRect ? result.element.getBoundingClientRect() : {};\n var screenWidth = window.innerWidth;\n var screenHeight = window.innerHeight;\n var isFullScreen = (rect.width >= screenWidth * 0.9 && rect.height >= screenHeight * 0.9);\n console.log('[SCREEN19-DEBUG][Click] DYNAMIC TAP WILL BE HANDLED', JSON.stringify({\n element: {\n tag: result.element.tagName,\n id: result.element.id || '(none)',\n class: (result.element.className && typeof result.element.className === 'string') ? result.element.className.substring(0,100) : '(none)',\n size: rect.width + 'x' + rect.height\n },\n isFullScreen: isFullScreen,\n WARNING: isFullScreen ? 'FULL SCREEN ELEMENT WITH DYNAMIC TAP - THIS IS THE BUG!' : 'normal element'\n }));\n }\n // ========== END DEBUG ==========\n\n try {\n var configStr = decodeHtml(result.config);\n var config = JSON.parse(configStr);\n\n // ========== DEBUG: Screen 19 - log parsed config ==========\n if (isScreen19Dynamic()) {\n console.log('[SCREEN19-DEBUG][Click] Parsed config:', JSON.stringify({\n hasValues: !!(config && config.values),\n valuesCount: config && config.values ? config.values.length : 0,\n firstCondition: config && config.values && config.values[0] ? {\n conditionType: config.values[0].conditionType,\n rulesCount: config.values[0].rules ? config.values[0].rules.length : 0,\n actionsCount: config.values[0].actions ? config.values[0].actions.length : 0\n } : null\n }));\n }\n // ========== END DEBUG ==========\n\n var handled = evalDynamicTap(config);\n if (handled) {\n debugScreen19Dynamic('Click HANDLED by dynamic tap - event stopped', { handled: true });\n event.stopImmediatePropagation();\n event.preventDefault();\n return false;\n }\n } catch (e) {\n console.log('[RampKit] Dynamic tap error:', e);\n if (isScreen19Dynamic()) {\n console.log('[SCREEN19-DEBUG][Click] Dynamic tap parse error:', e.message);\n }\n }\n }\n\n // Install interceptor on window in capture phase\n window.addEventListener('click', interceptClick, true);\n})();\n";
6
- export declare const injectedButtonAnimations = "\n(function(){\n try {\n if (window.__rkButtonAnimApplied) return true;\n window.__rkButtonAnimApplied = true;\n\n var pressed = null;\n var pressedOriginalTransform = '';\n var pressedOriginalOpacity = '';\n var pressedOriginalTransition = '';\n var releaseTimer = null;\n\n // ========== DEBUG: Screen 19 specific logging (REMOVE AFTER BUG FIX) ==========\n var isScreen19 = function() {\n // Check multiple ways to identify Screen 19\n var screenId = window.__rampkitScreenId || '';\n var screenIndex = window.__rampkitScreenIndex;\n return screenId.indexOf('19') !== -1 ||\n screenId.toLowerCase().indexOf('screen 19') !== -1 ||\n screenId.toLowerCase().indexOf('screen19') !== -1 ||\n screenIndex === 19 ||\n screenIndex === 18; // 0-indexed, so screen 19 would be index 18\n };\n\n var debugScreen19 = function(msg, data) {\n if (isScreen19()) {\n console.log('[SCREEN19-DEBUG][ButtonAnim] ' + msg, JSON.stringify(data || {}));\n }\n };\n // ========== END DEBUG ==========\n\n // Find interactive element - very permissive, looks for any clickable-looking element\n function findInteractive(el) {\n var current = el;\n var debugTrail = []; // DEBUG: Track search path for Screen 19\n\n for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {\n if (!current || !current.tagName) { current = current.parentElement; continue; }\n var tag = current.tagName.toLowerCase();\n\n // Skip tiny elements (likely icons inside buttons)\n var rect = current.getBoundingClientRect();\n if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }\n\n // DEBUG: Build trail for Screen 19\n var debugInfo = {\n depth: i,\n tag: tag,\n id: current.id || '(none)',\n class: (current.className && typeof current.className === 'string') ? current.className.substring(0, 100) : '(none)',\n size: rect.width + 'x' + rect.height\n };\n debugTrail.push(debugInfo);\n\n // Match standard interactive elements\n if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') {\n debugScreen19('MATCHED: standard tag', { reason: 'tag=' + tag, element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with any data attribute containing action/navigate/tap/click\n var attrs = current.attributes;\n if (attrs) {\n for (var j = 0; j < attrs.length; j++) {\n var attrName = attrs[j].name.toLowerCase();\n if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||\n attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||\n attrName.indexOf('press') !== -1) {\n debugScreen19('MATCHED: data-attr', { reason: 'attr=' + attrName, value: attrs[j].value.substring(0,50), element: debugInfo, trail: debugTrail });\n return current;\n }\n }\n }\n\n // Match elements with onclick\n if (current.onclick || current.hasAttribute('onclick')) {\n debugScreen19('MATCHED: onclick', { element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with role=\"button\" or tabindex\n if (current.getAttribute('role') === 'button') {\n debugScreen19('MATCHED: role=button', { element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match any element with an ID containing button/btn/cta\n var id = current.id || '';\n if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) {\n debugScreen19('MATCHED: button-like ID', { reason: 'id=' + id, element: debugInfo, trail: debugTrail });\n return current;\n }\n\n // Match elements with button-like classes\n var className = current.className;\n if (className && typeof className === 'string') {\n var cls = className.toLowerCase();\n if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||\n cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {\n debugScreen19('MATCHED: button-like class', { reason: 'class=' + className, element: debugInfo, trail: debugTrail });\n return current;\n }\n }\n\n // Match elements with cursor pointer\n try {\n var computed = window.getComputedStyle(current);\n if (computed && computed.cursor === 'pointer') {\n debugScreen19('MATCHED: cursor:pointer', { element: debugInfo, trail: debugTrail });\n return current;\n }\n } catch(e) {}\n\n current = current.parentElement;\n }\n debugScreen19('NO MATCH found', { originalTag: el.tagName, trail: debugTrail });\n return null;\n }\n \n function applyPressedStyle(el) {\n if (!el || !el.style) return;\n // Save original styles\n pressedOriginalTransform = el.style.transform || '';\n pressedOriginalOpacity = el.style.opacity || '';\n pressedOriginalTransition = el.style.transition || '';\n // Apply pressed style with inline styles for maximum specificity\n el.style.transition = 'transform 80ms cubic-bezier(0.25, 0.1, 0.25, 1), opacity 80ms cubic-bezier(0.25, 0.1, 0.25, 1)';\n el.style.transform = 'scale(0.97)';\n el.style.opacity = '0.8';\n }\n \n function applyReleasedStyle(el) {\n if (!el || !el.style) return;\n // Apply spring-back animation\n el.style.transition = 'transform 280ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 280ms cubic-bezier(0.34, 1.56, 0.64, 1)';\n el.style.transform = pressedOriginalTransform || 'scale(1)';\n el.style.opacity = pressedOriginalOpacity || '1';\n }\n \n function resetStyle(el) {\n if (!el || !el.style) return;\n el.style.transform = pressedOriginalTransform;\n el.style.opacity = pressedOriginalOpacity;\n el.style.transition = pressedOriginalTransition;\n }\n \n function onTouchStart(e) {\n try {\n // ========== DEBUG: Screen 19 touch logging ==========\n if (isScreen19()) {\n var touchX = e.touches ? e.touches[0].clientX : e.clientX;\n var touchY = e.touches ? e.touches[0].clientY : e.clientY;\n var originalTarget = e.target;\n var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};\n console.log('[SCREEN19-DEBUG][TouchStart] Touch at (' + touchX + ',' + touchY + ')', JSON.stringify({\n originalTarget: {\n tag: originalTarget.tagName,\n id: originalTarget.id || '(none)',\n class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',\n size: originalRect.width + 'x' + originalRect.height\n }\n }));\n }\n // ========== END DEBUG ==========\n\n var target = findInteractive(e.target);\n if (!target) return;\n\n // ========== DEBUG: Screen 19 - log what element was found interactive ==========\n if (isScreen19() && target) {\n var targetRect = target.getBoundingClientRect();\n var screenWidth = window.innerWidth;\n var screenHeight = window.innerHeight;\n var isFullScreen = (targetRect.width >= screenWidth * 0.9 && targetRect.height >= screenHeight * 0.9);\n console.log('[SCREEN19-DEBUG][TouchStart] INTERACTIVE ELEMENT FOUND', JSON.stringify({\n tag: target.tagName,\n id: target.id || '(none)',\n class: (target.className && typeof target.className === 'string') ? target.className.substring(0,100) : '(none)',\n size: targetRect.width + 'x' + targetRect.height,\n isFullScreen: isFullScreen,\n WARNING: isFullScreen ? 'FULL SCREEN ELEMENT DETECTED - THIS IS THE BUG!' : 'normal element'\n }));\n }\n // ========== END DEBUG ==========\n\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n if (pressed && pressed !== target) { resetStyle(pressed); }\n applyPressedStyle(target);\n pressed = target;\n } catch(err) {}\n }\n \n function onTouchEnd(e) {\n try {\n if (!pressed) return;\n var t = pressed;\n applyReleasedStyle(t);\n releaseTimer = setTimeout(function() {\n resetStyle(t);\n releaseTimer = null;\n }, 300);\n pressed = null;\n } catch(err) {}\n }\n \n function onTouchCancel(e) {\n try {\n if (!pressed) return;\n resetStyle(pressed);\n pressed = null;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n } catch(err) {}\n }\n \n // Use capture phase for immediate response before any other handlers\n document.addEventListener('touchstart', onTouchStart, { passive: true, capture: true });\n document.addEventListener('touchend', onTouchEnd, { passive: true, capture: true });\n document.addEventListener('touchcancel', onTouchCancel, { passive: true, capture: true });\n // Mouse events for testing\n document.addEventListener('mousedown', onTouchStart, { passive: true, capture: true });\n document.addEventListener('mouseup', onTouchEnd, { passive: true, capture: true });\n \n } catch (err) {}\n true;\n})();\n";
5
+ export declare const injectedDynamicTapHandler = "\n(function() {\n if (window.__rampkitClickInterceptorInstalled) return;\n window.__rampkitClickInterceptorInstalled = true;\n\n // Decode HTML entities\n function decodeHtml(str) {\n if (!str) return str;\n return str.replace(/&quot;/g, '\"').replace(/&#34;/g, '\"').replace(/&#x22;/g, '\"')\n .replace(/&apos;/g, \"'\").replace(/&#39;/g, \"'\").replace(/&#x27;/g, \"'\")\n .replace(/&lt;/g, '<').replace(/&gt;/g, '>').replace(/&amp;/g, '&');\n }\n\n // Find dynamic tap config on element or ancestors\n function findDynamicTap(el) {\n var current = el;\n var depth = 0;\n var attrNames = ['data-tap-dynamic', 'data-tapdynamic', 'tapDynamic', 'data-dynamic-tap'];\n while (current && current !== document.body && current !== document.documentElement && depth < 20) {\n if (current.getAttribute) {\n for (var i = 0; i < attrNames.length; i++) {\n var attr = current.getAttribute(attrNames[i]);\n if (attr && attr.length > 2) {\n return { element: current, config: attr };\n }\n }\n if (current.dataset && current.dataset.tapDynamic) {\n return { element: current, config: current.dataset.tapDynamic };\n }\n }\n current = current.parentElement;\n depth++;\n }\n return null;\n }\n \n // Get variables for condition evaluation - check ALL possible sources\n function getVars() {\n var vars = {};\n if (window.__rampkitVariables) {\n Object.keys(window.__rampkitVariables).forEach(function(k) {\n vars[k] = window.__rampkitVariables[k];\n });\n }\n if (window.__rampkitVars) {\n Object.keys(window.__rampkitVars).forEach(function(k) {\n vars[k] = window.__rampkitVars[k];\n });\n }\n if (window.RK_VARS) {\n Object.keys(window.RK_VARS).forEach(function(k) {\n vars[k] = window.RK_VARS[k];\n });\n }\n return vars;\n }\n \n // Evaluate a single rule\n function evalRule(rule, vars) {\n if (!rule || !rule.key) return false;\n var left = vars[rule.key];\n var right = rule.value;\n var op = rule.op || '=';\n if (left === undefined || left === null) left = '';\n if (right === undefined || right === null) right = '';\n var leftStr = String(left);\n var rightStr = String(right);\n var result = false;\n switch (op) {\n case '=': case '==': result = leftStr === rightStr; break;\n case '!=': case '<>': result = leftStr !== rightStr; break;\n case '>': result = parseFloat(left) > parseFloat(right); break;\n case '<': result = parseFloat(left) < parseFloat(right); break;\n case '>=': result = parseFloat(left) >= parseFloat(right); break;\n case '<=': result = parseFloat(left) <= parseFloat(right); break;\n default: result = false;\n }\n return result;\n }\n \n // Evaluate all rules (AND logic)\n function evalRules(rules, vars) {\n if (!rules || !rules.length) return true;\n for (var i = 0; i < rules.length; i++) {\n if (!evalRule(rules[i], vars)) return false;\n }\n return true;\n }\n \n // Execute an action\n function execAction(action) {\n if (!action || !action.type) return;\n var msg = null;\n var actionType = action.type.toLowerCase();\n \n switch (actionType) {\n case 'navigate':\n msg = { type: 'rampkit:navigate', targetScreenId: action.targetScreenId || '__continue__', animation: action.animation || 'fade' };\n break;\n case 'continue':\n msg = { type: 'rampkit:navigate', targetScreenId: '__continue__', animation: action.animation || 'fade' };\n break;\n case 'goback':\n msg = { type: 'rampkit:goBack', animation: action.animation || 'fade' };\n break;\n case 'close':\n msg = { type: 'rampkit:close' };\n break;\n case 'haptic':\n msg = { type: 'rampkit:haptic', hapticType: action.hapticType || 'impact', impactStyle: action.impactStyle || 'Medium', notificationType: action.notificationType };\n break;\n case 'showpaywall':\n msg = { type: 'rampkit:show-paywall', payload: action.payload || { paywallId: action.paywallId } };\n break;\n case 'requestreview':\n msg = { type: 'rampkit:request-review' };\n break;\n case 'requestnotificationpermission':\n msg = { type: 'rampkit:request-notification-permission' };\n break;\n case 'onboardingfinished':\n msg = { type: 'rampkit:onboarding-finished', payload: action.payload };\n break;\n case 'setvariable':\n case 'setstate':\n case 'updatevariable':\n case 'set':\n case 'assign':\n var varKey = action.key || action.variableName || action.name || action.variable;\n var varValue = action.variableValue !== undefined ? action.variableValue :\n action.value !== undefined ? action.value :\n action.newValue !== undefined ? action.newValue : undefined;\n if (varKey && varValue !== undefined) {\n if (window.__rampkitVariables) window.__rampkitVariables[varKey] = varValue;\n if (window.__rampkitVars) window.__rampkitVars[varKey] = varValue;\n var updateVars = {};\n updateVars[varKey] = varValue;\n msg = { type: 'rampkit:variables', vars: updateVars };\n }\n break;\n }\n if (msg) {\n try {\n if (window.ReactNativeWebView && window.ReactNativeWebView.postMessage) {\n window.ReactNativeWebView.postMessage(JSON.stringify(msg));\n }\n } catch(e) {}\n }\n }\n \n // Evaluate dynamic tap config\n function evalDynamicTap(config) {\n if (!config || !config.values) return false;\n var vars = getVars();\n var conditions = config.values;\n for (var i = 0; i < conditions.length; i++) {\n var cond = conditions[i];\n var condType = cond.conditionType || 'if';\n var rules = cond.rules || [];\n var actions = cond.actions || [];\n if (condType === 'else' || evalRules(rules, vars)) {\n for (var j = 0; j < actions.length; j++) {\n execAction(actions[j]);\n }\n return true;\n }\n }\n return false;\n }\n \n // Click interceptor - capture phase, runs BEFORE onclick handlers\n function interceptClick(event) {\n var result = findDynamicTap(event.target);\n if (!result) return;\n\n try {\n var configStr = decodeHtml(result.config);\n var config = JSON.parse(configStr);\n var handled = evalDynamicTap(config);\n if (handled) {\n event.stopImmediatePropagation();\n event.preventDefault();\n return false;\n }\n } catch (e) {\n console.log('[RampKit] Dynamic tap error:', e);\n }\n }\n\n // Install interceptor on window in capture phase\n window.addEventListener('click', interceptClick, true);\n})();\n";
6
+ export declare const injectedButtonAnimations = "\n(function(){\n try {\n if (window.__rkButtonAnimApplied) return true;\n window.__rkButtonAnimApplied = true;\n\n var pressed = null;\n var pressedOriginalTransform = '';\n var pressedOriginalOpacity = '';\n var pressedOriginalTransition = '';\n var releaseTimer = null;\n\n // Find interactive element - looks for clickable-looking elements\n function findInteractive(el) {\n var current = el;\n for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {\n if (!current || !current.tagName) { current = current.parentElement; continue; }\n var tag = current.tagName.toLowerCase();\n\n // Skip tiny elements (likely icons inside buttons)\n var rect = current.getBoundingClientRect();\n if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }\n\n // Match standard interactive elements\n if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') return current;\n\n // Match elements with tap/click-related data attributes\n // Exclude lifecycle attributes like data-on-open-actions, data-on-close-actions\n var attrs = current.attributes;\n if (attrs) {\n for (var j = 0; j < attrs.length; j++) {\n var attrName = attrs[j].name.toLowerCase();\n // Skip lifecycle attributes (on-open, on-close, on-load, on-appear, etc.)\n if (attrName.indexOf('on-open') !== -1 || attrName.indexOf('on-close') !== -1 ||\n attrName.indexOf('on-load') !== -1 || attrName.indexOf('on-appear') !== -1 ||\n attrName.indexOf('onopen') !== -1 || attrName.indexOf('onclose') !== -1 ||\n attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1) {\n continue;\n }\n // Match tap/click interaction attributes\n if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||\n attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||\n attrName.indexOf('press') !== -1) {\n return current;\n }\n }\n }\n\n // Match elements with onclick\n if (current.onclick || current.hasAttribute('onclick')) return current;\n\n // Match elements with role=\"button\"\n if (current.getAttribute('role') === 'button') return current;\n\n // Match any element with an ID containing button/btn/cta\n var id = current.id || '';\n if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) return current;\n\n // Match elements with button-like classes\n var className = current.className;\n if (className && typeof className === 'string') {\n var cls = className.toLowerCase();\n if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||\n cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {\n return current;\n }\n }\n\n // Match elements with cursor pointer\n try {\n var computed = window.getComputedStyle(current);\n if (computed && computed.cursor === 'pointer') return current;\n } catch(e) {}\n\n current = current.parentElement;\n }\n return null;\n }\n\n function applyPressedStyle(el) {\n if (!el || !el.style) return;\n // Save original styles\n pressedOriginalTransform = el.style.transform || '';\n pressedOriginalOpacity = el.style.opacity || '';\n pressedOriginalTransition = el.style.transition || '';\n // Apply pressed style with inline styles for maximum specificity\n el.style.transition = 'transform 80ms cubic-bezier(0.25, 0.1, 0.25, 1), opacity 80ms cubic-bezier(0.25, 0.1, 0.25, 1)';\n el.style.transform = 'scale(0.97)';\n el.style.opacity = '0.8';\n }\n\n function applyReleasedStyle(el) {\n if (!el || !el.style) return;\n // Apply spring-back animation\n el.style.transition = 'transform 280ms cubic-bezier(0.34, 1.56, 0.64, 1), opacity 280ms cubic-bezier(0.34, 1.56, 0.64, 1)';\n el.style.transform = pressedOriginalTransform || 'scale(1)';\n el.style.opacity = pressedOriginalOpacity || '1';\n }\n\n function resetStyle(el) {\n if (!el || !el.style) return;\n el.style.transform = pressedOriginalTransform;\n el.style.opacity = pressedOriginalOpacity;\n el.style.transition = pressedOriginalTransition;\n }\n\n function onTouchStart(e) {\n try {\n var target = findInteractive(e.target);\n if (!target) return;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n if (pressed && pressed !== target) { resetStyle(pressed); }\n applyPressedStyle(target);\n pressed = target;\n } catch(err) {}\n }\n \n function onTouchEnd(e) {\n try {\n if (!pressed) return;\n var t = pressed;\n applyReleasedStyle(t);\n releaseTimer = setTimeout(function() {\n resetStyle(t);\n releaseTimer = null;\n }, 300);\n pressed = null;\n } catch(err) {}\n }\n \n function onTouchCancel(e) {\n try {\n if (!pressed) return;\n resetStyle(pressed);\n pressed = null;\n if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }\n } catch(err) {}\n }\n \n // Use capture phase for immediate response before any other handlers\n document.addEventListener('touchstart', onTouchStart, { passive: true, capture: true });\n document.addEventListener('touchend', onTouchEnd, { passive: true, capture: true });\n document.addEventListener('touchcancel', onTouchCancel, { passive: true, capture: true });\n // Mouse events for testing\n document.addEventListener('mousedown', onTouchStart, { passive: true, capture: true });\n document.addEventListener('mouseup', onTouchEnd, { passive: true, capture: true });\n \n } catch (err) {}\n true;\n})();\n";
7
7
  export type ScreenPayload = {
8
8
  id: string;
9
9
  html: string;
@@ -182,24 +182,6 @@ exports.injectedDynamicTapHandler = `
182
182
  if (window.__rampkitClickInterceptorInstalled) return;
183
183
  window.__rampkitClickInterceptorInstalled = true;
184
184
 
185
- // ========== DEBUG: Screen 19 specific logging (REMOVE AFTER BUG FIX) ==========
186
- var isScreen19Dynamic = function() {
187
- var screenId = window.__rampkitScreenId || '';
188
- var screenIndex = window.__rampkitScreenIndex;
189
- return screenId.indexOf('19') !== -1 ||
190
- screenId.toLowerCase().indexOf('screen 19') !== -1 ||
191
- screenId.toLowerCase().indexOf('screen19') !== -1 ||
192
- screenIndex === 19 ||
193
- screenIndex === 18;
194
- };
195
-
196
- var debugScreen19Dynamic = function(msg, data) {
197
- if (isScreen19Dynamic()) {
198
- console.log('[SCREEN19-DEBUG][DynamicTap] ' + msg, JSON.stringify(data || {}));
199
- }
200
- };
201
- // ========== END DEBUG ==========
202
-
203
185
  // Decode HTML entities
204
186
  function decodeHtml(str) {
205
187
  if (!str) return str;
@@ -213,49 +195,21 @@ exports.injectedDynamicTapHandler = `
213
195
  var current = el;
214
196
  var depth = 0;
215
197
  var attrNames = ['data-tap-dynamic', 'data-tapdynamic', 'tapDynamic', 'data-dynamic-tap'];
216
- var searchTrail = []; // DEBUG: Track search path
217
-
218
198
  while (current && current !== document.body && current !== document.documentElement && depth < 20) {
219
- // DEBUG: Build search trail for Screen 19
220
- var trailInfo = {
221
- depth: depth,
222
- tag: current.tagName,
223
- id: current.id || '(none)',
224
- class: (current.className && typeof current.className === 'string') ? current.className.substring(0,50) : '(none)'
225
- };
226
- searchTrail.push(trailInfo);
227
-
228
199
  if (current.getAttribute) {
229
200
  for (var i = 0; i < attrNames.length; i++) {
230
201
  var attr = current.getAttribute(attrNames[i]);
231
202
  if (attr && attr.length > 2) {
232
- var rect = current.getBoundingClientRect ? current.getBoundingClientRect() : {};
233
- debugScreen19Dynamic('FOUND data-tap-dynamic', {
234
- attrName: attrNames[i],
235
- depth: depth,
236
- element: trailInfo,
237
- size: rect.width + 'x' + rect.height,
238
- configPreview: attr.substring(0, 100) + '...',
239
- trail: searchTrail
240
- });
241
203
  return { element: current, config: attr };
242
204
  }
243
205
  }
244
206
  if (current.dataset && current.dataset.tapDynamic) {
245
- var rect2 = current.getBoundingClientRect ? current.getBoundingClientRect() : {};
246
- debugScreen19Dynamic('FOUND dataset.tapDynamic', {
247
- depth: depth,
248
- element: trailInfo,
249
- size: rect2.width + 'x' + rect2.height,
250
- trail: searchTrail
251
- });
252
207
  return { element: current, config: current.dataset.tapDynamic };
253
208
  }
254
209
  }
255
210
  current = current.parentElement;
256
211
  depth++;
257
212
  }
258
- debugScreen19Dynamic('NO data-tap-dynamic found', { trail: searchTrail });
259
213
  return null;
260
214
  }
261
215
 
@@ -395,75 +349,20 @@ exports.injectedDynamicTapHandler = `
395
349
 
396
350
  // Click interceptor - capture phase, runs BEFORE onclick handlers
397
351
  function interceptClick(event) {
398
- // ========== DEBUG: Screen 19 click logging ==========
399
- if (isScreen19Dynamic()) {
400
- var clickX = event.clientX;
401
- var clickY = event.clientY;
402
- var originalTarget = event.target;
403
- var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};
404
- console.log('[SCREEN19-DEBUG][Click] Click at (' + clickX + ',' + clickY + ')', JSON.stringify({
405
- originalTarget: {
406
- tag: originalTarget.tagName,
407
- id: originalTarget.id || '(none)',
408
- class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',
409
- size: originalRect.width + 'x' + originalRect.height
410
- }
411
- }));
412
- }
413
- // ========== END DEBUG ==========
414
-
415
352
  var result = findDynamicTap(event.target);
416
353
  if (!result) return;
417
354
 
418
- // ========== DEBUG: Screen 19 - log when dynamic tap is found ==========
419
- if (isScreen19Dynamic()) {
420
- var rect = result.element.getBoundingClientRect ? result.element.getBoundingClientRect() : {};
421
- var screenWidth = window.innerWidth;
422
- var screenHeight = window.innerHeight;
423
- var isFullScreen = (rect.width >= screenWidth * 0.9 && rect.height >= screenHeight * 0.9);
424
- console.log('[SCREEN19-DEBUG][Click] DYNAMIC TAP WILL BE HANDLED', JSON.stringify({
425
- element: {
426
- tag: result.element.tagName,
427
- id: result.element.id || '(none)',
428
- class: (result.element.className && typeof result.element.className === 'string') ? result.element.className.substring(0,100) : '(none)',
429
- size: rect.width + 'x' + rect.height
430
- },
431
- isFullScreen: isFullScreen,
432
- WARNING: isFullScreen ? 'FULL SCREEN ELEMENT WITH DYNAMIC TAP - THIS IS THE BUG!' : 'normal element'
433
- }));
434
- }
435
- // ========== END DEBUG ==========
436
-
437
355
  try {
438
356
  var configStr = decodeHtml(result.config);
439
357
  var config = JSON.parse(configStr);
440
-
441
- // ========== DEBUG: Screen 19 - log parsed config ==========
442
- if (isScreen19Dynamic()) {
443
- console.log('[SCREEN19-DEBUG][Click] Parsed config:', JSON.stringify({
444
- hasValues: !!(config && config.values),
445
- valuesCount: config && config.values ? config.values.length : 0,
446
- firstCondition: config && config.values && config.values[0] ? {
447
- conditionType: config.values[0].conditionType,
448
- rulesCount: config.values[0].rules ? config.values[0].rules.length : 0,
449
- actionsCount: config.values[0].actions ? config.values[0].actions.length : 0
450
- } : null
451
- }));
452
- }
453
- // ========== END DEBUG ==========
454
-
455
358
  var handled = evalDynamicTap(config);
456
359
  if (handled) {
457
- debugScreen19Dynamic('Click HANDLED by dynamic tap - event stopped', { handled: true });
458
360
  event.stopImmediatePropagation();
459
361
  event.preventDefault();
460
362
  return false;
461
363
  }
462
364
  } catch (e) {
463
365
  console.log('[RampKit] Dynamic tap error:', e);
464
- if (isScreen19Dynamic()) {
465
- console.log('[SCREEN19-DEBUG][Click] Dynamic tap parse error:', e.message);
466
- }
467
366
  }
468
367
  }
469
368
 
@@ -486,30 +385,9 @@ exports.injectedButtonAnimations = `
486
385
  var pressedOriginalTransition = '';
487
386
  var releaseTimer = null;
488
387
 
489
- // ========== DEBUG: Screen 19 specific logging (REMOVE AFTER BUG FIX) ==========
490
- var isScreen19 = function() {
491
- // Check multiple ways to identify Screen 19
492
- var screenId = window.__rampkitScreenId || '';
493
- var screenIndex = window.__rampkitScreenIndex;
494
- return screenId.indexOf('19') !== -1 ||
495
- screenId.toLowerCase().indexOf('screen 19') !== -1 ||
496
- screenId.toLowerCase().indexOf('screen19') !== -1 ||
497
- screenIndex === 19 ||
498
- screenIndex === 18; // 0-indexed, so screen 19 would be index 18
499
- };
500
-
501
- var debugScreen19 = function(msg, data) {
502
- if (isScreen19()) {
503
- console.log('[SCREEN19-DEBUG][ButtonAnim] ' + msg, JSON.stringify(data || {}));
504
- }
505
- };
506
- // ========== END DEBUG ==========
507
-
508
- // Find interactive element - very permissive, looks for any clickable-looking element
388
+ // Find interactive element - looks for clickable-looking elements
509
389
  function findInteractive(el) {
510
390
  var current = el;
511
- var debugTrail = []; // DEBUG: Track search path for Screen 19
512
-
513
391
  for (var i = 0; i < 20 && current && current !== document.body && current !== document.documentElement; i++) {
514
392
  if (!current || !current.tagName) { current = current.parentElement; continue; }
515
393
  var tag = current.tagName.toLowerCase();
@@ -518,54 +396,40 @@ exports.injectedButtonAnimations = `
518
396
  var rect = current.getBoundingClientRect();
519
397
  if (rect.width < 20 || rect.height < 20) { current = current.parentElement; continue; }
520
398
 
521
- // DEBUG: Build trail for Screen 19
522
- var debugInfo = {
523
- depth: i,
524
- tag: tag,
525
- id: current.id || '(none)',
526
- class: (current.className && typeof current.className === 'string') ? current.className.substring(0, 100) : '(none)',
527
- size: rect.width + 'x' + rect.height
528
- };
529
- debugTrail.push(debugInfo);
530
-
531
399
  // Match standard interactive elements
532
- if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') {
533
- debugScreen19('MATCHED: standard tag', { reason: 'tag=' + tag, element: debugInfo, trail: debugTrail });
534
- return current;
535
- }
400
+ if (tag === 'button' || tag === 'a' || tag === 'input' || tag === 'select') return current;
536
401
 
537
- // Match elements with any data attribute containing action/navigate/tap/click
402
+ // Match elements with tap/click-related data attributes
403
+ // Exclude lifecycle attributes like data-on-open-actions, data-on-close-actions
538
404
  var attrs = current.attributes;
539
405
  if (attrs) {
540
406
  for (var j = 0; j < attrs.length; j++) {
541
407
  var attrName = attrs[j].name.toLowerCase();
408
+ // Skip lifecycle attributes (on-open, on-close, on-load, on-appear, etc.)
409
+ if (attrName.indexOf('on-open') !== -1 || attrName.indexOf('on-close') !== -1 ||
410
+ attrName.indexOf('on-load') !== -1 || attrName.indexOf('on-appear') !== -1 ||
411
+ attrName.indexOf('onopen') !== -1 || attrName.indexOf('onclose') !== -1 ||
412
+ attrName.indexOf('onload') !== -1 || attrName.indexOf('onappear') !== -1) {
413
+ continue;
414
+ }
415
+ // Match tap/click interaction attributes
542
416
  if (attrName.indexOf('click') !== -1 || attrName.indexOf('tap') !== -1 ||
543
417
  attrName.indexOf('action') !== -1 || attrName.indexOf('navigate') !== -1 ||
544
418
  attrName.indexOf('press') !== -1) {
545
- debugScreen19('MATCHED: data-attr', { reason: 'attr=' + attrName, value: attrs[j].value.substring(0,50), element: debugInfo, trail: debugTrail });
546
419
  return current;
547
420
  }
548
421
  }
549
422
  }
550
423
 
551
424
  // Match elements with onclick
552
- if (current.onclick || current.hasAttribute('onclick')) {
553
- debugScreen19('MATCHED: onclick', { element: debugInfo, trail: debugTrail });
554
- return current;
555
- }
425
+ if (current.onclick || current.hasAttribute('onclick')) return current;
556
426
 
557
- // Match elements with role="button" or tabindex
558
- if (current.getAttribute('role') === 'button') {
559
- debugScreen19('MATCHED: role=button', { element: debugInfo, trail: debugTrail });
560
- return current;
561
- }
427
+ // Match elements with role="button"
428
+ if (current.getAttribute('role') === 'button') return current;
562
429
 
563
430
  // Match any element with an ID containing button/btn/cta
564
431
  var id = current.id || '';
565
- if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) {
566
- debugScreen19('MATCHED: button-like ID', { reason: 'id=' + id, element: debugInfo, trail: debugTrail });
567
- return current;
568
- }
432
+ if (id && (id.toLowerCase().indexOf('button') !== -1 || id.toLowerCase().indexOf('btn') !== -1 || id.toLowerCase().indexOf('cta') !== -1)) return current;
569
433
 
570
434
  // Match elements with button-like classes
571
435
  var className = current.className;
@@ -573,7 +437,6 @@ exports.injectedButtonAnimations = `
573
437
  var cls = className.toLowerCase();
574
438
  if (cls.indexOf('btn') !== -1 || cls.indexOf('button') !== -1 || cls.indexOf('cta') !== -1 ||
575
439
  cls.indexOf('clickable') !== -1 || cls.indexOf('tappable') !== -1 || cls.indexOf('pressable') !== -1) {
576
- debugScreen19('MATCHED: button-like class', { reason: 'class=' + className, element: debugInfo, trail: debugTrail });
577
440
  return current;
578
441
  }
579
442
  }
@@ -581,18 +444,14 @@ exports.injectedButtonAnimations = `
581
444
  // Match elements with cursor pointer
582
445
  try {
583
446
  var computed = window.getComputedStyle(current);
584
- if (computed && computed.cursor === 'pointer') {
585
- debugScreen19('MATCHED: cursor:pointer', { element: debugInfo, trail: debugTrail });
586
- return current;
587
- }
447
+ if (computed && computed.cursor === 'pointer') return current;
588
448
  } catch(e) {}
589
449
 
590
450
  current = current.parentElement;
591
451
  }
592
- debugScreen19('NO MATCH found', { originalTag: el.tagName, trail: debugTrail });
593
452
  return null;
594
453
  }
595
-
454
+
596
455
  function applyPressedStyle(el) {
597
456
  if (!el || !el.style) return;
598
457
  // Save original styles
@@ -604,7 +463,7 @@ exports.injectedButtonAnimations = `
604
463
  el.style.transform = 'scale(0.97)';
605
464
  el.style.opacity = '0.8';
606
465
  }
607
-
466
+
608
467
  function applyReleasedStyle(el) {
609
468
  if (!el || !el.style) return;
610
469
  // Apply spring-back animation
@@ -612,53 +471,18 @@ exports.injectedButtonAnimations = `
612
471
  el.style.transform = pressedOriginalTransform || 'scale(1)';
613
472
  el.style.opacity = pressedOriginalOpacity || '1';
614
473
  }
615
-
474
+
616
475
  function resetStyle(el) {
617
476
  if (!el || !el.style) return;
618
477
  el.style.transform = pressedOriginalTransform;
619
478
  el.style.opacity = pressedOriginalOpacity;
620
479
  el.style.transition = pressedOriginalTransition;
621
480
  }
622
-
481
+
623
482
  function onTouchStart(e) {
624
483
  try {
625
- // ========== DEBUG: Screen 19 touch logging ==========
626
- if (isScreen19()) {
627
- var touchX = e.touches ? e.touches[0].clientX : e.clientX;
628
- var touchY = e.touches ? e.touches[0].clientY : e.clientY;
629
- var originalTarget = e.target;
630
- var originalRect = originalTarget.getBoundingClientRect ? originalTarget.getBoundingClientRect() : {};
631
- console.log('[SCREEN19-DEBUG][TouchStart] Touch at (' + touchX + ',' + touchY + ')', JSON.stringify({
632
- originalTarget: {
633
- tag: originalTarget.tagName,
634
- id: originalTarget.id || '(none)',
635
- class: (originalTarget.className && typeof originalTarget.className === 'string') ? originalTarget.className.substring(0,100) : '(none)',
636
- size: originalRect.width + 'x' + originalRect.height
637
- }
638
- }));
639
- }
640
- // ========== END DEBUG ==========
641
-
642
484
  var target = findInteractive(e.target);
643
485
  if (!target) return;
644
-
645
- // ========== DEBUG: Screen 19 - log what element was found interactive ==========
646
- if (isScreen19() && target) {
647
- var targetRect = target.getBoundingClientRect();
648
- var screenWidth = window.innerWidth;
649
- var screenHeight = window.innerHeight;
650
- var isFullScreen = (targetRect.width >= screenWidth * 0.9 && targetRect.height >= screenHeight * 0.9);
651
- console.log('[SCREEN19-DEBUG][TouchStart] INTERACTIVE ELEMENT FOUND', JSON.stringify({
652
- tag: target.tagName,
653
- id: target.id || '(none)',
654
- class: (target.className && typeof target.className === 'string') ? target.className.substring(0,100) : '(none)',
655
- size: targetRect.width + 'x' + targetRect.height,
656
- isFullScreen: isFullScreen,
657
- WARNING: isFullScreen ? 'FULL SCREEN ELEMENT DETECTED - THIS IS THE BUG!' : 'normal element'
658
- }));
659
- }
660
- // ========== END DEBUG ==========
661
-
662
486
  if (releaseTimer) { clearTimeout(releaseTimer); releaseTimer = null; }
663
487
  if (pressed && pressed !== target) { resetStyle(pressed); }
664
488
  applyPressedStyle(target);
@@ -2003,23 +1827,9 @@ function Overlay(props) {
2003
1827
  }
2004
1828
  }
2005
1829
  }, onMessage: (ev) => {
2006
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
1830
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
2007
1831
  const raw = ev.nativeEvent.data;
2008
1832
  console.log("raw", raw);
2009
- // ========== DEBUG: Screen 19 onMessage logging (REMOVE AFTER BUG FIX) ==========
2010
- const screenId = ((_a = props.screens[i]) === null || _a === void 0 ? void 0 : _a.id) || "";
2011
- const isScreen19OnMsg = screenId.indexOf('19') !== -1 ||
2012
- screenId.toLowerCase().indexOf('screen 19') !== -1 ||
2013
- screenId.toLowerCase().indexOf('screen19') !== -1 ||
2014
- i === 19 || i === 18;
2015
- if (isScreen19OnMsg) {
2016
- console.log(`[SCREEN19-DEBUG][onMessage] Received message from screen ${i} (ID: ${screenId})`, JSON.stringify({
2017
- rawPreview: raw.substring(0, 200),
2018
- isActiveScreen: i === activeScreenIndexRef.current,
2019
- activeScreenIndex: activeScreenIndexRef.current
2020
- }));
2021
- }
2022
- // ========== END DEBUG ==========
2023
1833
  // Accept either raw strings or JSON payloads from your editor
2024
1834
  try {
2025
1835
  // JSON path
@@ -2145,7 +1955,7 @@ function Overlay(props) {
2145
1955
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:onboarding-finished") {
2146
1956
  setOnboardingCompleted(true);
2147
1957
  try {
2148
- (_b = props.onOnboardingFinished) === null || _b === void 0 ? void 0 : _b.call(props, data === null || data === void 0 ? void 0 : data.payload);
1958
+ (_a = props.onOnboardingFinished) === null || _a === void 0 ? void 0 : _a.call(props, data === null || data === void 0 ? void 0 : data.payload);
2149
1959
  }
2150
1960
  catch (_) { }
2151
1961
  handleRequestClose({ completed: true });
@@ -2154,7 +1964,7 @@ function Overlay(props) {
2154
1964
  // 6) Request to show paywall
2155
1965
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:show-paywall") {
2156
1966
  try {
2157
- (_c = props.onShowPaywall) === null || _c === void 0 ? void 0 : _c.call(props, data === null || data === void 0 ? void 0 : data.payload);
1967
+ (_b = props.onShowPaywall) === null || _b === void 0 ? void 0 : _b.call(props, data === null || data === void 0 ? void 0 : data.payload);
2158
1968
  }
2159
1969
  catch (_) { }
2160
1970
  return;
@@ -2165,9 +1975,9 @@ function Overlay(props) {
2165
1975
  if (questionId) {
2166
1976
  const response = {
2167
1977
  questionId,
2168
- answer: (_d = data === null || data === void 0 ? void 0 : data.answer) !== null && _d !== void 0 ? _d : "",
1978
+ answer: (_c = data === null || data === void 0 ? void 0 : data.answer) !== null && _c !== void 0 ? _c : "",
2169
1979
  questionText: data === null || data === void 0 ? void 0 : data.questionText,
2170
- screenName: (_e = props.screens[i]) === null || _e === void 0 ? void 0 : _e.id,
1980
+ screenName: (_d = props.screens[i]) === null || _d === void 0 ? void 0 : _d.id,
2171
1981
  answeredAt: new Date().toISOString(),
2172
1982
  };
2173
1983
  OnboardingResponseStorage_1.OnboardingResponseStorage.saveResponse(response);
@@ -2182,14 +1992,6 @@ function Overlay(props) {
2182
1992
  console.log(`[RampKit] Ignoring continue from inactive screen ${i}`);
2183
1993
  return;
2184
1994
  }
2185
- // ========== DEBUG: Screen 19 continue logging ==========
2186
- if (isScreen19OnMsg) {
2187
- console.log(`[SCREEN19-DEBUG][onMessage] CONTINUE action triggered from screen ${i}`, JSON.stringify({
2188
- animation: (data === null || data === void 0 ? void 0 : data.animation) || "fade",
2189
- screenId: screenId
2190
- }));
2191
- }
2192
- // ========== END DEBUG ==========
2193
1995
  handleAdvance(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2194
1996
  return;
2195
1997
  }
@@ -2201,15 +2003,6 @@ function Overlay(props) {
2201
2003
  return;
2202
2004
  }
2203
2005
  const target = data === null || data === void 0 ? void 0 : data.targetScreenId;
2204
- // ========== DEBUG: Screen 19 navigate logging ==========
2205
- if (isScreen19OnMsg) {
2206
- console.log(`[SCREEN19-DEBUG][onMessage] NAVIGATE action triggered from screen ${i}`, JSON.stringify({
2207
- target: target,
2208
- animation: (data === null || data === void 0 ? void 0 : data.animation) || "fade",
2209
- screenId: screenId
2210
- }));
2211
- }
2212
- // ========== END DEBUG ==========
2213
2006
  if (target === "__goBack__") {
2214
2007
  handleGoBack(i, (data === null || data === void 0 ? void 0 : data.animation) || "fade");
2215
2008
  return;
@@ -2240,7 +2033,7 @@ function Overlay(props) {
2240
2033
  if ((data === null || data === void 0 ? void 0 : data.type) === "rampkit:close") {
2241
2034
  // Track close action for onboarding completion
2242
2035
  try {
2243
- (_f = props.onCloseAction) === null || _f === void 0 ? void 0 : _f.call(props, i, ((_g = props.screens[i]) === null || _g === void 0 ? void 0 : _g.id) || "");
2036
+ (_e = props.onCloseAction) === null || _e === void 0 ? void 0 : _e.call(props, i, ((_f = props.screens[i]) === null || _f === void 0 ? void 0 : _f.id) || "");
2244
2037
  }
2245
2038
  catch (_) { }
2246
2039
  handleRequestClose({ completed: true }); // Mark as completed so abandonment isn't tracked
@@ -2251,7 +2044,7 @@ function Overlay(props) {
2251
2044
  return;
2252
2045
  }
2253
2046
  }
2254
- catch (_m) {
2047
+ catch (_l) {
2255
2048
  // String path
2256
2049
  if (raw === "rampkit:tap" ||
2257
2050
  raw === "next" ||
@@ -2302,7 +2095,7 @@ function Overlay(props) {
2302
2095
  if (raw === "rampkit:onboarding-finished") {
2303
2096
  setOnboardingCompleted(true);
2304
2097
  try {
2305
- (_h = props.onOnboardingFinished) === null || _h === void 0 ? void 0 : _h.call(props, undefined);
2098
+ (_g = props.onOnboardingFinished) === null || _g === void 0 ? void 0 : _g.call(props, undefined);
2306
2099
  }
2307
2100
  catch (_) { }
2308
2101
  handleRequestClose({ completed: true });
@@ -2310,7 +2103,7 @@ function Overlay(props) {
2310
2103
  }
2311
2104
  if (raw === "rampkit:show-paywall") {
2312
2105
  try {
2313
- (_j = props.onShowPaywall) === null || _j === void 0 ? void 0 : _j.call(props);
2106
+ (_h = props.onShowPaywall) === null || _h === void 0 ? void 0 : _h.call(props);
2314
2107
  }
2315
2108
  catch (_) { }
2316
2109
  return;
@@ -2353,7 +2146,7 @@ function Overlay(props) {
2353
2146
  if (raw === "rampkit:close") {
2354
2147
  // Track close action for onboarding completion
2355
2148
  try {
2356
- (_k = props.onCloseAction) === null || _k === void 0 ? void 0 : _k.call(props, i, ((_l = props.screens[i]) === null || _l === void 0 ? void 0 : _l.id) || "");
2149
+ (_j = props.onCloseAction) === null || _j === void 0 ? void 0 : _j.call(props, i, ((_k = props.screens[i]) === null || _k === void 0 ? void 0 : _k.id) || "");
2357
2150
  }
2358
2151
  catch (_) { }
2359
2152
  handleRequestClose({ completed: true }); // Mark as completed so abandonment isn't tracked
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rampkit-expo-dev",
3
- "version": "0.0.82",
3
+ "version": "0.0.84",
4
4
  "description": "The Expo SDK for RampKit. Build, test, and personalize app onboardings with instant updates.",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",