[{"data":1,"prerenderedAt":1682},["ShallowReactive",2],{"navigation":3,"\u002Fguides\u002Ffan-out":170,"\u002Fguides\u002Ffan-out-surround":1677},[4,25,104,150,160],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting Started",false,"\u002Fgetting-started","1.getting-started",[10,15,20],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F1.introduction","i-lucide-book-open",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fgetting-started\u002Finstallation","1.getting-started\u002F2.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick start","\u002Fgetting-started\u002Fquick-start","1.getting-started\u002F3.quick-start","i-lucide-rocket",{"title":26,"icon":6,"path":27,"stem":28,"children":29,"page":6},"Guides","\u002Fguides","2.guides",[30,35,40,45,50,55,60,65,70,75,79,84,89,94,99],{"title":31,"path":32,"stem":33,"icon":34},"Seeds and TestBiome","\u002Fguides\u002Fseeds-and-testbiome","2.guides\u002F01.seeds-and-testbiome","i-lucide-sprout",{"title":36,"path":37,"stem":38,"icon":39},"Blueprints","\u002Fguides\u002Fblueprints","2.guides\u002F02.blueprints","i-lucide-drafting-compass",{"title":41,"path":42,"stem":43,"icon":44},"Customizing","\u002Fguides\u002Fcustomizing","2.guides\u002F03.customizing","i-lucide-sliders-horizontal",{"title":46,"path":47,"stem":48,"icon":49},"Parent\u002Fchild chains and .Under","\u002Fguides\u002Fparents-and-children","2.guides\u002F04.parents-and-children","i-lucide-git-fork",{"title":51,"path":52,"stem":53,"icon":54},"Fan-out","\u002Fguides\u002Ffan-out","2.guides\u002F05.fan-out","i-lucide-split",{"title":56,"path":57,"stem":58,"icon":59},"Sequences","\u002Fguides\u002Fsequences","2.guides\u002F06.sequences","i-lucide-list-ordered",{"title":61,"path":62,"stem":63,"icon":64},"Time and precision","\u002Fguides\u002Ftime-and-precision","2.guides\u002F07.time-and-precision","i-lucide-clock",{"title":66,"path":67,"stem":68,"icon":69},"Transients","\u002Fguides\u002Ftransients","2.guides\u002F08.transients","i-lucide-ghost",{"title":71,"path":72,"stem":73,"icon":74},"Aggregates","\u002Fguides\u002Faggregates","2.guides\u002F09.aggregates","i-lucide-boxes",{"title":76,"path":77,"stem":78,"icon":74},"Input blueprints","\u002Fguides\u002Finput-blueprints","2.guides\u002F09.input-blueprints",{"title":80,"path":81,"stem":82,"icon":83},"Save hooks and global defaults","\u002Fguides\u002Fsave-hooks-and-defaults","2.guides\u002F10.save-hooks-and-defaults","i-lucide-webhook",{"title":85,"path":86,"stem":87,"icon":88},"EF Core store","\u002Fguides\u002Fef-core-store","2.guides\u002F11.ef-core-store","i-lucide-database",{"title":90,"path":91,"stem":92,"icon":93},"No-DB unit tests","\u002Fguides\u002Fno-db-unit-tests","2.guides\u002F12.no-db-unit-tests","i-lucide-flask-conical",{"title":95,"path":96,"stem":97,"icon":98},"Generated grafts and scenario helpers","\u002Fguides\u002Fscenario-helpers-and-sugar","2.guides\u002F13.scenario-helpers-and-sugar","i-lucide-wand-sparkles",{"title":100,"path":101,"stem":102,"icon":103},"Constructor setup","\u002Fguides\u002Fconstructor-setup","2.guides\u002F14.constructor-setup","i-lucide-blocks",{"title":105,"path":106,"stem":107,"children":108,"icon":6},"Examples","\u002Fexamples","3.examples\u002F1.index",[109,111,116,121,126,130,135,140,145],{"title":105,"path":106,"stem":107,"icon":110},"i-lucide-library",{"title":112,"path":113,"stem":114,"icon":115},"Code reviews","\u002Fexamples\u002Fcode-reviews","3.examples\u002F2.code-reviews","i-lucide-git-pull-request",{"title":117,"path":118,"stem":119,"icon":120},"Membership","\u002Fexamples\u002Fmembership","3.examples\u002F3.membership","i-lucide-users",{"title":122,"path":123,"stem":124,"icon":125},"Board","\u002Fexamples\u002Fboard","3.examples\u002F4.board","i-lucide-kanban",{"title":127,"path":128,"stem":129,"icon":44},"Custom seed","\u002Fexamples\u002Fcustom-seed","3.examples\u002F5.custom-seed",{"title":131,"path":132,"stem":133,"icon":134},"Commerce","\u002Fexamples\u002Fcommerce","3.examples\u002F6.commerce","i-lucide-shopping-cart",{"title":136,"path":137,"stem":138,"icon":139},"Project management","\u002Fexamples\u002Fproject-management","3.examples\u002F7.project-management","i-lucide-folder-kanban",{"title":141,"path":142,"stem":143,"icon":144},"Learning","\u002Fexamples\u002Flearning","3.examples\u002F8.learning","i-lucide-graduation-cap",{"title":146,"path":147,"stem":148,"icon":149},"Docs ingest","\u002Fexamples\u002Fdocs-ingest","3.examples\u002F9.docs-ingest","i-lucide-file-search",{"title":151,"icon":6,"path":152,"stem":153,"children":154,"page":6},"Reference","\u002Freference","4.reference",[155],{"title":156,"path":157,"stem":158,"icon":159},"API cheat sheet","\u002Freference\u002Fapi-cheat-sheet","4.reference\u002F1.api-cheat-sheet","i-lucide-list-checks",{"title":161,"icon":6,"path":162,"stem":163,"children":164,"page":6},"Agent Skills","\u002Fagents","5.agents",[165],{"title":166,"path":167,"stem":168,"icon":169},"Agent skills","\u002Fagents\u002Fagent-skills","5.agents\u002F1.agent-skills","i-lucide-bot",{"id":171,"title":51,"body":172,"description":1670,"extension":1671,"links":1672,"meta":1673,"navigation":1674,"path":52,"seo":1675,"stem":53,"__hash__":1676},"docs\u002F2.guides\u002F05.fan-out.md",{"type":173,"value":174,"toc":1663},"minimark",[175,180,184,325,340,344,354,579,1049,1053,1064,1114,1318,1333,1337,1347,1638,1642,1659],[176,177,179],"h2",{"id":178},"per-parent-in-parent-order","Per parent, in parent order",[181,182,183],"p",{},"A test may need the same shape under several parents: three pull requests in each of two repositories, for example. Instead of writing a loop, add children while the anchor holds those parents. Counts and customizers apply to each parent, and the result is one flat array in parent order.",[185,186,194],"pre",{"className":187,"code":188,"filename":189,"highlights":190,"language":192,"meta":193,"style":193},"language-csharp shiki shiki-themes material-theme-lighter github-light github-dark","await TestBiome\n    .Start(out _)\n    .Add(Blueprints.Repository, out var repos, 2)\n    \u002F\u002F 3 per repo → 6: prs[0..2] → repos[0], prs[3..5] → repos[1]\n    .Add(Blueprints.PullRequest, out var prs, 3)\n    .BuildAsync();\n","FanOutTests.cs",[191],5,"csharp","",[195,196,197,210,234,274,281,314],"code",{"__ignoreMap":193},[198,199,202,206],"span",{"class":200,"line":201},"line",1,[198,203,205],{"class":204},"smGrS","await",[198,207,209],{"class":208},"su5hD"," TestBiome\n",[198,211,213,217,221,224,228,231],{"class":200,"line":212},2,[198,214,216],{"class":215},"sP7_E","    .",[198,218,220],{"class":219},"sGLFI","Start",[198,222,223],{"class":215},"(",[198,225,227],{"class":226},"sbsja","out",[198,229,230],{"class":208}," _",[198,232,233],{"class":215},")\n",[198,235,237,239,242,244,246,249,252,255,258,262,266,268,272],{"class":200,"line":236},3,[198,238,216],{"class":215},[198,240,241],{"class":219},"Add",[198,243,223],{"class":215},[198,245,36],{"class":208},[198,247,248],{"class":215},".",[198,250,251],{"class":208},"Repository",[198,253,254],{"class":215},",",[198,256,257],{"class":226}," out",[198,259,261],{"class":260},"sG8yY"," var",[198,263,265],{"class":264},"sbgvK"," repos",[198,267,254],{"class":215},[198,269,271],{"class":270},"srdBf"," 2",[198,273,233],{"class":215},[198,275,277],{"class":200,"line":276},4,[198,278,280],{"class":279},"sutJx","    \u002F\u002F 3 per repo → 6: prs[0..2] → repos[0], prs[3..5] → repos[1]\n",[198,282,285,287,289,291,293,295,298,300,302,304,307,309,312],{"class":283,"line":191},[200,284],"highlight",[198,286,216],{"class":215},[198,288,241],{"class":219},[198,290,223],{"class":215},[198,292,36],{"class":208},[198,294,248],{"class":215},[198,296,297],{"class":208},"PullRequest",[198,299,254],{"class":215},[198,301,257],{"class":226},[198,303,261],{"class":260},[198,305,306],{"class":264}," prs",[198,308,254],{"class":215},[198,310,311],{"class":270}," 3",[198,313,233],{"class":215},[198,315,317,319,322],{"class":200,"line":316},6,[198,318,216],{"class":215},[198,320,321],{"class":219},"BuildAsync",[198,323,324],{"class":215},"();\n",[326,327,328],"note",{},[181,329,330,331,335,336,248],{},"Two parents × three customizers is ",[332,333,334],"strong",{},"six"," children, not three. The count is ",[337,338,339],"em",{},"per parent",[176,341,343],{"id":342},"customizers-per-parent","Customizers per parent",[181,345,346,347,349,350,353],{},"Each customizer creates one entity per parent. From the library's ",[195,348,117],{}," tests: two users, two alias customizers, ",[332,351,352],{},"four"," aliases.",[185,355,364],{"className":187,"code":356,"filename":357,"highlights":358,"language":192,"meta":193,"style":193},"await TestBiome\n    .Start(out _)\n    \u002F\u002F Create user parents so alias customizers can fan out under each one.\n    .AddUsers(out var users, 2)\n    \u002F\u002F Apply each customization PER user; Derive normalizes only unset values.\n    .AddAliases(\n        out var aliases,\n        a => a.Value = \"Alice\",\n        a =>\n        {\n            a.Value = \"Bob\";\n            a.NormalizedValue = \"manual\";\n        }\n    )\n    .BuildAsync();\n\n\u002F\u002F aliases.Length == 4; aliases[0].User == users[0]; aliases[2].User == users[1]\n\u002F\u002F aliases[0].NormalizedValue == \"ALICE\" (derived)\n\u002F\u002F aliases[3].NormalizedValue == \"manual\" (kept)\n","MembershipTests.cs",[316,359,360,361,362,363],7,8,10,11,12,[195,365,366,372,386,391,413,418,429,443,476,484,490,512,533,539,545,554,561,567,573],{"__ignoreMap":193},[198,367,368,370],{"class":200,"line":201},[198,369,205],{"class":204},[198,371,209],{"class":208},[198,373,374,376,378,380,382,384],{"class":200,"line":212},[198,375,216],{"class":215},[198,377,220],{"class":219},[198,379,223],{"class":215},[198,381,227],{"class":226},[198,383,230],{"class":208},[198,385,233],{"class":215},[198,387,388],{"class":200,"line":236},[198,389,390],{"class":279},"    \u002F\u002F Create user parents so alias customizers can fan out under each one.\n",[198,392,393,395,398,400,402,404,407,409,411],{"class":200,"line":276},[198,394,216],{"class":215},[198,396,397],{"class":219},"AddUsers",[198,399,223],{"class":215},[198,401,227],{"class":226},[198,403,261],{"class":260},[198,405,406],{"class":264}," users",[198,408,254],{"class":215},[198,410,271],{"class":270},[198,412,233],{"class":215},[198,414,415],{"class":200,"line":191},[198,416,417],{"class":279},"    \u002F\u002F Apply each customization PER user; Derive normalizes only unset values.\n",[198,419,421,423,426],{"class":420,"line":316},[200,284],[198,422,216],{"class":215},[198,424,425],{"class":219},"AddAliases",[198,427,428],{"class":215},"(\n",[198,430,432,435,437,440],{"class":431,"line":359},[200,284],[198,433,434],{"class":226},"        out",[198,436,261],{"class":260},[198,438,439],{"class":264}," aliases",[198,441,442],{"class":215},",\n",[198,444,446,449,452,455,457,460,463,467,471,474],{"class":445,"line":360},[200,284],[198,447,448],{"class":264},"        a",[198,450,451],{"class":204}," =>",[198,453,454],{"class":208}," a",[198,456,248],{"class":215},[198,458,459],{"class":208},"Value ",[198,461,462],{"class":204},"=",[198,464,466],{"class":465},"sjJ54"," \"",[198,468,470],{"class":469},"s_sjI","Alice",[198,472,473],{"class":465},"\"",[198,475,442],{"class":215},[198,477,479,481],{"class":200,"line":478},9,[198,480,448],{"class":264},[198,482,483],{"class":204}," =>\n",[198,485,487],{"class":486,"line":361},[200,284],[198,488,489],{"class":215},"        {\n",[198,491,493,496,498,500,502,504,507,509],{"class":492,"line":362},[200,284],[198,494,495],{"class":208},"            a",[198,497,248],{"class":215},[198,499,459],{"class":208},[198,501,462],{"class":204},[198,503,466],{"class":465},[198,505,506],{"class":469},"Bob",[198,508,473],{"class":465},[198,510,511],{"class":215},";\n",[198,513,515,517,519,522,524,526,529,531],{"class":514,"line":363},[200,284],[198,516,495],{"class":208},[198,518,248],{"class":215},[198,520,521],{"class":208},"NormalizedValue ",[198,523,462],{"class":204},[198,525,466],{"class":465},[198,527,528],{"class":469},"manual",[198,530,473],{"class":465},[198,532,511],{"class":215},[198,534,536],{"class":200,"line":535},13,[198,537,538],{"class":215},"        }\n",[198,540,542],{"class":200,"line":541},14,[198,543,544],{"class":215},"    )\n",[198,546,548,550,552],{"class":200,"line":547},15,[198,549,216],{"class":215},[198,551,321],{"class":219},[198,553,324],{"class":215},[198,555,557],{"class":200,"line":556},16,[198,558,560],{"emptyLinePlaceholder":559},true,"\n",[198,562,564],{"class":200,"line":563},17,[198,565,566],{"class":279},"\u002F\u002F aliases.Length == 4; aliases[0].User == users[0]; aliases[2].User == users[1]\n",[198,568,570],{"class":200,"line":569},18,[198,571,572],{"class":279},"\u002F\u002F aliases[0].NormalizedValue == \"ALICE\" (derived)\n",[198,574,576],{"class":200,"line":575},19,[198,577,578],{"class":279},"\u002F\u002F aliases[3].NormalizedValue == \"manual\" (kept)\n",[580,581,582,690],"code-group",{},[185,583,587],{"className":187,"code":584,"filename":585,"highlights":586,"language":192,"meta":193,"style":193},"await TestBiome\n    .Start(out _)\n    .AddCodeRepositories(out var repos, 2)\n    \u002F\u002F 2 per repo → 4\n    .AddPullRequests(out var prs, PullRequests.Draft, PullRequests.Merged)\n    .BuildAsync();\n\u002F\u002F prs[0], prs[1] → repos[0]: #1 draft, #2 merged;\n\u002F\u002F prs[2], prs[3] → repos[1]: #1, #2\n","With Biome",[191],[195,588,589,595,609,630,635,672,680,685],{"__ignoreMap":193},[198,590,591,593],{"class":200,"line":201},[198,592,205],{"class":204},[198,594,209],{"class":208},[198,596,597,599,601,603,605,607],{"class":200,"line":212},[198,598,216],{"class":215},[198,600,220],{"class":219},[198,602,223],{"class":215},[198,604,227],{"class":226},[198,606,230],{"class":208},[198,608,233],{"class":215},[198,610,611,613,616,618,620,622,624,626,628],{"class":200,"line":236},[198,612,216],{"class":215},[198,614,615],{"class":219},"AddCodeRepositories",[198,617,223],{"class":215},[198,619,227],{"class":226},[198,621,261],{"class":260},[198,623,265],{"class":264},[198,625,254],{"class":215},[198,627,271],{"class":270},[198,629,233],{"class":215},[198,631,632],{"class":200,"line":276},[198,633,634],{"class":279},"    \u002F\u002F 2 per repo → 4\n",[198,636,638,640,643,645,647,649,651,653,656,658,661,663,665,667,670],{"class":637,"line":191},[200,284],[198,639,216],{"class":215},[198,641,642],{"class":219},"AddPullRequests",[198,644,223],{"class":215},[198,646,227],{"class":226},[198,648,261],{"class":260},[198,650,306],{"class":264},[198,652,254],{"class":215},[198,654,655],{"class":208}," PullRequests",[198,657,248],{"class":215},[198,659,660],{"class":208},"Draft",[198,662,254],{"class":215},[198,664,655],{"class":208},[198,666,248],{"class":215},[198,668,669],{"class":208},"Merged",[198,671,233],{"class":215},[198,673,674,676,678],{"class":200,"line":316},[198,675,216],{"class":215},[198,677,321],{"class":219},[198,679,324],{"class":215},[198,681,682],{"class":200,"line":359},[198,683,684],{"class":279},"\u002F\u002F prs[0], prs[1] → repos[0]: #1 draft, #2 merged;\n",[198,686,687],{"class":200,"line":360},[198,688,689],{"class":279},"\u002F\u002F prs[2], prs[3] → repos[1]: #1, #2\n",[691,692,695],"code-collapse",{"label":693,"name":694},"Without Biome","setup",[185,696,698],{"className":187,"code":697,"language":192,"meta":193,"style":193},"\u002F\u002F The loops, numbering and foreign keys are yours to get right.\nvar repos = new[] { NewRepository(), NewRepository() };\nvar prs = new List\u003CPullRequestRecord>();\nforeach (var repo in repos)\n{\n    var number = 1; \u002F\u002F restart per repository, by hand\n    foreach (\n        var configure in new Action\u003CPullRequestRecord>[]\n        {\n            p => p.IsDraft = true,\n            p => p.State = PullRequestState.Merged,\n        }\n    )\n    {\n        \u002F\u002F builds Id, FK, title, branch, timestamps\n        var pr = NewPullRequest(repo, number++);\n        configure(pr);\n        prs.Add(pr);\n    }\n}\n_db.AddRange(seed.Owner, seed.Organization);\n_db.AddRange(repos);\n_db.AddRange(prs);\nawait _db.SaveChangesAsync();\n",[195,699,700,705,738,760,781,786,805,813,835,839,862,886,890,894,899,904,931,943,958,963,969,1002,1018,1034],{"__ignoreMap":193},[198,701,702],{"class":200,"line":201},[198,703,704],{"class":279},"\u002F\u002F The loops, numbering and foreign keys are yours to get right.\n",[198,706,707,710,712,715,718,721,724,727,730,732,735],{"class":200,"line":212},[198,708,709],{"class":260},"var",[198,711,265],{"class":264},[198,713,714],{"class":204}," =",[198,716,717],{"class":204}," new",[198,719,720],{"class":215},"[]",[198,722,723],{"class":215}," {",[198,725,726],{"class":219}," NewRepository",[198,728,729],{"class":215},"(),",[198,731,726],{"class":219},[198,733,734],{"class":215},"()",[198,736,737],{"class":215}," };\n",[198,739,740,742,744,746,748,751,754,757],{"class":200,"line":236},[198,741,709],{"class":260},[198,743,306],{"class":264},[198,745,714],{"class":204},[198,747,717],{"class":204},[198,749,750],{"class":264}," List",[198,752,753],{"class":215},"\u003C",[198,755,756],{"class":264},"PullRequestRecord",[198,758,759],{"class":215},">();\n",[198,761,762,766,769,771,774,777,779],{"class":200,"line":276},[198,763,765],{"class":764},"sVHd0","foreach",[198,767,768],{"class":215}," (",[198,770,709],{"class":260},[198,772,773],{"class":264}," repo",[198,775,776],{"class":764}," in",[198,778,265],{"class":208},[198,780,233],{"class":215},[198,782,783],{"class":200,"line":191},[198,784,785],{"class":215},"{\n",[198,787,788,791,794,796,799,802],{"class":200,"line":316},[198,789,790],{"class":260},"    var",[198,792,793],{"class":264}," number",[198,795,714],{"class":204},[198,797,798],{"class":270}," 1",[198,800,801],{"class":215},";",[198,803,804],{"class":279}," \u002F\u002F restart per repository, by hand\n",[198,806,807,810],{"class":200,"line":359},[198,808,809],{"class":764},"    foreach",[198,811,812],{"class":215}," (\n",[198,814,815,818,821,823,825,828,830,832],{"class":200,"line":360},[198,816,817],{"class":260},"        var",[198,819,820],{"class":264}," configure",[198,822,776],{"class":764},[198,824,717],{"class":204},[198,826,827],{"class":264}," Action",[198,829,753],{"class":215},[198,831,756],{"class":264},[198,833,834],{"class":215},">[]\n",[198,836,837],{"class":200,"line":478},[198,838,489],{"class":215},[198,840,841,844,846,849,851,854,856,860],{"class":200,"line":361},[198,842,843],{"class":264},"            p",[198,845,451],{"class":204},[198,847,848],{"class":208}," p",[198,850,248],{"class":215},[198,852,853],{"class":208},"IsDraft ",[198,855,462],{"class":204},[198,857,859],{"class":858},"syTEX"," true",[198,861,442],{"class":215},[198,863,864,866,868,870,872,875,877,880,882,884],{"class":200,"line":362},[198,865,843],{"class":264},[198,867,451],{"class":204},[198,869,848],{"class":208},[198,871,248],{"class":215},[198,873,874],{"class":208},"State ",[198,876,462],{"class":204},[198,878,879],{"class":208}," PullRequestState",[198,881,248],{"class":215},[198,883,669],{"class":208},[198,885,442],{"class":215},[198,887,888],{"class":200,"line":363},[198,889,538],{"class":215},[198,891,892],{"class":200,"line":535},[198,893,544],{"class":215},[198,895,896],{"class":200,"line":541},[198,897,898],{"class":215},"    {\n",[198,900,901],{"class":200,"line":547},[198,902,903],{"class":279},"        \u002F\u002F builds Id, FK, title, branch, timestamps\n",[198,905,906,908,911,913,916,918,921,923,925,928],{"class":200,"line":556},[198,907,817],{"class":260},[198,909,910],{"class":264}," pr",[198,912,714],{"class":204},[198,914,915],{"class":219}," NewPullRequest",[198,917,223],{"class":215},[198,919,920],{"class":208},"repo",[198,922,254],{"class":215},[198,924,793],{"class":208},[198,926,927],{"class":204},"++",[198,929,930],{"class":215},");\n",[198,932,933,936,938,941],{"class":200,"line":563},[198,934,935],{"class":219},"        configure",[198,937,223],{"class":215},[198,939,940],{"class":208},"pr",[198,942,930],{"class":215},[198,944,945,948,950,952,954,956],{"class":200,"line":569},[198,946,947],{"class":208},"        prs",[198,949,248],{"class":215},[198,951,241],{"class":219},[198,953,223],{"class":215},[198,955,940],{"class":208},[198,957,930],{"class":215},[198,959,960],{"class":200,"line":575},[198,961,962],{"class":215},"    }\n",[198,964,966],{"class":200,"line":965},20,[198,967,968],{"class":215},"}\n",[198,970,972,975,977,980,982,985,987,990,992,995,997,1000],{"class":200,"line":971},21,[198,973,974],{"class":208},"_db",[198,976,248],{"class":215},[198,978,979],{"class":219},"AddRange",[198,981,223],{"class":215},[198,983,984],{"class":208},"seed",[198,986,248],{"class":215},[198,988,989],{"class":208},"Owner",[198,991,254],{"class":215},[198,993,994],{"class":208}," seed",[198,996,248],{"class":215},[198,998,999],{"class":208},"Organization",[198,1001,930],{"class":215},[198,1003,1005,1007,1009,1011,1013,1016],{"class":200,"line":1004},22,[198,1006,974],{"class":208},[198,1008,248],{"class":215},[198,1010,979],{"class":219},[198,1012,223],{"class":215},[198,1014,1015],{"class":208},"repos",[198,1017,930],{"class":215},[198,1019,1021,1023,1025,1027,1029,1032],{"class":200,"line":1020},23,[198,1022,974],{"class":208},[198,1024,248],{"class":215},[198,1026,979],{"class":219},[198,1028,223],{"class":215},[198,1030,1031],{"class":208},"prs",[198,1033,930],{"class":215},[198,1035,1037,1039,1042,1044,1047],{"class":200,"line":1036},24,[198,1038,205],{"class":204},[198,1040,1041],{"class":208}," _db",[198,1043,248],{"class":215},[198,1045,1046],{"class":219},"SaveChangesAsync",[198,1048,324],{"class":215},[176,1050,1052],{"id":1051},"parent-aware-customizers","Parent-aware customizers",[181,1054,1055,1056,1059,1060,1063],{},"A child customizer in the ",[332,1057,1058],{},"two-parameter form"," receives a ",[195,1061,1062],{},"ChildContext",":",[1065,1066,1067,1080],"table",{},[1068,1069,1070],"thead",{},[1071,1072,1073,1077],"tr",{},[1074,1075,1076],"th",{},"Member",[1074,1078,1079],{},"Meaning",[1081,1082,1083,1094,1104],"tbody",{},[1071,1084,1085,1091],{},[1086,1087,1088],"td",{},[195,1089,1090],{},"ctx.Parent",[1086,1092,1093],{},"This child's parent, typed.",[1071,1095,1096,1101],{},[1086,1097,1098],{},[195,1099,1100],{},"ctx.ParentIndex",[1086,1102,1103],{},"The parent's position in the anchor array.",[1071,1105,1106,1111],{},[1086,1107,1108],{},[195,1109,1110],{},"ctx.Index",[1086,1112,1113],{},"The child's position under that parent.",[185,1115,1119],{"className":187,"code":1116,"filename":1117,"highlights":1118,"language":192,"meta":193,"style":193},"await TestBiome\n    .Start(out _)\n    .AddUsers(\n        out var users,\n        u => u.DisplayName = \"Ada\",\n        u => u.DisplayName = \"Grace\"\n    )\n    .Add(\n        Blueprints.UserAlias,\n        out var aliases,\n        (alias, ctx) => alias.DisplayValue = $\"@{ctx.Parent.DisplayName}\"\n    )\n    .BuildAsync();\n\u002F\u002F aliases: \"@Ada\" → \"ada\", \"@Grace\" → \"grace\"\n","Parent-aware",[360,478,361,362,363],[195,1120,1121,1127,1141,1149,1159,1185,1207,1211,1220,1233,1244,1300,1305,1313],{"__ignoreMap":193},[198,1122,1123,1125],{"class":200,"line":201},[198,1124,205],{"class":204},[198,1126,209],{"class":208},[198,1128,1129,1131,1133,1135,1137,1139],{"class":200,"line":212},[198,1130,216],{"class":215},[198,1132,220],{"class":219},[198,1134,223],{"class":215},[198,1136,227],{"class":226},[198,1138,230],{"class":208},[198,1140,233],{"class":215},[198,1142,1143,1145,1147],{"class":200,"line":236},[198,1144,216],{"class":215},[198,1146,397],{"class":219},[198,1148,428],{"class":215},[198,1150,1151,1153,1155,1157],{"class":200,"line":276},[198,1152,434],{"class":226},[198,1154,261],{"class":260},[198,1156,406],{"class":264},[198,1158,442],{"class":215},[198,1160,1161,1164,1166,1169,1171,1174,1176,1178,1181,1183],{"class":200,"line":191},[198,1162,1163],{"class":264},"        u",[198,1165,451],{"class":204},[198,1167,1168],{"class":208}," u",[198,1170,248],{"class":215},[198,1172,1173],{"class":208},"DisplayName ",[198,1175,462],{"class":204},[198,1177,466],{"class":465},[198,1179,1180],{"class":469},"Ada",[198,1182,473],{"class":465},[198,1184,442],{"class":215},[198,1186,1187,1189,1191,1193,1195,1197,1199,1201,1204],{"class":200,"line":316},[198,1188,1163],{"class":264},[198,1190,451],{"class":204},[198,1192,1168],{"class":208},[198,1194,248],{"class":215},[198,1196,1173],{"class":208},[198,1198,462],{"class":204},[198,1200,466],{"class":465},[198,1202,1203],{"class":469},"Grace",[198,1205,1206],{"class":465},"\"\n",[198,1208,1209],{"class":200,"line":359},[198,1210,544],{"class":215},[198,1212,1214,1216,1218],{"class":1213,"line":360},[200,284],[198,1215,216],{"class":215},[198,1217,241],{"class":219},[198,1219,428],{"class":215},[198,1221,1223,1226,1228,1231],{"class":1222,"line":478},[200,284],[198,1224,1225],{"class":208},"        Blueprints",[198,1227,248],{"class":215},[198,1229,1230],{"class":208},"UserAlias",[198,1232,442],{"class":215},[198,1234,1236,1238,1240,1242],{"class":1235,"line":361},[200,284],[198,1237,434],{"class":226},[198,1239,261],{"class":260},[198,1241,439],{"class":264},[198,1243,442],{"class":215},[198,1245,1247,1250,1253,1255,1258,1261,1263,1266,1268,1271,1273,1276,1279,1282,1285,1287,1290,1292,1295,1298],{"class":1246,"line":362},[200,284],[198,1248,1249],{"class":215},"        (",[198,1251,1252],{"class":264},"alias",[198,1254,254],{"class":215},[198,1256,1257],{"class":264}," ctx",[198,1259,1260],{"class":215},")",[198,1262,451],{"class":204},[198,1264,1265],{"class":208}," alias",[198,1267,248],{"class":215},[198,1269,1270],{"class":208},"DisplayValue ",[198,1272,462],{"class":204},[198,1274,1275],{"class":465}," $\"",[198,1277,1278],{"class":469},"@",[198,1280,1281],{"class":465},"{",[198,1283,1284],{"class":208},"ctx",[198,1286,248],{"class":465},[198,1288,1289],{"class":208},"Parent",[198,1291,248],{"class":465},[198,1293,1294],{"class":208},"DisplayName",[198,1296,1297],{"class":465},"}",[198,1299,1206],{"class":465},[198,1301,1303],{"class":1302,"line":363},[200,284],[198,1304,544],{"class":215},[198,1306,1307,1309,1311],{"class":200,"line":535},[198,1308,216],{"class":215},[198,1310,321],{"class":219},[198,1312,324],{"class":215},[198,1314,1315],{"class":200,"line":541},[198,1316,1317],{"class":279},"\u002F\u002F aliases: \"@Ada\" → \"ada\", \"@Grace\" → \"grace\"\n",[1319,1320,1321],"caution",{},[181,1322,1323,1324,1328,1329,1332],{},"An index describes position in this Add, so it is useful for a display label. It restarts on the next call and cannot guarantee uniqueness. Use ",[1325,1326,1327],"a",{"href":57},"sequences"," for numbering and ordering, or ",[195,1330,1331],{},"ctx.NewId"," for IDs.",[176,1334,1336],{"id":1335},"a-base-context-trait-works-for-children-too","A base-context trait works for children too",[181,1338,1339,1340,1343,1344,1346],{},"A trait written against ",[195,1341,1342],{},"BiomeContext\u003CTSeed>"," is assignable to a child's ",[195,1345,1062],{}," form, so you can write it once. The library's tests exercise this:",[185,1348,1352],{"className":187,"code":1349,"filename":1350,"highlights":1351,"language":192,"meta":193,"style":193},"var positions = new List\u003C(int Parent, int Child)>();\nAction\u003CPullRequestRecord, BiomeContext\u003CCodeReviewSeed>> title = (pr, ctx) =>\n    pr.Title = ctx.Seed.Owner.Id;\n\nawait TestBiome\n    .Start(out _)\n    .AddCodeRepositories(out var repos, 2)\n    .Add(\n        Blueprints.PullRequest,\n        out var prs,\n        title,\n        (pr, ctx) =>\n        {\n            positions.Add((ctx.ParentIndex, ctx.Index));\n            pr.Title = ctx.Parent.Name;\n        }\n    )\n    .BuildAsync();\n\u002F\u002F positions == [(0, 1), (1, 1)]: the second customizer\n\u002F\u002F ran once per parent (ParentIndex, Index)\n","CodeReviewTests.cs",[212,236,362,363],[195,1353,1354,1387,1427,1458,1462,1468,1482,1502,1510,1520,1530,1538,1553,1557,1588,1612,1616,1620,1628,1633],{"__ignoreMap":193},[198,1355,1356,1358,1361,1363,1365,1367,1370,1373,1376,1378,1381,1384],{"class":200,"line":201},[198,1357,709],{"class":260},[198,1359,1360],{"class":264}," positions",[198,1362,714],{"class":204},[198,1364,717],{"class":204},[198,1366,750],{"class":264},[198,1368,1369],{"class":215},"\u003C(",[198,1371,1372],{"class":204},"int",[198,1374,1375],{"class":264}," Parent",[198,1377,254],{"class":215},[198,1379,1380],{"class":204}," int",[198,1382,1383],{"class":264}," Child",[198,1385,1386],{"class":215},")>();\n",[198,1388,1390,1393,1395,1397,1399,1402,1404,1407,1410,1413,1415,1417,1419,1421,1423,1425],{"class":1389,"line":212},[200,284],[198,1391,1392],{"class":264},"Action",[198,1394,753],{"class":215},[198,1396,756],{"class":264},[198,1398,254],{"class":215},[198,1400,1401],{"class":264}," BiomeContext",[198,1403,753],{"class":215},[198,1405,1406],{"class":264},"CodeReviewSeed",[198,1408,1409],{"class":215},">>",[198,1411,1412],{"class":264}," title",[198,1414,714],{"class":204},[198,1416,768],{"class":215},[198,1418,940],{"class":264},[198,1420,254],{"class":215},[198,1422,1257],{"class":264},[198,1424,1260],{"class":215},[198,1426,483],{"class":204},[198,1428,1430,1433,1435,1438,1440,1442,1444,1447,1449,1451,1453,1456],{"class":1429,"line":236},[200,284],[198,1431,1432],{"class":208},"    pr",[198,1434,248],{"class":215},[198,1436,1437],{"class":208},"Title ",[198,1439,462],{"class":204},[198,1441,1257],{"class":208},[198,1443,248],{"class":215},[198,1445,1446],{"class":208},"Seed",[198,1448,248],{"class":215},[198,1450,989],{"class":208},[198,1452,248],{"class":215},[198,1454,1455],{"class":208},"Id",[198,1457,511],{"class":215},[198,1459,1460],{"class":200,"line":276},[198,1461,560],{"emptyLinePlaceholder":559},[198,1463,1464,1466],{"class":200,"line":191},[198,1465,205],{"class":204},[198,1467,209],{"class":208},[198,1469,1470,1472,1474,1476,1478,1480],{"class":200,"line":316},[198,1471,216],{"class":215},[198,1473,220],{"class":219},[198,1475,223],{"class":215},[198,1477,227],{"class":226},[198,1479,230],{"class":208},[198,1481,233],{"class":215},[198,1483,1484,1486,1488,1490,1492,1494,1496,1498,1500],{"class":200,"line":359},[198,1485,216],{"class":215},[198,1487,615],{"class":219},[198,1489,223],{"class":215},[198,1491,227],{"class":226},[198,1493,261],{"class":260},[198,1495,265],{"class":264},[198,1497,254],{"class":215},[198,1499,271],{"class":270},[198,1501,233],{"class":215},[198,1503,1504,1506,1508],{"class":200,"line":360},[198,1505,216],{"class":215},[198,1507,241],{"class":219},[198,1509,428],{"class":215},[198,1511,1512,1514,1516,1518],{"class":200,"line":478},[198,1513,1225],{"class":208},[198,1515,248],{"class":215},[198,1517,297],{"class":208},[198,1519,442],{"class":215},[198,1521,1522,1524,1526,1528],{"class":200,"line":361},[198,1523,434],{"class":226},[198,1525,261],{"class":260},[198,1527,306],{"class":264},[198,1529,442],{"class":215},[198,1531,1533,1536],{"class":1532,"line":362},[200,284],[198,1534,1535],{"class":208},"        title",[198,1537,442],{"class":215},[198,1539,1541,1543,1545,1547,1549,1551],{"class":1540,"line":363},[200,284],[198,1542,1249],{"class":215},[198,1544,940],{"class":264},[198,1546,254],{"class":215},[198,1548,1257],{"class":264},[198,1550,1260],{"class":215},[198,1552,483],{"class":204},[198,1554,1555],{"class":200,"line":535},[198,1556,489],{"class":215},[198,1558,1559,1562,1564,1566,1569,1571,1573,1576,1578,1580,1582,1585],{"class":200,"line":541},[198,1560,1561],{"class":208},"            positions",[198,1563,248],{"class":215},[198,1565,241],{"class":219},[198,1567,1568],{"class":215},"((",[198,1570,1284],{"class":208},[198,1572,248],{"class":215},[198,1574,1575],{"class":208},"ParentIndex",[198,1577,254],{"class":215},[198,1579,1257],{"class":208},[198,1581,248],{"class":215},[198,1583,1584],{"class":208},"Index",[198,1586,1587],{"class":215},"));\n",[198,1589,1590,1593,1595,1597,1599,1601,1603,1605,1607,1610],{"class":200,"line":547},[198,1591,1592],{"class":208},"            pr",[198,1594,248],{"class":215},[198,1596,1437],{"class":208},[198,1598,462],{"class":204},[198,1600,1257],{"class":208},[198,1602,248],{"class":215},[198,1604,1289],{"class":208},[198,1606,248],{"class":215},[198,1608,1609],{"class":208},"Name",[198,1611,511],{"class":215},[198,1613,1614],{"class":200,"line":556},[198,1615,538],{"class":215},[198,1617,1618],{"class":200,"line":563},[198,1619,544],{"class":215},[198,1621,1622,1624,1626],{"class":200,"line":569},[198,1623,216],{"class":215},[198,1625,321],{"class":219},[198,1627,324],{"class":215},[198,1629,1630],{"class":200,"line":575},[198,1631,1632],{"class":279},"\u002F\u002F positions == [(0, 1), (1, 1)]: the second customizer\n",[198,1634,1635],{"class":200,"line":965},[198,1636,1637],{"class":279},"\u002F\u002F ran once per parent (ParentIndex, Index)\n",[176,1639,1641],{"id":1640},"singular-child-adds-need-one-parent","Singular child adds need one parent",[1643,1644,1645],"warning",{},[181,1646,1647,1648,1650,1651,1654,1655,1658],{},"A singular child Add needs one parent so its ",[195,1649,227],{}," value can identify one child. After ",[195,1652,1653],{},"AddCodeRepositories(out var repos, 2)",", use the plural Add for both repositories or select one with ",[195,1656,1657],{},".Under(repos[0])",". A singular child Add with zero or multiple parents throws.",[1660,1661,1662],"style",{},"html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sG8yY, html code.shiki .sG8yY{--shiki-light:#E2931D;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .syTEX, html code.shiki .syTEX{--shiki-light:#FF5370;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":193,"searchDepth":201,"depth":212,"links":1664},[1665,1666,1667,1668,1669],{"id":178,"depth":212,"text":179},{"id":342,"depth":212,"text":343},{"id":1051,"depth":212,"text":1052},{"id":1335,"depth":212,"text":1336},{"id":1640,"depth":212,"text":1641},"Child counts and customizers multiply per parent, and come back as one flat array.","md",null,{},{"icon":54},{"title":51,"description":1670},"jCkcAPb7Itd-oQD_1uykLuqNr1BW_jF9WdC6nOywanQ",[1678,1680],{"title":46,"path":47,"stem":48,"description":1679,"icon":49,"children":-1},"Typed parents, the anchor rule, ancestors, and jumping back with Under.",{"title":56,"path":57,"stem":58,"description":1681,"icon":59,"children":-1},"Numbers and ordering that continue across Add calls, per session, parent or ancestor.",1791831051915]