[{"data":1,"prerenderedAt":1236},["ShallowReactive",2],{"docs-navigation":3,"\u002Fdocs\u002Fdevelopment\u002Fsetup":231,"\u002Fdocs\u002Fdevelopment\u002Fsetup-surround":1231},[4],{"title":5,"path":6,"stem":7,"children":8},"Docs","\u002Fdocs","docs",[9,12,16,20,69,90,123,144,165,190],{"title":10,"path":6,"stem":11},"Gerbtrace Documentation","docs\u002Findex",{"title":13,"path":14,"stem":15},"Getting Started","\u002Fdocs\u002Fgetting-started","docs\u002F1.getting-started",{"title":17,"path":18,"stem":19},"Licensing","\u002Fdocs\u002Flicensing","docs\u002F2.licensing",{"title":21,"path":22,"stem":23,"children":24,"page":68},"Viewer","\u002Fdocs\u002Fviewer","docs\u002F3.viewer",[25,29,33,37,41,45,49,53,56,60,64],{"title":26,"path":27,"stem":28},"Files","\u002Fdocs\u002Fviewer\u002Ffiles","docs\u002F3.viewer\u002F01.files",{"title":30,"path":31,"stem":32},"PCB","\u002Fdocs\u002Fviewer\u002Fpcb","docs\u002F3.viewer\u002F02.pcb",{"title":34,"path":35,"stem":36},"Panel","\u002Fdocs\u002Fviewer\u002Fpanel","docs\u002F3.viewer\u002F03.panel",{"title":38,"path":39,"stem":40},"Paste","\u002Fdocs\u002Fviewer\u002Fpaste","docs\u002F3.viewer\u002F04.paste",{"title":42,"path":43,"stem":44},"SMD","\u002Fdocs\u002Fviewer\u002Fsmd","docs\u002F3.viewer\u002F05.smd",{"title":46,"path":47,"stem":48},"THT","\u002Fdocs\u002Fviewer\u002Ftht","docs\u002F3.viewer\u002F06.tht",{"title":50,"path":51,"stem":52},"BOM","\u002Fdocs\u002Fviewer\u002Fbom","docs\u002F3.viewer\u002F07.bom",{"title":5,"path":54,"stem":55},"\u002Fdocs\u002Fviewer\u002Fdocs","docs\u002F3.viewer\u002F08.docs",{"title":57,"path":58,"stem":59},"Conversation","\u002Fdocs\u002Fviewer\u002Fconversation","docs\u002F3.viewer\u002F09.conversation",{"title":61,"path":62,"stem":63},"Summary","\u002Fdocs\u002Fviewer\u002Fsummary","docs\u002F3.viewer\u002F10.summary",{"title":65,"path":66,"stem":67},"Pricing","\u002Fdocs\u002Fviewer\u002Fpricing","docs\u002F3.viewer\u002F11.pricing",false,{"title":70,"path":71,"stem":72,"children":73,"page":68},"Tools","\u002Fdocs\u002Ftools","docs\u002F4.tools",[74,78,82,86],{"title":75,"path":76,"stem":77},"Exports","\u002Fdocs\u002Ftools\u002Fexports","docs\u002F4.tools\u002F1.exports",{"title":79,"path":80,"stem":81},"Compare","\u002Fdocs\u002Ftools\u002Fcompare","docs\u002F4.tools\u002F2.compare",{"title":83,"path":84,"stem":85},"Package Manager","\u002Fdocs\u002Ftools\u002Fpackage-manager","docs\u002F4.tools\u002F3.package-manager",{"title":87,"path":88,"stem":89},"Draw Tool","\u002Fdocs\u002Ftools\u002Fdraw-tool","docs\u002F4.tools\u002F4.draw-tool",{"title":91,"path":92,"stem":93,"children":94,"page":68},"Collaboration","\u002Fdocs\u002Fcollaboration","docs\u002F5.collaboration",[95,99,103,107,111,115,119],{"title":96,"path":97,"stem":98},"Team Settings","\u002Fdocs\u002Fcollaboration\u002Fteam-settings","docs\u002F5.collaboration\u002F1.team-settings",{"title":100,"path":101,"stem":102},"Team Members","\u002Fdocs\u002Fcollaboration\u002Fteam-members","docs\u002F5.collaboration\u002F2.team-members",{"title":104,"path":105,"stem":106},"User Profile","\u002Fdocs\u002Fcollaboration\u002Fuser-profile","docs\u002F5.collaboration\u002F3.user-profile",{"title":108,"path":109,"stem":110},"Spaces","\u002Fdocs\u002Fcollaboration\u002Fspaces","docs\u002F5.collaboration\u002F4.spaces",{"title":112,"path":113,"stem":114},"Notifications","\u002Fdocs\u002Fcollaboration\u002Fnotifications","docs\u002F5.collaboration\u002F6.notifications",{"title":116,"path":117,"stem":118},"Plans & Billing","\u002Fdocs\u002Fcollaboration\u002Fplans-and-billing","docs\u002F5.collaboration\u002F7.plans-and-billing",{"title":120,"path":121,"stem":122},"Connected Apps & MCP","\u002Fdocs\u002Fcollaboration\u002Fconnected-apps","docs\u002F5.collaboration\u002F8.connected-apps",{"title":124,"path":125,"stem":126,"children":127,"page":68},"App","\u002Fdocs\u002Fapp","docs\u002F6.app",[128,132,136,140],{"title":129,"path":130,"stem":131},"Desktop App","\u002Fdocs\u002Fapp\u002Fdesktop","docs\u002F6.app\u002F1.desktop",{"title":133,"path":134,"stem":135},"Light & Dark Mode","\u002Fdocs\u002Fapp\u002Flight-dark-mode","docs\u002F6.app\u002F2.light-dark-mode",{"title":137,"path":138,"stem":139},"Performance Monitor","\u002Fdocs\u002Fapp\u002Fperformance-monitor","docs\u002F6.app\u002F3.performance-monitor",{"title":141,"path":142,"stem":143},"Report a Bug","\u002Fdocs\u002Fapp\u002Freport-a-bug","docs\u002F6.app\u002F4.report-a-bug",{"title":145,"path":146,"stem":147,"children":148,"page":68},"Guides","\u002Fdocs\u002Fguides","docs\u002F7.guides",[149,153,157,161],{"title":150,"path":151,"stem":152},"Importing Files","\u002Fdocs\u002Fguides\u002Fimporting-files","docs\u002F7.guides\u002F1.importing-files",{"title":154,"path":155,"stem":156},"Supported Formats","\u002Fdocs\u002Fguides\u002Fsupported-formats","docs\u002F7.guides\u002F2.supported-formats",{"title":158,"path":159,"stem":160},"Package Library","\u002Fdocs\u002Fguides\u002Fpackage-library","docs\u002F7.guides\u002F3.package-library",{"title":162,"path":163,"stem":164},"Panel Checks","\u002Fdocs\u002Fguides\u002Fpanel-checks","docs\u002F7.guides\u002F4.panel-checks",{"title":166,"path":167,"stem":168,"children":169,"page":68},"Reference","\u002Fdocs\u002Freference","docs\u002F8.reference",[170,174,178,182,186],{"title":171,"path":172,"stem":173},"BOM File Format","\u002Fdocs\u002Freference\u002Fbom-format","docs\u002F8.reference\u002F1.bom-format",{"title":175,"path":176,"stem":177},"Package Definitions","\u002Fdocs\u002Freference\u002Fpackage-definitions","docs\u002F8.reference\u002F2.package-definitions",{"title":179,"path":180,"stem":181},"Package Naming","\u002Fdocs\u002Freference\u002Fpackage-naming","docs\u002F8.reference\u002F3.package-naming",{"title":183,"path":184,"stem":185},"TPSys Format","\u002Fdocs\u002Freference\u002Ftpsys-format","docs\u002F8.reference\u002F4.tpsys-format",{"title":187,"path":188,"stem":189},"Jet Printing","\u002Fdocs\u002Freference\u002Fjet-printing","docs\u002F8.reference\u002F5.jet-printing",{"title":191,"path":192,"stem":193,"children":194,"page":68},"Development","\u002Fdocs\u002Fdevelopment","docs\u002F9.development",[195,199,203,207,211,215,219,223,227],{"title":196,"path":197,"stem":198},"Development Setup","\u002Fdocs\u002Fdevelopment\u002Fsetup","docs\u002F9.development\u002F1.setup",{"title":200,"path":201,"stem":202},"Architecture","\u002Fdocs\u002Fdevelopment\u002Farchitecture","docs\u002F9.development\u002F2.architecture",{"title":204,"path":205,"stem":206},"CAD Libraries","\u002Fdocs\u002Fdevelopment\u002Fcad-libraries","docs\u002F9.development\u002F3.cad-libraries",{"title":208,"path":209,"stem":210},"Release Process","\u002Fdocs\u002Fdevelopment\u002Frelease-process","docs\u002F9.development\u002F4.release-process",{"title":212,"path":213,"stem":214},"Error Monitoring","\u002Fdocs\u002Fdevelopment\u002Ferror-monitoring","docs\u002F9.development\u002F5.error-monitoring",{"title":216,"path":217,"stem":218},"Contributing","\u002Fdocs\u002Fdevelopment\u002Fcontributing","docs\u002F9.development\u002F6.contributing",{"title":220,"path":221,"stem":222},"Commit Conventions","\u002Fdocs\u002Fdevelopment\u002Fcommit-conventions","docs\u002F9.development\u002F7.commit-conventions",{"title":224,"path":225,"stem":226},"Sidebar Design","\u002Fdocs\u002Fdevelopment\u002Fsidebar-design","docs\u002F9.development\u002F8.sidebar-design",{"title":228,"path":229,"stem":230},"Operational Runbooks","\u002Fdocs\u002Fdevelopment\u002Frunbooks","docs\u002F9.development\u002F9.runbooks",{"id":232,"title":196,"body":233,"description":1225,"extension":1226,"links":1227,"meta":1228,"navigation":346,"path":197,"seo":1229,"stem":198,"__hash__":1230},"docs\u002Fdocs\u002F9.development\u002F1.setup.md",{"type":234,"value":235,"toc":1214},"minimark",[236,240,244,249,292,296,404,431,452,467,542,549,553,560,568,571,575,581,591,596,608,611,633,646,664,669,681,688,722,729,750,764,786,794,798,811,848,851,855,858,891,904,908,1051,1055,1061,1065,1210],[237,238,196],"h1",{"id":239},"development-setup",[241,242,243],"p",{},"This guide covers everything you need to start developing Gerbtrace locally.",[245,246,248],"h2",{"id":247},"prerequisites","Prerequisites",[250,251,252,272,284],"ul",{},[253,254,255,262,263,267,268,271],"li",{},[256,257,261],"a",{"href":258,"rel":259},"https:\u002F\u002Fnodejs.org",[260],"nofollow","Node.js"," 24.18.0 (LTS) — pinned via ",[264,265,266],"code",{},".nvmrc","; run ",[264,269,270],{},"nvm use"," in the repo root",[253,273,274,279,280,283],{},[256,275,278],{"href":276,"rel":277},"https:\u002F\u002Fpnpm.io",[260],"pnpm"," 10 or later (recommended via Corepack: ",[264,281,282],{},"corepack enable pnpm",")",[253,285,286,291],{},[256,287,290],{"href":288,"rel":289},"https:\u002F\u002Frustup.rs",[260],"Rust"," (only required for desktop app development)",[245,293,295],{"id":294},"getting-started","Getting started",[297,298,303],"pre",{"className":299,"code":300,"language":301,"meta":302,"style":302},"language-bash shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","# Clone the repository (with the package-renderer submodule)\ngit clone --recurse-submodules https:\u002F\u002Fgithub.com\u002Fnewmatik\u002Fgerbtrace.git\ncd gerbtrace\n\n# Select the pinned Node version from .nvmrc\nnvm use\n\n# Install dependencies\npnpm install\n\n# Start the web development server\npnpm run dev\n","bash","",[264,304,305,314,331,341,348,354,363,368,374,382,387,393],{"__ignoreMap":302},[306,307,310],"span",{"class":308,"line":309},"line",1,[306,311,313],{"class":312},"sHwdD","# Clone the repository (with the package-renderer submodule)\n",[306,315,317,321,325,328],{"class":308,"line":316},2,[306,318,320],{"class":319},"sBMFI","git",[306,322,324],{"class":323},"sfazB"," clone",[306,326,327],{"class":323}," --recurse-submodules",[306,329,330],{"class":323}," https:\u002F\u002Fgithub.com\u002Fnewmatik\u002Fgerbtrace.git\n",[306,332,334,338],{"class":308,"line":333},3,[306,335,337],{"class":336},"s2Zo4","cd",[306,339,340],{"class":323}," gerbtrace\n",[306,342,344],{"class":308,"line":343},4,[306,345,347],{"emptyLinePlaceholder":346},true,"\n",[306,349,351],{"class":308,"line":350},5,[306,352,353],{"class":312},"# Select the pinned Node version from .nvmrc\n",[306,355,357,360],{"class":308,"line":356},6,[306,358,359],{"class":319},"nvm",[306,361,362],{"class":323}," use\n",[306,364,366],{"class":308,"line":365},7,[306,367,347],{"emptyLinePlaceholder":346},[306,369,371],{"class":308,"line":370},8,[306,372,373],{"class":312},"# Install dependencies\n",[306,375,377,379],{"class":308,"line":376},9,[306,378,278],{"class":319},[306,380,381],{"class":323}," install\n",[306,383,385],{"class":308,"line":384},10,[306,386,347],{"emptyLinePlaceholder":346},[306,388,390],{"class":308,"line":389},11,[306,391,392],{"class":312},"# Start the web development server\n",[306,394,396,398,401],{"class":308,"line":395},12,[306,397,278],{"class":319},[306,399,400],{"class":323}," run",[306,402,403],{"class":323}," dev\n",[241,405,406,410,411,414,415,418,419,422,423,426,427,430],{},[407,408,409],"strong",{},"Submodule note:"," Gerbtrace vendors the ",[264,412,413],{},"package-renderer"," package as a git submodule. If you cloned without ",[264,416,417],{},"--recurse-submodules",", or you pulled changes that added or updated the submodule, initialize it ",[407,420,421],{},"before"," running ",[264,424,425],{},"pnpm install"," — otherwise typecheck, dev, and build fail with missing ",[264,428,429],{},"package-renderer\u002Fsrc\u002F*"," modules:",[297,432,434],{"className":299,"code":433,"language":301,"meta":302,"style":302},"git submodule update --init --recursive\n",[264,435,436],{"__ignoreMap":302},[306,437,438,440,443,446,449],{"class":308,"line":309},[306,439,320],{"class":319},[306,441,442],{"class":323}," submodule",[306,444,445],{"class":323}," update",[306,447,448],{"class":323}," --init",[306,450,451],{"class":323}," --recursive\n",[241,453,454,455,457,458,463,464,466],{},"If ",[264,456,278],{}," is not found, install ",[256,459,462],{"href":460,"rel":461},"https:\u002F\u002Fnodejs.org\u002Fapi\u002Fcorepack.html",[260],"Corepack"," and enable it, then run ",[264,465,425],{}," again:",[297,468,470],{"className":299,"code":469,"language":301,"meta":302,"style":302},"# Install corepack\nnpm install --global corepack@latest\n\n# Enable corepack\ncorepack enable pnpm\n\n# Install dependencies\npnpm install\n\n# Start the web development server again\npnpm run dev\n",[264,471,472,477,491,495,500,511,515,519,525,529,534],{"__ignoreMap":302},[306,473,474],{"class":308,"line":309},[306,475,476],{"class":312},"# Install corepack\n",[306,478,479,482,485,488],{"class":308,"line":316},[306,480,481],{"class":319},"npm",[306,483,484],{"class":323}," install",[306,486,487],{"class":323}," --global",[306,489,490],{"class":323}," corepack@latest\n",[306,492,493],{"class":308,"line":333},[306,494,347],{"emptyLinePlaceholder":346},[306,496,497],{"class":308,"line":343},[306,498,499],{"class":312},"# Enable corepack\n",[306,501,502,505,508],{"class":308,"line":350},[306,503,504],{"class":319},"corepack",[306,506,507],{"class":323}," enable",[306,509,510],{"class":323}," pnpm\n",[306,512,513],{"class":308,"line":356},[306,514,347],{"emptyLinePlaceholder":346},[306,516,517],{"class":308,"line":365},[306,518,373],{"class":312},[306,520,521,523],{"class":308,"line":370},[306,522,278],{"class":319},[306,524,381],{"class":323},[306,526,527],{"class":308,"line":376},[306,528,347],{"emptyLinePlaceholder":346},[306,530,531],{"class":308,"line":384},[306,532,533],{"class":312},"# Start the web development server again\n",[306,535,536,538,540],{"class":308,"line":389},[306,537,278],{"class":319},[306,539,400],{"class":323},[306,541,403],{"class":323},[241,543,544,545,548],{},"Visit ",[264,546,547],{},"http:\u002F\u002Flocalhost:3000"," in your browser.",[245,550,552],{"id":551},"environment-variables","Environment variables",[241,554,555,556,559],{},"Create a ",[264,557,558],{},".env"," file in the project root for Supabase connection:",[297,561,566],{"className":562,"code":564,"language":565},[563],"language-text","SUPABASE_URL=\u003Cyour-supabase-url>\nSUPABASE_ANON_KEY=\u003Cyour-supabase-anon-key>\n","text",[264,567,564],{"__ignoreMap":302},[241,569,570],{},"For local-only development (no team features), these can be omitted. Local projects use IndexedDB and do not require a backend.",[245,572,574],{"id":573},"local-supabase-development","Local Supabase development",[241,576,577,578,580],{},"You can run Supabase locally (Docker + CLI) and point the app at it via ",[264,579,558],{},".",[241,582,583,586,587,590],{},[407,584,585],{},"Prerequisites:"," Docker (required for ",[264,588,589],{},"supabase start","), Node\u002Fpnpm (already in the repo).",[241,592,593],{},[407,594,595],{},"Start local stack:",[297,597,599],{"className":299,"code":598,"language":301,"meta":302,"style":302},"pnpm supabase:start\n",[264,600,601],{"__ignoreMap":302},[306,602,603,605],{"class":308,"line":309},[306,604,278],{"class":319},[306,606,607],{"class":323}," supabase:start\n",[241,609,610],{},"The first run can take a few minutes while images are pulled.",[241,612,613,616,617,620,621,624,625,628,629,632],{},[407,614,615],{},"Get local keys:"," After start, the CLI prints ",[264,618,619],{},"API URL",", ",[264,622,623],{},"anon key",", and ",[264,626,627],{},"service_role key",". You can also run ",[264,630,631],{},"pnpm exec supabase status",". No project linking is needed for a purely local project.",[241,634,635,638,639,642,643,645],{},[407,636,637],{},"Configure the app:"," Copy ",[264,640,641],{},".env.example"," to ",[264,644,558],{}," and set:",[250,647,648,653,658],{},[253,649,650],{},[264,651,652],{},"SUPABASE_URL=http:\u002F\u002F127.0.0.1:54321",[253,654,655],{},[264,656,657],{},"SUPABASE_ANON_KEY=\u003Canon key from start\u002Fstatus>",[253,659,660,663],{},[264,661,662],{},"SUPABASE_SECRET_KEY=\u003Cservice_role key from start\u002Fstatus>"," (for server APIs and admin usage)",[241,665,666],{},[407,667,668],{},"Apply schema and seed:",[297,670,672],{"className":299,"code":671,"language":301,"meta":302,"style":302},"pnpm supabase:reset\n",[264,673,674],{"__ignoreMap":302},[306,675,676,678],{"class":308,"line":309},[306,677,278],{"class":319},[306,679,680],{"class":323}," supabase:reset\n",[241,682,683,684,687],{},"This applies all migrations and runs the seed. ",[264,685,686],{},"pnpm supabase:migrate"," pushes pending migrations to the local database without reseeding.",[241,689,690,693,694,697,698,701,702,705,706,709,710,705,713,715,716,705,719,721],{},[407,691,692],{},"Seed data:"," The seed creates test users, a team \"Gerbtrace Dev\" (slug ",[264,695,696],{},"gerbtrace-dev","), and a project \"Sample PCB\". Log in at ",[264,699,700],{},"\u002Fauth\u002Flogin"," with Email & Password: ",[264,703,704],{},"admin@gerbtrace.local"," \u002F ",[264,707,708],{},"Password123"," (team admin and platform admin), ",[264,711,712],{},"editor@gerbtrace.local",[264,714,708],{}," (editor), or ",[264,717,718],{},"viewer@gerbtrace.local",[264,720,708],{}," (viewer).",[241,723,724,725,728],{},"Platform-admin access is stored in ",[264,726,727],{},"profiles.is_super_admin","; it is independent of team roles and is never configured through an environment variable. Browser sessions cannot update this field. Grant or revoke it only through a trusted service-role or database operation after verifying the user UUID and environment.",[241,730,731,734,735,738,739,742,743,746,747,580],{},[407,732,733],{},"Run the app:"," ",[264,736,737],{},"pnpm run dev"," (or ",[264,740,741],{},"pnpm exec nuxt dev --no-fork","). Auth redirect is already ",[264,744,745],{},"http:\u002F\u002Flocalhost:3000\u002Fauth\u002Fcallback"," in ",[264,748,749],{},"supabase\u002Fconfig.toml",[241,751,752,755,756,759,760,763],{},[407,753,754],{},"Optional — Edge Functions:"," For flows that call Edge Functions (e.g. send-invitation, admin-team-action, stripe-checkout), run in a second terminal: ",[264,757,758],{},"pnpm exec supabase functions serve",". The app calls ",[264,761,762],{},"SUPABASE_URL\u002Ffunctions\u002Fv1\u002F\u003Cname>",", so with a local URL this hits the local functions server. Stripe-related functions need Stripe keys in env if you test billing; otherwise email\u002Fpassword and Magic Link work without them.",[241,765,766,769,770,773,774,746,777,779,780,782,783,580],{},[407,767,768],{},"Optional — GitHub OAuth (local):"," To test GitHub login locally, set ",[264,771,772],{},"GITHUB_CLIENT_ID"," and ",[264,775,776],{},"GITHUB_CLIENT_SECRET",[264,778,558],{},". ",[264,781,749],{}," already references them with ",[264,784,785],{},"env(...)",[241,787,788,734,791],{},[407,789,790],{},"Stop:",[264,792,793],{},"pnpm supabase:stop",[245,795,797],{"id":796},"desktop-development","Desktop development",[241,799,800,801,806,807,580],{},"The desktop app is built with ",[256,802,805],{"href":803,"rel":804},"https:\u002F\u002Fv2.tauri.app",[260],"Tauri 2",". Make sure Rust is installed via ",[256,808,810],{"href":288,"rel":809},[260],"rustup",[297,812,814],{"className":299,"code":813,"language":301,"meta":302,"style":302},"# Start Tauri development (launches native window with hot reload)\npnpm run tauri:dev\n\n# Build desktop app for your current platform\npnpm run tauri:build\n",[264,815,816,821,830,834,839],{"__ignoreMap":302},[306,817,818],{"class":308,"line":309},[306,819,820],{"class":312},"# Start Tauri development (launches native window with hot reload)\n",[306,822,823,825,827],{"class":308,"line":316},[306,824,278],{"class":319},[306,826,400],{"class":323},[306,828,829],{"class":323}," tauri:dev\n",[306,831,832],{"class":308,"line":333},[306,833,347],{"emptyLinePlaceholder":346},[306,835,836],{"class":308,"line":343},[306,837,838],{"class":312},"# Build desktop app for your current platform\n",[306,840,841,843,845],{"class":308,"line":350},[306,842,278],{"class":319},[306,844,400],{"class":323},[306,846,847],{"class":323}," tauri:build\n",[241,849,850],{},"Tauri development mode runs the Nuxt dev server and opens a native window pointing to it. Changes to Vue files hot-reload in the desktop window just like in the browser.",[245,852,854],{"id":853},"production-build","Production build",[241,856,857],{},"The web app is a Cloudflare Worker, not a static site:",[297,859,861],{"className":299,"code":860,"language":301,"meta":302,"style":302},"# Worker build (cloudflare-module preset) — what Cloudflare Workers Builds runs\npnpm run build\n# Build and deploy with wrangler (needs a Cloudflare API token for the Newmatik account)\npnpm run deploy\n",[264,862,863,868,877,882],{"__ignoreMap":302},[306,864,865],{"class":308,"line":309},[306,866,867],{"class":312},"# Worker build (cloudflare-module preset) — what Cloudflare Workers Builds runs\n",[306,869,870,872,874],{"class":308,"line":316},[306,871,278],{"class":319},[306,873,400],{"class":323},[306,875,876],{"class":323}," build\n",[306,878,879],{"class":308,"line":333},[306,880,881],{"class":312},"# Build and deploy with wrangler (needs a Cloudflare API token for the Newmatik account)\n",[306,883,884,886,888],{"class":308,"line":343},[306,885,278],{"class":319},[306,887,400],{"class":323},[306,889,890],{"class":323}," deploy\n",[241,892,893,896,897,900,901,903],{},[264,894,895],{},"pnpm run generate"," produces the static frontend in ",[264,898,899],{},".output\u002Fpublic\u002F"," for the Tauri desktop bundle only. See the ",[256,902,208],{"href":209}," for deployment authority and the release checklist.",[245,905,907],{"id":906},"tech-stack","Tech stack",[909,910,911,924],"table",{},[912,913,914],"thead",{},[915,916,917,921],"tr",{},[918,919,920],"th",{},"Component",[918,922,923],{},"Technology",[925,926,927,941,953,963,971,979,991,1003,1016,1028,1040],"tbody",{},[915,928,929,933],{},[930,931,932],"td",{},"Framework",[930,934,935,940],{},[256,936,939],{"href":937,"rel":938},"https:\u002F\u002Fnuxt.com",[260],"Nuxt 4"," (SPA mode, SSR disabled)",[915,942,943,946],{},[930,944,945],{},"UI Library",[930,947,948],{},[256,949,952],{"href":950,"rel":951},"https:\u002F\u002Fui.nuxt.com",[260],"Nuxt UI 4",[915,954,955,958],{},[930,956,957],{},"Desktop",[930,959,960],{},[256,961,805],{"href":803,"rel":962},[260],[915,964,965,968],{},[930,966,967],{},"Gerber Parsing",[930,969,970],{},"Custom RS-274X \u002F Excellon parser",[915,972,973,976],{},[930,974,975],{},"Rendering",[930,977,978],{},"Canvas 2D",[915,980,981,984],{},[930,982,983],{},"ZIP Handling",[930,985,986],{},[256,987,990],{"href":988,"rel":989},"https:\u002F\u002Fstuk.github.io\u002Fjszip\u002F",[260],"JSZip",[915,992,993,996],{},[930,994,995],{},"Text Diff",[930,997,998],{},[256,999,1002],{"href":1000,"rel":1001},"https:\u002F\u002Fgithub.com\u002Fkpdecker\u002Fjsdiff",[260],"diff",[915,1004,1005,1008],{},[930,1006,1007],{},"Local Storage",[930,1009,1010,1015],{},[256,1011,1014],{"href":1012,"rel":1013},"https:\u002F\u002Fdexie.org",[260],"Dexie.js"," (IndexedDB)",[915,1017,1018,1021],{},[930,1019,1020],{},"Excel Parsing",[930,1022,1023],{},[256,1024,1027],{"href":1025,"rel":1026},"https:\u002F\u002Fsheetjs.com\u002F",[260],"xlsx",[915,1029,1030,1033],{},[930,1031,1032],{},"Virtual Scrolling",[930,1034,1035],{},[256,1036,1039],{"href":1037,"rel":1038},"https:\u002F\u002Ftanstack.com\u002Fvirtual",[260],"@tanstack\u002Fvue-virtual",[915,1041,1042,1044],{},[930,1043,212],{},[930,1045,1046],{},[256,1047,1050],{"href":1048,"rel":1049},"https:\u002F\u002Fsentry.io",[260],"Sentry",[245,1052,1054],{"id":1053},"project-structure","Project structure",[297,1056,1059],{"className":1057,"code":1058,"language":565},[563],"gerbtrace\u002F\n  app\u002F                    # Nuxt app directory\n    components\u002F           # Vue components\n    composables\u002F          # Vue composables (state management)\n    pages\u002F                # Nuxt pages (routes)\n    utils\u002F                # Utility functions\n    workers\u002F              # Web Workers\n  lib\u002F                    # Core library code\n    gerber\u002F               # Gerber\u002Fdrill parser and plotter\n    renderer\u002F             # Canvas 2D and realistic renderers\n  package-renderer\u002F       # Component package\u002Ffootprint renderer (git submodule)\n  src-tauri\u002F              # Tauri desktop app (Rust)\n  supabase\u002F               # Database migrations and edge functions\n  content\u002F                # Nuxt Content documentation\n  public\u002F                 # Static assets (packages, samples)\n  scripts\u002F                # Build and maintenance scripts\n  .github\u002Fworkflows\u002F      # CI\u002FCD workflows\n",[264,1060,1058],{"__ignoreMap":302},[245,1062,1064],{"id":1063},"useful-commands","Useful commands",[909,1066,1067,1077],{},[912,1068,1069],{},[915,1070,1071,1074],{},[918,1072,1073],{},"Command",[918,1075,1076],{},"Description",[925,1078,1079,1091,1101,1110,1120,1130,1140,1150,1160,1170,1180,1190,1200],{},[915,1080,1081,1085],{},[930,1082,1083],{},[264,1084,737],{},[930,1086,1087,1088,1090],{},"Start web dev server (runs the pre-commit checks first; ",[264,1089,741],{}," skips them)",[915,1092,1093,1098],{},[930,1094,1095],{},[264,1096,1097],{},"pnpm run build",[930,1099,1100],{},"Production Worker build",[915,1102,1103,1107],{},[930,1104,1105],{},[264,1106,895],{},[930,1108,1109],{},"Static frontend for the desktop bundle",[915,1111,1112,1117],{},[930,1113,1114],{},[264,1115,1116],{},"pnpm run tauri:dev",[930,1118,1119],{},"Start desktop dev",[915,1121,1122,1127],{},[930,1123,1124],{},[264,1125,1126],{},"pnpm run tauri:build",[930,1128,1129],{},"Build desktop app",[915,1131,1132,1137],{},[930,1133,1134],{},[264,1135,1136],{},"pnpm run typecheck",[930,1138,1139],{},"Run TypeScript type checking",[915,1141,1142,1147],{},[930,1143,1144],{},[264,1145,1146],{},"pnpm run test",[930,1148,1149],{},"Run the Vitest suite",[915,1151,1152,1157],{},[930,1153,1154],{},[264,1155,1156],{},"pnpm run test:browser",[930,1158,1159],{},"Run the Playwright smoke suite",[915,1161,1162,1167],{},[930,1163,1164],{},[264,1165,1166],{},"pnpm run packages:manifest",[930,1168,1169],{},"Regenerate package library manifests",[915,1171,1172,1177],{},[930,1173,1174],{},[264,1175,1176],{},"pnpm run packages:check",[930,1178,1179],{},"Validate package library consistency",[915,1181,1182,1187],{},[930,1183,1184],{},[264,1185,1186],{},"pnpm run libraries:sync",[930,1188,1189],{},"Sync external CAD libraries",[915,1191,1192,1197],{},[930,1193,1194],{},[264,1195,1196],{},"pnpm run libraries:parse",[930,1198,1199],{},"Parse CAD libraries to SMD packages",[915,1201,1202,1207],{},[930,1203,1204],{},[264,1205,1206],{},"pnpm run libraries:parse:tht",[930,1208,1209],{},"Parse CAD libraries to THT packages",[1211,1212,1213],"style",{},"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 .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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);}",{"title":302,"searchDepth":333,"depth":316,"links":1215},[1216,1217,1218,1219,1220,1221,1222,1223,1224],{"id":247,"depth":316,"text":248},{"id":294,"depth":316,"text":295},{"id":551,"depth":316,"text":552},{"id":573,"depth":316,"text":574},{"id":796,"depth":316,"text":797},{"id":853,"depth":316,"text":854},{"id":906,"depth":316,"text":907},{"id":1053,"depth":316,"text":1054},{"id":1063,"depth":316,"text":1064},"Prerequisites, development server, desktop builds, and production builds.","md",null,{},{"title":196,"description":1225},"qIbGIjV5tfd4Zw3B_8cyQybWSLnwqWgpY-I4tDVggh4",[1232,1234],{"title":187,"path":188,"stem":189,"description":1233,"children":-1},"Technical overview of the Mycronic MY600 jet printer and the JPSys JSON program format.",{"title":200,"path":201,"stem":202,"description":1235,"children":-1},"System architecture, rendering pipeline, data flow, and high-level component overview.",1790998747589]