[{"data":1,"prerenderedAt":2012},["ShallowReactive",2],{"navigation_docs":3,"-modules-widget":153,"-modules-widget-surround":2007},[4,35,50,59,144],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":6},"Getting started",false,"\u002Fgetting-started","1.getting-started",[10,15,20,25,30],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fgetting-started\u002Fintroduction","1.getting-started\u002F2.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"Local Development","\u002Fgetting-started\u002Flocal-development","1.getting-started\u002F3.local-development","i-lucide-terminal",{"title":21,"path":22,"stem":23,"icon":24},"Publishing Packages","\u002Fgetting-started\u002Fpublishing","1.getting-started\u002F4.publishing","i-lucide-package-check",{"title":26,"path":27,"stem":28,"icon":29},"Writing a Module","\u002Fgetting-started\u002Fwriting-a-module","1.getting-started\u002F5.writing-a-module","i-lucide-puzzle",{"title":31,"path":32,"stem":33,"icon":34},"UX Patterns","\u002Fgetting-started\u002Fux-patterns","1.getting-started\u002F6.ux-patterns","i-lucide-layout-template",{"title":36,"path":37,"stem":38,"children":39},"Applications","\u002Fapplications","2.applications",[40,45],{"title":41,"path":42,"stem":43,"icon":44},"Website","\u002Fapplications\u002Fwebsite","2.applications\u002F1.website","i-lucide-layout-dashboard",{"title":46,"path":47,"stem":48,"icon":49},"Docs","\u002Fapplications\u002Fdocs","2.applications\u002F2.docs","i-lucide-book-open",{"title":51,"path":52,"stem":53,"children":54},"Layers","\u002Flayers","3.layers",[55],{"title":56,"path":57,"stem":58},"Base Layer","\u002Flayers\u002Fbase","3.layers\u002F1.base",{"title":60,"path":61,"stem":62,"children":63},"Modules","\u002Fmodules","4.modules",[64,68,72,76,80,84,88,92,96,100,104,108,112,116,120,124,128,132,136,140],{"title":65,"path":66,"stem":67},"Account","\u002Fmodules\u002Faccount","4.modules\u002F01.account",{"title":69,"path":70,"stem":71},"Admin","\u002Fmodules\u002Fadmin","4.modules\u002F02.admin",{"title":73,"path":74,"stem":75},"Auth","\u002Fmodules\u002Fauth","4.modules\u002F03.auth",{"title":77,"path":78,"stem":79},"Authorization","\u002Fmodules\u002Fauthorization","4.modules\u002F04.authorization",{"title":81,"path":82,"stem":83},"Cookie Consent","\u002Fmodules\u002Fcookie-consent","4.modules\u002F05.cookie-consent",{"title":85,"path":86,"stem":87},"Events","\u002Fmodules\u002Fevents","4.modules\u002F06.events",{"title":89,"path":90,"stem":91},"Forms","\u002Fmodules\u002Fforms","4.modules\u002F07.forms",{"title":93,"path":94,"stem":95},"MCP","\u002Fmodules\u002Fmcp","4.modules\u002F08.mcp",{"title":97,"path":98,"stem":99},"Menu","\u002Fmodules\u002Fmenu","4.modules\u002F09.menu",{"title":101,"path":102,"stem":103},"Module Kit","\u002Fmodules\u002Fmodule-kit","4.modules\u002F10.module-kit",{"title":105,"path":106,"stem":107},"Notify","\u002Fmodules\u002Fnotify","4.modules\u002F11.notify",{"title":109,"path":110,"stem":111},"OAuth Server","\u002Fmodules\u002Foauth-server","4.modules\u002F12.oauth-server",{"title":113,"path":114,"stem":115},"Payments","\u002Fmodules\u002Fpayments","4.modules\u002F13.payments",{"title":117,"path":118,"stem":119},"Preferences","\u002Fmodules\u002Fpreferences","4.modules\u002F14.preferences",{"title":121,"path":122,"stem":123},"Stripe","\u002Fmodules\u002Fstripe","4.modules\u002F15.stripe",{"title":125,"path":126,"stem":127},"Subscriptions","\u002Fmodules\u002Fsubscriptions","4.modules\u002F16.subscriptions",{"title":129,"path":130,"stem":131},"UI","\u002Fmodules\u002Fui","4.modules\u002F17.ui",{"title":133,"path":134,"stem":135},"Users","\u002Fmodules\u002Fusers","4.modules\u002F18.users",{"title":137,"path":138,"stem":139},"Widget","\u002Fmodules\u002Fwidget","4.modules\u002F19.widget",{"title":141,"path":142,"stem":143},"Email Templates","\u002Fmodules\u002Femail-templates","4.modules\u002F20.email-templates",{"title":145,"path":146,"stem":147,"children":148},"Packages","\u002Fpackages","5.packages",[149],{"title":150,"path":151,"stem":152},"CLI","\u002Fpackages\u002Fcli","5.packages\u002F4.cli",{"id":154,"title":137,"body":155,"description":2001,"extension":2002,"links":2003,"meta":2004,"navigation":764,"path":138,"seo":2005,"stem":139,"__hash__":2006},"docs\u002F4.modules\u002F19.widget.md",{"type":156,"value":157,"toc":1989},"minimark",[158,187,221,226,296,342,346,349,353,358,444,464,476,487,502,548,555,559,569,674,678,699,1129,1596,1600,1608,1674,1678,1685,1845,1849,1853,1985],[159,160,161,162,169,170,174,175,178,179,182,183,186],"p",{},"Named widget areas, modelled on ",[163,164,165],"a",{"href":98},[166,167,168],"code",{},"@frigear-nu\u002Fmenu",". An ",[171,172,173],"strong",{},"area"," (",[166,176,177],{},"admin.dashboard",", ",[166,180,181],{},"home.sidebar",",\n...) is a named slot in a page. Modules ",[171,184,185],{},"contribute widgets"," (Vue components) to it at build time and the host\nrenders the area wherever it likes; neither side knows about the other. The data is presentation-free and the\ncomponents are loaded lazily, so an area only ships the widgets it renders. Tabs are a second, separate registry with\nthe same ordering, replacement and gating.",[188,189,190,214],"note",{},[159,191,192,195,196,201,202,205,206,209,210,213],{},[171,193,194],{},"Requires"," ",[163,197,198],{"href":102},[166,199,200],{},"@frigear-nu\u002Fmodule-kit",". No other module is needed; ",[166,203,204],{},"\u003CWidgetTabs>"," draws tab icons\nwith Nuxt UI's ",[166,207,208],{},"UIcon",", and ",[166,211,212],{},"@nuxtjs\u002Fi18n"," is optional for translating tab labels.",[159,215,216,217,220],{},"The module has no options (",[166,218,219],{},"widgets"," is only a config key for internal state).",[222,223,225],"h2",{"id":224},"quick-setup","Quick setup",[227,228,233],"pre",{"className":229,"code":230,"language":231,"meta":232,"style":232},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","export default defineNuxtConfig({\n  modules: ['@frigear-nu\u002Fwidget'],\n})\n","ts","",[166,234,235,259,287],{"__ignoreMap":232},[236,237,240,244,247,251,255],"span",{"class":238,"line":239},"line",1,[236,241,243],{"class":242},"s7zQu","export",[236,245,246],{"class":242}," default",[236,248,250],{"class":249},"s2Zo4"," defineNuxtConfig",[236,252,254],{"class":253},"sTEyZ","(",[236,256,258],{"class":257},"sMK4o","{\n",[236,260,262,266,269,272,275,279,281,284],{"class":238,"line":261},2,[236,263,265],{"class":264},"swJcz","  modules",[236,267,268],{"class":257},":",[236,270,271],{"class":253}," [",[236,273,274],{"class":257},"'",[236,276,278],{"class":277},"sfazB","@frigear-nu\u002Fwidget",[236,280,274],{"class":257},[236,282,283],{"class":253},"]",[236,285,286],{"class":257},",\n",[236,288,290,293],{"class":238,"line":289},3,[236,291,292],{"class":257},"}",[236,294,295],{"class":253},")\n",[227,297,301],{"className":298,"code":299,"language":300,"meta":232,"style":232},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003CWidgetArea name=\"admin.dashboard\">\n  \u003Ctemplate #empty>Nothing to show yet.\u003C\u002Ftemplate>\n\u003C\u002FWidgetArea>\n","vue",[166,302,303,328,333],{"__ignoreMap":232},[236,304,305,308,311,315,318,321,323,325],{"class":238,"line":239},[236,306,307],{"class":257},"\u003C",[236,309,310],{"class":264},"WidgetArea",[236,312,314],{"class":313},"spNyl"," name",[236,316,317],{"class":257},"=",[236,319,320],{"class":257},"\"",[236,322,177],{"class":277},[236,324,320],{"class":257},[236,326,327],{"class":257},">\n",[236,329,330],{"class":238,"line":261},[236,331,332],{"class":253},"  \u003Ctemplate #empty>Nothing to show yet.\u003C\u002Ftemplate>\n",[236,334,335,338,340],{"class":238,"line":289},[236,336,337],{"class":257},"\u003C\u002F",[236,339,310],{"class":264},[236,341,327],{"class":257},[222,343,345],{"id":344},"options","Options",[159,347,348],{},"None.",[222,350,352],{"id":351},"app","App",[354,355,357],"h3",{"id":356},"components","Components",[359,360,361,380],"table",{},[362,363,364],"thead",{},[365,366,367,371,374,377],"tr",{},[368,369,370],"th",{},"Component",[368,372,373],{},"Props",[368,375,376],{},"Slots",[368,378,379],{},"Purpose",[381,382,383,421],"tbody",{},[365,384,385,391,403,415],{},[386,387,388],"td",{},[166,389,390],{},"\u003CWidgetArea>",[386,392,393,178,396,178,399,402],{},[166,394,395],{},"name: string",[166,397,398],{},"context?: Record\u003Cstring, unknown>",[166,400,401],{},"gridClass?: string"," (replaces the default grid classes of the wrapper)",[386,404,405,178,408,411,412],{},[166,406,407],{},"empty",[166,409,410],{},"item"," with ",[166,413,414],{},"{ widget: WidgetMeta, component, context }",[386,416,417,418,420],{},"Renders every widget of the area in a responsive grid. Use ",[166,419,410],{}," to lay widgets out yourself.",[365,422,423,427,433,437],{},[386,424,425],{},[166,426,204],{},[386,428,429,178,431],{},[166,430,395],{},[166,432,398],{},[386,434,435],{},[166,436,407],{},[386,438,439,440,443],{},"Renders the area's tabs as a tab list with the active tab's component below. Emits ",[166,441,442],{},"refresh",".",[159,445,446,449,450,453,454,457,458,460,461,443],{},[166,447,448],{},"context"," is whatever the host renders the area for (for example ",[166,451,452],{},"{ user }","). Each widget or tab component receives its\nstatic ",[166,455,456],{},"props",", then every entry of ",[166,459,448],{}," as a prop, and the context reaches the filter hooks as ",[166,462,463],{},"ctx.context",[159,465,466,468,469,472,473,475],{},[166,467,204],{}," keeps the active tab in the ",[166,470,471],{},"?tab="," query parameter (updated in place, without a navigation), supports\narrow-key navigation, and re-emits a tab's ",[166,474,442],{}," event so the host can reload its data.",[477,478,480,483,484],"h4",{"id":479},"widgettabs-or-pagetabs",[166,481,482],{},"WidgetTabs"," or ",[166,485,486],{},"PageTabs",[159,488,489,491,492,497,498,501],{},[166,490,204],{}," is drawn exactly like ",[163,493,495],{"href":494},"\u002Fmodules\u002Fui#page-components",[166,496,486],{}," from ",[166,499,500],{},"@frigear-nu\u002Fui",": the same bordered\nstrip with an underline highlight, scrolling sideways on narrow screens. A detail page looks the same whichever of the\ntwo it uses. The difference is who decides the sections:",[359,503,504,514],{},[362,505,506],{},[365,507,508,511],{},[368,509,510],{},"Use",[368,512,513],{},"When",[381,515,516,531],{},[365,517,518,522],{},[386,519,520],{},[166,521,204],{},[386,523,524,525,528,529,443],{},"Other modules should be able to add sections: the page names an area (for example ",[166,526,527],{},"admin.users",") and renders whatever is registered. The active tab lives in ",[166,530,471],{},[365,532,533,537],{},[386,534,535],{},[166,536,486],{},[386,538,539,540,543,544,547],{},"The page owns its sections and nobody else adds to them, such as a form's builder, settings and access. Link mode (items with ",[166,541,542],{},"to",") for sections that are routes, state mode (",[166,545,546],{},"v-model",") for the rest.",[159,549,550,551,443],{},"See ",[163,552,554],{"href":553},"\u002Fgetting-started\u002Fux-patterns#tabs","UX patterns",[354,556,558],{"id":557},"composables","Composables",[159,560,561,562,565,566,568],{},"Auto-imported. Both return the shape of ",[166,563,564],{},"useAsyncData",": the registered entries as plain data, ordered and passed through\nthe filter hook (the component itself is resolved by the components above). ",[166,567,448],{}," may be a ref or getter.",[227,570,572],{"className":229,"code":571,"language":231,"meta":232,"style":232},"useWidgets(area: string, context?: MaybeRefOrGetter\u003CRecord\u003Cstring, unknown> | undefined>): AsyncData\u003CWidgetMeta[]>\nuseTabs(area: string, context?: MaybeRefOrGetter\u003CRecord\u003Cstring, unknown> | undefined>): AsyncData\u003CTabMeta[]> \u002F\u002F labels already translated\n",[166,573,574,628],{"__ignoreMap":232},[236,575,576,579,582,585,588,591,594,596,599,601,604,606,609,612,615,618,621,623,626],{"class":238,"line":239},[236,577,578],{"class":249},"useWidgets",[236,580,581],{"class":253},"(area: string",[236,583,584],{"class":257},",",[236,586,587],{"class":253}," context",[236,589,590],{"class":257},"?:",[236,592,593],{"class":253}," MaybeRefOrGetter",[236,595,307],{"class":257},[236,597,598],{"class":253},"Record",[236,600,307],{"class":257},[236,602,603],{"class":253},"string",[236,605,584],{"class":257},[236,607,608],{"class":253}," unknown",[236,610,611],{"class":257},">",[236,613,614],{"class":257}," |",[236,616,617],{"class":257}," undefined>",[236,619,620],{"class":253},"): AsyncData",[236,622,307],{"class":257},[236,624,625],{"class":253},"WidgetMeta[]",[236,627,327],{"class":257},[236,629,630,633,635,637,639,641,643,645,647,649,651,653,655,657,659,661,663,665,668,670],{"class":238,"line":261},[236,631,632],{"class":249},"useTabs",[236,634,581],{"class":253},[236,636,584],{"class":257},[236,638,587],{"class":253},[236,640,590],{"class":257},[236,642,593],{"class":253},[236,644,307],{"class":257},[236,646,598],{"class":253},[236,648,307],{"class":257},[236,650,603],{"class":253},[236,652,584],{"class":257},[236,654,608],{"class":253},[236,656,611],{"class":257},[236,658,614],{"class":257},[236,660,617],{"class":257},[236,662,620],{"class":253},[236,664,307],{"class":257},[236,666,667],{"class":253},"TabMeta[]",[236,669,611],{"class":257},[236,671,673],{"class":672},"sHwdD"," \u002F\u002F labels already translated\n",[354,675,677],{"id":676},"contributing-from-a-module","Contributing from a module",[159,679,680,681,483,684,687,688,691,692,695,696,698],{},"Call ",[166,682,683],{},"extendWidgets",[166,685,686],{},"extendTabs"," once in a module's ",[166,689,690],{},"setup()","; registration order between modules does not matter.\nAn entry registered again under the same ",[166,693,694],{},"id"," in an area replaces the earlier one, which is how a host overrides a\nmodule's widget or tab. The ",[166,697,694],{}," defaults to the component's file name.",[227,700,702],{"className":229,"code":701,"language":231,"meta":232,"style":232},"import { createResolver, defineNuxtModule } from '@nuxt\u002Fkit'\nimport { extendWidgets, extendTabs } from '@frigear-nu\u002Fwidget\u002Futils'\n\nexport default defineNuxtModule({\n  setup(_options, nuxt) {\n    const resolver = createResolver(import.meta.url)\n\n    extendWidgets(nuxt, 'admin.dashboard', {\n      component: resolver.resolve('.\u002Fruntime\u002Fapp\u002Fwidgets\u002FNewMembers.vue'),\n      order: 10,\n      span: 2,\n      props: { days: 30 },\n      requires: 'admin',\n    })\n\n    extendTabs(nuxt, 'admin.users', {\n      id: 'payments',\n      component: resolver.resolve('.\u002Fruntime\u002Fapp\u002Ftabs\u002FPayments.vue'),\n      order: 20,\n      label: 'Payments',\n      labelKey: 'payments.admin.tab',\n      icon: 'i-lucide-credit-card',\n      requires: 'billing',\n    })\n  },\n})\n",[166,703,704,735,760,766,779,802,832,837,860,888,902,915,936,953,961,966,988,1005,1031,1043,1059,1076,1093,1109,1116,1122],{"__ignoreMap":232},[236,705,706,709,712,715,717,720,723,726,729,732],{"class":238,"line":239},[236,707,708],{"class":242},"import",[236,710,711],{"class":257}," {",[236,713,714],{"class":253}," createResolver",[236,716,584],{"class":257},[236,718,719],{"class":253}," defineNuxtModule",[236,721,722],{"class":257}," }",[236,724,725],{"class":242}," from",[236,727,728],{"class":257}," '",[236,730,731],{"class":277},"@nuxt\u002Fkit",[236,733,734],{"class":257},"'\n",[236,736,737,739,741,744,746,749,751,753,755,758],{"class":238,"line":261},[236,738,708],{"class":242},[236,740,711],{"class":257},[236,742,743],{"class":253}," extendWidgets",[236,745,584],{"class":257},[236,747,748],{"class":253}," extendTabs",[236,750,722],{"class":257},[236,752,725],{"class":242},[236,754,728],{"class":257},[236,756,757],{"class":277},"@frigear-nu\u002Fwidget\u002Futils",[236,759,734],{"class":257},[236,761,762],{"class":238,"line":289},[236,763,765],{"emptyLinePlaceholder":764},true,"\n",[236,767,769,771,773,775,777],{"class":238,"line":768},4,[236,770,243],{"class":242},[236,772,246],{"class":242},[236,774,719],{"class":249},[236,776,254],{"class":253},[236,778,258],{"class":257},[236,780,782,785,787,791,793,796,799],{"class":238,"line":781},5,[236,783,784],{"class":264},"  setup",[236,786,254],{"class":257},[236,788,790],{"class":789},"sHdIc","_options",[236,792,584],{"class":257},[236,794,795],{"class":789}," nuxt",[236,797,798],{"class":257},")",[236,800,801],{"class":257}," {\n",[236,803,805,808,811,814,816,818,820,822,825,827,830],{"class":238,"line":804},6,[236,806,807],{"class":313},"    const",[236,809,810],{"class":253}," resolver",[236,812,813],{"class":257}," =",[236,815,714],{"class":249},[236,817,254],{"class":264},[236,819,708],{"class":242},[236,821,443],{"class":257},[236,823,824],{"class":253},"meta",[236,826,443],{"class":257},[236,828,829],{"class":253},"url",[236,831,295],{"class":264},[236,833,835],{"class":238,"line":834},7,[236,836,765],{"emptyLinePlaceholder":764},[236,838,840,843,845,848,850,852,854,856,858],{"class":238,"line":839},8,[236,841,842],{"class":249},"    extendWidgets",[236,844,254],{"class":264},[236,846,847],{"class":253},"nuxt",[236,849,584],{"class":257},[236,851,728],{"class":257},[236,853,177],{"class":277},[236,855,274],{"class":257},[236,857,584],{"class":257},[236,859,801],{"class":257},[236,861,863,866,868,870,872,875,877,879,882,884,886],{"class":238,"line":862},9,[236,864,865],{"class":264},"      component",[236,867,268],{"class":257},[236,869,810],{"class":253},[236,871,443],{"class":257},[236,873,874],{"class":249},"resolve",[236,876,254],{"class":264},[236,878,274],{"class":257},[236,880,881],{"class":277},".\u002Fruntime\u002Fapp\u002Fwidgets\u002FNewMembers.vue",[236,883,274],{"class":257},[236,885,798],{"class":264},[236,887,286],{"class":257},[236,889,891,894,896,900],{"class":238,"line":890},10,[236,892,893],{"class":264},"      order",[236,895,268],{"class":257},[236,897,899],{"class":898},"sbssI"," 10",[236,901,286],{"class":257},[236,903,905,908,910,913],{"class":238,"line":904},11,[236,906,907],{"class":264},"      span",[236,909,268],{"class":257},[236,911,912],{"class":898}," 2",[236,914,286],{"class":257},[236,916,918,921,923,925,928,930,933],{"class":238,"line":917},12,[236,919,920],{"class":264},"      props",[236,922,268],{"class":257},[236,924,711],{"class":257},[236,926,927],{"class":264}," days",[236,929,268],{"class":257},[236,931,932],{"class":898}," 30",[236,934,935],{"class":257}," },\n",[236,937,939,942,944,946,949,951],{"class":238,"line":938},13,[236,940,941],{"class":264},"      requires",[236,943,268],{"class":257},[236,945,728],{"class":257},[236,947,948],{"class":277},"admin",[236,950,274],{"class":257},[236,952,286],{"class":257},[236,954,956,959],{"class":238,"line":955},14,[236,957,958],{"class":257},"    }",[236,960,295],{"class":264},[236,962,964],{"class":238,"line":963},15,[236,965,765],{"emptyLinePlaceholder":764},[236,967,969,972,974,976,978,980,982,984,986],{"class":238,"line":968},16,[236,970,971],{"class":249},"    extendTabs",[236,973,254],{"class":264},[236,975,847],{"class":253},[236,977,584],{"class":257},[236,979,728],{"class":257},[236,981,527],{"class":277},[236,983,274],{"class":257},[236,985,584],{"class":257},[236,987,801],{"class":257},[236,989,991,994,996,998,1001,1003],{"class":238,"line":990},17,[236,992,993],{"class":264},"      id",[236,995,268],{"class":257},[236,997,728],{"class":257},[236,999,1000],{"class":277},"payments",[236,1002,274],{"class":257},[236,1004,286],{"class":257},[236,1006,1008,1010,1012,1014,1016,1018,1020,1022,1025,1027,1029],{"class":238,"line":1007},18,[236,1009,865],{"class":264},[236,1011,268],{"class":257},[236,1013,810],{"class":253},[236,1015,443],{"class":257},[236,1017,874],{"class":249},[236,1019,254],{"class":264},[236,1021,274],{"class":257},[236,1023,1024],{"class":277},".\u002Fruntime\u002Fapp\u002Ftabs\u002FPayments.vue",[236,1026,274],{"class":257},[236,1028,798],{"class":264},[236,1030,286],{"class":257},[236,1032,1034,1036,1038,1041],{"class":238,"line":1033},19,[236,1035,893],{"class":264},[236,1037,268],{"class":257},[236,1039,1040],{"class":898}," 20",[236,1042,286],{"class":257},[236,1044,1046,1049,1051,1053,1055,1057],{"class":238,"line":1045},20,[236,1047,1048],{"class":264},"      label",[236,1050,268],{"class":257},[236,1052,728],{"class":257},[236,1054,113],{"class":277},[236,1056,274],{"class":257},[236,1058,286],{"class":257},[236,1060,1062,1065,1067,1069,1072,1074],{"class":238,"line":1061},21,[236,1063,1064],{"class":264},"      labelKey",[236,1066,268],{"class":257},[236,1068,728],{"class":257},[236,1070,1071],{"class":277},"payments.admin.tab",[236,1073,274],{"class":257},[236,1075,286],{"class":257},[236,1077,1079,1082,1084,1086,1089,1091],{"class":238,"line":1078},22,[236,1080,1081],{"class":264},"      icon",[236,1083,268],{"class":257},[236,1085,728],{"class":257},[236,1087,1088],{"class":277},"i-lucide-credit-card",[236,1090,274],{"class":257},[236,1092,286],{"class":257},[236,1094,1096,1098,1100,1102,1105,1107],{"class":238,"line":1095},23,[236,1097,941],{"class":264},[236,1099,268],{"class":257},[236,1101,728],{"class":257},[236,1103,1104],{"class":277},"billing",[236,1106,274],{"class":257},[236,1108,286],{"class":257},[236,1110,1112,1114],{"class":238,"line":1111},24,[236,1113,958],{"class":257},[236,1115,295],{"class":264},[236,1117,1119],{"class":238,"line":1118},25,[236,1120,1121],{"class":257},"  },\n",[236,1123,1125,1127],{"class":238,"line":1124},26,[236,1126,292],{"class":257},[236,1128,295],{"class":253},[227,1130,1132],{"className":229,"code":1131,"language":231,"meta":232,"style":232},"type WidgetDefinition = {\n  id?: string \u002F\u002F unique within an area; default: component file name\n  component: string \u002F\u002F resolved path of the Vue component\n  order?: number \u002F\u002F lower first; unordered last, in registration order\n  span?: 1 | 2 | 3 | 4 \u002F\u002F grid columns in the default layout (default 1)\n  props?: Record\u003Cstring, unknown> \u002F\u002F serializable\n  requires?: string \u002F\u002F free-form, for the widgets:filter hook; never interpreted by the module\n  tags?: string[]\n  meta?: Record\u003Cstring, unknown>\n}\n\ntype TabDefinition = {\n  id?: string \u002F\u002F default: component file name; also the `?tab=` value\n  component: string\n  order?: number\n  props?: Record\u003Cstring, unknown>\n  label?: string \u002F\u002F plain fallback label; default: the id\n  labelKey?: string \u002F\u002F i18n key, translated at render time with @nuxtjs\u002Fi18n\n  icon?: string \u002F\u002F for example 'i-lucide-credit-card'\n  requires?: string \u002F\u002F free-form, for the tabs:filter hook\n  tags?: string[]\n  meta?: Record\u003Cstring, unknown>\n}\n\ntype RegisteredWidget = WidgetDefinition & { id: string, area: string }\ntype RegisteredTab = TabDefinition & { id: string, area: string }\ntype WidgetMeta = Omit\u003CRegisteredWidget, 'component'> \u002F\u002F what useWidgets returns\ntype TabMeta = Omit\u003CRegisteredTab, 'component' | 'labelKey' | 'label'> & { label: string, labelKey?: string } \u002F\u002F what useTabs returns\n",[166,1133,1134,1147,1160,1172,1185,1212,1235,1247,1259,1278,1283,1287,1298,1309,1318,1327,1345,1357,1369,1381,1392,1402,1420,1424,1428,1463,1494,1526],{"__ignoreMap":232},[236,1135,1136,1139,1143,1145],{"class":238,"line":239},[236,1137,1138],{"class":313},"type",[236,1140,1142],{"class":1141},"sBMFI"," WidgetDefinition",[236,1144,813],{"class":257},[236,1146,801],{"class":257},[236,1148,1149,1152,1154,1157],{"class":238,"line":261},[236,1150,1151],{"class":264},"  id",[236,1153,590],{"class":257},[236,1155,1156],{"class":1141}," string",[236,1158,1159],{"class":672}," \u002F\u002F unique within an area; default: component file name\n",[236,1161,1162,1165,1167,1169],{"class":238,"line":289},[236,1163,1164],{"class":264},"  component",[236,1166,268],{"class":257},[236,1168,1156],{"class":1141},[236,1170,1171],{"class":672}," \u002F\u002F resolved path of the Vue component\n",[236,1173,1174,1177,1179,1182],{"class":238,"line":768},[236,1175,1176],{"class":264},"  order",[236,1178,590],{"class":257},[236,1180,1181],{"class":1141}," number",[236,1183,1184],{"class":672}," \u002F\u002F lower first; unordered last, in registration order\n",[236,1186,1187,1190,1192,1195,1197,1199,1201,1204,1206,1209],{"class":238,"line":781},[236,1188,1189],{"class":264},"  span",[236,1191,590],{"class":257},[236,1193,1194],{"class":898}," 1",[236,1196,614],{"class":257},[236,1198,912],{"class":898},[236,1200,614],{"class":257},[236,1202,1203],{"class":898}," 3",[236,1205,614],{"class":257},[236,1207,1208],{"class":898}," 4",[236,1210,1211],{"class":672}," \u002F\u002F grid columns in the default layout (default 1)\n",[236,1213,1214,1217,1219,1222,1224,1226,1228,1230,1232],{"class":238,"line":804},[236,1215,1216],{"class":264},"  props",[236,1218,590],{"class":257},[236,1220,1221],{"class":1141}," Record",[236,1223,307],{"class":257},[236,1225,603],{"class":1141},[236,1227,584],{"class":257},[236,1229,608],{"class":1141},[236,1231,611],{"class":257},[236,1233,1234],{"class":672}," \u002F\u002F serializable\n",[236,1236,1237,1240,1242,1244],{"class":238,"line":834},[236,1238,1239],{"class":264},"  requires",[236,1241,590],{"class":257},[236,1243,1156],{"class":1141},[236,1245,1246],{"class":672}," \u002F\u002F free-form, for the widgets:filter hook; never interpreted by the module\n",[236,1248,1249,1252,1254,1256],{"class":238,"line":839},[236,1250,1251],{"class":264},"  tags",[236,1253,590],{"class":257},[236,1255,1156],{"class":1141},[236,1257,1258],{"class":253},"[]\n",[236,1260,1261,1264,1266,1268,1270,1272,1274,1276],{"class":238,"line":862},[236,1262,1263],{"class":264},"  meta",[236,1265,590],{"class":257},[236,1267,1221],{"class":1141},[236,1269,307],{"class":257},[236,1271,603],{"class":1141},[236,1273,584],{"class":257},[236,1275,608],{"class":1141},[236,1277,327],{"class":257},[236,1279,1280],{"class":238,"line":890},[236,1281,1282],{"class":257},"}\n",[236,1284,1285],{"class":238,"line":904},[236,1286,765],{"emptyLinePlaceholder":764},[236,1288,1289,1291,1294,1296],{"class":238,"line":917},[236,1290,1138],{"class":313},[236,1292,1293],{"class":1141}," TabDefinition",[236,1295,813],{"class":257},[236,1297,801],{"class":257},[236,1299,1300,1302,1304,1306],{"class":238,"line":938},[236,1301,1151],{"class":264},[236,1303,590],{"class":257},[236,1305,1156],{"class":1141},[236,1307,1308],{"class":672}," \u002F\u002F default: component file name; also the `?tab=` value\n",[236,1310,1311,1313,1315],{"class":238,"line":955},[236,1312,1164],{"class":264},[236,1314,268],{"class":257},[236,1316,1317],{"class":1141}," string\n",[236,1319,1320,1322,1324],{"class":238,"line":963},[236,1321,1176],{"class":264},[236,1323,590],{"class":257},[236,1325,1326],{"class":1141}," number\n",[236,1328,1329,1331,1333,1335,1337,1339,1341,1343],{"class":238,"line":968},[236,1330,1216],{"class":264},[236,1332,590],{"class":257},[236,1334,1221],{"class":1141},[236,1336,307],{"class":257},[236,1338,603],{"class":1141},[236,1340,584],{"class":257},[236,1342,608],{"class":1141},[236,1344,327],{"class":257},[236,1346,1347,1350,1352,1354],{"class":238,"line":990},[236,1348,1349],{"class":264},"  label",[236,1351,590],{"class":257},[236,1353,1156],{"class":1141},[236,1355,1356],{"class":672}," \u002F\u002F plain fallback label; default: the id\n",[236,1358,1359,1362,1364,1366],{"class":238,"line":1007},[236,1360,1361],{"class":264},"  labelKey",[236,1363,590],{"class":257},[236,1365,1156],{"class":1141},[236,1367,1368],{"class":672}," \u002F\u002F i18n key, translated at render time with @nuxtjs\u002Fi18n\n",[236,1370,1371,1374,1376,1378],{"class":238,"line":1033},[236,1372,1373],{"class":264},"  icon",[236,1375,590],{"class":257},[236,1377,1156],{"class":1141},[236,1379,1380],{"class":672}," \u002F\u002F for example 'i-lucide-credit-card'\n",[236,1382,1383,1385,1387,1389],{"class":238,"line":1045},[236,1384,1239],{"class":264},[236,1386,590],{"class":257},[236,1388,1156],{"class":1141},[236,1390,1391],{"class":672}," \u002F\u002F free-form, for the tabs:filter hook\n",[236,1393,1394,1396,1398,1400],{"class":238,"line":1061},[236,1395,1251],{"class":264},[236,1397,590],{"class":257},[236,1399,1156],{"class":1141},[236,1401,1258],{"class":253},[236,1403,1404,1406,1408,1410,1412,1414,1416,1418],{"class":238,"line":1078},[236,1405,1263],{"class":264},[236,1407,590],{"class":257},[236,1409,1221],{"class":1141},[236,1411,307],{"class":257},[236,1413,603],{"class":1141},[236,1415,584],{"class":257},[236,1417,608],{"class":1141},[236,1419,327],{"class":257},[236,1421,1422],{"class":238,"line":1095},[236,1423,1282],{"class":257},[236,1425,1426],{"class":238,"line":1111},[236,1427,765],{"emptyLinePlaceholder":764},[236,1429,1430,1432,1435,1437,1439,1442,1444,1447,1449,1451,1453,1456,1458,1460],{"class":238,"line":1118},[236,1431,1138],{"class":313},[236,1433,1434],{"class":1141}," RegisteredWidget",[236,1436,813],{"class":257},[236,1438,1142],{"class":1141},[236,1440,1441],{"class":257}," &",[236,1443,711],{"class":257},[236,1445,1446],{"class":264}," id",[236,1448,268],{"class":257},[236,1450,1156],{"class":1141},[236,1452,584],{"class":257},[236,1454,1455],{"class":264}," area",[236,1457,268],{"class":257},[236,1459,1156],{"class":1141},[236,1461,1462],{"class":257}," }\n",[236,1464,1465,1467,1470,1472,1474,1476,1478,1480,1482,1484,1486,1488,1490,1492],{"class":238,"line":1124},[236,1466,1138],{"class":313},[236,1468,1469],{"class":1141}," RegisteredTab",[236,1471,813],{"class":257},[236,1473,1293],{"class":1141},[236,1475,1441],{"class":257},[236,1477,711],{"class":257},[236,1479,1446],{"class":264},[236,1481,268],{"class":257},[236,1483,1156],{"class":1141},[236,1485,584],{"class":257},[236,1487,1455],{"class":264},[236,1489,268],{"class":257},[236,1491,1156],{"class":1141},[236,1493,1462],{"class":257},[236,1495,1497,1499,1502,1504,1507,1509,1512,1514,1516,1519,1521,1523],{"class":238,"line":1496},27,[236,1498,1138],{"class":313},[236,1500,1501],{"class":1141}," WidgetMeta",[236,1503,813],{"class":257},[236,1505,1506],{"class":1141}," Omit",[236,1508,307],{"class":257},[236,1510,1511],{"class":1141},"RegisteredWidget",[236,1513,584],{"class":257},[236,1515,728],{"class":257},[236,1517,1518],{"class":277},"component",[236,1520,274],{"class":257},[236,1522,611],{"class":257},[236,1524,1525],{"class":672}," \u002F\u002F what useWidgets returns\n",[236,1527,1529,1531,1534,1536,1538,1540,1543,1545,1547,1549,1551,1553,1555,1558,1560,1562,1564,1567,1569,1571,1573,1575,1578,1580,1582,1584,1587,1589,1591,1593],{"class":238,"line":1528},28,[236,1530,1138],{"class":313},[236,1532,1533],{"class":1141}," TabMeta",[236,1535,813],{"class":257},[236,1537,1506],{"class":1141},[236,1539,307],{"class":257},[236,1541,1542],{"class":1141},"RegisteredTab",[236,1544,584],{"class":257},[236,1546,728],{"class":257},[236,1548,1518],{"class":277},[236,1550,274],{"class":257},[236,1552,614],{"class":257},[236,1554,728],{"class":257},[236,1556,1557],{"class":277},"labelKey",[236,1559,274],{"class":257},[236,1561,614],{"class":257},[236,1563,728],{"class":257},[236,1565,1566],{"class":277},"label",[236,1568,274],{"class":257},[236,1570,611],{"class":257},[236,1572,1441],{"class":257},[236,1574,711],{"class":257},[236,1576,1577],{"class":264}," label",[236,1579,268],{"class":257},[236,1581,1156],{"class":1141},[236,1583,584],{"class":257},[236,1585,1586],{"class":264}," labelKey",[236,1588,590],{"class":257},[236,1590,1156],{"class":1141},[236,1592,722],{"class":257},[236,1594,1595],{"class":672}," \u002F\u002F what useTabs returns\n",[354,1597,1599],{"id":1598},"utils","Utils",[159,1601,1602,1604,1605,443],{},[166,1603,757],{}," is framework-agnostic; the types above are also exported from ",[166,1606,1607],{},"@frigear-nu\u002Fwidget\u002Ftypes",[359,1609,1610,1619],{},[362,1611,1612],{},[365,1613,1614,1617],{},[368,1615,1616],{},"Export",[368,1618,379],{},[381,1620,1621,1634,1644,1660],{},[365,1622,1623,1628],{},[386,1624,1625],{},[166,1626,1627],{},"extendWidgets(nuxt, area, widgets)",[386,1629,1630,1631,1633],{},"Register one or more widgets into an area (call from a module's ",[166,1632,690],{},").",[365,1635,1636,1641],{},[386,1637,1638],{},[166,1639,1640],{},"extendTabs(nuxt, area, tabs)",[386,1642,1643],{},"Register one or more tabs into an area.",[365,1645,1646,1654],{},[386,1647,1648,178,1651],{},[166,1649,1650],{},"deriveWidgetId(widget)",[166,1652,1653],{},"deriveTabId(tab)",[386,1655,1656,1657,1659],{},"The id an entry gets: its ",[166,1658,694],{},", else the component file name.",[365,1661,1662,1667],{},[386,1663,1664],{},[166,1665,1666],{},"sortWidgets(list)",[386,1668,1669,1670,1673],{},"Order by ",[166,1671,1672],{},"order"," ascending; entries without one last, keeping registration order.",[354,1675,1677],{"id":1676},"gating","Gating",[159,1679,1680,1681,1684],{},"The module never interprets ",[166,1682,1683],{},"requires",". Listen to the filter hooks and drop what the current visitor should not see:",[227,1686,1688],{"className":229,"code":1687,"language":231,"meta":232,"style":232},"export default defineNuxtPlugin((nuxtApp) => {\n  nuxtApp.hook('widgets:filter', (ctx) => {\n    const role = useUserSession().user.value?.role\n    ctx.widgets = ctx.widgets.filter(widget => !widget.requires || widget.requires === role)\n  })\n})\n",[166,1689,1690,1713,1745,1776,1832,1839],{"__ignoreMap":232},[236,1691,1692,1694,1696,1699,1701,1703,1706,1708,1711],{"class":238,"line":239},[236,1693,243],{"class":242},[236,1695,246],{"class":242},[236,1697,1698],{"class":249}," defineNuxtPlugin",[236,1700,254],{"class":253},[236,1702,254],{"class":257},[236,1704,1705],{"class":789},"nuxtApp",[236,1707,798],{"class":257},[236,1709,1710],{"class":313}," =>",[236,1712,801],{"class":257},[236,1714,1715,1718,1720,1723,1725,1727,1730,1732,1734,1736,1739,1741,1743],{"class":238,"line":261},[236,1716,1717],{"class":253},"  nuxtApp",[236,1719,443],{"class":257},[236,1721,1722],{"class":249},"hook",[236,1724,254],{"class":264},[236,1726,274],{"class":257},[236,1728,1729],{"class":277},"widgets:filter",[236,1731,274],{"class":257},[236,1733,584],{"class":257},[236,1735,174],{"class":257},[236,1737,1738],{"class":789},"ctx",[236,1740,798],{"class":257},[236,1742,1710],{"class":313},[236,1744,801],{"class":257},[236,1746,1747,1749,1752,1754,1757,1760,1762,1765,1767,1770,1773],{"class":238,"line":289},[236,1748,807],{"class":313},[236,1750,1751],{"class":253}," role",[236,1753,813],{"class":257},[236,1755,1756],{"class":249}," useUserSession",[236,1758,1759],{"class":264},"()",[236,1761,443],{"class":257},[236,1763,1764],{"class":253},"user",[236,1766,443],{"class":257},[236,1768,1769],{"class":253},"value",[236,1771,1772],{"class":257},"?.",[236,1774,1775],{"class":253},"role\n",[236,1777,1778,1781,1783,1785,1787,1790,1792,1794,1796,1799,1801,1804,1806,1809,1811,1813,1815,1818,1821,1823,1825,1828,1830],{"class":238,"line":768},[236,1779,1780],{"class":253},"    ctx",[236,1782,443],{"class":257},[236,1784,219],{"class":253},[236,1786,813],{"class":257},[236,1788,1789],{"class":253}," ctx",[236,1791,443],{"class":257},[236,1793,219],{"class":253},[236,1795,443],{"class":257},[236,1797,1798],{"class":249},"filter",[236,1800,254],{"class":264},[236,1802,1803],{"class":789},"widget",[236,1805,1710],{"class":313},[236,1807,1808],{"class":257}," !",[236,1810,1803],{"class":253},[236,1812,443],{"class":257},[236,1814,1683],{"class":253},[236,1816,1817],{"class":257}," ||",[236,1819,1820],{"class":253}," widget",[236,1822,443],{"class":257},[236,1824,1683],{"class":253},[236,1826,1827],{"class":257}," ===",[236,1829,1751],{"class":253},[236,1831,295],{"class":264},[236,1833,1834,1837],{"class":238,"line":781},[236,1835,1836],{"class":257},"  }",[236,1838,295],{"class":264},[236,1840,1841,1843],{"class":238,"line":804},[236,1842,292],{"class":257},[236,1844,295],{"class":253},[1846,1847,1848],"warning",{},"Filtering only hides UI. Always enforce permissions on the server for the data a widget loads.",[222,1850,1852],{"id":1851},"hooks","Hooks",[359,1854,1855,1870],{},[362,1856,1857],{},[365,1858,1859,1862,1865,1867],{},[368,1860,1861],{},"Hook",[368,1863,1864],{},"Where",[368,1866,513],{},[368,1868,1869],{},"Payload",[381,1871,1872,1892,1909,1928,1944,1965],{},[365,1873,1874,1879,1882,1887],{},[386,1875,1876],{},[166,1877,1878],{},"widgets:extend",[386,1880,1881],{},"Nuxt (build)",[386,1883,1884,1886],{},[166,1885,683],{}," registers widgets",[386,1888,1889],{},[166,1890,1891],{},"(area: string, widgets: RegisteredWidget[])",[365,1893,1894,1899,1901,1904],{},[386,1895,1896],{},[166,1897,1898],{},"widgets:resolved",[386,1900,1881],{},[386,1902,1903],{},"Once, after every module has set up",[386,1905,1906],{},[166,1907,1908],{},"(areas: Record\u003Cstring, RegisteredWidget[]>)",[365,1910,1911,1916,1918,1923],{},[386,1912,1913],{},[166,1914,1915],{},"tabs:extend",[386,1917,1881],{},[386,1919,1920,1922],{},[166,1921,686],{}," registers tabs",[386,1924,1925],{},[166,1926,1927],{},"(area: string, tabs: RegisteredTab[])",[365,1929,1930,1935,1937,1939],{},[386,1931,1932],{},[166,1933,1934],{},"tabs:resolved",[386,1936,1881],{},[386,1938,1903],{},[386,1940,1941],{},[166,1942,1943],{},"(areas: Record\u003Cstring, RegisteredTab[]>)",[365,1945,1946,1950,1953,1956],{},[386,1947,1948],{},[166,1949,1729],{},[386,1951,1952],{},"Nuxt app",[386,1954,1955],{},"An area's widgets are resolved, before rendering",[386,1957,1958,1961,1962],{},[166,1959,1960],{},"{ area: string, widgets: WidgetMeta[], context?: Record\u003Cstring, unknown> }","; reassign or filter ",[166,1963,1964],{},"ctx.widgets",[365,1966,1967,1972,1974,1977],{},[386,1968,1969],{},[166,1970,1971],{},"tabs:filter",[386,1973,1952],{},[386,1975,1976],{},"An area's tabs are resolved, before rendering",[386,1978,1979,1961,1982],{},[166,1980,1981],{},"{ area: string, tabs: TabMeta[], context?: Record\u003Cstring, unknown> }",[166,1983,1984],{},"ctx.tabs",[1986,1987,1988],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}",{"title":232,"searchDepth":261,"depth":261,"links":1990},[1991,1992,1993,2000],{"id":224,"depth":261,"text":225},{"id":344,"depth":261,"text":345},{"id":351,"depth":261,"text":352,"children":1994},[1995,1996,1997,1998,1999],{"id":356,"depth":289,"text":357},{"id":557,"depth":289,"text":558},{"id":676,"depth":289,"text":677},{"id":1598,"depth":289,"text":1599},{"id":1676,"depth":289,"text":1677},{"id":1851,"depth":261,"text":1852},"Named widget and tab areas - modules contribute widgets (\u003CWidgetArea>) and tabs (\u003CWidgetTabs>), a hook gates them.","md",null,{},{"title":137,"description":2001},"WZeQzXqG68eU1yF6YjiNF65quDEKpcjpuPnGMY4y4L4",[2008,2010],{"title":133,"path":134,"stem":135,"description":2009,"children":-1},"The user entity - the users table, staff administration and self-service profile, email and password changes.",{"title":141,"path":142,"stem":143,"description":2011,"children":-1},"Vue email templates for Notify, rendered with nuxt-email-renderer - typed sendEmailTemplate for the host, and module emails the host can override by file name.",1792824489902]