[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"summary-a3224c85ae960168-layered-mvvm-keeps-swiftui-apps-scalable-summary":3,"summaries-facets-categories":292,"summary-related-a3224c85ae960168-layered-mvvm-keeps-swiftui-apps-scalable-summary":3861},{"id":4,"title":5,"ai":6,"body":13,"categories":251,"created_at":253,"date_modified":253,"description":245,"extension":254,"faq":253,"featured":255,"kicker_label":253,"meta":256,"navigation":274,"path":275,"published_at":253,"question":253,"scraped_at":276,"seo":277,"sitemap":278,"source_id":279,"source_name":280,"source_type":281,"source_url":282,"stem":283,"tags":284,"thumbnail_url":253,"tldr":289,"tweet":253,"unknown_tags":290,"__hash__":291},"summaries\u002Fsummaries\u002Fa3224c85ae960168-layered-mvvm-keeps-swiftui-apps-scalable-summary.md","Layered MVVM Keeps SwiftUI Apps Scalable",{"provider":7,"model":8,"input_tokens":9,"output_tokens":10,"processing_time_ms":11,"cost_usd":12},"openrouter","x-ai\u002Fgrok-4.1-fast",7799,1709,15718,0.00239165,{"type":14,"value":15,"toc":244},"minimark",[16,21,25,144,154,158,188,195,199,219,222,233],[17,18,20],"h2",{"id":19},"full-layer-cake-mvvm-prevents-spaghetti-code","Full Layer Cake MVVM Prevents Spaghetti Code",[22,23,24],"p",{},"SwiftUI tempts you to cram networking, persistence, and business logic into views, creating fragile monoliths by the third feature. Counter this with a five-layer MVVM architecture that enforces clear responsibilities and scales reliably:",[26,27,28,45,80,94,122],"ul",{},[29,30,31,35,36,40,41,44],"li",{},[32,33,34],"strong",{},"Models",": Pure data shapes like ",[37,38,39],"code",{},"@Model class Task"," with fields (id, title, priority enum, dueDate, subTasks via ",[37,42,43],{},"@Relationship","). Keep models ignorant of UI details like colors.",[29,46,47,50,51,54,55,58,59,58,62,58,65,58,68,71,72,75,76,79],{},[32,48,49],{},"Repositories",": Centralize persistence via protocols (e.g., ",[37,52,53],{},"TaskRepositoryProtocol"," with ",[37,56,57],{},"fetchAll()",", ",[37,60,61],{},"fetchTodayTasks(now:)",[37,63,64],{},"add(_:)",[37,66,67],{},"delete(_:)",[37,69,70],{},"toggleComplete(_:)","). Implement with SwiftData's ",[37,73,74],{},"ModelContext",", using ",[37,77,78],{},"FetchDescriptor"," for sorted queries and predicates for date filtering (e.g., today's tasks via calendar start\u002Fend of day).",[29,81,82,85,86,89,90,93],{},[32,83,84],{},"Services",": Handle cross-screen logic like ",[37,87,88],{},"DateManager"," for ",[37,91,92],{},"isToday(_:)",", time-based greetings (hour \u003C12: \"Good Morning\"), and formatted due dates (\"Today at 3PM\", \"Tomorrow\").",[29,95,96,99,100,103,104,54,107,58,110,113,114,117,118,121],{},[32,97,98],{},"ViewModels",": ",[37,101,102],{},"@Observable"," classes own screen state (e.g., ",[37,105,106],{},"TodayViewModel",[37,108,109],{},"tasks: [Task]",[37,111,112],{},"errorMessage",", computed ",[37,115,116],{},"completedCount","). Inject dependencies, call repos\u002Fservices on user actions (e.g., ",[37,119,120],{},"toggleComplete"," saves via repo then reloads), and expose UI-ready data.",[29,123,124,127,128,131,132,135,136,139,140,143],{},[32,125,126],{},"Views",": Render only, forwarding actions (e.g., ",[37,129,130],{},"TodayView"," uses ",[37,133,134],{},"ForEach"," on ",[37,137,138],{},"viewModel.tasks",", buttons call ",[37,141,142],{},"viewModel.toggleComplete(task)",").",[22,145,146,147,150,151,143],{},"Data flows unidirectionally: View → ViewModel → Repo\u002FService → Model → observable state update → View re-render. This keeps views lean (no ",[37,148,149],{},"@Query",", no business rules in ",[37,152,153],{},"onAppear",[17,155,157],{"id":156},"dependency-injection-wires-it-cleanly","Dependency Injection Wires It Cleanly",[22,159,160,161,164,165,89,168,171,172,175,176,179,180,183,184,187],{},"Avoid hard-coded dependencies by injecting at the app root. In ",[37,162,163],{},"@main TodoMVVMApp",", create ",[37,166,167],{},"ModelContainer",[37,169,170],{},"Task.self",". In ",[37,173,174],{},"RootView",", build ",[37,177,178],{},"repo = TaskRepository(context: modelContext)",", then ",[37,181,182],{},"vm = TodayViewModel(repository: repo)",", pass to ",[37,185,186],{},"TodayView(viewModel: vm)",". This enables swapping real repos for fakes in tests.",[22,189,190,191,194],{},"For a todo app with Today\u002FAll Tasks\u002FSearch\u002FSettings\u002Fsub-tasks, this structure handles SwiftData persistence, filters, ",[37,192,193],{},"@AppStorage",", and UI polish without views owning storage.",[17,196,198],{"id":197},"testability-and-pitfalls-unlocked","Testability and Pitfalls Unlocked",[22,200,201,202,205,206,208,209,212,213,58,216,218],{},"Protocols make ViewModels unit-testable: ",[37,203,204],{},"FakeTaskRepository"," mocks ",[37,207,109],{},", overrides methods to append\u002Fremove\u002Ftoggle without SwiftData. Test ",[37,210,211],{},"load()"," sets ",[37,214,215],{},"tasks",[37,217,120],{}," updates state.",[22,220,221],{},"Avoid these traps:",[26,223,224,227,230],{},[29,225,226],{},"Views querying SwiftData directly (leads to duplicated fetch logic).",[29,228,229],{},"God ViewModels handling persistence.",[29,231,232],{},"Instantiating repos inside ViewModels (blocks testing).",[22,234,235,236,243],{},"Result: Boring, trustworthy code where refactors aren't scary, features add cleanly, and months later you grok it instantly. Sample: ",[237,238,242],"a",{"href":239,"rel":240},"https:\u002F\u002Fgithub.com\u002Fsanjaynela\u002FIOSMvvCApp",[241],"nofollow","TodoMVVM GitHub repo",".",{"title":245,"searchDepth":246,"depth":246,"links":247},"",2,[248,249,250],{"id":19,"depth":246,"text":20},{"id":156,"depth":246,"text":157},{"id":197,"depth":246,"text":198},[252],"Software Engineering",null,"md",false,{"content_references":257,"triage":269},[258,262,266],{"type":259,"title":260,"url":239,"context":261},"other","TodoMVVM-SwiftUI","mentioned",{"type":259,"title":263,"author":264,"url":265,"context":261},"Build a Liquid Glass Design System in SwiftUI iOS 26","Sanjay Nelagadde","https:\u002F\u002Flevelup.gitconnected.com\u002Fbuild-a-liquid-glass-design-system-in-swiftui-ios-26-bfa62bcba5be",{"type":259,"title":267,"author":264,"url":268,"context":261},"SwiftUI Navigation in iOS: A Practical Guide","https:\u002F\u002Flevelup.gitconnected.com\u002Fswiftui-navigation-in-ios-a-practical-guide-2a4820971681",{"relevance":270,"novelty":271,"quality":270,"actionability":270,"composite":272,"reasoning":273},4,3,3.8,"Category: Software Engineering. The article provides a detailed breakdown of a layered MVVM architecture specifically for SwiftUI, addressing the audience's pain point of maintaining scalable applications. It offers actionable insights on structuring code to prevent monolithic views, which is directly applicable for developers looking to implement best practices in their projects.",true,"\u002Fsummaries\u002Fa3224c85ae960168-layered-mvvm-keeps-swiftui-apps-scalable-summary","2026-04-15 15:26:12",{"title":5,"description":245},{"loc":275},"a3224c85ae960168","__oneoff__","article","https:\u002F\u002Flevelup.gitconnected.com\u002Fmvvm-in-swiftui-build-an-ios-app-that-stays-organized-as-it-grows-a16e64d9eb3a","summaries\u002Fa3224c85ae960168-layered-mvvm-keeps-swiftui-apps-scalable-summary",[285,286,287,288],"coding","software-engineering","mvvm","swiftui","Use a 'full layer cake' MVVM with Models, Repositories, Services, ViewModels, and Views to separate concerns in SwiftUI apps, enabling testability, maintainability, and growth without monolithic views.",[286,287,288],"Im3kh5IaeVLLujkPW9g6-R8UDlmVBXMyTRJMEplcYI4",[293,296,299,302,305,308,310,312,314,316,318,320,323,325,327,329,331,333,335,337,339,341,344,347,349,351,353,355,357,360,362,364,366,368,370,372,374,376,378,380,382,384,386,388,390,392,394,396,398,400,402,404,406,408,410,412,414,416,418,420,422,424,426,428,430,432,434,436,438,440,442,444,446,448,450,452,454,456,458,460,462,464,466,468,470,472,474,476,478,480,482,484,486,488,490,492,494,496,498,500,502,504,506,508,510,512,514,516,518,520,522,524,526,528,530,532,534,536,538,540,542,544,546,548,550,552,554,556,558,560,562,564,566,568,570,572,574,576,578,580,582,584,586,588,590,592,594,596,598,600,602,604,606,608,610,612,615,617,619,621,623,625,627,629,631,633,635,637,639,641,643,645,647,649,651,653,655,657,659,661,663,665,667,669,671,673,675,677,679,681,683,685,687,689,691,693,695,697,699,701,703,705,707,709,711,713,715,717,719,721,723,725,727,729,731,733,735,737,739,741,743,745,747,749,751,753,755,757,759,761,763,765,767,769,771,773,775,777,779,781,783,785,787,789,791,793,795,797,799,801,803,805,807,809,811,813,815,817,819,821,823,825,827,829,831,833,835,837,839,841,843,845,847,849,851,853,855,857,859,861,863,865,867,869,871,873,875,877,879,881,883,885,887,889,891,893,895,897,899,901,903,905,907,909,911,913,915,917,919,921,923,925,927,929,931,933,935,937,939,941,943,945,947,949,951,953,955,957,959,961,963,965,967,969,971,973,975,977,979,981,983,985,987,989,991,993,995,997,999,1001,1003,1005,1007,1009,1011,1013,1015,1017,1019,1021,1023,1025,1027,1029,1031,1033,1035,1037,1039,1041,1043,1045,1047,1049,1051,1053,1055,1057,1059,1061,1063,1065,1067,1069,1071,1073,1075,1077,1079,1081,1083,1085,1087,1089,1091,1093,1095,1097,1099,1101,1103,1105,1107,1109,1111,1113,1115,1117,1119,1121,1123,1125,1127,1129,1131,1133,1135,1137,1139,1141,1143,1145,1147,1149,1151,1153,1155,1157,1159,1161,1163,1165,1167,1169,1171,1173,1175,1177,1179,1181,1183,1185,1187,1189,1191,1193,1195,1197,1199,1201,1203,1205,1207,1209,1211,1213,1215,1217,1219,1221,1223,1225,1227,1229,1231,1233,1235,1237,1239,1241,1243,1245,1247,1249,1251,1253,1255,1257,1259,1261,1263,1265,1267,1269,1271,1273,1275,1277,1279,1281,1283,1285,1287,1289,1291,1293,1295,1297,1299,1301,1303,1305,1307,1309,1311,1313,1315,1317,1319,1321,1323,1325,1327,1329,1331,1333,1335,1337,1339,1341,1343,1345,1347,1349,1351,1353,1355,1357,1359,1361,1363,1365,1367,1369,1371,1373,1375,1377,1379,1381,1383,1385,1387,1389,1391,1393,1395,1397,1399,1401,1403,1405,1407,1409,1411,1413,1415,1417,1419,1421,1423,1425,1427,1429,1431,1433,1435,1437,1439,1441,1443,1445,1447,1449,1451,1453,1455,1457,1459,1461,1463,1465,1467,1469,1471,1473,1475,1477,1479,1481,1483,1485,1487,1489,1491,1493,1495,1497,1499,1501,1503,1505,1507,1509,1511,1513,1515,1517,1519,1521,1523,1525,1527,1529,1531,1533,1535,1537,1539,1541,1543,1545,1547,1549,1551,1553,1555,1557,1559,1561,1563,1565,1567,1569,1571,1573,1575,1577,1579,1581,1583,1585,1587,1589,1591,1593,1595,1597,1599,1601,1603,1605,1607,1609,1611,1613,1615,1617,1619,1621,1623,1625,1627,1629,1631,1633,1635,1637,1639,1641,1643,1645,1647,1649,1651,1653,1655,1657,1659,1661,1663,1665,1667,1669,1671,1673,1675,1677,1679,1681,1683,1685,1687,1689,1691,1693,1695,1697,1699,1701,1703,1705,1707,1709,1711,1713,1715,1717,1719,1721,1723,1725,1727,1729,1731,1733,1735,1737,1739,1741,1743,1745,1747,1749,1751,1753,1755,1757,1759,1761,1763,1765,1767,1769,1771,1773,1775,1777,1779,1781,1783,1785,1787,1789,1791,1793,1795,1797,1799,1801,1803,1805,1807,1809,1811,1813,1815,1817,1819,1821,1823,1825,1827,1829,1831,1833,1835,1837,1839,1841,1843,1845,1847,1849,1851,1853,1855,1857,1859,1861,1863,1865,1867,1869,1871,1873,1875,1877,1879,1881,1883,1885,1887,1889,1891,1893,1895,1897,1899,1901,1903,1905,1907,1909,1911,1913,1915,1917,1919,1921,1923,1925,1927,1929,1931,1933,1935,1937,1939,1941,1943,1945,1947,1949,1951,1953,1955,1957,1959,1961,1963,1965,1967,1969,1971,1973,1975,1977,1979,1981,1983,1985,1987,1989,1991,1993,1995,1997,1999,2001,2003,2005,2007,2009,2011,2013,2015,2017,2019,2021,2023,2025,2027,2029,2031,2033,2035,2037,2039,2041,2043,2045,2047,2049,2051,2053,2055,2057,2059,2061,2063,2065,2067,2069,2071,2073,2075,2077,2079,2081,2083,2085,2087,2089,2091,2093,2095,2097,2099,2101,2103,2105,2107,2109,2111,2113,2115,2117,2119,2121,2123,2125,2127,2129,2131,2133,2135,2137,2139,2141,2143,2145,2147,2149,2151,2153,2155,2157,2159,2161,2163,2165,2167,2169,2171,2173,2175,2177,2179,2181,2183,2185,2187,2189,2191,2193,2195,2197,2199,2201,2203,2205,2207,2209,2211,2213,2215,2217,2219,2221,2223,2225,2227,2229,2231,2233,2235,2237,2239,2241,2243,2245,2247,2249,2251,2253,2255,2257,2259,2261,2263,2265,2267,2269,2271,2273,2275,2277,2279,2281,2283,2285,2287,2289,2291,2293,2295,2297,2299,2301,2303,2305,2307,2309,2311,2313,2315,2317,2319,2321,2323,2325,2327,2329,2331,2333,2335,2337,2339,2341,2343,2345,2347,2349,2351,2353,2355,2357,2359,2361,2363,2365,2367,2369,2371,2373,2375,2377,2379,2381,2383,2385,2387,2389,2391,2393,2395,2397,2399,2401,2403,2405,2407,2409,2411,2413,2415,2417,2419,2421,2423,2425,2427,2429,2431,2433,2435,2437,2439,2441,2443,2445,2447,2449,2451,2453,2455,2457,2459,2461,2463,2465,2467,2469,2471,2473,2475,2477,2479,2481,2483,2485,2487,2489,2491,2493,2495,2497,2499,2501,2503,2505,2507,2509,2511,2513,2515,2517,2519,2521,2523,2525,2527,2529,2531,2533,2535,2537,2539,2541,2543,2545,2547,2549,2551,2553,2555,2557,2559,2561,2563,2565,2567,2569,2571,2573,2575,2577,2579,2581,2583,2585,2587,2589,2591,2593,2595,2597,2599,2601,2603,2605,2607,2609,2611,2613,2615,2617,2619,2621,2623,2625,2627,2629,2631,2633,2635,2637,2639,2641,2643,2645,2647,2649,2651,2653,2655,2657,2659,2661,2663,2665,2667,2669,2671,2673,2675,2677,2679,2681,2683,2685,2687,2689,2691,2693,2695,2697,2699,2701,2703,2705,2707,2709,2711,2713,2715,2717,2719,2721,2723,2725,2727,2729,2731,2733,2735,2737,2739,2741,2743,2745,2747,2749,2751,2753,2755,2757,2759,2761,2763,2765,2767,2769,2771,2773,2775,2777,2779,2781,2783,2785,2787,2789,2791,2793,2795,2797,2799,2801,2803,2805,2807,2809,2811,2813,2815,2817,2819,2821,2823,2825,2827,2829,2831,2833,2835,2837,2839,2841,2843,2845,2847,2849,2851,2853,2855,2857,2859,2861,2863,2865,2867,2869,2871,2873,2875,2877,2879,2881,2883,2885,2887,2889,2891,2893,2895,2897,2899,2901,2903,2905,2907,2909,2911,2913,2915,2917,2919,2921,2923,2925,2927,2929,2931,2933,2935,2937,2939,2941,2943,2945,2947,2949,2951,2953,2955,2957,2959,2961,2963,2965,2967,2969,2971,2973,2975,2977,2979,2981,2983,2985,2987,2989,2991,2993,2995,2997,2999,3001,3003,3005,3007,3009,3011,3013,3015,3017,3019,3021,3023,3025,3027,3029,3031,3033,3035,3037,3039,3041,3043,3045,3047,3049,3051,3053,3055,3057,3059,3061,3063,3065,3067,3069,3071,3073,3075,3077,3079,3081,3083,3085,3087,3089,3091,3093,3095,3097,3099,3101,3103,3105,3107,3109,3111,3113,3115,3117,3119,3121,3123,3125,3127,3129,3131,3133,3135,3137,3139,3141,3143,3145,3147,3149,3151,3153,3155,3157,3159,3161,3163,3165,3167,3169,3171,3173,3175,3177,3179,3181,3183,3185,3187,3189,3191,3193,3195,3197,3199,3201,3203,3205,3207,3209,3211,3213,3215,3217,3219,3221,3223,3225,3227,3229,3231,3233,3235,3237,3239,3241,3243,3245,3247,3249,3251,3253,3255,3257,3259,3261,3263,3265,3267,3269,3271,3273,3275,3277,3279,3281,3283,3285,3287,3289,3291,3293,3295,3297,3299,3301,3303,3305,3307,3309,3311,3313,3315,3317,3319,3321,3323,3325,3327,3329,3331,3333,3335,3337,3339,3341,3343,3345,3347,3349,3351,3353,3355,3357,3359,3361,3363,3365,3367,3369,3371,3373,3375,3377,3379,3381,3383,3385,3387,3389,3391,3393,3395,3397,3399,3401,3403,3405,3407,3409,3411,3413,3415,3417,3419,3421,3423,3425,3427,3429,3431,3433,3435,3437,3439,3441,3443,3445,3447,3449,3451,3453,3455,3457,3459,3461,3463,3465,3467,3469,3471,3473,3475,3477,3479,3481,3483,3485,3487,3489,3491,3493,3495,3497,3499,3501,3503,3505,3507,3509,3511,3513,3515,3517,3519,3521,3523,3525,3527,3529,3531,3533,3535,3537,3539,3541,3543,3545,3547,3549,3551,3553,3555,3557,3559,3561,3563,3565,3567,3569,3571,3573,3575,3577,3579,3581,3583,3585,3587,3589,3591,3593,3595,3597,3599,3601,3603,3605,3607,3609,3611,3613,3615,3617,3619,3621,3623,3625,3627,3629,3631,3633,3635,3637,3639,3641,3643,3645,3647,3649,3651,3653,3655,3657,3659,3661,3663,3665,3667,3669,3671,3673,3675,3677,3679,3681,3683,3685,3687,3689,3691,3693,3695,3697,3699,3701,3703,3705,3707,3709,3711,3713,3715,3717,3719,3721,3723,3725,3727,3729,3731,3733,3735,3737,3739,3741,3743,3745,3747,3749,3751,3753,3755,3757,3759,3761,3763,3765,3767,3769,3771,3773,3775,3777,3779,3781,3783,3785,3787,3789,3791,3793,3795,3797,3799,3801,3803,3805,3807,3809,3811,3813,3815,3817,3819,3821,3823,3825,3827,3829,3831,3833,3835,3837,3839,3841,3843,3845,3847,3849,3851,3853,3855,3857,3859],{"categories":294},[295],"Developer Productivity",{"categories":297},[298],"Business & SaaS",{"categories":300},[301],"AI & LLMs",{"categories":303},[304],"AI Automation",{"categories":306},[307],"Product Strategy",{"categories":309},[301],{"categories":311},[295],{"categories":313},[298],{"categories":315},[],{"categories":317},[301],{"categories":319},[],{"categories":321},[322],"AI News & Trends",{"categories":324},[304],{"categories":326},[322],{"categories":328},[304],{"categories":330},[304],{"categories":332},[301],{"categories":334},[301],{"categories":336},[322],{"categories":338},[301],{"categories":340},[],{"categories":342},[343],"Design & Frontend",{"categories":345},[346],"Data Science & Visualization",{"categories":348},[322],{"categories":350},[],{"categories":352},[252],{"categories":354},[301],{"categories":356},[304],{"categories":358},[359],"Marketing & Growth",{"categories":361},[301],{"categories":363},[304],{"categories":365},[],{"categories":367},[],{"categories":369},[343],{"categories":371},[304],{"categories":373},[295],{"categories":375},[343],{"categories":377},[301],{"categories":379},[304],{"categories":381},[322],{"categories":383},[],{"categories":385},[],{"categories":387},[304],{"categories":389},[252],{"categories":391},[],{"categories":393},[298],{"categories":395},[],{"categories":397},[],{"categories":399},[304],{"categories":401},[304],{"categories":403},[301],{"categories":405},[],{"categories":407},[252],{"categories":409},[],{"categories":411},[],{"categories":413},[],{"categories":415},[301],{"categories":417},[359],{"categories":419},[343],{"categories":421},[343],{"categories":423},[301],{"categories":425},[304],{"categories":427},[301],{"categories":429},[301],{"categories":431},[304],{"categories":433},[304],{"categories":435},[346],{"categories":437},[322],{"categories":439},[304],{"categories":441},[359],{"categories":443},[304],{"categories":445},[307],{"categories":447},[],{"categories":449},[304],{"categories":451},[],{"categories":453},[304],{"categories":455},[252],{"categories":457},[343],{"categories":459},[301],{"categories":461},[],{"categories":463},[],{"categories":465},[304],{"categories":467},[],{"categories":469},[301],{"categories":471},[],{"categories":473},[295],{"categories":475},[252],{"categories":477},[298],{"categories":479},[322],{"categories":481},[301],{"categories":483},[],{"categories":485},[301],{"categories":487},[],{"categories":489},[252],{"categories":491},[346],{"categories":493},[],{"categories":495},[301],{"categories":497},[343],{"categories":499},[],{"categories":501},[343],{"categories":503},[304],{"categories":505},[],{"categories":507},[304],{"categories":509},[322],{"categories":511},[301],{"categories":513},[],{"categories":515},[304],{"categories":517},[301],{"categories":519},[307],{"categories":521},[],{"categories":523},[301],{"categories":525},[304],{"categories":527},[304],{"categories":529},[],{"categories":531},[346],{"categories":533},[301],{"categories":535},[],{"categories":537},[295],{"categories":539},[298],{"categories":541},[301],{"categories":543},[304],{"categories":545},[252],{"categories":547},[301],{"categories":549},[],{"categories":551},[],{"categories":553},[301],{"categories":555},[],{"categories":557},[343],{"categories":559},[],{"categories":561},[301],{"categories":563},[],{"categories":565},[304],{"categories":567},[301],{"categories":569},[343],{"categories":571},[],{"categories":573},[301],{"categories":575},[301],{"categories":577},[298],{"categories":579},[304],{"categories":581},[301],{"categories":583},[343],{"categories":585},[304],{"categories":587},[],{"categories":589},[],{"categories":591},[322],{"categories":593},[],{"categories":595},[301],{"categories":597},[298,359],{"categories":599},[],{"categories":601},[301],{"categories":603},[],{"categories":605},[],{"categories":607},[301],{"categories":609},[],{"categories":611},[301],{"categories":613},[614],"DevOps & Cloud",{"categories":616},[],{"categories":618},[322],{"categories":620},[343],{"categories":622},[],{"categories":624},[322],{"categories":626},[322],{"categories":628},[301],{"categories":630},[359],{"categories":632},[],{"categories":634},[298],{"categories":636},[],{"categories":638},[301,614],{"categories":640},[301],{"categories":642},[301],{"categories":644},[304],{"categories":646},[301,252],{"categories":648},[346],{"categories":650},[301],{"categories":652},[359],{"categories":654},[304],{"categories":656},[304],{"categories":658},[],{"categories":660},[304],{"categories":662},[301,298],{"categories":664},[],{"categories":666},[343],{"categories":668},[343],{"categories":670},[],{"categories":672},[],{"categories":674},[322],{"categories":676},[],{"categories":678},[295],{"categories":680},[252],{"categories":682},[301],{"categories":684},[343],{"categories":686},[304],{"categories":688},[252],{"categories":690},[322],{"categories":692},[343],{"categories":694},[],{"categories":696},[301],{"categories":698},[301],{"categories":700},[301],{"categories":702},[322],{"categories":704},[295],{"categories":706},[301],{"categories":708},[304],{"categories":710},[614],{"categories":712},[343],{"categories":714},[304],{"categories":716},[],{"categories":718},[],{"categories":720},[343],{"categories":722},[322],{"categories":724},[346],{"categories":726},[],{"categories":728},[301],{"categories":730},[301],{"categories":732},[298],{"categories":734},[301],{"categories":736},[301],{"categories":738},[322],{"categories":740},[],{"categories":742},[304],{"categories":744},[252],{"categories":746},[],{"categories":748},[301],{"categories":750},[301],{"categories":752},[304],{"categories":754},[],{"categories":756},[],{"categories":758},[301],{"categories":760},[],{"categories":762},[298],{"categories":764},[304],{"categories":766},[],{"categories":768},[295],{"categories":770},[301],{"categories":772},[298],{"categories":774},[322],{"categories":776},[],{"categories":778},[],{"categories":780},[],{"categories":782},[322],{"categories":784},[322],{"categories":786},[],{"categories":788},[],{"categories":790},[298],{"categories":792},[],{"categories":794},[],{"categories":796},[295],{"categories":798},[],{"categories":800},[359],{"categories":802},[304],{"categories":804},[298],{"categories":806},[304],{"categories":808},[],{"categories":810},[307],{"categories":812},[343],{"categories":814},[252],{"categories":816},[301],{"categories":818},[304],{"categories":820},[298],{"categories":822},[301],{"categories":824},[],{"categories":826},[],{"categories":828},[252],{"categories":830},[346],{"categories":832},[307],{"categories":834},[304],{"categories":836},[301],{"categories":838},[],{"categories":840},[614],{"categories":842},[],{"categories":844},[304],{"categories":846},[],{"categories":848},[],{"categories":850},[301],{"categories":852},[343],{"categories":854},[359],{"categories":856},[304],{"categories":858},[],{"categories":860},[295],{"categories":862},[],{"categories":864},[322],{"categories":866},[301,614],{"categories":868},[322],{"categories":870},[301],{"categories":872},[298],{"categories":874},[301],{"categories":876},[],{"categories":878},[298],{"categories":880},[],{"categories":882},[252],{"categories":884},[343],{"categories":886},[322],{"categories":888},[346],{"categories":890},[295],{"categories":892},[301],{"categories":894},[252],{"categories":896},[],{"categories":898},[],{"categories":900},[307],{"categories":902},[],{"categories":904},[301],{"categories":906},[],{"categories":908},[343],{"categories":910},[343],{"categories":912},[343],{"categories":914},[],{"categories":916},[],{"categories":918},[322],{"categories":920},[304],{"categories":922},[301],{"categories":924},[301],{"categories":926},[301],{"categories":928},[298],{"categories":930},[301],{"categories":932},[],{"categories":934},[252],{"categories":936},[252],{"categories":938},[298],{"categories":940},[],{"categories":942},[301],{"categories":944},[301],{"categories":946},[298],{"categories":948},[322],{"categories":950},[359],{"categories":952},[304],{"categories":954},[],{"categories":956},[343],{"categories":958},[],{"categories":960},[301],{"categories":962},[],{"categories":964},[298],{"categories":966},[304],{"categories":968},[],{"categories":970},[614],{"categories":972},[346],{"categories":974},[252],{"categories":976},[359],{"categories":978},[252],{"categories":980},[304],{"categories":982},[],{"categories":984},[],{"categories":986},[304],{"categories":988},[295],{"categories":990},[304],{"categories":992},[307],{"categories":994},[298],{"categories":996},[],{"categories":998},[301],{"categories":1000},[307],{"categories":1002},[301],{"categories":1004},[301],{"categories":1006},[359],{"categories":1008},[343],{"categories":1010},[304],{"categories":1012},[],{"categories":1014},[],{"categories":1016},[614],{"categories":1018},[252],{"categories":1020},[],{"categories":1022},[304],{"categories":1024},[301],{"categories":1026},[343,301],{"categories":1028},[295],{"categories":1030},[],{"categories":1032},[301],{"categories":1034},[295],{"categories":1036},[343],{"categories":1038},[304],{"categories":1040},[252],{"categories":1042},[],{"categories":1044},[301],{"categories":1046},[],{"categories":1048},[295],{"categories":1050},[],{"categories":1052},[304],{"categories":1054},[307],{"categories":1056},[301],{"categories":1058},[301],{"categories":1060},[343],{"categories":1062},[304],{"categories":1064},[614],{"categories":1066},[343],{"categories":1068},[304],{"categories":1070},[301],{"categories":1072},[301],{"categories":1074},[301],{"categories":1076},[322],{"categories":1078},[],{"categories":1080},[307],{"categories":1082},[304],{"categories":1084},[343],{"categories":1086},[304],{"categories":1088},[252],{"categories":1090},[343],{"categories":1092},[304],{"categories":1094},[322],{"categories":1096},[],{"categories":1098},[301],{"categories":1100},[343],{"categories":1102},[301],{"categories":1104},[295],{"categories":1106},[322],{"categories":1108},[301],{"categories":1110},[359],{"categories":1112},[301],{"categories":1114},[301],{"categories":1116},[304],{"categories":1118},[304],{"categories":1120},[301],{"categories":1122},[304],{"categories":1124},[343],{"categories":1126},[301],{"categories":1128},[],{"categories":1130},[],{"categories":1132},[252],{"categories":1134},[],{"categories":1136},[295],{"categories":1138},[614],{"categories":1140},[],{"categories":1142},[295],{"categories":1144},[298],{"categories":1146},[359],{"categories":1148},[],{"categories":1150},[298],{"categories":1152},[],{"categories":1154},[],{"categories":1156},[],{"categories":1158},[],{"categories":1160},[],{"categories":1162},[301],{"categories":1164},[304],{"categories":1166},[614],{"categories":1168},[295],{"categories":1170},[301],{"categories":1172},[252],{"categories":1174},[307],{"categories":1176},[301],{"categories":1178},[359],{"categories":1180},[301],{"categories":1182},[301],{"categories":1184},[301],{"categories":1186},[301,295],{"categories":1188},[252],{"categories":1190},[252],{"categories":1192},[343],{"categories":1194},[301],{"categories":1196},[],{"categories":1198},[],{"categories":1200},[],{"categories":1202},[252],{"categories":1204},[346],{"categories":1206},[322],{"categories":1208},[343],{"categories":1210},[],{"categories":1212},[301],{"categories":1214},[301],{"categories":1216},[],{"categories":1218},[],{"categories":1220},[304],{"categories":1222},[301],{"categories":1224},[298],{"categories":1226},[],{"categories":1228},[295],{"categories":1230},[301],{"categories":1232},[295],{"categories":1234},[301],{"categories":1236},[252],{"categories":1238},[359],{"categories":1240},[301,343],{"categories":1242},[322],{"categories":1244},[343],{"categories":1246},[],{"categories":1248},[614],{"categories":1250},[343],{"categories":1252},[304],{"categories":1254},[],{"categories":1256},[],{"categories":1258},[],{"categories":1260},[],{"categories":1262},[252],{"categories":1264},[304],{"categories":1266},[304],{"categories":1268},[301],{"categories":1270},[301],{"categories":1272},[],{"categories":1274},[343],{"categories":1276},[],{"categories":1278},[],{"categories":1280},[304],{"categories":1282},[],{"categories":1284},[],{"categories":1286},[359],{"categories":1288},[359],{"categories":1290},[304],{"categories":1292},[],{"categories":1294},[301],{"categories":1296},[301],{"categories":1298},[252],{"categories":1300},[343],{"categories":1302},[343],{"categories":1304},[304],{"categories":1306},[295],{"categories":1308},[301],{"categories":1310},[343],{"categories":1312},[343],{"categories":1314},[304],{"categories":1316},[304],{"categories":1318},[301],{"categories":1320},[],{"categories":1322},[],{"categories":1324},[301],{"categories":1326},[304],{"categories":1328},[322],{"categories":1330},[252],{"categories":1332},[295],{"categories":1334},[301],{"categories":1336},[],{"categories":1338},[304],{"categories":1340},[304],{"categories":1342},[],{"categories":1344},[295],{"categories":1346},[301],{"categories":1348},[295],{"categories":1350},[295],{"categories":1352},[],{"categories":1354},[],{"categories":1356},[304],{"categories":1358},[304],{"categories":1360},[301],{"categories":1362},[301],{"categories":1364},[322],{"categories":1366},[346],{"categories":1368},[307],{"categories":1370},[322],{"categories":1372},[343],{"categories":1374},[],{"categories":1376},[322],{"categories":1378},[],{"categories":1380},[],{"categories":1382},[],{"categories":1384},[],{"categories":1386},[252],{"categories":1388},[346],{"categories":1390},[],{"categories":1392},[301],{"categories":1394},[301],{"categories":1396},[346],{"categories":1398},[252],{"categories":1400},[],{"categories":1402},[],{"categories":1404},[304],{"categories":1406},[322],{"categories":1408},[322],{"categories":1410},[304],{"categories":1412},[295],{"categories":1414},[301,614],{"categories":1416},[],{"categories":1418},[343],{"categories":1420},[295],{"categories":1422},[304],{"categories":1424},[343],{"categories":1426},[],{"categories":1428},[304],{"categories":1430},[304],{"categories":1432},[301],{"categories":1434},[359],{"categories":1436},[252],{"categories":1438},[343],{"categories":1440},[],{"categories":1442},[304],{"categories":1444},[301],{"categories":1446},[304],{"categories":1448},[304],{"categories":1450},[304],{"categories":1452},[359],{"categories":1454},[304],{"categories":1456},[301],{"categories":1458},[],{"categories":1460},[359],{"categories":1462},[322],{"categories":1464},[304],{"categories":1466},[],{"categories":1468},[],{"categories":1470},[301],{"categories":1472},[304],{"categories":1474},[322],{"categories":1476},[304],{"categories":1478},[],{"categories":1480},[],{"categories":1482},[],{"categories":1484},[304],{"categories":1486},[],{"categories":1488},[],{"categories":1490},[346],{"categories":1492},[301],{"categories":1494},[346],{"categories":1496},[322],{"categories":1498},[301],{"categories":1500},[301],{"categories":1502},[304],{"categories":1504},[301],{"categories":1506},[],{"categories":1508},[],{"categories":1510},[614],{"categories":1512},[],{"categories":1514},[],{"categories":1516},[295],{"categories":1518},[],{"categories":1520},[],{"categories":1522},[],{"categories":1524},[],{"categories":1526},[252],{"categories":1528},[322],{"categories":1530},[359],{"categories":1532},[298],{"categories":1534},[301],{"categories":1536},[301],{"categories":1538},[298],{"categories":1540},[],{"categories":1542},[343],{"categories":1544},[304],{"categories":1546},[298],{"categories":1548},[301],{"categories":1550},[301],{"categories":1552},[295],{"categories":1554},[],{"categories":1556},[295],{"categories":1558},[301],{"categories":1560},[359],{"categories":1562},[304],{"categories":1564},[322],{"categories":1566},[298],{"categories":1568},[301],{"categories":1570},[304],{"categories":1572},[],{"categories":1574},[301],{"categories":1576},[295],{"categories":1578},[301],{"categories":1580},[],{"categories":1582},[322],{"categories":1584},[301],{"categories":1586},[],{"categories":1588},[298],{"categories":1590},[301],{"categories":1592},[],{"categories":1594},[],{"categories":1596},[],{"categories":1598},[301],{"categories":1600},[],{"categories":1602},[614],{"categories":1604},[301],{"categories":1606},[],{"categories":1608},[301],{"categories":1610},[301],{"categories":1612},[301],{"categories":1614},[301,614],{"categories":1616},[301],{"categories":1618},[301],{"categories":1620},[343],{"categories":1622},[304],{"categories":1624},[],{"categories":1626},[304],{"categories":1628},[301],{"categories":1630},[301],{"categories":1632},[301],{"categories":1634},[295],{"categories":1636},[295],{"categories":1638},[252],{"categories":1640},[343],{"categories":1642},[304],{"categories":1644},[],{"categories":1646},[301],{"categories":1648},[322],{"categories":1650},[301],{"categories":1652},[298],{"categories":1654},[],{"categories":1656},[614],{"categories":1658},[343],{"categories":1660},[343],{"categories":1662},[304],{"categories":1664},[322],{"categories":1666},[304],{"categories":1668},[301],{"categories":1670},[],{"categories":1672},[301],{"categories":1674},[],{"categories":1676},[],{"categories":1678},[301],{"categories":1680},[301],{"categories":1682},[301],{"categories":1684},[304],{"categories":1686},[301],{"categories":1688},[],{"categories":1690},[346],{"categories":1692},[304],{"categories":1694},[],{"categories":1696},[301],{"categories":1698},[322],{"categories":1700},[],{"categories":1702},[343],{"categories":1704},[614],{"categories":1706},[322],{"categories":1708},[252],{"categories":1710},[252],{"categories":1712},[322],{"categories":1714},[322],{"categories":1716},[614],{"categories":1718},[],{"categories":1720},[322],{"categories":1722},[301],{"categories":1724},[295],{"categories":1726},[322],{"categories":1728},[],{"categories":1730},[346],{"categories":1732},[322],{"categories":1734},[252],{"categories":1736},[322],{"categories":1738},[614],{"categories":1740},[301],{"categories":1742},[301],{"categories":1744},[],{"categories":1746},[298],{"categories":1748},[],{"categories":1750},[],{"categories":1752},[301],{"categories":1754},[301],{"categories":1756},[301],{"categories":1758},[301],{"categories":1760},[],{"categories":1762},[346],{"categories":1764},[295],{"categories":1766},[],{"categories":1768},[301],{"categories":1770},[301],{"categories":1772},[614],{"categories":1774},[614],{"categories":1776},[],{"categories":1778},[304],{"categories":1780},[322],{"categories":1782},[322],{"categories":1784},[301],{"categories":1786},[304],{"categories":1788},[],{"categories":1790},[343],{"categories":1792},[301],{"categories":1794},[301],{"categories":1796},[],{"categories":1798},[],{"categories":1800},[614],{"categories":1802},[301],{"categories":1804},[252],{"categories":1806},[298],{"categories":1808},[301],{"categories":1810},[],{"categories":1812},[304],{"categories":1814},[295],{"categories":1816},[295],{"categories":1818},[],{"categories":1820},[301],{"categories":1822},[343],{"categories":1824},[304],{"categories":1826},[],{"categories":1828},[301],{"categories":1830},[301],{"categories":1832},[304],{"categories":1834},[],{"categories":1836},[304],{"categories":1838},[252],{"categories":1840},[],{"categories":1842},[301],{"categories":1844},[],{"categories":1846},[301],{"categories":1848},[],{"categories":1850},[301],{"categories":1852},[301],{"categories":1854},[],{"categories":1856},[301],{"categories":1858},[322],{"categories":1860},[301],{"categories":1862},[301],{"categories":1864},[295],{"categories":1866},[301],{"categories":1868},[322],{"categories":1870},[304],{"categories":1872},[],{"categories":1874},[301],{"categories":1876},[359],{"categories":1878},[],{"categories":1880},[],{"categories":1882},[],{"categories":1884},[295],{"categories":1886},[322],{"categories":1888},[304],{"categories":1890},[301],{"categories":1892},[343],{"categories":1894},[304],{"categories":1896},[],{"categories":1898},[304],{"categories":1900},[],{"categories":1902},[301],{"categories":1904},[304],{"categories":1906},[301],{"categories":1908},[],{"categories":1910},[301],{"categories":1912},[301],{"categories":1914},[322],{"categories":1916},[343],{"categories":1918},[304],{"categories":1920},[343],{"categories":1922},[298],{"categories":1924},[],{"categories":1926},[],{"categories":1928},[301],{"categories":1930},[295],{"categories":1932},[322],{"categories":1934},[],{"categories":1936},[],{"categories":1938},[252],{"categories":1940},[343],{"categories":1942},[],{"categories":1944},[301],{"categories":1946},[],{"categories":1948},[359],{"categories":1950},[301],{"categories":1952},[614],{"categories":1954},[252],{"categories":1956},[],{"categories":1958},[304],{"categories":1960},[301],{"categories":1962},[304],{"categories":1964},[304],{"categories":1966},[301],{"categories":1968},[],{"categories":1970},[295],{"categories":1972},[301],{"categories":1974},[298],{"categories":1976},[252],{"categories":1978},[343],{"categories":1980},[],{"categories":1982},[],{"categories":1984},[],{"categories":1986},[304],{"categories":1988},[343],{"categories":1990},[322],{"categories":1992},[301],{"categories":1994},[322],{"categories":1996},[343],{"categories":1998},[],{"categories":2000},[343],{"categories":2002},[322],{"categories":2004},[298],{"categories":2006},[301],{"categories":2008},[322],{"categories":2010},[359],{"categories":2012},[],{"categories":2014},[],{"categories":2016},[346],{"categories":2018},[301,252],{"categories":2020},[322],{"categories":2022},[301],{"categories":2024},[304],{"categories":2026},[304],{"categories":2028},[301],{"categories":2030},[],{"categories":2032},[252],{"categories":2034},[301],{"categories":2036},[346],{"categories":2038},[304],{"categories":2040},[359],{"categories":2042},[614],{"categories":2044},[],{"categories":2046},[295],{"categories":2048},[304],{"categories":2050},[304],{"categories":2052},[252],{"categories":2054},[301],{"categories":2056},[301],{"categories":2058},[],{"categories":2060},[],{"categories":2062},[],{"categories":2064},[614],{"categories":2066},[322],{"categories":2068},[301],{"categories":2070},[301],{"categories":2072},[301],{"categories":2074},[],{"categories":2076},[346],{"categories":2078},[298],{"categories":2080},[],{"categories":2082},[304],{"categories":2084},[614],{"categories":2086},[],{"categories":2088},[343],{"categories":2090},[343],{"categories":2092},[],{"categories":2094},[252],{"categories":2096},[343],{"categories":2098},[301],{"categories":2100},[],{"categories":2102},[322],{"categories":2104},[301],{"categories":2106},[343],{"categories":2108},[304],{"categories":2110},[322],{"categories":2112},[],{"categories":2114},[304],{"categories":2116},[343],{"categories":2118},[301],{"categories":2120},[],{"categories":2122},[301],{"categories":2124},[301],{"categories":2126},[614],{"categories":2128},[322],{"categories":2130},[346],{"categories":2132},[346],{"categories":2134},[],{"categories":2136},[],{"categories":2138},[],{"categories":2140},[304],{"categories":2142},[252],{"categories":2144},[252],{"categories":2146},[],{"categories":2148},[],{"categories":2150},[301],{"categories":2152},[],{"categories":2154},[304],{"categories":2156},[301],{"categories":2158},[],{"categories":2160},[301],{"categories":2162},[298],{"categories":2164},[301],{"categories":2166},[359],{"categories":2168},[304],{"categories":2170},[301],{"categories":2172},[252],{"categories":2174},[322],{"categories":2176},[304],{"categories":2178},[],{"categories":2180},[322],{"categories":2182},[304],{"categories":2184},[304],{"categories":2186},[],{"categories":2188},[298],{"categories":2190},[304],{"categories":2192},[],{"categories":2194},[301],{"categories":2196},[295],{"categories":2198},[322],{"categories":2200},[614],{"categories":2202},[304],{"categories":2204},[304],{"categories":2206},[295],{"categories":2208},[301],{"categories":2210},[],{"categories":2212},[],{"categories":2214},[343],{"categories":2216},[301,298],{"categories":2218},[],{"categories":2220},[295],{"categories":2222},[346],{"categories":2224},[301],{"categories":2226},[252],{"categories":2228},[301],{"categories":2230},[304],{"categories":2232},[301],{"categories":2234},[301],{"categories":2236},[322],{"categories":2238},[304],{"categories":2240},[],{"categories":2242},[],{"categories":2244},[304],{"categories":2246},[301],{"categories":2248},[614],{"categories":2250},[],{"categories":2252},[301],{"categories":2254},[304],{"categories":2256},[],{"categories":2258},[301],{"categories":2260},[359],{"categories":2262},[346],{"categories":2264},[304],{"categories":2266},[301],{"categories":2268},[614],{"categories":2270},[],{"categories":2272},[301],{"categories":2274},[359],{"categories":2276},[343],{"categories":2278},[301],{"categories":2280},[],{"categories":2282},[359],{"categories":2284},[322],{"categories":2286},[301],{"categories":2288},[301],{"categories":2290},[295],{"categories":2292},[],{"categories":2294},[],{"categories":2296},[343],{"categories":2298},[301],{"categories":2300},[346],{"categories":2302},[359],{"categories":2304},[359],{"categories":2306},[322],{"categories":2308},[],{"categories":2310},[],{"categories":2312},[301],{"categories":2314},[],{"categories":2316},[301,252],{"categories":2318},[322],{"categories":2320},[304],{"categories":2322},[252],{"categories":2324},[301],{"categories":2326},[295],{"categories":2328},[],{"categories":2330},[],{"categories":2332},[295],{"categories":2334},[359],{"categories":2336},[301],{"categories":2338},[],{"categories":2340},[343,301],{"categories":2342},[614],{"categories":2344},[295],{"categories":2346},[],{"categories":2348},[298],{"categories":2350},[298],{"categories":2352},[301],{"categories":2354},[252],{"categories":2356},[304],{"categories":2358},[322],{"categories":2360},[359],{"categories":2362},[343],{"categories":2364},[301],{"categories":2366},[301],{"categories":2368},[301],{"categories":2370},[295],{"categories":2372},[301],{"categories":2374},[304],{"categories":2376},[322],{"categories":2378},[],{"categories":2380},[],{"categories":2382},[346],{"categories":2384},[252],{"categories":2386},[301],{"categories":2388},[343],{"categories":2390},[346],{"categories":2392},[301],{"categories":2394},[301],{"categories":2396},[304],{"categories":2398},[304],{"categories":2400},[301,298],{"categories":2402},[],{"categories":2404},[343],{"categories":2406},[],{"categories":2408},[301],{"categories":2410},[322],{"categories":2412},[295],{"categories":2414},[295],{"categories":2416},[304],{"categories":2418},[301],{"categories":2420},[298],{"categories":2422},[252],{"categories":2424},[359],{"categories":2426},[],{"categories":2428},[322],{"categories":2430},[301],{"categories":2432},[301],{"categories":2434},[322],{"categories":2436},[252],{"categories":2438},[301],{"categories":2440},[304],{"categories":2442},[322],{"categories":2444},[301],{"categories":2446},[343],{"categories":2448},[301],{"categories":2450},[301],{"categories":2452},[614],{"categories":2454},[307],{"categories":2456},[304],{"categories":2458},[301],{"categories":2460},[322],{"categories":2462},[304],{"categories":2464},[359],{"categories":2466},[301],{"categories":2468},[],{"categories":2470},[301],{"categories":2472},[],{"categories":2474},[],{"categories":2476},[],{"categories":2478},[298],{"categories":2480},[301],{"categories":2482},[304],{"categories":2484},[322],{"categories":2486},[322],{"categories":2488},[322],{"categories":2490},[322],{"categories":2492},[],{"categories":2494},[295],{"categories":2496},[304],{"categories":2498},[322],{"categories":2500},[295],{"categories":2502},[304],{"categories":2504},[301],{"categories":2506},[301,304],{"categories":2508},[304],{"categories":2510},[614],{"categories":2512},[322],{"categories":2514},[322],{"categories":2516},[304],{"categories":2518},[301],{"categories":2520},[],{"categories":2522},[322],{"categories":2524},[359],{"categories":2526},[295],{"categories":2528},[301],{"categories":2530},[301],{"categories":2532},[],{"categories":2534},[252],{"categories":2536},[],{"categories":2538},[295],{"categories":2540},[304],{"categories":2542},[322],{"categories":2544},[301],{"categories":2546},[322],{"categories":2548},[295],{"categories":2550},[322],{"categories":2552},[322],{"categories":2554},[],{"categories":2556},[298],{"categories":2558},[304],{"categories":2560},[322],{"categories":2562},[322],{"categories":2564},[322],{"categories":2566},[322],{"categories":2568},[322],{"categories":2570},[322],{"categories":2572},[322],{"categories":2574},[322],{"categories":2576},[322],{"categories":2578},[322],{"categories":2580},[346],{"categories":2582},[295],{"categories":2584},[301],{"categories":2586},[301],{"categories":2588},[],{"categories":2590},[301,295],{"categories":2592},[],{"categories":2594},[304],{"categories":2596},[322],{"categories":2598},[304],{"categories":2600},[301],{"categories":2602},[301],{"categories":2604},[301],{"categories":2606},[301],{"categories":2608},[301],{"categories":2610},[304],{"categories":2612},[298],{"categories":2614},[343],{"categories":2616},[322],{"categories":2618},[301],{"categories":2620},[],{"categories":2622},[],{"categories":2624},[304],{"categories":2626},[343],{"categories":2628},[301],{"categories":2630},[],{"categories":2632},[],{"categories":2634},[359],{"categories":2636},[301],{"categories":2638},[],{"categories":2640},[],{"categories":2642},[295],{"categories":2644},[298],{"categories":2646},[301],{"categories":2648},[298],{"categories":2650},[343],{"categories":2652},[],{"categories":2654},[322],{"categories":2656},[],{"categories":2658},[343],{"categories":2660},[301],{"categories":2662},[359],{"categories":2664},[],{"categories":2666},[359],{"categories":2668},[],{"categories":2670},[],{"categories":2672},[304],{"categories":2674},[],{"categories":2676},[298],{"categories":2678},[295],{"categories":2680},[343],{"categories":2682},[252],{"categories":2684},[],{"categories":2686},[],{"categories":2688},[301],{"categories":2690},[295],{"categories":2692},[359],{"categories":2694},[],{"categories":2696},[304],{"categories":2698},[304],{"categories":2700},[322],{"categories":2702},[301],{"categories":2704},[304],{"categories":2706},[301],{"categories":2708},[304],{"categories":2710},[301],{"categories":2712},[307],{"categories":2714},[322],{"categories":2716},[],{"categories":2718},[359],{"categories":2720},[252],{"categories":2722},[304],{"categories":2724},[],{"categories":2726},[301],{"categories":2728},[304],{"categories":2730},[298],{"categories":2732},[295],{"categories":2734},[301],{"categories":2736},[343],{"categories":2738},[252],{"categories":2740},[252],{"categories":2742},[301],{"categories":2744},[346],{"categories":2746},[301],{"categories":2748},[304],{"categories":2750},[298],{"categories":2752},[304],{"categories":2754},[301],{"categories":2756},[301],{"categories":2758},[304],{"categories":2760},[322],{"categories":2762},[],{"categories":2764},[295],{"categories":2766},[301],{"categories":2768},[304],{"categories":2770},[301],{"categories":2772},[301],{"categories":2774},[],{"categories":2776},[343],{"categories":2778},[298],{"categories":2780},[322],{"categories":2782},[301],{"categories":2784},[301],{"categories":2786},[343],{"categories":2788},[359],{"categories":2790},[346],{"categories":2792},[301],{"categories":2794},[322],{"categories":2796},[301],{"categories":2798},[304],{"categories":2800},[614],{"categories":2802},[301],{"categories":2804},[304],{"categories":2806},[346],{"categories":2808},[],{"categories":2810},[304],{"categories":2812},[252],{"categories":2814},[343],{"categories":2816},[301],{"categories":2818},[295],{"categories":2820},[298],{"categories":2822},[252],{"categories":2824},[],{"categories":2826},[304],{"categories":2828},[301],{"categories":2830},[],{"categories":2832},[322],{"categories":2834},[],{"categories":2836},[322],{"categories":2838},[301],{"categories":2840},[304],{"categories":2842},[304],{"categories":2844},[304],{"categories":2846},[],{"categories":2848},[],{"categories":2850},[301],{"categories":2852},[301],{"categories":2854},[],{"categories":2856},[343],{"categories":2858},[304],{"categories":2860},[359],{"categories":2862},[295],{"categories":2864},[],{"categories":2866},[],{"categories":2868},[322],{"categories":2870},[252],{"categories":2872},[301],{"categories":2874},[301],{"categories":2876},[301],{"categories":2878},[252],{"categories":2880},[322],{"categories":2882},[343],{"categories":2884},[301],{"categories":2886},[301],{"categories":2888},[301],{"categories":2890},[322],{"categories":2892},[301],{"categories":2894},[322],{"categories":2896},[304],{"categories":2898},[304],{"categories":2900},[252],{"categories":2902},[304],{"categories":2904},[301],{"categories":2906},[252],{"categories":2908},[343],{"categories":2910},[],{"categories":2912},[304],{"categories":2914},[],{"categories":2916},[],{"categories":2918},[298],{"categories":2920},[301],{"categories":2922},[304],{"categories":2924},[295],{"categories":2926},[304],{"categories":2928},[359],{"categories":2930},[],{"categories":2932},[304],{"categories":2934},[],{"categories":2936},[295],{"categories":2938},[304],{"categories":2940},[],{"categories":2942},[304],{"categories":2944},[301],{"categories":2946},[322],{"categories":2948},[301],{"categories":2950},[304],{"categories":2952},[322],{"categories":2954},[304],{"categories":2956},[252],{"categories":2958},[343],{"categories":2960},[295],{"categories":2962},[],{"categories":2964},[304],{"categories":2966},[343],{"categories":2968},[322],{"categories":2970},[301],{"categories":2972},[343],{"categories":2974},[295],{"categories":2976},[],{"categories":2978},[304],{"categories":2980},[304],{"categories":2982},[301],{"categories":2984},[],{"categories":2986},[304],{"categories":2988},[307],{"categories":2990},[322],{"categories":2992},[304],{"categories":2994},[298],{"categories":2996},[],{"categories":2998},[301],{"categories":3000},[307],{"categories":3002},[301],{"categories":3004},[304],{"categories":3006},[322],{"categories":3008},[295],{"categories":3010},[614],{"categories":3012},[301],{"categories":3014},[301],{"categories":3016},[301],{"categories":3018},[322],{"categories":3020},[298],{"categories":3022},[301],{"categories":3024},[343],{"categories":3026},[322],{"categories":3028},[614],{"categories":3030},[301],{"categories":3032},[],{"categories":3034},[],{"categories":3036},[614],{"categories":3038},[346],{"categories":3040},[304],{"categories":3042},[304],{"categories":3044},[322],{"categories":3046},[301],{"categories":3048},[295],{"categories":3050},[343],{"categories":3052},[304],{"categories":3054},[301],{"categories":3056},[359],{"categories":3058},[301],{"categories":3060},[304],{"categories":3062},[],{"categories":3064},[301],{"categories":3066},[301],{"categories":3068},[322],{"categories":3070},[295],{"categories":3072},[],{"categories":3074},[301],{"categories":3076},[301],{"categories":3078},[252],{"categories":3080},[343],{"categories":3082},[301,304],{"categories":3084},[359,298],{"categories":3086},[301],{"categories":3088},[],{"categories":3090},[304],{"categories":3092},[],{"categories":3094},[252],{"categories":3096},[301],{"categories":3098},[322],{"categories":3100},[],{"categories":3102},[304],{"categories":3104},[],{"categories":3106},[304],{"categories":3108},[295],{"categories":3110},[304],{"categories":3112},[301],{"categories":3114},[614],{"categories":3116},[359],{"categories":3118},[298],{"categories":3120},[298],{"categories":3122},[295],{"categories":3124},[295],{"categories":3126},[301],{"categories":3128},[304],{"categories":3130},[301],{"categories":3132},[301],{"categories":3134},[295],{"categories":3136},[301],{"categories":3138},[359],{"categories":3140},[322],{"categories":3142},[301],{"categories":3144},[304],{"categories":3146},[301],{"categories":3148},[],{"categories":3150},[252],{"categories":3152},[],{"categories":3154},[304],{"categories":3156},[295],{"categories":3158},[],{"categories":3160},[614],{"categories":3162},[301],{"categories":3164},[],{"categories":3166},[322],{"categories":3168},[304],{"categories":3170},[252],{"categories":3172},[301],{"categories":3174},[304],{"categories":3176},[252],{"categories":3178},[304],{"categories":3180},[322],{"categories":3182},[295],{"categories":3184},[322],{"categories":3186},[252],{"categories":3188},[301],{"categories":3190},[343],{"categories":3192},[301],{"categories":3194},[301],{"categories":3196},[301],{"categories":3198},[301],{"categories":3200},[304],{"categories":3202},[301],{"categories":3204},[304],{"categories":3206},[301],{"categories":3208},[295],{"categories":3210},[301],{"categories":3212},[304],{"categories":3214},[343],{"categories":3216},[295],{"categories":3218},[304],{"categories":3220},[343],{"categories":3222},[],{"categories":3224},[301],{"categories":3226},[301],{"categories":3228},[252],{"categories":3230},[],{"categories":3232},[304],{"categories":3234},[359],{"categories":3236},[301],{"categories":3238},[322],{"categories":3240},[359],{"categories":3242},[304],{"categories":3244},[298],{"categories":3246},[298],{"categories":3248},[301],{"categories":3250},[295],{"categories":3252},[],{"categories":3254},[301],{"categories":3256},[],{"categories":3258},[295],{"categories":3260},[301],{"categories":3262},[304],{"categories":3264},[304],{"categories":3266},[],{"categories":3268},[252],{"categories":3270},[252],{"categories":3272},[359],{"categories":3274},[343],{"categories":3276},[],{"categories":3278},[301],{"categories":3280},[295],{"categories":3282},[301],{"categories":3284},[252],{"categories":3286},[295],{"categories":3288},[322],{"categories":3290},[322],{"categories":3292},[],{"categories":3294},[322],{"categories":3296},[304],{"categories":3298},[343],{"categories":3300},[346],{"categories":3302},[301],{"categories":3304},[],{"categories":3306},[322],{"categories":3308},[252],{"categories":3310},[298],{"categories":3312},[301],{"categories":3314},[295],{"categories":3316},[614],{"categories":3318},[295],{"categories":3320},[],{"categories":3322},[],{"categories":3324},[322],{"categories":3326},[],{"categories":3328},[304],{"categories":3330},[304],{"categories":3332},[304],{"categories":3334},[],{"categories":3336},[301],{"categories":3338},[],{"categories":3340},[322],{"categories":3342},[295],{"categories":3344},[343],{"categories":3346},[301],{"categories":3348},[322],{"categories":3350},[322],{"categories":3352},[],{"categories":3354},[322],{"categories":3356},[295],{"categories":3358},[301],{"categories":3360},[],{"categories":3362},[304],{"categories":3364},[304],{"categories":3366},[295],{"categories":3368},[],{"categories":3370},[],{"categories":3372},[],{"categories":3374},[343],{"categories":3376},[304],{"categories":3378},[301],{"categories":3380},[],{"categories":3382},[],{"categories":3384},[],{"categories":3386},[343],{"categories":3388},[],{"categories":3390},[295],{"categories":3392},[],{"categories":3394},[],{"categories":3396},[343],{"categories":3398},[301],{"categories":3400},[322],{"categories":3402},[],{"categories":3404},[359],{"categories":3406},[322],{"categories":3408},[359],{"categories":3410},[301],{"categories":3412},[],{"categories":3414},[],{"categories":3416},[304],{"categories":3418},[],{"categories":3420},[],{"categories":3422},[304],{"categories":3424},[301],{"categories":3426},[],{"categories":3428},[304],{"categories":3430},[322],{"categories":3432},[359],{"categories":3434},[346],{"categories":3436},[304],{"categories":3438},[304],{"categories":3440},[],{"categories":3442},[],{"categories":3444},[],{"categories":3446},[322],{"categories":3448},[],{"categories":3450},[],{"categories":3452},[343],{"categories":3454},[295],{"categories":3456},[],{"categories":3458},[298],{"categories":3460},[359],{"categories":3462},[301],{"categories":3464},[252],{"categories":3466},[295],{"categories":3468},[346],{"categories":3470},[298],{"categories":3472},[252],{"categories":3474},[],{"categories":3476},[],{"categories":3478},[304],{"categories":3480},[295],{"categories":3482},[343],{"categories":3484},[295],{"categories":3486},[304],{"categories":3488},[614],{"categories":3490},[304],{"categories":3492},[],{"categories":3494},[301],{"categories":3496},[322],{"categories":3498},[252],{"categories":3500},[],{"categories":3502},[343],{"categories":3504},[322],{"categories":3506},[295],{"categories":3508},[304],{"categories":3510},[301],{"categories":3512},[298],{"categories":3514},[304,614],{"categories":3516},[304],{"categories":3518},[252],{"categories":3520},[301],{"categories":3522},[346],{"categories":3524},[359],{"categories":3526},[304],{"categories":3528},[],{"categories":3530},[304],{"categories":3532},[301],{"categories":3534},[298],{"categories":3536},[],{"categories":3538},[],{"categories":3540},[301],{"categories":3542},[346],{"categories":3544},[301],{"categories":3546},[],{"categories":3548},[322],{"categories":3550},[],{"categories":3552},[322],{"categories":3554},[252],{"categories":3556},[304],{"categories":3558},[301],{"categories":3560},[359],{"categories":3562},[252],{"categories":3564},[],{"categories":3566},[322],{"categories":3568},[301],{"categories":3570},[],{"categories":3572},[301],{"categories":3574},[304],{"categories":3576},[301],{"categories":3578},[304],{"categories":3580},[301],{"categories":3582},[301],{"categories":3584},[301],{"categories":3586},[301],{"categories":3588},[298],{"categories":3590},[],{"categories":3592},[307],{"categories":3594},[322],{"categories":3596},[301],{"categories":3598},[],{"categories":3600},[252],{"categories":3602},[301],{"categories":3604},[301],{"categories":3606},[304],{"categories":3608},[322],{"categories":3610},[301],{"categories":3612},[301],{"categories":3614},[298],{"categories":3616},[304],{"categories":3618},[343],{"categories":3620},[],{"categories":3622},[346],{"categories":3624},[301],{"categories":3626},[],{"categories":3628},[322],{"categories":3630},[359],{"categories":3632},[],{"categories":3634},[],{"categories":3636},[322],{"categories":3638},[322],{"categories":3640},[359],{"categories":3642},[295],{"categories":3644},[304],{"categories":3646},[304],{"categories":3648},[301],{"categories":3650},[298],{"categories":3652},[],{"categories":3654},[],{"categories":3656},[322],{"categories":3658},[346],{"categories":3660},[252],{"categories":3662},[304],{"categories":3664},[343],{"categories":3666},[346],{"categories":3668},[346],{"categories":3670},[],{"categories":3672},[322],{"categories":3674},[301],{"categories":3676},[301],{"categories":3678},[252],{"categories":3680},[],{"categories":3682},[322],{"categories":3684},[322],{"categories":3686},[322],{"categories":3688},[],{"categories":3690},[304],{"categories":3692},[301],{"categories":3694},[],{"categories":3696},[295],{"categories":3698},[298],{"categories":3700},[],{"categories":3702},[301],{"categories":3704},[301],{"categories":3706},[],{"categories":3708},[252],{"categories":3710},[],{"categories":3712},[],{"categories":3714},[],{"categories":3716},[],{"categories":3718},[301],{"categories":3720},[322],{"categories":3722},[],{"categories":3724},[],{"categories":3726},[301],{"categories":3728},[301],{"categories":3730},[301],{"categories":3732},[346],{"categories":3734},[301],{"categories":3736},[346],{"categories":3738},[],{"categories":3740},[346],{"categories":3742},[346],{"categories":3744},[614],{"categories":3746},[304],{"categories":3748},[252],{"categories":3750},[],{"categories":3752},[],{"categories":3754},[346],{"categories":3756},[252],{"categories":3758},[252],{"categories":3760},[252],{"categories":3762},[],{"categories":3764},[295],{"categories":3766},[252],{"categories":3768},[252],{"categories":3770},[295],{"categories":3772},[252],{"categories":3774},[298],{"categories":3776},[252],{"categories":3778},[252],{"categories":3780},[252],{"categories":3782},[346],{"categories":3784},[322],{"categories":3786},[322],{"categories":3788},[301],{"categories":3790},[252],{"categories":3792},[346],{"categories":3794},[614],{"categories":3796},[346],{"categories":3798},[346],{"categories":3800},[346],{"categories":3802},[],{"categories":3804},[298],{"categories":3806},[],{"categories":3808},[614],{"categories":3810},[252],{"categories":3812},[252],{"categories":3814},[252],{"categories":3816},[304],{"categories":3818},[322,298],{"categories":3820},[346],{"categories":3822},[],{"categories":3824},[],{"categories":3826},[346],{"categories":3828},[],{"categories":3830},[346],{"categories":3832},[322],{"categories":3834},[304],{"categories":3836},[],{"categories":3838},[252],{"categories":3840},[301],{"categories":3842},[343],{"categories":3844},[],{"categories":3846},[301],{"categories":3848},[],{"categories":3850},[322],{"categories":3852},[295],{"categories":3854},[346],{"categories":3856},[],{"categories":3858},[252],{"categories":3860},[322],[3862,4122,4612,4748],{"id":3863,"title":3864,"ai":3865,"body":3870,"categories":4104,"created_at":253,"date_modified":253,"description":245,"extension":254,"faq":253,"featured":255,"kicker_label":253,"meta":4105,"navigation":274,"path":4109,"published_at":4110,"question":253,"scraped_at":4111,"seo":4112,"sitemap":4113,"source_id":4114,"source_name":4115,"source_type":281,"source_url":4116,"stem":4117,"tags":4118,"thumbnail_url":253,"tldr":4119,"tweet":253,"unknown_tags":4120,"__hash__":4121},"summaries\u002Fsummaries\u002F565cd461d5e56e35-python-variables-sticky-notes-on-shared-objects-summary.md","Python Variables: Sticky Notes on Shared Objects",{"provider":7,"model":8,"input_tokens":3866,"output_tokens":3867,"processing_time_ms":3868,"cost_usd":3869},5293,1238,13529,0.0016551,{"type":14,"value":3871,"toc":4099},[3872,3876,3887,3890,3895,3938,3943,3977,3980,3984,3999,4004,4044,4051,4055,4062,4090,4095],[17,3873,3875],{"id":3874},"names-bind-to-objects-not-values","Names Bind to Objects, Not Values",[22,3877,3878,3879,3882,3883,3886],{},"Python lacks variables as fixed memory boxes like in C or Java. Instead, everything is an object in memory, and variables are labels (sticky notes) pointing to those objects. Assigning ",[37,3880,3881],{},"x = [1, 2, 3]"," creates a list object (e.g., at address 0x1234) and binds the name ",[37,3884,3885],{},"x"," to it. Passing to a function creates a new local label bound to the same object—no copy occurs.",[22,3888,3889],{},"This 'call by sharing' means mutations to mutable objects (lists, dicts) affect all bound names, but rebinding a local name inside a function doesn't alter the caller's object.",[22,3891,3892],{},[32,3893,3894],{},"mutate example:",[3896,3897,3901],"pre",{"className":3898,"code":3899,"language":3900,"meta":245,"style":245},"language-python shiki shiki-themes github-light github-dark","def mutate(lst):\n    lst.append(99)  # Mutates shared object\n\nx = [10, 20]\nmutate(x)\n# x now [10, 20, 99]—original object changed\n","python",[37,3902,3903,3911,3916,3921,3926,3932],{"__ignoreMap":245},[3904,3905,3908],"span",{"class":3906,"line":3907},"line",1,[3904,3909,3910],{},"def mutate(lst):\n",[3904,3912,3913],{"class":3906,"line":246},[3904,3914,3915],{},"    lst.append(99)  # Mutates shared object\n",[3904,3917,3918],{"class":3906,"line":271},[3904,3919,3920],{"emptyLinePlaceholder":274},"\n",[3904,3922,3923],{"class":3906,"line":270},[3904,3924,3925],{},"x = [10, 20]\n",[3904,3927,3929],{"class":3906,"line":3928},5,[3904,3930,3931],{},"mutate(x)\n",[3904,3933,3935],{"class":3906,"line":3934},6,[3904,3936,3937],{},"# x now [10, 20, 99]—original object changed\n",[22,3939,3940],{},[32,3941,3942],{},"rebind example:",[3896,3944,3946],{"className":3898,"code":3945,"language":3900,"meta":245,"style":245},"def rebind(lst):\n    lst = [1, 2, 3]  # Local label now points to new object\n\nx = [10, 20, 99]\nrebind(x)\n# x unchanged—original object untouched\n",[37,3947,3948,3953,3958,3962,3967,3972],{"__ignoreMap":245},[3904,3949,3950],{"class":3906,"line":3907},[3904,3951,3952],{},"def rebind(lst):\n",[3904,3954,3955],{"class":3906,"line":246},[3904,3956,3957],{},"    lst = [1, 2, 3]  # Local label now points to new object\n",[3904,3959,3960],{"class":3906,"line":271},[3904,3961,3920],{"emptyLinePlaceholder":274},[3904,3963,3964],{"class":3906,"line":270},[3904,3965,3966],{},"x = [10, 20, 99]\n",[3904,3968,3969],{"class":3906,"line":3928},[3904,3970,3971],{},"rebind(x)\n",[3904,3973,3974],{"class":3906,"line":3934},[3904,3975,3976],{},"# x unchanged—original object untouched\n",[22,3978,3979],{},"Rebinding peels the local label off the shared object and attaches it to a new one, leaving external references intact.",[17,3981,3983],{"id":3982},"mutable-defaults-create-permanent-shared-state","Mutable Defaults Create Permanent Shared State",[22,3985,3986,3987,3990,3991,3994,3995,3998],{},"Functions are objects with defaults evaluated ",[32,3988,3989],{},"once at definition time",", stored in ",[37,3992,3993],{},".__defaults__",". A mutable default like ",[37,3996,3997],{},"items=[]"," creates one list object bound to the function forever—GC can't reclaim it while the function lives.",[22,4000,4001],{},[32,4002,4003],{},"Buggy example:",[3896,4005,4007],{"className":3898,"code":4006,"language":3900,"meta":245,"style":245},"def add_item(item, items=[]):\n    items.append(item)\n    return items\n\nprint(add_item(1))      # [1]—mutates function's default\nprint(add_item(2, []))  # [2]—uses new list\nprint(add_item(\"a\"))   # [1, 'a']—reuses mutated default\n",[37,4008,4009,4014,4019,4024,4028,4033,4038],{"__ignoreMap":245},[3904,4010,4011],{"class":3906,"line":3907},[3904,4012,4013],{},"def add_item(item, items=[]):\n",[3904,4015,4016],{"class":3906,"line":246},[3904,4017,4018],{},"    items.append(item)\n",[3904,4020,4021],{"class":3906,"line":271},[3904,4022,4023],{},"    return items\n",[3904,4025,4026],{"class":3906,"line":270},[3904,4027,3920],{"emptyLinePlaceholder":274},[3904,4029,4030],{"class":3906,"line":3928},[3904,4031,4032],{},"print(add_item(1))      # [1]—mutates function's default\n",[3904,4034,4035],{"class":3906,"line":3934},[3904,4036,4037],{},"print(add_item(2, []))  # [2]—uses new list\n",[3904,4039,4041],{"class":3906,"line":4040},7,[3904,4042,4043],{},"print(add_item(\"a\"))   # [1, 'a']—reuses mutated default\n",[22,4045,4046,4047,4050],{},"First call mutates the shared default list. Later calls without ",[37,4048,4049],{},"items"," reuse it, accumulating data across invocations. In servers or workers, this leaks state between requests\u002Fjobs, manifesting as ghost bugs like User B seeing User A's data.",[17,4052,4054],{"id":4053},"defensive-fix-none-instantiation-prevents-shared-state","Defensive Fix: None + Instantiation Prevents Shared State",[22,4056,4057,4058,4061],{},"Replace mutable defaults with ",[37,4059,4060],{},"None",", then create fresh objects inside the function at call time:",[3896,4063,4065],{"className":3898,"code":4064,"language":3900,"meta":245,"style":245},"def add_item(item, items=None):\n    if items is None:\n        items = []  # New list per call\n    items.append(item)\n    return items\n",[37,4066,4067,4072,4077,4082,4086],{"__ignoreMap":245},[3904,4068,4069],{"class":3906,"line":3907},[3904,4070,4071],{},"def add_item(item, items=None):\n",[3904,4073,4074],{"class":3906,"line":246},[3904,4075,4076],{},"    if items is None:\n",[3904,4078,4079],{"class":3906,"line":271},[3904,4080,4081],{},"        items = []  # New list per call\n",[3904,4083,4084],{"class":3906,"line":270},[3904,4085,4018],{},[3904,4087,4088],{"class":3906,"line":3928},[3904,4089,4023],{},[22,4091,4092,4094],{},[37,4093,4060],{}," is immutable\u002Fsafe. Instantiation happens on the heap each run, ensuring no shared state. Enforce via linters like Flake8's B006 banning mutable defaults. This model resolves 90% of Python's 'weirdness' for production code.",[4096,4097,4098],"style",{},"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);}",{"title":245,"searchDepth":246,"depth":246,"links":4100},[4101,4102,4103],{"id":3874,"depth":246,"text":3875},{"id":3982,"depth":246,"text":3983},{"id":4053,"depth":246,"text":4054},[252],{"content_references":4106,"triage":4107},[],{"relevance":270,"novelty":271,"quality":270,"actionability":270,"composite":272,"reasoning":4108},"Category: Software Engineering. The article provides a deep dive into Python's variable handling, addressing a common pain point for developers regarding mutable defaults and shared state. It offers practical solutions to avoid bugs, making it actionable for developers looking to improve their code quality.","\u002Fsummaries\u002F565cd461d5e56e35-python-variables-sticky-notes-on-shared-objects-summary","2026-05-05 09:11:46","2026-05-05 16:09:35",{"title":3864,"description":245},{"loc":4109},"565cd461d5e56e35","Data and Beyond","https:\u002F\u002Fmedium.com\u002Fdata-and-beyond\u002Fpythons-silent-production-killer-why-pass-by-reference-is-a-lie-b7f1f5ce7930?source=rss----b680b860beb1---4","summaries\u002F565cd461d5e56e35-python-variables-sticky-notes-on-shared-objects-summary",[3900,285,286],"Forget 'pass-by-reference'—Python variables are labels binding to objects via 'call by sharing'. Mutable defaults like [] create shared state across calls, causing ghost bugs; fix by using None and instantiating inside functions.",[286],"fzEeWz1c9LJmn1gZgGIJuMZGoHMLOUzv4UIryNTNhfk",{"id":4123,"title":4124,"ai":4125,"body":4130,"categories":4593,"created_at":253,"date_modified":253,"description":245,"extension":254,"faq":253,"featured":255,"kicker_label":253,"meta":4594,"navigation":274,"path":4598,"published_at":4599,"question":253,"scraped_at":4600,"seo":4601,"sitemap":4602,"source_id":4603,"source_name":4604,"source_type":281,"source_url":4605,"stem":4606,"tags":4607,"thumbnail_url":253,"tldr":4609,"tweet":253,"unknown_tags":4610,"__hash__":4611},"summaries\u002Fsummaries\u002F8d5558e87957c77a-scale-compose-nav-with-nested-graphs-and-state-lay-summary.md","Scale Compose Nav with Nested Graphs and State Layers",{"provider":7,"model":8,"input_tokens":4126,"output_tokens":4127,"processing_time_ms":4128,"cost_usd":4129},6768,1765,14725,0.00221345,{"type":14,"value":4131,"toc":4587},[4132,4136,4139,4142,4208,4211,4287,4290,4293,4326,4330,4333,4336,4357,4386,4398,4401,4405,4412,4468,4471,4500,4503,4507,4528,4567,4585],[17,4133,4135],{"id":4134},"nested-graphs-isolate-features-and-simplify-reasoning","Nested Graphs Isolate Features and Simplify Reasoning",[22,4137,4138],{},"Flat NavHosts with dozens of composables become unmaintainable—files bloat, flows interfere, back stacks confuse, and refactors risk breakage. Instead, centralize ownership in one root NavHost that only defines major app flows (e.g., auth, main), then nest separate graphs per feature.",[22,4140,4141],{},"Root setup:",[3896,4143,4147],{"className":4144,"code":4145,"language":4146,"meta":245,"style":245},"language-kotlin shiki shiki-themes github-light github-dark","@Composable\nfun AppNavHost(navController: NavHostController) {\n    NavHost(\n        navController = navController,\n        startDestination = Graph.AUTH,\n        route = Graph.ROOT\n    ) {\n        authNavGraph(navController)\n        mainNavGraph(navController)\n    }\n}\n","kotlin",[37,4148,4149,4154,4159,4164,4169,4174,4179,4184,4190,4196,4202],{"__ignoreMap":245},[3904,4150,4151],{"class":3906,"line":3907},[3904,4152,4153],{},"@Composable\n",[3904,4155,4156],{"class":3906,"line":246},[3904,4157,4158],{},"fun AppNavHost(navController: NavHostController) {\n",[3904,4160,4161],{"class":3906,"line":271},[3904,4162,4163],{},"    NavHost(\n",[3904,4165,4166],{"class":3906,"line":270},[3904,4167,4168],{},"        navController = navController,\n",[3904,4170,4171],{"class":3906,"line":3928},[3904,4172,4173],{},"        startDestination = Graph.AUTH,\n",[3904,4175,4176],{"class":3906,"line":3934},[3904,4177,4178],{},"        route = Graph.ROOT\n",[3904,4180,4181],{"class":3906,"line":4040},[3904,4182,4183],{},"    ) {\n",[3904,4185,4187],{"class":3906,"line":4186},8,[3904,4188,4189],{},"        authNavGraph(navController)\n",[3904,4191,4193],{"class":3906,"line":4192},9,[3904,4194,4195],{},"        mainNavGraph(navController)\n",[3904,4197,4199],{"class":3906,"line":4198},10,[3904,4200,4201],{},"    }\n",[3904,4203,4205],{"class":3906,"line":4204},11,[3904,4206,4207],{},"}\n",[22,4209,4210],{},"Feature graphs group related screens:",[3896,4212,4214],{"className":4144,"code":4213,"language":4146,"meta":245,"style":245},"fun NavGraphBuilder.authNavGraph(navController: NavHostController) {\n    navigation(startDestination = \"login\", route = Graph.AUTH) {\n        composable(\"login\") {\n            LoginScreen(\n                onLoginSuccess = {\n                    navController.navigate(Graph.MAIN) {\n                        popUpTo(Graph.AUTH) { inclusive = true }\n                    }\n                }\n            )\n        }\n        \u002F\u002F signup composable...\n    }\n}\n",[37,4215,4216,4221,4226,4231,4236,4241,4246,4251,4256,4261,4266,4271,4277,4282],{"__ignoreMap":245},[3904,4217,4218],{"class":3906,"line":3907},[3904,4219,4220],{},"fun NavGraphBuilder.authNavGraph(navController: NavHostController) {\n",[3904,4222,4223],{"class":3906,"line":246},[3904,4224,4225],{},"    navigation(startDestination = \"login\", route = Graph.AUTH) {\n",[3904,4227,4228],{"class":3906,"line":271},[3904,4229,4230],{},"        composable(\"login\") {\n",[3904,4232,4233],{"class":3906,"line":270},[3904,4234,4235],{},"            LoginScreen(\n",[3904,4237,4238],{"class":3906,"line":3928},[3904,4239,4240],{},"                onLoginSuccess = {\n",[3904,4242,4243],{"class":3906,"line":3934},[3904,4244,4245],{},"                    navController.navigate(Graph.MAIN) {\n",[3904,4247,4248],{"class":3906,"line":4040},[3904,4249,4250],{},"                        popUpTo(Graph.AUTH) { inclusive = true }\n",[3904,4252,4253],{"class":3906,"line":4186},[3904,4254,4255],{},"                    }\n",[3904,4257,4258],{"class":3906,"line":4192},[3904,4259,4260],{},"                }\n",[3904,4262,4263],{"class":3906,"line":4198},[3904,4264,4265],{},"            )\n",[3904,4267,4268],{"class":3906,"line":4204},[3904,4269,4270],{},"        }\n",[3904,4272,4274],{"class":3906,"line":4273},12,[3904,4275,4276],{},"        \u002F\u002F signup composable...\n",[3904,4278,4280],{"class":3906,"line":4279},13,[3904,4281,4201],{},[3904,4283,4285],{"class":3906,"line":4284},14,[3904,4286,4207],{},[22,4288,4289],{},"This keeps graphs small, prevents cross-flow pollution, and makes back stack behavior predictable—e.g., clear auth stack on login success.",[22,4291,4292],{},"Centralize routes with sealed classes to avoid string typos:",[3896,4294,4296],{"className":4144,"code":4295,"language":4146,"meta":245,"style":245},"sealed class AppScreen(val route: String) {\n    data object Home : AppScreen(\"home\")\n    data object UserDetails : AppScreen(\"user\u002F{userId}\") {\n        fun createRoute(userId: Long) = \"user\u002F$userId\"\n    }\n}\n",[37,4297,4298,4303,4308,4313,4318,4322],{"__ignoreMap":245},[3904,4299,4300],{"class":3906,"line":3907},[3904,4301,4302],{},"sealed class AppScreen(val route: String) {\n",[3904,4304,4305],{"class":3906,"line":246},[3904,4306,4307],{},"    data object Home : AppScreen(\"home\")\n",[3904,4309,4310],{"class":3906,"line":271},[3904,4311,4312],{},"    data object UserDetails : AppScreen(\"user\u002F{userId}\") {\n",[3904,4314,4315],{"class":3906,"line":270},[3904,4316,4317],{},"        fun createRoute(userId: Long) = \"user\u002F$userId\"\n",[3904,4319,4320],{"class":3906,"line":3928},[3904,4321,4201],{},[3904,4323,4324],{"class":3906,"line":3934},[3904,4325,4207],{},[17,4327,4329],{"id":4328},"layered-state-keeps-navigation-stable","Layered State Keeps Navigation Stable",[22,4331,4332],{},"Navigation only handles movement and small primitives (IDs, filters, flags)—never full objects, which fail serialization and stale quickly. Load data in destinations.",[22,4334,4335],{},"Three layers:",[4337,4338,4339,4348],"ol",{},[29,4340,4341,4344,4345,243],{},[32,4342,4343],{},"Nav args",": Primitives only, e.g., ",[37,4346,4347],{},"navController.navigate(UserDetails.createRoute(42L))",[29,4349,4350,4352,4353,4356],{},[32,4351,98],{},": Screen\u002Fbusiness state with API calls, loading\u002Ferrors. Extract args via ",[37,4354,4355],{},"SavedStateHandle",":",[3896,4358,4360],{"className":4144,"code":4359,"language":4146,"meta":245,"style":245},"class UserDetailsViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {\n    private val userId: Long = checkNotNull(savedStateHandle[\"userId\"])\n    val uiState = MutableStateFlow(UserDetailsUiState())\n    \u002F\u002F Load data in init...\n}\n",[37,4361,4362,4367,4372,4377,4382],{"__ignoreMap":245},[3904,4363,4364],{"class":3906,"line":3907},[3904,4365,4366],{},"class UserDetailsViewModel(savedStateHandle: SavedStateHandle) : ViewModel() {\n",[3904,4368,4369],{"class":3906,"line":246},[3904,4370,4371],{},"    private val userId: Long = checkNotNull(savedStateHandle[\"userId\"])\n",[3904,4373,4374],{"class":3906,"line":271},[3904,4375,4376],{},"    val uiState = MutableStateFlow(UserDetailsUiState())\n",[3904,4378,4379],{"class":3906,"line":270},[3904,4380,4381],{},"    \u002F\u002F Load data in init...\n",[3904,4383,4384],{"class":3906,"line":3928},[3904,4385,4207],{},[4337,4387,4388],{"start":271},[29,4389,4390,4393,4394,4397],{},[32,4391,4392],{},"Composable state",": UI-only like ",[37,4395,4396],{},"rememberSaveable { mutableStateOf(\"\") }"," for inputs\u002Ftoggles.",[22,4399,4400],{},"This separation makes nav robust: pass ID, fetch fresh data, avoid fragile deep passing.",[17,4402,4404],{"id":4403},"route-level-wiring-and-tab-polish","Route-Level Wiring and Tab Polish",[22,4406,4407,4408,4411],{},"Avoid scattering ",[37,4409,4410],{},"NavController"," in leaf UI—pass lambdas from route composables for reusable, testable screens:",[3896,4413,4415],{"className":4144,"code":4414,"language":4146,"meta":245,"style":245},"@Composable\nfun HomeRoute(navController: NavHostController) {\n    HomeScreen(\n        onOpenSettings = { navController.navigate(\"settings\") },\n        onOpenUser = { id -> navController.navigate(\"user\u002F$id\") }\n    )\n}\n@Composable\nfun HomeScreen(onOpenSettings: () -> Unit, onOpenUser: (Long) -> Unit) {\n    \u002F\u002F Buttons call lambdas\n}\n",[37,4416,4417,4421,4426,4431,4436,4441,4446,4450,4454,4459,4464],{"__ignoreMap":245},[3904,4418,4419],{"class":3906,"line":3907},[3904,4420,4153],{},[3904,4422,4423],{"class":3906,"line":246},[3904,4424,4425],{},"fun HomeRoute(navController: NavHostController) {\n",[3904,4427,4428],{"class":3906,"line":271},[3904,4429,4430],{},"    HomeScreen(\n",[3904,4432,4433],{"class":3906,"line":270},[3904,4434,4435],{},"        onOpenSettings = { navController.navigate(\"settings\") },\n",[3904,4437,4438],{"class":3906,"line":3928},[3904,4439,4440],{},"        onOpenUser = { id -> navController.navigate(\"user\u002F$id\") }\n",[3904,4442,4443],{"class":3906,"line":3934},[3904,4444,4445],{},"    )\n",[3904,4447,4448],{"class":3906,"line":4040},[3904,4449,4207],{},[3904,4451,4452],{"class":3906,"line":4186},[3904,4453,4153],{},[3904,4455,4456],{"class":3906,"line":4192},[3904,4457,4458],{},"fun HomeScreen(onOpenSettings: () -> Unit, onOpenUser: (Long) -> Unit) {\n",[3904,4460,4461],{"class":3906,"line":4198},[3904,4462,4463],{},"    \u002F\u002F Buttons call lambdas\n",[3904,4465,4466],{"class":3906,"line":4204},[3904,4467,4207],{},[22,4469,4470],{},"For bottom tabs, use this nav spec to avoid duplicates, save\u002Frestore state:",[3896,4472,4474],{"className":4144,"code":4473,"language":4146,"meta":245,"style":245},"navController.navigate(route) {\n    popUpTo(navController.graph.startDestinationId) { saveState = true }\n    launchSingleTop = true\n    restoreState = true\n}\n",[37,4475,4476,4481,4486,4491,4496],{"__ignoreMap":245},[3904,4477,4478],{"class":3906,"line":3907},[3904,4479,4480],{},"navController.navigate(route) {\n",[3904,4482,4483],{"class":3906,"line":246},[3904,4484,4485],{},"    popUpTo(navController.graph.startDestinationId) { saveState = true }\n",[3904,4487,4488],{"class":3906,"line":271},[3904,4489,4490],{},"    launchSingleTop = true\n",[3904,4492,4493],{"class":3906,"line":270},[3904,4494,4495],{},"    restoreState = true\n",[3904,4497,4498],{"class":3906,"line":3928},[3904,4499,4207],{},[22,4501,4502],{},"This preserves tab state across switches, polishing UX.",[17,4504,4506],{"id":4505},"full-stack-ties-it-together","Full Stack Ties It Together",[22,4508,4509,4510,212,4513,54,4516,4519,4520,4523,4524,4527],{},"Thin ",[37,4511,4512],{},"MainActivity",[37,4514,4515],{},"App()",[37,4517,4518],{},"rememberNavController()",". ",[37,4521,4522],{},"AppNavHost"," wires root. Graphs use route sealed interfaces (e.g., ",[37,4525,4526],{},"AuthDest.Login.route","). UserDetails handles args:",[3896,4529,4531],{"className":4144,"code":4530,"language":4146,"meta":245,"style":245},"composable(\n    route = MainDest.UserDetails.route,\n    arguments = listOf(navArgument(MainDest.UserDetails.ARG) { type = NavType.LongType })\n) { entry ->\n    val userId = entry.arguments?.getLong(MainDest.UserDetails.ARG) ?: return@composable\n    UserDetailsRoute(userId)\n}\n",[37,4532,4533,4538,4543,4548,4553,4558,4563],{"__ignoreMap":245},[3904,4534,4535],{"class":3906,"line":3907},[3904,4536,4537],{},"composable(\n",[3904,4539,4540],{"class":3906,"line":246},[3904,4541,4542],{},"    route = MainDest.UserDetails.route,\n",[3904,4544,4545],{"class":3906,"line":271},[3904,4546,4547],{},"    arguments = listOf(navArgument(MainDest.UserDetails.ARG) { type = NavType.LongType })\n",[3904,4549,4550],{"class":3906,"line":270},[3904,4551,4552],{},") { entry ->\n",[3904,4554,4555],{"class":3906,"line":3928},[3904,4556,4557],{},"    val userId = entry.arguments?.getLong(MainDest.UserDetails.ARG) ?: return@composable\n",[3904,4559,4560],{"class":3906,"line":3934},[3904,4561,4562],{},"    UserDetailsRoute(userId)\n",[3904,4564,4565],{"class":3906,"line":4040},[3904,4566,4207],{},[22,4568,4569,4572,4573,4576,4577,4580,4581,4584],{},[37,4570,4571],{},"UserDetailsRoute"," injects ",[37,4574,4575],{},"viewModel()",", collects ",[37,4578,4579],{},"uiState",", passes to pure ",[37,4582,4583],{},"UserDetailsScreen",". Add screens freely without central chaos.",[4096,4586,4098],{},{"title":245,"searchDepth":246,"depth":246,"links":4588},[4589,4590,4591,4592],{"id":4134,"depth":246,"text":4135},{"id":4328,"depth":246,"text":4329},{"id":4403,"depth":246,"text":4404},{"id":4505,"depth":246,"text":4506},[252],{"content_references":4595,"triage":4596},[],{"relevance":270,"novelty":271,"quality":270,"actionability":270,"composite":272,"reasoning":4597},"Category: Software Engineering. The article provides a practical approach to scaling navigation in Jetpack Compose, addressing a common pain point for developers managing complex app architectures. It includes specific code examples and a structured method for implementing nested graphs and layered state, making it actionable for developers looking to improve their navigation systems.","\u002Fsummaries\u002F8d5558e87957c77a-scale-compose-nav-with-nested-graphs-and-state-lay-summary","2026-05-01 20:30:17","2026-05-03 17:00:35",{"title":4124,"description":245},{"loc":4598},"8d5558e87957c77a","Level Up Coding","https:\u002F\u002Flevelup.gitconnected.com\u002Fscaling-navigation-in-jetpack-compose-from-simple-apps-to-real-world-architecture-c6cf897f5a58?source=rss----5517fd7b58a6---4","summaries\u002F8d5558e87957c77a-scale-compose-nav-with-nested-graphs-and-state-lay-summary",[285,286,4608],"dev-productivity","For apps with 20-50 screens, use one root NavHost with nested feature graphs, centralized route objects, and layered state (nav args for IDs, ViewModels for data, composables for UI) to prevent navigation fragility.",[286,4608],"MdJCmrlysKnhasneoBQPUQQjKPDk05jtmg82txx-jf4",{"id":4613,"title":4614,"ai":4615,"body":4620,"categories":4721,"created_at":253,"date_modified":253,"description":245,"extension":254,"faq":253,"featured":255,"kicker_label":253,"meta":4722,"navigation":274,"path":4734,"published_at":4735,"question":253,"scraped_at":4736,"seo":4737,"sitemap":4738,"source_id":4739,"source_name":4740,"source_type":281,"source_url":4741,"stem":4742,"tags":4743,"thumbnail_url":253,"tldr":4745,"tweet":253,"unknown_tags":4746,"__hash__":4747},"summaries\u002Fsummaries\u002Fc116726456b33e2b-tanstack-server-components-opt-in-granularity-beat-summary.md","TanStack Server Components: Opt-In Granularity Beats Next.js",{"provider":7,"model":8,"input_tokens":4616,"output_tokens":4617,"processing_time_ms":4618,"cost_usd":4619},7116,1537,11991,0.00216905,{"type":14,"value":4621,"toc":4716},[4622,4626,4641,4648,4652,4663,4666,4670,4673,4713],[17,4623,4625],{"id":4624},"opt-in-server-rendering-via-server-functions","Opt-In Server Rendering via Server Functions",[22,4627,4628,4629,4632,4633,4636,4637,4640],{},"Render React components on the server explicitly by wrapping them in ",[37,4630,4631],{},"renderServerComponent"," inside a server function, then fetch like JSON data. This runs server-only code (e.g., ",[37,4634,4635],{},"os.hostname()",", env vars) without changing your client-first app structure. Pass computed values as props to keep components pure and reusable on client or server. In a TanStack Start route loader, await the server function and use ",[37,4638,4639],{},"loaderData"," to render: the boundary stays clear since server logic lives solely in the function. Replace server components with JSON fetches seamlessly—no framework overhaul required, unlike Next.js's server-first tree where 'use client' opts out interactivity.",[22,4642,4643,4644,4647],{},"For multiple components, use ",[37,4645,4646],{},"Promise.all"," in one server function or return promises directly for streaming. Client-side, wrap in Suspense for skeletons: slow components load independently without blocking the page.",[17,4649,4651],{"id":4650},"composite-components-eliminate-server-controlled-client-trees","Composite Components Eliminate Server-Controlled Client Trees",[22,4653,4654,4655,4658,4659,4662],{},"Avoid nesting 'use client' components inside server renders, which muddies boundaries (e.g., tracing counter logic requires jumping files). Instead, return ",[37,4656,4657],{},"createCompositeComponent"," from server functions, defining slots for client content. Fetch the source in loaders, then render with ",[37,4660,4661],{},"\u003CComposite source={greetingSource}>","—server defines structure and data passthrough, but clients fill slots.",[22,4664,4665],{},"This keeps all client decisions in client code: server sees opaque slots, executes no client functions. Integrates with TanStack Query for caching\u002FCDN simplicity. Result: explicit server\u002Fclient separation, no 'use client' needed for slots.",[17,4667,4669],{"id":4668},"slot-patterns-for-flexible-client-integration","Slot Patterns for Flexible Client Integration",[22,4671,4672],{},"Use three slot types to inject client components without server knowledge of their identity:",[26,4674,4675,4685,4695],{},[29,4676,4677,4680,4681,4684],{},[32,4678,4679],{},"Children slots",": Pass ",[37,4682,4683],{},"{children}"," prop; server forwards anything provided (e.g., counter under greeting).",[29,4686,4687,4690,4691,4694],{},[32,4688,4689],{},"Render props",": Define function props (e.g., ",[37,4692,4693],{},"renderActions?: (postId: string, authorId: string) => ReactNode","). Server calls optionally with data (e.g., above post title); client provides function returning component. Opaque to server—runs client-side, avoids double-fetches (author data passes directly).",[29,4696,4697,4700,4701,4704,4705,4708,4709,4712],{},[32,4698,4699],{},"Component props",": Pass component directly (e.g., ",[37,4702,4703],{},"PostActions: Component\u003C{postId: string, authorId: string}>","). Server renders ",[37,4706,4707],{},"\u003CPostActions {...data} \u002F>"," as placeholder. Swap implementations client-side (e.g., ",[37,4710,4711],{},"FakePostActions"," works identically). Prefer render props if needing data transforms; component props for direct passthrough.",[22,4714,4715],{},"These solve real issues: targeted actions (like\u002Ffollow) without children dumping at bottom, data sharing without client refetching. Server provides data\u002Fslots; client handles rendering—reverses Next.js logic for better DX and modularity.",{"title":245,"searchDepth":246,"depth":246,"links":4717},[4718,4719,4720],{"id":4624,"depth":246,"text":4625},{"id":4650,"depth":246,"text":4651},{"id":4668,"depth":246,"text":4669},[252],{"content_references":4723,"triage":4732},[4724,4728],{"type":4725,"title":4726,"url":4727,"context":261},"tool","TanStack Start Server Components Docs","https:\u002F\u002Ftanstack.com\u002Fstart\u002Flatest\u002Fdocs\u002Fframework\u002Freact\u002Fguide\u002Fserver-components",{"type":259,"title":4729,"url":4730,"context":4731},"TanStack React Server Components Announcement","https:\u002F\u002Ftanstack.com\u002Fblog\u002Freact-server-components","cited",{"relevance":270,"novelty":271,"quality":270,"actionability":270,"composite":272,"reasoning":4733},"Category: Design & Frontend. The article discusses practical techniques for rendering React components on the server, addressing a specific pain point for developers looking to optimize their frontend architecture. It provides actionable insights on using `renderServerComponent` and `createCompositeComponent`, which can be directly applied in building AI-powered products.","\u002Fsummaries\u002Fc116726456b33e2b-tanstack-server-components-opt-in-granularity-beat-summary","2026-04-20 22:30:20","2026-04-21 15:16:40",{"title":4614,"description":245},{"loc":4734},"44549f7a250bdc2f","Better Stack","https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=pWxRvFFUHcY","summaries\u002Fc116726456b33e2b-tanstack-server-components-opt-in-granularity-beat-summary",[4744,285,286],"frontend","Use renderServerComponent in server functions to render React components on the server granularly, like fetching JSON. Composite components with slots keep client boundaries clean without 'use client' directives.",[286],"txEuohnvndBk3yN4LUpj-Ih9qNEyhx3iGFhMQ45h3_o",{"id":4749,"title":4750,"ai":4751,"body":4756,"categories":5378,"created_at":253,"date_modified":253,"description":245,"extension":254,"faq":253,"featured":255,"kicker_label":253,"meta":5379,"navigation":274,"path":5389,"published_at":5390,"question":253,"scraped_at":5391,"seo":5392,"sitemap":5393,"source_id":5394,"source_name":280,"source_type":281,"source_url":5395,"stem":5396,"tags":5397,"thumbnail_url":253,"tldr":5398,"tweet":253,"unknown_tags":5399,"__hash__":5400},"summaries\u002Fsummaries\u002F1e45509feec027b6-swiftui-state-ownership-rules-end-view-redraw-bugs-summary.md","SwiftUI State: Ownership Rules End View Redraw Bugs",{"provider":7,"model":8,"input_tokens":4752,"output_tokens":4753,"processing_time_ms":4754,"cost_usd":4755},6903,2144,14144,0.00242995,{"type":14,"value":4757,"toc":5372},[4758,4762,4769,4776,4850,4853,4938,4941,4994,4998,5008,5090,5104,5174,5185,5192,5239,5242,5246,5252,5284,5290,5322,5325,5363,5367,5370],[17,4759,4761],{"id":4760},"views-as-functions-of-state-redraws-are-features-not-bugs","Views as Functions of State: Redraws Are Features, Not Bugs",[22,4763,4764,4765,4768],{},"SwiftUI views are structs that act like pure functions: UI = f(state). When state changes, SwiftUI re-runs the body computation and redraws only affected parts—no manual ",[37,4766,4767],{},"reloadData()"," needed. State is any value the UI depends on, like a counter, toggle, or form validity.",[22,4770,4771,4772,4775],{},"Use ",[37,4773,4774],{},"@State"," for local, simple state owned by the view (Bool, Int, String, small structs). It persists across redraws because SwiftUI stores it stably:",[3896,4777,4781],{"className":4778,"code":4779,"language":4780,"meta":245,"style":245},"language-swift shiki shiki-themes github-light github-dark","import SwiftUI\nstruct CounterView: View {\n    @State private var count = 0\n    var body: some View {\n        VStack(spacing: 16) {\n            Text(\"Count: \\(count)\")\n                .font(.title)\n            Button(\"Tap Me\") {\n                count += 1\n            }\n        }\n        .padding()\n    }\n}\n","swift",[37,4782,4783,4788,4793,4798,4803,4808,4813,4818,4823,4828,4833,4837,4842,4846],{"__ignoreMap":245},[3904,4784,4785],{"class":3906,"line":3907},[3904,4786,4787],{},"import SwiftUI\n",[3904,4789,4790],{"class":3906,"line":246},[3904,4791,4792],{},"struct CounterView: View {\n",[3904,4794,4795],{"class":3906,"line":271},[3904,4796,4797],{},"    @State private var count = 0\n",[3904,4799,4800],{"class":3906,"line":270},[3904,4801,4802],{},"    var body: some View {\n",[3904,4804,4805],{"class":3906,"line":3928},[3904,4806,4807],{},"        VStack(spacing: 16) {\n",[3904,4809,4810],{"class":3906,"line":3934},[3904,4811,4812],{},"            Text(\"Count: \\(count)\")\n",[3904,4814,4815],{"class":3906,"line":4040},[3904,4816,4817],{},"                .font(.title)\n",[3904,4819,4820],{"class":3906,"line":4186},[3904,4821,4822],{},"            Button(\"Tap Me\") {\n",[3904,4824,4825],{"class":3906,"line":4192},[3904,4826,4827],{},"                count += 1\n",[3904,4829,4830],{"class":3906,"line":4198},[3904,4831,4832],{},"            }\n",[3904,4834,4835],{"class":3906,"line":4204},[3904,4836,4270],{},[3904,4838,4839],{"class":3906,"line":4273},[3904,4840,4841],{},"        .padding()\n",[3904,4843,4844],{"class":3906,"line":4279},[3904,4845,4201],{},[3904,4847,4848],{"class":3906,"line":4284},[3904,4849,4207],{},[22,4851,4852],{},"Normal variables reset on redraws since views are disposable. For UI toggles:",[3896,4854,4856],{"className":4778,"code":4855,"language":4780,"meta":245,"style":245},"struct ShowDetailsView: View {\n    @State private var showDetails = false\n    var body: some View {\n        VStack(spacing: 16) {\n            Button(showDetails ? \"Hide Details\" : \"Show Details\") {\n                showDetails.toggle()\n            }\n            if showDetails {\n                Text(\"Here are the details you definitely won't read.\")\n                    .padding()\n                    .background(.thinMaterial)\n                    .cornerRadius(12)\n            }\n        }\n        .padding()\n    }\n}\n",[37,4857,4858,4863,4868,4872,4876,4881,4886,4890,4895,4900,4905,4910,4915,4919,4923,4928,4933],{"__ignoreMap":245},[3904,4859,4860],{"class":3906,"line":3907},[3904,4861,4862],{},"struct ShowDetailsView: View {\n",[3904,4864,4865],{"class":3906,"line":246},[3904,4866,4867],{},"    @State private var showDetails = false\n",[3904,4869,4870],{"class":3906,"line":271},[3904,4871,4802],{},[3904,4873,4874],{"class":3906,"line":270},[3904,4875,4807],{},[3904,4877,4878],{"class":3906,"line":3928},[3904,4879,4880],{},"            Button(showDetails ? \"Hide Details\" : \"Show Details\") {\n",[3904,4882,4883],{"class":3906,"line":3934},[3904,4884,4885],{},"                showDetails.toggle()\n",[3904,4887,4888],{"class":3906,"line":4040},[3904,4889,4832],{},[3904,4891,4892],{"class":3906,"line":4186},[3904,4893,4894],{},"            if showDetails {\n",[3904,4896,4897],{"class":3906,"line":4192},[3904,4898,4899],{},"                Text(\"Here are the details you definitely won't read.\")\n",[3904,4901,4902],{"class":3906,"line":4198},[3904,4903,4904],{},"                    .padding()\n",[3904,4906,4907],{"class":3906,"line":4204},[3904,4908,4909],{},"                    .background(.thinMaterial)\n",[3904,4911,4912],{"class":3906,"line":4273},[3904,4913,4914],{},"                    .cornerRadius(12)\n",[3904,4916,4917],{"class":3906,"line":4279},[3904,4918,4832],{},[3904,4920,4921],{"class":3906,"line":4284},[3904,4922,4270],{},[3904,4924,4926],{"class":3906,"line":4925},15,[3904,4927,4841],{},[3904,4929,4931],{"class":3906,"line":4930},16,[3904,4932,4201],{},[3904,4934,4936],{"class":3906,"line":4935},17,[3904,4937,4207],{},[22,4939,4940],{},"Never store derived state—compute it to avoid sync bugs. Example form validation:",[3896,4942,4944],{"className":4778,"code":4943,"language":4780,"meta":245,"style":245},"struct SignupView: View {\n    @State private var email = \"\"\n    @State private var password = \"\"\n    private var isValid: Bool {\n        email.contains(\"@\") && password.count >= 8\n    }\n    \u002F\u002F ...\n    Button(\"Create Account\")\n        .disabled(!isValid)\n}\n",[37,4945,4946,4951,4956,4961,4966,4971,4975,4980,4985,4990],{"__ignoreMap":245},[3904,4947,4948],{"class":3906,"line":3907},[3904,4949,4950],{},"struct SignupView: View {\n",[3904,4952,4953],{"class":3906,"line":246},[3904,4954,4955],{},"    @State private var email = \"\"\n",[3904,4957,4958],{"class":3906,"line":271},[3904,4959,4960],{},"    @State private var password = \"\"\n",[3904,4962,4963],{"class":3906,"line":270},[3904,4964,4965],{},"    private var isValid: Bool {\n",[3904,4967,4968],{"class":3906,"line":3928},[3904,4969,4970],{},"        email.contains(\"@\") && password.count >= 8\n",[3904,4972,4973],{"class":3906,"line":3934},[3904,4974,4201],{},[3904,4976,4977],{"class":3906,"line":4040},[3904,4978,4979],{},"    \u002F\u002F ...\n",[3904,4981,4982],{"class":3906,"line":4186},[3904,4983,4984],{},"    Button(\"Create Account\")\n",[3904,4986,4987],{"class":3906,"line":4192},[3904,4988,4989],{},"        .disabled(!isValid)\n",[3904,4991,4992],{"class":3906,"line":4198},[3904,4993,4207],{},[17,4995,4997],{"id":4996},"sharing-and-model-state-bindings-and-observable-objects","Sharing and Model State: Bindings and Observable Objects",[22,4999,5000,5001,5004,5005,5007],{},"Pass ownership with ",[37,5002,5003],{},"@Binding",": parent holds ",[37,5006,4774],{},", child gets a binding like a remote control:",[3896,5009,5011],{"className":4778,"code":5010,"language":4780,"meta":245,"style":245},"struct ParentView: View {\n    @State private var isOn = false\n    var body: some View {\n        VStack {\n            Text(isOn ? \"On\" : \"Off\")\n            OnOffButton(isOn: $isOn)\n        }\n    }\n}\nstruct OnOffButton: View {\n    @Binding var isOn: Bool\n    var body: some View {\n        Button(isOn ? \"Turn Off\" : \"Turn On\") {\n            isOn.toggle()\n        }\n    }\n}\n",[37,5012,5013,5018,5023,5027,5032,5037,5042,5046,5050,5054,5059,5064,5068,5073,5078,5082,5086],{"__ignoreMap":245},[3904,5014,5015],{"class":3906,"line":3907},[3904,5016,5017],{},"struct ParentView: View {\n",[3904,5019,5020],{"class":3906,"line":246},[3904,5021,5022],{},"    @State private var isOn = false\n",[3904,5024,5025],{"class":3906,"line":271},[3904,5026,4802],{},[3904,5028,5029],{"class":3906,"line":270},[3904,5030,5031],{},"        VStack {\n",[3904,5033,5034],{"class":3906,"line":3928},[3904,5035,5036],{},"            Text(isOn ? \"On\" : \"Off\")\n",[3904,5038,5039],{"class":3906,"line":3934},[3904,5040,5041],{},"            OnOffButton(isOn: $isOn)\n",[3904,5043,5044],{"class":3906,"line":4040},[3904,5045,4270],{},[3904,5047,5048],{"class":3906,"line":4186},[3904,5049,4201],{},[3904,5051,5052],{"class":3906,"line":4192},[3904,5053,4207],{},[3904,5055,5056],{"class":3906,"line":4198},[3904,5057,5058],{},"struct OnOffButton: View {\n",[3904,5060,5061],{"class":3906,"line":4204},[3904,5062,5063],{},"    @Binding var isOn: Bool\n",[3904,5065,5066],{"class":3906,"line":4273},[3904,5067,4802],{},[3904,5069,5070],{"class":3906,"line":4279},[3904,5071,5072],{},"        Button(isOn ? \"Turn Off\" : \"Turn On\") {\n",[3904,5074,5075],{"class":3906,"line":4284},[3904,5076,5077],{},"            isOn.toggle()\n",[3904,5079,5080],{"class":3906,"line":4925},[3904,5081,4270],{},[3904,5083,5084],{"class":3906,"line":4930},[3904,5085,4201],{},[3904,5087,5088],{"class":3906,"line":4935},[3904,5089,4207],{},[22,5091,5092,5093,54,5096,5099,5100,5103],{},"For complex state, use ",[37,5094,5095],{},"ObservableObject",[37,5097,5098],{},"@Published"," properties. View creating the object uses ",[37,5101,5102],{},"@StateObject"," to prevent recreation on redraws:",[3896,5105,5107],{"className":4778,"code":5106,"language":4780,"meta":245,"style":245},"@MainActor\nfinal class ProfileViewModel: ObservableObject {\n    @Published var name: String = \"Sanjay\"\n    @Published var status: String = \"Trying not to over-engineer\"\n    func updateStatus() {\n        status = \"Still trying. Still failing.\"\n    }\n}\n\nstruct ProfileView: View {\n    @StateObject private var vm = ProfileViewModel()\n    \u002F\u002F ...\n    Button(\"Update Status\") { vm.updateStatus() }\n}\n",[37,5108,5109,5114,5119,5124,5129,5134,5139,5143,5147,5151,5156,5161,5165,5170],{"__ignoreMap":245},[3904,5110,5111],{"class":3906,"line":3907},[3904,5112,5113],{},"@MainActor\n",[3904,5115,5116],{"class":3906,"line":246},[3904,5117,5118],{},"final class ProfileViewModel: ObservableObject {\n",[3904,5120,5121],{"class":3906,"line":271},[3904,5122,5123],{},"    @Published var name: String = \"Sanjay\"\n",[3904,5125,5126],{"class":3906,"line":270},[3904,5127,5128],{},"    @Published var status: String = \"Trying not to over-engineer\"\n",[3904,5130,5131],{"class":3906,"line":3928},[3904,5132,5133],{},"    func updateStatus() {\n",[3904,5135,5136],{"class":3906,"line":3934},[3904,5137,5138],{},"        status = \"Still trying. Still failing.\"\n",[3904,5140,5141],{"class":3906,"line":4040},[3904,5142,4201],{},[3904,5144,5145],{"class":3906,"line":4186},[3904,5146,4207],{},[3904,5148,5149],{"class":3906,"line":4192},[3904,5150,3920],{"emptyLinePlaceholder":274},[3904,5152,5153],{"class":3906,"line":4198},[3904,5154,5155],{},"struct ProfileView: View {\n",[3904,5157,5158],{"class":3906,"line":4204},[3904,5159,5160],{},"    @StateObject private var vm = ProfileViewModel()\n",[3904,5162,5163],{"class":3906,"line":4273},[3904,5164,4979],{},[3904,5166,5167],{"class":3906,"line":4279},[3904,5168,5169],{},"    Button(\"Update Status\") { vm.updateStatus() }\n",[3904,5171,5172],{"class":3906,"line":4284},[3904,5173,4207],{},[22,5175,5176,5177,5180,5181,5184],{},"Injected objects use ",[37,5178,5179],{},"@ObservedObject",". Avoid ",[37,5182,5183],{},"@ObservedObject var vm = ProfileViewModel()","—it recreates and resets data\u002FAPI calls.",[22,5186,5187,5188,5191],{},"For app-wide state (user login, theme), inject ",[37,5189,5190],{},"@EnvironmentObject"," at root:",[3896,5193,5195],{"className":4778,"code":5194,"language":4780,"meta":245,"style":245},"struct RootView: View {\n    @StateObject private var appState = AppState()\n    var body: some View {\n        ContentView()\n            .environmentObject(appState)\n    }\n}\n\u002F\u002F In any descendant:\n@EnvironmentObject var appState: AppState\n",[37,5196,5197,5202,5207,5211,5216,5221,5225,5229,5234],{"__ignoreMap":245},[3904,5198,5199],{"class":3906,"line":3907},[3904,5200,5201],{},"struct RootView: View {\n",[3904,5203,5204],{"class":3906,"line":246},[3904,5205,5206],{},"    @StateObject private var appState = AppState()\n",[3904,5208,5209],{"class":3906,"line":271},[3904,5210,4802],{},[3904,5212,5213],{"class":3906,"line":270},[3904,5214,5215],{},"        ContentView()\n",[3904,5217,5218],{"class":3906,"line":3928},[3904,5219,5220],{},"            .environmentObject(appState)\n",[3904,5222,5223],{"class":3906,"line":3934},[3904,5224,4201],{},[3904,5226,5227],{"class":3906,"line":4040},[3904,5228,4207],{},[3904,5230,5231],{"class":3906,"line":4186},[3904,5232,5233],{},"\u002F\u002F In any descendant:\n",[3904,5235,5236],{"class":3906,"line":4192},[3904,5237,5238],{},"@EnvironmentObject var appState: AppState\n",[22,5240,5241],{},"Limit to true globals; they hide dependencies.",[17,5243,5245],{"id":5244},"persistence-and-decision-framework-survive-restarts","Persistence and Decision Framework: Survive Restarts",[22,5247,5248,5249,5251],{},"Persist simple values across app kills with ",[37,5250,193],{}," (UserDefaults-backed):",[3896,5253,5255],{"className":4778,"code":5254,"language":4780,"meta":245,"style":245},"struct SettingsView: View {\n    @AppStorage(\"isDarkMode\") private var isDarkMode = false\n    var body: some View {\n        Toggle(\"Dark Mode\", isOn: $isDarkMode)\n    }\n}\n",[37,5256,5257,5262,5267,5271,5276,5280],{"__ignoreMap":245},[3904,5258,5259],{"class":3906,"line":3907},[3904,5260,5261],{},"struct SettingsView: View {\n",[3904,5263,5264],{"class":3906,"line":246},[3904,5265,5266],{},"    @AppStorage(\"isDarkMode\") private var isDarkMode = false\n",[3904,5268,5269],{"class":3906,"line":271},[3904,5270,4802],{},[3904,5272,5273],{"class":3906,"line":270},[3904,5274,5275],{},"        Toggle(\"Dark Mode\", isOn: $isDarkMode)\n",[3904,5277,5278],{"class":3906,"line":3928},[3904,5279,4201],{},[3904,5281,5282],{"class":3906,"line":3934},[3904,5283,4207],{},[22,5285,5286,5287,4356],{},"For scene\u002Fwindow-specific UI (drafts, tabs), use ",[37,5288,5289],{},"@SceneStorage",[3896,5291,5293],{"className":4778,"code":5292,"language":4780,"meta":245,"style":245},"struct NotesView: View {\n    @SceneStorage(\"draftText\") private var draftText = \"\"\n    var body: some View {\n        TextEditor(text: $draftText)\n    }\n}\n",[37,5294,5295,5300,5305,5309,5314,5318],{"__ignoreMap":245},[3904,5296,5297],{"class":3906,"line":3907},[3904,5298,5299],{},"struct NotesView: View {\n",[3904,5301,5302],{"class":3906,"line":246},[3904,5303,5304],{},"    @SceneStorage(\"draftText\") private var draftText = \"\"\n",[3904,5306,5307],{"class":3906,"line":271},[3904,5308,4802],{},[3904,5310,5311],{"class":3906,"line":270},[3904,5312,5313],{},"        TextEditor(text: $draftText)\n",[3904,5315,5316],{"class":3906,"line":3928},[3904,5317,4201],{},[3904,5319,5320],{"class":3906,"line":3934},[3904,5321,4207],{},[22,5323,5324],{},"Decision checklist by ownership\u002Flifetime:",[26,5326,5327,5332,5337,5342,5347,5353,5358],{},[29,5328,5329,5330],{},"Local\u002Fsimple: ",[37,5331,4774],{},[29,5333,5334,5335],{},"Child edits: ",[37,5336,5003],{},[29,5338,5339,5340],{},"View-owned model: ",[37,5341,5102],{},[29,5343,5344,5345],{},"Injected model: ",[37,5346,5179],{},[29,5348,5349,5350,5352],{},"App-shared: ",[37,5351,5190],{}," (sparingly)",[29,5354,5355,5356],{},"App-persistent: ",[37,5357,193],{},[29,5359,5360,5361],{},"Scene-persistent: ",[37,5362,5289],{},[17,5364,5366],{"id":5365},"pitfalls-that-cause-90-of-state-confusion","Pitfalls That Cause 90% of State Confusion",[22,5368,5369],{},"Common bugs: storing computed values (leads to staleness), wrong object wrapper (data resets), overusing globals (debug hell), fearing redraws (they're efficient). Answer: Who owns it? How long does it live? This shifts state from magic to predictable tools.",[4096,5371,4098],{},{"title":245,"searchDepth":246,"depth":246,"links":5373},[5374,5375,5376,5377],{"id":4760,"depth":246,"text":4761},{"id":4996,"depth":246,"text":4997},{"id":5244,"depth":246,"text":5245},{"id":5365,"depth":246,"text":5366},[252],{"content_references":5380,"triage":5386},[5381,5384],{"type":259,"title":267,"url":5382,"context":5383},"https:\u002F\u002Fmedium.com\u002Fgitconnected\u002Fswiftui-navigation-in-ios-a-practical-guide-2a4820971681","recommended",{"type":259,"title":5385,"url":282,"context":5383},"MVVM in SwiftUI: Build an iOS App That Stays Organized as It Grows",{"relevance":3928,"novelty":271,"quality":270,"actionability":270,"composite":5387,"reasoning":5388},4.15,"Category: Software Engineering. The article provides a practical guide on managing state in SwiftUI, which is directly relevant to developers building AI-powered products that may involve UI components. It includes specific examples and code snippets that can be immediately applied, addressing common pain points in UI development.","\u002Fsummaries\u002F1e45509feec027b6-swiftui-state-ownership-rules-end-view-redraw-bugs-summary","2026-03-16 15:49:07","2026-04-14 14:30:07",{"title":4750,"description":245},{"loc":5389},"1e45509feec027b6","https:\u002F\u002Fmedium.com\u002Fgitconnected\u002Fswiftui-state-in-ios-a-practical-guide-993a70794cdd","summaries\u002F1e45509feec027b6-swiftui-state-ownership-rules-end-view-redraw-bugs-summary",[286,4608,288],"Treat SwiftUI views as functions of state (UI = f(state)). Choose wrappers by ownership: @State for local simple values, @Binding to share edits, @StateObject for view-owned models, @ObservedObject for injected ones. Compute derived state, persist with @AppStorage.",[286,4608,288],"pcfRBH2XDV6VJA40AS3Zz8Qxct8wm6viRFns7bL4nLM"]