PageSourceSearch

https://farm-nightly.netlify.app/assets/js/187d724a.0c840ddd.js

js farm-nightly.netlify.app collected 2026-10-03 10:44:03 UTC 27,835 bytes, 1 lines download raw bytes

1"use strict";(self.webpackChunkfarm_docs=self.webpackChunkfarm_docs||[]).push([[919],{39608:(e,n,s)=>{s.r(n),s.d(n,{assets:()=>u,contentTitle:()=>a,default:()=>m,frontMatter:()=>c,metadata:()=>d,toc:()=>h});var r=s(49214),t=s(36906),o=s(87955),l=s(12790),i=s(71947);const c={},a="Writing JavaScript Plugins",d={id:"plugins/writing-plugins/js-plugin",title:"Writing JavaScript Plugins",description:"A JavaScript plugin is simply a pure JavaScript object that defines a set of property hooks:",source:"@site/docs/plugins/writing-plugins/js-plugin.mdx",sourceDirName:"plugins/writing-plugins",slug:"/plugins/writing-plugins/js-plugin",permalink:"/docs/plugins/writing-plugins/js-plugin",draft:!1,unlisted:!1,editUrl:"https://github.com/farm-fe/farm-fe.github.io/tree/main/docs/plugins/writing-plugins/js-plugin.mdx",tags:[],version:"current",frontMatter:{},sidebar:"pluginSidebar",previous:{title:"Writing Rust Plugins",permalink:"/docs/plugins/writing-plugins/rust-plugin"},next:{title:"Writing Runtime Plugin",permalink:"/docs/plugins/writing-plugins/runtime-plugin"}},u={},h=[{value:"Conventions",id:"conventions",level:2},{value:"Concepts",id:"concepts",level:2},{value:"Filters",id:"filters",level:3},{value:"Module Type",id:"module-type",level:3},{value:"Create Plugin",id:"create-plugin",level:2},{value:"Develop Plugin",id:"develop-plugin",level:2},{value:"Publish Plugin",id:"publish-plugin",level:2}];function p(e){const n={a:"a",admonition:"admonition",code:"code",h1:"h1",h2:"h2",h3:"h3",header:"header",li:"li",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,t.R)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.header,{children:(0,r.jsx)(n.h1,{id:"writing-javascript-plugins",children:"Writing JavaScript Plugins"})}),"\n",(0,r.jsx)(n.p,{children:"A JavaScript plugin is simply a pure JavaScript object that defines a set of property hooks:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-js",children:'// farm.config.ts\nimport { defineConfig } from "@farmfe/core";\n\nexport default defineConfig({\n  // ...\n  plugins: [\n    // a plugin object\n    {\n      name: "my-resolve-plugin",\n      priority: 1000, // the priority of this plugin, the larger the value, the earlier the execution. Normally internal plugins is 100.\n      resolve: {\n        filters: {\n          // Only execute the hook when following conditions satisfied\n          sources: ["\\\\./index.ts"], // a regex array\n          importers: ["None"],\n        },\n        executor: async (param) => {\n          // this hook executor\n          console.log(param); // resolve params\n          // return the resolve result\n          return {\n            resolvedPath: "virtual:my-module",\n            query: {},\n            sideEffects: false,\n            external: false,\n          };\n        },\n      },\n    },\n    // load, transform are similar to resolve, refer to their types\n  ],\n});\n'})}),"\n",(0,r.jsx)(n.p,{children:"If you want to pass args to your plugins\uff0cyou can use a closure."}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'// my-resolve-plugin.ts\nexport function myResolvePlugin(options: Options) {\n  const { xx } = options;\n\n  return {\n    name: "my-resolve-plugin",\n    resolve: {\n      // ...\n    },\n  };\n}\n\n// farm.config.ts\nimport { defineConfig } from "@farmfe/core";\nimport { myResolvePlugin } from "./myResolvePlugin.ts";\n\nexport default defineConfig({\n  // ...\n  plugins: [myResolvePlugin({ xx: "xx" })],\n});\n'})}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["See ",(0,r.jsx)(n.a,{href:"#create-plugin",children:"Create Plugin"})," to create a new plugin quickly based on official plugin templates."]}),"\n",(0,r.jsxs)(n.li,{children:["This document only covers how to create, develop and publish a js plugin, for more detail about the plugin hooks, see ",(0,r.jsx)(n.a,{href:"/docs/api/js-plugin-api",children:"Js Plugin Hooks"}),"."]}),"\n"]})}),"\n",(0,r.jsx)(n.h2,{id:"conventions",children:"Conventions"}),"\n",(0,r.jsx)(n.p,{children:"For farm specific js plugins:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:["The Farm Js plugin should have a name with a ",(0,r.jsx)(n.code,{children:"farm-plugin-"})," prefix and clear semantics."]}),"\n",(0,r.jsxs)(n.li,{children:["Include the ",(0,r.jsx)(n.code,{children:"farm-plugin-"})," keyword in package.json."]}),"\n"]}),"\n",(0,r.jsx)(n.p,{children:"If your plugin is only applicable to a specific framework, its name should follow the following prefix format:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"farm-plugin-vue-"}),": Prefix as a Vue plugin"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"farm-plugin-react-"}),": Prefix as a React plugin"]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.code,{children:"farm-plugin-svelte-"}
1),": Prefix as a svelte plugin"]}),"\n",(0,r.jsx)(n.li,{children:"..."}),"\n"]}),"\n",(0,r.jsx)(n.h2,{id:"concepts",children:"Concepts"}),"\n",(0,r.jsx)(n.p,{children:"Before you start to write your js plugin, you should know the following concepts:"}),"\n",(0,r.jsxs)(n.ul,{children:["\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"filters"}),": Cause Js Plugins are much slower than Rust Plugins, your js plugin need to set explicit filters to avoid unnecessary call for js plugins hook. For example, you should set ",(0,r.jsx)(n.code,{children:"transform.filters.moduleTypes = ['js']"})," to make sure that the transform hook of your js plugin only runs for ",(0,r.jsx)(n.code,{children:".js/mjs/cjs"})," files."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"module_type"}),": The type of the module, it can be ",(0,r.jsx)(n.code,{children:"js"}),", ",(0,r.jsx)(n.code,{children:"ts"}),", ",(0,r.jsx)(n.code,{children:"css"}),", ",(0,r.jsx)(n.code,{children:"sass"}),", ",(0,r.jsx)(n.code,{children:"json"}),", etc. Farm supports ",(0,r.jsx)(n.code,{children:"js/ts/jsx/tsx"}),", ",(0,r.jsx)(n.code,{children:"css"}),", ",(0,r.jsx)(n.code,{children:"html"}),", ",(0,r.jsx)(n.code,{children:"json"}),", ",(0,r.jsx)(n.code,{children:"static assets(png, svg, etc)"})," natively. ",(0,r.jsx)(n.code,{children:"module_type"})," is returned by ",(0,r.jsx)(n.code,{children:"load"})," hook or ",(0,r.jsx)(n.code,{children:"transform"})," hook."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"resolved_path and module_id"}),": ",(0,r.jsx)(n.code,{children:"resolved_path"})," is the absolute path of the module, and ",(0,r.jsx)(n.code,{children:"module_id"})," is the unique id of the module, it's usually ",(0,r.jsx)(n.code,{children:"relative path of the module from the project root"})," + ",(0,r.jsx)(n.code,{children:"query"}),". For example, we import a module as ",(0,r.jsx)(n.code,{children:"import './a?query'"}),", the resolved_path is ",(0,r.jsx)(n.code,{children:"/project/src/a.ts"})," and the module_id is ",(0,r.jsx)(n.code,{children:"src/a.ts?query"}),"."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"context"}),": All the hooks in the plugin accept a ",(0,r.jsx)(n.code,{children:"context"})," argument, it's the compilation context of the farm project, you can use it to get the ModuleGraph, Module, Resources, etc."]}),"\n",(0,r.jsxs)(n.li,{children:[(0,r.jsx)(n.strong,{children:"Resource and Resource Pot"}),": ",(0,r.jsx)(n.code,{children:"Resource"})," is the final output bundle file, and ",(0,r.jsx)(n.code,{children:"Resource Pot"})," is the abstract representation of the resource, similar to ",(0,r.jsx)(n.code,{children:"Chunk"})," of other bundlers. Inside Farm, first we will generate ",(0,r.jsx)(n.code,{children:"Resource Pots"})," from ",(0,r.jsx)(n.code,{children:"ModuleGraph"}),", render ",(0,r.jsx)(n.code,{children:"Resource Pots"})," and finally generate ",(0,r.jsx)(n.code,{children:"Resources"})," from ",(0,r.jsx)(n.code,{children:"Resource Pots"}),"."]}),"\n"]}),"\n",(0,r.jsx)(n.h3,{id:"filters",children:"Filters"}),"\n",(0,r.jsxs)(n.p,{children:["Cause ",(0,r.jsx)(n.code,{children:"Js Plugins"})," are much slower than ",(0,r.jsx)(n.code,{children:"Rust Plugins"}),", Farm use ",(0,r.jsx)(n.code,{children:"filters"})," to control the execution of js plugin hooks. The plugin hook executes only when given ",(0,r.jsx)(n.code,{children:"filters"})," matched to improve performance. ",(0,r.jsx)(n.code,{children:"filters"})," is neccessary for some commonly used hooks, such as ",(0,r.jsx)(n.code,{children:"resolve"}),", ",(0,r.jsx)(n.code,{children:"load"}),", ",(0,r.jsx)(n.code,{children:"transform"}),", etc."]}),"\n",(0,r.jsxs)(n.p,{children:["For example, if you want to transform css files, you can use ",(0,r.jsx)(n.code,{children:"transform.filters.moduleTypes = ['css']"})," to make sure that the transform hook of your js plugin only runs for ",(0,r.jsx)(n.code,{children:".css"})," files:"]}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:'const myCssPlugin = {\n  name: "my-css-plugin",\n  transform: {\n    filters: {\n      // Only execute the hook when following conditions satisfied\n      // resolvedPaths: ["\\\\./index.ts"], // a regex array to match the resolvedPaths\n      moduleTypes: ["css"],\n    },\n    executor: async (param) => {\n      // transform css\n    },\n  },\n};\n'})}),"\n",(0,r.jsx)(n.h3,{id:"module-type",children:"Module Type"}),"\n",(0,r.jsxs)(n.p,{children:["In Farm, every thing is ",(0,r.jsx)(n.code,{children:"First Class Citizens"}),", so Farm designs ",(0,r.jsx)(n.code,{children:"module_type"})," to identify the type of a module and handle different kinds of ModuleTypes in different plugins."]}),"\n",(0,r.jsxs)(n.p,{children:[(0,r.jsx)(n.code,{children:"module_type"})," returned by ",(0,r.jsx)(n.code,{children:"load"})," hook, and can be transformed by ",(0,r.jsx)(n.code,{children:"transform"})," hook. Farm supports ",(0,r.jsx)(n.code,{children:"js/ts/jsx/tsx"}),", ",(0,r.jsx)(n.code,{children:"css"}),", ",(0,r.jsx)(n.code,{children:"html"}),", ",(0,r.jsx)(n.code,{children:"json"}),", ",(0,r.jsx)(n.code,{children:"static assets(png, svg, etc)"})," natively. For these module types, you can return them directly in ",(0,r.jsx)(n.code,{children:"load"})," or ",(0,r.jsx)(n.code,{children:"transform"})," hook directly. But if you want to handle custom module types, you may 
1need to implement ohter hooks like ",(0,r.jsx)(n.code,{children:"parse"}),", ",(0,r.jsx)(n.code,{children:"render_resource_pot_modules"}),", ",(0,r.jsx)(n.code,{children:"generate resources"}),", etc to control how to parse, render and generate resources for the custom module types."]}),"\n",(0,r.jsx)(n.admonition,{type:"note",children:(0,r.jsxs)(n.p,{children:["Js Plugins don't support ",(0,r.jsx)(n.code,{children:"parse"}),", ",(0,r.jsx)(n.code,{children:"render_resource_pot_modules"}),", ",(0,r.jsx)(n.code,{children:"generate resources"})," hooks, you have to use Rust Plugins to handle custom module types."]})}),"\n",(0,r.jsx)(n.h2,{id:"create-plugin",children:"Create Plugin"}),"\n",(0,r.jsx)(n.p,{children:"Farm provides official templates to help your create your js plugins quickly:"}),"\n",(0,r.jsx)(r.Fragment,{children:(0,r.jsxs)(l.A,{children:[(0,r.jsx)(i.A,{value:"pnpm",label:"pnpm",children:(0,r.jsx)(o.A,{children:"pnpm create farm-plugin"})}),(0,r.jsx)(i.A,{value:"npm",label:"npm",children:(0,r.jsx)(o.A,{children:"npm create farm-plugin@latest"})}),(0,r.jsx)(i.A,{value:"yarn",label:"yarn",children:(0,r.jsx)(o.A,{children:"yarn create farm-plugin"})})]})}),"\n",(0,r.jsx)(n.p,{children:"then follow the prompts to create your plugin."}),"\n",(0,r.jsx)(n.p,{children:"or you can create a plugin derectly by running the following command:"}),"\n",(0,r.jsxs)(l.A,{children:[(0,r.jsx)(i.A,{value:"pnpm",label:"pnpm",children:(0,r.jsx)(o.A,{children:"pnpm create farm-plugin my-farm-plugin --type js"})}),(0,r.jsx)(i.A,{value:"npm",label:"npm",children:(0,r.jsx)(o.A,{children:"npm create my-farm-plugin --type js"})}),(0,r.jsx)(i.A,{value:"yarn",label:"yarn",children:(0,r.jsx)(o.A,{children:"yarn create my-farm-plugin --type js"})})]}),"\n",(0,r.jsxs)(n.p,{children:["Above command will create new js plugin with name ",(0,r.jsx)(n.code,{children:"my-farm-plugin"})," in the current directory. ",(0,r.jsx)(n.code,{children:"--type"})," can be ",(0,r.jsx)(n.code,{children:"rust"})," or ",(0,r.jsx)(n.code,{children:"js"})]}),"\n",(0,r.jsx)(n.h2,{id:"develop-plugin",children:"Develop Plugin"}),"\n",(0,r.jsx)(n.p,{children:"After creating the plugin, you can start to develop your plugin. The plugin is a pure JavaScript object that defines a set of property hooks:"}),"\n",(0,r.jsx)(n.pre,{children:(0,r.jsx)(n.code,{className:"language-ts",children:"// import { readFileSync } from 'node:fs';\nimport type { JsPlugin } from '@farmfe/core';\n\ninterface Options {\n  /* Your options here */\n}\n\nexport default function farmPlugin(options: Options): JsPlugin {\n  return {\n    name: '<FARM-JS-PLUGIN-NPM-NAME>',\n    /* Your plugin hooks here: */ \n\n    // transform: {\n    //   filters: {\n    //     moduleTypes: ['js']\n    //   },\n    //   async executor(params) {\n    //     const { content } = params;\n    //     return {\n    //       content,\n    //       moduleType: 'js'\n    //     };\n    //   }\n    // },\n    // finish: {\n    //   executor() {}\n    // }\n  };\n}\n"})}),"\n",(0,r.jsx)(n.admonition,{type:"tip",children:(0,r.jsxs)(n.p,{children:["For more detail about the plugin hooks, see ",(0,r.jsx)(n.a,{href:"/docs/api/js-plugin-api",children:"Js Plugin Hooks"}),"."]})}),"\n",(0,r.jsxs)(n.p,{children:["Run ",(0,r.jsx)(n.code,{children:"npm run dev"})," to compile the plugin and watch for changes. Run ",(0,r.jsx)(n.code,{children:"npm run build"})," to build the plugin."]}),"\n",(0,r.jsx)(n.h2,{id:"publish-plugin",children:"Publish Plugin"}),"\n",(0,r.jsxs)(n.p,{children:["A js plugin package is a normal npm package, you can publish it to npm registry by running ",(0,r.jsx)(n.code,{children:"npm publish"}),"."]})]})}function m(e={}){const{wrapper:n}={...(0,t.R)(),...e.components};return n?(0,r.jsx)(n,{...e,children:(0,r.jsx)(p,{...e})}):p(e)}},87955:(e,n,s)=>{s.d(n,{A:()=>a});var r=s(48318);const t={"shiki-wrapper":"shiki-wrapper_eFVS","code-header":"code-header_obPU","code-title":"code-title_n3kD","copy-button":"copy-button_MpeX","copy-icon":"copy-icon_DvHB",popIn:"popIn_sXIp","copy-success":"copy-success_xuS0"};var o=s(70251),l=s(21970);const i=[{name:"ts",content:'<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="#3178C6" d="M20 0h216c11.046 0 20 8.954 20 20v216c0 11.046-8.954 20-20 20H20c-11.046 0-20-8.954-20-20V20C0 8.954 8.954 0 20 0Z"/><path fill="#FFF" d="M150.518 200.475v27.62c4.492 2.302 9.805 4.028 15.938 5.179c6.133 1.151 12.597 1.726 19.393 1.726c6.622 0 12.914-.633 18.874-1.899c5.96-1.266 11.187-3.352 15.678-6.257c4.492-2.906 8.048-6.704 10.669-11.394c2.62-4.689 3.93-10.486 3.93-17.391c0-5.006-.749-9.394-2.246-13.163a30.748 30.748 0 0 0-6.479-10.055c-2.821-2.935-6.205-5.567-10.149-7.898c-3.945-2.33-8.394-4.531-13.347-6.
1602c-3.628-1.497-6.881-2.949-9.761-4.359c-2.879-1.41-5.327-2.848-7.342-4.316c-2.016-1.467-3.571-3.021-4.665-4.661c-1.094-1.64-1.641-3.495-1.641-5.567c0-1.899.489-3.61 1.468-5.135s2.362-2.834 4.147-3.927c1.785-1.094 3.973-1.942 6.565-2.547c2.591-.604 5.471-.906 8.638-.906c2.304 0 4.737.173 7.299.518c2.563.345 5.14.877 7.732 1.597a53.669 53.669 0 0 1 7.558 2.719a41.7 41.7 0 0 1 6.781 3.797v-25.807c-4.204-1.611-8.797-2.805-13.778-3.582c-4.981-.777-10.697-1.165-17.147-1.165c-6.565 0-12.784.705-18.658 2.115c-5.874 1.409-11.043 3.61-15.506 6.602c-4.463 2.993-7.99 6.805-10.582 11.437c-2.591 4.632-3.887 10.17-3.887 16.615c0 8.228 2.375 15.248 7.127 21.06c4.751 5.811 11.963 10.731 21.638 14.759a291.458 291.458 0 0 1 10.625 4.575c3.283 1.496 6.119 3.049 8.509 4.66c2.39 1.611 4.276 3.366 5.658 5.265c1.382 1.899 2.073 4.057 2.073 6.474a9.901 9.901 0 0 1-1.296 4.963c-.863 1.524-2.174 2.848-3.93 3.97c-1.756 1.122-3.945 1.999-6.565 2.632c-2.62.633-5.687.95-9.2.95c-5.989 0-11.92-1.05-17.794-3.151c-5.875-2.1-11.317-5.25-16.327-9.451Zm-46.036-68.733H140V109H41v22.742h35.345V233h28.137V131.742Z"/></svg>'},{name:"js",content:'<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 256 256"><path fill="#F7DF1E" d="M0 0h256v256H0V0Z"/><path d="m67.312 213.932l19.59-11.856c3.78 6.701 7.218 12.371 15.465 12.371c7.905 0 12.89-3.092 12.89-15.12v-81.798h24.057v82.138c0 24.917-14.606 36.259-35.916 36.259c-19.245 0-30.416-9.967-36.087-21.996m85.07-2.576l19.588-11.341c5.157 8.421 11.859 14.607 23.715 14.607c9.969 0 16.325-4.984 16.325-11.858c0-8.248-6.53-11.17-17.528-15.98l-6.013-2.58c-17.357-7.387-28.87-16.667-28.87-36.257c0-18.044 13.747-31.792 35.228-31.792c15.294 0 26.292 5.328 34.196 19.247l-18.732 12.03c-4.125-7.389-8.591-10.31-15.465-10.31c-7.046 0-11.514 4.468-11.514 10.31c0 7.217 4.468 10.14 14.778 14.608l6.014 2.577c20.45 8.765 31.963 17.7 31.963 37.804c0 21.654-17.012 33.51-39.867 33.51c-22.339 0-36.774-10.654-43.819-24.574"/></svg>'},{name:"css",content:'<svg xmlns="http://www.w3.org/2000/svg" width="29.37" height="32" viewBox="0 0 256 279"><defs><linearGradient id="logosWindiCss0" x1="16.639%" x2="137.275%" y1="36.186%" y2="175.371%"><stop offset="7.822%" stop-color="#54C8F1"/><stop offset="57.292%" stop-color="#41A2EF"/><stop offset="100%" stop-color="#3386EE"/></linearGradient><linearGradient id="logosWindiCss1" x1="-22.099%" x2="91.451%" y1="-49.621%" y2="73.695%"><stop offset="7.822%" stop-color="#54C8F1"/><stop offset="57.292%" stop-color="#41A2EF"/><stop offset="100%" stop-color="#3386EE"/></linearGradient><linearGradient id="logosWindiCss2" x1="8.696%" x2="71.739%" y1="37.461%" y2="80.271%"><stop offset="7.822%" stop-color="#54C8F1"/><stop offset="57.292%" stop-color="#41A2EF"/><stop offset="100%" stop-color="#3386EE"/></linearGradient><linearGradient id="logosWindiCss3" x1="60.744%" x2="501.135%" y1="-308.636%" y2="225.788%"><stop offset="7.822%" stop-color="#54C8F1"/><stop offset="57.292%" stop-color="#41A2EF"/><stop offset="100%" stop-color="#3386EE"/></linearGradient></defs><path fill="url(#logosWindiCss0)" d="M133.784 48.922C133.784 21.945 111.84 0 84.863 0c-28.43 0-45.428 21.316-45.428 41.933h27.956c0-5.8 5.423-13.978 17.472-13.978c11.56 0 20.966 9.407 20.966 20.967c0 11.56-8.438 20.966-29.715 20.966H0v27.955h76.114c35.911 0 57.67-21.944 57.67-48.921Zm0 0C133.784 21.945 111.84 0 84.863 0c-28.43 0-45.428 21.316-45.428 41.933h27.956c0-5.8 5.423-13.978 17.472-13.978c11.56 0 20.966 9.407 20.966 20.967c0 11.56-8.438 20.966-29.715 20.966H0v27.955h76.114c35.911 0 57.67-21.944 57.67-48.921Z"/><path fill="url(#logosWindiCss1)" d="M195.803 229.339c0 26.978-21.945 48.922-48.922 48.922c-28.43 0-45.427-21.315-45.427-41.933h27.955c0 5.8 5.423 13.979 17.472 13.979c11.56 0 20.967-9.408 20.967-20.968s-10.63-20.966-29.716-20.966H53.671v-27.956h84.461c35.912 0 57.671 21.945 57.671 48.922Zm0 0c0 26.978-21.945 48.922-48.922 48.922c-28.43 0-45.427-21.315-45.427-41.933h27.955c0 5.8 5.423 13.979 17.472 13.979c11.56 0 20.967-9.408 20.967-20.968s-10.63-20.966-29.716-20.966H53.671v-27.956h84.461c35.912 0 57.671 21.945 57.671 48.922Z"/><path fill="url(#logosWindiCss2)" d="M203.13 43.13c-30.834 0-52.585 23.45-52.585 54.284h24.76c0-15.327 11.13-26.457 27.825-26.457c16.696 0 25.044 11.13 25.044 26.457s-10.842 27.955-40.348 27.955H0v27.956h192c43.695 0 64-28.085 64-55.911c0-30.835-20.87-54.284-52.87-54.284Z"/><path fill="url(#logosWindiCss3)" d="M36.647 180.417H0v28.19h36.647z"/></svg>'},{name:"json",content:'<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 16 16"><path fill="none" stroke="#eed49f" stroke-linecap="round" stroke-linejoin="round" d="M4.5 2.5H4c-.75 0-1.5.75-1.5 1.5v2c0 1.1-1 2-1.83 2c.83 0 1.83.9 1.83 2v2c0 .75.75 1.5 1.5 1.5h.5m7-11h.5c.75 0 1.5.75 1.5 1.5v2c0 1.1 1 2 1.83 2c-.83 0-1.83.9-1.83 2v2c0 .74-.75 1.5-1.5 1.5h-.5m-6.5-3a.5.5 0 1 0 0-1a.5.5 0 0 0 0 1m3 0a.5.5 0 1 0 0-1a.5.5 0 0 0 0 1m3 0a.5.5 0 1 0 0-1a.5.5 0 0 0 0 1"/></svg>'},{name:"text",content:'<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 48 48"><g fill="none" stroke-width="4"><path fill="#2F88FF" stroke="#000" stroke-linejoin="round" d="M10 4H30L40 14V42C40 43.1046 39.1046 44 38 44H10C8.89543 44 8 43.1046 8 42V6C8 4.89543 8.89543 4 10 4Z"/><path stroke="#fff" stroke-linecap="round" d="M18 18.0083H30"/><path stroke="#fff" stroke-linecap="round" d="M24.0083 18.0083V34"/></g></svg>'},{name:"vue",content:'<svg xmlns="http://www.w3.org/2000/svg" width="37.07" height="32" viewBox="0 0 256 221"><path fill="#41B883" d="M204.8 0H256L128 220.8L0 0h97.92L128 51.2L157.44 
10h47.36Z"/><path fill="#41B883" d="m0 0l128 220.8L256 0h-51.2L128 132.48L50.56 0H0Z"/><path fill="#35495E" d="M50.56 0L128 133.12L204.8 0h-47.36L128 51.2L97.92 0H50.56Z"/></svg>'}];var c=s(49214);function a(e){const[n,s]=(0,r.useState)(""),[a,d]=(0,r.useState)(!1),u=e.className?e.className.replace(/language-/,""):"javascript",h=e.metastring?e.metastring.match(/title="([^"]+)"/):null,p=h?h[1]:null,m=e.metastring?e.metastring.match(/{([\d,-]+)}/):null,{colorMode:f}=(0,l.G)(),g={ts:i.find((e=>"ts"===e.name))?.content,js:i.find((e=>"js"===e.name))?.content,css:i.find((e=>"css"===e.name))?.content,json:i.find((e=>"json"===e.name))?.content,txt:i.find((e=>"text"===e.name))?.content,vue:i.find((e=>"vue"===e.name))?.content},x=(e,n)=>(0,c.jsx)("span",{className:n,dangerouslySetInnerHTML:{__html:e}});(0,r.useEffect)((()=>{(async()=>{let n=[];m&&(n=m[1].split(",").flatMap((e=>{const[n,s]=e.split("-").map(Number);return s?Array.from({length:s-n+1},((e,s)=>n+s)):[n]})));const r=await(0,o.Yz)(e.children,{lang:u,theme:"dark"===f?"vitesse-dark":"vitesse-light",transformers:[{name:"line-highlight",code(e){let s=0;return e.children.forEach((e=>{"element"===e.type&&"span"===e.tagName&&"line"===e.properties.class&&(s++,n.includes(s)&&(e.properties.class="line highlighted-line"))})),e}}]});s(r)})()}),[e.children,f,u,m]);return(0,c.jsx)(c.Fragment,{children:(0,c.jsxs)("div",{className:t["shiki-wrapper"],children:[(0,c.jsxs)("div",{className:t["code-header"],children:[p&&(0,c.jsxs)("div",{className:t["code-title"],children:[(e=>{if(!e)return null;const n=e.split(".").pop().toLowerCase(),s=g[n];return s?x(s,t["file-icon"]):null})(p),p]}),(0,c.jsx)("button",{className:t["copy-button"],onClick:()=>{navigator.clipboard.writeText(e.children).then((()=>{d(!0),setTimeout((()=>d(!1)),2e3)}))},children:a?(0,c.jsx)("svg",{className:`${t["copy-icon"]} ${t["copy-success"]}`,viewBox:"0 0 24 24",children:(0,c.jsx)("path",{d:"M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41L9 16.17z"})}):(0,c.jsx)("svg",{className:t["copy-icon"],viewBox:"0 0 24 24",children:(0,c.jsx)("path",{d:"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12V1zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2zm0 16H8V7h11v14z"})})})]}),(0,c.jsx)("div",{className:t["code-content"],dangerouslySetInnerHTML:{__html:n}})]})})}},71947:(e,n,s)=>{s.d(n,{A:()=>l});s(48318);var r=s(23372);const t={tabItem:"tabItem_Q1qS"};var o=s(49214);function l(e){let{children:n,hidden:s,className:l}=e;return(0,o.jsx)("div",{role:"tabpanel",className:(0,r.A)(t.tabItem,l),hidden:s,children:n})}},12790:(e,n,s)=>{s.d(n,{A:()=>w});var r=s(48318),t=s(23372),o=s(52521),l=s(66325),i=s(97478),c=s(37202),a=s(42587),d=s(7152);function u(e){return r.Children.toArray(e).filter((e=>"\n"!==e)).map((e=>{if(!e||(0,r.isValidElement)(e)&&function(e){const{props:n}=e;return!!n&&"object"==typeof n&&"value"in n}(e))return e;throw new Error(`Docusaurus error: Bad <Tabs> child <${"string"==typeof e.type?e.type:e.type.name}>: all children of the <Tabs> component should be <TabItem>, and every <TabItem> should have a unique "value" prop.`)}))?.filter(Boolean)??[]}function h(e){const{values:n,children:s}=e;return(0,r.useMemo)((()=>{const e=n??function(e){return u(e).map((e=>{let{props:{value:n,label:s,attributes:r,default:t}}=e;return{value:n,label:s,attributes:r,default:t}}))}(s);return function(e){const n=(0,a.XI)(e,((e,n)=>e.value===n.value));if(n.length>0)throw new Error(`Docusaurus error: Duplicate values "${n.map((e=>e.value)).join(", ")}" found in <Tabs>. Every value needs to be unique.`)}(e),e}),[n,s])}function p(e){let{value:n,tabValues:s}=e;return s.some((e=>e.value===n))}function m(e){let{queryString:n=!1,groupId:s}=e;const t=(0,l.W6)(),o=function(e){let{queryString:n=!1,groupId:s}=e;if("string"==typeof n)return n;if(!1===n)return null;if(!0===n&&!s)throw new Error('Docusaurus error: The <Tabs> component groupId prop is required if queryString=true, because this value is used as the search param name. You can also provide an explicit value such as queryString="my-search-param".');return s??null}({queryString:n,groupId:s});return[(0,c.aZ)(o),(0,r.useCallback)((e=>{if(!o)return;const n=new URLSearchParams(t.location.search);n.set(o,e),t.replace({...t.location,search:n.toString()})}),[o,t])]}function f(e){const{defaultValue:n,queryString:s=!1,groupId:t}=e,o=h(e),[l,c]=(0,r.useState)((()=>function(e){let{defaultValue:n,tabValues:s}=e;if(0===s.length)throw new Error("Docusaurus error: the <Tabs> component requires at least one <TabItem> children component");if(n){if(!p({value:n,tabValues:s}))throw new Error(`Docusaurus error: The <Tabs> has a defaultValue "${n}" but none of its children has the corresponding value. Available values are: ${s.map((e=>e.value)).join(", ")}. If you intend to show no default tab, use defaultValue={null} instead.`);return n}const r=s.find((e=>e.default))??s[0];if(!r)throw new Error("Unexpected error: 0 tabValues");return r.value}({defaultValue:n,tabValues:o}))),[a,u]=m({queryString:s,groupId:t}),[f,g]=function(e){let{groupId:n}=e;const s=function(e){return e?`docusaurus.tab.${e}`:null}(n),[t,o]=(0,d.Dv)(s);return[t,(0,r.useCallback)((e=>{s&&o.set(e)}),[s,o])]}({groupId:t}),x=(()=>{const e=a??f;return p({value:e,tabValues:o})?e:null})();(0,i.A)((()=>{x&&c(x)}),[x]);return{selectedValue:l,selectValue:(0,r.useCallback)((e=>{if(!p({value:e,tabValues:o}))throw new Error(`Can't select invalid tab value=${e}`);c(e),u(e),g(e)}),[u,g,o]),tabValues:o}}var g=s(3662);const x={tabList:"tabList_vzF7",tabItem:"tabItem_gx_e"};var j=s(49214);function v(e){let{className:n,block:s,selectedValue:r,selectValue:l,tabValues:i}=e;const c=[],{blockElementScrollPositionUntilNextRender:a}=(0,o.a_)(),d=e=>{const n=e.currentTarget,s=c.indexOf(n),t=i[s].value;t!==r&&(a(n),l(t))},u=e=>{let n=null;switch(e.key){case"Enter":d(e);break;case"ArrowRight":{const s=c.indexOf(e.currentTarget)+1;n=c[s]??c[0];break}case"ArrowLeft":{const s=c.indexOf(e.currentTarget)-1;n=c[s]??c[c.length-1];break}}n?.focus()};return(0,j.jsx)("ul",{role:"tablist","aria-orientation":"horizontal",className:(0,t.A)("tabs",{"tabs--block":s},n),children:i.map((e=>{let{value:n,label:s,attributes:o}=e;return(0,j.jsx)("li",{role:"tab",tabIndex:r===n?0:-1,"aria-selected":r===n,ref:e=>c.push(e),onKeyDown:u,onClick:d,...o,className:(0,t.A)("tabs__item",x.tabItem,o?.className,{"tabs__item--active":r===n}),children:s??n},n)}))})}function y(e){let{lazy:n,children:s,selectedValue:o}=e;
1const l=(Array.isArray(s)?s:[s]).filter(Boolean);if(n){const e=l.find((e=>e.props.value===o));return e?(0,r.cloneElement)(e,{className:(0,t.A)("margin-top--md",e.props.className)}):null}return(0,j.jsx)("div",{className:"margin-top--md",children:l.map(((e,n)=>(0,r.cloneElement)(e,{key:n,hidden:e.props.value!==o})))})}function b(e){const n=f(e);return(0,j.jsxs)("div",{className:(0,t.A)("tabs-container",x.tabList),children:[(0,j.jsx)(v,{...n,...e}),(0,j.jsx)(y,{...n,...e})]})}function w(e){const n=(0,g.A)();return(0,j.jsx)(b,{...e,children:u(e.children)},String(n))}}}]);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.