[{"data":1,"prerenderedAt":2035},["ShallowReactive",2],{"navigation_docs":3,"-sdks-flutter":233,"-sdks-flutter-surround":2030},[4,36,67,122,187,207,223],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":35},"Getting started","i-lucide-rocket","\u002Fgetting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"What is Rabolic","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":16,"path":17,"stem":18,"icon":19},"Quickstart","\u002Fgetting-started\u002Fquickstart","1.getting-started\u002F2.quickstart","i-lucide-zap",{"title":21,"path":22,"stem":23,"icon":24},"Keys","\u002Fgetting-started\u002Fkeys","1.getting-started\u002F3.keys","i-lucide-key-round",{"title":26,"path":27,"stem":28,"icon":29},"Setup CLI","\u002Fgetting-started\u002Fsetup-cli","1.getting-started\u002F4.setup-cli","i-lucide-terminal",{"title":31,"path":32,"stem":33,"icon":34},"Trial","\u002Fgetting-started\u002Ftrial","1.getting-started\u002F5.trial","i-lucide-hourglass",false,{"title":37,"icon":38,"path":39,"stem":40,"children":41,"page":35},"SDKs and API","i-lucide-code","\u002Fsdks","2.sdks",[42,47,52,57,62],{"title":43,"path":44,"stem":45,"icon":46},"Web","\u002Fsdks\u002Fweb","2.sdks\u002F1.web","i-lucide-globe",{"title":48,"path":49,"stem":50,"icon":51},"React Native and Expo","\u002Fsdks\u002Freact-native","2.sdks\u002F2.react-native","i-simple-icons-react",{"title":53,"path":54,"stem":55,"icon":56},"Flutter","\u002Fsdks\u002Fflutter","2.sdks\u002F3.flutter","i-simple-icons-flutter",{"title":58,"path":59,"stem":60,"icon":61},"Node.js","\u002Fsdks\u002Fnode","2.sdks\u002F4.node","i-simple-icons-nodedotjs",{"title":63,"path":64,"stem":65,"icon":66},"Ingest HTTP API","\u002Fsdks\u002Fhttp-api","2.sdks\u002F5.http-api","i-lucide-send",{"title":68,"icon":69,"path":70,"stem":71,"children":72,"page":35},"Concepts","i-lucide-lightbulb","\u002Fconcepts","3.concepts",[73,77,82,87,92,97,102,107,112,117],{"title":74,"path":75,"stem":76,"icon":19},"Events","\u002Fconcepts\u002Fevents","3.concepts\u002F01.events",{"title":78,"path":79,"stem":80,"icon":81},"Identity","\u002Fconcepts\u002Fidentity","3.concepts\u002F02.identity","i-lucide-fingerprint",{"title":83,"path":84,"stem":85,"icon":86},"Sessions","\u002Fconcepts\u002Fsessions","3.concepts\u002F03.sessions","i-lucide-activity",{"title":88,"path":89,"stem":90,"icon":91},"Key events and conversions","\u002Fconcepts\u002Fkey-events-and-conversions","3.concepts\u002F04.key-events-and-conversions","i-lucide-star",{"title":93,"path":94,"stem":95,"icon":96},"Funnels","\u002Fconcepts\u002Ffunnels","3.concepts\u002F05.funnels","i-lucide-filter",{"title":98,"path":99,"stem":100,"icon":101},"Journeys","\u002Fconcepts\u002Fjourneys","3.concepts\u002F06.journeys","i-lucide-route",{"title":103,"path":104,"stem":105,"icon":106},"Retention","\u002Fconcepts\u002Fretention","3.concepts\u002F07.retention","i-lucide-repeat",{"title":108,"path":109,"stem":110,"icon":111},"Revenue and attribution","\u002Fconcepts\u002Frevenue-and-attribution","3.concepts\u002F08.revenue-and-attribution","i-lucide-wallet",{"title":113,"path":114,"stem":115,"icon":116},"Consent and privacy","\u002Fconcepts\u002Fprivacy","3.concepts\u002F09.privacy","i-lucide-shield-check",{"title":118,"path":119,"stem":120,"icon":121},"Data retention","\u002Fconcepts\u002Fdata-retention","3.concepts\u002F10.data-retention","i-lucide-archive",{"title":123,"icon":124,"path":125,"stem":126,"children":127,"page":35},"Using the dashboard","i-lucide-layout-dashboard","\u002Fdashboard","4.dashboard",[128,133,138,143,146,151,154,157,160,163,167,172,177,182],{"title":129,"path":130,"stem":131,"icon":132},"Overview","\u002Fdashboard\u002Foverview","4.dashboard\u002F01.overview","i-lucide-gauge",{"title":134,"path":135,"stem":136,"icon":137},"Live","\u002Fdashboard\u002Flive","4.dashboard\u002F02.live","i-lucide-radio",{"title":139,"path":140,"stem":141,"icon":142},"Analytics","\u002Fdashboard\u002Fanalytics","4.dashboard\u002F03.analytics","i-lucide-bar-chart-3",{"title":74,"path":144,"stem":145,"icon":19},"\u002Fdashboard\u002Fevents","4.dashboard\u002F04.events",{"title":147,"path":148,"stem":149,"icon":150},"Users","\u002Fdashboard\u002Fusers","4.dashboard\u002F05.users","i-lucide-users",{"title":83,"path":152,"stem":153,"icon":86},"\u002Fdashboard\u002Fsessions","4.dashboard\u002F06.sessions",{"title":93,"path":155,"stem":156,"icon":96},"\u002Fdashboard\u002Ffunnels","4.dashboard\u002F07.funnels",{"title":98,"path":158,"stem":159,"icon":101},"\u002Fdashboard\u002Fjourneys","4.dashboard\u002F08.journeys",{"title":103,"path":161,"stem":162,"icon":106},"\u002Fdashboard\u002Fretention","4.dashboard\u002F09.retention",{"title":164,"path":165,"stem":166,"icon":111},"Revenue","\u002Fdashboard\u002Frevenue","4.dashboard\u002F10.revenue",{"title":168,"path":169,"stem":170,"icon":171},"Alerts","\u002Fdashboard\u002Falerts","4.dashboard\u002F11.alerts","i-lucide-bell",{"title":173,"path":174,"stem":175,"icon":176},"Integrations","\u002Fdashboard\u002Fintegrations","4.dashboard\u002F12.integrations","i-lucide-plug-zap",{"title":178,"path":179,"stem":180,"icon":181},"Project settings","\u002Fdashboard\u002Fproject-settings","4.dashboard\u002F13.project-settings","i-lucide-settings",{"title":183,"path":184,"stem":185,"icon":186},"Organizations and roles","\u002Fdashboard\u002Forganizations-and-roles","4.dashboard\u002F14.organizations-and-roles","i-lucide-building-2",{"title":188,"icon":189,"path":190,"stem":191,"children":192,"page":35},"Plans and billing","i-lucide-credit-card","\u002Fbilling","5.billing",[193,198,202],{"title":194,"path":195,"stem":196,"icon":197},"Plans","\u002Fbilling\u002Fplans","5.billing\u002F1.plans","i-lucide-tags",{"title":199,"path":200,"stem":201,"icon":132},"Usage and overage","\u002Fbilling\u002Fusage-and-overage","5.billing\u002F2.usage-and-overage",{"title":203,"path":204,"stem":205,"icon":206},"Read-only and deletion","\u002Fbilling\u002Fread-only-and-deletion","5.billing\u002F3.read-only-and-deletion","i-lucide-lock",{"title":208,"icon":209,"path":210,"stem":211,"children":212,"page":35},"Limits and troubleshooting","i-lucide-life-buoy","\u002Flimits","6.limits",[213,218],{"title":214,"path":215,"stem":216,"icon":217},"Limits","\u002Flimits\u002Flimits","6.limits\u002F1.limits","i-lucide-ruler",{"title":219,"path":220,"stem":221,"icon":222},"Events not showing","\u002Flimits\u002Ftroubleshooting","6.limits\u002F2.troubleshooting","i-lucide-search-check",{"title":224,"icon":225,"path":226,"stem":227,"children":228,"page":35},"AI connector","i-lucide-sparkles","\u002Fai","7.ai",[229],{"title":224,"path":230,"stem":231,"icon":232},"\u002Fai\u002Fconnector","7.ai\u002F1.connector","i-lucide-plug",{"id":234,"title":53,"body":235,"description":2021,"extension":2022,"links":2023,"meta":2024,"navigation":2025,"path":54,"seo":2026,"stem":55,"__hash__":2029},"docs\u002F2.sdks\u002F3.flutter.md",{"type":236,"value":237,"toc":1999},"minimark",[238,265,276,281,310,323,327,501,507,514,518,671,678,682,691,895,909,913,919,956,960,975,1107,1126,1129,1187,1202,1206,1217,1304,1311,1315,1321,1396,1402,1405,1427,1430,1442,1446,1458,1525,1548,1567,1571,1584,1607,1613,1672,1677,1681,1732,1752,1756,1759,1762,1766,1789,1812,1822,1826,1829,1850,1855,1858,1939,1942,1995],[239,240,241,245,246,250,251,258,259,264],"p",{},[242,243,244],"code",{},"rabolic_flutter"," is one pure-Dart SDK for ",[247,248,249],"strong",{},"iOS, Android and Flutter web",", with no platform channels of its own. Events survive restarts and offline periods in a persisted queue, and are sent in batches with retry and backoff. Package: ",[252,253,257],"a",{"href":254,"rel":255},"https:\u002F\u002Fpub.dev\u002Fpackages\u002Frabolic_flutter",[256],"nofollow","pub.dev\u002Fpackages\u002Frabolic_flutter",". Source: ",[252,260,263],{"href":261,"rel":262},"https:\u002F\u002Fgithub.com\u002Frabolic\u002Fsdks\u002Ftree\u002Fmain\u002Fflutter",[256],"github.com\u002Frabolic\u002Fsdks\u002Fflutter",".",[239,266,267,268,271,272,275],{},"Use the project's ",[247,269,270],{},"publishable key"," (",[242,273,274],{},"rb_pub_…",").",[277,278,280],"h2",{"id":279},"install","Install",[282,283,289],"pre",{"className":284,"code":285,"filename":286,"language":287,"meta":288,"style":288},"language-bash shiki shiki-themes github-light-default github-light-default github-dark-default","flutter pub add rabolic_flutter\n","Terminal","bash","",[242,290,291],{"__ignoreMap":288},[292,293,296,300,304,307],"span",{"class":294,"line":295},"line",1,[292,297,299],{"class":298},"sQJ0q","flutter",[292,301,303],{"class":302},"s-BGO"," pub",[292,305,306],{"class":302}," add",[292,308,309],{"class":302}," rabolic_flutter\n",[239,311,312,313,318,319,322],{},"The SDK needs Dart 3.10 and Flutter 3.38 or later. ",[252,314,315],{"href":27},[242,316,317],{},"npx rabolic init"," also adds the package and prints the ",[242,320,321],{},"init"," call for you.",[277,324,326],{"id":325},"initialize","Initialize",[282,328,333],{"className":329,"code":330,"filename":331,"language":332,"meta":288,"style":288},"language-dart shiki shiki-themes github-light-default github-light-default github-dark-default","import 'package:rabolic_flutter\u002Frabolic_flutter.dart';\n\nFuture\u003Cvoid> main() async {\n  WidgetsFlutterBinding.ensureInitialized();\n  await Rabolic.init(const RabolicConfig(projectKey: 'rb_pub_…'));\n  runApp(const MyApp());\n}\n\n\u002F\u002F Anywhere in the app:\nRabolic.track('workout_started', properties: {'program_id': 'strength-30'});\n","lib\u002Fmain.dart","dart",[242,334,335,348,355,384,398,432,448,454,459,466],{"__ignoreMap":288},[292,336,337,341,344],{"class":294,"line":295},[292,338,340],{"class":339},"s5nWI","import",[292,342,343],{"class":302}," 'package:rabolic_flutter\u002Frabolic_flutter.dart'",[292,345,347],{"class":346},"s_bOF",";\n",[292,349,351],{"class":294,"line":350},2,[292,352,354],{"emptyLinePlaceholder":353},true,"\n",[292,356,358,362,365,368,371,375,378,381],{"class":294,"line":357},3,[292,359,361],{"class":360},"sDkKp","Future",[292,363,364],{"class":346},"\u003C",[292,366,367],{"class":339},"void",[292,369,370],{"class":346},"> ",[292,372,374],{"class":373},"sd69k","main",[292,376,377],{"class":346},"() ",[292,379,380],{"class":339},"async",[292,382,383],{"class":346}," {\n",[292,385,387,390,392,395],{"class":294,"line":386},4,[292,388,389],{"class":360},"  WidgetsFlutterBinding",[292,391,264],{"class":346},[292,393,394],{"class":373},"ensureInitialized",[292,396,397],{"class":346},"();\n",[292,399,401,404,407,409,411,414,417,420,423,426,429],{"class":294,"line":400},5,[292,402,403],{"class":339},"  await",[292,405,406],{"class":360}," Rabolic",[292,408,264],{"class":346},[292,410,321],{"class":373},[292,412,413],{"class":346},"(",[292,415,416],{"class":339},"const",[292,418,419],{"class":360}," RabolicConfig",[292,421,422],{"class":346},"(projectKey",[292,424,425],{"class":339},":",[292,427,428],{"class":302}," 'rb_pub_…'",[292,430,431],{"class":346},"));\n",[292,433,435,438,440,442,445],{"class":294,"line":434},6,[292,436,437],{"class":373},"  runApp",[292,439,413],{"class":346},[292,441,416],{"class":339},[292,443,444],{"class":360}," MyApp",[292,446,447],{"class":346},"());\n",[292,449,451],{"class":294,"line":450},7,[292,452,453],{"class":346},"}\n",[292,455,457],{"class":294,"line":456},8,[292,458,354],{"emptyLinePlaceholder":353},[292,460,462],{"class":294,"line":461},9,[292,463,465],{"class":464},"s9BHP","\u002F\u002F Anywhere in the app:\n",[292,467,469,472,474,477,479,482,485,487,490,493,495,498],{"class":294,"line":468},10,[292,470,471],{"class":360},"Rabolic",[292,473,264],{"class":346},[292,475,476],{"class":373},"track",[292,478,413],{"class":346},[292,480,481],{"class":302},"'workout_started'",[292,483,484],{"class":346},", properties",[292,486,425],{"class":339},[292,488,489],{"class":346}," {",[292,491,492],{"class":302},"'program_id'",[292,494,425],{"class":339},[292,496,497],{"class":302}," 'strength-30'",[292,499,500],{"class":346},"});\n",[239,502,503,504,506],{},"You don't have to await ",[242,505,321],{},". Calls made while the SDK is loading are kept, with their original timestamps, and sent once it has loaded.",[239,508,509,510,513],{},"Turn on ",[242,511,512],{},"debug: true"," while you integrate. Every call and response is logged, and events appear on the dashboard's Live page within seconds.",[277,515,517],{"id":516},"configuration","Configuration",[282,519,521],{"className":329,"code":520,"language":332,"meta":288,"style":288},"RabolicConfig(\n  projectKey: 'rb_pub_…',           \u002F\u002F required: the publishable key\n  host: 'https:\u002F\u002Fingest.rabolic.com', \u002F\u002F or your first-party proxy\n  flushAt: 20,                      \u002F\u002F send when this many events are queued\n  flushInterval: Duration(seconds: 15), \u002F\u002F default: 15 s on mobile, 5 s on web\n  maxQueueSize: 10000,              \u002F\u002F default: 10,000 on mobile, 1,000 on web\n  trackLifecycle: true,             \u002F\u002F $app_* events (iOS and Android)\n  consent: RabolicConsent.granted,  \u002F\u002F starting consent state\n  debug: false,                     \u002F\u002F log every call\n)\n",[242,522,523,531,546,562,578,602,618,634,650,666],{"__ignoreMap":288},[292,524,525,528],{"class":294,"line":295},[292,526,527],{"class":360},"RabolicConfig",[292,529,530],{"class":346},"(\n",[292,532,533,536,538,540,543],{"class":294,"line":350},[292,534,535],{"class":346},"  projectKey",[292,537,425],{"class":339},[292,539,428],{"class":302},[292,541,542],{"class":346},",           ",[292,544,545],{"class":464},"\u002F\u002F required: the publishable key\n",[292,547,548,551,553,556,559],{"class":294,"line":357},[292,549,550],{"class":346},"  host",[292,552,425],{"class":339},[292,554,555],{"class":302}," 'https:\u002F\u002Fingest.rabolic.com'",[292,557,558],{"class":346},", ",[292,560,561],{"class":464},"\u002F\u002F or your first-party proxy\n",[292,563,564,567,569,572,575],{"class":294,"line":386},[292,565,566],{"class":346},"  flushAt",[292,568,425],{"class":339},[292,570,571],{"class":360}," 20",[292,573,574],{"class":346},",                      ",[292,576,577],{"class":464},"\u002F\u002F send when this many events are queued\n",[292,579,580,583,585,588,591,593,596,599],{"class":294,"line":400},[292,581,582],{"class":346},"  flushInterval",[292,584,425],{"class":339},[292,586,587],{"class":360}," Duration",[292,589,590],{"class":346},"(seconds",[292,592,425],{"class":339},[292,594,595],{"class":360}," 15",[292,597,598],{"class":346},"), ",[292,600,601],{"class":464},"\u002F\u002F default: 15 s on mobile, 5 s on web\n",[292,603,604,607,609,612,615],{"class":294,"line":434},[292,605,606],{"class":346},"  maxQueueSize",[292,608,425],{"class":339},[292,610,611],{"class":360}," 10000",[292,613,614],{"class":346},",              ",[292,616,617],{"class":464},"\u002F\u002F default: 10,000 on mobile, 1,000 on web\n",[292,619,620,623,625,628,631],{"class":294,"line":450},[292,621,622],{"class":346},"  trackLifecycle",[292,624,425],{"class":339},[292,626,627],{"class":360}," true",[292,629,630],{"class":346},",             ",[292,632,633],{"class":464},"\u002F\u002F $app_* events (iOS and Android)\n",[292,635,636,639,641,644,647],{"class":294,"line":456},[292,637,638],{"class":346},"  consent",[292,640,425],{"class":339},[292,642,643],{"class":360}," RabolicConsent",[292,645,646],{"class":346},".granted,  ",[292,648,649],{"class":464},"\u002F\u002F starting consent state\n",[292,651,652,655,657,660,663],{"class":294,"line":461},[292,653,654],{"class":346},"  debug",[292,656,425],{"class":339},[292,658,659],{"class":360}," false",[292,661,662],{"class":346},",                     ",[292,664,665],{"class":464},"\u002F\u002F log every call\n",[292,667,668],{"class":294,"line":468},[292,669,670],{"class":346},")\n",[239,672,673,674,677],{},"Remote config is fetched from ",[242,675,676],{},"GET \u002Fv1\u002Fconfig"," at start. It is cached on the device and refreshed when the app returns to the foreground and the cache is more than 5 minutes old. Tracking never waits for it. Today the server sets only the session timeouts there, from your project settings.",[277,679,681],{"id":680},"api","API",[239,683,684,685,687,688,690],{},"All calls are static on ",[242,686,471],{},". None of them throws into your app: invalid input is logged (with ",[242,689,512],{},") and ignored.",[692,693,694,707],"table",{},[695,696,697],"thead",{},[698,699,700,704],"tr",{},[701,702,703],"th",{},"Call",[701,705,706],{},"What it does",[708,709,710,721,738,759,780,793,807,817,836,846,858,875,885],"tbody",{},[698,711,712,718],{},[713,714,715],"td",{},[242,716,717],{},"Rabolic.init(RabolicConfig)",[713,719,720],{},"Starts the SDK. Call once. A second call is ignored",[698,722,723,728],{},[713,724,725],{},[242,726,727],{},"Rabolic.track(name, {properties})",[713,729,730,731,734,735],{},"Sends a custom event. Use ",[242,732,733],{},"snake_case",", 1–200 characters. Names may not start with ",[242,736,737],{},"$",[698,739,740,745],{},[713,741,742],{},[242,743,744],{},"Rabolic.screen(name, {properties})",[713,746,747,748,751,752,755,756],{},"Sends ",[242,749,750],{},"$screen",", with the name in ",[242,753,754],{},"context.screen_name"," and ",[242,757,758],{},"properties.name",[698,760,761,766],{},[713,762,763],{},[242,764,765],{},"Rabolic.identify(userId, {traits})",[713,767,768,769,772,773,776,777],{},"Sets ",[242,770,771],{},"user_id"," on this and every later event, and sends ",[242,774,775],{},"$identify"," with ",[242,778,779],{},"traits",[698,781,782,787],{},[713,783,784],{},[242,785,786],{},"Rabolic.reset()",[713,788,789,790],{},"Logout. Creates a new anonymous id and session, and clears the user id, super properties and ",[242,791,792],{},"appAccountToken",[698,794,795,804],{},[713,796,797,800,801],{},[242,798,799],{},"Rabolic.register(props)"," \u002F ",[242,802,803],{},"Rabolic.unregister(key)",[713,805,806],{},"Super properties, added to every event and kept across launches. Event properties win over them",[698,808,809,814],{},[713,810,811],{},[242,812,813],{},"Rabolic.setConsent(RabolicConsent)",[713,815,816],{},"Changes consent at runtime",[698,818,819,827],{},[713,820,821,800,824],{},[242,822,823],{},"Rabolic.optOut()",[242,825,826],{},"Rabolic.optIn()",[713,828,829,830,800,833],{},"Short for ",[242,831,832],{},"setConsent(denied)",[242,834,835],{},"setConsent(granted)",[698,837,838,843],{},[713,839,840],{},[242,841,842],{},"Rabolic.flush()",[713,844,845],{},"Sends queued events now",[698,847,848,853],{},[713,849,850],{},[242,851,852],{},"Rabolic.handleDeepLink(Uri)",[713,854,747,855],{},[242,856,857],{},"$deep_link",[698,859,860,865],{},[713,861,862],{},[242,863,864],{},"Rabolic.anonymousId",[713,866,867,868,871,872,874],{},"This install's anonymous id (UUIDv4), or ",[242,869,870],{},"null"," until ",[242,873,321],{}," completes",[698,876,877,882],{},[713,878,879],{},[242,880,881],{},"Rabolic.appAccountToken",[713,883,884],{},"A stable UUID for the identified person, for in-app purchases",[698,886,887,892],{},[713,888,889],{},[242,890,891],{},"Rabolic.close()",[713,893,894],{},"Stops the SDK, mostly for tests",[239,896,897,898,900,901,904,905,908],{},"Property values may be strings, numbers, booleans, ",[242,899,870],{},", lists and maps. ",[242,902,903],{},"DateTime"," values are sent as RFC 3339 strings, enums as their name and ",[242,906,907],{},"Uri","s as strings. Any other value is dropped.",[277,910,912],{"id":911},"screens","Screens",[239,914,915,916,425],{},"Add the observer to ",[242,917,918],{},"MaterialApp",[282,920,922],{"className":329,"code":921,"language":332,"meta":288,"style":288},"MaterialApp(\n  navigatorObservers: [RabolicNavigatorObserver()],\n  \u002F\u002F …\n);\n",[242,923,924,930,946,951],{"__ignoreMap":288},[292,925,926,928],{"class":294,"line":295},[292,927,918],{"class":360},[292,929,530],{"class":346},[292,931,932,935,937,940,943],{"class":294,"line":350},[292,933,934],{"class":346},"  navigatorObservers",[292,936,425],{"class":339},[292,938,939],{"class":346}," [",[292,941,942],{"class":360},"RabolicNavigatorObserver",[292,944,945],{"class":346},"()],\n",[292,947,948],{"class":294,"line":357},[292,949,950],{"class":464},"  \u002F\u002F …\n",[292,952,953],{"class":294,"line":386},[292,954,955],{"class":346},");\n",[957,958,959],"h3",{"id":959},"go_router",[239,961,962,963,966,967,970,971,974],{},"Pass the observer to ",[242,964,965],{},"GoRouter",". Screens are named after the route's ",[242,968,969],{},"name",", or its path pattern (",[242,972,973],{},"\u002Fusers\u002F:id",") when it has none:",[282,976,978],{"className":329,"code":977,"language":332,"meta":288,"style":288},"final router = GoRouter(\n  observers: [RabolicNavigatorObserver()],\n  routes: [\n    GoRoute(path: '\u002F', name: 'home', builder: (_, __) => const HomeScreen()),\n    GoRoute(path: '\u002Fusers\u002F:id', builder: (_, state) => UserScreen(state.pathParameters['id']!)),\n  ],\n);\n",[242,979,980,996,1009,1019,1060,1098,1103],{"__ignoreMap":288},[292,981,982,985,988,991,994],{"class":294,"line":295},[292,983,984],{"class":339},"final",[292,986,987],{"class":346}," router ",[292,989,990],{"class":339},"=",[292,992,993],{"class":360}," GoRouter",[292,995,530],{"class":346},[292,997,998,1001,1003,1005,1007],{"class":294,"line":350},[292,999,1000],{"class":346},"  observers",[292,1002,425],{"class":339},[292,1004,939],{"class":346},[292,1006,942],{"class":360},[292,1008,945],{"class":346},[292,1010,1011,1014,1016],{"class":294,"line":357},[292,1012,1013],{"class":346},"  routes",[292,1015,425],{"class":339},[292,1017,1018],{"class":346}," [\n",[292,1020,1021,1024,1027,1029,1032,1035,1037,1040,1043,1045,1048,1051,1054,1057],{"class":294,"line":386},[292,1022,1023],{"class":360},"    GoRoute",[292,1025,1026],{"class":346},"(path",[292,1028,425],{"class":339},[292,1030,1031],{"class":302}," '\u002F'",[292,1033,1034],{"class":346},", name",[292,1036,425],{"class":339},[292,1038,1039],{"class":302}," 'home'",[292,1041,1042],{"class":346},", builder",[292,1044,425],{"class":339},[292,1046,1047],{"class":346}," (_, __) ",[292,1049,1050],{"class":339},"=>",[292,1052,1053],{"class":339}," const",[292,1055,1056],{"class":360}," HomeScreen",[292,1058,1059],{"class":346},"()),\n",[292,1061,1062,1064,1066,1068,1071,1073,1075,1078,1080,1083,1086,1089,1092,1095],{"class":294,"line":400},[292,1063,1023],{"class":360},[292,1065,1026],{"class":346},[292,1067,425],{"class":339},[292,1069,1070],{"class":302}," '\u002Fusers\u002F:id'",[292,1072,1042],{"class":346},[292,1074,425],{"class":339},[292,1076,1077],{"class":346}," (_, state) ",[292,1079,1050],{"class":339},[292,1081,1082],{"class":360}," UserScreen",[292,1084,1085],{"class":346},"(state.pathParameters[",[292,1087,1088],{"class":302},"'id'",[292,1090,1091],{"class":346},"]",[292,1093,1094],{"class":339},"!",[292,1096,1097],{"class":346},")),\n",[292,1099,1100],{"class":294,"line":434},[292,1101,1102],{"class":346},"  ],\n",[292,1104,1105],{"class":294,"line":450},[292,1106,955],{"class":346},[239,1108,1109,1110,1113,1114,1117,1118,1121,1122,1125],{},"A ",[242,1111,1112],{},"ShellRoute"," or ",[242,1115,1116],{},"StatefulShellBranch"," has its own navigator, so give it its own observer: ",[242,1119,1120],{},"ShellRoute(observers: [RabolicNavigatorObserver()], …)",". A ",[242,1123,1124],{},"NavigatorObserver"," can only watch one navigator at a time, so don't reuse one instance.",[957,1127,1128],{"id":1128},"auto_route",[282,1130,1132],{"className":329,"code":1131,"language":332,"meta":288,"style":288},"MaterialApp.router(\n  routerConfig: _appRouter.config(\n    navigatorObservers: () => [RabolicNavigatorObserver()],\n  ),\n);\n",[242,1133,1134,1145,1160,1178,1183],{"__ignoreMap":288},[292,1135,1136,1138,1140,1143],{"class":294,"line":295},[292,1137,918],{"class":360},[292,1139,264],{"class":346},[292,1141,1142],{"class":373},"router",[292,1144,530],{"class":346},[292,1146,1147,1150,1152,1155,1158],{"class":294,"line":350},[292,1148,1149],{"class":346},"  routerConfig",[292,1151,425],{"class":339},[292,1153,1154],{"class":346}," _appRouter.",[292,1156,1157],{"class":373},"config",[292,1159,530],{"class":346},[292,1161,1162,1165,1167,1170,1172,1174,1176],{"class":294,"line":357},[292,1163,1164],{"class":346},"    navigatorObservers",[292,1166,425],{"class":339},[292,1168,1169],{"class":346}," () ",[292,1171,1050],{"class":339},[292,1173,939],{"class":346},[292,1175,942],{"class":360},[292,1177,945],{"class":346},[292,1179,1180],{"class":294,"line":386},[292,1181,1182],{"class":346},"  ),\n",[292,1184,1185],{"class":294,"line":400},[292,1186,955],{"class":346},[239,1188,1189,1190,1193,1194,1197,1198,1201],{},"Screens are named after the route name (",[242,1191,1192],{},"HomeRoute","). Tab changes inside ",[242,1195,1196],{},"AutoTabsRouter"," don't go through a navigator. Call ",[242,1199,1200],{},"Rabolic.screen"," for those yourself.",[957,1203,1205],{"id":1204},"naming-and-filtering-screens","Naming and filtering screens",[239,1207,1208,1209,1212,1213,1216],{},"By default the observer tracks only ",[242,1210,1211],{},"PageRoute","s, so dialogs, sheets and menus don't count, and it uses ",[242,1214,1215],{},"RouteSettings.name",". Both are configurable:",[282,1218,1220],{"className":329,"code":1219,"language":332,"meta":288,"style":288},"RabolicNavigatorObserver(\n  nameExtractor: (settings) => settings.name?.replaceFirst('\u002F', ''),\n  routeFilter: (route) => route is PageRoute && route.settings.name != '\u002Fsplash',\n);\n",[242,1221,1222,1228,1264,1300],{"__ignoreMap":288},[292,1223,1224,1226],{"class":294,"line":295},[292,1225,942],{"class":360},[292,1227,530],{"class":346},[292,1229,1230,1233,1235,1238,1240,1243,1246,1248,1251,1253,1256,1258,1261],{"class":294,"line":350},[292,1231,1232],{"class":346},"  nameExtractor",[292,1234,425],{"class":339},[292,1236,1237],{"class":346}," (settings) ",[292,1239,1050],{"class":339},[292,1241,1242],{"class":346}," settings.name",[292,1244,1245],{"class":339},"?",[292,1247,264],{"class":346},[292,1249,1250],{"class":373},"replaceFirst",[292,1252,413],{"class":346},[292,1254,1255],{"class":302},"'\u002F'",[292,1257,558],{"class":346},[292,1259,1260],{"class":302},"''",[292,1262,1263],{"class":346},"),\n",[292,1265,1266,1269,1271,1274,1276,1279,1282,1285,1288,1291,1294,1297],{"class":294,"line":357},[292,1267,1268],{"class":346},"  routeFilter",[292,1270,425],{"class":339},[292,1272,1273],{"class":346}," (route) ",[292,1275,1050],{"class":339},[292,1277,1278],{"class":346}," route ",[292,1280,1281],{"class":339},"is",[292,1283,1284],{"class":360}," PageRoute",[292,1286,1287],{"class":339}," &&",[292,1289,1290],{"class":346}," route.settings.name ",[292,1292,1293],{"class":339},"!=",[292,1295,1296],{"class":302}," '\u002Fsplash'",[292,1298,1299],{"class":346},",\n",[292,1301,1302],{"class":294,"line":386},[292,1303,955],{"class":346},[239,1305,1306,1307,1310],{},"Routes without a name are skipped. Use ",[242,1308,1309],{},"MaterialPageRoute(settings: RouteSettings(name: 'Checkout'), …)"," or named routes.",[277,1312,1314],{"id":1313},"automatic-events","Automatic events",[239,1316,1317,1318,425],{},"On iOS and Android, with ",[242,1319,1320],{},"trackLifecycle: true",[692,1322,1323,1336],{},[695,1324,1325],{},[698,1326,1327,1330,1333],{},[701,1328,1329],{},"Event",[701,1331,1332],{},"When",[701,1334,1335],{},"Properties",[708,1337,1338,1351,1366,1381],{},[698,1339,1340,1345,1348],{},[713,1341,1342],{},[242,1343,1344],{},"$app_first_open",[713,1346,1347],{},"First launch after install",[713,1349,1350],{},"None",[698,1352,1353,1358,1361],{},[713,1354,1355],{},[242,1356,1357],{},"$app_update",[713,1359,1360],{},"First launch on a new app version",[713,1362,1363],{},[242,1364,1365],{},"previous_version",[698,1367,1368,1373,1376],{},[713,1369,1370],{},[242,1371,1372],{},"$app_open",[713,1374,1375],{},"Launch, and every return to the foreground",[713,1377,1378],{},[242,1379,1380],{},"from_background",[698,1382,1383,1388,1391],{},[713,1384,1385],{},[242,1386,1387],{},"$app_background",[713,1389,1390],{},"The app leaves the foreground",[713,1392,1393],{},[242,1394,1395],{},"foreground_ms",[239,1397,1398,1399,1401],{},"A launch straight into the background (a push or background fetch) sends ",[242,1400,1372],{}," only when the app is first shown. Queued events are sent when the app goes to the background.",[277,1403,83],{"id":1404},"sessions",[1406,1407,1408,1415,1421],"ul",{},[1409,1410,1411,1414],"li",{},[247,1412,1413],{},"iOS and Android:"," a session starts at launch, and again when the app returns after more than 30 seconds in the background. The project setting can change the 30 seconds. Time in the background never counts as active time.",[1409,1416,1417,1420],{},[247,1418,1419],{},"Web:"," a session starts after 30 minutes without an event, or when the page is opened with campaign parameters that differ from the current session's. Tabs share the session.",[1409,1422,1423,1426],{},[242,1424,1425],{},"reset()"," always starts a new session.",[277,1428,78],{"id":1429},"identity",[239,1431,1432,1433,1436,1437,1439,1440,264],{},"Call ",[242,1434,1435],{},"Rabolic.identify(userId)"," after signup and every login, with the same user id you use on the web and your server. Call ",[242,1438,786],{}," at logout. See ",[252,1441,78],{"href":79},[277,1443,1445],{"id":1444},"in-app-purchases","In-app purchases",[239,1447,1448,1450,1451,1454,1455,425],{},[242,1449,881],{}," is a stable UUID for the identified person. Pass it to ",[242,1452,1453],{},"in_app_purchase"," as ",[242,1456,1457],{},"applicationUserName",[282,1459,1461],{"className":329,"code":1460,"language":332,"meta":288,"style":288},"final purchase = PurchaseParam(\n  productDetails: product,\n  applicationUserName: Rabolic.appAccountToken,\n);\nawait InAppPurchase.instance.buyNonConsumable(purchaseParam: purchase);\n",[242,1462,1463,1477,1487,1499,1503],{"__ignoreMap":288},[292,1464,1465,1467,1470,1472,1475],{"class":294,"line":295},[292,1466,984],{"class":339},[292,1468,1469],{"class":346}," purchase ",[292,1471,990],{"class":339},[292,1473,1474],{"class":360}," PurchaseParam",[292,1476,530],{"class":346},[292,1478,1479,1482,1484],{"class":294,"line":350},[292,1480,1481],{"class":346},"  productDetails",[292,1483,425],{"class":339},[292,1485,1486],{"class":346}," product,\n",[292,1488,1489,1492,1494,1496],{"class":294,"line":357},[292,1490,1491],{"class":346},"  applicationUserName",[292,1493,425],{"class":339},[292,1495,406],{"class":360},[292,1497,1498],{"class":346},".appAccountToken,\n",[292,1500,1501],{"class":294,"line":386},[292,1502,955],{"class":346},[292,1504,1505,1508,1511,1514,1517,1520,1522],{"class":294,"line":400},[292,1506,1507],{"class":339},"await",[292,1509,1510],{"class":360}," InAppPurchase",[292,1512,1513],{"class":346},".instance.",[292,1515,1516],{"class":373},"buyNonConsumable",[292,1518,1519],{"class":346},"(purchaseParam",[292,1521,425],{"class":339},[292,1523,1524],{"class":346}," purchase);\n",[239,1526,1527,1528,1530,1531,1534,1535,1538,1539,1541,1542,1545,1546,264],{},"The App Store stores it as the transaction's ",[242,1529,792],{}," and Google Play as ",[242,1532,1533],{},"obfuscatedAccountId",". It is created by ",[242,1536,1537],{},"identify",", kept across launches, changes when a different user is identified, and is cleared by ",[242,1540,1425],{},". It is also sent as the ",[242,1543,1544],{},"app_account_token"," trait on ",[242,1547,775],{},[1549,1550,1551,1552,1557,1558,558,1561,755,1564,264],"warning",{},"Rabolic doesn't receive App Store or Google Play transactions yet, so it can't link store purchases to the person from this token today. To record revenue now, report verified purchases from your server with ",[252,1553,1554],{"href":59},[242,1555,1556],{},"@rabolic\u002Fnode","'s ",[242,1559,1560],{},"purchase",[242,1562,1563],{},"renewal",[242,1565,1566],{},"refund",[277,1568,1570],{"id":1569},"deep-links","Deep links",[239,1572,1432,1573,1576,1577,425],{},[242,1574,1575],{},"Rabolic.handleDeepLink"," with every link that opens the app. With ",[252,1578,1581],{"href":1579,"rel":1580},"https:\u002F\u002Fpub.dev\u002Fpackages\u002Fapp_links",[256],[242,1582,1583],{},"app_links",[282,1585,1587],{"className":329,"code":1586,"language":332,"meta":288,"style":288},"AppLinks().uriLinkStream.listen(Rabolic.handleDeepLink);\n",[242,1588,1589],{"__ignoreMap":288},[292,1590,1591,1594,1597,1600,1602,1604],{"class":294,"line":295},[292,1592,1593],{"class":360},"AppLinks",[292,1595,1596],{"class":346},"().uriLinkStream.",[292,1598,1599],{"class":373},"listen",[292,1601,413],{"class":346},[292,1603,471],{"class":360},[292,1605,1606],{"class":346},".handleDeepLink);\n",[239,1608,1609,1610,1612],{},"The SDK sends ",[242,1611,857],{}," with:",[1406,1614,1615,1621,1638],{},[1409,1616,1617,1620],{},[242,1618,1619],{},"url",";",[1409,1622,1623,1626,1627,1630,1631,1634,1635,1637],{},[242,1624,1625],{},"linked_anonymous_id",", from the link's ",[242,1628,1629],{},"rb_aid"," parameter, which the web SDK's ",[242,1632,1633],{},"appLink()"," adds. Rabolic stores it but doesn't join the web visitor to the app user from it yet; ",[242,1636,1537],{}," with the same user id on web and app does;",[1409,1639,1640,1643,1644,558,1647,558,1650,558,1653,558,1656,1659,1660,558,1663,558,1666,558,1669,275],{},[242,1641,1642],{},"context.campaign",", from ",[242,1645,1646],{},"utm_source",[242,1648,1649],{},"utm_medium",[242,1651,1652],{},"utm_campaign",[242,1654,1655],{},"utm_content",[242,1657,1658],{},"utm_term"," and the click ids (",[242,1661,1662],{},"gclid",[242,1664,1665],{},"fbclid",[242,1667,1668],{},"ttclid",[242,1670,1671],{},"msclkid",[239,1673,1674,1675,264],{},"The full URL is sent. If your links can carry secrets, such as magic-link login tokens, strip them before you pass the ",[242,1676,907],{},[277,1678,1680],{"id":1679},"consent","Consent",[692,1682,1683,1693],{},[695,1684,1685],{},[698,1686,1687,1690],{},[701,1688,1689],{},"State",[701,1691,1692],{},"Behaviour",[708,1694,1695,1706,1723],{},[698,1696,1697,1703],{},[713,1698,1699,1702],{},[242,1700,1701],{},"granted"," (default)",[713,1704,1705],{},"Tracks and sends normally",[698,1707,1708,1713],{},[713,1709,1710],{},[242,1711,1712],{},"pending",[713,1714,1715,1716,1718,1719,1722],{},"Keeps new events in memory only (never on disk) and sends nothing. Switching to ",[242,1717,1701],{}," sends them; ",[242,1720,1721],{},"denied"," drops them",[698,1724,1725,1729],{},[713,1726,1727],{},[242,1728,1721],{},[713,1730,1731],{},"Drops every event and clears the queue on disk",[239,1733,1734,1735,1738,1739,558,1742,558,1745,1748,1749,1751],{},"Pass the starting state as ",[242,1736,1737],{},"RabolicConfig.consent",". A state you set at runtime (",[242,1740,1741],{},"setConsent",[242,1743,1744],{},"optIn",[242,1746,1747],{},"optOut",") is stored on the device and wins over ",[242,1750,1737],{}," on later launches.",[277,1753,1755],{"id":1754},"privacy","Privacy",[239,1757,1758],{},"The SDK never collects advertising ids (IDFA, GAID), the Android id, form field values, the clipboard, location or device fingerprints.",[239,1760,1761],{},"The device context is limited to the platform; app version, build and bundle id; device model, manufacturer and type; OS name and version; locale and time zone; and screen size and density. On the web, it also sends the user agent. The anonymous id is a random UUID created on the device.",[957,1763,1765],{"id":1764},"ios-privacy-manifest","iOS privacy manifest",[239,1767,1768,1769,1772,1773,558,1776,558,1779,755,1782,1785,1786,1788],{},"The SDK has no native code, so it has no ",[242,1770,1771],{},"PrivacyInfo.xcprivacy"," of its own. The plugins it uses (",[242,1774,1775],{},"shared_preferences",[242,1777,1778],{},"path_provider",[242,1780,1781],{},"package_info_plus",[242,1783,1784],{},"device_info_plus",") ship their own manifests. In your app's ",[242,1787,1771],{},", declare the data Rabolic collects for you:",[1406,1790,1791,1797,1803],{},[1409,1792,1793,1796],{},[247,1794,1795],{},"Product Interaction:"," analytics, not used for tracking.",[1409,1798,1799,1802],{},[247,1800,1801],{},"Device ID:"," the install's anonymous id. Analytics, not used for tracking.",[1409,1804,1805,1808,1809,1811],{},[247,1806,1807],{},"User ID:"," only if you call ",[242,1810,1537],{},". Analytics, linked to the user, not used for tracking.",[239,1813,1814,1817,1818,1821],{},[242,1815,1816],{},"NSPrivacyTracking"," stays ",[242,1819,1820],{},"false",", and App Tracking Transparency isn't needed.",[957,1823,1825],{"id":1824},"google-play-data-safety","Google Play Data safety",[239,1827,1828],{},"Declare:",[1406,1830,1831,1837,1843],{},[1409,1832,1833,1836],{},[247,1834,1835],{},"App activity → App interactions:"," collected, for analytics.",[1409,1838,1839,1842],{},[247,1840,1841],{},"Device or other IDs:"," the anonymous install id, for analytics.",[1409,1844,1845,1808,1848,264],{},[247,1846,1847],{},"Personal info → User IDs:",[242,1849,1537],{},[239,1851,1852,1853,275],{},"Data is encrypted in transit (HTTPS). Users can ask you to delete their data; delete the person in Rabolic (see ",[252,1854,147],{"href":148},[277,1856,214],{"id":1857},"limits",[692,1859,1860,1870],{},[695,1861,1862],{},[698,1863,1864,1867],{},[701,1865,1866],{},"Limit",[701,1868,1869],{},"Value",[708,1871,1872,1880,1887,1895,1903,1911,1919,1927],{},[698,1873,1874,1877],{},[713,1875,1876],{},"Event name",[713,1878,1879],{},"1–200 characters",[698,1881,1882,1884],{},[713,1883,1335],{},[713,1885,1886],{},"255 keys per level, nesting depth 5, keys up to 255 characters",[698,1888,1889,1892],{},[713,1890,1891],{},"Serialized event",[713,1893,1894],{},"32 KB (32,768 bytes of UTF-8 JSON). Larger events are dropped; the server applies the same limit",[698,1896,1897,1900],{},[713,1898,1899],{},"User id",[713,1901,1902],{},"1–255 characters",[698,1904,1905,1908],{},[713,1906,1907],{},"Queue",[713,1909,1910],{},"10,000 events on iOS and Android, 1,000 on the web. When it is full, the oldest events are dropped",[698,1912,1913,1916],{},[713,1914,1915],{},"Event age",[713,1917,1918],{},"Events older than 7 days are dropped before sending. The server also rejects events older than 30 days and corrects device clocks that are off by more than 30 s",[698,1920,1921,1924],{},[713,1922,1923],{},"Batch",[713,1925,1926],{},"500 events or 900 KB. Bodies over 1 KB are gzipped (not on the web)",[698,1928,1929,1932],{},[713,1930,1931],{},"Requests",[713,1933,1934,1935,1938],{},"One at a time, 10 s timeout. Backoff from 1 s to 5 min with jitter. ",[242,1936,1937],{},"Retry-After"," is honored",[239,1940,1941],{},"Known limitations:",[1406,1943,1944,1950,1964,1974,1985],{},[1409,1945,1946,1949],{},[247,1947,1948],{},"Desktop"," (macOS, Windows, Linux) isn't supported yet. There, every call does nothing, and debug builds log one line saying so.",[1409,1951,1952,1955,1956,1959,1960,1963],{},[247,1953,1954],{},"Time zone:"," on iOS and Android, ",[242,1957,1958],{},"context.timezone"," is left out, because Dart only exposes ambiguous abbreviations such as ",[242,1961,1962],{},"CET",". The web sends the IANA name.",[1409,1965,1966,1969,1970,1973],{},[247,1967,1968],{},"Web page close:"," browsers may cancel a request when the tab closes. Unsent events stay in ",[242,1971,1972],{},"localStorage"," and go out on the next visit.",[1409,1975,1976,1979,1980,1982,1983,264],{},[247,1977,1978],{},"Android Auto Backup"," restores ",[242,1981,1775],{}," on reinstall, so a restored install keeps its anonymous id and doesn't send ",[242,1984,1344],{},[1409,1986,1987,1990,1991,1994],{},[247,1988,1989],{},"One client per process:"," the queue file is shared, so don't run two ",[242,1992,1993],{},"RabolicClient","s at once in an app.",[1996,1997,1998],"style",{},"html pre.shiki code .sQJ0q, html code.shiki .sQJ0q{--shiki-light:#953800;--shiki-default:#953800;--shiki-dark:#FFA657}html pre.shiki code .s-BGO, html code.shiki .s-BGO{--shiki-light:#0A3069;--shiki-default:#0A3069;--shiki-dark:#A5D6FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s5nWI, html code.shiki .s5nWI{--shiki-light:#CF222E;--shiki-default:#CF222E;--shiki-dark:#FF7B72}html pre.shiki code .s_bOF, html code.shiki .s_bOF{--shiki-light:#1F2328;--shiki-default:#1F2328;--shiki-dark:#E6EDF3}html pre.shiki code .sDkKp, html code.shiki .sDkKp{--shiki-light:#0550AE;--shiki-default:#0550AE;--shiki-dark:#79C0FF}html pre.shiki code .sd69k, html code.shiki .sd69k{--shiki-light:#8250DF;--shiki-default:#8250DF;--shiki-dark:#D2A8FF}html pre.shiki code .s9BHP, html code.shiki .s9BHP{--shiki-light:#6E7781;--shiki-default:#6E7781;--shiki-dark:#8B949E}",{"title":288,"searchDepth":350,"depth":350,"links":2000},[2001,2002,2003,2004,2005,2010,2011,2012,2013,2014,2015,2016,2020],{"id":279,"depth":350,"text":280},{"id":325,"depth":350,"text":326},{"id":516,"depth":350,"text":517},{"id":680,"depth":350,"text":681},{"id":911,"depth":350,"text":912,"children":2006},[2007,2008,2009],{"id":959,"depth":357,"text":959},{"id":1128,"depth":357,"text":1128},{"id":1204,"depth":357,"text":1205},{"id":1313,"depth":350,"text":1314},{"id":1404,"depth":350,"text":83},{"id":1429,"depth":350,"text":78},{"id":1444,"depth":350,"text":1445},{"id":1569,"depth":350,"text":1570},{"id":1679,"depth":350,"text":1680},{"id":1754,"depth":350,"text":1755,"children":2017},[2018,2019],{"id":1764,"depth":357,"text":1765},{"id":1824,"depth":357,"text":1825},{"id":1857,"depth":350,"text":214},"Install rabolic_flutter for iOS, Android and Flutter web. Configuration, lifecycle events, screens with Navigator, go_router and auto_route, identity, in-app purchase tokens, deep links, consent, app store privacy forms and limits.","md",null,{},{"icon":56},{"title":2027,"description":2028},"Flutter SDK (rabolic_flutter)","Install Rabolic's Flutter SDK for iOS, Android and Flutter web. Configuration, lifecycle events, screens with Navigator, go_router and auto_route, identity, deep links, consent, privacy forms and limits.","NmAOln2O-y5F-MeVKofs4n-Jn0kR96_6N96QZSPUs18",[2031,2033],{"title":48,"path":49,"stem":50,"description":2032,"icon":51,"children":-1},"Install @rabolic\u002Freact-native in Expo or bare React Native apps for iOS and Android. Options, app lifecycle events, screens with React Navigation and Expo Router, identity, deep links, consent and limits.",{"title":58,"path":59,"stem":60,"description":2034,"icon":61,"children":-1},"Install @rabolic\u002Fnode to send server-side events and verified revenue (purchases, renewals, refunds) with a secret key. Options, identity, idempotency, Dodo Payments checkout metadata, delivery and limits.",1794242363863]