revenge-plugins/key-inspector/install/index.js
2026-08-02 18:11:23 +00:00

32 lines
27 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(function(E,e,r,y,k,R,w,F){"use strict";const{ScrollView:A,View:_}=e.ReactNative;function O({children:t}){return e.React.createElement(A,{style:{flex:1}},t,e.React.createElement(_,{style:{height:24}}))}const{View:j,Text:I}=e.ReactNative;function D({children:t,style:i}){return e.React.createElement(j,{style:[{marginHorizontal:16,marginVertical:8,padding:10,borderRadius:8,borderWidth:1,borderColor:"rgba(128,128,128,0.25)"},i]},e.React.createElement(I,{style:{fontSize:12.5,lineHeight:18,opacity:.75}},t))}const{TouchableOpacity:z,Text:H}=e.ReactNative;function h({label:t,onPress:i,disabled:n,style:l}){return e.React.createElement(z,{disabled:n,onPress:i,style:[{backgroundColor:"#5865F2",borderRadius:8,padding:10,alignItems:"center",opacity:n?.5:1},l]},e.React.createElement(H,{style:{color:"white",fontWeight:"600"}},t))}function P(t){const i=window?.modules;if(i)for(const n in i){const l=i[n];if(!l?.isInitialized)continue;const a=l.publicModule?.exports;if(a)try{if(t(a))return a;if(a.default!=null&&t(a.default))return a.default}catch{}}}function $(t){return P(function(i){return i?.name===t||i?.displayName===t||i?.type?.name===t||i?.type?.displayName===t})}function m(t){return P(function(i){return i?.name===t||i?.displayName===t})}function T(...t){return P(function(i){return t.every(function(n){return i?.[n]!==void 0})})}function C(t){return P(function(i){return typeof i?.getName=="function"&&i.getName.length===0&&i.getName()===t})}const x=[{label:'findByProps("computePermissions", "canEveryoneRole")',run:function(){return r.findByProps("computePermissions","canEveryoneRole")}},{label:'findByProps("getBotLabel")',run:function(){return r.findByProps("getBotLabel")}},{label:'findByName("DisplayName", false)',run:function(){return r.findByName("DisplayName",!1)}},{label:'findByName("HeaderName", false)',run:function(){return r.findByName("HeaderName",!1)}},{label:'findByName("getTagProperties", false)',run:function(){return r.findByName("getTagProperties",!1)}},{label:'findByTypeNameAll("UserRow")',run:function(){return r.findByTypeNameAll("UserRow")}},{label:'findByStoreName("ThemeStore")',run:function(){return r.findByStoreName("ThemeStore")}},{label:'findByStoreName("GuildMemberStore")',run:function(){return r.findByStoreName("GuildMemberStore")}},{label:'findByStoreName("GuildStore")',run:function(){return r.findByStoreName("GuildStore")}},{label:'findByStoreName("ChannelStore")',run:function(){return r.findByStoreName("ChannelStore")}},{label:'findByStoreName("UserStore")',run:function(){return r.findByStoreName("UserStore")}},{label:'findByStoreName("RelationshipStore")',run:function(){return r.findByStoreName("RelationshipStore")}},{label:'findByName("RowManager", false)',run:function(){return r.findByName("RowManager",!1)}},{label:'findByProps("TYPING_WRAPPER_HEIGHT")',run:function(){return r.findByProps("TYPING_WRAPPER_HEIGHT")}},{label:'findByName("VoiceUserConnected", false)',run:function(){return r.findByName("VoiceUserConnected",!1)}},{label:"find(resolveSemanticColor via default.internal)",run:function(){return r.find(function(t){return t?.default?.internal?.resolveSemanticColor})}},{label:"find(resolveSemanticColor via meta)",run:function(){return r.find(function(t){return t?.meta?.resolveSemanticColor})}},{label:"find(UserProfileContent)",run:function(){return r.find(function(t){return t?.type?.name==="UserProfileContent"})}},{label:"find(UserProfile)",run:function(){return r.find(function(t){return t?.type?.name==="UserProfile"})}},{label:'findByName("UserProfileSection", false)',run:function(){return r.findByName("UserProfileSection",!1)}},{label:'findByProps("sendMessage", "sendBotMessage")',run:function(){return r.findByProps("sendMessage","sendBotMessage")}},{label:'findByProps("sendBotMessage") (single prop, matches Revenge core)',run:function(){return r.findByProps("sendBotMessage")}},{label:'findByProps("openLazy", "hideActionSheet")',run:function(){return r.findByProps("openLazy","hideActionSheet")}},{label:'findByProps("push", "pushLazy", "pop")',run:function(){return r.findByProps("push","pushLazy","pop")}},{label:'findByProps("getRenderCloseButton")',run:function(){return r.findByProps("getRenderCloseButton")}},{label:'findByProps("getHeaderCloseButton")',run:function(){return r.findByProps("getHeaderCloseButton")}},{label:'findByName("Navigator")',run:function(){return r.findByName("Navigator")}},{label:'findByName("ThemedRolePill", false)',run:function(){return r.findByName("ThemedRolePill",!1)}},{label:'findByName("RolePill", false)',run:function(){return r.findByName("RolePill",!1)}},{label:'findByProps("saveProfileChanges")',run:function(){return r.findByProps("saveProfileChanges")}},{label:'findByProps("useAvatarColors")',run:function(){return r.findByProps("useAvatarColors")}},{label:'findByProps("useThemeContext")',run:function(){return r.findByProps("useThemeContext")}},{label:'findByProps("getProfileTheme")',run:function(){return r.findByProps("getProfileTheme")}},{label:'findByProps("ThemeContextProvider")',run:function(){return r.findByProps("ThemeContextProvider")}},{label:'findByName("ProfileEffectRecord", false)',run:function(){return r.findByName("ProfileEffectRecord",!1)}},{label:'findByStoreName("UserProfileStore")',run:function(){return r.findByStoreName("UserProfileStore")}},{label:'findByStoreName("CollectiblesPurchaseStore")',run:function(){return r.findByStoreName("CollectiblesPurchaseStore")}},{label:'findByStoreName("ProfileEffectStore")',run:function(){return r.findByStoreName("ProfileEffectStore")}},{label:'findByName("GuildProfileEditForm", false) (currently dead/unused patch)',run:function(){return r.findByName("GuildProfileEditForm",!1)}},{label:'findByName("UserProfileEditForm", false)',run:function(){return r.findByName("UserProfileEditForm",!1)}},{label:'findByName("useProfileTheme", false)',run:function(){return r.findByName("useProfileTheme",!1)}},{label:'findByName("useProfileThemeColors", false)',run:function(){return r.findByName("useProfileThemeColors",!1)}},{label:'findByPropsAll("NONE_ITEM")',run:function(){return r.findByPropsAll("NONE_ITEM")}},{label:'findByProps("Radius")',run:function(){return r.findByProps("Radius")}},{label:'findByProps("Spacing")',run:function(){return r.findByProps("Spacing")}},{label:'findByProps("SafeAreaContext")',run:function(){return r.findByProps("SafeAreaContext")}},{label:'findByName("useWindowDimensions")',run:function(){return r.findByName("useWindowDimensions")}},{label:'findByProps("IconSizes")',run:function(){return r.findByProps("IconSizes")}},{label:'findByName("FlashList")',run:function(){return r.findByName("FlashList")}},{label:'findByProps("Svg")',run:function(){return r.findByProps("Svg")}},{label:'findByProps("PressableOpacity")',run:function(){return r.findByProps("PressableOpacity")}},{label:'findByProps("TextStyleSheet")',run:function(){return r.findByProps("TextStyleSheet")}},{label:'findByProps("BottomSheet")',run:function(){return r.findByProps("BottomSheet")}},{label:'findByProps("ActionSheet")',run:function(){return r.findByProps("ActionSheet")}},{label:'findByProps("BottomSheetScrollView")',run:function(){return r.findByProps("BottomSheetScrollView")}},{label:'findByProps("showActionSheet")',run:function(){return r.findByProps("showActionSheet")}},{label:'findByName("EditProfileEffectActionSheet")',run:function(){return r.findByName("EditProfileEffectActionSheet")}},{label:'findByName("showCustomColorPickerActionSheet")',run:function(){return r.findByName("showCustomColorPickerActionSheet")}},{label:'findByProps("triggerHapticFeedback")',run:function(){return r.findByProps("triggerHapticFeedback")}},{label:"semanticColors.HEADER_SECONDARY",run:function(){return R.semanticColors?.HEADER_SECONDARY}},{label:"semanticColors.BACKGROUND_ACCENT",run:function(){return R.semanticColors?.BACKGROUND_ACCENT}},{label:"semanticColors.BACKGROUND_PRIMARY",run:function(){return R.semanticColors?.BACKGROUND_PRIMARY}},{label:"semanticColors.BACKGROUND_FLOATING",run:function(){return R.semanticColors?.BACKGROUND_FLOATING}},{label:"semanticColors.BUTTON_OUTLINE_BRAND_BORDER_ACTIVE",run:function(){return R.semanticColors?.BUTTON_OUTLINE_BRAND_BORDER_ACTIVE}},{label:"semanticColors.TEXT_NORMAL",run:function(){return R.semanticColors?.TEXT_NORMAL}}];function M(t){if(t==null)return"NOT FOUND";if(typeof t=="object"){const i=Object.keys(t);return`found (${i.length} key${i.length===1?"":"s"})`}return`found (${typeof t})`}function U(){return x.map(function({label:t,run:i}){try{const n=i();return{label:t,found:n!=null,detail:M(n)}}catch(n){return{label:t,found:!1,detail:`threw: ${n}`}}})}function V(t){const i=t.filter(function(n){return!n.found});return[`Key Inspector report - ${new Date().toISOString()}`,`${t.length} checked, ${i.length} missing`,"",...t.map(function(n){return`[${n.found?"OK":"MISSING"}] ${n.label} -> ${n.detail}`}),"",`semanticColors keys (${Object.keys(R.semanticColors??{}).length}):`,...Object.keys(R.semanticColors??{}).sort(),"",`rawColors keys (${Object.keys(R.rawColors??{}).length}):`,...Object.keys(R.rawColors??{}).sort()].join(`
`)}const G=new Set(["vendetta.metro.modules"]);function L(t){return t===null?"null":t===void 0?"undefined":Array.isArray(t)?`array(${t.length})`:typeof t}function W(t=3){const i=new WeakSet,n=[];function l(a,c,u){if(a==null||typeof a!="object"&&typeof a!="function")return;if(G.has(c)){n.push(`${c} -> (skipped - Discord's full module registry, use the search tools for this)`);return}if(typeof a=="object"){if(i.has(a)){n.push(`${c} -> [already listed elsewhere, circular]`);return}i.add(a)}let d;try{d=Object.keys(a).sort()}catch(o){n.push(`${c} -> [couldn't read keys: ${o}]`);return}const s=d.slice(0,60);for(const o of s){const f=`${c}.${o}`;let p;try{p=a[o]}catch(v){n.push(`${f} -> [threw on access: ${v}]`);continue}const B=L(p);n.push(`${f} (${B})`),B==="object"&&u<t&&l(p,f,u+1)}d.length>60&&n.push(`${c} -> (+${d.length-60} more keys not shown at this level)`)}try{l(globalThis.vendetta,"vendetta",0)}catch(a){n.push(`Error walking the vendetta object: ${a}`)}return n.length?n.join(`
`):"vendetta object not found or empty"}function Y(t){if(t===void 0)return"undefined";if(t===null)return"null";if(typeof t=="function")return`[Function: ${t.name||"anonymous"}]`;if(typeof t!="object")return String(t);const i=new WeakSet;try{return JSON.stringify(t,function(n,l){if(typeof l=="function")return`[Function: ${l.name||"anonymous"}]`;if(typeof l=="symbol")return l.toString();if(typeof l=="object"&&l!==null){if(i.has(l))return"[Circular]";i.add(l)}return l},2)}catch{try{return`[unserializable object, keys: ${Object.keys(t).join(", ")}]`}catch(n){return`[unserializable, and Object.keys threw: ${n}]`}}}function K(t){return t.replace(/[‘’]/g,"'").replace(/[“”]/g,'"').replace(/[–—]/g,"-")}async function q(t){const i=K(t);try{const n=new Function("findByProps","findByName","findByTypeName","findByStoreName","findByPropsAll","findByNameAll","find","rawFind","rawFindByTypeName","rawFindByProps","rawFindByName","rawFindByStoreName","instead","before","after","getAssetIDByName","showToast","React","ReactNative","FluxDispatcher","window",`return (function() {
${i}
})();`)(r.findByProps,r.findByName,r.findByTypeName,r.findByStoreName,r.findByPropsAll,r.findByNameAll,r.find,P,$,T,m,C,w.instead,w.before,w.after,F.getAssetIDByName,y.showToast,e.React,e.ReactNative,e.FluxDispatcher,window),l=n&&typeof n.then=="function"?await n:n;return Y(l)}catch(n){return`Error: ${n instanceof Error?`${n.message}
${n.stack??""}`:String(n)}`}}const J=500;function X(t,i){return new Promise(function(n){const l=new Map;let a=function(){},c=!1;const u=function(){if(c)return;c=!0,a();const d=i?.trim(),s=[...l.entries()].sort(function(o,f){return f[1]-o[1]}).map(function([o,f]){return`${String(f).padStart(5)} ${o}`});n(s.length?`${l.size} distinct type(s)${d?` matching "${d}"`:""} over ${t}ms:
${s.join(`
`)}`:`(no${d?` matching "${d}"`:""} events fired during the ${t}ms capture window)`)};try{a=w.before("dispatch",e.FluxDispatcher,function(d){const s=d[0]?.type??"(no type)",o=i?.trim();o&&!s.includes(o)||!l.has(s)&&l.size>=J||l.set(s,(l.get(s)??0)+1)})}catch(d){n(`Failed to patch FluxDispatcher.dispatch: ${d}`);return}setTimeout(u,t)})}function Q(t){try{return JSON.stringify(t,function(i,n){return typeof n=="function"?`[Function: ${n.name||"anonymous"}]`:n},2)}catch{try{return`[unserializable, keys: ${Object.keys(t??{}).join(", ")}]`}catch{return String(t)}}}function Z(t,i,n){return new Promise(function(l){const a=t.trim(),c=r.findByTypeName(a)??r.findByName(a,!1);if(!c){l(`"${a}" not found via findByTypeName or findByName.`);return}if(typeof c.type!="function"){l(`Found "${a}", but it has no callable .type property (not a memo/forwardRef wrapper), so its own render calls can't be intercepted this way. Its keys: ${Object.keys(c).join(", ")}`);return}const u=[];let d=!1,s=function(){};const o=function(){d||(d=!0,s(),l(u.length?u.join(`
---
`):`"${a}" never rendered during the ${n}ms capture window.`))};try{s=w.before("type",c,function(f){u.push(`Call ${u.length+1} props:
${Q(f[0])}`),u.length>=i&&o()})}catch(f){l(`Failed to patch "${a}": ${f}`);return}setTimeout(o,n)})}const{View:N,Text:g}=e.ReactNative,{FormSection:S,FormInput:b}=k.Forms;function ee(){const[t,i]=e.React.useState(null);return e.React.createElement(S,{title:"Full diagnostic scan"},e.React.createElement(N,{style:{paddingHorizontal:16,paddingVertical:8}},e.React.createElement(h,{label:"Run scan & copy full report",onPress:function(){const n=U(),l=n.filter(function(a){return!a.found}).length;e.clipboard.setString(V(n)),i(`${n.length} checked, ${l} missing - full report copied`),y.showToast(`${l} missing out of ${n.length} - report copied`,void 0)}}),t&&e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.7}},t)))}function te(){const[t,i]=e.React.useState(""),[n,l]=e.React.useState(null),[a,c]=e.React.useState(!1),u=async function(){if(!(!t.trim()||a)){c(!0);try{const d=await q(t);l(d),e.clipboard.setString(d),y.showToast("Result copied",void 0)}finally{c(!1)}}};return e.React.createElement(S,{title:"Eval"},e.React.createElement(N,{style:{paddingHorizontal:16,paddingVertical:8}},e.React.createElement(b,{title:"Code",placeholder:'e.g. return findByProps("getRootNavigationRef")',value:t,onChange:i,multiline:!0,autoCorrect:!1,autoCapitalize:"none",spellCheck:!1}),e.React.createElement(h,{label:a?"Running...":"Run & copy result",style:{marginTop:8},disabled:a,onPress:u}),n!=null&&e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.85},selectable:!0},n.length>2e3?`${n.slice(0,2e3)}
... (truncated, full result copied)`:n),e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.7}},"Runs as a plain (non-async) function body - a bare expression or `return ...` works, but not the async/await keywords (Hermes doesn't support those in dynamically-eval'd code). For timed/async checks, return a Promise built with a plain function instead of an arrow/async function - it gets awaited for you outside the sandbox. In scope: findByProps/findByName/ findByTypeName/findByStoreName/findByPropsAll/findByNameAll/find, the raw* passive variants (rawFind/rawFindByTypeName/rawFindByProps/rawFindByName/ rawFindByStoreName), instead/before/after, getAssetIDByName, showToast, React, ReactNative, FluxDispatcher, and window. Nothing runs until you tap the button.")))}function ne(){const[t,i]=e.React.useState(""),[n,l]=e.React.useState("10"),[a,c]=e.React.useState(null),[u,d]=e.React.useState(!1),s=async function(){if(u)return;const o=Math.max(1,Number(n)||10)*1e3;d(!0),c(null),y.showToast(`Capturing Flux events for ${o/1e3}s - go do the thing...`,void 0);try{const f=await X(o,t);c(f),e.clipboard.setString(f),y.showToast("Capture done - report copied",void 0)}finally{d(!1)}};return e.React.createElement(S,{title:"Flux event logger"},e.React.createElement(N,{style:{paddingHorizontal:16,paddingVertical:8}},e.React.createElement(b,{title:"Filter (optional substring, e.g. GUILD)",placeholder:"Leave blank to capture everything",value:t,onChange:i}),e.React.createElement(b,{title:"Capture duration (seconds)",placeholder:"10",value:n,onChange:l,keyboardType:"numeric"}),e.React.createElement(h,{label:u?"Capturing...":"Start capture",style:{marginTop:8},disabled:u,onPress:s}),a!=null&&e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.85},selectable:!0},a.length>2e3?`${a.slice(0,2e3)}
... (truncated, full report copied)`:a),e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.7}},"Tap start, then go do the thing you're trying to understand (open a screen, send a message, tap a button) before the window closes. Reports every action type that dispatched, sorted by count - the fastest way to find which event to hook into instead of guessing from decompiled source.")))}function re(){const[t,i]=e.React.useState(""),[n,l]=e.React.useState("3"),[a,c]=e.React.useState("15"),[u,d]=e.React.useState(null),[s,o]=e.React.useState(!1),f=async function(){const p=t.trim();if(!p||s)return;const B=Math.max(1,Number(a)||15)*1e3;o(!0),d(null);try{const v=await Z(p,Math.max(1,Number(n)||3),B);d(v),e.clipboard.setString(v),y.showToast("Capture done - result copied",void 0)}finally{o(!1)}};return e.React.createElement(S,{title:"Component render/props logger"},e.React.createElement(N,{style:{paddingHorizontal:16,paddingVertical:8}},e.React.createElement(b,{title:"Component name (findByTypeName / findByName)",placeholder:"e.g. YouBarNotificationsButton",value:t,onChange:i}),e.React.createElement(b,{title:"Max renders to capture",placeholder:"3",value:n,onChange:l,keyboardType:"numeric"}),e.React.createElement(b,{title:"Give up after (seconds)",placeholder:"15",value:a,onChange:c,keyboardType:"numeric"}),e.React.createElement(h,{label:s?"Waiting for renders...":"Start capture",style:{marginTop:8},disabled:s,onPress:f}),u!=null&&e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.85},selectable:!0},u.length>2e3?`${u.slice(0,2e3)}
... (truncated, full result copied)`:u),e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.7}},"Patches the component to log its actual props on every render, up to the call cap or the time limit. Only works for React.memo/forwardRef-wrapped components (most of what findByTypeName/findByName return) - a bare function component has no property to intercept its own calls through.")))}function ae(){const[t,i]=e.React.useState(""),[n,l]=e.React.useState(""),[a,c]=e.React.useState(""),[u,d]=e.React.useState(""),s=function(o,f){try{const p=f();if(!p){e.clipboard.setString(`${o} -> not found`),y.showToast("Not found - copied that result",void 0);return}const B=Object.keys(p).sort();e.clipboard.setString(`${o} -> found, keys:
${B.join(`
`)}`),y.showToast(`Found it - copied ${B.length} key(s)`,void 0)}catch(p){e.clipboard.setString(`Error running ${o}: ${p}`),y.showToast("Search failed - copied the error instead",void 0)}};return e.React.createElement(S,{title:"Raw search (bypasses the negative-result cache)"},e.React.createElement(N,{style:{paddingHorizontal:16,paddingVertical:8}},e.React.createElement(b,{title:"rawFindByProps - comma-separated prop names",placeholder:"e.g. getRootNavigationRef",value:t,onChange:i}),e.React.createElement(h,{label:"Search & copy result",style:{marginTop:8,marginBottom:16},onPress:function(){const o=t.split(",").map(function(f){return f.trim()}).filter(Boolean);o.length&&s(`rawFindByProps(${o.join(", ")})`,function(){return T(...o)})}}),e.React.createElement(b,{title:"rawFindByName",placeholder:"e.g. YouBarNotificationsButton",value:n,onChange:l}),e.React.createElement(h,{label:"Search & copy result",style:{marginTop:8,marginBottom:16},onPress:function(){return n.trim()&&s(`rawFindByName("${n.trim()}")`,function(){return m(n.trim())})}}),e.React.createElement(b,{title:"rawFindByTypeName",placeholder:"e.g. YouBarNotificationsButton",value:a,onChange:c}),e.React.createElement(h,{label:"Search & copy result",style:{marginTop:8,marginBottom:16},onPress:function(){return a.trim()&&s(`rawFindByTypeName("${a.trim()}")`,function(){return $(a.trim())})}}),e.React.createElement(b,{title:"rawFindByStoreName",placeholder:"e.g. GuildStore",value:u,onChange:d}),e.React.createElement(h,{label:"Search & copy result",style:{marginTop:8},onPress:function(){return u.trim()&&s(`rawFindByStoreName("${u.trim()}")`,function(){return C(u.trim())})}}),e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.7}},`Revenge's own findByProps/findByName/findByTypeName/findByStoreName cache a negative result forever the first time a search comes up empty, and never rescan - so if a module hasn't been required yet when you search, it can look "missing" permanently for the rest of the session even after it registers. These raw* variants only ever read modules Metro's own isInitialized flag says are already loaded (never force-requiring anything), so re-running one after doing the thing that loads your target module will actually find it.`)))}function ie(){const[t,i]=e.React.useState("Not captured yet - scroll this section into view (or reopen this screen) to trigger the ref."),n=function(l){if(l)try{let a=null,c="";if(l._internalFiberInstanceHandleDEV)a=l._internalFiberInstanceHandleDEV,c="_internalFiberInstanceHandleDEV";else if(l._internalInstanceHandle)a=l._internalInstanceHandle,c="_internalInstanceHandle";else if(l.__internalInstanceHandle)a=l.__internalInstanceHandle,c="__internalInstanceHandle";else{const s=Object.keys(l).find(function(o){return o.startsWith("__reactFiber$")||o.startsWith("__reactInternalInstance$")});s&&(a=l[s],c=s)}if(!a){i(`No fiber pointer found on the instance. Instance keys: ${Object.keys(l).join(", ")||"(none)"}`);return}if(a.return===void 0&&a.child===void 0){const s=a.stateNode??a.fiber??a._debugOwner;if(s&&(s.return!==void 0||s.child!==void 0))a=s,c+=" (via nested property)";else{i(`Found "${c}" but it doesn't look fiber-shaped (no .return/.child). Its keys: ${Object.keys(a).join(", ")||"(none)"}`);return}}let u=a,d=0;for(;u.return&&d<5e3;)u=u.return,d++;window.__keyInspectorFiberRoot=u,window.__keyInspectorFiberSelf=a,i(`Captured via "${c}" (walked up ${d} level(s) to the root). window.__keyInspectorFiberRoot and window.__keyInspectorFiberSelf are now set - use Eval to walk them.`)}catch(a){i(`Error: ${a}`)}};return e.React.createElement(S,{title:"Fiber capture (for Eval)"},e.React.createElement(N,{style:{paddingHorizontal:16,paddingVertical:8}},e.React.createElement(N,{ref:n,style:{width:1,height:1}}),e.React.createElement(g,{style:{fontSize:12.5,opacity:.85},selectable:!0},t),e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.7}},"Reads React's own internal fiber pointer directly off a native view instance - works without React DevTools (confirmed absent on this build), since it's the same internal linkage React itself relies on to route touch events, not an inspector-only feature. Walks up to the root fiber automatically so Eval can search the whole live tree (whatever's actually mounted right now, not module-registry guessing) from window.__keyInspectorFiberRoot afterward.")))}function oe(){return e.React.createElement(S,{title:"Full Vendetta API tree"},e.React.createElement(N,{style:{paddingHorizontal:16,paddingVertical:8}},e.React.createElement(h,{label:"Copy the entire plugin API tree",onPress:function(){const t=W(3),i=t.split(`
`).length;e.clipboard.setString(t),y.showToast(`Copied ${i} lines - every key path under window.vendetta`,void 0)}}),e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.7}},"Every key path under the stable plugin API (window.vendetta), 3 levels deep - this is everything Revenge itself exposes to plugins, not Discord's raw internals (those are searchable individually below, since dumping all of them would be enormous).")))}function le(){const[t,i]=e.React.useState(""),[n,l]=e.React.useState(""),a=function(){const s=t.split(",").map(function(o){return o.trim()}).filter(Boolean);if(s.length)try{const o=r.findByProps(...s);if(!o){e.clipboard.setString(`findByProps(${s.join(", ")}) -> not found`),y.showToast("No module found - copied that result",void 0);return}const f=Object.keys(o).sort();e.clipboard.setString(`findByProps(${s.join(", ")}) -> found, keys:
${f.join(`
`)}`),y.showToast(`Found it - copied ${f.length} key(s)`,void 0)}catch(o){e.clipboard.setString(`Error searching for ${s.join(", ")}: ${o}`),y.showToast("Search failed - copied the error instead",void 0)}},c=function(){const s=n.trim();if(s)try{const o=r.findByName(s,!1);if(!o){e.clipboard.setString(`findByName("${s}") -> not found`),y.showToast("No component found - copied that result",void 0);return}const f=Object.keys(o).sort();e.clipboard.setString(`findByName("${s}") -> found, keys:
${f.join(`
`)}`),y.showToast(`Found it - copied ${f.length} key(s)`,void 0)}catch(o){e.clipboard.setString(`Error searching for "${s}": ${o}`),y.showToast("Search failed - copied the error instead",void 0)}},u=function(){const s=t.split(",").map(function(o){return o.trim()}).filter(Boolean);if(s.length)try{const o=r.findByPropsAll(...s)??[],f=o.map(function(p,B){return`[${B}] keys: ${Object.keys(p).sort().join(", ")}`}).join(`
`);e.clipboard.setString(`findByPropsAll(${s.join(", ")}) -> ${o.length} match(es)
${f}`),y.showToast(`${o.length} match(es) - report copied`,void 0)}catch(o){e.clipboard.setString(`Error searching for ${s.join(", ")}: ${o}`),y.showToast("Search failed - copied the error instead",void 0)}},d=function(){const s=n.trim();if(s)try{const o=r.findByNameAll(s,!1)??[],f=o.map(function(p,B){return`[${B}] keys: ${Object.keys(p).sort().join(", ")}`}).join(`
`);e.clipboard.setString(`findByNameAll("${s}") -> ${o.length} match(es)
${f}`),y.showToast(`${o.length} match(es) - report copied`,void 0)}catch(o){e.clipboard.setString(`Error searching for "${s}": ${o}`),y.showToast("Search failed - copied the error instead",void 0)}};return e.React.createElement(S,{title:"One-off search"},e.React.createElement(N,{style:{paddingHorizontal:16,paddingVertical:8}},e.React.createElement(b,{title:"findByProps - comma-separated prop names",placeholder:"e.g. sendMessage, sendBotMessage",value:t,onChange:i}),e.React.createElement(h,{label:"Search first match & copy",style:{marginTop:8},onPress:a}),e.React.createElement(h,{label:"Search ALL matches & copy",style:{marginTop:8,marginBottom:16},onPress:u}),e.React.createElement(b,{title:"findByName - component name",placeholder:"e.g. ThemedRolePill",value:n,onChange:l}),e.React.createElement(h,{label:"Search first match & copy",style:{marginTop:8},onPress:c}),e.React.createElement(h,{label:"Search ALL matches & copy",style:{marginTop:8},onPress:d}),e.React.createElement(g,{style:{marginTop:8,fontSize:12.5,opacity:.7}},'"ALL matches" is worth checking even when the first-match search succeeds - more than one module matching the same name/props is a common source of "found the wrong one" bugs (patching a re-export or an unrelated duplicate instead of the component actually on screen).')))}function se(){return e.React.createElement(O,null,e.React.createElement(ee,null),e.React.createElement(ie,null),e.React.createElement(ae,null),e.React.createElement(le,null),e.React.createElement(ne,null),e.React.createElement(re,null),e.React.createElement(te,null),e.React.createElement(oe,null),e.React.createElement(D,null,"The full scan checks every internal lookup this repo's plugins depend on (plus a few for plugins currently being fixed) in one pass, and includes the complete list of semanticColors/rawColors keys at the end. Paste the report back into chat when reporting a bug - it tells us exactly what's missing on your Discord version."))}var ce={settings:se};return E.default=ce,Object.defineProperty(E,"__esModule",{value:!0}),E})({},vendetta.metro.common,vendetta.metro,vendetta.ui.toasts,vendetta.ui.components,vendetta.ui,vendetta.patcher,vendetta.ui.assets);