[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M7DF8GD6CZ402WWG4ASPYJDW":3,"skill-same:01M7DF8GD6CZ402WWG4ASPYJDW":921},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":19,"linkOnly":20,"markdownContent":21,"markdownBody":22,"frontMatter":23,"refName":24,"commitSha":25,"skillDirectory":26,"forksCount":14,"repositoryHtmlUrl":27,"repositoryHomepageUrl":6,"ownerHtmlUrl":28,"ownerBlogUrl":29,"ownerDescription":30,"updatedAt":31,"install":32,"resources":45},"01M7DF8GD6CZ402WWG4ASPYJDW","premium-purchase",null,"Builds and checks each game's one Premium purchase - expo-iap behind PurchasePort, S12 state reducer, save-before-finish, pending, restore, refund revocation, store price, StoreKit harness, App Store and Play products. Use when touching IAP, buy, restore or Premium state. Not for ads (admob-ads).","zakariaf\u002Fpocket-arcade","zakariaf","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F2259803?v=4","01M7DEF0YMPS6Y6RQ4WGA0JH9R","Zakaria Fatahi","01M7DEF0ZN5WYWJT595FWW1A0Y",0,"MIT","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002FSKILL.md",[],[],"2026-11-15 14:19:17",false,"---\nname: premium-purchase\ndescription: Builds and checks each game's one Premium purchase - expo-iap behind PurchasePort, S12 state reducer, save-before-finish, pending, restore, refund revocation, store price, StoreKit harness, App Store and Play products. Use when touching IAP, buy, restore or Premium state. Not for ads (admob-ads).\n---\n\n# Premium purchase\n\nMakes each game sell its single non-consumable \"Premium\" honestly and with no server: StoreKit 2 verifies on the phone, Premium is saved before a transaction is finished, only explicit evidence ever revokes it, every S12 state is reachable and tested, and two scripts prove it on the real code.\n\n## Rules that must hold\n\n1. **Save Premium before finishing: `persistPremium({ isPremium: true })` (synchronous) -> dispatch `premium-granted` -> `finish(tx)`.** Never finish first, never auto-finish, and never finish when `persistPremium` returns `false` (the change did not reach the disk: `save.update` answered `false` for a refused write, a rejected document, a pending quarantine copy or a newer app's read-only save). On Android `finishTransaction({ purchase, isConsumable: false })` is the acknowledge, called only from the port's `finish()` and never with `isConsumable: true` (that consumes Premium); an unacknowledged purchase is never delivered again and Google refunds it after 3 days, so `recheckPremium` and `restorePremium` finish every owned transaction marked `isUnfinished` (the adapter's `isAcknowledgedAndroid === false`) once `persistPremium` returned `true`. *Why:* StoreKit re-delivers unfinished transactions; a finished-but-unsaved purchase is lost for good, and an unacknowledged Android one is refunded.\n2. **Revoke only on explicit evidence:** a verified Premium transaction with a revocation date and no newer valid one. Absence, errors and offline keep the cached Premium; a revocation is saved with its `revokedAtMs`. On Android a refund leaves no dated proof on the phone (it only vanishes from the query), so absence never revokes there (owner default a). *Why:* a fresh purchase can be briefly missing from StoreKit, and the save guard ignores a revoke without a date.\n3. **Listen first:** `startPremium` subscribes to purchase events before `initConnection`, then loads the price, then re-checks silently (`Transaction.all`, `onlyIncludeActiveItemsIOS: false`). *Why:* StoreKit replays unfinished and approved Ask-to-Buy transactions right after connecting, and only `Transaction.all` shows refunds.\n4. **Every handler is idempotent;** a failure counts only while a purchase is in flight. *Why:* iOS reports one failure twice (rejection and listener) and re-delivers owned purchases on relaunch.\n5. **Restore distinguishes \"couldn't restore\" from \"nothing to restore\":** a failed sync (cancelled Apple Account prompt, offline) is always `restore-failed`; `restore-empty` only after a successful sync with no evidence. On Android `restorePurchases` is the Play query itself: billing unavailable, no Play Store or offline is `restore-failed`, never a query error swallowed into `[]`. *Why:* telling a paying player \"no purchase found\" because the network failed is the worst answer.\n6. **`expo-iap` is exactly 5.8.0, imported only by `expo-iap-purchase-adapter.ts`, and its plugin entry is the bare string `'expo-iap'`.** On Android it runs Play Billing 9.1.0 and needs `['expo-build-properties', { android: { kotlinVersion: '2.1.20' } }]` in the same plugin list; the adapter keeps `state: purchase.purchaseState`, so a pending Play purchase is never granted or acknowledged. Never `kitApi`, `KitApiError`, `verifyPurchaseWithProvider`, `verifyPurchase`, `useIAP`, `andDangerouslyFinishTransactionAutomatically`, any plugin option, `ios.onside.enabled` or `EXPO_IAP_ONSIDE`. *Why:* they add a server (IAPKit) or the OnsideKit pod (spec N2\u002FN3), or hide the finishing logic.\n7. **One product per game: `\u003CbundleId>.premium` (`io.applander.\u003Cgame id without hyphens>.premium`, owner decision O4), NON_CONSUMABLE, the EUR 1.99 App Store price point (O2), `familySharable: false` (O3: Family Sharing stays off, never turned on).** Every StoreKit configuration (the template and each generated `*.storekit`) and the ASC payload say `false`; `create-premium-iap.ts` targets exactly 1.99. On Google Play the same id is a one-time (managed) product at a EUR 1.99 default price with Google's local prices (owner step GP6, after the first internal upload). *Why:* spec N7; the owner decided the price and Family Sharing on 2026-09-30; product IDs can never be reused, and Family Sharing cannot be turned off once on.\n8. **An empty product list, a failed connection or being offline is \"store unavailable\", never an error dialog;** the port is `withConnectivity(createExpoIapPurchaseAdapter(), connectivity.isOnline)`, and a connectivity change reloads the store when `shouldReloadStore` says so. Apple's error texts are never shown. *Why:* StoreKit returns `[]` instead of throwing; S12 has its own catalog messages; and the debug \"Simulate offline\" switch (Tier 2 flow 07) only reaches the store through ConnectivityPort.\n9. **Show the price the store reports, in the player's digits (`formatStorePrice`, fallback `displayPrice`).** Never type a price into code or catalogs; catalogs use `{priceText}`. The EUR 1.99 point is what App Store Connect sells in Germany; players elsewhere see their own territory's price. *Why:* spec S12 and Apple's per-territory price points.\n10. **Every S12 state is designed and tested:** reducer tests for each (Tier 1), the StoreKit harness before each release and after every expo-iap upgrade (Tier 2), and the owner's TestFlight run per game (Tier 3). *Why:* spec S12\u002F15.5; the real purchase sheet only exists on TestFlight.\n11. **All S12 text comes from the Shell catalogs in en, de, fa and ckb.** *Why:* App Store Connect has no Persian or Sorani, and its texts are never shown in the app.\n12. **The StoreKit harness exists only in throwaway harness builds;** `get-task-allow`, `*.storekit` and `*.xctest` never ship. *Why:* `get-task-allow` in a store build is a security hole and a rejection.\n13. **Premium changes only through the reducer, after the save:** purchases, restores and re-checks via the service; the test build's debug switch (`premium=0|1`) via `debug-premium-set`, only from test-only code. *Why:* one path keeps ads, the save and S12 in step, and a stray unlock would give Premium away.\n14. **Premium is never pushed with pop-ups:** Home button (hidden once owned), Settings row, at most one Result-screen line per day (`premiumNudgePrice` against the save's `upsell.lastShownOn`). *Why:* spec S12 rules.\n15. **The owner does the App Store Connect human steps** (agreements, the app record with its fixed id, attaching Premium to the first version, the TestFlight test); the price (EUR 1.99) and Family Sharing (off) are decided, so there is no price or Family Sharing question. Ask in plain words and wait; never submit anything yourself, and stop only if Apple no longer offers EUR 1.99.\n\n## Workflow\n\n1. Read [references\u002Fstore-and-adapter.md](references\u002Fstore-and-adapter.md). Install `npm install -E expo-iap@5.8.0` in every app (Shell step 5, with the services). The bare string `'expo-iap'` (no options) is a line of the Shell's one plugin list (Shell step 8), `shellPlugins` in `packages\u002Fshell\u002Fsrc\u002Fconfig\u002Fshell-plugins.ts` (architecture-and-boundaries ships it); never add a second list. Set `premium.productId` to `\u003CbundleId>.premium` in each `game.config.ts`.\n2. At Shell step 5 copy the templates at the same relative paths: `templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002F`, `templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002F`, `templates\u002F__mocks__\u002Fexpo-iap.ts` (each test lands with its file; they need only step 5's prerequisites: zustand, `testing\u002Fcreate-test-save.ts`, `testing\u002Fflush-microtasks.ts` and `app\u002Fstores-context.tsx`). Keep existing `packages\u002Fshell\u002Fsrc\u002Fapp\u002Fstores-context.tsx` and the save service; the store needs both.\n3. Read [references\u002Fpremium-states.md](references\u002Fpremium-states.md). The composition root is game-host-integration's template set (`packages\u002Fshell\u002Fsrc\u002Fapp\u002F`, Shell step 7): it builds the port where the adapter is created (`withConnectivity(createExpoIapPurchaseAdapter(), isOnline)` in `device-adapters.ts`), the dependencies once (`create-premium-deps.ts`), calls `startPremium` (never awaited) and right after it `connectPremiumReloads(connectivity, stores, premiumDeps)` (`connect-premium-reloads.ts`: `loadStore` when `shouldReloadStore(flow, isOnline)` on a connectivity change, `recheckPremium` when the app comes back to the foreground online). `startPremium` runs before the first network state arrives, so without the reloads Settings and S12 never show a price after an offline start. Wire `buyPremium` and `restorePremium` on the S12 buttons, and render S12 from `premiumView` and `premiumNotice` with the test IDs and copy keys in its tables. [examples\u002Fwire-premium.md](examples\u002Fwire-premium.md) shows each call in place. The S12 layout comes from its Toybox design (hand off to `toybox-screens`), and every state screen must then match its design screenshot (`toybox-visual-parity`).\n4. Make sure the four Shell catalogs hold every Premium key from the copy deck (the i18n work owns the texts), with `{priceText}` in the price keys.\n5. Run Tier 1: `npx jest packages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium packages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase packages\u002Fshell\u002Fsrc\u002Fapp\u002Fconnect-premium-reloads.test.ts --ci --selectProjects unit --coverage --collectCoverageFrom='packages\u002Fshell\u002Fsrc\u002F{stores\u002Fpremium,services\u002Fpurchase}\u002F**\u002F*.ts' --coverageThreshold='{}'` (paths first; only `npm run test:coverage` judges the thresholds).\n6. Run `node ${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fcheck-premium.mjs .` and `node ${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fcheck-premium-behaviour.mjs .`. Fix every `FAIL` line (file, rule, fix) and rerun until both print `RESULT: PASS`. Early in the Shell build order two rules are not due yet and print `SKIP` lines instead (a pass): `plugin-entry` until `packages\u002Fshell\u002Fsrc\u002Fconfig\u002Fshell-plugins.ts` exists (Shell step 8) and `catalog-keys` until the catalog linter `packages\u002Ftooling\u002Fsrc\u002Fi18n\u002Fverify-catalogs.ts` exists (Shell step 6); once the file exists the rule is strict (missing Shell catalogs then fail). `price-target` and `family-sharing` read the ASC tooling and every StoreKit configuration once they are in the repo.\n7. Before a release (Shell step 11 for the pilot, game step 14 for a new game) and after an expo-iap upgrade: read [references\u002Ftesting-tiers.md](references\u002Ftesting-tiers.md), copy `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002F`, `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fe2e\u002Fmaestro-args.ts` (+ test, if the repo lacks e2e-maestro's copy) and `templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F`, and make sure `packages\u002Fshell\u002Fe2e\u002Fsubflows\u002Fdebug-setup.yaml` is the Shell's one copy (e2e-maestro installs the same bytes; `templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fsubflows\u002Fdebug-setup.yaml` is that shared file: it waits for the app's first screen before it opens the debug link, and taps only Apple's \"Open in ...?\" alert, never a bare 'Open'). Run the Tier 2 harness on a throwaway simulator of your own (`e07-\u003Cpurpose>`; the harness gives Maestro the global `--device \u003Cudid>` and a driver port of its own for each flow, and Metro its own port) in the release-day order of testing-tiers.md: the E2E evidence run first, then the harness, then `xcrun simctl delete \u003Cudid>`, then `npx expo prebuild --platform ios --clean` before any Release or store build.\n8. For the store step (Shell step 11 for the pilot, game step 14 for a new game, with the harness) read [references\u002Fapp-store-connect.md](references\u002Fapp-store-connect.md): ask the owner for the human steps, copy `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002F` (keep existing ASC client files) and `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fclock\u002Fsystem-clock.ts` if missing, and run `create-premium-iap.ts \u003CbundleId>`: it sets exactly the EUR 1.99 price point with Family Sharing off, and stops (then ask the owner) only if Apple no longer offers EUR 1.99.\n9. Ask the owner for the Tier 3 TestFlight run (buy, cancel, reinstall + restore) and report the result in plain words.\n10. On Android (once the game's iOS version has shipped): read [references\u002Fgoogle-play-billing.md](references\u002Fgoogle-play-billing.md). Copy `expo-iap-purchase-adapter.android.test.ts` with the other purchase templates and `premium-flow.android.test.ts` with the premium store templates (both run in the `unit-android` Jest project), make sure `shellPlugins` holds `['expo-build-properties', { android: { kotlinVersion: '2.1.20' } }]` next to `'expo-iap'`, rerun both checkers, and ask the owner for GP6 (the Play product, after the first internal upload) and the Android Tier 3 run as a license tester (buy, cancel, pending with the slow test card, reinstall from Play + restore). The StoreKit harness has no Android counterpart; an emulator or `adb install` build correctly shows \"store unavailable\".\n\n## Definition of done\n\n- [ ] `expo-iap` is exactly 5.8.0, imported only by the adapter; the plugin entry is the bare string; no banned API, option or Onside switch anywhere.\n- [ ] Every template file is in place and Tier 1 passes (reducer, notice, nudge, evidence, service, connectivity gate, price, ASC payloads).\n- [ ] A purchase saves Premium, updates ads at once, then finishes; pending shows \"Waiting for approval\" and an approval later turns Premium on without a tap.\n- [ ] Restore shows `restore-failed` after a failed sync and `restore-empty` only after a successful one; refunds revoke only with a revocation date.\n- [ ] Offline (and with the debug offline switch) S12 shows \"store unavailable\" without asking StoreKit: the port is wrapped in `withConnectivity` where the adapter is created; after an offline start the price loads once the network comes (`connectPremiumReloads` after `startPremium`).\n- [ ] Prices come from the store in the player's digits; S12 texts exist in all four catalogs; every S12 state has its test ID.\n- [ ] Every S12 state screen has passed the Toybox visual-parity check against its design screenshot.\n- [ ] Before a release: the seven Tier 2 scenarios pass on a throwaway simulator in the release-day order (E2E, harness, delete the simulator, clean prebuild); the store IPA has no `*.storekit`, `*.xctest` or `get-task-allow`; the owner's Tier 3 run passed for this game and version.\n- [ ] Premium is `\u003CbundleId>.premium` at the EUR 1.99 price point with Family Sharing off in every StoreKit configuration and ASC payload (`price-target`, `family-sharing`).\n- [ ] The product exists in App Store Connect (en-US\u002Fde-DE texts, EUR 1.99, Family Sharing off, availability, review screenshot) and is attached to the first version.\n- [ ] Android: Premium is saved before the purchase is acknowledged and never consumed, a pending Play purchase is neither granted nor acknowledged, the launch re-check acknowledges a saved but unacknowledged purchase, absence never revokes (owner default a), Kotlin 2.1.20 is set through `expo-build-properties`, and `expo-iap-purchase-adapter.android.test.ts` and `premium-flow.android.test.ts` pass in `unit-android`.\n- [ ] `node ${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fcheck-premium.mjs .` and `node ${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fcheck-premium-behaviour.mjs .` both print `RESULT: PASS`\n\n## Anti-patterns\n\n- **Finishing the transaction first \"so StoreKit stops re-sending it\".** Re-delivery is the safety net; save, grant, then finish.\n- **Turning Premium off because the re-check found nothing.** Absence is not evidence; only a revocation date is.\n- **Showing \"No purchase to restore\" when `restorePurchases` threw.** That is `restore-failed`.\n- **`useIAP` or `verifyPurchase` \"for simplicity\".** They hide finishing or call a server; the adapter template is the whole integration.\n- **Giving the plugin `{ iapkitApiKey }` or any options object.** Even an empty object fails the audit; use `'expo-iap'`.\n- **Typing \"€1.99\" in a catalog, a test fixture of the screen, or a component.** Use `{priceText}` and `formatStorePrice`.\n- **Reading `getAvailablePurchases()` with the default active-only list.** Refunds disappear from it; pass `onlyIncludeActiveItemsIOS: false`.\n- **`launchApp: { clearState: true }` in a Tier 2 flow.** Uninstalling clears the test transactions.\n- **A short wait in a relaunch flow.** StoreKit answers the launch re-check only after its transaction sync (28 s once after a refund); the refund and approval relaunch flows wait 60 s for their state (`harness-relaunch-wait`). Never shorten it to make a run faster.\n- **Handing the raw expo-iap adapter to the service.** Without `withConnectivity` the store ignores ConnectivityPort: offline S12 waits on StoreKit and Tier 2 flow 07 (`offline=1`) shows a price instead of \"store unavailable\".\n- **Putting a StoreKit flow under `e2e\u002Fflows\u002F`.** The normal E2E run would run it against an unarmed build.\n- **Pushing Premium with a pop-up after a loss or on launch.** Only the three quiet entry points.\n- **Editing a Jest test or a fixture until the checker passes.** The behaviour check runs the real modules; fix the module.\n\n## Files in this skill\n\n| File | What it is | Read\u002Frun when |\n|---|---|---|\n| [references\u002Fstore-and-adapter.md](references\u002Fstore-and-adapter.md) | Premium rules, the three StoreKit facts, versions, bans, PurchasePort, adapter facts, error-code table, re-verify | Workflow step 1, and before touching the adapter |\n| [references\u002Fpremium-states.md](references\u002Fpremium-states.md) | Reducer and actions, the S12 state table (views, test IDs, copy keys), restore toasts, service order, wiring, edge cases, price display | Workflow step 3, and on any state change |\n| [references\u002Ftesting-tiers.md](references\u002Ftesting-tiers.md) | Tier 1 tests, the verified StoreKit harness, its files, scenarios, commands and gotchas, Tier 3 steps | Workflow steps 5 and 7 |\n| [references\u002Fapp-store-connect.md](references\u002Fapp-store-connect.md) | Product rules, the EUR 1.99 price (O2), Family Sharing off (O3), the ASC API script, remaining steps, human steps | Workflow step 8 |\n| [references\u002Fgoogle-play-billing.md](references\u002Fgoogle-play-billing.md) | Android: Play Billing 9.1.0 and Kotlin 2.1.20, acknowledge after the save, the 3-day refund of unacknowledged purchases, pending, restore, refunds (absence never revokes, owner default a), the GP6 product at EUR 1.99, license testers, Play-installed builds | Workflow step 10, and before touching Android purchase code |\n| [examples\u002Fwire-premium.md](examples\u002Fwire-premium.md) | The complete wiring for the pilot game | Workflow step 3, as the model |\n| `templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002F` | Port, expo-iap adapter, fake, connectivity gate `withConnectivity` (+ test), service (+ test; the test is synced from the library, the same file as unit-and-component-tests' example: do not edit here), store flow with `shouldReloadStore`, the Android adapter test `expo-iap-purchase-adapter.android.test.ts` (the `unit-android` project), price formatter (+ test) | Workflow step 2 |\n| `templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002F` | State, transitions, reducer (+ test), view, notice (+ test), Result-screen nudge (+ test), evidence (+ test), Zustand store, and `premium-flow.android.test.ts` (the `unit-android` project: listening before `initConnection`, the launch re-check acknowledging a saved but unacknowledged purchase, offline keeping the cached Premium) | Workflow step 2 |\n| `templates\u002F__mocks__\u002Fexpo-iap.ts` | Jest root mock (real `ErrorCode`, no banned APIs) | Workflow step 2 |\n| `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002F` | `Premium.storekit.template` (EUR 1.99, Family Sharing off), `storekit-harness.entitlements`, `ArmTests.swift`, `add-harness.rb`, `storekit-harness.ts` (explicit `--device`, its own driver port for each flow, its own Metro port), `metro-session.ts` with its test (Metro's output in `build\u002Flogs\u002Fstorekit-metro.log`, Metro stopped however the run ends), `busy-note.ts` with its test (the log line that names a busy Mac) | Workflow step 7 |\n| `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fe2e\u002F` | `maestro-args.ts`: the shared Maestro target helper (`maestroGlobalArgs`, `freeDriverPort`, `driverPortFor`) with its test; e2e-maestro's file, synced from the library (do not edit here) | Workflow step 7, with the harness |\n| `templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F` | The seven Tier 2 Maestro flows (the two relaunch flows wait 60 s for StoreKit's launch re-check) | Workflow step 7 |\n| `templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fsubflows\u002Fdebug-setup.yaml` | The debug deep-link subflow the flows call (the Shell's one shared copy, synced from the library: it waits for the first screen before the link and taps only Apple's \"Open in ...?\" alert; do not edit here) | Workflow step 7 |\n| `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002F` | ASC payloads (+ test), `create-premium-iap.ts` (the CLI with `TARGET_EUR`) over `premium-iap-setup.ts` (+ test on a fake App Store Connect: the bundle id checked with ios-simulator-build's `isAppId` before the key is read, exit 2 with the usage; the app found by its exact bundle id), `find-app.ts` (+ test; synced from the library, identical to ios-release-testflight's copy), JWT, credentials and client | Workflow step 8 |\n| `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fclock\u002Fsystem-clock.ts` | The tooling wall clock with `nowEpochSeconds` and `todayIso` | Workflow step 8, if missing or lacking `nowEpochSeconds` |\n| `assets\u002Fpremium-facts.json` | Pinned version, adapter allowlist, banned APIs and config words, catalog keys, S12 test IDs, views, required files, Family Sharing decision | Read by the checkers; update on an upgrade or an owner decision |\n| `scripts\u002Fcheck-premium.mjs` | Static checks: files, pin, imports, banned APIs, plugin options, adapter facts, the adapter wrapped in `withConnectivity` where it is created, the debug Premium action only in test-only code, product IDs, typed prices (the parity harness's fixture store excepted), catalog keys, S12 test IDs, harness isolation (the repo scan skips `skills\u002F`, `.claude\u002F` and generated folders), StoreKit config, Family Sharing, the EUR 1.99 target and every StoreKit `displayPrice` (`price-target`) and Family Sharing off in the StoreKit template, every generated `apps\u002F\u003Cid>\u002Fios\u002F*.storekit` and the ASC payload (`family-sharing`), the StoreKit harness's Maestro calls through `maestroGlobalArgs`, never `--udid`, each flow on its own driver port (`harness-maestro`), and the 60 s wait of the two relaunch flows (`harness-relaunch-wait`); on Android the acknowledge only in `finish()` and never consumed (`android-acknowledge`), `state: purchase.purchaseState` (`android-pending`), Kotlin through expo-build-properties (`android-kotlin`) | Workflow step 6 |\n| `scripts\u002Fcheck-premium-behaviour.mjs` | Runs the repo's Premium modules (type stripping) against the S12 table, evidence, service order, restore, revocation, offline gate, Result-screen nudge and price rules, the expo-iap adapter against a scripted expo-iap (error codes, restore, `Transaction.all` mapping, call shapes), the composition root's two store reloads (`store-reloads`), and Google Play Billing through the real adapter with Play's purchase shape (`android-pending`, `android-restore`, `android-refund`) | Workflow step 6 |\n| `scripts\u002Flib\u002Frepo-scan.mjs` | File listing and import parsing helpers | Read only to change a checker |\n| `scripts\u002Flib\u002Fload-ts.mjs` | Imports repo TypeScript modules with the `@e07\u002F*` aliases and the module stand-ins | Read only to change a checker |\n| `scripts\u002Flib\u002Fstubs\u002Fexpo-iap.mjs` | Scripted Node stand-in for expo-iap 5.8.0 used by the behaviour check (update `ErrorCode` on an upgrade) | Read only to change a checker |\n| `scripts\u002Flib\u002Fassemble-fixtures.mjs` | Builds each self-test case from templates + base repo + `mutation.json` | Read only to add a self-test case |\n| `scripts\u002Fselftest.mjs` | Proves both checkers on the clean repo and 67 planted problems (the Android acknowledge, pending, Kotlin, restore and refund cases included) | After changing a checker, a template or a fixture |\n| `scripts\u002Fcheck-lib.mjs` | Shared script helper, synced from the library (do not edit here) | Never by hand |\n| `assets\u002Fshared.json` | Declares the shared files copied into this skill | When adding a shared file |\n| `tests\u002Ffixtures\u002F` | `base-repo\u002F` plus one `mutation.json` and `EXPECT.txt` per case, per checker | When adding a rule |\n\n## Related skills\n\n- `admob-ads` - Premium turns ads off and perks free; it reads `isPremium`.\n- `state-stores` - the store pattern and `createShellStores`, which creates the Premium store.\n- `save-persistence-and-migrations` - the save's `premium` section and its revoke guard.\n- `toybox-screens` - the S12 layout that renders the states and toasts.\n- `toybox-visual-parity` - proves each S12 state screen matches its design screenshot.\n- `i18n-strings-and-catalogs` - the Premium texts in four languages.\n- `privacy-and-network-audit` - the network audit that fails on IAPKit or Onside.\n- `ios-release-testflight` - signing, the store-artifact gate and the TestFlight human steps.\n- `e2e-maestro` - Maestro installation and the debug deep link.\n","# Premium purchase\n\nMakes each game sell its single non-consumable \"Premium\" honestly and with no server: StoreKit 2 verifies on the phone, Premium is saved before a transaction is finished, only explicit evidence ever revokes it, every S12 state is reachable and tested, and two scripts prove it on the real code.\n\n## Rules that must hold\n\n1. **Save Premium before finishing: `persistPremium({ isPremium: true })` (synchronous) -> dispatch `premium-granted` -> `finish(tx)`.** Never finish first, never auto-finish, and never finish when `persistPremium` returns `false` (the change did not reach the disk: `save.update` answered `false` for a refused write, a rejected document, a pending quarantine copy or a newer app's read-only save). On Android `finishTransaction({ purchase, isConsumable: false })` is the acknowledge, called only from the port's `finish()` and never with `isConsumable: true` (that consumes Premium); an unacknowledged purchase is never delivered again and Google refunds it after 3 days, so `recheckPremium` and `restorePremium` finish every owned transaction marked `isUnfinished` (the adapter's `isAcknowledgedAndroid === false`) once `persistPremium` returned `true`. *Why:* StoreKit re-delivers unfinished transactions; a finished-but-unsaved purchase is lost for good, and an unacknowledged Android one is refunded.\n2. **Revoke only on explicit evidence:** a verified Premium transaction with a revocation date and no newer valid one. Absence, errors and offline keep the cached Premium; a revocation is saved with its `revokedAtMs`. On Android a refund leaves no dated proof on the phone (it only vanishes from the query), so absence never revokes there (owner default a). *Why:* a fresh purchase can be briefly missing from StoreKit, and the save guard ignores a revoke without a date.\n3. **Listen first:** `startPremium` subscribes to purchase events before `initConnection`, then loads the price, then re-checks silently (`Transaction.all`, `onlyIncludeActiveItemsIOS: false`). *Why:* StoreKit replays unfinished and approved Ask-to-Buy transactions right after connecting, and only `Transaction.all` shows refunds.\n4. **Every handler is idempotent;** a failure counts only while a purchase is in flight. *Why:* iOS reports one failure twice (rejection and listener) and re-delivers owned purchases on relaunch.\n5. **Restore distinguishes \"couldn't restore\" from \"nothing to restore\":** a failed sync (cancelled Apple Account prompt, offline) is always `restore-failed`; `restore-empty` only after a successful sync with no evidence. On Android `restorePurchases` is the Play query itself: billing unavailable, no Play Store or offline is `restore-failed`, never a query error swallowed into `[]`. *Why:* telling a paying player \"no purchase found\" because the network failed is the worst answer.\n6. **`expo-iap` is exactly 5.8.0, imported only by `expo-iap-purchase-adapter.ts`, and its plugin entry is the bare string `'expo-iap'`.** On Android it runs Play Billing 9.1.0 and needs `['expo-build-properties', { android: { kotlinVersion: '2.1.20' } }]` in the same plugin list; the adapter keeps `state: purchase.purchaseState`, so a pending Play purchase is never granted or acknowledged. Never `kitApi`, `KitApiError`, `verifyPurchaseWithProvider`, `verifyPurchase`, `useIAP`, `andDangerouslyFinishTransactionAutomatically`, any plugin option, `ios.onside.enabled` or `EXPO_IAP_ONSIDE`. *Why:* they add a server (IAPKit) or the OnsideKit pod (spec N2\u002FN3), or hide the finishing logic.\n7. **One product per game: `\u003CbundleId>.premium` (`io.applander.\u003Cgame id without hyphens>.premium`, owner decision O4), NON_CONSUMABLE, the EUR 1.99 App Store price point (O2), `familySharable: false` (O3: Family Sharing stays off, never turned on).** Every StoreKit configuration (the template and each generated `*.storekit`) and the ASC payload say `false`; `create-premium-iap.ts` targets exactly 1.99. On Google Play the same id is a one-time (managed) product at a EUR 1.99 default price with Google's local prices (owner step GP6, after the first internal upload). *Why:* spec N7; the owner decided the price and Family Sharing on 2026-09-30; product IDs can never be reused, and Family Sharing cannot be turned off once on.\n8. **An empty product list, a failed connection or being offline is \"store unavailable\", never an error dialog;** the port is `withConnectivity(createExpoIapPurchaseAdapter(), connectivity.isOnline)`, and a connectivity change reloads the store when `shouldReloadStore` says so. Apple's error texts are never shown. *Why:* StoreKit returns `[]` instead of throwing; S12 has its own catalog messages; and the debug \"Simulate offline\" switch (Tier 2 flow 07) only reaches the store through ConnectivityPort.\n9. **Show the price the store reports, in the player's digits (`formatStorePrice`, fallback `displayPrice`).** Never type a price into code or catalogs; catalogs use `{priceText}`. The EUR 1.99 point is what App Store Connect sells in Germany; players elsewhere see their own territory's price. *Why:* spec S12 and Apple's per-territory price points.\n10. **Every S12 state is designed and tested:** reducer tests for each (Tier 1), the StoreKit harness before each release and after every expo-iap upgrade (Tier 2), and the owner's TestFlight run per game (Tier 3). *Why:* spec S12\u002F15.5; the real purchase sheet only exists on TestFlight.\n11. **All S12 text comes from the Shell catalogs in en, de, fa and ckb.** *Why:* App Store Connect has no Persian or Sorani, and its texts are never shown in the app.\n12. **The StoreKit harness exists only in throwaway harness builds;** `get-task-allow`, `*.storekit` and `*.xctest` never ship. *Why:* `get-task-allow` in a store build is a security hole and a rejection.\n13. **Premium changes only through the reducer, after the save:** purchases, restores and re-checks via the service; the test build's debug switch (`premium=0|1`) via `debug-premium-set`, only from test-only code. *Why:* one path keeps ads, the save and S12 in step, and a stray unlock would give Premium away.\n14. **Premium is never pushed with pop-ups:** Home button (hidden once owned), Settings row, at most one Result-screen line per day (`premiumNudgePrice` against the save's `upsell.lastShownOn`). *Why:* spec S12 rules.\n15. **The owner does the App Store Connect human steps** (agreements, the app record with its fixed id, attaching Premium to the first version, the TestFlight test); the price (EUR 1.99) and Family Sharing (off) are decided, so there is no price or Family Sharing question. Ask in plain words and wait; never submit anything yourself, and stop only if Apple no longer offers EUR 1.99.\n\n## Workflow\n\n1. Read [references\u002Fstore-and-adapter.md](references\u002Fstore-and-adapter.md). Install `npm install -E expo-iap@5.8.0` in every app (Shell step 5, with the services). The bare string `'expo-iap'` (no options) is a line of the Shell's one plugin list (Shell step 8), `shellPlugins` in `packages\u002Fshell\u002Fsrc\u002Fconfig\u002Fshell-plugins.ts` (architecture-and-boundaries ships it); never add a second list. Set `premium.productId` to `\u003CbundleId>.premium` in each `game.config.ts`.\n2. At Shell step 5 copy the templates at the same relative paths: `templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002F`, `templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002F`, `templates\u002F__mocks__\u002Fexpo-iap.ts` (each test lands with its file; they need only step 5's prerequisites: zustand, `testing\u002Fcreate-test-save.ts`, `testing\u002Fflush-microtasks.ts` and `app\u002Fstores-context.tsx`). Keep existing `packages\u002Fshell\u002Fsrc\u002Fapp\u002Fstores-context.tsx` and the save service; the store needs both.\n3. Read [references\u002Fpremium-states.md](references\u002Fpremium-states.md). The composition root is game-host-integration's template set (`packages\u002Fshell\u002Fsrc\u002Fapp\u002F`, Shell step 7): it builds the port where the adapter is created (`withConnectivity(createExpoIapPurchaseAdapter(), isOnline)` in `device-adapters.ts`), the dependencies once (`create-premium-deps.ts`), calls `startPremium` (never awaited) and right after it `connectPremiumReloads(connectivity, stores, premiumDeps)` (`connect-premium-reloads.ts`: `loadStore` when `shouldReloadStore(flow, isOnline)` on a connectivity change, `recheckPremium` when the app comes back to the foreground online). `startPremium` runs before the first network state arrives, so without the reloads Settings and S12 never show a price after an offline start. Wire `buyPremium` and `restorePremium` on the S12 buttons, and render S12 from `premiumView` and `premiumNotice` with the test IDs and copy keys in its tables. [examples\u002Fwire-premium.md](examples\u002Fwire-premium.md) shows each call in place. The S12 layout comes from its Toybox design (hand off to `toybox-screens`), and every state screen must then match its design screenshot (`toybox-visual-parity`).\n4. Make sure the four Shell catalogs hold every Premium key from the copy deck (the i18n work owns the texts), with `{priceText}` in the price keys.\n5. Run Tier 1: `npx jest packages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium packages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase packages\u002Fshell\u002Fsrc\u002Fapp\u002Fconnect-premium-reloads.test.ts --ci --selectProjects unit --coverage --collectCoverageFrom='packages\u002Fshell\u002Fsrc\u002F{stores\u002Fpremium,services\u002Fpurchase}\u002F**\u002F*.ts' --coverageThreshold='{}'` (paths first; only `npm run test:coverage` judges the thresholds).\n6. Run `node ${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fcheck-premium.mjs .` and `node ${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fcheck-premium-behaviour.mjs .`. Fix every `FAIL` line (file, rule, fix) and rerun until both print `RESULT: PASS`. Early in the Shell build order two rules are not due yet and print `SKIP` lines instead (a pass): `plugin-entry` until `packages\u002Fshell\u002Fsrc\u002Fconfig\u002Fshell-plugins.ts` exists (Shell step 8) and `catalog-keys` until the catalog linter `packages\u002Ftooling\u002Fsrc\u002Fi18n\u002Fverify-catalogs.ts` exists (Shell step 6); once the file exists the rule is strict (missing Shell catalogs then fail). `price-target` and `family-sharing` read the ASC tooling and every StoreKit configuration once they are in the repo.\n7. Before a release (Shell step 11 for the pilot, game step 14 for a new game) and after an expo-iap upgrade: read [references\u002Ftesting-tiers.md](references\u002Ftesting-tiers.md), copy `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002F`, `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fe2e\u002Fmaestro-args.ts` (+ test, if the repo lacks e2e-maestro's copy) and `templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F`, and make sure `packages\u002Fshell\u002Fe2e\u002Fsubflows\u002Fdebug-setup.yaml` is the Shell's one copy (e2e-maestro installs the same bytes; `templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fsubflows\u002Fdebug-setup.yaml` is that shared file: it waits for the app's first screen before it opens the debug link, and taps only Apple's \"Open in ...?\" alert, never a bare 'Open'). Run the Tier 2 harness on a throwaway simulator of your own (`e07-\u003Cpurpose>`; the harness gives Maestro the global `--device \u003Cudid>` and a driver port of its own for each flow, and Metro its own port) in the release-day order of testing-tiers.md: the E2E evidence run first, then the harness, then `xcrun simctl delete \u003Cudid>`, then `npx expo prebuild --platform ios --clean` before any Release or store build.\n8. For the store step (Shell step 11 for the pilot, game step 14 for a new game, with the harness) read [references\u002Fapp-store-connect.md](references\u002Fapp-store-connect.md): ask the owner for the human steps, copy `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002F` (keep existing ASC client files) and `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fclock\u002Fsystem-clock.ts` if missing, and run `create-premium-iap.ts \u003CbundleId>`: it sets exactly the EUR 1.99 price point with Family Sharing off, and stops (then ask the owner) only if Apple no longer offers EUR 1.99.\n9. Ask the owner for the Tier 3 TestFlight run (buy, cancel, reinstall + restore) and report the result in plain words.\n10. On Android (once the game's iOS version has shipped): read [references\u002Fgoogle-play-billing.md](references\u002Fgoogle-play-billing.md). Copy `expo-iap-purchase-adapter.android.test.ts` with the other purchase templates and `premium-flow.android.test.ts` with the premium store templates (both run in the `unit-android` Jest project), make sure `shellPlugins` holds `['expo-build-properties', { android: { kotlinVersion: '2.1.20' } }]` next to `'expo-iap'`, rerun both checkers, and ask the owner for GP6 (the Play product, after the first internal upload) and the Android Tier 3 run as a license tester (buy, cancel, pending with the slow test card, reinstall from Play + restore). The StoreKit harness has no Android counterpart; an emulator or `adb install` build correctly shows \"store unavailable\".\n\n## Definition of done\n\n- [ ] `expo-iap` is exactly 5.8.0, imported only by the adapter; the plugin entry is the bare string; no banned API, option or Onside switch anywhere.\n- [ ] Every template file is in place and Tier 1 passes (reducer, notice, nudge, evidence, service, connectivity gate, price, ASC payloads).\n- [ ] A purchase saves Premium, updates ads at once, then finishes; pending shows \"Waiting for approval\" and an approval later turns Premium on without a tap.\n- [ ] Restore shows `restore-failed` after a failed sync and `restore-empty` only after a successful one; refunds revoke only with a revocation date.\n- [ ] Offline (and with the debug offline switch) S12 shows \"store unavailable\" without asking StoreKit: the port is wrapped in `withConnectivity` where the adapter is created; after an offline start the price loads once the network comes (`connectPremiumReloads` after `startPremium`).\n- [ ] Prices come from the store in the player's digits; S12 texts exist in all four catalogs; every S12 state has its test ID.\n- [ ] Every S12 state screen has passed the Toybox visual-parity check against its design screenshot.\n- [ ] Before a release: the seven Tier 2 scenarios pass on a throwaway simulator in the release-day order (E2E, harness, delete the simulator, clean prebuild); the store IPA has no `*.storekit`, `*.xctest` or `get-task-allow`; the owner's Tier 3 run passed for this game and version.\n- [ ] Premium is `\u003CbundleId>.premium` at the EUR 1.99 price point with Family Sharing off in every StoreKit configuration and ASC payload (`price-target`, `family-sharing`).\n- [ ] The product exists in App Store Connect (en-US\u002Fde-DE texts, EUR 1.99, Family Sharing off, availability, review screenshot) and is attached to the first version.\n- [ ] Android: Premium is saved before the purchase is acknowledged and never consumed, a pending Play purchase is neither granted nor acknowledged, the launch re-check acknowledges a saved but unacknowledged purchase, absence never revokes (owner default a), Kotlin 2.1.20 is set through `expo-build-properties`, and `expo-iap-purchase-adapter.android.test.ts` and `premium-flow.android.test.ts` pass in `unit-android`.\n- [ ] `node ${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fcheck-premium.mjs .` and `node ${CLAUDE_SKILL_DIR}\u002Fscripts\u002Fcheck-premium-behaviour.mjs .` both print `RESULT: PASS`\n\n## Anti-patterns\n\n- **Finishing the transaction first \"so StoreKit stops re-sending it\".** Re-delivery is the safety net; save, grant, then finish.\n- **Turning Premium off because the re-check found nothing.** Absence is not evidence; only a revocation date is.\n- **Showing \"No purchase to restore\" when `restorePurchases` threw.** That is `restore-failed`.\n- **`useIAP` or `verifyPurchase` \"for simplicity\".** They hide finishing or call a server; the adapter template is the whole integration.\n- **Giving the plugin `{ iapkitApiKey }` or any options object.** Even an empty object fails the audit; use `'expo-iap'`.\n- **Typing \"€1.99\" in a catalog, a test fixture of the screen, or a component.** Use `{priceText}` and `formatStorePrice`.\n- **Reading `getAvailablePurchases()` with the default active-only list.** Refunds disappear from it; pass `onlyIncludeActiveItemsIOS: false`.\n- **`launchApp: { clearState: true }` in a Tier 2 flow.** Uninstalling clears the test transactions.\n- **A short wait in a relaunch flow.** StoreKit answers the launch re-check only after its transaction sync (28 s once after a refund); the refund and approval relaunch flows wait 60 s for their state (`harness-relaunch-wait`). Never shorten it to make a run faster.\n- **Handing the raw expo-iap adapter to the service.** Without `withConnectivity` the store ignores ConnectivityPort: offline S12 waits on StoreKit and Tier 2 flow 07 (`offline=1`) shows a price instead of \"store unavailable\".\n- **Putting a StoreKit flow under `e2e\u002Fflows\u002F`.** The normal E2E run would run it against an unarmed build.\n- **Pushing Premium with a pop-up after a loss or on launch.** Only the three quiet entry points.\n- **Editing a Jest test or a fixture until the checker passes.** The behaviour check runs the real modules; fix the module.\n\n## Files in this skill\n\n| File | What it is | Read\u002Frun when |\n|---|---|---|\n| [references\u002Fstore-and-adapter.md](references\u002Fstore-and-adapter.md) | Premium rules, the three StoreKit facts, versions, bans, PurchasePort, adapter facts, error-code table, re-verify | Workflow step 1, and before touching the adapter |\n| [references\u002Fpremium-states.md](references\u002Fpremium-states.md) | Reducer and actions, the S12 state table (views, test IDs, copy keys), restore toasts, service order, wiring, edge cases, price display | Workflow step 3, and on any state change |\n| [references\u002Ftesting-tiers.md](references\u002Ftesting-tiers.md) | Tier 1 tests, the verified StoreKit harness, its files, scenarios, commands and gotchas, Tier 3 steps | Workflow steps 5 and 7 |\n| [references\u002Fapp-store-connect.md](references\u002Fapp-store-connect.md) | Product rules, the EUR 1.99 price (O2), Family Sharing off (O3), the ASC API script, remaining steps, human steps | Workflow step 8 |\n| [references\u002Fgoogle-play-billing.md](references\u002Fgoogle-play-billing.md) | Android: Play Billing 9.1.0 and Kotlin 2.1.20, acknowledge after the save, the 3-day refund of unacknowledged purchases, pending, restore, refunds (absence never revokes, owner default a), the GP6 product at EUR 1.99, license testers, Play-installed builds | Workflow step 10, and before touching Android purchase code |\n| [examples\u002Fwire-premium.md](examples\u002Fwire-premium.md) | The complete wiring for the pilot game | Workflow step 3, as the model |\n| `templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002F` | Port, expo-iap adapter, fake, connectivity gate `withConnectivity` (+ test), service (+ test; the test is synced from the library, the same file as unit-and-component-tests' example: do not edit here), store flow with `shouldReloadStore`, the Android adapter test `expo-iap-purchase-adapter.android.test.ts` (the `unit-android` project), price formatter (+ test) | Workflow step 2 |\n| `templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002F` | State, transitions, reducer (+ test), view, notice (+ test), Result-screen nudge (+ test), evidence (+ test), Zustand store, and `premium-flow.android.test.ts` (the `unit-android` project: listening before `initConnection`, the launch re-check acknowledging a saved but unacknowledged purchase, offline keeping the cached Premium) | Workflow step 2 |\n| `templates\u002F__mocks__\u002Fexpo-iap.ts` | Jest root mock (real `ErrorCode`, no banned APIs) | Workflow step 2 |\n| `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002F` | `Premium.storekit.template` (EUR 1.99, Family Sharing off), `storekit-harness.entitlements`, `ArmTests.swift`, `add-harness.rb`, `storekit-harness.ts` (explicit `--device`, its own driver port for each flow, its own Metro port), `metro-session.ts` with its test (Metro's output in `build\u002Flogs\u002Fstorekit-metro.log`, Metro stopped however the run ends), `busy-note.ts` with its test (the log line that names a busy Mac) | Workflow step 7 |\n| `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fe2e\u002F` | `maestro-args.ts`: the shared Maestro target helper (`maestroGlobalArgs`, `freeDriverPort`, `driverPortFor`) with its test; e2e-maestro's file, synced from the library (do not edit here) | Workflow step 7, with the harness |\n| `templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F` | The seven Tier 2 Maestro flows (the two relaunch flows wait 60 s for StoreKit's launch re-check) | Workflow step 7 |\n| `templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fsubflows\u002Fdebug-setup.yaml` | The debug deep-link subflow the flows call (the Shell's one shared copy, synced from the library: it waits for the first screen before the link and taps only Apple's \"Open in ...?\" alert; do not edit here) | Workflow step 7 |\n| `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002F` | ASC payloads (+ test), `create-premium-iap.ts` (the CLI with `TARGET_EUR`) over `premium-iap-setup.ts` (+ test on a fake App Store Connect: the bundle id checked with ios-simulator-build's `isAppId` before the key is read, exit 2 with the usage; the app found by its exact bundle id), `find-app.ts` (+ test; synced from the library, identical to ios-release-testflight's copy), JWT, credentials and client | Workflow step 8 |\n| `templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fclock\u002Fsystem-clock.ts` | The tooling wall clock with `nowEpochSeconds` and `todayIso` | Workflow step 8, if missing or lacking `nowEpochSeconds` |\n| `assets\u002Fpremium-facts.json` | Pinned version, adapter allowlist, banned APIs and config words, catalog keys, S12 test IDs, views, required files, Family Sharing decision | Read by the checkers; update on an upgrade or an owner decision |\n| `scripts\u002Fcheck-premium.mjs` | Static checks: files, pin, imports, banned APIs, plugin options, adapter facts, the adapter wrapped in `withConnectivity` where it is created, the debug Premium action only in test-only code, product IDs, typed prices (the parity harness's fixture store excepted), catalog keys, S12 test IDs, harness isolation (the repo scan skips `skills\u002F`, `.claude\u002F` and generated folders), StoreKit config, Family Sharing, the EUR 1.99 target and every StoreKit `displayPrice` (`price-target`) and Family Sharing off in the StoreKit template, every generated `apps\u002F\u003Cid>\u002Fios\u002F*.storekit` and the ASC payload (`family-sharing`), the StoreKit harness's Maestro calls through `maestroGlobalArgs`, never `--udid`, each flow on its own driver port (`harness-maestro`), and the 60 s wait of the two relaunch flows (`harness-relaunch-wait`); on Android the acknowledge only in `finish()` and never consumed (`android-acknowledge`), `state: purchase.purchaseState` (`android-pending`), Kotlin through expo-build-properties (`android-kotlin`) | Workflow step 6 |\n| `scripts\u002Fcheck-premium-behaviour.mjs` | Runs the repo's Premium modules (type stripping) against the S12 table, evidence, service order, restore, revocation, offline gate, Result-screen nudge and price rules, the expo-iap adapter against a scripted expo-iap (error codes, restore, `Transaction.all` mapping, call shapes), the composition root's two store reloads (`store-reloads`), and Google Play Billing through the real adapter with Play's purchase shape (`android-pending`, `android-restore`, `android-refund`) | Workflow step 6 |\n| `scripts\u002Flib\u002Frepo-scan.mjs` | File listing and import parsing helpers | Read only to change a checker |\n| `scripts\u002Flib\u002Fload-ts.mjs` | Imports repo TypeScript modules with the `@e07\u002F*` aliases and the module stand-ins | Read only to change a checker |\n| `scripts\u002Flib\u002Fstubs\u002Fexpo-iap.mjs` | Scripted Node stand-in for expo-iap 5.8.0 used by the behaviour check (update `ErrorCode` on an upgrade) | Read only to change a checker |\n| `scripts\u002Flib\u002Fassemble-fixtures.mjs` | Builds each self-test case from templates + base repo + `mutation.json` | Read only to add a self-test case |\n| `scripts\u002Fselftest.mjs` | Proves both checkers on the clean repo and 67 planted problems (the Android acknowledge, pending, Kotlin, restore and refund cases included) | After changing a checker, a template or a fixture |\n| `scripts\u002Fcheck-lib.mjs` | Shared script helper, synced from the library (do not edit here) | Never by hand |\n| `assets\u002Fshared.json` | Declares the shared files copied into this skill | When adding a shared file |\n| `tests\u002Ffixtures\u002F` | `base-repo\u002F` plus one `mutation.json` and `EXPECT.txt` per case, per checker | When adding a rule |\n\n## Related skills\n\n- `admob-ads` - Premium turns ads off and perks free; it reads `isPremium`.\n- `state-stores` - the store pattern and `createShellStores`, which creates the Premium store.\n- `save-persistence-and-migrations` - the save's `premium` section and its revoke guard.\n- `toybox-screens` - the S12 layout that renders the states and toasts.\n- `toybox-visual-parity` - proves each S12 state screen matches its design screenshot.\n- `i18n-strings-and-catalogs` - the Premium texts in four languages.\n- `privacy-and-network-audit` - the network audit that fails on IAPKit or Onside.\n- `ios-release-testflight` - signing, the store-artifact gate and the TestFlight human steps.\n- `e2e-maestro` - Maestro installation and the debug deep link.\n",{"name":5,"description":7},"main","5d711936a7299f9bb0c0132bfe99d3b43cfbfb48","skills\u002Fpremium-purchase","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade","https:\u002F\u002Fgithub.com\u002Fzakariaf","https:\u002F\u002Fzakaria.dev","Seniore Software Engineer","2026-11-05 04:56:14",{"source":8,"skillName":5,"commands":33,"prompt":43,"zipAvailable":44},[34,37,40],{"tool":35,"command":36},"npx","npx skills add zakariaf\u002Fpocket-arcade --skill premium-purchase",{"tool":38,"command":39},"bunx","bunx skills add zakariaf\u002Fpocket-arcade --skill premium-purchase",{"tool":41,"command":42},"pnpm","pnpm dlx skills add zakariaf\u002Fpocket-arcade --skill premium-purchase","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002FSKILL.md",true,[46,52,56,62,66,70,74,78,82,88,92,96,100,104,108,112,116,120,124,128,132,136,140,144,148,152,156,160,164,168,172,176,180,184,188,192,196,200,204,208,212,216,220,224,228,232,236,240,244,248,252,256,260,264,268,272,276,280,284,288,292,296,300,304,308,312,318,322,326,330,334,338,342,346,350,354,358,362,366,370,374,378,382,386,390,394,398,402,406,410,414,418,422,426,430,434,438,442,446,450,454,458,462,465,469,473,477,481,484,488,492,496,500,504,508,512,516,520,524,527,530,533,537,541,545,548,552,555,559,563,566,570,573,577,581,585,589,593,597,601,605,608,612,616,619,623,627,631,635,639,643,646,649,652,656,659,662,666,670,674,678,682,686,689,693,697,700,704,707,711,714,718,722,726,729,733,737,741,745,749,753,757,761,764,767,771,775,779,783,787,791,795,799,803,807,811,815,819,823,827,831,835,839,843,846,849,852,856,859,862,865,868,872,876,879,883,886,890,894,898,901,904,907,911,914,918],{"path":47,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":50,"sourceHtmlUrl":51},"assets\u002Fpremium-facts.json","ASSET","资产文件",6414,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fassets\u002Fpremium-facts.json",{"path":53,"resourceType":48,"resourceTypeDesc":49,"sizeBytes":54,"sourceHtmlUrl":55},"assets\u002Fshared.json",1527,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fassets\u002Fshared.json",{"path":57,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":60,"sourceHtmlUrl":61},"examples\u002Fwire-premium.md","REFERENCE","参考文档",10394,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fexamples\u002Fwire-premium.md",{"path":63,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":64,"sourceHtmlUrl":65},"references\u002Fapp-store-connect.md",7596,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Freferences\u002Fapp-store-connect.md",{"path":67,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":68,"sourceHtmlUrl":69},"references\u002Fgoogle-play-billing.md",10593,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Freferences\u002Fgoogle-play-billing.md",{"path":71,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":72,"sourceHtmlUrl":73},"references\u002Fpremium-states.md",17829,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Freferences\u002Fpremium-states.md",{"path":75,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":76,"sourceHtmlUrl":77},"references\u002Fstore-and-adapter.md",10963,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Freferences\u002Fstore-and-adapter.md",{"path":79,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":80,"sourceHtmlUrl":81},"references\u002Ftesting-tiers.md",19584,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Freferences\u002Ftesting-tiers.md",{"path":83,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":86,"sourceHtmlUrl":87},"scripts\u002Fcheck-lib.mjs","SCRIPT","脚本",45444,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fscripts\u002Fcheck-lib.mjs",{"path":89,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":90,"sourceHtmlUrl":91},"scripts\u002Fcheck-premium-behaviour.mjs",40269,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fscripts\u002Fcheck-premium-behaviour.mjs",{"path":93,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":94,"sourceHtmlUrl":95},"scripts\u002Fcheck-premium.mjs",31586,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fscripts\u002Fcheck-premium.mjs",{"path":97,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":98,"sourceHtmlUrl":99},"scripts\u002Flib\u002Fassemble-fixtures.mjs",3194,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fscripts\u002Flib\u002Fassemble-fixtures.mjs",{"path":101,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":102,"sourceHtmlUrl":103},"scripts\u002Flib\u002Fload-ts.mjs",2697,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fscripts\u002Flib\u002Fload-ts.mjs",{"path":105,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":106,"sourceHtmlUrl":107},"scripts\u002Flib\u002Frepo-scan.mjs",5746,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fscripts\u002Flib\u002Frepo-scan.mjs",{"path":109,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":110,"sourceHtmlUrl":111},"scripts\u002Flib\u002Fstubs\u002Fexpo-iap.mjs",3991,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fscripts\u002Flib\u002Fstubs\u002Fexpo-iap.mjs",{"path":113,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":114,"sourceHtmlUrl":115},"scripts\u002Fselftest.mjs",1541,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Fscripts\u002Fselftest.mjs",{"path":117,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":118,"sourceHtmlUrl":119},"templates\u002F__mocks__\u002Fexpo-iap.ts",1257,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002F__mocks__\u002Fexpo-iap.ts",{"path":121,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":122,"sourceHtmlUrl":123},"templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F01-buy.yaml",575,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F01-buy.yaml",{"path":125,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":126,"sourceHtmlUrl":127},"templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F02-refund-relaunch.yaml",705,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F02-refund-relaunch.yaml",{"path":129,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":130,"sourceHtmlUrl":131},"templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F03-ask-to-buy.yaml",547,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F03-ask-to-buy.yaml",{"path":133,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":134,"sourceHtmlUrl":135},"templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F04-approval-relaunch.yaml",710,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F04-approval-relaunch.yaml",{"path":137,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":138,"sourceHtmlUrl":139},"templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F05-restore.yaml",828,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F05-restore.yaml",{"path":141,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":142,"sourceHtmlUrl":143},"templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F06-failure.yaml",543,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F06-failure.yaml",{"path":145,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":146,"sourceHtmlUrl":147},"templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F07-store-unavailable.yaml",568,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fe2e\u002Fstorekit\u002F07-store-unavailable.yaml",{"path":149,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":150,"sourceHtmlUrl":151},"templates\u002Fpackages\u002Fshell\u002Fe2e\u002Fsubflows\u002Fdebug-setup.yaml",2373,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fe2e\u002Fsubflows\u002Fdebug-setup.yaml",{"path":153,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":154,"sourceHtmlUrl":155},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fconnectivity-gated-purchase.test.ts",2472,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fconnectivity-gated-purchase.test.ts",{"path":157,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":158,"sourceHtmlUrl":159},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fconnectivity-gated-purchase.ts",1083,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fconnectivity-gated-purchase.ts",{"path":161,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":162,"sourceHtmlUrl":163},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fexpo-iap-purchase-adapter.android.test.ts",8388,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fexpo-iap-purchase-adapter.android.test.ts",{"path":165,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":166,"sourceHtmlUrl":167},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fexpo-iap-purchase-adapter.ts",4974,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fexpo-iap-purchase-adapter.ts",{"path":169,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":170,"sourceHtmlUrl":171},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Ffake-purchase.ts",1357,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Ffake-purchase.ts",{"path":173,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":174,"sourceHtmlUrl":175},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fformat-store-price.test.ts",897,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fformat-store-price.test.ts",{"path":177,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":178,"sourceHtmlUrl":179},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fformat-store-price.ts",694,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fformat-store-price.ts",{"path":181,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":182,"sourceHtmlUrl":183},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fpremium-service.test.ts",5710,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fpremium-service.test.ts",{"path":185,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":186,"sourceHtmlUrl":187},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fpremium-service.ts",5645,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fpremium-service.ts",{"path":189,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":190,"sourceHtmlUrl":191},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fpremium-store-flow.ts",2224,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fpremium-store-flow.ts",{"path":193,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":194,"sourceHtmlUrl":195},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fpurchase-port.ts",2104,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fservices\u002Fpurchase\u002Fpurchase-port.ts",{"path":197,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":198,"sourceHtmlUrl":199},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fentitlement-evidence.test.ts",1529,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fentitlement-evidence.test.ts",{"path":201,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":202,"sourceHtmlUrl":203},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fentitlement-evidence.ts",1393,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fentitlement-evidence.ts",{"path":205,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":206,"sourceHtmlUrl":207},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-flow.android.test.ts",6838,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-flow.android.test.ts",{"path":209,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":210,"sourceHtmlUrl":211},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-notice.test.ts",2817,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-notice.test.ts",{"path":213,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":214,"sourceHtmlUrl":215},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-notice.ts",888,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-notice.ts",{"path":217,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":218,"sourceHtmlUrl":219},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-nudge.test.ts",970,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-nudge.test.ts",{"path":221,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":222,"sourceHtmlUrl":223},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-nudge.ts",903,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-nudge.ts",{"path":225,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":226,"sourceHtmlUrl":227},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-reducer.test.ts",11332,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-reducer.test.ts",{"path":229,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":230,"sourceHtmlUrl":231},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-reducer.ts",2538,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-reducer.ts",{"path":233,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":234,"sourceHtmlUrl":235},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-state.ts",2710,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-state.ts",{"path":237,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":238,"sourceHtmlUrl":239},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-store.test.ts",907,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-store.test.ts",{"path":241,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":242,"sourceHtmlUrl":243},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-store.ts",1355,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-store.ts",{"path":245,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":246,"sourceHtmlUrl":247},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-transitions.test.ts",1923,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-transitions.test.ts",{"path":249,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":250,"sourceHtmlUrl":251},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-transitions.ts",6115,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-transitions.ts",{"path":253,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":254,"sourceHtmlUrl":255},"templates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-view.ts",1594,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Fshell\u002Fsrc\u002Fstores\u002Fpremium\u002Fpremium-view.ts",{"path":257,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":258,"sourceHtmlUrl":259},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fasc-client.ts",1901,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fasc-client.ts",{"path":261,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":262,"sourceHtmlUrl":263},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fasc-credentials.ts",1165,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fasc-credentials.ts",{"path":265,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":266,"sourceHtmlUrl":267},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fasc-jwt.ts",1127,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fasc-jwt.ts",{"path":269,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":270,"sourceHtmlUrl":271},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fcreate-premium-iap.ts",1243,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fcreate-premium-iap.ts",{"path":273,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":274,"sourceHtmlUrl":275},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Ffind-app.test.ts",2953,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Ffind-app.test.ts",{"path":277,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":278,"sourceHtmlUrl":279},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Ffind-app.ts",2153,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Ffind-app.ts",{"path":281,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":282,"sourceHtmlUrl":283},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fpremium-iap-payloads.test.ts",2518,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fpremium-iap-payloads.test.ts",{"path":285,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":286,"sourceHtmlUrl":287},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fpremium-iap-payloads.ts",4041,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fpremium-iap-payloads.ts",{"path":289,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":290,"sourceHtmlUrl":291},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fpremium-iap-setup.test.ts",4026,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fpremium-iap-setup.test.ts",{"path":293,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":294,"sourceHtmlUrl":295},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fpremium-iap-setup.ts",5241,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fasc\u002Fpremium-iap-setup.ts",{"path":297,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":298,"sourceHtmlUrl":299},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fclock\u002Fsystem-clock.ts",584,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fclock\u002Fsystem-clock.ts",{"path":301,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":302,"sourceHtmlUrl":303},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fe2e\u002Fmaestro-args.test.ts",2433,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fe2e\u002Fmaestro-args.test.ts",{"path":305,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":306,"sourceHtmlUrl":307},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fe2e\u002Fmaestro-args.ts",3226,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fe2e\u002Fmaestro-args.ts",{"path":309,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":310,"sourceHtmlUrl":311},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fadd-harness.rb",2078,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fadd-harness.rb",{"path":313,"resourceType":314,"resourceTypeDesc":315,"sizeBytes":316,"sourceHtmlUrl":317},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002FArmTests.swift","OTHER","其他",1864,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002FArmTests.swift",{"path":319,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":320,"sourceHtmlUrl":321},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fbusy-note.test.ts",629,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fbusy-note.test.ts",{"path":323,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":324,"sourceHtmlUrl":325},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fbusy-note.ts",791,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fbusy-note.ts",{"path":327,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":328,"sourceHtmlUrl":329},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fmetro-session.test.ts",2280,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fmetro-session.test.ts",{"path":331,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":332,"sourceHtmlUrl":333},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fmetro-session.ts",1722,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fmetro-session.ts",{"path":335,"resourceType":314,"resourceTypeDesc":315,"sizeBytes":336,"sourceHtmlUrl":337},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002FPremium.storekit.template",616,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002FPremium.storekit.template",{"path":339,"resourceType":314,"resourceTypeDesc":315,"sizeBytes":340,"sourceHtmlUrl":341},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fstorekit-harness.entitlements",224,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fstorekit-harness.entitlements",{"path":343,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":344,"sourceHtmlUrl":345},"templates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fstorekit-harness.ts",9009,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fstorekit-harness.ts",{"path":347,"resourceType":314,"resourceTypeDesc":315,"sizeBytes":348,"sourceHtmlUrl":349},"tests\u002Ffixtures\u002Fbase-repo\u002F.claude\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002FPremium.storekit",19,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002F.claude\u002Fskills\u002Fpremium-purchase\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002FPremium.storekit",{"path":351,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":352,"sourceHtmlUrl":353},"tests\u002Ffixtures\u002Fbase-repo\u002Fapps\u002Fdemo-game\u002Fgame.config.ts",216,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fapps\u002Fdemo-game\u002Fgame.config.ts",{"path":355,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":356,"sourceHtmlUrl":357},"tests\u002Ffixtures\u002Fbase-repo\u002Fapps\u002Fdemo-game\u002Fpackage.json",99,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fapps\u002Fdemo-game\u002Fpackage.json",{"path":359,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":360,"sourceHtmlUrl":361},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackage.json",189,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackage.json",{"path":363,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":364,"sourceHtmlUrl":365},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fpackage.json",115,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fpackage.json",{"path":367,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":368,"sourceHtmlUrl":369},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fapp\u002Fconnect-premium-reloads.ts",1210,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fapp\u002Fconnect-premium-reloads.ts",{"path":371,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":372,"sourceHtmlUrl":373},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fapp\u002Fcreate-purchase-port.ts",533,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fapp\u002Fcreate-purchase-port.ts",{"path":375,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":376,"sourceHtmlUrl":377},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fapp\u002Fparity\u002Fparity-purchase.ts",243,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fapp\u002Fparity\u002Fparity-purchase.ts",{"path":379,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":380,"sourceHtmlUrl":381},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fconfig\u002Fshell-plugins.ts",244,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fconfig\u002Fshell-plugins.ts",{"path":383,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":384,"sourceHtmlUrl":385},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fi18n\u002Fcatalogs\u002Fckb.json",2286,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fi18n\u002Fcatalogs\u002Fckb.json",{"path":387,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":388,"sourceHtmlUrl":389},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fi18n\u002Fcatalogs\u002Fde.json",1762,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fi18n\u002Fcatalogs\u002Fde.json",{"path":391,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":392,"sourceHtmlUrl":393},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fi18n\u002Fcatalogs\u002Fen.json",1613,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fi18n\u002Fcatalogs\u002Fen.json",{"path":395,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":396,"sourceHtmlUrl":397},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fi18n\u002Fcatalogs\u002Ffa.json",2204,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fi18n\u002Fcatalogs\u002Ffa.json",{"path":399,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":400,"sourceHtmlUrl":401},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fscreens\u002Fpremium\u002Fpremium-state-ids.ts",841,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Fshell\u002Fsrc\u002Fscreens\u002Fpremium\u002Fpremium-state-ids.ts",{"path":403,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":404,"sourceHtmlUrl":405},"tests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Ftooling\u002Fsrc\u002Fi18n\u002Fverify-catalogs.ts",153,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fpackages\u002Ftooling\u002Fsrc\u002Fi18n\u002Fverify-catalogs.ts",{"path":407,"resourceType":314,"resourceTypeDesc":315,"sizeBytes":408,"sourceHtmlUrl":409},"tests\u002Ffixtures\u002Fbase-repo\u002Fskills\u002Fios-release-testflight\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fstorekit-harness.entitlements",114,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fskills\u002Fios-release-testflight\u002Ftemplates\u002Fpackages\u002Ftooling\u002Fsrc\u002Fstorekit\u002Fstorekit-harness.entitlements",{"path":411,"resourceType":84,"resourceTypeDesc":85,"sizeBytes":412,"sourceHtmlUrl":413},"tests\u002Ffixtures\u002Fbase-repo\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbad\u002Fapps\u002Fdemo-game\u002Fharness.ts",102,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbase-repo\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fbad\u002Fapps\u002Fdemo-game\u002Fharness.ts",{"path":415,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":416,"sourceHtmlUrl":417},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-deferred-as-failed\u002FEXPECT.txt",49,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-deferred-as-failed\u002FEXPECT.txt",{"path":419,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":420,"sourceHtmlUrl":421},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-deferred-as-failed\u002Fmutation.json",231,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-deferred-as-failed\u002Fmutation.json",{"path":423,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":424,"sourceHtmlUrl":425},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-drops-revocation\u002FEXPECT.txt",73,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-drops-revocation\u002FEXPECT.txt",{"path":427,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":428,"sourceHtmlUrl":429},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-drops-revocation\u002Fmutation.json",210,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-drops-revocation\u002Fmutation.json",{"path":431,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":432,"sourceHtmlUrl":433},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-ignores-acknowledged\u002FEXPECT.txt",79,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-ignores-acknowledged\u002FEXPECT.txt",{"path":435,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":436,"sourceHtmlUrl":437},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-ignores-acknowledged\u002Fmutation.json",211,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-ignores-acknowledged\u002Fmutation.json",{"path":439,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":440,"sourceHtmlUrl":441},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-restore-rethrows\u002FEXPECT.txt",81,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-restore-rethrows\u002FEXPECT.txt",{"path":443,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":444,"sourceHtmlUrl":445},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-restore-rethrows\u002Fmutation.json",383,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-restore-rethrows\u002Fmutation.json",{"path":447,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":448,"sourceHtmlUrl":449},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-restore-swallows-failure\u002FEXPECT.txt",53,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-restore-swallows-failure\u002FEXPECT.txt",{"path":451,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":452,"sourceHtmlUrl":453},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-restore-swallows-failure\u002Fmutation.json",230,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-adapter-restore-swallows-failure\u002Fmutation.json",{"path":455,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":456,"sourceHtmlUrl":457},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-pending-granted\u002FEXPECT.txt",107,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-pending-granted\u002FEXPECT.txt",{"path":459,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":460,"sourceHtmlUrl":461},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-pending-granted\u002Fmutation.json",298,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-pending-granted\u002Fmutation.json",{"path":463,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":356,"sourceHtmlUrl":464},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-query-swallowed\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-query-swallowed\u002FEXPECT.txt",{"path":466,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":467,"sourceHtmlUrl":468},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-query-swallowed\u002Fmutation.json",345,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-query-swallowed\u002Fmutation.json",{"path":470,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":471,"sourceHtmlUrl":472},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-unknown-revokes\u002FEXPECT.txt",97,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-unknown-revokes\u002FEXPECT.txt",{"path":474,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":475,"sourceHtmlUrl":476},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-unknown-revokes\u002Fmutation.json",495,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-android-unknown-revokes\u002Fmutation.json",{"path":478,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":479,"sourceHtmlUrl":480},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-display-price-only\u002FEXPECT.txt",22,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-display-price-only\u002FEXPECT.txt",{"path":482,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":452,"sourceHtmlUrl":483},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-display-price-only\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-display-price-only\u002Fmutation.json",{"path":485,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":486,"sourceHtmlUrl":487},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-duplicate-failure\u002FEXPECT.txt",45,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-duplicate-failure\u002FEXPECT.txt",{"path":489,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":490,"sourceHtmlUrl":491},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-duplicate-failure\u002Fmutation.json",323,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-duplicate-failure\u002Fmutation.json",{"path":493,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":494,"sourceHtmlUrl":495},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-empty-after-failed-sync\u002FEXPECT.txt",46,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-empty-after-failed-sync\u002FEXPECT.txt",{"path":497,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":498,"sourceHtmlUrl":499},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-empty-after-failed-sync\u002Fmutation.json",329,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-empty-after-failed-sync\u002Fmutation.json",{"path":501,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":502,"sourceHtmlUrl":503},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-empty-product-silent\u002FEXPECT.txt",56,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-empty-product-silent\u002FEXPECT.txt",{"path":505,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":506,"sourceHtmlUrl":507},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-empty-product-silent\u002Fmutation.json",297,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-empty-product-silent\u002Fmutation.json",{"path":509,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":510,"sourceHtmlUrl":511},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-finish-first\u002FEXPECT.txt",55,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-finish-first\u002FEXPECT.txt",{"path":513,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":514,"sourceHtmlUrl":515},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-finish-first\u002Fmutation.json",764,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-finish-first\u002Fmutation.json",{"path":517,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":518,"sourceHtmlUrl":519},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-finish-unsaved\u002FEXPECT.txt",66,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-finish-unsaved\u002FEXPECT.txt",{"path":521,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":522,"sourceHtmlUrl":523},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-finish-unsaved\u002Fmutation.json",168,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-finish-unsaved\u002Fmutation.json",{"path":525,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":416,"sourceHtmlUrl":526},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-gate-connects-offline\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-gate-connects-offline\u002FEXPECT.txt",{"path":528,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":420,"sourceHtmlUrl":529},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-gate-connects-offline\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-gate-connects-offline\u002Fmutation.json",{"path":531,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":510,"sourceHtmlUrl":532},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-listen-late\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-listen-late\u002FEXPECT.txt",{"path":534,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":535,"sourceHtmlUrl":536},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-listen-late\u002Fmutation.json",440,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-listen-late\u002Fmutation.json",{"path":538,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":539,"sourceHtmlUrl":540},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-missing-module\u002FEXPECT.txt",51,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-missing-module\u002FEXPECT.txt",{"path":542,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":543,"sourceHtmlUrl":544},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-missing-module\u002Fmutation.json",87,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-missing-module\u002Fmutation.json",{"path":546,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":416,"sourceHtmlUrl":547},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-foreground-recheck\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-foreground-recheck\u002FEXPECT.txt",{"path":549,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":550,"sourceHtmlUrl":551},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-foreground-recheck\u002Fmutation.json",68,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-foreground-recheck\u002Fmutation.json",{"path":553,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":494,"sourceHtmlUrl":554},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-restore-toast\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-restore-toast\u002FEXPECT.txt",{"path":556,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":557,"sourceHtmlUrl":558},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-restore-toast\u002Fmutation.json",206,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-restore-toast\u002Fmutation.json",{"path":560,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":561,"sourceHtmlUrl":562},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-store-reload\u002FEXPECT.txt",57,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-store-reload\u002FEXPECT.txt",{"path":564,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":340,"sourceHtmlUrl":565},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-store-reload\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-no-store-reload\u002Fmutation.json",{"path":567,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":568,"sourceHtmlUrl":569},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-nudge-every-result\u002FEXPECT.txt",35,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-nudge-every-result\u002FEXPECT.txt",{"path":571,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":420,"sourceHtmlUrl":572},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-nudge-every-result\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-nudge-every-result\u002Fmutation.json",{"path":574,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":575,"sourceHtmlUrl":576},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-read-after-failed-sync\u002FEXPECT.txt",32,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-read-after-failed-sync\u002FEXPECT.txt",{"path":578,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":579,"sourceHtmlUrl":580},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-read-after-failed-sync\u002Fmutation.json",246,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-read-after-failed-sync\u002Fmutation.json",{"path":582,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":583,"sourceHtmlUrl":584},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-recheck-leaves-unfinished\u002FEXPECT.txt",72,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-recheck-leaves-unfinished\u002FEXPECT.txt",{"path":586,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":587,"sourceHtmlUrl":588},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-recheck-leaves-unfinished\u002Fmutation.json",339,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-recheck-leaves-unfinished\u002Fmutation.json",{"path":590,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":591,"sourceHtmlUrl":592},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-reload-no-recheck\u002FEXPECT.txt",52,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-reload-no-recheck\u002FEXPECT.txt",{"path":594,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":595,"sourceHtmlUrl":596},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-reload-no-recheck\u002Fmutation.json",254,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-reload-no-recheck\u002Fmutation.json",{"path":598,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":599,"sourceHtmlUrl":600},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-reload-while-buying\u002FEXPECT.txt",59,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-reload-while-buying\u002FEXPECT.txt",{"path":602,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":603,"sourceHtmlUrl":604},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-reload-while-buying\u002Fmutation.json",281,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-reload-while-buying\u002Fmutation.json",{"path":606,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":424,"sourceHtmlUrl":607},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-restore-shows-thanks\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-restore-shows-thanks\u002FEXPECT.txt",{"path":609,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":610,"sourceHtmlUrl":611},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-restore-shows-thanks\u002Fmutation.json",302,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-restore-shows-thanks\u002Fmutation.json",{"path":613,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":614,"sourceHtmlUrl":615},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoke-on-absence\u002FEXPECT.txt",39,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoke-on-absence\u002FEXPECT.txt",{"path":617,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":444,"sourceHtmlUrl":618},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoke-on-absence\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoke-on-absence\u002Fmutation.json",{"path":620,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":621,"sourceHtmlUrl":622},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoke-without-date\u002FEXPECT.txt",47,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoke-without-date\u002FEXPECT.txt",{"path":624,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":625,"sourceHtmlUrl":626},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoke-without-date\u002Fmutation.json",256,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoke-without-date\u002Fmutation.json",{"path":628,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":629,"sourceHtmlUrl":630},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoked-beats-owned\u002FEXPECT.txt",43,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoked-beats-owned\u002FEXPECT.txt",{"path":632,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":633,"sourceHtmlUrl":634},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoked-beats-owned\u002Fmutation.json",611,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-revoked-beats-owned\u002Fmutation.json",{"path":636,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":637,"sourceHtmlUrl":638},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-thanks-at-launch\u002FEXPECT.txt",63,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-thanks-at-launch\u002FEXPECT.txt",{"path":640,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":641,"sourceHtmlUrl":642},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-thanks-at-launch\u002Fmutation.json",218,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fbad-thanks-at-launch\u002Fmutation.json",{"path":644,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":599,"sourceHtmlUrl":645},"tests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fgood\u002FCASE.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium-behaviour\u002Fgood\u002FCASE.txt",{"path":647,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":621,"sourceHtmlUrl":648},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-active-only\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-active-only\u002FEXPECT.txt",{"path":650,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":352,"sourceHtmlUrl":651},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-active-only\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-active-only\u002Fmutation.json",{"path":653,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":654,"sourceHtmlUrl":655},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-ack-in-listener\u002FEXPECT.txt",112,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-ack-in-listener\u002FEXPECT.txt",{"path":657,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":490,"sourceHtmlUrl":658},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-ack-in-listener\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-ack-in-listener\u002Fmutation.json",{"path":660,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":471,"sourceHtmlUrl":661},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-consumed\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-consumed\u002FEXPECT.txt",{"path":663,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":664,"sourceHtmlUrl":665},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-consumed\u002Fmutation.json",322,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-consumed\u002Fmutation.json",{"path":667,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":668,"sourceHtmlUrl":669},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-kotlin-version\u002FEXPECT.txt",67,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-kotlin-version\u002FEXPECT.txt",{"path":671,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":672,"sourceHtmlUrl":673},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-kotlin-version\u002Fmutation.json",176,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-kotlin-version\u002Fmutation.json",{"path":675,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":676,"sourceHtmlUrl":677},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-no-kotlin\u002FEXPECT.txt",74,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-no-kotlin\u002FEXPECT.txt",{"path":679,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":680,"sourceHtmlUrl":681},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-no-kotlin\u002Fmutation.json",199,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-no-kotlin\u002Fmutation.json",{"path":683,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":684,"sourceHtmlUrl":685},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-pending-as-purchased\u002FEXPECT.txt",92,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-pending-as-purchased\u002FEXPECT.txt",{"path":687,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":460,"sourceHtmlUrl":688},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-pending-as-purchased\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-android-pending-as-purchased\u002Fmutation.json",{"path":690,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":691,"sourceHtmlUrl":692},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-auto-finish\u002FEXPECT.txt",58,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-auto-finish\u002FEXPECT.txt",{"path":694,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":695,"sourceHtmlUrl":696},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-auto-finish\u002Fmutation.json",327,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-auto-finish\u002Fmutation.json",{"path":698,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":676,"sourceHtmlUrl":699},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalog-missing-key\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalog-missing-key\u002FEXPECT.txt",{"path":701,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":702,"sourceHtmlUrl":703},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalog-missing-key\u002Fmutation.json",161,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalog-missing-key\u002Fmutation.json",{"path":705,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":510,"sourceHtmlUrl":706},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalog-typed-price\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalog-typed-price\u002FEXPECT.txt",{"path":708,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":709,"sourceHtmlUrl":710},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalog-typed-price\u002Fmutation.json",181,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalog-typed-price\u002Fmutation.json",{"path":712,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":494,"sourceHtmlUrl":713},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalogs-missing-once-due\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalogs-missing-once-due\u002FEXPECT.txt",{"path":715,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":716,"sourceHtmlUrl":717},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalogs-missing-once-due\u002Fmutation.json",61,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-catalogs-missing-once-due\u002Fmutation.json",{"path":719,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":720,"sourceHtmlUrl":721},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-consumable\u002FEXPECT.txt",36,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-consumable\u002FEXPECT.txt",{"path":723,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":724,"sourceHtmlUrl":725},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-consumable\u002Fmutation.json",190,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-consumable\u002Fmutation.json",{"path":727,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":668,"sourceHtmlUrl":728},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-debug-premium-in-app\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-debug-premium-in-app\u002FEXPECT.txt",{"path":730,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":731,"sourceHtmlUrl":732},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-debug-premium-in-app\u002Fmutation.json",419,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-debug-premium-in-app\u002Fmutation.json",{"path":734,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":735,"sourceHtmlUrl":736},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-family-sharing\u002FEXPECT.txt",17,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-family-sharing\u002FEXPECT.txt",{"path":738,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":739,"sourceHtmlUrl":740},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-family-sharing\u002Fmutation.json",177,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-family-sharing\u002Fmutation.json",{"path":742,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":743,"sourceHtmlUrl":744},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-flow-in-flows\u002FEXPECT.txt",65,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-flow-in-flows\u002FEXPECT.txt",{"path":746,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":747,"sourceHtmlUrl":748},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-flow-in-flows\u002Fmutation.json",169,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-flow-in-flows\u002Fmutation.json",{"path":750,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":751,"sourceHtmlUrl":752},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-generated-storekit-family-sharing\u002FEXPECT.txt",77,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-generated-storekit-family-sharing\u002FEXPECT.txt",{"path":754,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":755,"sourceHtmlUrl":756},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-generated-storekit-family-sharing\u002Fmutation.json",819,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-generated-storekit-family-sharing\u002Fmutation.json",{"path":758,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":759,"sourceHtmlUrl":760},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-get-task-allow\u002FEXPECT.txt",44,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-get-task-allow\u002FEXPECT.txt",{"path":762,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":452,"sourceHtmlUrl":763},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-get-task-allow\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-get-task-allow\u002Fmutation.json",{"path":765,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":356,"sourceHtmlUrl":766},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-maestro-env\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-maestro-env\u002FEXPECT.txt",{"path":768,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":769,"sourceHtmlUrl":770},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-maestro-env\u002Fmutation.json",473,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-maestro-env\u002Fmutation.json",{"path":772,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":773,"sourceHtmlUrl":774},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-maestro-udid\u002FEXPECT.txt",91,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-maestro-udid\u002FEXPECT.txt",{"path":776,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":777,"sourceHtmlUrl":778},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-maestro-udid\u002Fmutation.json",242,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-maestro-udid\u002Fmutation.json",{"path":780,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":781,"sourceHtmlUrl":782},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-relaunch-wait\u002FEXPECT.txt",303,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-relaunch-wait\u002FEXPECT.txt",{"path":784,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":785,"sourceHtmlUrl":786},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-relaunch-wait\u002Fmutation.json",467,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-relaunch-wait\u002Fmutation.json",{"path":788,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":789,"sourceHtmlUrl":790},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-shared-port\u002FEXPECT.txt",106,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-shared-port\u002FEXPECT.txt",{"path":792,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":793,"sourceHtmlUrl":794},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-shared-port\u002Fmutation.json",325,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-harness-shared-port\u002Fmutation.json",{"path":796,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":797,"sourceHtmlUrl":798},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-import-outside\u002FEXPECT.txt",71,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-import-outside\u002FEXPECT.txt",{"path":800,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":801,"sourceHtmlUrl":802},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-import-outside\u002Fmutation.json",251,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-import-outside\u002Fmutation.json",{"path":804,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":805,"sourceHtmlUrl":806},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-kitapi\u002FEXPECT.txt",38,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-kitapi\u002FEXPECT.txt",{"path":808,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":809,"sourceHtmlUrl":810},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-kitapi\u002Fmutation.json",202,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-kitapi\u002Fmutation.json",{"path":812,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":813,"sourceHtmlUrl":814},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-missing-notice\u002FEXPECT.txt",34,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-missing-notice\u002FEXPECT.txt",{"path":816,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":817,"sourceHtmlUrl":818},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-missing-notice\u002Fmutation.json",80,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-missing-notice\u002Fmutation.json",{"path":820,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":821,"sourceHtmlUrl":822},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-no-plugin\u002FEXPECT.txt",15,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-no-plugin\u002FEXPECT.txt",{"path":824,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":825,"sourceHtmlUrl":826},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-no-plugin\u002Fmutation.json",148,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-no-plugin\u002Fmutation.json",{"path":828,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":829,"sourceHtmlUrl":830},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-not-yet-due\u002FEXPECT.txt",300,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-not-yet-due\u002FEXPECT.txt",{"path":832,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":833,"sourceHtmlUrl":834},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-not-yet-due\u002Fmutation.json",307,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-not-yet-due\u002Fmutation.json",{"path":836,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":837,"sourceHtmlUrl":838},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-onside-env\u002FEXPECT.txt",33,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-onside-env\u002FEXPECT.txt",{"path":840,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":841,"sourceHtmlUrl":842},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-onside-env\u002Fmutation.json",197,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-onside-env\u002Fmutation.json",{"path":844,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":424,"sourceHtmlUrl":845},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-plugin-options\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-plugin-options\u002FEXPECT.txt",{"path":847,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":709,"sourceHtmlUrl":848},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-plugin-options\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-plugin-options\u002Fmutation.json",{"path":850,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":404,"sourceHtmlUrl":851},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-price-target\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-price-target\u002FEXPECT.txt",{"path":853,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":854,"sourceHtmlUrl":855},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-price-target\u002Fmutation.json",431,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-price-target\u002Fmutation.json",{"path":857,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":629,"sourceHtmlUrl":858},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-product-id\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-product-id\u002FEXPECT.txt",{"path":860,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":841,"sourceHtmlUrl":861},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-product-id\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-product-id\u002Fmutation.json",{"path":863,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":805,"sourceHtmlUrl":864},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-sdk-caret\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-sdk-caret\u002FEXPECT.txt",{"path":866,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":747,"sourceHtmlUrl":867},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-sdk-caret\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-sdk-caret\u002Fmutation.json",{"path":869,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":870,"sourceHtmlUrl":871},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-sktestsession-in-app\u002FEXPECT.txt",60,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-sktestsession-in-app\u002FEXPECT.txt",{"path":873,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":874,"sourceHtmlUrl":875},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-sktestsession-in-app\u002Fmutation.json",203,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-sktestsession-in-app\u002Fmutation.json",{"path":877,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":805,"sourceHtmlUrl":878},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-state-testid\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-state-testid\u002FEXPECT.txt",{"path":880,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":881,"sourceHtmlUrl":882},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-state-testid\u002Fmutation.json",180,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-state-testid\u002Fmutation.json",{"path":884,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":684,"sourceHtmlUrl":885},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-store-not-gated\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-store-not-gated\u002FEXPECT.txt",{"path":887,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":888,"sourceHtmlUrl":889},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-store-not-gated\u002Fmutation.json",284,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-store-not-gated\u002Fmutation.json",{"path":891,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":892,"sourceHtmlUrl":893},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-consumable\u002FEXPECT.txt",18,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-consumable\u002FEXPECT.txt",{"path":895,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":896,"sourceHtmlUrl":897},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-consumable\u002Fmutation.json",196,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-consumable\u002Fmutation.json",{"path":899,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":684,"sourceHtmlUrl":900},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-display-price\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-display-price\u002FEXPECT.txt",{"path":902,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":680,"sourceHtmlUrl":903},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-display-price\u002Fmutation.json","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-display-price\u002Fmutation.json",{"path":905,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":591,"sourceHtmlUrl":906},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-file-in-app\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-file-in-app\u002FEXPECT.txt",{"path":908,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":909,"sourceHtmlUrl":910},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-file-in-app\u002Fmutation.json",124,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-storekit-file-in-app\u002Fmutation.json",{"path":912,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":424,"sourceHtmlUrl":913},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-typed-price\u002FEXPECT.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-typed-price\u002FEXPECT.txt",{"path":915,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":916,"sourceHtmlUrl":917},"tests\u002Ffixtures\u002Fcheck-premium\u002Fbad-typed-price\u002Fmutation.json",249,"https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fbad-typed-price\u002Fmutation.json",{"path":919,"resourceType":58,"resourceTypeDesc":59,"sizeBytes":599,"sourceHtmlUrl":920},"tests\u002Ffixtures\u002Fcheck-premium\u002Fgood\u002FCASE.txt","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Fpremium-purchase\u002Ftests\u002Ffixtures\u002Fcheck-premium\u002Fgood\u002FCASE.txt",[922,929,936,943,948,955],{"skillNo":923,"name":924,"nameZh":6,"description":925,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":926,"categories":927,"keywords":928,"publishedAt":19},"01M7DFK8QE5P9TME3GRJC5716K","unit-and-component-tests","Sets up Jest and writes Pocket Arcade test code - three projects, RNTL 14 async via renderWithShell, root SDK mocks, fakes, fast-check, coverage, Stryker. Use when a test needs the Shell wrapper, a mock or a fake, or Jest fails. Not for the red-green loop (tdd-workflow) or goldens (golden-tests).","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Funit-and-component-tests\u002FSKILL.md",[],[],{"skillNo":930,"name":931,"nameZh":6,"description":932,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":933,"categories":934,"keywords":935,"publishedAt":19},"01M7DFK0YRGRX0S7FB79KSKK7F","typescript-and-lint-rules","Enforces Pocket Arcade's strict TypeScript 6 tsconfigs, ESLint 9 flat config, Prettier and size limits. Use when writing or splitting .ts\u002F.tsx or fixing a tsc or lint error. Not for gate wiring (quality-gates), names (naming-conventions) or import zones (architecture-and-boundaries).","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Ftypescript-and-lint-rules\u002FSKILL.md",[],[],{"skillNo":937,"name":938,"nameZh":6,"description":939,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":940,"categories":941,"keywords":942,"publishedAt":19},"01M7DFJZB14VQ3F8A6A5G8D5BY","demo-skill","Builds a demo. Use when testing the pitfall checker.","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Ftroubleshooting-playbook\u002Ftests\u002Ffixtures\u002Fcheck-known-pitfalls\u002Fgood\u002Fskills\u002Fdemo-skill\u002FSKILL.md",[],[],{"skillNo":944,"name":938,"nameZh":6,"description":939,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":945,"categories":946,"keywords":947,"publishedAt":19},"01M7DFJXMSA9Y9K6DF4CJJ2XPZ","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Ftroubleshooting-playbook\u002Ftests\u002Ffixtures\u002Fcheck-known-pitfalls\u002Fbad-configs\u002Fskills\u002Fdemo-skill\u002FSKILL.md",[],[],{"skillNo":949,"name":950,"nameZh":6,"description":951,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":952,"categories":953,"keywords":954,"publishedAt":19},"01M7DFJKZXFJ7403V3YNE83MBS","troubleshooting-playbook","Diagnoses and fixes Pocket Arcade failures with a catalogue of 300+ known ones (symptom, cause, fix). Use when something errors, crashes, hangs or renders wrong, or an error or log needs explaining. Not for gate setup (quality-gates) or running builds (ios-simulator-build, ios-release-testflight).","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Ftroubleshooting-playbook\u002FSKILL.md",[],[],{"skillNo":956,"name":957,"nameZh":6,"description":958,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":959,"categories":960,"keywords":961,"publishedAt":19},"01M7DFJ7FGGWGMV63YW4VT4QPX","toybox-visual-parity","Proves a built Pocket Arcade screen matches its Toybox design screenshot (light\u002Fdark, en\u002Ffa) and drives the fixes: capture, element gates, sheets, sign-off. Use when any screen is built or changed, or for visual parity, design match, screenshot compare. Not for building screens (toybox-screens).","https:\u002F\u002Fgithub.com\u002Fzakariaf\u002Fpocket-arcade\u002Fblob\u002Fmain\u002Fskills\u002Ftoybox-visual-parity\u002FSKILL.md",[],[]]