diff --git a/404.html b/404.html index 2057579..ad0499c 100644 --- a/404.html +++ b/404.html @@ -4,13 +4,13 @@ Page Not Found | UF OSC Docs - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/CNAME b/CNAME deleted file mode 100644 index 51b79d0..0000000 --- a/CNAME +++ /dev/null @@ -1 +0,0 @@ -docs.ufosc.org \ No newline at end of file diff --git a/assets/js/12000fc4.67f35f03.js b/assets/js/12000fc4.6f7d552a.js similarity index 51% rename from assets/js/12000fc4.67f35f03.js rename to assets/js/12000fc4.6f7d552a.js index b9ae7ab..0345474 100644 --- a/assets/js/12000fc4.67f35f03.js +++ b/assets/js/12000fc4.6f7d552a.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[4212],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>b});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=c(e.components);return r.createElement(l.Provider,{value:n},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=c(t),d=a,b=m["".concat(l,".").concat(d)]||m[d]||u[d]||i;return t?r.createElement(b,s(s({ref:n},p),{},{components:t})):r.createElement(b,s({ref:n},p))}));function b(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,s=new Array(i);s[0]=d;var o={};for(var l in n)hasOwnProperty.call(n,l)&&(o[l]=n[l]);o.originalType=e,o[m]="string"==typeof e?e:a,s[1]=o;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=t(7462),a=(t(7294),t(3905));const i={title:"Rendering Pages",description:"Club Website Rendering Pages",sidebar_position:3},s="Rendering Pages",o={unversionedId:"Developers/rendering",id:"Developers/rendering",title:"Rendering Pages",description:"Club Website Rendering Pages",source:"@site/docs/website/Developers/rendering.md",sourceDirName:"Developers",slug:"/Developers/rendering",permalink:"/docs/website/Developers/rendering",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/rendering.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Rendering Pages",description:"Club Website Rendering Pages",sidebar_position:3},sidebar:"defaultSidebar",previous:{title:"Usage & Configuration",permalink:"/docs/website/Developers/configuration"},next:{title:"Using MongoDB",permalink:"/docs/website/Developers/Databases/mongodb"}},l={},c=[{value:"EJS Basics",id:"ejs-basics",level:2},{value:"Website Views & Components",id:"website-views--components",level:2}],p={toc:c},m="wrapper";function u(e){let{components:n,...t}=e;return(0,a.kt)(m,(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"rendering-pages"},"Rendering Pages"),(0,a.kt)("p",null,'The OSC website uses EJS to dynamically render HTML pages. EJS stands for "embedded JavaScript templates," and allows developers to write HTML with JavaScript code that gets executed prior to the user\'s request. It is simillar to PHP in the sense that the server will process the file, replace each EJS JavaScript template with HTML, and ultimately return an HTML page.'),(0,a.kt)("p",null,"For documentation on EJS, see ",(0,a.kt)("a",{parentName:"p",href:"https://ejs.co/"},"EJS"),"."),(0,a.kt)("h2",{id:"ejs-basics"},"EJS Basics"),(0,a.kt)("p",null,"EJS files accept standard HTML, with the exception of certain tags which will accept server-side JavaScript. For example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html",metastring:'title="myEJSTemplate.ejs"',title:'"myEJSTemplate.ejs"'},"

My H1 HTML Title

\n\n\x3c!-- This will be replaced by a single value. --\x3e\n<%= myVariable %>\n\n\x3c!-- This will be replaced by the outcome of the executed code --\x3e\n<% if (myVariable2) { %>\n

<%= myVariable3 %>

\n<% } %>\n")),(0,a.kt)("p",null,"The template may then be renderred by the following JavaScript code:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"const express = require('express')\nconst app = express()\n\napp.set('view engine', 'ejs')\n\napp.get('/', (req, res) => {\n return res.render('myEJSTemplate', {\n myVariable: \"value 1\",\n myVariable2: \"value 2\",\n myVariable3: \"value 3\"\n })\n})\n")),(0,a.kt)("h2",{id:"website-views--components"},"Website Views & Components"),(0,a.kt)("p",null,"The OSC website organizes EJS templates into two categories: views (which are usually entire pages/sites) and components (standalone HTML templates used alongside views). All of the source code's views are stored in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/tree/main/views"},"/views"),", and all components in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/tree/main/views/components"},"/views/components"),"."),(0,a.kt)("p",null,"An example of a reusable component is the navigation bar:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html",metastring:'title="views/components/navbar.ejs"',title:'"views/components/navbar.ejs"'},'\n')),(0,a.kt)("p",null,"The navbar does not take in any EJS parameters, but it can be imported by other views. For example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html"},"\n\n\n \x3c!-- The navbar will be loaded and placed here. --\x3e\n <%- include('./components/navbar.ejs') %>\n\n

My other content...

\n\n\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[4212],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>b});var r=t(7294);function a(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function i(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);n&&(r=r.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,r)}return t}function s(e){for(var n=1;n=0||(a[t]=e[t]);return a}(e,n);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(a[t]=e[t])}return a}var l=r.createContext({}),c=function(e){var n=r.useContext(l),t=n;return e&&(t="function"==typeof e?e(n):s(s({},n),e)),t},p=function(e){var n=c(e.components);return r.createElement(l.Provider,{value:n},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return r.createElement(r.Fragment,{},n)}},d=r.forwardRef((function(e,n){var t=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),m=c(t),d=a,b=m["".concat(l,".").concat(d)]||m[d]||u[d]||i;return t?r.createElement(b,s(s({ref:n},p),{},{components:t})):r.createElement(b,s({ref:n},p))}));function b(e,n){var t=arguments,a=n&&n.mdxType;if("string"==typeof e||a){var i=t.length,s=new Array(i);s[0]=d;var o={};for(var l in n)hasOwnProperty.call(n,l)&&(o[l]=n[l]);o.originalType=e,o[m]="string"==typeof e?e:a,s[1]=o;for(var c=2;c{t.r(n),t.d(n,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>c});var r=t(7462),a=(t(7294),t(3905));const i={title:"Rendering Pages",description:"Club Website Rendering Pages",sidebar_position:3},s="Rendering Pages",o={unversionedId:"Developers/rendering",id:"Developers/rendering",title:"Rendering Pages",description:"Club Website Rendering Pages",source:"@site/docs/website/Developers/rendering.md",sourceDirName:"Developers",slug:"/Developers/rendering",permalink:"/docs/website/Developers/rendering",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/rendering.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Rendering Pages",description:"Club Website Rendering Pages",sidebar_position:3},sidebar:"defaultSidebar",previous:{title:"Usage & Configuration",permalink:"/docs/website/Developers/configuration"},next:{title:"Using MongoDB",permalink:"/docs/website/Developers/Databases/mongodb"}},l={},c=[{value:"EJS Basics",id:"ejs-basics",level:2},{value:"Website Views & Components",id:"website-views--components",level:2}],p={toc:c},m="wrapper";function u(e){let{components:n,...t}=e;return(0,a.kt)(m,(0,r.Z)({},p,t,{components:n,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"rendering-pages"},"Rendering Pages"),(0,a.kt)("p",null,'The OSC website uses EJS to dynamically render HTML pages. EJS stands for "embedded JavaScript templates," and allows developers to write HTML with JavaScript code that gets executed prior to the user\'s request. It is similar to PHP in the sense that the server will process the file, replace each EJS JavaScript template with HTML, and ultimately return an HTML page.'),(0,a.kt)("p",null,"For documentation on EJS, see ",(0,a.kt)("a",{parentName:"p",href:"https://ejs.co/"},"EJS"),"."),(0,a.kt)("h2",{id:"ejs-basics"},"EJS Basics"),(0,a.kt)("p",null,"EJS files accept standard HTML, with the exception of certain tags which will accept server-side JavaScript. For example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html",metastring:'title="myEJSTemplate.ejs"',title:'"myEJSTemplate.ejs"'},"

My H1 HTML Title

\n\n\x3c!-- This will be replaced by a single value. --\x3e\n<%= myVariable %>\n\n\x3c!-- This will be replaced by the outcome of the executed code --\x3e\n<% if (myVariable2) { %>\n

<%= myVariable3 %>

\n<% } %>\n")),(0,a.kt)("p",null,"The template may then be rendered by the following JavaScript code:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-js"},"const express = require('express')\nconst app = express()\n\napp.set('view engine', 'ejs')\n\napp.get('/', (req, res) => {\n return res.render('myEJSTemplate', {\n myVariable: \"value 1\",\n myVariable2: \"value 2\",\n myVariable3: \"value 3\"\n })\n})\n")),(0,a.kt)("h2",{id:"website-views--components"},"Website Views & Components"),(0,a.kt)("p",null,"The OSC website organizes EJS templates into two categories: views (which are usually entire pages/sites) and components (standalone HTML templates used alongside views). All of the source code's views are stored in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/tree/main/views"},"/views"),", and all components in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/tree/main/views/components"},"/views/components"),"."),(0,a.kt)("p",null,"An example of a reusable component is the navigation bar:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html",metastring:'title="views/components/navbar.ejs"',title:'"views/components/navbar.ejs"'},'\n')),(0,a.kt)("p",null,"The navbar does not take in any EJS parameters, but it can be imported by other views. For example:"),(0,a.kt)("pre",null,(0,a.kt)("code",{parentName:"pre",className:"language-html"},"\n\n\n \x3c!-- The navbar will be loaded and placed here. --\x3e\n <%- include('./components/navbar.ejs') %>\n\n

My other content...

\n\n\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/26e5135d.9f32bbc4.js b/assets/js/26e5135d.e72bee4c.js similarity index 95% rename from assets/js/26e5135d.9f32bbc4.js rename to assets/js/26e5135d.e72bee4c.js index 58e7f28..6248a62 100644 --- a/assets/js/26e5135d.9f32bbc4.js +++ b/assets/js/26e5135d.e72bee4c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[4252],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=l(n),m=o,h=u["".concat(c,".").concat(m)]||u[m]||p[m]||a;return n?r.createElement(h,s(s({ref:t},d),{},{components:n})):r.createElement(h,s({ref:t},d))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={title:"Introduction",description:"OSC Docs Introduction",sidebar_position:1},s="Introduction",i={unversionedId:"index",id:"index",title:"Introduction",description:"OSC Docs Introduction",source:"@site/docs/osc-docs/index.md",sourceDirName:".",slug:"/",permalink:"/docs/osc-docs/",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/osc-docs/index.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Introduction",description:"OSC Docs Introduction",sidebar_position:1},sidebar:"defaultSidebar",next:{title:"Installation",permalink:"/docs/osc-docs/installation"}},c={},l=[{value:"Index",id:"index",level:2}],d={toc:l},u="wrapper";function p(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/RichardLitt/standard-readme"},(0,o.kt)("img",{parentName:"a",src:"https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square",alt:"standard-readme compliant"}))," ",(0,o.kt)("img",{parentName:"p",src:"https://img.shields.io/github/actions/workflow/status/ufosc/osc-docs/node.js.yml",alt:"GitHub Workflow Status (with event)"})," ",(0,o.kt)("a",{parentName:"p",href:"https://standardjs.com"},(0,o.kt)("img",{parentName:"a",src:"https://img.shields.io/badge/code_style-standard-brightgreen.svg",alt:"JavaScript Style Guide"}))," ",(0,o.kt)("img",{parentName:"p",src:"https://img.shields.io/github/license/ufosc/osc-docs",alt:"GitHub"})," ",(0,o.kt)("img",{parentName:"p",src:"https://img.shields.io/github/issues/ufosc/osc-docs",alt:"GitHub issues"})),(0,o.kt)("p",null,"The OSC Docs website is a source of truth for projects and club activity at the University of Florida's Open Source Club. More specifically, it hosts user and developer documentation for the various projects started each semester. This project uses ",(0,o.kt)("a",{parentName:"p",href:"https://docusaurus.io/"},"Docusaurus")," to quickly and conveniently generate static sites from ",(0,o.kt)("a",{parentName:"p",href:"https://www.markdownguide.org/basic-syntax/"},"Markdown")," files."),(0,o.kt)("p",null,"Unlike the ",(0,o.kt)("a",{parentName:"p",href:"https://ufosc.org"},"main OSC website"),", the docs website emphasizes content delivery, accessibility, and ease of content creation (especially for non-technical users). This is beyond the capabilities and scope of the main site's native content management system, hence the need for a separate documentation site."),(0,o.kt)("p",null,"The source code is available on the Open Source Club's ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc"},"GitHub page")," under the ",(0,o.kt)("a",{parentName:"p",href:"https://spdx.org/licenses/AGPL-3.0-or-later"},"AGLP-3.0-or-later")," license, and the site is hosted at ",(0,o.kt)("a",{parentName:"p",href:"https://docs.ufosc.org"},"docs.ufosc.org"),". To get started with contributing to the osc docs, start by ",(0,o.kt)("a",{parentName:"p",href:"/docs/osc-docs/installation"},"installing the project"),"."),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"index"},"Index"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/installation"},"Installation"),": Instructions on installing the project and its dependencies."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/usage"},"Usage"),": Instructions on setting up a local development server and using the project."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/markdown"},"Markdown"),": Introduction to the Markdown language."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/writingdocs"},"Documentation"),": Creating documentation sites and managing their contents."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/static-pages"},"Static Pages"),": Guide to creating non-documentational static pages."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/docusaurus"},"Configuring Docusaurus"),": Guide to modifying the Docusaurus website template.")))}p.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[4252],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function s(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),l=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):s(s({},t),e)),n},d=function(e){var t=l(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},m=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,d=i(e,["components","mdxType","originalType","parentName"]),u=l(n),m=o,h=u["".concat(c,".").concat(m)]||u[m]||p[m]||a;return n?r.createElement(h,s(s({ref:t},d),{},{components:n})):r.createElement(h,s({ref:t},d))}));function h(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,s=new Array(a);s[0]=m;var i={};for(var c in t)hasOwnProperty.call(t,c)&&(i[c]=t[c]);i.originalType=e,i[u]="string"==typeof e?e:o,s[1]=i;for(var l=2;l{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>s,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var r=n(7462),o=(n(7294),n(3905));const a={title:"Introduction",description:"OSC Docs Introduction",sidebar_position:1},s="Introduction",i={unversionedId:"index",id:"index",title:"Introduction",description:"OSC Docs Introduction",source:"@site/docs/osc-docs/index.md",sourceDirName:".",slug:"/",permalink:"/docs/osc-docs/",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/osc-docs/index.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Introduction",description:"OSC Docs Introduction",sidebar_position:1},sidebar:"defaultSidebar",next:{title:"Installation",permalink:"/docs/osc-docs/installation"}},c={},l=[{value:"Index",id:"index",level:2}],d={toc:l},u="wrapper";function p(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,(0,o.kt)("a",{parentName:"p",href:"https://github.com/RichardLitt/standard-readme"},(0,o.kt)("img",{parentName:"a",src:"https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square",alt:"standard-readme compliant"}))," ",(0,o.kt)("img",{parentName:"p",src:"https://img.shields.io/github/actions/workflow/status/ufosc/osc-docs/node.js.yml",alt:"GitHub Workflow Status (with event)"})," ",(0,o.kt)("a",{parentName:"p",href:"https://standardjs.com"},(0,o.kt)("img",{parentName:"a",src:"https://img.shields.io/badge/code_style-standard-brightgreen.svg",alt:"JavaScript Style Guide"}))," ",(0,o.kt)("img",{parentName:"p",src:"https://img.shields.io/github/license/ufosc/osc-docs",alt:"GitHub"})," ",(0,o.kt)("img",{parentName:"p",src:"https://img.shields.io/github/issues/ufosc/osc-docs",alt:"GitHub issues"})),(0,o.kt)("p",null,"The OSC Docs website is a source of truth for projects and club activity at the University of Florida's Open Source Club. More specifically, it hosts user and developer documentation for the various projects started each semester. This project uses ",(0,o.kt)("a",{parentName:"p",href:"https://docusaurus.io/"},"Docusaurus")," to quickly and conveniently generate static sites from ",(0,o.kt)("a",{parentName:"p",href:"https://www.markdownguide.org/basic-syntax/"},"Markdown")," files."),(0,o.kt)("p",null,"Unlike the ",(0,o.kt)("a",{parentName:"p",href:"https://ufosc.org"},"main OSC website"),", the docs website emphasizes content delivery, accessibility, and ease of content creation (especially for non-technical users). This is beyond the capabilities and scope of the main site's native content management system, hence the need for a separate documentation site."),(0,o.kt)("p",null,"The source code is available on the Open Source Club's ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc"},"GitHub page")," under the ",(0,o.kt)("a",{parentName:"p",href:"https://spdx.org/licenses/AGPL-3.0-or-later"},"AGLP-3.0-or-later")," license, and the site is hosted at ",(0,o.kt)("a",{parentName:"p",href:"https://docs.ufosc.org"},"docs.ufosc.org"),". To get started with contributing to the osc docs, start by ",(0,o.kt)("a",{parentName:"p",href:"/docs/osc-docs/installation"},"installing the project"),"."),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"index"},"Index"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/installation"},"Installation"),": Instructions on installing the project and its dependencies."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/usage"},"Usage"),": Instructions on setting up a local development server and using the project."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/markdown"},"Markdown"),": Introduction to the Markdown language."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/writingdocs"},"Documentation"),": Creating documentation sites and managing their contents."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/static-pages"},"Static Pages"),": Guide to creating non-documentation static pages."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs/docusaurus"},"Configuring Docusaurus"),": Guide to modifying the Docusaurus website template.")))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/2cc0550e.84abafc5.js b/assets/js/2cc0550e.33f615db.js similarity index 71% rename from assets/js/2cc0550e.84abafc5.js rename to assets/js/2cc0550e.33f615db.js index 9df3ba1..a1bd453 100644 --- a/assets/js/2cc0550e.84abafc5.js +++ b/assets/js/2cc0550e.33f615db.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[942],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(r),m=a,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const o={title:"Contact Route",description:"Club Website Developer API",sidebar_position:3},i="Contact Route",s={unversionedId:"Developers/API/contact",id:"Developers/API/contact",title:"Contact Route",description:"Club Website Developer API",source:"@site/docs/website/Developers/API/contact.md",sourceDirName:"Developers/API",slug:"/Developers/API/contact",permalink:"/docs/website/Developers/API/contact",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/API/contact.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Contact Route",description:"Club Website Developer API",sidebar_position:3},sidebar:"defaultSidebar",previous:{title:"Blog Route",permalink:"/docs/website/Developers/API/blog"},next:{title:"Edit Route",permalink:"/docs/website/Developers/API/edit"}},l={},c=[{value:"Submit Contact Form: (POST) /api/contact/",id:"submit-contact-form-post-apicontact",level:2},{value:"Request Parameters",id:"request-parameters",level:3},{value:"Sample Response",id:"sample-response",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"contact-route"},"Contact Route"),(0,a.kt)("p",null,"The contact route manages the website contact form. It validates email addresses and form input fields, and (if applicable) sends emails to both the OSC and form-user's email addresses."),(0,a.kt)("admonition",{title:"routes/contact.js",type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"The contact route is defined in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/contact.js"},"/routes/contact.js")," and operates on the ",(0,a.kt)("inlineCode",{parentName:"p"},"/api/edit")," API path.")),(0,a.kt)("h2",{id:"submit-contact-form-post-apicontact"},"Submit Contact Form: (POST) /api/contact/"),(0,a.kt)("p",null,"This route expects the contact form's field data (as JSON). If the data is succesfully validated, it sends an email to the admin account notifying it of the new message, whilst also sending a receipt of the submitted form to the specified email address of the submitter."),(0,a.kt)("p",null,"Email protocol interfacing is achieved via an SMTP server, which receives and processes outgoing server mail. For configuration instructions, see ",(0,a.kt)("a",{parentName:"p",href:"/docs/website/Developers/configuration"},"configuration"),"."),(0,a.kt)("h3",{id:"request-parameters"},"Request Parameters"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,a.kt)("th",{parentName:"tr",align:null},"Description"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"FirstName (JSON, body)"),(0,a.kt)("td",{parentName:"tr",align:null},"The sender's first name")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"LastName (JSON, body)"),(0,a.kt)("td",{parentName:"tr",align:null},"The sender's last name")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Email (JSON, body)"),(0,a.kt)("td",{parentName:"tr",align:null},"The sender's email address")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Message (JSON, body)"),(0,a.kt)("td",{parentName:"tr",align:null},"The sender's message")))),(0,a.kt)("h3",{id:"sample-response"},"Sample Response"),(0,a.kt)("p",null,"If the request succeeded, a single 'Success' string will be returned."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[942],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});var n=r(7294);function a(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function o(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function i(e){for(var t=1;t=0||(a[r]=e[r]);return a}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(a[r]=e[r])}return a}var l=n.createContext({}),c=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):i(i({},t),e)),r},p=function(e){var t=c(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,a=e.mdxType,o=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),u=c(r),m=a,f=u["".concat(l,".").concat(m)]||u[m]||d[m]||o;return r?n.createElement(f,i(i({ref:t},p),{},{components:r})):n.createElement(f,i({ref:t},p))}));function f(e,t){var r=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var o=r.length,i=new Array(o);i[0]=m;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[u]="string"==typeof e?e:a,i[1]=s;for(var c=2;c{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>d,frontMatter:()=>o,metadata:()=>s,toc:()=>c});var n=r(7462),a=(r(7294),r(3905));const o={title:"Contact Route",description:"Club Website Developer API",sidebar_position:3},i="Contact Route",s={unversionedId:"Developers/API/contact",id:"Developers/API/contact",title:"Contact Route",description:"Club Website Developer API",source:"@site/docs/website/Developers/API/contact.md",sourceDirName:"Developers/API",slug:"/Developers/API/contact",permalink:"/docs/website/Developers/API/contact",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/API/contact.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Contact Route",description:"Club Website Developer API",sidebar_position:3},sidebar:"defaultSidebar",previous:{title:"Blog Route",permalink:"/docs/website/Developers/API/blog"},next:{title:"Edit Route",permalink:"/docs/website/Developers/API/edit"}},l={},c=[{value:"Submit Contact Form: (POST) /api/contact/",id:"submit-contact-form-post-apicontact",level:2},{value:"Request Parameters",id:"request-parameters",level:3},{value:"Sample Response",id:"sample-response",level:3}],p={toc:c},u="wrapper";function d(e){let{components:t,...r}=e;return(0,a.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"contact-route"},"Contact Route"),(0,a.kt)("p",null,"The contact route manages the website contact form. It validates email addresses and form input fields, and (if applicable) sends emails to both the OSC and form-user's email addresses."),(0,a.kt)("admonition",{title:"routes/contact.js",type:"tip"},(0,a.kt)("p",{parentName:"admonition"},"The contact route is defined in ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/contact.js"},"/routes/contact.js")," and operates on the ",(0,a.kt)("inlineCode",{parentName:"p"},"/api/edit")," API path.")),(0,a.kt)("h2",{id:"submit-contact-form-post-apicontact"},"Submit Contact Form: (POST) /api/contact/"),(0,a.kt)("p",null,"This route expects the contact form's field data (as JSON). If the data is successfully validated, it sends an email to the admin account notifying it of the new message, whilst also sending a receipt of the submitted form to the specified email address of the submitter."),(0,a.kt)("p",null,"Email protocol interfacing is achieved via an SMTP server, which receives and processes outgoing server mail. For configuration instructions, see ",(0,a.kt)("a",{parentName:"p",href:"/docs/website/Developers/configuration"},"configuration"),"."),(0,a.kt)("h3",{id:"request-parameters"},"Request Parameters"),(0,a.kt)("table",null,(0,a.kt)("thead",{parentName:"table"},(0,a.kt)("tr",{parentName:"thead"},(0,a.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,a.kt)("th",{parentName:"tr",align:null},"Description"))),(0,a.kt)("tbody",{parentName:"table"},(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"FirstName (JSON, body)"),(0,a.kt)("td",{parentName:"tr",align:null},"The sender's first name")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"LastName (JSON, body)"),(0,a.kt)("td",{parentName:"tr",align:null},"The sender's last name")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Email (JSON, body)"),(0,a.kt)("td",{parentName:"tr",align:null},"The sender's email address")),(0,a.kt)("tr",{parentName:"tbody"},(0,a.kt)("td",{parentName:"tr",align:null},"Message (JSON, body)"),(0,a.kt)("td",{parentName:"tr",align:null},"The sender's message")))),(0,a.kt)("h3",{id:"sample-response"},"Sample Response"),(0,a.kt)("p",null,"If the request succeeded, a single 'Success' string will be returned."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/347d410c.02f5a972.js b/assets/js/347d410c.8d296d15.js similarity index 52% rename from assets/js/347d410c.02f5a972.js rename to assets/js/347d410c.8d296d15.js index d34266f..b080b08 100644 --- a/assets/js/347d410c.02f5a972.js +++ b/assets/js/347d410c.8d296d15.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[2644],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),l=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,c=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),h=l(n),m=r,d=h["".concat(s,".").concat(m)]||h[m]||u[m]||c;return n?a.createElement(d,i(i({ref:t},p),{},{components:n})):a.createElement(d,i({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var c=n.length,i=new Array(c);i[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[h]="string"==typeof e?e:r,i[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var a=n(7462),r=(n(7294),n(3905));const c={title:"Caching",description:"Club Website Developer Caching",sidebar_position:6},i="Caching",o={unversionedId:"Developers/caching",id:"Developers/caching",title:"Caching",description:"Club Website Developer Caching",source:"@site/docs/website/Developers/caching.md",sourceDirName:"Developers",slug:"/Developers/caching",permalink:"/docs/website/Developers/caching",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/caching.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{title:"Caching",description:"Club Website Developer Caching",sidebar_position:6},sidebar:"defaultSidebar",previous:{title:"Users Route",permalink:"/docs/website/Developers/API/users"},next:{title:"Authentication",permalink:"/docs/website/Developers/authentication"}},s={},l=[{value:"Cache Module",id:"cache-module",level:2},{value:"Example: Writing to the Cache",id:"example-writing-to-the-cache",level:3},{value:"Example: Reading from the Cache",id:"example-reading-from-the-cache",level:3},{value:"Example: Force-updating the cache",id:"example-force-updating-the-cache",level:3},{value:"Example: Starting/Stopping the cache",id:"example-startingstopping-the-cache",level:3}],p={toc:l},h="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(h,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"caching"},"Caching"),(0,r.kt)("p",null,"Caching allows the website's server to imporove performance and preserve CPU by storing time-insensitive data in memory. Its most common use case is in serving the home and blog pages: instead of dynamically re-rendering the same page for each user request, it is rendered only once and then served from memory. Naturally, the cache updates its data after some predetermined time period, configurable by the ",(0,r.kt)("a",{parentName:"p",href:"/docs/website/Developers/configuration#caching"},"CACHE_INTERVAL")," environment variable."),(0,r.kt)("h2",{id:"cache-module"},"Cache Module"),(0,r.kt)("p",null,"The cache module is defined in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/utils/cache.js"},"utils/cache.js"),". The cache essentially functions as a state machine: it consumes user-defined functions that modify variables in the cache's internal state, and runs said functions at most once every ",(0,r.kt)("inlineCode",{parentName:"p"},"CACHE_INTERVAL")," minutes. Likewise, if the ",(0,r.kt)("inlineCode",{parentName:"p"},"CACHE_INTERVAL")," passes, then it will not update the cache until some other module tries to read its data (e.g when the server reads the cache to server a user's request)."),(0,r.kt)("h3",{id:"example-writing-to-the-cache"},"Example: Writing to the Cache"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const CacheModule = require(\'./utils/cache\')\nconst cache = new CacheModule()\n\n// These functions will run at most once every CACHE_INTERVAL.\n// Their return values (which must be JSON objects) will be\n// written to the cache\'s memory.\n\ncache.register(() => {\n return { myKey1: "my value 1", myKey2: "my value 2" }\n})\n\ncache.register(() => {\n return { myKey3: "my value 3", myKey4: "my value 4" }\n})\n\n// Registering multiple functions\n\ncache.register(myFunction1, myFunction2, ...)\n\n// Start the cache interval.\n// Updates every 5 minutes.\ncache.start(5)\n')),(0,r.kt)("h3",{id:"example-reading-from-the-cache"},"Example: Reading from the Cache"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"// You can read the stored cache values by reading from\n// the .cache() object using the same keys that were\n// returned by the registered callbacks.\n\nconsole.log(cache.cache().myKey1)\nconsole.log(cache.cache().myKey2)\nconsole.log(cache.cache().myKey3)\n")),(0,r.kt)("h3",{id:"example-force-updating-the-cache"},"Example: Force-updating the cache"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"cache.run()\n")),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},".run()")," will force each callback function to be executed, hence forcefully updating the cache's state."),(0,r.kt)("h3",{id:"example-startingstopping-the-cache"},"Example: Starting/Stopping the cache"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"// Start, update every 5 minutes.\ncache.start(5)\n\n// Stop the interval.\ncache.stop()\n\n// Start again\ncache.start(5)\n")),(0,r.kt)("p",null,"The cache can be started and stopped with the ",(0,r.kt)("inlineCode",{parentName:"p"},".start(MINUTES)")," and ",(0,r.kt)("inlineCode",{parentName:"p"},".stop()")," functions, respectively. The cache can be started and stopped as many times as needed without consequence."))}u.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[2644],{3905:(e,t,n)=>{n.d(t,{Zo:()=>p,kt:()=>d});var a=n(7294);function r(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function c(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function i(e){for(var t=1;t=0||(r[n]=e[n]);return r}(e,t);if(Object.getOwnPropertySymbols){var c=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(r[n]=e[n])}return r}var s=a.createContext({}),l=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=l(e.components);return a.createElement(s.Provider,{value:t},e.children)},h="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},m=a.forwardRef((function(e,t){var n=e.components,r=e.mdxType,c=e.originalType,s=e.parentName,p=o(e,["components","mdxType","originalType","parentName"]),h=l(n),m=r,d=h["".concat(s,".").concat(m)]||h[m]||u[m]||c;return n?a.createElement(d,i(i({ref:t},p),{},{components:n})):a.createElement(d,i({ref:t},p))}));function d(e,t){var n=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var c=n.length,i=new Array(c);i[0]=m;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[h]="string"==typeof e?e:r,i[1]=o;for(var l=2;l{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>u,frontMatter:()=>c,metadata:()=>o,toc:()=>l});var a=n(7462),r=(n(7294),n(3905));const c={title:"Caching",description:"Club Website Developer Caching",sidebar_position:6},i="Caching",o={unversionedId:"Developers/caching",id:"Developers/caching",title:"Caching",description:"Club Website Developer Caching",source:"@site/docs/website/Developers/caching.md",sourceDirName:"Developers",slug:"/Developers/caching",permalink:"/docs/website/Developers/caching",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/caching.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{title:"Caching",description:"Club Website Developer Caching",sidebar_position:6},sidebar:"defaultSidebar",previous:{title:"Users Route",permalink:"/docs/website/Developers/API/users"},next:{title:"Authentication",permalink:"/docs/website/Developers/authentication"}},s={},l=[{value:"Cache Module",id:"cache-module",level:2},{value:"Example: Writing to the Cache",id:"example-writing-to-the-cache",level:3},{value:"Example: Reading from the Cache",id:"example-reading-from-the-cache",level:3},{value:"Example: Force-updating the cache",id:"example-force-updating-the-cache",level:3},{value:"Example: Starting/Stopping the cache",id:"example-startingstopping-the-cache",level:3}],p={toc:l},h="wrapper";function u(e){let{components:t,...n}=e;return(0,r.kt)(h,(0,a.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"caching"},"Caching"),(0,r.kt)("p",null,"Caching allows the website's server to improve performance and preserve CPU by storing time-insensitive data in memory. Its most common use case is in serving the home and blog pages: instead of dynamically re-rendering the same page for each user request, it is rendered only once and then served from memory. Naturally, the cache updates its data after some predetermined time period, configurable by the ",(0,r.kt)("a",{parentName:"p",href:"/docs/website/Developers/configuration#caching"},"CACHE_INTERVAL")," environment variable."),(0,r.kt)("h2",{id:"cache-module"},"Cache Module"),(0,r.kt)("p",null,"The cache module is defined in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/utils/cache.js"},"utils/cache.js"),". The cache essentially functions as a state machine: it consumes user-defined functions that modify variables in the cache's internal state, and runs said functions at most once every ",(0,r.kt)("inlineCode",{parentName:"p"},"CACHE_INTERVAL")," minutes. Likewise, if the ",(0,r.kt)("inlineCode",{parentName:"p"},"CACHE_INTERVAL")," passes, then it will not update the cache until some other module tries to read its data (e.g when the server reads the cache to server a user's request)."),(0,r.kt)("h3",{id:"example-writing-to-the-cache"},"Example: Writing to the Cache"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},'const CacheModule = require(\'./utils/cache\')\nconst cache = new CacheModule()\n\n// These functions will run at most once every CACHE_INTERVAL.\n// Their return values (which must be JSON objects) will be\n// written to the cache\'s memory.\n\ncache.register(() => {\n return { myKey1: "my value 1", myKey2: "my value 2" }\n})\n\ncache.register(() => {\n return { myKey3: "my value 3", myKey4: "my value 4" }\n})\n\n// Registering multiple functions\n\ncache.register(myFunction1, myFunction2, ...)\n\n// Start the cache interval.\n// Updates every 5 minutes.\ncache.start(5)\n')),(0,r.kt)("h3",{id:"example-reading-from-the-cache"},"Example: Reading from the Cache"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"// You can read the stored cache values by reading from\n// the .cache() object using the same keys that were\n// returned by the registered callbacks.\n\nconsole.log(cache.cache().myKey1)\nconsole.log(cache.cache().myKey2)\nconsole.log(cache.cache().myKey3)\n")),(0,r.kt)("h3",{id:"example-force-updating-the-cache"},"Example: Force-updating the cache"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"cache.run()\n")),(0,r.kt)("p",null,(0,r.kt)("inlineCode",{parentName:"p"},".run()")," will force each callback function to be executed, hence forcefully updating the cache's state."),(0,r.kt)("h3",{id:"example-startingstopping-the-cache"},"Example: Starting/Stopping the cache"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"// Start, update every 5 minutes.\ncache.start(5)\n\n// Stop the interval.\ncache.stop()\n\n// Start again\ncache.start(5)\n")),(0,r.kt)("p",null,"The cache can be started and stopped with the ",(0,r.kt)("inlineCode",{parentName:"p"},".start(MINUTES)")," and ",(0,r.kt)("inlineCode",{parentName:"p"},".stop()")," functions, respectively. The cache can be started and stopped as many times as needed without consequence."))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/59a06d98.26e2156b.js b/assets/js/59a06d98.26e2156b.js deleted file mode 100644 index 511688c..0000000 --- a/assets/js/59a06d98.26e2156b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[5031],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>g});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),p=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),d=p(a),c=r,g=d["".concat(l,".").concat(c)]||d[c]||u[c]||i;return a?n.createElement(g,s(s({ref:t},m),{},{components:a})):n.createElement(g,s({ref:t},m))}));function g(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,s=new Array(i);s[0]=c;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:r,s[1]=o;for(var p=2;p{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const i={title:"Image Storage",description:"Club Website Developer Database",sidebar_position:3},s="Image Storage",o={unversionedId:"Developers/Databases/image-storage",id:"Developers/Databases/image-storage",title:"Image Storage",description:"Club Website Developer Database",source:"@site/docs/website/Developers/Databases/image-storage.md",sourceDirName:"Developers/Databases",slug:"/Developers/Databases/image-storage",permalink:"/docs/website/Developers/Databases/image-storage",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/Databases/image-storage.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Image Storage",description:"Club Website Developer Database",sidebar_position:3},sidebar:"defaultSidebar",previous:{title:"Database Models",permalink:"/docs/website/Developers/Databases/models"},next:{title:"API & Routes",permalink:"/docs/website/Developers/API/"}},l={},p=[{value:"Express Multer",id:"express-multer",level:2},{value:"Image Upload Route",id:"image-upload-route",level:2}],m={toc:p},d="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(d,(0,n.Z)({},m,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"image-storage"},"Image Storage"),(0,r.kt)("p",null,"The images API route exists to serve image content for blog articles. To minimise latency, images are stored on the server's hard disk, whilst image metadata lives on the database. The purpose of the metadata is to assert the image's existence, physical location, description, and API path."),(0,r.kt)("p",null,"If you'd like to learn more about the type of metadata that's stored, refer to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/model/images.js"},"models/images.js"),"."),(0,r.kt)("h2",{id:"express-multer"},"Express Multer"),(0,r.kt)("p",null,"The ",(0,r.kt)("a",{parentName:"p",href:"https://expressjs.com/en/resources/middleware/multer.html"},"Express Multer")," library enables the Express webserver to do multiplexing. Consequently, this means that it can receive multiform and multipart data (data that takes multiple requests to transmit, i.e large image files). The library is configured to save incoming image files to the disk (",(0,r.kt)("inlineCode",{parentName:"p"},"/uploads"),") folder:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js"',title:'"routes/images.js"'},"const multer = require('multer')\n// ...\n\nconst storage = multer.diskStorage({\n destination: (req, file, cb) => {\n // Create directory if it doesnt exist.\n if (!fs.existsSync('uploads/')) {\n fs.mkdirSync('uploads/', { recursive: true })\n }\n cb(null, 'uploads/')\n },\n filename: (req, file, cb) => {\n // If its not a .jpeg, then it will be caught later.\n const suffix = (file.mimetype === 'image/png') ? '.png' : '.jpeg'\n const prefix = Date.now() + '-' + Math.round(Math.random() * 1E9)\n cb(null, prefix + suffix)\n }\n})\n// ...\n\n// Max size: 25MB\nconst upload = multer({ storage, limits: { fileSize: 26214400 } })\n")),(0,r.kt)("p",null,"Essentially, whenever a new file arrives, it will be stored in the destination specified by ",(0,r.kt)("inlineCode",{parentName:"p"},"storage.destination")," with the file name specified by ",(0,r.kt)("inlineCode",{parentName:"p"},"storage.filename"),". The file name function (",(0,r.kt)("inlineCode",{parentName:"p"},"storage.filename"),") generates a file name according to the following criteria:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"If the file type is '.png', then the file name suffix will be ",(0,r.kt)("inlineCode",{parentName:"li"},".png"),". Otherwise, it will be ",(0,r.kt)("inlineCode",{parentName:"li"},".jpeg"),". If it is neither, an error will be issued later on ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/images.js#L65"},"here"),"."),(0,r.kt)("li",{parentName:"ol"},"The prefix will be the current date, plus a dash symbol ('-'), plus some random number."),(0,r.kt)("li",{parentName:"ol"},"Finally, the file name is produced by combining the two strings: ",(0,r.kt)("inlineCode",{parentName:"li"},"prefix + suffix"),".")),(0,r.kt)("p",null,"With the multer storage configured, the ",(0,r.kt)("inlineCode",{parentName:"p"},"storage")," constant is passed along with a ",(0,r.kt)("inlineCode",{parentName:"p"},"fileSize")," limit (set to 25MB) to produce the ",(0,r.kt)("inlineCode",{parentName:"p"},"upload")," constant, which can now be used as an ",(0,r.kt)("a",{parentName:"p",href:"https://expressjs.com/en/guide/using-middleware.html"},"Express Middleware"),"."),(0,r.kt)("admonition",{title:"Express Middleware",type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application\u2019s request-response cycle. They control the data coming and going from the server's routes. When the upload ",(0,r.kt)("inlineCode",{parentName:"p"},"upload.single('file')")," is used, the middleware will ensure that a single file has been sent by the client, and will then store it on the disk.")),(0,r.kt)("h2",{id:"image-upload-route"},"Image Upload Route"),(0,r.kt)("p",null,"Image API operations are managed in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/images.js"},"routes/images.js"),". An excerpt of the image upload route is copied below as an explanatory reference:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js"',title:'"routes/images.js"'},"router.post('/', passport.authenticate('loggedIn', { session: false }), upload.single('File'), (req, res) => {\n\n // ...\n\n const image = new ImageModel({\n filename: req.file.filename,\n description: req.body.Description,\n path: req.file.path\n })\n\n image.save((err) => {\n if (err) return res.status(500).send({ error: 'Internal Server Error' })\n })\n\n return res.status(200).send(image)\n})\n")),(0,r.kt)("p",null,"First, the ",(0,r.kt)("inlineCode",{parentName:"p"},"passport.authenticate('loggedIn', { session: false })")," ensures that the user is ",(0,r.kt)("inlineCode",{parentName:"p"},"loggedIn")," before they can proceed with uploading an image. Next, ",(0,r.kt)("inlineCode",{parentName:"p"},"upload.single('File')")," ensures that a single file has been sent, and then saves that file on the disk. Finally, ",(0,r.kt)("inlineCode",{parentName:"p"},"(req, res)")," is the function definition that handles the rest of the image upload routine."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"upload")," middleware will automatically store the file's metadata in the ",(0,r.kt)("inlineCode",{parentName:"p"},"req")," object, that way we can pass it along to our ",(0,r.kt)("inlineCode",{parentName:"p"},"(req, res)")," function:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"req.file.filename")," stores the name of the file, as defined by ",(0,r.kt)("inlineCode",{parentName:"li"},"storage.filename"),"."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"req.file.path")," is the file system path where our file is located."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"req.body.Description")," is not actually handled by ",(0,r.kt)("inlineCode",{parentName:"li"},"upload"),". It is passed by the image submission form and keeps the user-specified image description.")),(0,r.kt)("p",null,"With this information, we create a new ImageModel instance (read ",(0,r.kt)("a",{parentName:"p",href:"/docs/website/Developers/Databases/mongodb"},"Using MongoDB")," to learn more about models):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"const image = new ImageModel({\n filename: req.file.filename,\n description: req.body.Description,\n path: req.file.path\n})\n")),(0,r.kt)("p",null,"And save it to the database:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"image.save((err) => {\n if (err) return res.status(500).send({ error: 'Internal Server Error' })\n})\n")),(0,r.kt)("p",null,"Note that the physical image has already been saved by ",(0,r.kt)("inlineCode",{parentName:"p"},"upload")," to our server's ",(0,r.kt)("inlineCode",{parentName:"p"},"/upload")," folder."),(0,r.kt)("p",null,"Henceforth, whenever we want to retrieve and send an image (assuming we know it's ID), we can query the MongoDB database, retrieve its file system path, and load the image into memory:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js"',title:'"routes/images.js"'},"const imageExists = await ImageModel.findById(req.params.id)\nif (!imageExists) {\n return res.status(404).send({ error: 'ID does not exist' })\n}\n\nres.status(200).sendFile(resolve(imageExists.path))\n")),(0,r.kt)("p",null,"If we find that, for some reason, the file no longer exists on the file system, we delete it from the database and return an error:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js"',title:'"routes/images.js"'},"if (!fs.existsSync(imageExists.path)) {\n await ImageModel.findByIdAndDelete(req.params.id)\n return res.status(404).send({ error: 'image does not exist' })\n}\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/59a06d98.cab93558.js b/assets/js/59a06d98.cab93558.js new file mode 100644 index 0000000..f782780 --- /dev/null +++ b/assets/js/59a06d98.cab93558.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[5031],{3905:(e,t,a)=>{a.d(t,{Zo:()=>m,kt:()=>g});var n=a(7294);function r(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function i(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function s(e){for(var t=1;t=0||(r[a]=e[a]);return r}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(r[a]=e[a])}return r}var l=n.createContext({}),p=function(e){var t=n.useContext(l),a=t;return e&&(a="function"==typeof e?e(t):s(s({},t),e)),a},m=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},d="mdxType",u={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,r=e.mdxType,i=e.originalType,l=e.parentName,m=o(e,["components","mdxType","originalType","parentName"]),d=p(a),c=r,g=d["".concat(l,".").concat(c)]||d[c]||u[c]||i;return a?n.createElement(g,s(s({ref:t},m),{},{components:a})):n.createElement(g,s({ref:t},m))}));function g(e,t){var a=arguments,r=t&&t.mdxType;if("string"==typeof e||r){var i=a.length,s=new Array(i);s[0]=c;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[d]="string"==typeof e?e:r,s[1]=o;for(var p=2;p{a.r(t),a.d(t,{assets:()=>l,contentTitle:()=>s,default:()=>u,frontMatter:()=>i,metadata:()=>o,toc:()=>p});var n=a(7462),r=(a(7294),a(3905));const i={title:"Image Storage",description:"Club Website Developer Database",sidebar_position:3},s="Image Storage",o={unversionedId:"Developers/Databases/image-storage",id:"Developers/Databases/image-storage",title:"Image Storage",description:"Club Website Developer Database",source:"@site/docs/website/Developers/Databases/image-storage.md",sourceDirName:"Developers/Databases",slug:"/Developers/Databases/image-storage",permalink:"/docs/website/Developers/Databases/image-storage",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/Databases/image-storage.md",tags:[],version:"current",sidebarPosition:3,frontMatter:{title:"Image Storage",description:"Club Website Developer Database",sidebar_position:3},sidebar:"defaultSidebar",previous:{title:"Database Models",permalink:"/docs/website/Developers/Databases/models"},next:{title:"API & Routes",permalink:"/docs/website/Developers/API/"}},l={},p=[{value:"Express Multer",id:"express-multer",level:2},{value:"Image Upload Route",id:"image-upload-route",level:2}],m={toc:p},d="wrapper";function u(e){let{components:t,...a}=e;return(0,r.kt)(d,(0,n.Z)({},m,a,{components:t,mdxType:"MDXLayout"}),(0,r.kt)("h1",{id:"image-storage"},"Image Storage"),(0,r.kt)("p",null,"The images API route exists to serve image content for blog articles. To minimize latency, images are stored on the server's hard disk, whilst image metadata lives on the database. The purpose of the metadata is to assert the image's existence, physical location, description, and API path."),(0,r.kt)("p",null,"If you'd like to learn more about the type of metadata that's stored, refer to ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/model/images.js"},"models/images.js"),"."),(0,r.kt)("h2",{id:"express-multer"},"Express Multer"),(0,r.kt)("p",null,"The ",(0,r.kt)("a",{parentName:"p",href:"https://expressjs.com/en/resources/middleware/multer.html"},"Express Multer")," library enables the Express web server to do multiplexing. Consequently, this means that it can receive multiform and multipart data (data that takes multiple requests to transmit, i.e large image files). The library is configured to save incoming image files to the disk (",(0,r.kt)("inlineCode",{parentName:"p"},"/uploads"),") folder:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js"',title:'"routes/images.js"'},"const multer = require('multer')\n// ...\n\nconst storage = multer.diskStorage({\n destination: (req, file, cb) => {\n // Create directory if it doesnt exist.\n if (!fs.existsSync('uploads/')) {\n fs.mkdirSync('uploads/', { recursive: true })\n }\n cb(null, 'uploads/')\n },\n filename: (req, file, cb) => {\n // If its not a .jpeg, then it will be caught later.\n const suffix = (file.mimetype === 'image/png') ? '.png' : '.jpeg'\n const prefix = Date.now() + '-' + Math.round(Math.random() * 1E9)\n cb(null, prefix + suffix)\n }\n})\n// ...\n\n// Max size: 25MB\nconst upload = multer({ storage, limits: { fileSize: 26214400 } })\n")),(0,r.kt)("p",null,"Essentially, whenever a new file arrives, it will be stored in the destination specified by ",(0,r.kt)("inlineCode",{parentName:"p"},"storage.destination")," with the file name specified by ",(0,r.kt)("inlineCode",{parentName:"p"},"storage.filename"),". The file name function (",(0,r.kt)("inlineCode",{parentName:"p"},"storage.filename"),") generates a file name according to the following criteria:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},"If the file type is '.png', then the file name suffix will be ",(0,r.kt)("inlineCode",{parentName:"li"},".png"),". Otherwise, it will be ",(0,r.kt)("inlineCode",{parentName:"li"},".jpeg"),". If it is neither, an error will be issued later on ",(0,r.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/images.js#L65"},"here"),"."),(0,r.kt)("li",{parentName:"ol"},"The prefix will be the current date, plus a dash symbol ('-'), plus some random number."),(0,r.kt)("li",{parentName:"ol"},"Finally, the file name is produced by combining the two strings: ",(0,r.kt)("inlineCode",{parentName:"li"},"prefix + suffix"),".")),(0,r.kt)("p",null,"With the multer storage configured, the ",(0,r.kt)("inlineCode",{parentName:"p"},"storage")," constant is passed along with a ",(0,r.kt)("inlineCode",{parentName:"p"},"fileSize")," limit (set to 25MB) to produce the ",(0,r.kt)("inlineCode",{parentName:"p"},"upload")," constant, which can now be used as an ",(0,r.kt)("a",{parentName:"p",href:"https://expressjs.com/en/guide/using-middleware.html"},"Express Middleware"),"."),(0,r.kt)("admonition",{title:"Express Middleware",type:"tip"},(0,r.kt)("p",{parentName:"admonition"},"Middleware functions are functions that have access to the request object (req), the response object (res), and the next middleware function in the application\u2019s request-response cycle. They control the data coming and going from the server's routes. When the upload ",(0,r.kt)("inlineCode",{parentName:"p"},"upload.single('file')")," is used, the middleware will ensure that a single file has been sent by the client, and will then store it on the disk.")),(0,r.kt)("h2",{id:"image-upload-route"},"Image Upload Route"),(0,r.kt)("p",null,"Image API operations are managed in ",(0,r.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/images.js"},"routes/images.js"),". An excerpt of the image upload route is copied below as an explanatory reference:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js"',title:'"routes/images.js"'},"router.post('/', passport.authenticate('loggedIn', { session: false }), upload.single('File'), (req, res) => {\n\n // ...\n\n const image = new ImageModel({\n filename: req.file.filename,\n description: req.body.Description,\n path: req.file.path\n })\n\n image.save((err) => {\n if (err) return res.status(500).send({ error: 'Internal Server Error' })\n })\n\n return res.status(200).send(image)\n})\n")),(0,r.kt)("p",null,"First, the ",(0,r.kt)("inlineCode",{parentName:"p"},"passport.authenticate('loggedIn', { session: false })")," ensures that the user is ",(0,r.kt)("inlineCode",{parentName:"p"},"loggedIn")," before they can proceed with uploading an image. Next, ",(0,r.kt)("inlineCode",{parentName:"p"},"upload.single('File')")," ensures that a single file has been sent, and then saves that file on the disk. Finally, ",(0,r.kt)("inlineCode",{parentName:"p"},"(req, res)")," is the function definition that handles the rest of the image upload routine."),(0,r.kt)("p",null,"The ",(0,r.kt)("inlineCode",{parentName:"p"},"upload")," middleware will automatically store the file's metadata in the ",(0,r.kt)("inlineCode",{parentName:"p"},"req")," object, that way we can pass it along to our ",(0,r.kt)("inlineCode",{parentName:"p"},"(req, res)")," function:"),(0,r.kt)("ol",null,(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"req.file.filename")," stores the name of the file, as defined by ",(0,r.kt)("inlineCode",{parentName:"li"},"storage.filename"),"."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"req.file.path")," is the file system path where our file is located."),(0,r.kt)("li",{parentName:"ol"},(0,r.kt)("inlineCode",{parentName:"li"},"req.body.Description")," is not actually handled by ",(0,r.kt)("inlineCode",{parentName:"li"},"upload"),". It is passed by the image submission form and keeps the user-specified image description.")),(0,r.kt)("p",null,"With this information, we create a new ImageModel instance (read ",(0,r.kt)("a",{parentName:"p",href:"/docs/website/Developers/Databases/mongodb"},"Using MongoDB")," to learn more about models):"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"const image = new ImageModel({\n filename: req.file.filename,\n description: req.body.Description,\n path: req.file.path\n})\n")),(0,r.kt)("p",null,"And save it to the database:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js"},"image.save((err) => {\n if (err) return res.status(500).send({ error: 'Internal Server Error' })\n})\n")),(0,r.kt)("p",null,"Note that the physical image has already been saved by ",(0,r.kt)("inlineCode",{parentName:"p"},"upload")," to our server's ",(0,r.kt)("inlineCode",{parentName:"p"},"/upload")," folder."),(0,r.kt)("p",null,"Henceforth, whenever we want to retrieve and send an image (assuming we know it's ID), we can query the MongoDB database, retrieve its file system path, and load the image into memory:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js"',title:'"routes/images.js"'},"const imageExists = await ImageModel.findById(req.params.id)\nif (!imageExists) {\n return res.status(404).send({ error: 'ID does not exist' })\n}\n\nres.status(200).sendFile(resolve(imageExists.path))\n")),(0,r.kt)("p",null,"If we find that, for some reason, the file no longer exists on the file system, we delete it from the database and return an error:"),(0,r.kt)("pre",null,(0,r.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js"',title:'"routes/images.js"'},"if (!fs.existsSync(imageExists.path)) {\n await ImageModel.findByIdAndDelete(req.params.id)\n return res.status(404).send({ error: 'image does not exist' })\n}\n")))}u.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/5bf5bdb1.9037623f.js b/assets/js/5bf5bdb1.f3df875c.js similarity index 99% rename from assets/js/5bf5bdb1.9037623f.js rename to assets/js/5bf5bdb1.f3df875c.js index f1fb202..c433db1 100644 --- a/assets/js/5bf5bdb1.9037623f.js +++ b/assets/js/5bf5bdb1.f3df875c.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[4199],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var o=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=o.createContext({}),u=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d=function(e){var t=u(e.components);return o.createElement(s.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=u(n),m=i,h=p["".concat(s,".").concat(m)]||p[m]||c[m]||r;return n?o.createElement(h,a(a({ref:t},d),{},{components:n})):o.createElement(h,a({ref:t},d))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:i,a[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>u});var o=n(7462),i=(n(7294),n(3905));const r={title:"Getting Started",description:"Club Website Developer Introduction",sidebar_position:1},a=void 0,l={unversionedId:"Developers/introduction",id:"Developers/introduction",title:"Getting Started",description:"Club Website Developer Introduction",source:"@site/docs/website/Developers/introduction.md",sourceDirName:"Developers",slug:"/Developers/introduction",permalink:"/docs/website/Developers/introduction",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Getting Started",description:"Club Website Developer Introduction",sidebar_position:1},sidebar:"defaultSidebar",previous:{title:"Admin Dashboard",permalink:"/docs/website/admin"},next:{title:"Usage & Configuration",permalink:"/docs/website/Developers/configuration"}},s={},u=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"System Development Libraries",id:"system-development-libraries",level:3},{value:"Installing Xcode Command Line Tools:",id:"installing-xcode-command-line-tools",level:4},{value:"Build Essential (for Linux)",id:"build-essential-for-linux",level:4},{value:"Git",id:"git",level:3},{value:"NodeJS & NPM",id:"nodejs--npm",level:3},{value:"Text Editor",id:"text-editor",level:3},{value:"Installation",id:"installation",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Beginner Resources",id:"beginner-resources",level:2}],d={toc:u},p="wrapper";function c(e){let{components:t,...n}=e;return(0,i.kt)(p,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"The OSC Club Website is built in NodeJS, using EJS as a frontend framework and ExpressJS for backend hosting. Our objective was to maximize resource-loading performance and consequently minimise resource sizes and overhead. For this reason, we opted against modern front-end frameworks (React, Angular, etc.) and instead built a dynamic full-stack site - essentially relying on the backend for processing, rather than serving a resource-heavy frontend that pulls data via APIs."),(0,i.kt)("p",null,"Moreover, we hoped that this approach would better support beginner programmers at the University of Florida in learning the fundamentals of web development: HTML, CSS, and vanilla JavaScript."),(0,i.kt)("p",null,"We've tried to make this guide as beginner-friendly as possible, however this ",(0,i.kt)("ins",null,"is not a tutorial of the various frameworks/libraries used"),". For beginner-friendly resources, refer to the ",(0,i.kt)("a",{parentName:"p",href:"#beginner-resources"},"resources")," section."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"The OSC website project requires certain dependencies to be installed on the user's machine."),(0,i.kt)("h3",{id:"system-development-libraries"},"System Development Libraries"),(0,i.kt)("p",null,"If you are using macOS, you will need to install Xcode Command Line Tools. These tools provide essential development libraries and utilities, including Git, which is required for the OSC website project and other development tasks."),(0,i.kt)("h4",{id:"installing-xcode-command-line-tools"},"Installing Xcode Command Line Tools:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},'Open Terminal, which can be found in the Utilities folder within the Applications folder, or you can use Spotlight search (Cmd + Space) and type "Terminal" to open it.'),(0,i.kt)("li",{parentName:"ol"},"Enter the following command:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"xcode-select --install\n")),(0,i.kt)("ol",{start:3},(0,i.kt)("li",{parentName:"ol"},'A dialog will pop up asking you to install the Xcode Command Line Tools. Click "Install" and follow the on-screen instructions.')),(0,i.kt)("h4",{id:"build-essential-for-linux"},"Build Essential (for Linux)"),(0,i.kt)("p",null,"If you are using a Linux distribution, you'll need to ensure you have the ",(0,i.kt)("inlineCode",{parentName:"p"},"build-essential")," package installed. This package includes essential tools for building software on a Linux system, such as compilers and libraries."),(0,i.kt)("p",null,"For Debian-based distributions (e.g., Ubuntu):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt update\nsudo apt install build-essential\n")),(0,i.kt)("p",null,"For Red Hat-based distributions (e.g., Fedora):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'sudo dnf groupinstall "Development Tools"\n')),(0,i.kt)("p",null,"For Arch Linux:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo pacman -S base-devel\n")),(0,i.kt)("p",null,"The installation process will depend on your specific Linux distribution. Once build-essential is installed, you'll have the necessary tools for development on your Linux system."),(0,i.kt)("h3",{id:"git"},"Git"),(0,i.kt)("p",null,"Git is a version control system that's necessary for installing the project and collaborating with others."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Visit the official Git website: ",(0,i.kt)("a",{parentName:"li",href:"https://git-scm.com/downloads"},"https://git-scm.com/downloads")),(0,i.kt)("li",{parentName:"ol"},"Download the installer for your operating system (Windows, macOS, or Linux)."),(0,i.kt)("li",{parentName:"ol"},"Run the installer and follow the on-screen instructions to install Git.")),(0,i.kt)("h3",{id:"nodejs--npm"},"NodeJS & NPM"),(0,i.kt)("p",null,"The OSC website website is built using NodeJS, so you'll need to have it installed prior to running the site."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Visit the official Node.js website: ",(0,i.kt)("a",{parentName:"li",href:"https://nodejs.org/"},"https://nodejs.org/")),(0,i.kt)("li",{parentName:"ol"},"Download the LTS (Long-Term Support) version for your operating system."),(0,i.kt)("li",{parentName:"ol"},"Run the installer and follow the installation instructions."),(0,i.kt)("li",{parentName:"ol"},"After installation, open your command line (Terminal on macOS/Linux, Command Prompt on Windows) and run the following commands to verify that Node.js and NPM are installed:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"node -v\nnpm -v\n")),(0,i.kt)("h3",{id:"text-editor"},"Text Editor"),(0,i.kt)("p",null,"You'll need a text editor to write and modify your Docusaurus project files. Many developers prefer using code editors with syntax highlighting and other useful features."),(0,i.kt)("p",null,"Some popular text editors and Integrated Development Environments (IDEs) for web development include:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Visual Studio Code: ",(0,i.kt)("a",{parentName:"li",href:"https://code.visualstudio.com/"},"https://code.visualstudio.com/")),(0,i.kt)("li",{parentName:"ol"},"Sublime Text: ",(0,i.kt)("a",{parentName:"li",href:"https://www.sublimetext.com/"},"https://www.sublimetext.com/")),(0,i.kt)("li",{parentName:"ol"},"Atom: ",(0,i.kt)("a",{parentName:"li",href:"https://atom.io/"},"https://atom.io/")),(0,i.kt)("li",{parentName:"ol"},"JetBrains WebStorm: ",(0,i.kt)("a",{parentName:"li",href:"https://www.jetbrains.com/webstorm/"},"https://www.jetbrains.com/webstorm/")),(0,i.kt)("li",{parentName:"ol"},"Emacs ",(0,i.kt)("a",{parentName:"li",href:"https://www.gnu.org/software/emacs/"},"https://www.gnu.org/software/emacs/")," (requires IQ > 160).")),(0,i.kt)("p",null,"Choose the one that suits your preferences and install it on your system."),(0,i.kt)("h2",{id:"installation"},"Installation"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Clone the Github Repository.")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/ufosc/Club_Website_2.git\n")),(0,i.kt)("ol",{start:2},(0,i.kt)("li",{parentName:"ol"},"Navigate to the downloaded directory.")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"cd Club_Website_2\n")),(0,i.kt)("ol",{start:3},(0,i.kt)("li",{parentName:"ol"},"Install NodeJS dependencies")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"npm i\n")),(0,i.kt)("h2",{id:"contributing"},"Contributing"),(0,i.kt)("p",null,"The OSC Website is distributed under the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/LICENSE.md"},"AGPL-3.0-or-later")," license. Aside from being open-source, the license asserts that anyone is free to run, modify, redistribute exact copies, and distribute modified versions of the project (in accordance with the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/LICENSE.md"},"AGPL-3.0-or-later license"),")."),(0,i.kt)("p",null,"To contribute or download the source code, refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2"},"Github Repository"),"."),(0,i.kt)("p",null,"Contributions must adhere to the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/CONTRIBUTING.md"},"contributing guide"),"."),(0,i.kt)("h2",{id:"beginner-resources"},"Beginner Resources"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.w3schools.com/html/"},"HTML Tutorial")," by W3Schools (interactive text)."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=pQN-pnXPaVg"},"Learn HTML by building a website")," by freeCodeCamp.org (youtube)."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=Oe421EPjeBE"},"NodeJS & ExpressJS Full Course")," by freeCodeCamp.org (youtube)."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=DvlyzDZDEq4"},"Build a Zoom Clone with NodeJS")," Basic NodeJS and EJS by Web Dev Simplified (youtube).")))}c.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[4199],{3905:(e,t,n)=>{n.d(t,{Zo:()=>d,kt:()=>h});var o=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function a(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var s=o.createContext({}),u=function(e){var t=o.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},d=function(e){var t=u(e.components);return o.createElement(s.Provider,{value:t},e.children)},p="mdxType",c={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,r=e.originalType,s=e.parentName,d=l(e,["components","mdxType","originalType","parentName"]),p=u(n),m=i,h=p["".concat(s,".").concat(m)]||p[m]||c[m]||r;return n?o.createElement(h,a(a({ref:t},d),{},{components:n})):o.createElement(h,a({ref:t},d))}));function h(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var r=n.length,a=new Array(r);a[0]=m;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[p]="string"==typeof e?e:i,a[1]=l;for(var u=2;u{n.r(t),n.d(t,{assets:()=>s,contentTitle:()=>a,default:()=>c,frontMatter:()=>r,metadata:()=>l,toc:()=>u});var o=n(7462),i=(n(7294),n(3905));const r={title:"Getting Started",description:"Club Website Developer Introduction",sidebar_position:1},a=void 0,l={unversionedId:"Developers/introduction",id:"Developers/introduction",title:"Getting Started",description:"Club Website Developer Introduction",source:"@site/docs/website/Developers/introduction.md",sourceDirName:"Developers",slug:"/Developers/introduction",permalink:"/docs/website/Developers/introduction",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/introduction.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Getting Started",description:"Club Website Developer Introduction",sidebar_position:1},sidebar:"defaultSidebar",previous:{title:"Admin Dashboard",permalink:"/docs/website/admin"},next:{title:"Usage & Configuration",permalink:"/docs/website/Developers/configuration"}},s={},u=[{value:"Prerequisites",id:"prerequisites",level:2},{value:"System Development Libraries",id:"system-development-libraries",level:3},{value:"Installing Xcode Command Line Tools:",id:"installing-xcode-command-line-tools",level:4},{value:"Build Essential (for Linux)",id:"build-essential-for-linux",level:4},{value:"Git",id:"git",level:3},{value:"NodeJS & NPM",id:"nodejs--npm",level:3},{value:"Text Editor",id:"text-editor",level:3},{value:"Installation",id:"installation",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Beginner Resources",id:"beginner-resources",level:2}],d={toc:u},p="wrapper";function c(e){let{components:t,...n}=e;return(0,i.kt)(p,(0,o.Z)({},d,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("p",null,"The OSC Club Website is built in NodeJS, using EJS as a frontend framework and ExpressJS for backend hosting. Our objective was to maximize resource-loading performance and consequently minimize resource sizes and overhead. For this reason, we opted against modern front-end frameworks (React, Angular, etc.) and instead built a dynamic full-stack site - essentially relying on the backend for processing, rather than serving a resource-heavy frontend that pulls data via APIs."),(0,i.kt)("p",null,"Moreover, we hoped that this approach would better support beginner programmers at the University of Florida in learning the fundamentals of web development: HTML, CSS, and vanilla JavaScript."),(0,i.kt)("p",null,"We've tried to make this guide as beginner-friendly as possible, however this ",(0,i.kt)("ins",null,"is not a tutorial of the various frameworks/libraries used"),". For beginner-friendly resources, refer to the ",(0,i.kt)("a",{parentName:"p",href:"#beginner-resources"},"resources")," section."),(0,i.kt)("h2",{id:"prerequisites"},"Prerequisites"),(0,i.kt)("p",null,"The OSC website project requires certain dependencies to be installed on the user's machine."),(0,i.kt)("h3",{id:"system-development-libraries"},"System Development Libraries"),(0,i.kt)("p",null,"If you are using macOS, you will need to install Xcode Command Line Tools. These tools provide essential development libraries and utilities, including Git, which is required for the OSC website project and other development tasks."),(0,i.kt)("h4",{id:"installing-xcode-command-line-tools"},"Installing Xcode Command Line Tools:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},'Open Terminal, which can be found in the Utilities folder within the Applications folder, or you can use Spotlight search (Cmd + Space) and type "Terminal" to open it.'),(0,i.kt)("li",{parentName:"ol"},"Enter the following command:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"xcode-select --install\n")),(0,i.kt)("ol",{start:3},(0,i.kt)("li",{parentName:"ol"},'A dialog will pop up asking you to install the Xcode Command Line Tools. Click "Install" and follow the on-screen instructions.')),(0,i.kt)("h4",{id:"build-essential-for-linux"},"Build Essential (for Linux)"),(0,i.kt)("p",null,"If you are using a Linux distribution, you'll need to ensure you have the ",(0,i.kt)("inlineCode",{parentName:"p"},"build-essential")," package installed. This package includes essential tools for building software on a Linux system, such as compilers and libraries."),(0,i.kt)("p",null,"For Debian-based distributions (e.g., Ubuntu):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt update\nsudo apt install build-essential\n")),(0,i.kt)("p",null,"For Red Hat-based distributions (e.g., Fedora):"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},'sudo dnf groupinstall "Development Tools"\n')),(0,i.kt)("p",null,"For Arch Linux:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"sudo pacman -S base-devel\n")),(0,i.kt)("p",null,"The installation process will depend on your specific Linux distribution. Once build-essential is installed, you'll have the necessary tools for development on your Linux system."),(0,i.kt)("h3",{id:"git"},"Git"),(0,i.kt)("p",null,"Git is a version control system that's necessary for installing the project and collaborating with others."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Visit the official Git website: ",(0,i.kt)("a",{parentName:"li",href:"https://git-scm.com/downloads"},"https://git-scm.com/downloads")),(0,i.kt)("li",{parentName:"ol"},"Download the installer for your operating system (Windows, macOS, or Linux)."),(0,i.kt)("li",{parentName:"ol"},"Run the installer and follow the on-screen instructions to install Git.")),(0,i.kt)("h3",{id:"nodejs--npm"},"NodeJS & NPM"),(0,i.kt)("p",null,"The OSC website website is built using NodeJS, so you'll need to have it installed prior to running the site."),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Visit the official Node.js website: ",(0,i.kt)("a",{parentName:"li",href:"https://nodejs.org/"},"https://nodejs.org/")),(0,i.kt)("li",{parentName:"ol"},"Download the LTS (Long-Term Support) version for your operating system."),(0,i.kt)("li",{parentName:"ol"},"Run the installer and follow the installation instructions."),(0,i.kt)("li",{parentName:"ol"},"After installation, open your command line (Terminal on macOS/Linux, Command Prompt on Windows) and run the following commands to verify that Node.js and NPM are installed:")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"node -v\nnpm -v\n")),(0,i.kt)("h3",{id:"text-editor"},"Text Editor"),(0,i.kt)("p",null,"You'll need a text editor to write and modify your Docusaurus project files. Many developers prefer using code editors with syntax highlighting and other useful features."),(0,i.kt)("p",null,"Some popular text editors and Integrated Development Environments (IDEs) for web development include:"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Visual Studio Code: ",(0,i.kt)("a",{parentName:"li",href:"https://code.visualstudio.com/"},"https://code.visualstudio.com/")),(0,i.kt)("li",{parentName:"ol"},"Sublime Text: ",(0,i.kt)("a",{parentName:"li",href:"https://www.sublimetext.com/"},"https://www.sublimetext.com/")),(0,i.kt)("li",{parentName:"ol"},"Atom: ",(0,i.kt)("a",{parentName:"li",href:"https://atom.io/"},"https://atom.io/")),(0,i.kt)("li",{parentName:"ol"},"JetBrains WebStorm: ",(0,i.kt)("a",{parentName:"li",href:"https://www.jetbrains.com/webstorm/"},"https://www.jetbrains.com/webstorm/")),(0,i.kt)("li",{parentName:"ol"},"Emacs ",(0,i.kt)("a",{parentName:"li",href:"https://www.gnu.org/software/emacs/"},"https://www.gnu.org/software/emacs/")," (requires IQ > 160).")),(0,i.kt)("p",null,"Choose the one that suits your preferences and install it on your system."),(0,i.kt)("h2",{id:"installation"},"Installation"),(0,i.kt)("ol",null,(0,i.kt)("li",{parentName:"ol"},"Clone the Github Repository.")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/ufosc/Club_Website_2.git\n")),(0,i.kt)("ol",{start:2},(0,i.kt)("li",{parentName:"ol"},"Navigate to the downloaded directory.")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"cd Club_Website_2\n")),(0,i.kt)("ol",{start:3},(0,i.kt)("li",{parentName:"ol"},"Install NodeJS dependencies")),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"npm i\n")),(0,i.kt)("h2",{id:"contributing"},"Contributing"),(0,i.kt)("p",null,"The OSC Website is distributed under the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/LICENSE.md"},"AGPL-3.0-or-later")," license. Aside from being open-source, the license asserts that anyone is free to run, modify, redistribute exact copies, and distribute modified versions of the project (in accordance with the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/LICENSE.md"},"AGPL-3.0-or-later license"),")."),(0,i.kt)("p",null,"To contribute or download the source code, refer to the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2"},"Github Repository"),"."),(0,i.kt)("p",null,"Contributions must adhere to the ",(0,i.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/CONTRIBUTING.md"},"contributing guide"),"."),(0,i.kt)("h2",{id:"beginner-resources"},"Beginner Resources"),(0,i.kt)("ul",null,(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.w3schools.com/html/"},"HTML Tutorial")," by W3Schools (interactive text)."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=pQN-pnXPaVg"},"Learn HTML by building a website")," by freeCodeCamp.org (youtube)."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=Oe421EPjeBE"},"NodeJS & ExpressJS Full Course")," by freeCodeCamp.org (youtube)."),(0,i.kt)("li",{parentName:"ul"},(0,i.kt)("a",{parentName:"li",href:"https://www.youtube.com/watch?v=DvlyzDZDEq4"},"Build a Zoom Clone with NodeJS")," Basic NodeJS and EJS by Web Dev Simplified (youtube).")))}c.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/6d49fdd4.2c3e450c.js b/assets/js/6d49fdd4.9efde4e5.js similarity index 78% rename from assets/js/6d49fdd4.2c3e450c.js rename to assets/js/6d49fdd4.9efde4e5.js index 26881e3..08ccae0 100644 --- a/assets/js/6d49fdd4.2c3e450c.js +++ b/assets/js/6d49fdd4.9efde4e5.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[2424],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>g});var n=a(7294);function l(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(l[a]=e[a]);return l}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(l[a]=e[a])}return l}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},d=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,l=e.mdxType,r=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),u=p(a),c=l,g=u["".concat(s,".").concat(c)]||u[c]||m[c]||r;return a?n.createElement(g,i(i({ref:t},d),{},{components:a})):n.createElement(g,i({ref:t},d))}));function g(e,t){var a=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var r=a.length,i=new Array(r);i[0]=c;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[u]="string"==typeof e?e:l,i[1]=o;for(var p=2;p{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>p});var n=a(7462),l=(a(7294),a(3905));const r={title:"Blog Route",description:"Club Website Developer API",sidebar_position:2},i="Blog Route",o={unversionedId:"Developers/API/blog",id:"Developers/API/blog",title:"Blog Route",description:"Club Website Developer API",source:"@site/docs/website/Developers/API/blog.md",sourceDirName:"Developers/API",slug:"/Developers/API/blog",permalink:"/docs/website/Developers/API/blog",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/API/blog.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Blog Route",description:"Club Website Developer API",sidebar_position:2},sidebar:"defaultSidebar",previous:{title:"API & Routes",permalink:"/docs/website/Developers/API/"},next:{title:"Contact Route",permalink:"/docs/website/Developers/API/contact"}},s={},p=[{value:"Bulk Retrieve Posts: (GET) /api/blog/",id:"bulk-retrieve-posts-get-apiblog",level:2},{value:"Request Parameters",id:"request-parameters",level:3},{value:"Sample Response",id:"sample-response",level:3},{value:"Example",id:"example",level:3},{value:"Fetch Article Page: (GET) api/blog/:id",id:"fetch-article-page-get-apiblogid",level:2},{value:"Request Parameters",id:"request-parameters-1",level:3},{value:"Example",id:"example-1",level:3},{value:"Create Article: (POST) /api/blog/",id:"create-article-post-apiblog",level:2},{value:"Request Parameters",id:"request-parameters-2",level:3},{value:"Response",id:"response",level:3},{value:"Example",id:"example-2",level:3},{value:"Modify Article: (PUT) api/blog/:id",id:"modify-article-put-apiblogid",level:2},{value:"Request Parameters",id:"request-parameters-3",level:3},{value:"Response",id:"response-1",level:3},{value:"Example",id:"example-3",level:3},{value:"Delete Article: (DELETE) api/blog/:id",id:"delete-article-delete-apiblogid",level:2},{value:"Request Parameters",id:"request-parameters-4",level:3},{value:"Response",id:"response-2",level:3},{value:"Example",id:"example-4",level:3}],d={toc:p},u="wrapper";function m(e){let{components:t,...a}=e;return(0,l.kt)(u,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"blog-route"},"Blog Route"),(0,l.kt)("p",null,"The blog route interfaces with the blog ",(0,l.kt)("a",{parentName:"p",href:"/docs/website/Developers/Databases/models"},"database model")," and dynamically renders blog articles."),(0,l.kt)("admonition",{title:"routes/blog.js",type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"The blog route is defined in ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/blog.js"},"/routes/blog.js")," and operates on the ",(0,l.kt)("inlineCode",{parentName:"p"},"/api/blog")," API path.")),(0,l.kt)("h2",{id:"bulk-retrieve-posts-get-apiblog"},"Bulk Retrieve Posts: (GET) /api/blog/"),(0,l.kt)("p",null,"To index posts in the /blog and /admin pages, it was necessary to implement a route which returned an index of the most recent posts. Unlike the ",(0,l.kt)("inlineCode",{parentName:"p"},"GET: /api/blog/:id")," route, which returns an HTML render of the blog, the ",(0,l.kt)("inlineCode",{parentName:"p"},"GET: /api/blog/")," route returns the underlying JSON objects."),(0,l.kt)("p",null,"Although authentication is optional, non-authenticated users can only retrieve posts that are marked ",(0,l.kt)("inlineCode",{parentName:"p"},"status: published"),"."),(0,l.kt)("h3",{id:"request-parameters"},"Request Parameters"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Auth cookie")))),(0,l.kt)("h3",{id:"sample-response"},"Sample Response"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="Content-Type: application/json"',title:'"Content-Type:','application/json"':!0},'[\n {\n "_id":"64be230c227074ba993f8e3f",\n "title":"post has been modified",\n "status":"draft",\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my modified article",\n "subtitle":"my draft",\n "author":["zeim839"],\n "date":"2023-07-24T07:06:52.208Z",\n "__v":0\n }\n]\n')),(0,l.kt)("p",null,"Empty response:"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="Content-Type: application/json"',title:'"Content-Type:','application/json"':!0},"[]\n")),(0,l.kt)("h3",{id:"example"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"curl -XGET 'https://ufosc.org/api/blog'\n")),(0,l.kt)("h2",{id:"fetch-article-page-get-apiblogid"},"Fetch Article Page: (GET) api/blog/:id"),(0,l.kt)("p",null,"This route fetches articles by the specified URL ID parameter and returns them as rendered HTML. An error article is rendered if the ID is invalid or non-existent."),(0,l.kt)("p",null,"Articles whose status is not 'published' (e.g 'draft') are only visible to authenticated users. They do not render on the /blog page, but may be accessed by authenticated users if their ID is known. Generally, authenticated users may access these posts by clicking on the 'preview' button alongside their table entries in the ",(0,l.kt)("a",{parentName:"p",href:"/docs/website/admin"},"admin dashboard"),"."),(0,l.kt)("h3",{id:"request-parameters-1"},"Request Parameters"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},":id (path)"),(0,l.kt)("td",{parentName:"tr",align:null},"ID of the requested blog post.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Auth cookie for accessing restricted posts.")))),(0,l.kt)("h3",{id:"example-1"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"curl -XGET 'https://ufosc.org/api/blog/'\n")),(0,l.kt)("h2",{id:"create-article-post-apiblog"},"Create Article: (POST) /api/blog/"),(0,l.kt)("p",null,"This route consumes a JSON body and produces a new blog article. This route requires authentication."),(0,l.kt)("h3",{id:"request-parameters-2"},"Request Parameters"),(0,l.kt)("p",null,"Request body: ",(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Auth cookie")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"title (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Article title")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"status (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Article status")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"previewImg (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article banner image URL")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"content (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article body text")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"subtitle (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article subtitle")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"author (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) JSON string array of author names")))),(0,l.kt)("h3",{id:"response"},"Response"),(0,l.kt)("p",null,"The server responds with the newly created JSON blog object."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="application/json"',title:'"application/json"'},'{\n "_id":"64be231938d6d068d0732b50",\n "title":"new post",\n "status":"published",\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my new article",\n "author":["zeim839"],\n "date":"2023-07-24T07:07:05.160Z","__v":0\n}\n')),(0,l.kt)("p",null,"If the request body is missing the required ",(0,l.kt)("inlineCode",{parentName:"p"},"title")," or ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," keys, the following error will be returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Missing field(s) in request body" }\n')),(0,l.kt)("p",null,"If the client attempts to manually assign an ID, by including an ",(0,l.kt)("inlineCode",{parentName:"p"},"_id")," or ",(0,l.kt)("inlineCode",{parentName:"p"},"id")," key in the request body, the following error will be returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Setting custom blog ID is prohibited" }\n')),(0,l.kt)("h3",{id:"example-2"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'curl -XPOST --cookie "jwt=" -H "Content-type: application/json" -d \'{\n "title":"my blog title,\n "status":"published"\n}\' \'https://ufosc.org/api/blog/\'\n')),(0,l.kt)("h2",{id:"modify-article-put-apiblogid"},"Modify Article: (PUT) api/blog/:id"),(0,l.kt)("p",null,"Modifies the existing article specified by the path parameter ':id'. This is an authenticated route."),(0,l.kt)("h3",{id:"request-parameters-3"},"Request Parameters"),(0,l.kt)("p",null,"Request body: ",(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},":id (path)"),(0,l.kt)("td",{parentName:"tr",align:null},"ID of the requested blog post.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Auth cookie")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"title (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article title")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"status (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article status")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"previewImg (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article banner image URL")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"content (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article body text")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"subtitle (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article subtitle")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"author (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) JSON string array of author names")))),(0,l.kt)("h3",{id:"response-1"},"Response"),(0,l.kt)("p",null,"The server responds with the modified JSON blog object"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="application/json"',title:'"application/json"'},'{\n "_id":"64be231938d6d068d0732b50",\n "title":"modified post",\n "status":"published",\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my modified article",\n "author":["zeim839"],\n "date":"2023-07-24T07:07:05.160Z","__v":0\n}\n')),(0,l.kt)("p",null,"If the ",(0,l.kt)("inlineCode",{parentName:"p"},"_id")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"date")," keys are ommitted, then the above response example may also be used as a sample request body. Note that all schema keys are optional: only the key/values that the client wishes to modify need to be specified."),(0,l.kt)("p",null,"If the ':id' parameter is invalid, the following JSON object is returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Invalid ID" }\n')),(0,l.kt)("p",null,"If the ID is valid but not longer exists, the following JSON object is returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "ID does not exist" }\n')),(0,l.kt)("p",null,"To maintain database collection consistency, and prevent unexpected collision/behavior from renamed article IDs, modifying the ID parameter of an article is prohibited. If a client attempts to send a JSON request body with an ",(0,l.kt)("inlineCode",{parentName:"p"},"id")," or ",(0,l.kt)("inlineCode",{parentName:"p"},"_id")," key, the following error will be returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Setting custom blog ID is prohibited" }\n')),(0,l.kt)("p",null,"If a client lacks sufficient authentication, a status 401-Forbidden error will be returned."),(0,l.kt)("h3",{id:"example-3"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'curl -XPUT --cookie "jwt=" -H "Content-type: application/json" -d \'{\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my modified article",\n "author":["zeim839"]\n}\' \'https://ufosc.org/api/blog/\'\n')),(0,l.kt)("h2",{id:"delete-article-delete-apiblogid"},"Delete Article: (DELETE) api/blog/:id"),(0,l.kt)("p",null,"Deletes the blog post specified by the path parameter ':id'. This is an authenticated route."),(0,l.kt)("h3",{id:"request-parameters-4"},"Request Parameters"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},":id (path)"),(0,l.kt)("td",{parentName:"tr",align:null},"ID of the requested blog post.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Auth cookie")))),(0,l.kt)("h3",{id:"response-2"},"Response"),(0,l.kt)("p",null,"The server responds with the JSON object of the deleted article."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="Content-Type: application/json"',title:'"Content-Type:','application/json"':!0},'{\n "_id":"64be231938d6d068d0732b50",\n "title":"test post",\n "status":"published",\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my article",\n "author":[],\n "date":"2023-07-24T07:07:05.160Z","__v":0\n}\n')),(0,l.kt)("p",null,"If the ':id' parameter is invalid, the following JSON object is returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Invalid ID" }\n')),(0,l.kt)("p",null,"If the ID is valid but not longer exists, the following JSON object is returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Blog not found" }\n')),(0,l.kt)("p",null,"If a client lacks sufficient authentication, a status 401-Forbidden error will be returned."),(0,l.kt)("h3",{id:"example-4"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"curl -XDELETE --cookie \"jwt=\" 'https://ufosc.org/api/blog/'\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[2424],{3905:(e,t,a)=>{a.d(t,{Zo:()=>d,kt:()=>g});var n=a(7294);function l(e,t,a){return t in e?Object.defineProperty(e,t,{value:a,enumerable:!0,configurable:!0,writable:!0}):e[t]=a,e}function r(e,t){var a=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),a.push.apply(a,n)}return a}function i(e){for(var t=1;t=0||(l[a]=e[a]);return l}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,a)&&(l[a]=e[a])}return l}var s=n.createContext({}),p=function(e){var t=n.useContext(s),a=t;return e&&(a="function"==typeof e?e(t):i(i({},t),e)),a},d=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},u="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var a=e.components,l=e.mdxType,r=e.originalType,s=e.parentName,d=o(e,["components","mdxType","originalType","parentName"]),u=p(a),c=l,g=u["".concat(s,".").concat(c)]||u[c]||m[c]||r;return a?n.createElement(g,i(i({ref:t},d),{},{components:a})):n.createElement(g,i({ref:t},d))}));function g(e,t){var a=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var r=a.length,i=new Array(r);i[0]=c;var o={};for(var s in t)hasOwnProperty.call(t,s)&&(o[s]=t[s]);o.originalType=e,o[u]="string"==typeof e?e:l,i[1]=o;for(var p=2;p{a.r(t),a.d(t,{assets:()=>s,contentTitle:()=>i,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>p});var n=a(7462),l=(a(7294),a(3905));const r={title:"Blog Route",description:"Club Website Developer API",sidebar_position:2},i="Blog Route",o={unversionedId:"Developers/API/blog",id:"Developers/API/blog",title:"Blog Route",description:"Club Website Developer API",source:"@site/docs/website/Developers/API/blog.md",sourceDirName:"Developers/API",slug:"/Developers/API/blog",permalink:"/docs/website/Developers/API/blog",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/API/blog.md",tags:[],version:"current",sidebarPosition:2,frontMatter:{title:"Blog Route",description:"Club Website Developer API",sidebar_position:2},sidebar:"defaultSidebar",previous:{title:"API & Routes",permalink:"/docs/website/Developers/API/"},next:{title:"Contact Route",permalink:"/docs/website/Developers/API/contact"}},s={},p=[{value:"Bulk Retrieve Posts: (GET) /api/blog/",id:"bulk-retrieve-posts-get-apiblog",level:2},{value:"Request Parameters",id:"request-parameters",level:3},{value:"Sample Response",id:"sample-response",level:3},{value:"Example",id:"example",level:3},{value:"Fetch Article Page: (GET) api/blog/:id",id:"fetch-article-page-get-apiblogid",level:2},{value:"Request Parameters",id:"request-parameters-1",level:3},{value:"Example",id:"example-1",level:3},{value:"Create Article: (POST) /api/blog/",id:"create-article-post-apiblog",level:2},{value:"Request Parameters",id:"request-parameters-2",level:3},{value:"Response",id:"response",level:3},{value:"Example",id:"example-2",level:3},{value:"Modify Article: (PUT) api/blog/:id",id:"modify-article-put-apiblogid",level:2},{value:"Request Parameters",id:"request-parameters-3",level:3},{value:"Response",id:"response-1",level:3},{value:"Example",id:"example-3",level:3},{value:"Delete Article: (DELETE) api/blog/:id",id:"delete-article-delete-apiblogid",level:2},{value:"Request Parameters",id:"request-parameters-4",level:3},{value:"Response",id:"response-2",level:3},{value:"Example",id:"example-4",level:3}],d={toc:p},u="wrapper";function m(e){let{components:t,...a}=e;return(0,l.kt)(u,(0,n.Z)({},d,a,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"blog-route"},"Blog Route"),(0,l.kt)("p",null,"The blog route interfaces with the blog ",(0,l.kt)("a",{parentName:"p",href:"/docs/website/Developers/Databases/models"},"database model")," and dynamically renders blog articles."),(0,l.kt)("admonition",{title:"routes/blog.js",type:"tip"},(0,l.kt)("p",{parentName:"admonition"},"The blog route is defined in ",(0,l.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/blog.js"},"/routes/blog.js")," and operates on the ",(0,l.kt)("inlineCode",{parentName:"p"},"/api/blog")," API path.")),(0,l.kt)("h2",{id:"bulk-retrieve-posts-get-apiblog"},"Bulk Retrieve Posts: (GET) /api/blog/"),(0,l.kt)("p",null,"To index posts in the /blog and /admin pages, it was necessary to implement a route which returned an index of the most recent posts. Unlike the ",(0,l.kt)("inlineCode",{parentName:"p"},"GET: /api/blog/:id")," route, which returns an HTML render of the blog, the ",(0,l.kt)("inlineCode",{parentName:"p"},"GET: /api/blog/")," route returns the underlying JSON objects."),(0,l.kt)("p",null,"Although authentication is optional, non-authenticated users can only retrieve posts that are marked ",(0,l.kt)("inlineCode",{parentName:"p"},"status: published"),"."),(0,l.kt)("h3",{id:"request-parameters"},"Request Parameters"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Auth cookie")))),(0,l.kt)("h3",{id:"sample-response"},"Sample Response"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="Content-Type: application/json"',title:'"Content-Type:','application/json"':!0},'[\n {\n "_id":"64be230c227074ba993f8e3f",\n "title":"post has been modified",\n "status":"draft",\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my modified article",\n "subtitle":"my draft",\n "author":["zeim839"],\n "date":"2023-07-24T07:06:52.208Z",\n "__v":0\n }\n]\n')),(0,l.kt)("p",null,"Empty response:"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="Content-Type: application/json"',title:'"Content-Type:','application/json"':!0},"[]\n")),(0,l.kt)("h3",{id:"example"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"curl -XGET 'https://ufosc.org/api/blog'\n")),(0,l.kt)("h2",{id:"fetch-article-page-get-apiblogid"},"Fetch Article Page: (GET) api/blog/:id"),(0,l.kt)("p",null,"This route fetches articles by the specified URL ID parameter and returns them as rendered HTML. An error article is rendered if the ID is invalid or non-existent."),(0,l.kt)("p",null,"Articles whose status is not 'published' (e.g 'draft') are only visible to authenticated users. They do not render on the /blog page, but may be accessed by authenticated users if their ID is known. Generally, authenticated users may access these posts by clicking on the 'preview' button alongside their table entries in the ",(0,l.kt)("a",{parentName:"p",href:"/docs/website/admin"},"admin dashboard"),"."),(0,l.kt)("h3",{id:"request-parameters-1"},"Request Parameters"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},":id (path)"),(0,l.kt)("td",{parentName:"tr",align:null},"ID of the requested blog post.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Auth cookie for accessing restricted posts.")))),(0,l.kt)("h3",{id:"example-1"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"curl -XGET 'https://ufosc.org/api/blog/'\n")),(0,l.kt)("h2",{id:"create-article-post-apiblog"},"Create Article: (POST) /api/blog/"),(0,l.kt)("p",null,"This route consumes a JSON body and produces a new blog article. This route requires authentication."),(0,l.kt)("h3",{id:"request-parameters-2"},"Request Parameters"),(0,l.kt)("p",null,"Request body: ",(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Auth cookie")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"title (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Article title")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"status (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Article status")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"previewImg (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article banner image URL")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"content (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article body text")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"subtitle (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article subtitle")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"author (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) JSON string array of author names")))),(0,l.kt)("h3",{id:"response"},"Response"),(0,l.kt)("p",null,"The server responds with the newly created JSON blog object."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="application/json"',title:'"application/json"'},'{\n "_id":"64be231938d6d068d0732b50",\n "title":"new post",\n "status":"published",\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my new article",\n "author":["zeim839"],\n "date":"2023-07-24T07:07:05.160Z","__v":0\n}\n')),(0,l.kt)("p",null,"If the request body is missing the required ",(0,l.kt)("inlineCode",{parentName:"p"},"title")," or ",(0,l.kt)("inlineCode",{parentName:"p"},"status")," keys, the following error will be returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Missing field(s) in request body" }\n')),(0,l.kt)("p",null,"If the client attempts to manually assign an ID, by including an ",(0,l.kt)("inlineCode",{parentName:"p"},"_id")," or ",(0,l.kt)("inlineCode",{parentName:"p"},"id")," key in the request body, the following error will be returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Setting custom blog ID is prohibited" }\n')),(0,l.kt)("h3",{id:"example-2"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'curl -XPOST --cookie "jwt=" -H "Content-type: application/json" -d \'{\n "title":"my blog title,\n "status":"published"\n}\' \'https://ufosc.org/api/blog/\'\n')),(0,l.kt)("h2",{id:"modify-article-put-apiblogid"},"Modify Article: (PUT) api/blog/:id"),(0,l.kt)("p",null,"Modifies the existing article specified by the path parameter ':id'. This is an authenticated route."),(0,l.kt)("h3",{id:"request-parameters-3"},"Request Parameters"),(0,l.kt)("p",null,"Request body: ",(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},":id (path)"),(0,l.kt)("td",{parentName:"tr",align:null},"ID of the requested blog post.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Auth cookie")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"title (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article title")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"status (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article status")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"previewImg (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article banner image URL")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"content (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article body text")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"subtitle (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) Article subtitle")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"author (body)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Optional) JSON string array of author names")))),(0,l.kt)("h3",{id:"response-1"},"Response"),(0,l.kt)("p",null,"The server responds with the modified JSON blog object"),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="application/json"',title:'"application/json"'},'{\n "_id":"64be231938d6d068d0732b50",\n "title":"modified post",\n "status":"published",\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my modified article",\n "author":["zeim839"],\n "date":"2023-07-24T07:07:05.160Z","__v":0\n}\n')),(0,l.kt)("p",null,"If the ",(0,l.kt)("inlineCode",{parentName:"p"},"_id")," and ",(0,l.kt)("inlineCode",{parentName:"p"},"date")," keys are omitted, then the above response example may also be used as a sample request body. Note that all schema keys are optional: only the key/values that the client wishes to modify need to be specified."),(0,l.kt)("p",null,"If the ':id' parameter is invalid, the following JSON object is returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Invalid ID" }\n')),(0,l.kt)("p",null,"If the ID is valid but not longer exists, the following JSON object is returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "ID does not exist" }\n')),(0,l.kt)("p",null,"To maintain database collection consistency, and prevent unexpected collision/behavior from renamed article IDs, modifying the ID parameter of an article is prohibited. If a client attempts to send a JSON request body with an ",(0,l.kt)("inlineCode",{parentName:"p"},"id")," or ",(0,l.kt)("inlineCode",{parentName:"p"},"_id")," key, the following error will be returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Setting custom blog ID is prohibited" }\n')),(0,l.kt)("p",null,"If a client lacks sufficient authentication, a status 401-Forbidden error will be returned."),(0,l.kt)("h3",{id:"example-3"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'curl -XPUT --cookie "jwt=" -H "Content-type: application/json" -d \'{\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my modified article",\n "author":["zeim839"]\n}\' \'https://ufosc.org/api/blog/\'\n')),(0,l.kt)("h2",{id:"delete-article-delete-apiblogid"},"Delete Article: (DELETE) api/blog/:id"),(0,l.kt)("p",null,"Deletes the blog post specified by the path parameter ':id'. This is an authenticated route."),(0,l.kt)("h3",{id:"request-parameters-4"},"Request Parameters"),(0,l.kt)("table",null,(0,l.kt)("thead",{parentName:"table"},(0,l.kt)("tr",{parentName:"thead"},(0,l.kt)("th",{parentName:"tr",align:null},"Parameter"),(0,l.kt)("th",{parentName:"tr",align:null},"Description"))),(0,l.kt)("tbody",{parentName:"table"},(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},":id (path)"),(0,l.kt)("td",{parentName:"tr",align:null},"ID of the requested blog post.")),(0,l.kt)("tr",{parentName:"tbody"},(0,l.kt)("td",{parentName:"tr",align:null},"JWT (cookie)"),(0,l.kt)("td",{parentName:"tr",align:null},"(Required) Auth cookie")))),(0,l.kt)("h3",{id:"response-2"},"Response"),(0,l.kt)("p",null,"The server responds with the JSON object of the deleted article."),(0,l.kt)("p",null,(0,l.kt)("inlineCode",{parentName:"p"},"Content-Type: application/json")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="Content-Type: application/json"',title:'"Content-Type:','application/json"':!0},'{\n "_id":"64be231938d6d068d0732b50",\n "title":"test post",\n "status":"published",\n "previewImg":"/assets/blog_default_img.jpeg",\n "content":"my article",\n "author":[],\n "date":"2023-07-24T07:07:05.160Z","__v":0\n}\n')),(0,l.kt)("p",null,"If the ':id' parameter is invalid, the following JSON object is returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Invalid ID" }\n')),(0,l.kt)("p",null,"If the ID is valid but not longer exists, the following JSON object is returned:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json",metastring:'title="routes/blog.js"',title:'"routes/blog.js"'},'{ "error": "Blog not found" }\n')),(0,l.kt)("p",null,"If a client lacks sufficient authentication, a status 401-Forbidden error will be returned."),(0,l.kt)("h3",{id:"example-4"},"Example"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"curl -XDELETE --cookie \"jwt=\" 'https://ufosc.org/api/blog/'\n")))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/8161bbfb.e3ac6688.js b/assets/js/8161bbfb.56c6e6c0.js similarity index 87% rename from assets/js/8161bbfb.e3ac6688.js rename to assets/js/8161bbfb.56c6e6c0.js index e446f65..1d96f9d 100644 --- a/assets/js/8161bbfb.e3ac6688.js +++ b/assets/js/8161bbfb.56c6e6c0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[4672],{3905:(e,t,i)=>{i.d(t,{Zo:()=>u,kt:()=>k});var n=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function r(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function o(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):o(o({},t),e)),i},u=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var i=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=p(i),c=a,k=m["".concat(s,".").concat(c)]||m[c]||d[c]||r;return i?n.createElement(k,o(o({ref:t},u),{},{components:i})):n.createElement(k,o({ref:t},u))}));function k(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=i.length,o=new Array(r);o[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:a,o[1]=l;for(var p=2;p{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var n=i(7462),a=(i(7294),i(3905));const r={title:"Contributing Guide",description:"Club Website Developer Contributing Guide",sidebar_position:9},o="Contributing Guide",l={unversionedId:"Developers/contributing-guide",id:"Developers/contributing-guide",title:"Contributing Guide",description:"Club Website Developer Contributing Guide",source:"@site/docs/website/Developers/contributing-guide.md",sourceDirName:"Developers",slug:"/Developers/contributing-guide",permalink:"/docs/website/Developers/contributing-guide",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/contributing-guide.md",tags:[],version:"current",sidebarPosition:9,frontMatter:{title:"Contributing Guide",description:"Club Website Developer Contributing Guide",sidebar_position:9},sidebar:"defaultSidebar",previous:{title:"Testing & Linting",permalink:"/docs/website/Developers/testing"},next:{title:"API Reference",permalink:"/docs/website/api-reference"}},s={},p=[{value:"Table of contents",id:"table-of-contents",level:2},{value:"Contribution workflow",id:"contribution-workflow",level:2},{value:"Commit Messages",id:"commit-messages",level:2},{value:"Writing messages",id:"writing-messages",level:3},{value:"Message prefixes",id:"message-prefixes",level:3},{value:"Pull Requests",id:"pull-requests",level:2},{value:"Opening issues",id:"opening-issues",level:2},{value:"Feature proposals",id:"feature-proposals",level:3},{value:"Bugs and errors",id:"bugs-and-errors",level:3},{value:"Typos",id:"typos",level:3},{value:"Fixing issues and implementing proposals",id:"fixing-issues-and-implementing-proposals",level:3},{value:"Standard README",id:"standard-readme",level:2},{value:"Standard JS",id:"standard-js",level:2},{value:"Labels",id:"labels",level:2},{value:"Maintainers",id:"maintainers",level:2}],u={toc:p},m="wrapper";function d(e){let{components:t,...i}=e;return(0,a.kt)(m,(0,n.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"contributing-guide"},"Contributing Guide"),(0,a.kt)("admonition",{title:"Static Copy",type:"danger"},(0,a.kt)("p",{parentName:"admonition"},"This is a copy of the contributing guide originally hosted on Github, reproduced here solely for presentation purposes. It may not be up-to-date. Developers should refer to the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/CONTRIBUTING.md"},"original copy")," whenever possible.")),(0,a.kt)("p",null,"The OSC website is free and open source software, all contributions are welcome and appreciated so long as they comply with AGPL-3.0-or-later licensing. To expedite the submission and review process, we urge all contributors to familiarize themselves with the following contribution guidelines."),(0,a.kt)("h2",{id:"table-of-contents"},"Table of contents"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#contribution-workflow"},"Contribution Workflow")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#commit-messages"},"Commit Messages"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#writing-messages"},"Writing Messages")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#message-prefixes"},"Message Prefixes")))),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#pull-requests"},"Pull Requests")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#opening-issues"},"Opening Issues"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#feature-proposals"},"Feature Proposals")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#bugs-and-errors"},"Bugs & Errors")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#typos"},"Typos")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#fixing-issues-and-implementing-proposals"},"Fixing Issues & Implementing Proposals")))),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#standard-readme"},"Standard README")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#standard-js"},"Standard JS")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#labels"},"Labels")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#maintainers"},"Maintainers"))),(0,a.kt)("h2",{id:"contribution-workflow"},"Contribution workflow"),(0,a.kt)("p",null,"Always discuss big changes by speaking with your group, by contacting a maintainer or by opening a discussion issue (see ",(0,a.kt)("a",{parentName:"p",href:"#opening-issues"},"opening issues"),")."),(0,a.kt)("p",null,"Suggested workflow:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"(Optional) fork the project repository."),(0,a.kt)("li",{parentName:"ol"},"Checkout a new branch from ",(0,a.kt)("inlineCode",{parentName:"li"},"main"),".",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"ALWAYS branch from the latest version of ",(0,a.kt)("inlineCode",{parentName:"li"},"main"),"."),(0,a.kt)("li",{parentName:"ul"},"Each PR/feature goes on its own branch (again, branched from ",(0,a.kt)("inlineCode",{parentName:"li"},"main"),"). This ensures that new features are not dependent on uncommitted code."))),(0,a.kt)("li",{parentName:"ol"},"Commit changes",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Refer to ",(0,a.kt)("a",{parentName:"li",href:"#commit-messages"},"Commit Messages")," for writing commit messages."),(0,a.kt)("li",{parentName:"ul"},'Each commit should be small and specific, don\'t try to push large/generic commits like "updated app" or "updated to requested changes".'),(0,a.kt)("li",{parentName:"ul"},"Each commit should describe a change to the codebase. You can nest multiple files under a commit, as long as the message applies to both."),(0,a.kt)("li",{parentName:"ul"},"Small, specific commits allow maintainers to easily revert/modify changes, keep track of versions and detect problems."),(0,a.kt)("li",{parentName:"ul"},"Messed up your commit history? Its ok, maintainers are the ones ultimately responsible for maintaining messages."))),(0,a.kt)("li",{parentName:"ol"},"Write unit tests (if needed)."),(0,a.kt)("li",{parentName:"ol"},"Once you're finished making changes...",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Open a terminal and run ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run test")," to test your code."),(0,a.kt)("li",{parentName:"ul"},"If tests fail, it's your responsibility to fix breaking changes."),(0,a.kt)("li",{parentName:"ul"},"Lint your code with ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run fix"),". This will (try to) automatically fix your code syntax for you."),(0,a.kt)("li",{parentName:"ul"},"Run ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run lint")," to check for any remaining syntax issues. Please fix these."))),(0,a.kt)("li",{parentName:"ol"},"Push to origin with ",(0,a.kt)("inlineCode",{parentName:"li"},"git push origin [your branch name]")," on your terminal."),(0,a.kt)("li",{parentName:"ol"},"Create a pull request.",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"If you've made changes to a fork, make sure you're opening a pull request to the original remote repository."),(0,a.kt)("li",{parentName:"ul"},"Always open PR's on the ",(0,a.kt)("inlineCode",{parentName:"li"},"main")," branch unless otherwise instructed. Convoluted merge histories create dependency hell and are hard to review."),(0,a.kt)("li",{parentName:"ul"},"Add a descriptive title and describe your changes."),(0,a.kt)("li",{parentName:"ul"},"Refer to ",(0,a.kt)("a",{parentName:"li",href:"#pull-requests"},"Pull Requests")))),(0,a.kt)("li",{parentName:"ol"},"Wait for your code to be reviewed and repeat steps 3-6 for any requested changes.")),(0,a.kt)("h2",{id:"commit-messages"},"Commit Messages"),(0,a.kt)("p",null,"Commits and commit messages should be written for each (loosely) independent change made. It goes without saying that messages should be as specific as possible - if a change can't be described in a single sentence then it probably has to be broken down into multiple commits."),(0,a.kt)("p",null,"Messed up your commit history? That's ok, maintainers are the ones ultimately responsible for maintaining commit messages."),(0,a.kt)("h3",{id:"writing-messages"},"Writing messages"),(0,a.kt)("p",null,"That said, avoid commiting large changes all at once: messages like ",(0,a.kt)("inlineCode",{parentName:"p"},"updated app")," or ",(0,a.kt)("inlineCode",{parentName:"p"},"fixed problem")," should be broken down into their specific constituents. For example:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"fixed problem")," should ideally be broken up into multiple commits like ",(0,a.kt)("inlineCode",{parentName:"li"},"fix: added missing form validation")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"fix: typo"),"."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"updated app"),": What exactly did you update and how did you do it? Break up each change into a commit like ",(0,a.kt)("inlineCode",{parentName:"li"},"feat: added form element for xyz"),", or ",(0,a.kt)("inlineCode",{parentName:"li"},"feat: added password field"),".")),(0,a.kt)("h3",{id:"message-prefixes"},"Message prefixes"),(0,a.kt)("p",null,"We recommend adding the following prefixes to your commit messages. These aren't necessary, but they keep the commit history clean-looking:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"feat: ..."),": For new features."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"docs: ..."),": For adding or changing documentation"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ci: ..."),": For modifying CI, jobs or workflows"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"fix: ..."),": For when you've fixed something."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lint: ..."),": For when you've fixed/changed code syntax."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"refactor: ..."),": For when you've rewritten or reorganized something. Use this if you've moved files or created folders. This is different from ",(0,a.kt)("inlineCode",{parentName:"li"},"lint")," because it doesn't necessarily describe syntactical changes, it describes organizational changes."),(0,a.kt)("li",{parentName:"ul"},"Does your specific change not apply to any of these? Use your own best judgement.")),(0,a.kt)("h2",{id:"pull-requests"},"Pull Requests"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Always discuss big changes with by speaking to your group, by contacting a maintainer or by opening a discussion issue (see ",(0,a.kt)("a",{parentName:"li",href:"#opening-issues"},"opening issues"),"). This increases the likelihood that they'll be accepted."),(0,a.kt)("li",{parentName:"ol"},"Always open pull requests on the ",(0,a.kt)("inlineCode",{parentName:"li"},"main")," branch."),(0,a.kt)("li",{parentName:"ol"},"Each branch and pull request should only feature 1 significant change. We might like one feature but not like the other - if they're on separate PRs we can approve/reject them easily, otherwise you'll have to do a lot of refactoring."),(0,a.kt)("li",{parentName:"ol"},"Add an appropriate title. Like commit messages, your PR titles should be intuitive to understand and should give a good overview of what you've accomplished."),(0,a.kt)("li",{parentName:"ol"},"Add a description. Explain what you've done and why you've done it - it might be useful to include code blocks and explain your reasoning.")),(0,a.kt)("h2",{id:"opening-issues"},"Opening issues"),(0,a.kt)("h3",{id:"feature-proposals"},"Feature proposals"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Add an appropriate title."),(0,a.kt)("li",{parentName:"ol"},"Explain your proposed feature and why it might be useful."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Suggest an approach/method for it to be done."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Request to be assigned if you want to implement the proposal yourself."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Add the github ",(0,a.kt)("inlineCode",{parentName:"li"},"proposal")," issue label.")),(0,a.kt)("h3",{id:"bugs-and-errors"},"Bugs and errors"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Add an appropriate title."),(0,a.kt)("li",{parentName:"ol"},"Explain the bug/error you've encountered."),(0,a.kt)("li",{parentName:"ol"},"Add a list of steps to reproduce the problem."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Add a screenshot."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Add the github ",(0,a.kt)("inlineCode",{parentName:"li"},"bug")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"error")," label.")),(0,a.kt)("h3",{id:"typos"},"Typos"),(0,a.kt)("p",null,"Dont open issues for typos, just fix them and create a PR."),(0,a.kt)("h3",{id:"fixing-issues-and-implementing-proposals"},"Fixing issues and implementing proposals"),(0,a.kt)("p",null,"Please ask (by replying to the conversation) before trying to fix an issue or implement a feature proposal. Don't waste your time: the issue might be outdated, someone else might already be assigned or we might be waiting for more information."),(0,a.kt)("h2",{id:"standard-readme"},"Standard README"),(0,a.kt)("p",null,"This repository adheres to the README standard style described ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/RichardLitt/standard-readme"},"here"),". Please adhere to the standard when making or requesting changes."),(0,a.kt)("p",null,"Maintainers are responsible for enforcement."),(0,a.kt)("h2",{id:"standard-js"},"Standard JS"),(0,a.kt)("p",null,"This repository adheres to Javascript Standard syntax described ",(0,a.kt)("a",{parentName:"p",href:"https://standardjs.com/"},"here"),". Contributors can run ",(0,a.kt)("inlineCode",{parentName:"p"},"npm run lint")," to list syntax issues that need to be fixed for adherence, or ",(0,a.kt)("inlineCode",{parentName:"p"},"npm run fix")," to (try to) automatically fix some of them."),(0,a.kt)("p",null,"Maintainers are responsible for enforcement."),(0,a.kt)("h2",{id:"labels"},"Labels"),(0,a.kt)("p",null,"Refer to this guideline on what labels to use and look for when deciding on what to contribute to."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"bug/error"),": Something isn't working properly."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"difficulty"),": How hard the issue is to resolve (easy, medium, hard)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"discussion"),": Should be discussed before moving forward."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"documentation"),": Related to the documentation."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"duplicate"),": It already exists."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"good first issue"),": Friendly for beginners to work on."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"help wanted"),": Someone is needed to work on it."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"priority"),": How important it needs to be worked on (low, medium, high)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"proposal"),": Brings up a new idea."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"question"),": Requesting more information."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"wontfix"),": Won't be worked on anymore.")),(0,a.kt)("h2",{id:"maintainers"},"Maintainers"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Review all PRs before merging."),(0,a.kt)("li",{parentName:"ol"},"When upgarding the release version:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Create a ",(0,a.kt)("inlineCode",{parentName:"li"},"BUMP X.X.X")," commit message (where ",(0,a.kt)("inlineCode",{parentName:"li"},"X.X.X")," is the version). If anyone ever wants to revert to a particular version, they can just modify the git history head to point to this commit."),(0,a.kt)("li",{parentName:"ul"},"The ",(0,a.kt)("inlineCode",{parentName:"li"},"package.json")," contains a version tag, make sure it gets updated."),(0,a.kt)("li",{parentName:"ul"},"Create a github release."))),(0,a.kt)("li",{parentName:"ol"},"Enforce Standard README style."),(0,a.kt)("li",{parentName:"ol"},"Enforce unit testing: ask contributors to write unit tests and fix failing PRs."),(0,a.kt)("li",{parentName:"ol"},"Enforce Javascript Standard style: ask contributors to ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run lint")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run fix"),"."),(0,a.kt)("li",{parentName:"ol"},"Enforce commit history: rebase commit messages if required."),(0,a.kt)("li",{parentName:"ol"},"Discuss big changes with the group."),(0,a.kt)("li",{parentName:"ol"},"Ask another maintainer to peer-review your code.")))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[4672],{3905:(e,t,i)=>{i.d(t,{Zo:()=>u,kt:()=>k});var n=i(7294);function a(e,t,i){return t in e?Object.defineProperty(e,t,{value:i,enumerable:!0,configurable:!0,writable:!0}):e[t]=i,e}function r(e,t){var i=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),i.push.apply(i,n)}return i}function o(e){for(var t=1;t=0||(a[i]=e[i]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,i)&&(a[i]=e[i])}return a}var s=n.createContext({}),p=function(e){var t=n.useContext(s),i=t;return e&&(i="function"==typeof e?e(t):o(o({},t),e)),i},u=function(e){var t=p(e.components);return n.createElement(s.Provider,{value:t},e.children)},m="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},c=n.forwardRef((function(e,t){var i=e.components,a=e.mdxType,r=e.originalType,s=e.parentName,u=l(e,["components","mdxType","originalType","parentName"]),m=p(i),c=a,k=m["".concat(s,".").concat(c)]||m[c]||d[c]||r;return i?n.createElement(k,o(o({ref:t},u),{},{components:i})):n.createElement(k,o({ref:t},u))}));function k(e,t){var i=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=i.length,o=new Array(r);o[0]=c;var l={};for(var s in t)hasOwnProperty.call(t,s)&&(l[s]=t[s]);l.originalType=e,l[m]="string"==typeof e?e:a,o[1]=l;for(var p=2;p{i.r(t),i.d(t,{assets:()=>s,contentTitle:()=>o,default:()=>d,frontMatter:()=>r,metadata:()=>l,toc:()=>p});var n=i(7462),a=(i(7294),i(3905));const r={title:"Contributing Guide",description:"Club Website Developer Contributing Guide",sidebar_position:9},o="Contributing Guide",l={unversionedId:"Developers/contributing-guide",id:"Developers/contributing-guide",title:"Contributing Guide",description:"Club Website Developer Contributing Guide",source:"@site/docs/website/Developers/contributing-guide.md",sourceDirName:"Developers",slug:"/Developers/contributing-guide",permalink:"/docs/website/Developers/contributing-guide",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/contributing-guide.md",tags:[],version:"current",sidebarPosition:9,frontMatter:{title:"Contributing Guide",description:"Club Website Developer Contributing Guide",sidebar_position:9},sidebar:"defaultSidebar",previous:{title:"Testing & Linting",permalink:"/docs/website/Developers/testing"},next:{title:"API Reference",permalink:"/docs/website/api-reference"}},s={},p=[{value:"Table of contents",id:"table-of-contents",level:2},{value:"Contribution workflow",id:"contribution-workflow",level:2},{value:"Commit Messages",id:"commit-messages",level:2},{value:"Writing messages",id:"writing-messages",level:3},{value:"Message prefixes",id:"message-prefixes",level:3},{value:"Pull Requests",id:"pull-requests",level:2},{value:"Opening issues",id:"opening-issues",level:2},{value:"Feature proposals",id:"feature-proposals",level:3},{value:"Bugs and errors",id:"bugs-and-errors",level:3},{value:"Typos",id:"typos",level:3},{value:"Fixing issues and implementing proposals",id:"fixing-issues-and-implementing-proposals",level:3},{value:"Standard README",id:"standard-readme",level:2},{value:"Standard JS",id:"standard-js",level:2},{value:"Labels",id:"labels",level:2},{value:"Maintainers",id:"maintainers",level:2}],u={toc:p},m="wrapper";function d(e){let{components:t,...i}=e;return(0,a.kt)(m,(0,n.Z)({},u,i,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"contributing-guide"},"Contributing Guide"),(0,a.kt)("admonition",{title:"Static Copy",type:"danger"},(0,a.kt)("p",{parentName:"admonition"},"This is a copy of the contributing guide originally hosted on Github, reproduced here solely for presentation purposes. It may not be up-to-date. Developers should refer to the ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/CONTRIBUTING.md"},"original copy")," whenever possible.")),(0,a.kt)("p",null,"The OSC website is free and open source software, all contributions are welcome and appreciated so long as they comply with AGPL-3.0-or-later licensing. To expedite the submission and review process, we urge all contributors to familiarize themselves with the following contribution guidelines."),(0,a.kt)("h2",{id:"table-of-contents"},"Table of contents"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#contribution-workflow"},"Contribution Workflow")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#commit-messages"},"Commit Messages"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#writing-messages"},"Writing Messages")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#message-prefixes"},"Message Prefixes")))),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#pull-requests"},"Pull Requests")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#opening-issues"},"Opening Issues"),(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#feature-proposals"},"Feature Proposals")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#bugs-and-errors"},"Bugs & Errors")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#typos"},"Typos")),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("a",{parentName:"li",href:"#fixing-issues-and-implementing-proposals"},"Fixing Issues & Implementing Proposals")))),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#standard-readme"},"Standard README")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#standard-js"},"Standard JS")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#labels"},"Labels")),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("a",{parentName:"li",href:"#maintainers"},"Maintainers"))),(0,a.kt)("h2",{id:"contribution-workflow"},"Contribution workflow"),(0,a.kt)("p",null,"Always discuss big changes by speaking with your group, by contacting a maintainer or by opening a discussion issue (see ",(0,a.kt)("a",{parentName:"p",href:"#opening-issues"},"opening issues"),")."),(0,a.kt)("p",null,"Suggested workflow:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"(Optional) fork the project repository."),(0,a.kt)("li",{parentName:"ol"},"Checkout a new branch from ",(0,a.kt)("inlineCode",{parentName:"li"},"main"),".",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"ALWAYS branch from the latest version of ",(0,a.kt)("inlineCode",{parentName:"li"},"main"),"."),(0,a.kt)("li",{parentName:"ul"},"Each PR/feature goes on its own branch (again, branched from ",(0,a.kt)("inlineCode",{parentName:"li"},"main"),"). This ensures that new features are not dependent on uncommitted code."))),(0,a.kt)("li",{parentName:"ol"},"Commit changes",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Refer to ",(0,a.kt)("a",{parentName:"li",href:"#commit-messages"},"Commit Messages")," for writing commit messages."),(0,a.kt)("li",{parentName:"ul"},'Each commit should be small and specific, don\'t try to push large/generic commits like "updated app" or "updated to requested changes".'),(0,a.kt)("li",{parentName:"ul"},"Each commit should describe a change to the codebase. You can nest multiple files under a commit, as long as the message applies to both."),(0,a.kt)("li",{parentName:"ul"},"Small, specific commits allow maintainers to easily revert/modify changes, keep track of versions and detect problems."),(0,a.kt)("li",{parentName:"ul"},"Messed up your commit history? Its ok, maintainers are the ones ultimately responsible for maintaining messages."))),(0,a.kt)("li",{parentName:"ol"},"Write unit tests (if needed)."),(0,a.kt)("li",{parentName:"ol"},"Once you're finished making changes...",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Open a terminal and run ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run test")," to test your code."),(0,a.kt)("li",{parentName:"ul"},"If tests fail, it's your responsibility to fix breaking changes."),(0,a.kt)("li",{parentName:"ul"},"Lint your code with ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run fix"),". This will (try to) automatically fix your code syntax for you."),(0,a.kt)("li",{parentName:"ul"},"Run ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run lint")," to check for any remaining syntax issues. Please fix these."))),(0,a.kt)("li",{parentName:"ol"},"Push to origin with ",(0,a.kt)("inlineCode",{parentName:"li"},"git push origin [your branch name]")," on your terminal."),(0,a.kt)("li",{parentName:"ol"},"Create a pull request.",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"If you've made changes to a fork, make sure you're opening a pull request to the original remote repository."),(0,a.kt)("li",{parentName:"ul"},"Always open PR's on the ",(0,a.kt)("inlineCode",{parentName:"li"},"main")," branch unless otherwise instructed. Convoluted merge histories create dependency hell and are hard to review."),(0,a.kt)("li",{parentName:"ul"},"Add a descriptive title and describe your changes."),(0,a.kt)("li",{parentName:"ul"},"Refer to ",(0,a.kt)("a",{parentName:"li",href:"#pull-requests"},"Pull Requests")))),(0,a.kt)("li",{parentName:"ol"},"Wait for your code to be reviewed and repeat steps 3-6 for any requested changes.")),(0,a.kt)("h2",{id:"commit-messages"},"Commit Messages"),(0,a.kt)("p",null,"Commits and commit messages should be written for each (loosely) independent change made. It goes without saying that messages should be as specific as possible - if a change can't be described in a single sentence then it probably has to be broken down into multiple commits."),(0,a.kt)("p",null,"Messed up your commit history? That's ok, maintainers are the ones ultimately responsible for maintaining commit messages."),(0,a.kt)("h3",{id:"writing-messages"},"Writing messages"),(0,a.kt)("p",null,"That said, avoid commiting large changes all at once: messages like ",(0,a.kt)("inlineCode",{parentName:"p"},"updated app")," or ",(0,a.kt)("inlineCode",{parentName:"p"},"fixed problem")," should be broken down into their specific constituents. For example:"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"fixed problem")," should ideally be broken up into multiple commits like ",(0,a.kt)("inlineCode",{parentName:"li"},"fix: added missing form validation")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"fix: typo"),"."),(0,a.kt)("li",{parentName:"ol"},(0,a.kt)("inlineCode",{parentName:"li"},"updated app"),": What exactly did you update and how did you do it? Break up each change into a commit like ",(0,a.kt)("inlineCode",{parentName:"li"},"feat: added form element for xyz"),", or ",(0,a.kt)("inlineCode",{parentName:"li"},"feat: added password field"),".")),(0,a.kt)("h3",{id:"message-prefixes"},"Message prefixes"),(0,a.kt)("p",null,"We recommend adding the following prefixes to your commit messages. These aren't necessary, but they keep the commit history clean-looking:"),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"feat: ..."),": For new features."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"docs: ..."),": For adding or changing documentation"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"ci: ..."),": For modifying CI, jobs or workflows"),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"fix: ..."),": For when you've fixed something."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"lint: ..."),": For when you've fixed/changed code syntax."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"refactor: ..."),": For when you've rewritten or reorganized something. Use this if you've moved files or created folders. This is different from ",(0,a.kt)("inlineCode",{parentName:"li"},"lint")," because it doesn't necessarily describe syntactical changes, it describes organizational changes."),(0,a.kt)("li",{parentName:"ul"},"Does your specific change not apply to any of these? Use your own best judgment.")),(0,a.kt)("h2",{id:"pull-requests"},"Pull Requests"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Always discuss big changes with by speaking to your group, by contacting a maintainer or by opening a discussion issue (see ",(0,a.kt)("a",{parentName:"li",href:"#opening-issues"},"opening issues"),"). This increases the likelihood that they'll be accepted."),(0,a.kt)("li",{parentName:"ol"},"Always open pull requests on the ",(0,a.kt)("inlineCode",{parentName:"li"},"main")," branch."),(0,a.kt)("li",{parentName:"ol"},"Each branch and pull request should only feature 1 significant change. We might like one feature but not like the other - if they're on separate PRs we can approve/reject them easily, otherwise you'll have to do a lot of refactoring."),(0,a.kt)("li",{parentName:"ol"},"Add an appropriate title. Like commit messages, your PR titles should be intuitive to understand and should give a good overview of what you've accomplished."),(0,a.kt)("li",{parentName:"ol"},"Add a description. Explain what you've done and why you've done it - it might be useful to include code blocks and explain your reasoning.")),(0,a.kt)("h2",{id:"opening-issues"},"Opening issues"),(0,a.kt)("h3",{id:"feature-proposals"},"Feature proposals"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Add an appropriate title."),(0,a.kt)("li",{parentName:"ol"},"Explain your proposed feature and why it might be useful."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Suggest an approach/method for it to be done."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Request to be assigned if you want to implement the proposal yourself."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Add the github ",(0,a.kt)("inlineCode",{parentName:"li"},"proposal")," issue label.")),(0,a.kt)("h3",{id:"bugs-and-errors"},"Bugs and errors"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Add an appropriate title."),(0,a.kt)("li",{parentName:"ol"},"Explain the bug/error you've encountered."),(0,a.kt)("li",{parentName:"ol"},"Add a list of steps to reproduce the problem."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Add a screenshot."),(0,a.kt)("li",{parentName:"ol"},"(Optional) Add the github ",(0,a.kt)("inlineCode",{parentName:"li"},"bug")," or ",(0,a.kt)("inlineCode",{parentName:"li"},"error")," label.")),(0,a.kt)("h3",{id:"typos"},"Typos"),(0,a.kt)("p",null,"Don't open issues for typos, just fix them and create a PR."),(0,a.kt)("h3",{id:"fixing-issues-and-implementing-proposals"},"Fixing issues and implementing proposals"),(0,a.kt)("p",null,"Please ask (by replying to the conversation) before trying to fix an issue or implement a feature proposal. Don't waste your time: the issue might be outdated, someone else might already be assigned or we might be waiting for more information."),(0,a.kt)("h2",{id:"standard-readme"},"Standard README"),(0,a.kt)("p",null,"This repository adheres to the README standard style described ",(0,a.kt)("a",{parentName:"p",href:"https://github.com/RichardLitt/standard-readme"},"here"),". Please adhere to the standard when making or requesting changes."),(0,a.kt)("p",null,"Maintainers are responsible for enforcement."),(0,a.kt)("h2",{id:"standard-js"},"Standard JS"),(0,a.kt)("p",null,"This repository adheres to Javascript Standard syntax described ",(0,a.kt)("a",{parentName:"p",href:"https://standardjs.com/"},"here"),". Contributors can run ",(0,a.kt)("inlineCode",{parentName:"p"},"npm run lint")," to list syntax issues that need to be fixed for adherence, or ",(0,a.kt)("inlineCode",{parentName:"p"},"npm run fix")," to (try to) automatically fix some of them."),(0,a.kt)("p",null,"Maintainers are responsible for enforcement."),(0,a.kt)("h2",{id:"labels"},"Labels"),(0,a.kt)("p",null,"Refer to this guideline on what labels to use and look for when deciding on what to contribute to."),(0,a.kt)("ul",null,(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"bug/error"),": Something isn't working properly."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"difficulty"),": How hard the issue is to resolve (easy, medium, hard)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"discussion"),": Should be discussed before moving forward."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"documentation"),": Related to the documentation."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"duplicate"),": It already exists."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"good first issue"),": Friendly for beginners to work on."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"help wanted"),": Someone is needed to work on it."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"priority"),": How important it needs to be worked on (low, medium, high)."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"proposal"),": Brings up a new idea."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"question"),": Requesting more information."),(0,a.kt)("li",{parentName:"ul"},(0,a.kt)("inlineCode",{parentName:"li"},"wontfix"),": Won't be worked on anymore.")),(0,a.kt)("h2",{id:"maintainers"},"Maintainers"),(0,a.kt)("ol",null,(0,a.kt)("li",{parentName:"ol"},"Review all PRs before merging."),(0,a.kt)("li",{parentName:"ol"},"When upgrading the release version:",(0,a.kt)("ul",{parentName:"li"},(0,a.kt)("li",{parentName:"ul"},"Create a ",(0,a.kt)("inlineCode",{parentName:"li"},"BUMP X.X.X")," commit message (where ",(0,a.kt)("inlineCode",{parentName:"li"},"X.X.X")," is the version). If anyone ever wants to revert to a particular version, they can just modify the git history head to point to this commit."),(0,a.kt)("li",{parentName:"ul"},"The ",(0,a.kt)("inlineCode",{parentName:"li"},"package.json")," contains a version tag, make sure it gets updated."),(0,a.kt)("li",{parentName:"ul"},"Create a github release."))),(0,a.kt)("li",{parentName:"ol"},"Enforce Standard README style."),(0,a.kt)("li",{parentName:"ol"},"Enforce unit testing: ask contributors to write unit tests and fix failing PRs."),(0,a.kt)("li",{parentName:"ol"},"Enforce Javascript Standard style: ask contributors to ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run lint")," and ",(0,a.kt)("inlineCode",{parentName:"li"},"npm run fix"),"."),(0,a.kt)("li",{parentName:"ol"},"Enforce commit history: rebase commit messages if required."),(0,a.kt)("li",{parentName:"ol"},"Discuss big changes with the group."),(0,a.kt)("li",{parentName:"ol"},"Ask another maintainer to peer-review your code.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9232a1e9.0f2bbcc7.js b/assets/js/9232a1e9.0f2bbcc7.js deleted file mode 100644 index 031868f..0000000 --- a/assets/js/9232a1e9.0f2bbcc7.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[779],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>g});var o=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=o.createContext({}),d=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},l=function(e){var t=d(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=i,g=u["".concat(c,".").concat(m)]||u[m]||p[m]||a;return n?o.createElement(g,r(r({ref:t},l),{},{components:n})):o.createElement(g,r({ref:t},l))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,r=new Array(a);r[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,r[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>d});var o=n(7462),i=(n(7294),n(3905));const a={title:"Documentation",description:"OSC Docs Writing Documentation",sidebar_position:5},r="Writing Documentation",s={unversionedId:"writingdocs",id:"writingdocs",title:"Documentation",description:"OSC Docs Writing Documentation",source:"@site/docs/osc-docs/writingdocs.md",sourceDirName:".",slug:"/writingdocs",permalink:"/docs/osc-docs/writingdocs",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/osc-docs/writingdocs.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{title:"Documentation",description:"OSC Docs Writing Documentation",sidebar_position:5},sidebar:"defaultSidebar",previous:{title:"Markdown",permalink:"/docs/osc-docs/markdown"},next:{title:"Static Pages",permalink:"/docs/osc-docs/static-pages"}},c={},d=[{value:"Documentation Site Structure",id:"documentation-site-structure",level:2},{value:"Pages",id:"pages",level:3},{value:"Folders",id:"folders",level:3},{value:"Customizing Order & Titles",id:"customizing-order--titles",level:3},{value:"Writing Documentation",id:"writing-documentation-1",level:2},{value:"Creating sub-sites",id:"creating-sub-sites",level:2},{value:"Previewing your Changes Live",id:"previewing-your-changes-live",level:2}],l={toc:d},u="wrapper";function p(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"writing-documentation"},"Writing Documentation"),(0,i.kt)("p",null,"Docusaurus is a powerful tool for creating documentation websites with ease. It simplifies the process of creating, organizing, and publishing documentation using Markdown as the primary content format. Markdown is a lightweight markup language that allows you to write formatted text, you can read more about it at the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/markdown"},"Markdown Guide")," page."),(0,i.kt)("admonition",{title:"Installing the Project",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"It is highly recommended to have the OSC Docs repository installed on your system prior to modifying the codebase. Installation of OSC Docs is documented in the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/installation"},"Installation")," guide.")),(0,i.kt)("h2",{id:"documentation-site-structure"},"Documentation Site Structure"),(0,i.kt)("p",null,"Unlike most Docusaurus sites, which host documentation for a single project, the OSC Docs website organizes multiple projects into separate documentation sites (henceforth referred to as \"sub-sites\"). Each documentation sub-site resides in the project's 'docs' directory. In each sub-site's folder, a series of sub-folders and markdown files are stored. Docusaurus parses their structure and generates documentation sites automatically."),(0,i.kt)("h3",{id:"pages"},"Pages"),(0,i.kt)("p",null,"Each file in a sub-site's folder will generate a separate documentation page. If there are multiple files in one folder, they will appear in alphabetical order"),(0,i.kt)("img",{src:"/img/osc-docs/osc-docs-structure-2.png",style:{width:"100%",maxWidth:600,border:"2px solid black"}}),(0,i.kt)("img",{src:"/img/osc-docs/osc-docs-structure-1.png",style:{width:"100%",maxWidth:600,border:"2px solid black"}}),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"Each file in the documentation directory appears as an entry (in alphabetical order) in the sub-site's navigation bar. If an 'index.md' file is added, then that'll be the first page visitors see when they navigate to the sub-site.")),(0,i.kt)("h3",{id:"folders"},"Folders"),(0,i.kt)("p",null,"Similarly, you can create sub-folders to your documentation sub-site. Creating a folder in the sub-site directory and adding at least one file to it will create a dropdown menu in the sub-site's navigation bar."),(0,i.kt)("img",{src:"/img/osc-docs/osc-docs-structure-3.png",style:{width:"100%",maxWidth:600,border:"2px solid black"}}),(0,i.kt)("img",{src:"/img/osc-docs/osc-docs-structure-4.png",style:{width:"100%",maxWidth:600,border:"2px solid black"}}),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Sometimes, you might need to stop & restart docusaurus for new folders to take effect. Also, make sure that at least 1 file has been added to the sub-folder.")),(0,i.kt)("h3",{id:"customizing-order--titles"},"Customizing Order & Titles"),(0,i.kt)("p",null,"If you wish to name a navigation menu page something other than its file name, you can add a metadata section to your markdown file, as in the example below:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-markdown"},"---\ntitle: Introduction\ndescription: OSC Docs Introduction\nsidebar_position: 1\n---\n")),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"sidebar_position")," key can also be used to rearrange the page's position in the navigation menu."),(0,i.kt)("p",null,"To customize folders and sub-menus, a separate metadata file needs to be created within the folder. The file must be called ",(0,i.kt)("inlineCode",{parentName:"p"},"_category_.json"),", and assume the structure below:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "position": 3,\n "label": "Developers",\n "collapsible": true,\n "collapsed": true,\n}\n')),(0,i.kt)("h2",{id:"writing-documentation-1"},"Writing Documentation"),(0,i.kt)("p",null,"Documentation is written in Markdown format. To learn about the basics of Markdown, see the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/markdown"},"Markdown")," guide."),(0,i.kt)("p",null,"To modify existing documentation, navigate to your desired project's subsite directory, and open your desired markdown (.md) file. Alternatively, if you wish to add a new page, simply create a new file and write up its content with ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/markdown"},"Markdown"),"."),(0,i.kt)("h2",{id:"creating-sub-sites"},"Creating sub-sites"),(0,i.kt)("p",null,"If, instead of modifying or adding to the documentation of an existing project, you wish to create a separate documentation site for a different project, you can do so by modifying the ",(0,i.kt)("inlineCode",{parentName:"p"},"docusaurus.config.js")," file."),(0,i.kt)("p",null,"To add a new subsite, first make sure that you've created a subfolder for your project in the 'docs' directory. Then, navigate to the ",(0,i.kt)("inlineCode",{parentName:"p"},"plugins")," section in ",(0,i.kt)("inlineCode",{parentName:"p"},"docusaurus.config.js")," and append your desired information into the array:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config.js"',title:'"docusaurus.config.js"'},"{\n plugins: [\n [\n '@docusaurus/plugin-content-docs',\n {\n id: 'website', // a unique ID for your project\n path: 'docs/website', // the path to your docs folder\n routeBasePath: 'docs/website', // the path on the website's URL\n editUrl: 'https://github.com/ufosc/osc-docs'\n }\n ],\n ]\n}\n")),(0,i.kt)("p",null,"To add your subsite to the website's navigation bar, navigate to the ",(0,i.kt)("inlineCode",{parentName:"p"},"themeConfig")," property in ",(0,i.kt)("inlineCode",{parentName:"p"},"docusaurus.config.js")," and add the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config.js"',title:'"docusaurus.config.js"'},"navbar: {\n title: 'OSC Docs',\n logo: {\n alt: 'OSC Logo',\n src: 'img/logo.png'\n },\n items: [\n // ....\n {\n to: 'docs/club', // Your subsite routeBasePath\n label: 'Club Archive', // Label to appear on the navmenu.\n position: 'left'\n }\n // ...\n ]\n}\n")),(0,i.kt)("h2",{id:"previewing-your-changes-live"},"Previewing your Changes Live"),(0,i.kt)("p",null,"Starting a docusaurus server will allow you to instantly preview your markdown changes on your browser. It can be started by navigating to your project's directory, opening a terminal, and typing in the following command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"npm start\n")),(0,i.kt)("p",null,"For more information, see the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/usage"},"Usage")," section. You must have the project and its dependencies installed, if you dont, then refer to the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/installation"},"Installation")," guide."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9232a1e9.fb92e7c6.js b/assets/js/9232a1e9.fb92e7c6.js new file mode 100644 index 0000000..4ec9db0 --- /dev/null +++ b/assets/js/9232a1e9.fb92e7c6.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[779],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>g});var o=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);t&&(o=o.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,o)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(o=0;o=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var c=o.createContext({}),d=function(e){var t=o.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},l=function(e){var t=d(e.components);return o.createElement(c.Provider,{value:t},e.children)},u="mdxType",p={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},m=o.forwardRef((function(e,t){var n=e.components,i=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=d(n),m=i,g=u["".concat(c,".").concat(m)]||u[m]||p[m]||a;return n?o.createElement(g,r(r({ref:t},l),{},{components:n})):o.createElement(g,r({ref:t},l))}));function g(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var a=n.length,r=new Array(a);r[0]=m;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:i,r[1]=s;for(var d=2;d{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>p,frontMatter:()=>a,metadata:()=>s,toc:()=>d});var o=n(7462),i=(n(7294),n(3905));const a={title:"Documentation",description:"OSC Docs Writing Documentation",sidebar_position:5},r="Writing Documentation",s={unversionedId:"writingdocs",id:"writingdocs",title:"Documentation",description:"OSC Docs Writing Documentation",source:"@site/docs/osc-docs/writingdocs.md",sourceDirName:".",slug:"/writingdocs",permalink:"/docs/osc-docs/writingdocs",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/osc-docs/writingdocs.md",tags:[],version:"current",sidebarPosition:5,frontMatter:{title:"Documentation",description:"OSC Docs Writing Documentation",sidebar_position:5},sidebar:"defaultSidebar",previous:{title:"Markdown",permalink:"/docs/osc-docs/markdown"},next:{title:"Static Pages",permalink:"/docs/osc-docs/static-pages"}},c={},d=[{value:"Documentation Site Structure",id:"documentation-site-structure",level:2},{value:"Pages",id:"pages",level:3},{value:"Folders",id:"folders",level:3},{value:"Customizing Order & Titles",id:"customizing-order--titles",level:3},{value:"Writing Documentation",id:"writing-documentation-1",level:2},{value:"Creating sub-sites",id:"creating-sub-sites",level:2},{value:"Previewing your Changes Live",id:"previewing-your-changes-live",level:2}],l={toc:d},u="wrapper";function p(e){let{components:t,...n}=e;return(0,i.kt)(u,(0,o.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,i.kt)("h1",{id:"writing-documentation"},"Writing Documentation"),(0,i.kt)("p",null,"Docusaurus is a powerful tool for creating documentation websites with ease. It simplifies the process of creating, organizing, and publishing documentation using Markdown as the primary content format. Markdown is a lightweight markup language that allows you to write formatted text, you can read more about it at the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/markdown"},"Markdown Guide")," page."),(0,i.kt)("admonition",{title:"Installing the Project",type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"It is highly recommended to have the OSC Docs repository installed on your system prior to modifying the code base. Installation of OSC Docs is documented in the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/installation"},"Installation")," guide.")),(0,i.kt)("h2",{id:"documentation-site-structure"},"Documentation Site Structure"),(0,i.kt)("p",null,"Unlike most Docusaurus sites, which host documentation for a single project, the OSC Docs website organizes multiple projects into separate documentation sites (henceforth referred to as \"sub-sites\"). Each documentation sub-site resides in the project's 'docs' directory. In each sub-site's folder, a series of sub-folders and markdown files are stored. Docusaurus parses their structure and generates documentation sites automatically."),(0,i.kt)("h3",{id:"pages"},"Pages"),(0,i.kt)("p",null,"Each file in a sub-site's folder will generate a separate documentation page. If there are multiple files in one folder, they will appear in alphabetical order"),(0,i.kt)("img",{src:"/img/osc-docs/osc-docs-structure-2.png",style:{width:"100%",maxWidth:600,border:"2px solid black"}}),(0,i.kt)("img",{src:"/img/osc-docs/osc-docs-structure-1.png",style:{width:"100%",maxWidth:600,border:"2px solid black"}}),(0,i.kt)("admonition",{type:"tip"},(0,i.kt)("p",{parentName:"admonition"},"Each file in the documentation directory appears as an entry (in alphabetical order) in the sub-site's navigation bar. If an 'index.md' file is added, then that'll be the first page visitors see when they navigate to the sub-site.")),(0,i.kt)("h3",{id:"folders"},"Folders"),(0,i.kt)("p",null,"Similarly, you can create sub-folders to your documentation sub-site. Creating a folder in the sub-site directory and adding at least one file to it will create a dropdown menu in the sub-site's navigation bar."),(0,i.kt)("img",{src:"/img/osc-docs/osc-docs-structure-3.png",style:{width:"100%",maxWidth:600,border:"2px solid black"}}),(0,i.kt)("img",{src:"/img/osc-docs/osc-docs-structure-4.png",style:{width:"100%",maxWidth:600,border:"2px solid black"}}),(0,i.kt)("admonition",{type:"caution"},(0,i.kt)("p",{parentName:"admonition"},"Sometimes, you might need to stop & restart docusaurus for new folders to take effect. Also, make sure that at least 1 file has been added to the sub-folder.")),(0,i.kt)("h3",{id:"customizing-order--titles"},"Customizing Order & Titles"),(0,i.kt)("p",null,"If you wish to name a navigation menu page something other than its file name, you can add a metadata section to your markdown file, as in the example below:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-markdown"},"---\ntitle: Introduction\ndescription: OSC Docs Introduction\nsidebar_position: 1\n---\n")),(0,i.kt)("p",null,"The ",(0,i.kt)("inlineCode",{parentName:"p"},"sidebar_position")," key can also be used to rearrange the page's position in the navigation menu."),(0,i.kt)("p",null,"To customize folders and sub-menus, a separate metadata file needs to be created within the folder. The file must be called ",(0,i.kt)("inlineCode",{parentName:"p"},"_category_.json"),", and assume the structure below:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-json"},'{\n "position": 3,\n "label": "Developers",\n "collapsible": true,\n "collapsed": true,\n}\n')),(0,i.kt)("h2",{id:"writing-documentation-1"},"Writing Documentation"),(0,i.kt)("p",null,"Documentation is written in Markdown format. To learn about the basics of Markdown, see the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/markdown"},"Markdown")," guide."),(0,i.kt)("p",null,"To modify existing documentation, navigate to your desired project's subsite directory, and open your desired markdown (.md) file. Alternatively, if you wish to add a new page, simply create a new file and write up its content with ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/markdown"},"Markdown"),"."),(0,i.kt)("h2",{id:"creating-sub-sites"},"Creating sub-sites"),(0,i.kt)("p",null,"If, instead of modifying or adding to the documentation of an existing project, you wish to create a separate documentation site for a different project, you can do so by modifying the ",(0,i.kt)("inlineCode",{parentName:"p"},"docusaurus.config.js")," file."),(0,i.kt)("p",null,"To add a new subsite, first make sure that you've created a subfolder for your project in the 'docs' directory. Then, navigate to the ",(0,i.kt)("inlineCode",{parentName:"p"},"plugins")," section in ",(0,i.kt)("inlineCode",{parentName:"p"},"docusaurus.config.js")," and append your desired information into the array:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config.js"',title:'"docusaurus.config.js"'},"{\n plugins: [\n [\n '@docusaurus/plugin-content-docs',\n {\n id: 'website', // a unique ID for your project\n path: 'docs/website', // the path to your docs folder\n routeBasePath: 'docs/website', // the path on the website's URL\n editUrl: 'https://github.com/ufosc/osc-docs'\n }\n ],\n ]\n}\n")),(0,i.kt)("p",null,"To add your subsite to the website's navigation bar, navigate to the ",(0,i.kt)("inlineCode",{parentName:"p"},"themeConfig")," property in ",(0,i.kt)("inlineCode",{parentName:"p"},"docusaurus.config.js")," and add the following:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config.js"',title:'"docusaurus.config.js"'},"navbar: {\n title: 'OSC Docs',\n logo: {\n alt: 'OSC Logo',\n src: 'img/logo.png'\n },\n items: [\n // ....\n {\n to: 'docs/club', // Your subsite routeBasePath\n label: 'Club Archive', // Label to appear on the navmenu.\n position: 'left'\n }\n // ...\n ]\n}\n")),(0,i.kt)("h2",{id:"previewing-your-changes-live"},"Previewing your Changes Live"),(0,i.kt)("p",null,"Starting a docusaurus server will allow you to instantly preview your markdown changes on your browser. It can be started by navigating to your project's directory, opening a terminal, and typing in the following command:"),(0,i.kt)("pre",null,(0,i.kt)("code",{parentName:"pre",className:"language-bash"},"npm start\n")),(0,i.kt)("p",null,"For more information, see the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/usage"},"Usage")," section. You must have the project and its dependencies installed, if you don't, then refer to the ",(0,i.kt)("a",{parentName:"p",href:"/docs/osc-docs/installation"},"Installation")," guide."))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/9b50b30c.224cf55c.js b/assets/js/9b50b30c.61c7fd87.js similarity index 63% rename from assets/js/9b50b30c.224cf55c.js rename to assets/js/9b50b30c.61c7fd87.js index 77b9604..36929b7 100644 --- a/assets/js/9b50b30c.224cf55c.js +++ b/assets/js/9b50b30c.61c7fd87.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[9197],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>g});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},m=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,m=i(e,["components","mdxType","originalType","parentName"]),p=c(n),u=o,g=p["".concat(l,".").concat(u)]||p[u]||d[u]||s;return n?a.createElement(g,r(r({ref:t},m),{},{components:n})):a.createElement(g,r({ref:t},m))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,r=new Array(s);r[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:o,r[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var a=n(7462),o=(n(7294),n(3905));const s={title:"Using MongoDB",description:"Club Website Developer Database",sidebar_position:1},r="Using MongoDB",i={unversionedId:"Developers/Databases/mongodb",id:"Developers/Databases/mongodb",title:"Using MongoDB",description:"Club Website Developer Database",source:"@site/docs/website/Developers/Databases/mongodb.md",sourceDirName:"Developers/Databases",slug:"/Developers/Databases/mongodb",permalink:"/docs/website/Developers/Databases/mongodb",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/Databases/mongodb.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Using MongoDB",description:"Club Website Developer Database",sidebar_position:1},sidebar:"defaultSidebar",previous:{title:"Rendering Pages",permalink:"/docs/website/Developers/rendering"},next:{title:"Database Models",permalink:"/docs/website/Developers/Databases/models"}},l={},c=[{value:"Mongoose Basics",id:"mongoose-basics",level:2},{value:"Example 1",id:"example-1",level:3},{value:"Example 2",id:"example-2",level:3},{value:"Database.js",id:"databasejs",level:2},{value:"Setting up your own database",id:"setting-up-your-own-database",level:2}],m={toc:c},p="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"using-mongodb"},"Using MongoDB"),(0,o.kt)("p",null,"The website uses ",(0,o.kt)("a",{parentName:"p",href:"https://www.mongodb.com/"},"MongoDB"),", a document-oriented database program, to fetch and serve information for the backend. When running in a development environment, the backend is automatically configured to connect to a public OSC testing database. This section documents the basic prolegomena of operating and managing the OSC Website database."),(0,o.kt)("p",null,"For the OSC testing URI, see ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/utils/config.js#L3"},"here")," (note that the database is public and volatile, and not meant for production environments). For instructions on changing environments or configuring your own Mongo connection URI, see ",(0,o.kt)("a",{parentName:"p",href:"/docs/website/Developers/configuration"},"here"),"."),(0,o.kt)("h2",{id:"mongoose-basics"},"Mongoose Basics"),(0,o.kt)("p",null,"The project uses the ",(0,o.kt)("a",{parentName:"p",href:"https://mongoosejs.com/"},"Mongoose")," library as an abstraction over the default MongoDB NodeJS package. Mongoose organizes database structures into schemas and models (analogous to schemas in SQL) that automatically validate and enforce rules on database entries. For instance:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="model/images.js"',title:'"model/images.js"'},"const mongoose = require('mongoose')\n\nconst ImageSchema = new mongoose.Schema({\n filename: {\n type: String,\n required: true\n },\n description: {\n type: String,\n required: true\n },\n path: {\n type: String,\n required: true\n },\n date: {\n type: Date,\n required: true,\n default: Date.now\n }\n})\n\nconst ImageModel = mongoose.model('image', ImageSchema)\nmodule.exports = { ImageSchema, ImageModel }\n")),(0,o.kt)("p",null,"In the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/model/images.js"},"source above"),", an ",(0,o.kt)("inlineCode",{parentName:"p"},"ImageSchema")," is defined. The schema defines ",(0,o.kt)("inlineCode",{parentName:"p"},"filename, description, path, and date")," as properties of the 'Image' object. Similarly, it enforces certain rules over these properties: that 'filename' is a required string, that 'date' is a required JavaScript 'Date' object with a default value, etc."),(0,o.kt)("p",null,"Furthermore, Mongoose allows us to formalize a 'model' from this schema, in this case, it is named ",(0,o.kt)("inlineCode",{parentName:"p"},"ImageModel"),". The ",(0,o.kt)("inlineCode",{parentName:"p"},"ImageModel")," acts as a driver to our database's 'Image' collection (collections are structures similar to tables in SQL). Once the model is created, it is exported and ready to be used in other files. What follows is a series of code examples drawn from the website sourcecode that illustrate what models are capable of:"),(0,o.kt)("h3",{id:"example-1"},"Example 1"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js:32"',title:'"routes/images.js:32"'},"const images = await ImageModel.find().sort({ date: -1 })\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/images.js#L32"},"example")," above fetches all images in the database and sorts them in descending (-1) date order."),(0,o.kt)("h3",{id:"example-2"},"Example 2"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js:68"',title:'"routes/images.js:68"'},"const image = new ImageModel({\n filename: req.file.filename,\n description: req.body.Description,\n path: req.file.path\n})\n\nimage.save((err) => {\n if (err) return res.status(500).send({ error: 'Internal Server Error' })\n})\n")),(0,o.kt)("p",null,"In the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/images.js#L68C3-L76C5"},"example")," above, a new ",(0,o.kt)("ins",null,"instance")," of an ",(0,o.kt)("inlineCode",{parentName:"p"},"ImageModel")," with some given data, automatically validates it to make sure it matches the schema we've defined, and then attempts to save it to the database."),(0,o.kt)("admonition",{title:"Further Reading",type:"info"},(0,o.kt)("p",{parentName:"admonition"},"To learn more about Mongoose and MongoDB, refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://mongoosejs.com/docs/index.html"},"Mongoose Documentation")," and the ",(0,o.kt)("a",{parentName:"p",href:"https://www.mongodb.com/languages/mongodb-with-nodejs"},"MongoDB NodeJS documentation"),".")),(0,o.kt)("h2",{id:"databasejs"},"Database.js"),(0,o.kt)("p",null,"The database connection URI is configured in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/utils/config.js"},"utils/config.js"),", whilst the effective database connection configuration happens in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/utils/database.js"},"utils/database.js"),". The database utility modularizes the connection (allowing us to handle the connection in multiple files simultaneously), whilst also implementing various event listeners:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="utils/database.js"',title:'"utils/database.js"'},"mongoose.connection.on('connected', () => {\n // CONNECTION SUCCEEDED...\n})\n\nmongoose.connection.on('error', (error) => {\n // CONNECTION FAILED...\n})\n\nmongoose.connection.on('disconnected', () => {\n // DISCONNECTED...\n})\n\nprocess.on('SIGINT', (error, data) => {\n // SIGINT: User stopped the program.\n})\n")),(0,o.kt)("p",null,"Database.js is imported, and a database connection is subsequently opened in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/app.js#L81"},"main.js"),"."),(0,o.kt)("h2",{id:"setting-up-your-own-database"},"Setting up your own database"),(0,o.kt)("p",null,"If you're interested in hosting your own instance of the website, you'll need to set up your own MongoDB node. The MongoDB team currently offers free (but limited) database hosting on their ",(0,o.kt)("a",{parentName:"p",href:"https://www.mongodb.com/atlas"},"MongoDB Atlas")," platform. Alternatively, you can set up MongoDB ",(0,o.kt)("a",{parentName:"p",href:"https://www.mongodb.com/try/download/community"},"community edition"),' on your machine and host your own instance for "free."'))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[9197],{3905:(e,t,n)=>{n.d(t,{Zo:()=>m,kt:()=>g});var a=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function s(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var l=a.createContext({}),c=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},m=function(e){var t=c(e.components);return a.createElement(l.Provider,{value:t},e.children)},p="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,m=i(e,["components","mdxType","originalType","parentName"]),p=c(n),u=o,g=p["".concat(l,".").concat(u)]||p[u]||d[u]||s;return n?a.createElement(g,r(r({ref:t},m),{},{components:n})):a.createElement(g,r({ref:t},m))}));function g(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=n.length,r=new Array(s);r[0]=u;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:o,r[1]=i;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>r,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>c});var a=n(7462),o=(n(7294),n(3905));const s={title:"Using MongoDB",description:"Club Website Developer Database",sidebar_position:1},r="Using MongoDB",i={unversionedId:"Developers/Databases/mongodb",id:"Developers/Databases/mongodb",title:"Using MongoDB",description:"Club Website Developer Database",source:"@site/docs/website/Developers/Databases/mongodb.md",sourceDirName:"Developers/Databases",slug:"/Developers/Databases/mongodb",permalink:"/docs/website/Developers/Databases/mongodb",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/Databases/mongodb.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"Using MongoDB",description:"Club Website Developer Database",sidebar_position:1},sidebar:"defaultSidebar",previous:{title:"Rendering Pages",permalink:"/docs/website/Developers/rendering"},next:{title:"Database Models",permalink:"/docs/website/Developers/Databases/models"}},l={},c=[{value:"Mongoose Basics",id:"mongoose-basics",level:2},{value:"Example 1",id:"example-1",level:3},{value:"Example 2",id:"example-2",level:3},{value:"Database.js",id:"databasejs",level:2},{value:"Setting up your own database",id:"setting-up-your-own-database",level:2}],m={toc:c},p="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(p,(0,a.Z)({},m,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"using-mongodb"},"Using MongoDB"),(0,o.kt)("p",null,"The website uses ",(0,o.kt)("a",{parentName:"p",href:"https://www.mongodb.com/"},"MongoDB"),", a document-oriented database program, to fetch and serve information for the backend. When running in a development environment, the backend is automatically configured to connect to a public OSC testing database. This section documents the basic prolegomena of operating and managing the OSC Website database."),(0,o.kt)("p",null,"For the OSC testing URI, see ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/utils/config.js#L3"},"here")," (note that the database is public and volatile, and not meant for production environments). For instructions on changing environments or configuring your own Mongo connection URI, see ",(0,o.kt)("a",{parentName:"p",href:"/docs/website/Developers/configuration"},"here"),"."),(0,o.kt)("h2",{id:"mongoose-basics"},"Mongoose Basics"),(0,o.kt)("p",null,"The project uses the ",(0,o.kt)("a",{parentName:"p",href:"https://mongoosejs.com/"},"Mongoose")," library as an abstraction over the default MongoDB NodeJS package. Mongoose organizes database structures into schemas and models (analogous to schemas in SQL) that automatically validate and enforce rules on database entries. For instance:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="model/images.js"',title:'"model/images.js"'},"const mongoose = require('mongoose')\n\nconst ImageSchema = new mongoose.Schema({\n filename: {\n type: String,\n required: true\n },\n description: {\n type: String,\n required: true\n },\n path: {\n type: String,\n required: true\n },\n date: {\n type: Date,\n required: true,\n default: Date.now\n }\n})\n\nconst ImageModel = mongoose.model('image', ImageSchema)\nmodule.exports = { ImageSchema, ImageModel }\n")),(0,o.kt)("p",null,"In the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/model/images.js"},"source above"),", an ",(0,o.kt)("inlineCode",{parentName:"p"},"ImageSchema")," is defined. The schema defines ",(0,o.kt)("inlineCode",{parentName:"p"},"filename, description, path, and date")," as properties of the 'Image' object. Similarly, it enforces certain rules over these properties: that 'filename' is a required string, that 'date' is a required JavaScript 'Date' object with a default value, etc."),(0,o.kt)("p",null,"Furthermore, Mongoose allows us to formalize a 'model' from this schema, in this case, it is named ",(0,o.kt)("inlineCode",{parentName:"p"},"ImageModel"),". The ",(0,o.kt)("inlineCode",{parentName:"p"},"ImageModel")," acts as a driver to our database's 'Image' collection (collections are structures similar to tables in SQL). Once the model is created, it is exported and ready to be used in other files. What follows is a series of code examples drawn from the website source code that illustrate what models are capable of:"),(0,o.kt)("h3",{id:"example-1"},"Example 1"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js:32"',title:'"routes/images.js:32"'},"const images = await ImageModel.find().sort({ date: -1 })\n")),(0,o.kt)("p",null,"The ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/images.js#L32"},"example")," above fetches all images in the database and sorts them in descending (-1) date order."),(0,o.kt)("h3",{id:"example-2"},"Example 2"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="routes/images.js:68"',title:'"routes/images.js:68"'},"const image = new ImageModel({\n filename: req.file.filename,\n description: req.body.Description,\n path: req.file.path\n})\n\nimage.save((err) => {\n if (err) return res.status(500).send({ error: 'Internal Server Error' })\n})\n")),(0,o.kt)("p",null,"In the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/images.js#L68C3-L76C5"},"example")," above, a new ",(0,o.kt)("ins",null,"instance")," of an ",(0,o.kt)("inlineCode",{parentName:"p"},"ImageModel")," with some given data, automatically validates it to make sure it matches the schema we've defined, and then attempts to save it to the database."),(0,o.kt)("admonition",{title:"Further Reading",type:"info"},(0,o.kt)("p",{parentName:"admonition"},"To learn more about Mongoose and MongoDB, refer to the ",(0,o.kt)("a",{parentName:"p",href:"https://mongoosejs.com/docs/index.html"},"Mongoose Documentation")," and the ",(0,o.kt)("a",{parentName:"p",href:"https://www.mongodb.com/languages/mongodb-with-nodejs"},"MongoDB NodeJS documentation"),".")),(0,o.kt)("h2",{id:"databasejs"},"Database.js"),(0,o.kt)("p",null,"The database connection URI is configured in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/utils/config.js"},"utils/config.js"),", whilst the effective database connection configuration happens in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/utils/database.js"},"utils/database.js"),". The database utility modularizes the connection (allowing us to handle the connection in multiple files simultaneously), whilst also implementing various event listeners:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="utils/database.js"',title:'"utils/database.js"'},"mongoose.connection.on('connected', () => {\n // CONNECTION SUCCEEDED...\n})\n\nmongoose.connection.on('error', (error) => {\n // CONNECTION FAILED...\n})\n\nmongoose.connection.on('disconnected', () => {\n // DISCONNECTED...\n})\n\nprocess.on('SIGINT', (error, data) => {\n // SIGINT: User stopped the program.\n})\n")),(0,o.kt)("p",null,"Database.js is imported, and a database connection is subsequently opened in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/app.js#L81"},"main.js"),"."),(0,o.kt)("h2",{id:"setting-up-your-own-database"},"Setting up your own database"),(0,o.kt)("p",null,"If you're interested in hosting your own instance of the website, you'll need to set up your own MongoDB node. The MongoDB team currently offers free (but limited) database hosting on their ",(0,o.kt)("a",{parentName:"p",href:"https://www.mongodb.com/atlas"},"MongoDB Atlas")," platform. Alternatively, you can set up MongoDB ",(0,o.kt)("a",{parentName:"p",href:"https://www.mongodb.com/try/download/community"},"community edition"),' on your machine and host your own instance for "free."'))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/cbb21fe1.5875b2a4.js b/assets/js/cbb21fe1.334baf69.js similarity index 54% rename from assets/js/cbb21fe1.5875b2a4.js rename to assets/js/cbb21fe1.334baf69.js index ef45962..dd318df 100644 --- a/assets/js/cbb21fe1.5875b2a4.js +++ b/assets/js/cbb21fe1.334baf69.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[3903],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>b});var i=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=i.createContext({}),c=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,s=e.mdxType,r=e.originalType,l=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),p=c(n),d=s,b=p["".concat(l,".").concat(d)]||p[d]||m[d]||r;return n?i.createElement(b,a(a({ref:t},u),{},{components:n})):i.createElement(b,a({ref:t},u))}));function b(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var r=n.length,a=new Array(r);a[0]=d;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[p]="string"==typeof e?e:s,a[1]=o;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=n(7462),s=(n(7294),n(3905));const r={title:"Testing & Linting",description:"Club Website Developer Testing",sidebar_position:8},a="Testing & Linting",o={unversionedId:"Developers/testing",id:"Developers/testing",title:"Testing & Linting",description:"Club Website Developer Testing",source:"@site/docs/website/Developers/testing.md",sourceDirName:"Developers",slug:"/Developers/testing",permalink:"/docs/website/Developers/testing",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/testing.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{title:"Testing & Linting",description:"Club Website Developer Testing",sidebar_position:8},sidebar:"defaultSidebar",previous:{title:"Authentication",permalink:"/docs/website/Developers/authentication"},next:{title:"Contributing Guide",permalink:"/docs/website/Developers/contributing-guide"}},l={},c=[{value:"Test Index",id:"test-index",level:2},{value:"Running Tests",id:"running-tests",level:2},{value:"Testing for Style Issues (Linting)",id:"testing-for-style-issues-linting",level:2},{value:"Fixing Style Issues Automatically",id:"fixing-style-issues-automatically",level:2},{value:"Silencing Linting Errors",id:"silencing-linting-errors",level:2}],u={toc:c},p="wrapper";function m(e){let{components:t,...n}=e;return(0,s.kt)(p,(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"testing--linting"},"Testing & Linting"),(0,s.kt)("p",null,"The project currently maintains unit tests for several backend routes and routines - no automated frontend testing has been implemented. The unit testing library used is ",(0,s.kt)("a",{parentName:"p",href:"https://mochajs.org/"},"MochaJS"),", coupled with ",(0,s.kt)("a",{parentName:"p",href:"https://www.chaijs.com/"},"ChaiJS")," for testing assertions. Additionally, a linter has been configured to automatically format code according to the ",(0,s.kt)("a",{parentName:"p",href:"https://standardjs.com/"},"JavaScript Standard Style"),"."),(0,s.kt)("p",null,"Any contribution to the OSC Website source code must pass testing and linting workflows, as well as implement new tests where necessary. See: ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/CONTRIBUTING.md"},"contributing"),"."),(0,s.kt)("h2",{id:"test-index"},"Test Index"),(0,s.kt)("p",null,"Sourcecode and documentation indices for currently available unit tests."),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"Blog API Route Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/blog.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/blog"},"Docs"),"."),(0,s.kt)("li",{parentName:"ul"},"Cache Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/cache.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/caching"},"Docs"),"."),(0,s.kt)("li",{parentName:"ul"},"Edit API Route Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/edit.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/edit"},"Docs"),"."),(0,s.kt)("li",{parentName:"ul"},"Images API Route Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/images.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/images"},"Docs"),"."),(0,s.kt)("li",{parentName:"ul"},"Users API Route Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/users.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/users"},"Docs"),".")),(0,s.kt)("h2",{id:"running-tests"},"Running Tests"),(0,s.kt)("admonition",{type:"danger"},(0,s.kt)("p",{parentName:"admonition"},"Tests are only meant to be ran on development environments. Do not use production databases in testing, their contents ",(0,s.kt)("b",null,"risk being deleted"),". To learn more about managing environments, see ",(0,s.kt)("a",{parentName:"p",href:"/docs/website/Developers/configuration"},"Usage & Configuration"),".")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"npm run test\n")),(0,s.kt)("h2",{id:"testing-for-style-issues-linting"},"Testing for Style Issues (Linting)"),(0,s.kt)("p",null,"OSC Website source code implements JavaScript Standard Style. To test for compliance, run:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"npm run lint\n")),(0,s.kt)("h2",{id:"fixing-style-issues-automatically"},"Fixing Style Issues Automatically"),(0,s.kt)("p",null,"In certain cases, the linter may be able to automatically fix linting issues. This is feature is made available via the following command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"npm run fix\n")),(0,s.kt)("p",null,"If an issue cannot be automatically fixed, the command will issue an error. If this happens, the developer must manually resolve the issue."),(0,s.kt)("h2",{id:"silencing-linting-errors"},"Silencing Linting Errors"),(0,s.kt)("p",null,"Sometimes, the implementation of certain pre-existing libraries (usually chaiJS and mochaJS) or functions may require the developer to break the linter's rules. Although this should ideally be avoided whenever possible, the following example illustrates how to silence a problematic line of code:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-js"},"expect(fs.existsSync(path)).to.be.true // eslint-disable-line\n")),(0,s.kt)("p",null,"If the linter complains of undefined global variables, it is silenced by adding the following code as the first line of the problematic file:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="First Line of Code"',title:'"First',Line:!0,of:!0,'Code"':!0},"/* global describe, it, before */\n")),(0,s.kt)("p",null,"Where ",(0,s.kt)("inlineCode",{parentName:"p"},"describe"),", ",(0,s.kt)("inlineCode",{parentName:"p"},"it"),", and ",(0,s.kt)("inlineCode",{parentName:"p"},"before")," may each be replaced by some global variable."))}m.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[3903],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>b});var i=n(7294);function s(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function r(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);t&&(i=i.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,i)}return n}function a(e){for(var t=1;t=0||(s[n]=e[n]);return s}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(i=0;i=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(s[n]=e[n])}return s}var l=i.createContext({}),c=function(e){var t=i.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):a(a({},t),e)),n},u=function(e){var t=c(e.components);return i.createElement(l.Provider,{value:t},e.children)},p="mdxType",m={inlineCode:"code",wrapper:function(e){var t=e.children;return i.createElement(i.Fragment,{},t)}},d=i.forwardRef((function(e,t){var n=e.components,s=e.mdxType,r=e.originalType,l=e.parentName,u=o(e,["components","mdxType","originalType","parentName"]),p=c(n),d=s,b=p["".concat(l,".").concat(d)]||p[d]||m[d]||r;return n?i.createElement(b,a(a({ref:t},u),{},{components:n})):i.createElement(b,a({ref:t},u))}));function b(e,t){var n=arguments,s=t&&t.mdxType;if("string"==typeof e||s){var r=n.length,a=new Array(r);a[0]=d;var o={};for(var l in t)hasOwnProperty.call(t,l)&&(o[l]=t[l]);o.originalType=e,o[p]="string"==typeof e?e:s,a[1]=o;for(var c=2;c{n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>m,frontMatter:()=>r,metadata:()=>o,toc:()=>c});var i=n(7462),s=(n(7294),n(3905));const r={title:"Testing & Linting",description:"Club Website Developer Testing",sidebar_position:8},a="Testing & Linting",o={unversionedId:"Developers/testing",id:"Developers/testing",title:"Testing & Linting",description:"Club Website Developer Testing",source:"@site/docs/website/Developers/testing.md",sourceDirName:"Developers",slug:"/Developers/testing",permalink:"/docs/website/Developers/testing",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/testing.md",tags:[],version:"current",sidebarPosition:8,frontMatter:{title:"Testing & Linting",description:"Club Website Developer Testing",sidebar_position:8},sidebar:"defaultSidebar",previous:{title:"Authentication",permalink:"/docs/website/Developers/authentication"},next:{title:"Contributing Guide",permalink:"/docs/website/Developers/contributing-guide"}},l={},c=[{value:"Test Index",id:"test-index",level:2},{value:"Running Tests",id:"running-tests",level:2},{value:"Testing for Style Issues (Linting)",id:"testing-for-style-issues-linting",level:2},{value:"Fixing Style Issues Automatically",id:"fixing-style-issues-automatically",level:2},{value:"Silencing Linting Errors",id:"silencing-linting-errors",level:2}],u={toc:c},p="wrapper";function m(e){let{components:t,...n}=e;return(0,s.kt)(p,(0,i.Z)({},u,n,{components:t,mdxType:"MDXLayout"}),(0,s.kt)("h1",{id:"testing--linting"},"Testing & Linting"),(0,s.kt)("p",null,"The project currently maintains unit tests for several backend routes and routines - no automated frontend testing has been implemented. The unit testing library used is ",(0,s.kt)("a",{parentName:"p",href:"https://mochajs.org/"},"MochaJS"),", coupled with ",(0,s.kt)("a",{parentName:"p",href:"https://www.chaijs.com/"},"ChaiJS")," for testing assertions. Additionally, a linter has been configured to automatically format code according to the ",(0,s.kt)("a",{parentName:"p",href:"https://standardjs.com/"},"JavaScript Standard Style"),"."),(0,s.kt)("p",null,"Any contribution to the OSC Website source code must pass testing and linting workflows, as well as implement new tests where necessary. See: ",(0,s.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/CONTRIBUTING.md"},"contributing"),"."),(0,s.kt)("h2",{id:"test-index"},"Test Index"),(0,s.kt)("p",null,"Source code and documentation indices for currently available unit tests."),(0,s.kt)("ul",null,(0,s.kt)("li",{parentName:"ul"},"Blog API Route Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/blog.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/blog"},"Docs"),"."),(0,s.kt)("li",{parentName:"ul"},"Cache Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/cache.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/caching"},"Docs"),"."),(0,s.kt)("li",{parentName:"ul"},"Edit API Route Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/edit.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/edit"},"Docs"),"."),(0,s.kt)("li",{parentName:"ul"},"Images API Route Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/images.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/images"},"Docs"),"."),(0,s.kt)("li",{parentName:"ul"},"Users API Route Tests: ",(0,s.kt)("a",{parentName:"li",href:"https://github.com/ufosc/Club_Website_2/blob/main/test/users.spec.js"},"GitHub")," or ",(0,s.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/users"},"Docs"),".")),(0,s.kt)("h2",{id:"running-tests"},"Running Tests"),(0,s.kt)("admonition",{type:"danger"},(0,s.kt)("p",{parentName:"admonition"},"Tests are only meant to be ran on development environments. Do not use production databases in testing, their contents ",(0,s.kt)("b",null,"risk being deleted"),". To learn more about managing environments, see ",(0,s.kt)("a",{parentName:"p",href:"/docs/website/Developers/configuration"},"Usage & Configuration"),".")),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"npm run test\n")),(0,s.kt)("h2",{id:"testing-for-style-issues-linting"},"Testing for Style Issues (Linting)"),(0,s.kt)("p",null,"OSC Website source code implements JavaScript Standard Style. To test for compliance, run:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"npm run lint\n")),(0,s.kt)("h2",{id:"fixing-style-issues-automatically"},"Fixing Style Issues Automatically"),(0,s.kt)("p",null,"In certain cases, the linter may be able to automatically fix linting issues. This is feature is made available via the following command:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-bash"},"npm run fix\n")),(0,s.kt)("p",null,"If an issue cannot be automatically fixed, the command will issue an error. If this happens, the developer must manually resolve the issue."),(0,s.kt)("h2",{id:"silencing-linting-errors"},"Silencing Linting Errors"),(0,s.kt)("p",null,"Sometimes, the implementation of certain pre-existing libraries (usually chaiJS and mochaJS) or functions may require the developer to break the linter's rules. Although this should ideally be avoided whenever possible, the following example illustrates how to silence a problematic line of code:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-js"},"expect(fs.existsSync(path)).to.be.true // eslint-disable-line\n")),(0,s.kt)("p",null,"If the linter complains of undefined global variables, it is silenced by adding the following code as the first line of the problematic file:"),(0,s.kt)("pre",null,(0,s.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="First Line of Code"',title:'"First',Line:!0,of:!0,'Code"':!0},"/* global describe, it, before */\n")),(0,s.kt)("p",null,"Where ",(0,s.kt)("inlineCode",{parentName:"p"},"describe"),", ",(0,s.kt)("inlineCode",{parentName:"p"},"it"),", and ",(0,s.kt)("inlineCode",{parentName:"p"},"before")," may each be replaced by some global variable."))}m.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/dd34c948.5d50aa3b.js b/assets/js/dd34c948.c6301c53.js similarity index 97% rename from assets/js/dd34c948.5d50aa3b.js rename to assets/js/dd34c948.c6301c53.js index da5a9b9..7e119ef 100644 --- a/assets/js/dd34c948.5d50aa3b.js +++ b/assets/js/dd34c948.c6301c53.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[7764],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>b});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=p(r),m=o,b=u["".concat(l,".").concat(m)]||u[m]||d[m]||s;return r?n.createElement(b,a(a({ref:t},c),{},{components:r})):n.createElement(b,a({ref:t},c))}));function b(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=r.length,a=new Array(s);a[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:o,a[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const s={title:"API & Routes",description:"Club Website Developer API",sidebar_position:1},a="API & Routes",i={unversionedId:"Developers/API/api",id:"Developers/API/api",title:"API & Routes",description:"Club Website Developer API",source:"@site/docs/website/Developers/API/api.md",sourceDirName:"Developers/API",slug:"/Developers/API/",permalink:"/docs/website/Developers/API/",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/API/api.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"API & Routes",description:"Club Website Developer API",sidebar_position:1},sidebar:"defaultSidebar",previous:{title:"Image Storage",permalink:"/docs/website/Developers/Databases/image-storage"},next:{title:"Blog Route",permalink:"/docs/website/Developers/API/blog"}},l={},p=[{value:"Express",id:"express",level:2},{value:"Express Router",id:"express-router",level:2}],c={toc:p},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"api--routes"},"API & Routes"),(0,o.kt)("p",null,"The OSC website API exists to serve, create, modify, and delete dynamic resources, for instance:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Blog metadata and rendered HTML articles (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/blog"},"Developers/API/blog"),")."),(0,o.kt)("li",{parentName:"ol"},"Passing contact messages to the SMTP mail server (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/contact"},"Developers/API/contact"),")."),(0,o.kt)("li",{parentName:"ol"},"Serving the various editable forms (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/edit"},"Developers/API/edit"),")."),(0,o.kt)("li",{parentName:"ol"},"Serving and storing blog images (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/images"},"Developers/API/images"),")."),(0,o.kt)("li",{parentName:"ol"},"User authentication (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/users"},"Developers/API/users"),").")),(0,o.kt)("p",null,"In the source code, each route occupies a separate file in the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/tree/main/routes"},"routes folder"),", and all routes are subsequently organized in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/api.js"},"routes/api.js"),"."),(0,o.kt)("h2",{id:"express"},"Express"),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Express.js is a backend web framework for creating and serving RESTful APIs on NodeJS. It is documented extensively at ",(0,o.kt)("a",{parentName:"p",href:"https://expressjs.com/"},"expressjs.com"),".")),(0,o.kt)("p",null,"Expressjs, otherwise known as Express, implements a simple NodeJS web server. It defines a relative routing path and a series of middleware to use with each function. Each middleware iis a JavaScript function that accepts an HTTP request (the ",(0,o.kt)("inlineCode",{parentName:"p"},"req")," variable) and a respone object (the ",(0,o.kt)("inlineCode",{parentName:"p"},"res")," variable). The ",(0,o.kt)("inlineCode",{parentName:"p"},"res")," variable is an interface for sending responses back to users."),(0,o.kt)("p",null,"Example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},"// An API route served over '/', using the HTTP GET method.\nrouter.get('/', (req, res) => {\n\n // req holds the user's request.\n const body = req.body\n const someField = body.someField\n const someField2 = body.someField2\n\n // We respond by interfacing with 'res'\n res.status(200).send({ message: \"accepted\" })\n\n})\n\n// Other HTTP methods...\nrouter.post('/', (req, res) => { /* ... */ })\nrouter.delete('/', (req, res) => { /* ... */ })\nrouter.put('/', (req, res) => { /* ... */ })\n")),(0,o.kt)("h2",{id:"express-router"},"Express Router"),(0,o.kt)("p",null,"The express router, part of the Expressjs framework, enables developers to create and export APIs modularly. Meaning, an API can be developed according to some relative path (e.g ",(0,o.kt)("inlineCode",{parentName:"p"},"/images"),"), imported into another router, and then served over some other, more abstract path (e.g ",(0,o.kt)("inlineCode",{parentName:"p"},"/api/images"),"). Consider the following example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="File A"',title:'"File','A"':!0},"const express = require('express')\nconst router = express.Router()\n\nrouter.get('/', (req, res) => { /* ... */ }\nrouter.post('/', (req, res) => { /* ... */ }\n// ...\n\nmodule.exports = router\n")),(0,o.kt)("p",null,"Then, imported into file B:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="File B"',title:'"File','B"':!0},"const express = require('express')\nconst router = express.Router()\n\n// The API defined in File A.\nconst myFirstRoute = require('./fileA')\n\n// Serve the API in File A on /mySecondRoute.\nrouter.use('/mySecondRoute', myFirstRoute)\n")),(0,o.kt)("p",null,"In this way, HTTP routes can be defined in a secure, conveniently testable, and organized manner."))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[7764],{3905:(e,t,r)=>{r.d(t,{Zo:()=>c,kt:()=>b});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function s(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function a(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),p=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},c=function(e){var t=p(e.components);return n.createElement(l.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},m=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,s=e.originalType,l=e.parentName,c=i(e,["components","mdxType","originalType","parentName"]),u=p(r),m=o,b=u["".concat(l,".").concat(m)]||u[m]||d[m]||s;return r?n.createElement(b,a(a({ref:t},c),{},{components:r})):n.createElement(b,a({ref:t},c))}));function b(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var s=r.length,a=new Array(s);a[0]=m;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[u]="string"==typeof e?e:o,a[1]=i;for(var p=2;p{r.r(t),r.d(t,{assets:()=>l,contentTitle:()=>a,default:()=>d,frontMatter:()=>s,metadata:()=>i,toc:()=>p});var n=r(7462),o=(r(7294),r(3905));const s={title:"API & Routes",description:"Club Website Developer API",sidebar_position:1},a="API & Routes",i={unversionedId:"Developers/API/api",id:"Developers/API/api",title:"API & Routes",description:"Club Website Developer API",source:"@site/docs/website/Developers/API/api.md",sourceDirName:"Developers/API",slug:"/Developers/API/",permalink:"/docs/website/Developers/API/",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/website/Developers/API/api.md",tags:[],version:"current",sidebarPosition:1,frontMatter:{title:"API & Routes",description:"Club Website Developer API",sidebar_position:1},sidebar:"defaultSidebar",previous:{title:"Image Storage",permalink:"/docs/website/Developers/Databases/image-storage"},next:{title:"Blog Route",permalink:"/docs/website/Developers/API/blog"}},l={},p=[{value:"Express",id:"express",level:2},{value:"Express Router",id:"express-router",level:2}],c={toc:p},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},c,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"api--routes"},"API & Routes"),(0,o.kt)("p",null,"The OSC website API exists to serve, create, modify, and delete dynamic resources, for instance:"),(0,o.kt)("ol",null,(0,o.kt)("li",{parentName:"ol"},"Blog metadata and rendered HTML articles (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/blog"},"Developers/API/blog"),")."),(0,o.kt)("li",{parentName:"ol"},"Passing contact messages to the SMTP mail server (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/contact"},"Developers/API/contact"),")."),(0,o.kt)("li",{parentName:"ol"},"Serving the various editable forms (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/edit"},"Developers/API/edit"),")."),(0,o.kt)("li",{parentName:"ol"},"Serving and storing blog images (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/images"},"Developers/API/images"),")."),(0,o.kt)("li",{parentName:"ol"},"User authentication (documented in ",(0,o.kt)("a",{parentName:"li",href:"/docs/website/Developers/API/users"},"Developers/API/users"),").")),(0,o.kt)("p",null,"In the source code, each route occupies a separate file in the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/tree/main/routes"},"routes folder"),", and all routes are subsequently organized in ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/Club_Website_2/blob/main/routes/api.js"},"routes/api.js"),"."),(0,o.kt)("h2",{id:"express"},"Express"),(0,o.kt)("admonition",{type:"note"},(0,o.kt)("p",{parentName:"admonition"},"Express.js is a backend web framework for creating and serving RESTful APIs on NodeJS. It is documented extensively at ",(0,o.kt)("a",{parentName:"p",href:"https://expressjs.com/"},"expressjs.com"),".")),(0,o.kt)("p",null,"Expressjs, otherwise known as Express, implements a simple NodeJS web server. It defines a relative routing path and a series of middleware to use with each function. Each middleware is a JavaScript function that accepts an HTTP request (the ",(0,o.kt)("inlineCode",{parentName:"p"},"req")," variable) and a response object (the ",(0,o.kt)("inlineCode",{parentName:"p"},"res")," variable). The ",(0,o.kt)("inlineCode",{parentName:"p"},"res")," variable is an interface for sending responses back to users."),(0,o.kt)("p",null,"Example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},"// An API route served over '/', using the HTTP GET method.\nrouter.get('/', (req, res) => {\n\n // req holds the user's request.\n const body = req.body\n const someField = body.someField\n const someField2 = body.someField2\n\n // We respond by interfacing with 'res'\n res.status(200).send({ message: \"accepted\" })\n\n})\n\n// Other HTTP methods...\nrouter.post('/', (req, res) => { /* ... */ })\nrouter.delete('/', (req, res) => { /* ... */ })\nrouter.put('/', (req, res) => { /* ... */ })\n")),(0,o.kt)("h2",{id:"express-router"},"Express Router"),(0,o.kt)("p",null,"The express router, part of the Expressjs framework, enables developers to create and export APIs modularly. Meaning, an API can be developed according to some relative path (e.g ",(0,o.kt)("inlineCode",{parentName:"p"},"/images"),"), imported into another router, and then served over some other, more abstract path (e.g ",(0,o.kt)("inlineCode",{parentName:"p"},"/api/images"),"). Consider the following example:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="File A"',title:'"File','A"':!0},"const express = require('express')\nconst router = express.Router()\n\nrouter.get('/', (req, res) => { /* ... */ }\nrouter.post('/', (req, res) => { /* ... */ }\n// ...\n\nmodule.exports = router\n")),(0,o.kt)("p",null,"Then, imported into file B:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="File B"',title:'"File','B"':!0},"const express = require('express')\nconst router = express.Router()\n\n// The API defined in File A.\nconst myFirstRoute = require('./fileA')\n\n// Serve the API in File A on /mySecondRoute.\nrouter.use('/mySecondRoute', myFirstRoute)\n")),(0,o.kt)("p",null,"In this way, HTTP routes can be defined in a secure, conveniently testable, and organized manner."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/ea395eac.c699dab2.js b/assets/js/ea395eac.efcd8646.js similarity index 95% rename from assets/js/ea395eac.c699dab2.js rename to assets/js/ea395eac.efcd8646.js index 2c0adcb..3c25db7 100644 --- a/assets/js/ea395eac.c699dab2.js +++ b/assets/js/ea395eac.efcd8646.js @@ -1 +1 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[1936],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),g=o,f=u["".concat(c,".").concat(g)]||u[g]||d[g]||a;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={title:"Static Pages",description:"OSC Docs Static Pages",sidebar_position:6},i="Static Pages",s={unversionedId:"static-pages",id:"static-pages",title:"Static Pages",description:"OSC Docs Static Pages",source:"@site/docs/osc-docs/static-pages.md",sourceDirName:".",slug:"/static-pages",permalink:"/docs/osc-docs/static-pages",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/osc-docs/static-pages.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{title:"Static Pages",description:"OSC Docs Static Pages",sidebar_position:6},sidebar:"defaultSidebar",previous:{title:"Documentation",permalink:"/docs/osc-docs/writingdocs"},next:{title:"Configuring Docusaurus",permalink:"/docs/osc-docs/docusaurus"}},c={},p=[],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"static-pages"},"Static Pages"),(0,o.kt)("p",null,"You can create static pages that are not part of a documentation sub-site by creating JavaScript or Markdown files in the project's ",(0,o.kt)("inlineCode",{parentName:"p"},"src/pages")," directory. By default, you'll be able to navigate to said pages by visiting the ",(0,o.kt)("inlineCode",{parentName:"p"},"/")," path of the website."),(0,o.kt)("p",null,"To add the site to the website's topmost navigation bar, navigate to the ",(0,o.kt)("inlineCode",{parentName:"p"},"themeConfig")," property in ",(0,o.kt)("inlineCode",{parentName:"p"},"docusaurus.config.js")," and add the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config.js"',title:'"docusaurus.config.js"'},"navbar: {\n title: 'OSC Docs',\n logo: {\n alt: 'OSC Logo',\n src: 'img/logo.png'\n },\n items: [\n // ....\n {\n to: 'docs/club', // Your subsite routeBasePath\n label: 'Club Archive', // Label to appear on the navmenu.\n position: 'left'\n }\n // ...\n ]\n}\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The OSC Docs homepage is an example of a non-documentational static page. You may find its source code (in Markdown) in the project's ",(0,o.kt)("inlineCode",{parentName:"p"},"src/pages/index.md")," path.")))}d.isMDXComponent=!0}}]); \ No newline at end of file +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[1936],{3905:(e,t,n)=>{n.d(t,{Zo:()=>l,kt:()=>f});var r=n(7294);function o(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function a(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function i(e){for(var t=1;t=0||(o[n]=e[n]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(o[n]=e[n])}return o}var c=r.createContext({}),p=function(e){var t=r.useContext(c),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},l=function(e){var t=p(e.components);return r.createElement(c.Provider,{value:t},e.children)},u="mdxType",d={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},g=r.forwardRef((function(e,t){var n=e.components,o=e.mdxType,a=e.originalType,c=e.parentName,l=s(e,["components","mdxType","originalType","parentName"]),u=p(n),g=o,f=u["".concat(c,".").concat(g)]||u[g]||d[g]||a;return n?r.createElement(f,i(i({ref:t},l),{},{components:n})):r.createElement(f,i({ref:t},l))}));function f(e,t){var n=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=n.length,i=new Array(a);i[0]=g;var s={};for(var c in t)hasOwnProperty.call(t,c)&&(s[c]=t[c]);s.originalType=e,s[u]="string"==typeof e?e:o,i[1]=s;for(var p=2;p{n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>i,default:()=>d,frontMatter:()=>a,metadata:()=>s,toc:()=>p});var r=n(7462),o=(n(7294),n(3905));const a={title:"Static Pages",description:"OSC Docs Static Pages",sidebar_position:6},i="Static Pages",s={unversionedId:"static-pages",id:"static-pages",title:"Static Pages",description:"OSC Docs Static Pages",source:"@site/docs/osc-docs/static-pages.md",sourceDirName:".",slug:"/static-pages",permalink:"/docs/osc-docs/static-pages",draft:!1,editUrl:"https://github.com/ufosc/osc-docs/blob/main/docs/osc-docs/static-pages.md",tags:[],version:"current",sidebarPosition:6,frontMatter:{title:"Static Pages",description:"OSC Docs Static Pages",sidebar_position:6},sidebar:"defaultSidebar",previous:{title:"Documentation",permalink:"/docs/osc-docs/writingdocs"},next:{title:"Configuring Docusaurus",permalink:"/docs/osc-docs/docusaurus"}},c={},p=[],l={toc:p},u="wrapper";function d(e){let{components:t,...n}=e;return(0,o.kt)(u,(0,r.Z)({},l,n,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"static-pages"},"Static Pages"),(0,o.kt)("p",null,"You can create static pages that are not part of a documentation sub-site by creating JavaScript or Markdown files in the project's ",(0,o.kt)("inlineCode",{parentName:"p"},"src/pages")," directory. By default, you'll be able to navigate to said pages by visiting the ",(0,o.kt)("inlineCode",{parentName:"p"},"/")," path of the website."),(0,o.kt)("p",null,"To add the site to the website's topmost navigation bar, navigate to the ",(0,o.kt)("inlineCode",{parentName:"p"},"themeConfig")," property in ",(0,o.kt)("inlineCode",{parentName:"p"},"docusaurus.config.js")," and add the following:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js",metastring:'title="docusaurus.config.js"',title:'"docusaurus.config.js"'},"navbar: {\n title: 'OSC Docs',\n logo: {\n alt: 'OSC Logo',\n src: 'img/logo.png'\n },\n items: [\n // ....\n {\n to: 'docs/club', // Your subsite routeBasePath\n label: 'Club Archive', // Label to appear on the navmenu.\n position: 'left'\n }\n // ...\n ]\n}\n")),(0,o.kt)("admonition",{type:"tip"},(0,o.kt)("p",{parentName:"admonition"},"The OSC Docs homepage is an example of a non-documentation static page. You may find its source code (in Markdown) in the project's ",(0,o.kt)("inlineCode",{parentName:"p"},"src/pages/index.md")," path.")))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f3976560.8db6801b.js b/assets/js/f3976560.8db6801b.js deleted file mode 100644 index aeb10f7..0000000 --- a/assets/js/f3976560.8db6801b.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[2844],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),u=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},s=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),p=u(r),d=o,m=p["".concat(l,".").concat(d)]||p[d]||f[d]||a;return r?n.createElement(m,c(c({ref:t},s),{},{components:r})):n.createElement(m,c({ref:t},s))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:o,c[1]=i;for(var u=2;u{r.r(t),r.d(t,{contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const a={description:"Club Website API Reference Users"},c="Open Source Club Documentation",i={type:"mdx",permalink:"/",source:"@site/src/pages/index.md",title:"Open Source Club Documentation",description:"Club Website API Reference Users",frontMatter:{description:"Club Website API Reference Users"}},l=[{value:"Documetation Index",id:"documetation-index",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Contact",id:"contact",level:2},{value:"License",id:"license",level:2}],u={toc:l},s="wrapper";function p(e){let{components:t,...r}=e;return(0,o.kt)(s,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"open-source-club-documentation"},"Open Source Club Documentation"),(0,o.kt)("p",null,"OSC is the Open Source Club at the University of Florida. We are a community of makers, who want to solve problems and improve our world using open source projects. We were founded in the Spring of 2016 as an official student organization at UF. The club is also a partnered Special Interest Group of the UF ACM chapter."),(0,o.kt)("p",null,"Each semester, members meet and collaborate to build open source projects. Their documentation can be found here. For the main site, see: ",(0,o.kt)("a",{parentName:"p",href:"https://www.ufosc.org"},"https://www.ufosc.org")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"documetation-index"},"Documetation Index"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/club"},"Club Archive"),": Archive of club presentations, notes, etc."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/website"},"OSC Website"),": User & Developer Documentation for the ",(0,o.kt)("a",{parentName:"li",href:"https://ufosc.org"},"OSC website"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs"},"OSC Docs"),": Developer Documentation for the OSC Docs website.")),(0,o.kt)("h2",{id:"contributing"},"Contributing"),(0,o.kt)("p",null,"All projects by the UF Open Source Club are governed by open-source licenses. In nearly all projecs, you are allowed and encouraged to make contributions - as long as they likewise adhere to the project's respective license. You can browse available projects on the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc"},"GitHub UF OSC page"),"."),(0,o.kt)("p",null,"If you wish to contribute to OSC Docs, navigate to its ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/osc-docs"},"GitHub Repository"),'. Alternatively, clicking on the "Edit this page" button on your desired documentation page will redirect you to the source code for that particular page, where you\'ll be able to contribute.'),(0,o.kt)("h2",{id:"contact"},"Contact"),(0,o.kt)("p",null,"You can reach the UF OSC team via email at gator.osc(at)cise.ufl.edu ",(0,o.kt)("br",null),"\nOr via the ",(0,o.kt)("a",{parentName:"p",href:"https://ufosc.org/#contact"},"contact form"),"."),(0,o.kt)("h2",{id:"license"},"License"),(0,o.kt)("p",null,"This site is licensed under ",(0,o.kt)("a",{parentName:"p",href:"https://spdx.org/licenses/AGPL-3.0-or-later"},"AGPL-3.0-or-later"),". Source code hosted on ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/osc-docs"},"GitHub"),"."),(0,o.kt)("p",null,"Copyright \xa9 2023 UF Open Source Club"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/f3976560.cf4734bf.js b/assets/js/f3976560.cf4734bf.js new file mode 100644 index 0000000..f2c5708 --- /dev/null +++ b/assets/js/f3976560.cf4734bf.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[2844],{3905:(e,t,r)=>{r.d(t,{Zo:()=>s,kt:()=>m});var n=r(7294);function o(e,t,r){return t in e?Object.defineProperty(e,t,{value:r,enumerable:!0,configurable:!0,writable:!0}):e[t]=r,e}function a(e,t){var r=Object.keys(e);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(e);t&&(n=n.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),r.push.apply(r,n)}return r}function c(e){for(var t=1;t=0||(o[r]=e[r]);return o}(e,t);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);for(n=0;n=0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var l=n.createContext({}),u=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):c(c({},t),e)),r},s=function(e){var t=u(e.components);return n.createElement(l.Provider,{value:t},e.children)},p="mdxType",f={inlineCode:"code",wrapper:function(e){var t=e.children;return n.createElement(n.Fragment,{},t)}},d=n.forwardRef((function(e,t){var r=e.components,o=e.mdxType,a=e.originalType,l=e.parentName,s=i(e,["components","mdxType","originalType","parentName"]),p=u(r),d=o,m=p["".concat(l,".").concat(d)]||p[d]||f[d]||a;return r?n.createElement(m,c(c({ref:t},s),{},{components:r})):n.createElement(m,c({ref:t},s))}));function m(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,c=new Array(a);c[0]=d;var i={};for(var l in t)hasOwnProperty.call(t,l)&&(i[l]=t[l]);i.originalType=e,i[p]="string"==typeof e?e:o,c[1]=i;for(var u=2;u{r.r(t),r.d(t,{contentTitle:()=>c,default:()=>p,frontMatter:()=>a,metadata:()=>i,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const a={description:"Club Website API Reference Users"},c="Open Source Club Documentation",i={type:"mdx",permalink:"/",source:"@site/src/pages/index.md",title:"Open Source Club Documentation",description:"Club Website API Reference Users",frontMatter:{description:"Club Website API Reference Users"}},l=[{value:"Documentation Index",id:"documentation-index",level:2},{value:"Contributing",id:"contributing",level:2},{value:"Contact",id:"contact",level:2},{value:"License",id:"license",level:2}],u={toc:l},s="wrapper";function p(e){let{components:t,...r}=e;return(0,o.kt)(s,(0,n.Z)({},u,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"open-source-club-documentation"},"Open Source Club Documentation"),(0,o.kt)("p",null,"OSC is the Open Source Club at the University of Florida. We are a community of makers, who want to solve problems and improve our world using open source projects. We were founded in the Spring of 2016 as an official student organization at UF. The club is also a partnered Special Interest Group of the UF ACM chapter."),(0,o.kt)("p",null,"Each semester, members meet and collaborate to build open source projects. Their documentation can be found here. For the main site, see: ",(0,o.kt)("a",{parentName:"p",href:"https://www.ufosc.org"},"https://www.ufosc.org")),(0,o.kt)("hr",null),(0,o.kt)("h2",{id:"documentation-index"},"Documentation Index"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/club"},"Club Archive"),": Archive of club presentations, notes, etc."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/website"},"OSC Website"),": User & Developer Documentation for the ",(0,o.kt)("a",{parentName:"li",href:"https://ufosc.org"},"OSC website"),"."),(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/osc-docs"},"OSC Docs"),": Developer Documentation for the OSC Docs website.")),(0,o.kt)("h2",{id:"contributing"},"Contributing"),(0,o.kt)("p",null,"All projects by the UF Open Source Club are governed by open-source licenses. In nearly all projects, you are allowed and encouraged to make contributions - as long as they likewise adhere to the project's respective license. You can browse available projects on the ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc"},"GitHub UF OSC page"),"."),(0,o.kt)("p",null,"If you wish to contribute to OSC Docs, navigate to its ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/osc-docs"},"GitHub Repository"),'. Alternatively, clicking on the "Edit this page" button on your desired documentation page will redirect you to the source code for that particular page, where you\'ll be able to contribute.'),(0,o.kt)("h2",{id:"contact"},"Contact"),(0,o.kt)("p",null,"You can reach the UF OSC team via email at gator.osc(at)cise.ufl.edu ",(0,o.kt)("br",null),"\nOr via the ",(0,o.kt)("a",{parentName:"p",href:"https://ufosc.org/#contact"},"contact form"),"."),(0,o.kt)("h2",{id:"license"},"License"),(0,o.kt)("p",null,"This site is licensed under ",(0,o.kt)("a",{parentName:"p",href:"https://spdx.org/licenses/AGPL-3.0-or-later"},"AGPL-3.0-or-later"),". Source code hosted on ",(0,o.kt)("a",{parentName:"p",href:"https://github.com/ufosc/osc-docs"},"GitHub"),"."),(0,o.kt)("p",null,"Copyright \xa9 2023 UF Open Source Club"))}p.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/main.5b65ce11.js b/assets/js/main.04236c0d.js similarity index 98% rename from assets/js/main.5b65ce11.js rename to assets/js/main.04236c0d.js index dfa0d3d..49f0068 100644 --- a/assets/js/main.5b65ce11.js +++ b/assets/js/main.04236c0d.js @@ -1,2 +1,2 @@ -/*! For license information please see main.5b65ce11.js.LICENSE.txt */ -(self.webpackChunkosc_docs=self.webpackChunkosc_docs||[]).push([[179],{723:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7294),a=n(7462),o=n(8356),i=n.n(o),l=n(6887);const s={"00b93840":[()=>n.e(882).then(n.bind(n,9418)),"@site/docs/club/2021-2022/spring-gbm-03-30-22.md",9418],"0e39a0cd":[()=>n.e(3290).then(n.bind(n,1291)),"@site/docs/website/Developers/Databases/models.md",1291],"12000fc4":[()=>n.e(4212).then(n.bind(n,9112)),"@site/docs/website/Developers/rendering.md",9112],"12f0493a":[()=>n.e(8841).then(n.t.bind(n,5172,19)),"/Users/mz/projects/osc-docs/.docusaurus/docusaurus-plugin-content-docs/osc-docs/plugin-route-context-module-100.json",5172],17896441:[()=>Promise.all([n.e(532),n.e(9455),n.e(7918)]).then(n.bind(n,903)),"@theme/DocItem",903],"1be78505":[()=>Promise.all([n.e(532),n.e(9514)]).then(n.bind(n,9963)),"@theme/DocPage",9963],"1de99325":[()=>n.e(9465).then(n.bind(n,5351)),"@site/docs/website/Developers/authentication.md",5351],"1f391b9e":[()=>Promise.all([n.e(532),n.e(9455),n.e(3085)]).then(n.bind(n,4247)),"@theme/MDXPage",4247],"26e5135d":[()=>n.e(4252).then(n.bind(n,1574)),"@site/docs/osc-docs/index.md",1574],"28dfb2d5":[()=>n.e(7034).then(n.bind(n,6370)),"@site/docs/club/2021-2022/fall-gbm-09-09-21.md",6370],"2a3c7f3c":[()=>n.e(808).then(n.bind(n,7010)),"@site/docs/club/2022-2023/fall-gbm-11-04-2022.md",7010],"2cc0550e":[()=>n.e(942).then(n.bind(n,3894)),"@site/docs/website/Developers/API/contact.md",3894],"31287fdd":[()=>n.e(9394).then(n.bind(n,8857)),"@site/docs/website/Developers/configuration.md",8857],"347d410c":[()=>n.e(2644).then(n.bind(n,1275)),"@site/docs/website/Developers/caching.md",1275],35041632:[()=>n.e(8838).then(n.bind(n,1713)),"@site/docs/club/2021-2022/fall-gbm-10-13-21.md",1713],"3a1cec24":[()=>n.e(9961).then(n.bind(n,3222)),"@site/docs/website/Developers/API/edit.md",3222],"409871ed":[()=>n.e(5832).then(n.bind(n,7772)),"@site/docs/club/2021-2022/NLP-workshop.md",7772],"56f4606f":[()=>n.e(5041).then(n.bind(n,8176)),"@site/docs/club/2021-2022/spring-gbm-04-06-22.md",8176],"5843de5d":[()=>n.e(6965).then(n.t.bind(n,2011,19)),"~docs/osc-docs/version-current-metadata-prop-751.json",2011],"59a06d98":[()=>n.e(5031).then(n.bind(n,4035)),"@site/docs/website/Developers/Databases/image-storage.md",4035],"5bf5bdb1":[()=>n.e(4199).then(n.bind(n,4200)),"@site/docs/website/Developers/introduction.md",4200],"6a2729da":[()=>n.e(4492).then(n.t.bind(n,5745,19)),"/Users/mz/projects/osc-docs/.docusaurus/docusaurus-plugin-content-pages/default/plugin-route-context-module-100.json",5745],"6c220528":[()=>n.e(8007).then(n.bind(n,2313)),"@site/docs/club/2021-2022/spring-gbm-01-06-22.md",2313],"6ca7e745":[()=>n.e(366).then(n.bind(n,2636)),"@site/docs/website/api-reference.md",2636],"6d49fdd4":[()=>n.e(2424).then(n.bind(n,4458)),"@site/docs/website/Developers/API/blog.md",4458],"749ef08d":[()=>n.e(2886).then(n.bind(n,4681)),"@site/docs/website/admin.md",4681],"75a7683f":[()=>n.e(9062).then(n.bind(n,576)),"@site/docs/osc-docs/markdown.md",576],"7da8cb4d":[()=>n.e(8072).then(n.bind(n,644)),"@site/docs/club/2021-2022/swamphacks-sql-01-30-22.md",644],"8161bbfb":[()=>n.e(4672).then(n.bind(n,1446)),"@site/docs/website/Developers/contributing-guide.md",1446],"9232a1e9":[()=>n.e(779).then(n.bind(n,1751)),"@site/docs/osc-docs/writingdocs.md",1751],"935f2afb":[()=>n.e(53).then(n.t.bind(n,1109,19)),"~docs/default/version-current-metadata-prop-751.json",1109],"9b50b30c":[()=>n.e(9197).then(n.bind(n,9882)),"@site/docs/website/Developers/Databases/mongodb.md",9882],"9d0ebba8":[()=>n.e(3933).then(n.bind(n,449)),"@site/docs/club/2022-2023/spring-gbm-03-30-2023.md",449],b03ee68b:[()=>n.e(5368).then(n.bind(n,6765)),"@site/docs/website/Developers/API/images.md",6765],bd19a0bf:[()=>n.e(4217).then(n.bind(n,5251)),"@site/docs/website/index.md",5251],bd7c2054:[()=>n.e(9398).then(n.bind(n,4146)),"@site/docs/website/Developers/API/users.md",4146],bdbf0ec8:[()=>n.e(9809).then(n.bind(n,2309)),"@site/docs/club/index.md",2309],be3efe0c:[()=>n.e(5466).then(n.bind(n,7407)),"@site/docs/club/2023-2024/fall-gbm-09-06-2023.md",7407],c4bf2b51:[()=>n.e(9992).then(n.bind(n,3164)),"@site/docs/club/2022-2023/spring-project-proposals.md",3164],cad82f49:[()=>n.e(5442).then(n.t.bind(n,3769,19)),"/Users/mz/projects/osc-docs/.docusaurus/docusaurus-plugin-content-docs/default/plugin-route-context-module-100.json",3769],cbb21fe1:[()=>n.e(3903).then(n.bind(n,5829)),"@site/docs/website/Developers/testing.md",5829],d502361b:[()=>n.e(7445).then(n.bind(n,2718)),"@site/docs/osc-docs/usage.md",2718],d8a3a66a:[()=>n.e(6713).then(n.t.bind(n,1295,19)),"~docs/website/version-current-metadata-prop-751.json",1295],dd34c948:[()=>n.e(7764).then(n.bind(n,1211)),"@site/docs/website/Developers/API/api.md",1211],ded0a667:[()=>n.e(5859).then(n.bind(n,3941)),"@site/docs/club/2022-2023/spring-gbm-01-25-2023.md",3941],e064b256:[()=>n.e(9170).then(n.bind(n,1611)),"@site/docs/osc-docs/docusaurus.md",1611],e1520d8a:[()=>n.e(5850).then(n.bind(n,6770)),"@site/docs/club/2021-2022/swamphacks-git-01-26-22.md",6770],e41e86bd:[()=>n.e(3785).then(n.t.bind(n,6644,19)),"/Users/mz/projects/osc-docs/.docusaurus/docusaurus-plugin-content-docs/website/plugin-route-context-module-100.json",6644],ea395eac:[()=>n.e(1936).then(n.bind(n,7383)),"@site/docs/osc-docs/static-pages.md",7383],ebb803d9:[()=>n.e(5290).then(n.bind(n,7972)),"@site/docs/club/2022-2023/fall-gbm-09-07-2022.md",7972],f3976560:[()=>n.e(2844).then(n.bind(n,672)),"@site/src/pages/index.md",672],f95c0569:[()=>n.e(2022).then(n.bind(n,2873)),"@site/docs/osc-docs/installation.md",2873]};function u(e){let{error:t,retry:n,pastDelay:a}=e;return t?r.createElement("div",{style:{textAlign:"center",color:"#fff",backgroundColor:"#fa383e",borderColor:"#fa383e",borderStyle:"solid",borderRadius:"0.25rem",borderWidth:"1px",boxSizing:"border-box",display:"block",padding:"1rem",flex:"0 0 50%",marginLeft:"25%",marginRight:"25%",marginTop:"5rem",maxWidth:"50%",width:"100%"}},r.createElement("p",null,String(t)),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},"Retry"))):a?r.createElement("div",{style:{display:"flex",justifyContent:"center",alignItems:"center",height:"100vh"}},r.createElement("svg",{id:"loader",style:{width:128,height:110,position:"absolute",top:"calc(100vh - 64%)"},viewBox:"0 0 45 45",xmlns:"http://www.w3.org/2000/svg",stroke:"#61dafb"},r.createElement("g",{fill:"none",fillRule:"evenodd",transform:"translate(1 1)",strokeWidth:"2"},r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"1.5s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"1.5s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"1.5s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"6",strokeOpacity:"0"},r.createElement("animate",{attributeName:"r",begin:"3s",dur:"3s",values:"6;22",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-opacity",begin:"3s",dur:"3s",values:"1;0",calcMode:"linear",repeatCount:"indefinite"}),r.createElement("animate",{attributeName:"stroke-width",begin:"3s",dur:"3s",values:"2;0",calcMode:"linear",repeatCount:"indefinite"})),r.createElement("circle",{cx:"22",cy:"22",r:"8"},r.createElement("animate",{attributeName:"r",begin:"0s",dur:"1.5s",values:"6;1;2;3;4;5;6",calcMode:"linear",repeatCount:"indefinite"}))))):null}var c=n(9670),d=n(226);function f(e,t){if("*"===e)return i()({loading:u,loader:()=>n.e(4972).then(n.bind(n,4972)),modules:["@theme/NotFound"],webpack:()=>[4972],render(e,t){const n=e.default;return r.createElement(d.z,{value:{plugin:{name:"native",id:"default"}}},r.createElement(n,t))}});const o=l[`${e}-${t}`],f={},p=[],m=[],g=(0,c.Z)(o);return Object.entries(g).forEach((e=>{let[t,n]=e;const r=s[n];r&&(f[t]=r[0],p.push(r[1]),m.push(r[2]))})),i().Map({loading:u,loader:f,modules:p,webpack:()=>m,render(t,n){const i=JSON.parse(JSON.stringify(o));Object.entries(t).forEach((t=>{let[n,r]=t;const a=r.default;if(!a)throw new Error(`The page component at ${e} doesn't have a default export. This makes it impossible to render anything. Consider default-exporting a React component.`);"object"!=typeof a&&"function"!=typeof a||Object.keys(r).filter((e=>"default"!==e)).forEach((e=>{a[e]=r[e]}));let o=i;const l=n.split(".");l.slice(0,-1).forEach((e=>{o=o[e]})),o[l[l.length-1]]=a}));const l=i.__comp;delete i.__comp;const s=i.__context;return delete i.__context,r.createElement(d.z,{value:s},r.createElement(l,(0,a.Z)({},i,n)))}})}const p=[{path:"/docs/club",component:f("/docs/club","e39"),routes:[{path:"/docs/club",component:f("/docs/club","4b2"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2021-2022/fall-gbm-09-09-21",component:f("/docs/club/2021-2022/fall-gbm-09-09-21","e9c"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2021-2022/fall-gbm-10-13-21",component:f("/docs/club/2021-2022/fall-gbm-10-13-21","f14"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2021-2022/NLP-workshop",component:f("/docs/club/2021-2022/NLP-workshop","4ff"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2021-2022/spring-gbm-01-06-22",component:f("/docs/club/2021-2022/spring-gbm-01-06-22","0ec"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2021-2022/spring-gbm-03-30-22",component:f("/docs/club/2021-2022/spring-gbm-03-30-22","3bd"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2021-2022/spring-gbm-04-06-22",component:f("/docs/club/2021-2022/spring-gbm-04-06-22","d3e"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2021-2022/swamphacks-git-01-26-22",component:f("/docs/club/2021-2022/swamphacks-git-01-26-22","d58"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2021-2022/swamphacks-sql-01-30-22",component:f("/docs/club/2021-2022/swamphacks-sql-01-30-22","36e"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2022-2023/fall-gbm-09-07-2022",component:f("/docs/club/2022-2023/fall-gbm-09-07-2022","f42"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2022-2023/fall-gbm-11-04-2022",component:f("/docs/club/2022-2023/fall-gbm-11-04-2022","9d1"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2022-2023/spring-gbm-01-25-2023",component:f("/docs/club/2022-2023/spring-gbm-01-25-2023","824"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2022-2023/spring-gbm-03-30-2023",component:f("/docs/club/2022-2023/spring-gbm-03-30-2023","f89"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2022-2023/spring-project-proposals",component:f("/docs/club/2022-2023/spring-project-proposals","edb"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/club/2023-2024/fall-gbm-09-06-2023",component:f("/docs/club/2023-2024/fall-gbm-09-06-2023","ec7"),exact:!0,sidebar:"defaultSidebar"}]},{path:"/docs/osc-docs",component:f("/docs/osc-docs","071"),routes:[{path:"/docs/osc-docs",component:f("/docs/osc-docs","29f"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/osc-docs/docusaurus",component:f("/docs/osc-docs/docusaurus","e35"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/osc-docs/installation",component:f("/docs/osc-docs/installation","e4b"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/osc-docs/markdown",component:f("/docs/osc-docs/markdown","016"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/osc-docs/static-pages",component:f("/docs/osc-docs/static-pages","978"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/osc-docs/usage",component:f("/docs/osc-docs/usage","176"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/osc-docs/writingdocs",component:f("/docs/osc-docs/writingdocs","4e7"),exact:!0,sidebar:"defaultSidebar"}]},{path:"/docs/website",component:f("/docs/website","dd7"),routes:[{path:"/docs/website",component:f("/docs/website","8fc"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/admin",component:f("/docs/website/admin","d57"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/api-reference",component:f("/docs/website/api-reference","8ed"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/API",component:f("/docs/website/Developers/API","614"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/API/blog",component:f("/docs/website/Developers/API/blog","5c6"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/API/contact",component:f("/docs/website/Developers/API/contact","e91"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/API/edit",component:f("/docs/website/Developers/API/edit","ec9"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/API/images",component:f("/docs/website/Developers/API/images","98a"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/API/users",component:f("/docs/website/Developers/API/users","d97"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/authentication",component:f("/docs/website/Developers/authentication","6a0"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/caching",component:f("/docs/website/Developers/caching","7a4"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/configuration",component:f("/docs/website/Developers/configuration","a37"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/contributing-guide",component:f("/docs/website/Developers/contributing-guide","01d"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/Databases/image-storage",component:f("/docs/website/Developers/Databases/image-storage","2b2"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/Databases/models",component:f("/docs/website/Developers/Databases/models","4dc"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/Databases/mongodb",component:f("/docs/website/Developers/Databases/mongodb","0d0"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/introduction",component:f("/docs/website/Developers/introduction","b04"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/rendering",component:f("/docs/website/Developers/rendering","d50"),exact:!0,sidebar:"defaultSidebar"},{path:"/docs/website/Developers/testing",component:f("/docs/website/Developers/testing","ae0"),exact:!0,sidebar:"defaultSidebar"}]},{path:"/",component:f("/","abe"),exact:!0},{path:"*",component:f("*")}]},8934:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,t:()=>o});var r=n(7294);const a=r.createContext(!1);function o(e){let{children:t}=e;const[n,o]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{o(!0)}),[]),r.createElement(a.Provider,{value:n},t)}},9383:(e,t,n)=>{"use strict";var r=n(7294),a=n(3935),o=n(3727),i=n(405),l=n(412);const s=[n(2497),n(3310),n(8320),n(2295)];var u=n(723),c=n(6550),d=n(8790);function f(e){let{children:t}=e;return r.createElement(r.Fragment,null,t)}var p=n(7462),m=n(5742),g=n(2263),h=n(4996),b=n(6668),v=n(1944),y=n(4711),w=n(9727),k=n(3320),E=n(197);function S(){const{i18n:{defaultLocale:e,localeConfigs:t}}=(0,g.Z)(),n=(0,y.l)();return r.createElement(m.Z,null,Object.entries(t).map((e=>{let[t,{htmlLang:a}]=e;return r.createElement("link",{key:t,rel:"alternate",href:n.createUrl({locale:t,fullyQualified:!0}),hrefLang:a})})),r.createElement("link",{rel:"alternate",href:n.createUrl({locale:e,fullyQualified:!0}),hrefLang:"x-default"}))}function x(e){let{permalink:t}=e;const{siteConfig:{url:n}}=(0,g.Z)(),a=function(){const{siteConfig:{url:e}}=(0,g.Z)(),{pathname:t}=(0,c.TH)();return e+(0,h.Z)(t)}(),o=t?`${n}${t}`:a;return r.createElement(m.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function _(){const{i18n:{currentLocale:e}}=(0,g.Z)(),{metadata:t,image:n}=(0,b.L)();return r.createElement(r.Fragment,null,r.createElement(m.Z,null,r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:w.h})),n&&r.createElement(v.d,{image:n}),r.createElement(x,null),r.createElement(S,null),r.createElement(E.Z,{tag:k.HX,locale:e}),r.createElement(m.Z,null,t.map(((e,t)=>r.createElement("meta",(0,p.Z)({key:t},e))))))}const C=new Map;function T(e){if(C.has(e.pathname))return{...e,pathname:C.get(e.pathname)};if((0,d.f)(u.Z,e.pathname).some((e=>{let{route:t}=e;return!0===t.exact})))return C.set(e.pathname,e.pathname),e;const t=e.pathname.trim().replace(/(?:\/index)?\.html$/,"")||"/";return C.set(e.pathname,t),{...e,pathname:t}}var A=n(8934),L=n(8940);function D(e){for(var t=arguments.length,n=new Array(t>1?t-1:0),r=1;r{const r=t.default?.[e]??t[e];return r?.(...n)}));return()=>a.forEach((e=>e?.()))}const P=function(e){let{children:t,location:n,previousLocation:a}=e;return(0,r.useLayoutEffect)((()=>{a!==n&&(!function(e){let{location:t,previousLocation:n}=e;if(!n)return;const r=t.pathname===n.pathname,a=t.hash===n.hash,o=t.search===n.search;if(r&&a&&!o)return;const{hash:i}=t;if(i){const e=decodeURIComponent(i.substring(1)),t=document.getElementById(e);t?.scrollIntoView()}else window.scrollTo(0,0)}({location:n,previousLocation:a}),D("onRouteDidUpdate",{previousLocation:a,location:n}))}),[a,n]),t};function N(e){const t=Array.from(new Set([e,decodeURI(e)])).map((e=>(0,d.f)(u.Z,e))).flat();return Promise.all(t.map((e=>e.route.component.preload?.())))}class R extends r.Component{previousLocation;routeUpdateCleanupCb;constructor(e){super(e),this.previousLocation=null,this.routeUpdateCleanupCb=l.Z.canUseDOM?D("onRouteUpdate",{previousLocation:null,location:this.props.location}):()=>{},this.state={nextRouteHasLoaded:!0}}shouldComponentUpdate(e,t){if(e.location===this.props.location)return t.nextRouteHasLoaded;const n=e.location;return this.previousLocation=this.props.location,this.setState({nextRouteHasLoaded:!1}),this.routeUpdateCleanupCb=D("onRouteUpdate",{previousLocation:this.previousLocation,location:n}),N(n.pathname).then((()=>{this.routeUpdateCleanupCb(),this.setState({nextRouteHasLoaded:!0})})).catch((e=>{console.warn(e),window.location.reload()})),!1}render(){const{children:e,location:t}=this.props;return r.createElement(P,{previousLocation:this.previousLocation,location:t},r.createElement(c.AW,{location:t,render:()=>e}))}}const O=R,I="__docusaurus-base-url-issue-banner-container",M="__docusaurus-base-url-issue-banner",F="__docusaurus-base-url-issue-banner-suggestion-container",B="__DOCUSAURUS_INSERT_BASEURL_BANNER";function j(e){return`\nwindow['${B}'] = true;\n\ndocument.addEventListener('DOMContentLoaded', maybeInsertBanner);\n\nfunction maybeInsertBanner() {\n var shouldInsert = window['${B}'];\n shouldInsert && insertBanner();\n}\n\nfunction insertBanner() {\n var bannerContainer = document.getElementById('${I}');\n if (!bannerContainer) {\n return;\n }\n var bannerHtml = ${JSON.stringify(function(e){return`\n
\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = ${e} ${"/"===e?" (default value)":""}

\n

We suggest trying baseUrl =

\n
\n`}(e)).replace(/{window[B]=!1}),[]),r.createElement(r.Fragment,null,!l.Z.canUseDOM&&r.createElement(m.Z,null,r.createElement("script",null,j(e))),r.createElement("div",{id:I}))}function U(){const{siteConfig:{baseUrl:e,baseUrlIssueBanner:t}}=(0,g.Z)(),{pathname:n}=(0,c.TH)();return t&&n===e?r.createElement(z,null):null}function $(){const{siteConfig:{favicon:e,title:t,noIndex:n},i18n:{currentLocale:a,localeConfigs:o}}=(0,g.Z)(),i=(0,h.Z)(e),{htmlLang:l,direction:s}=o[a];return r.createElement(m.Z,null,r.createElement("html",{lang:l,dir:s}),r.createElement("title",null,t),r.createElement("meta",{property:"og:title",content:t}),r.createElement("meta",{name:"viewport",content:"width=device-width, initial-scale=1.0"}),n&&r.createElement("meta",{name:"robots",content:"noindex, nofollow"}),e&&r.createElement("link",{rel:"icon",href:i}))}var q=n(4763);function H(){const e=(0,d.H)(u.Z),t=(0,c.TH)();return r.createElement(q.Z,null,r.createElement(L.M,null,r.createElement(A.t,null,r.createElement(f,null,r.createElement($,null),r.createElement(_,null),r.createElement(U,null),r.createElement(O,{location:T(t)},e)))))}var G=n(6887);const Z=function(e){try{return document.createElement("link").relList.supports(e)}catch{return!1}}("prefetch")?function(e){return new Promise(((t,n)=>{if("undefined"==typeof document)return void n();const r=document.createElement("link");r.setAttribute("rel","prefetch"),r.setAttribute("href",e),r.onload=()=>t(),r.onerror=()=>n();const a=document.getElementsByTagName("head")[0]??document.getElementsByName("script")[0]?.parentNode;a?.appendChild(r)}))}:function(e){return new Promise(((t,n)=>{const r=new XMLHttpRequest;r.open("GET",e,!0),r.withCredentials=!0,r.onload=()=>{200===r.status?t():n()},r.send(null)}))};var V=n(9670);const W=new Set,Y=new Set,K=()=>navigator.connection?.effectiveType.includes("2g")||navigator.connection?.saveData,Q={prefetch(e){if(!(e=>!K()&&!Y.has(e)&&!W.has(e))(e))return!1;W.add(e);const t=(0,d.f)(u.Z,e).flatMap((e=>{return t=e.route.path,Object.entries(G).filter((e=>{let[n]=e;return n.replace(/-[^-]+$/,"")===t})).flatMap((e=>{let[,t]=e;return Object.values((0,V.Z)(t))}));var t}));return Promise.all(t.map((e=>{const t=n.gca(e);return t&&!t.includes("undefined")?Z(t).catch((()=>{})):Promise.resolve()})))},preload:e=>!!(e=>!K()&&!Y.has(e))(e)&&(Y.add(e),N(e))},X=Object.freeze(Q);if(l.Z.canUseDOM){window.docusaurus=X;const e=a.hydrate;N(window.location.pathname).then((()=>{e(r.createElement(i.B6,null,r.createElement(o.VK,null,r.createElement(H,null))),document.getElementById("__docusaurus"))}))}},8940:(e,t,n)=>{"use strict";n.d(t,{_:()=>c,M:()=>d});var r=n(7294),a=n(6809);const o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/docs/club","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs/club","mainDocId":"index","docs":[{"id":"2021-2022/fall-gbm-09-09-21","path":"/docs/club/2021-2022/fall-gbm-09-09-21","sidebar":"defaultSidebar"},{"id":"2021-2022/fall-gbm-10-13-21","path":"/docs/club/2021-2022/fall-gbm-10-13-21","sidebar":"defaultSidebar"},{"id":"2021-2022/NLP-workshop","path":"/docs/club/2021-2022/NLP-workshop","sidebar":"defaultSidebar"},{"id":"2021-2022/spring-gbm-01-06-22","path":"/docs/club/2021-2022/spring-gbm-01-06-22","sidebar":"defaultSidebar"},{"id":"2021-2022/spring-gbm-03-30-22","path":"/docs/club/2021-2022/spring-gbm-03-30-22","sidebar":"defaultSidebar"},{"id":"2021-2022/spring-gbm-04-06-22","path":"/docs/club/2021-2022/spring-gbm-04-06-22","sidebar":"defaultSidebar"},{"id":"2021-2022/swamphacks-git-01-26-22","path":"/docs/club/2021-2022/swamphacks-git-01-26-22","sidebar":"defaultSidebar"},{"id":"2021-2022/swamphacks-sql-01-30-22","path":"/docs/club/2021-2022/swamphacks-sql-01-30-22","sidebar":"defaultSidebar"},{"id":"2022-2023/fall-gbm-09-07-2022","path":"/docs/club/2022-2023/fall-gbm-09-07-2022","sidebar":"defaultSidebar"},{"id":"2022-2023/fall-gbm-11-04-2022","path":"/docs/club/2022-2023/fall-gbm-11-04-2022","sidebar":"defaultSidebar"},{"id":"2022-2023/spring-gbm-01-25-2023","path":"/docs/club/2022-2023/spring-gbm-01-25-2023","sidebar":"defaultSidebar"},{"id":"2022-2023/spring-gbm-03-30-2023","path":"/docs/club/2022-2023/spring-gbm-03-30-2023","sidebar":"defaultSidebar"},{"id":"2022-2023/spring-project-proposals","path":"/docs/club/2022-2023/spring-project-proposals","sidebar":"defaultSidebar"},{"id":"2023-2024/fall-gbm-09-06-2023","path":"/docs/club/2023-2024/fall-gbm-09-06-2023","sidebar":"defaultSidebar"},{"id":"index","path":"/docs/club/","sidebar":"defaultSidebar"}],"draftIds":[],"sidebars":{"defaultSidebar":{"link":{"path":"/docs/club/","label":"index"}}}}],"breadcrumbs":true},"osc-docs":{"path":"/docs/osc-docs","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs/osc-docs","mainDocId":"index","docs":[{"id":"docusaurus","path":"/docs/osc-docs/docusaurus","sidebar":"defaultSidebar"},{"id":"index","path":"/docs/osc-docs/","sidebar":"defaultSidebar"},{"id":"installation","path":"/docs/osc-docs/installation","sidebar":"defaultSidebar"},{"id":"markdown","path":"/docs/osc-docs/markdown","sidebar":"defaultSidebar"},{"id":"static-pages","path":"/docs/osc-docs/static-pages","sidebar":"defaultSidebar"},{"id":"usage","path":"/docs/osc-docs/usage","sidebar":"defaultSidebar"},{"id":"writingdocs","path":"/docs/osc-docs/writingdocs","sidebar":"defaultSidebar"}],"draftIds":[],"sidebars":{"defaultSidebar":{"link":{"path":"/docs/osc-docs/","label":"index"}}}}],"breadcrumbs":true},"website":{"path":"/docs/website","versions":[{"name":"current","label":"Next","isLast":true,"path":"/docs/website","mainDocId":"index","docs":[{"id":"admin","path":"/docs/website/admin","sidebar":"defaultSidebar"},{"id":"api-reference","path":"/docs/website/api-reference","sidebar":"defaultSidebar"},{"id":"Developers/API/api","path":"/docs/website/Developers/API/","sidebar":"defaultSidebar"},{"id":"Developers/API/blog","path":"/docs/website/Developers/API/blog","sidebar":"defaultSidebar"},{"id":"Developers/API/contact","path":"/docs/website/Developers/API/contact","sidebar":"defaultSidebar"},{"id":"Developers/API/edit","path":"/docs/website/Developers/API/edit","sidebar":"defaultSidebar"},{"id":"Developers/API/images","path":"/docs/website/Developers/API/images","sidebar":"defaultSidebar"},{"id":"Developers/API/users","path":"/docs/website/Developers/API/users","sidebar":"defaultSidebar"},{"id":"Developers/authentication","path":"/docs/website/Developers/authentication","sidebar":"defaultSidebar"},{"id":"Developers/caching","path":"/docs/website/Developers/caching","sidebar":"defaultSidebar"},{"id":"Developers/configuration","path":"/docs/website/Developers/configuration","sidebar":"defaultSidebar"},{"id":"Developers/contributing-guide","path":"/docs/website/Developers/contributing-guide","sidebar":"defaultSidebar"},{"id":"Developers/Databases/image-storage","path":"/docs/website/Developers/Databases/image-storage","sidebar":"defaultSidebar"},{"id":"Developers/Databases/models","path":"/docs/website/Developers/Databases/models","sidebar":"defaultSidebar"},{"id":"Developers/Databases/mongodb","path":"/docs/website/Developers/Databases/mongodb","sidebar":"defaultSidebar"},{"id":"Developers/introduction","path":"/docs/website/Developers/introduction","sidebar":"defaultSidebar"},{"id":"Developers/rendering","path":"/docs/website/Developers/rendering","sidebar":"defaultSidebar"},{"id":"Developers/testing","path":"/docs/website/Developers/testing","sidebar":"defaultSidebar"},{"id":"index","path":"/docs/website/","sidebar":"defaultSidebar"}],"draftIds":[],"sidebars":{"defaultSidebar":{"link":{"path":"/docs/website/","label":"index"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"path":"i18n","currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en","calendar":"gregory","path":"en"}}}');var l=n(7529);const s=JSON.parse('{"docusaurusVersion":"2.4.1","siteVersion":"1.0.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.4.1"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.4.1"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.4.1"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.4.1"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.4.1"}}}'),u={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},c=r.createContext(u);function d(e){let{children:t}=e;return r.createElement(c.Provider,{value:u},t)}},4763:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var r=n(7294),a=n(412),o=n(5742),i=n(8780),l=n(7961);function s(e){let{error:t,tryAgain:n}=e;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"flex-start",minHeight:"100vh",width:"100%",maxWidth:"80ch",fontSize:"20px",margin:"0 auto",padding:"1rem"}},r.createElement("h1",{style:{fontSize:"3rem"}},"This page crashed"),r.createElement("button",{type:"button",onClick:n,style:{margin:"1rem 0",fontSize:"2rem",cursor:"pointer",borderRadius:20,padding:"1rem"}},"Try again"),r.createElement(u,{error:t}))}function u(e){let{error:t}=e;const n=(0,i.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{style:{whiteSpace:"pre-wrap"}},n)}function c(e){let{error:t,tryAgain:n}=e;return r.createElement(f,{fallback:()=>r.createElement(s,{error:t,tryAgain:n})},r.createElement(o.Z,null,r.createElement("title",null,"Page Error")),r.createElement(l.Z,null,r.createElement(s,{error:t,tryAgain:n})))}const d=e=>r.createElement(c,e);class f extends r.Component{constructor(e){super(e),this.state={error:null}}componentDidCatch(e){a.Z.canUseDOM&&this.setState({error:e})}render(){const{children:e}=this.props,{error:t}=this.state;if(t){const e={error:t,tryAgain:()=>this.setState({error:null})};return(this.props.fallback??d)(e)}return e??null}}},412:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r="undefined"!=typeof window&&"document"in window&&"createElement"in window.document,a={canUseDOM:r,canUseEventListeners:r&&("addEventListener"in window||"attachEvent"in window),canUseIntersectionObserver:r&&"IntersectionObserver"in window,canUseViewport:r&&"screen"in window}},5742:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(405);function o(e){return r.createElement(a.ql,e)}},9960:(e,t,n)=>{"use strict";n.d(t,{Z:()=>p});var r=n(7462),a=n(7294),o=n(3727),i=n(8780),l=n(2263),s=n(3919),u=n(412);const c=a.createContext({collectLink:()=>{}});var d=n(4996);function f(e,t){let{isNavLink:n,to:f,href:p,activeClassName:m,isActive:g,"data-noBrokenLinkCheck":h,autoAddBaseUrl:b=!0,...v}=e;const{siteConfig:{trailingSlash:y,baseUrl:w}}=(0,l.Z)(),{withBaseUrl:k}=(0,d.C)(),E=(0,a.useContext)(c),S=(0,a.useRef)(null);(0,a.useImperativeHandle)(t,(()=>S.current));const x=f||p;const _=(0,s.Z)(x),C=x?.replace("pathname://","");let T=void 0!==C?(A=C,b&&(e=>e.startsWith("/"))(A)?k(A):A):void 0;var A;T&&_&&(T=(0,i.applyTrailingSlash)(T,{trailingSlash:y,baseUrl:w}));const L=(0,a.useRef)(!1),D=n?o.OL:o.rU,P=u.Z.canUseIntersectionObserver,N=(0,a.useRef)(),R=()=>{L.current||null==T||(window.docusaurus.preload(T),L.current=!0)};(0,a.useEffect)((()=>(!P&&_&&null!=T&&window.docusaurus.prefetch(T),()=>{P&&N.current&&N.current.disconnect()})),[N,T,P,_]);const O=T?.startsWith("#")??!1,I=!T||!_||O;return I||h||E.collectLink(T),I?a.createElement("a",(0,r.Z)({ref:S,href:T},x&&!_&&{target:"_blank",rel:"noopener noreferrer"},v)):a.createElement(D,(0,r.Z)({},v,{onMouseEnter:R,onTouchStart:R,innerRef:e=>{S.current=e,P&&e&&_&&(N.current=new window.IntersectionObserver((t=>{t.forEach((t=>{e===t.target&&(t.isIntersecting||t.intersectionRatio>0)&&(N.current.unobserve(e),N.current.disconnect(),null!=T&&window.docusaurus.prefetch(T))}))})),N.current.observe(e))},to:T},n&&{isActive:g,activeClassName:m}))}const p=a.forwardRef(f)},1875:(e,t,n)=>{"use strict";n.d(t,{Z:()=>r});const r=()=>null},5999:(e,t,n)=>{"use strict";n.d(t,{Z:()=>s,I:()=>l});var r=n(7294);function a(e,t){const n=e.split(/(\{\w+\})/).map(((e,n)=>{if(n%2==1){const n=t?.[e.slice(1,-1)];if(void 0!==n)return n}return e}));return n.some((e=>(0,r.isValidElement)(e)))?n.map(((e,t)=>(0,r.isValidElement)(e)?r.cloneElement(e,{key:t}):e)).filter((e=>""!==e)):n.join("")}var o=n(7529);function i(e){let{id:t,message:n}=e;if(void 0===t&&void 0===n)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return o[t??n]??n??t}function l(e,t){let{message:n,id:r}=e;return a(i({message:n,id:r}),t)}function s(e){let{children:t,id:n,values:o}=e;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");const l=i({message:t,id:n});return r.createElement(r.Fragment,null,a(l,o))}},9935:(e,t,n)=>{"use strict";n.d(t,{m:()=>r});const r="default"},3919:(e,t,n)=>{"use strict";function r(e){return/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:()=>a,b:()=>r})},4996:(e,t,n)=>{"use strict";n.d(t,{C:()=>i,Z:()=>l});var r=n(7294),a=n(2263),o=n(3919);function i(){const{siteConfig:{baseUrl:e,url:t}}=(0,a.Z)(),n=(0,r.useCallback)(((n,r)=>function(e,t,n,r){let{forcePrependBaseUrl:a=!1,absolute:i=!1}=void 0===r?{}:r;if(!n||n.startsWith("#")||(0,o.b)(n))return n;if(a)return t+n.replace(/^\//,"");if(n===t.replace(/\/$/,""))return t;const l=n.startsWith(t)?n:t+n.replace(/^\//,"");return i?e+l:l}(t,e,n,r)),[t,e]);return{withBaseUrl:n}}function l(e,t){void 0===t&&(t={});const{withBaseUrl:n}=i();return n(e,t)}},2263:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8940);function o(){return(0,r.useContext)(a._)}},2389:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(8934);function o(){return(0,r.useContext)(a._)}},9670:(e,t,n)=>{"use strict";n.d(t,{Z:()=>a});const r=e=>"object"==typeof e&&!!e&&Object.keys(e).length>0;function a(e){const t={};return function e(n,a){Object.entries(n).forEach((n=>{let[o,i]=n;const l=a?`${a}.${o}`:o;r(i)?e(i,l):t[l]=i}))}(e),t}},226:(e,t,n)=>{"use strict";n.d(t,{_:()=>a,z:()=>o});var r=n(7294);const a=r.createContext(null);function o(e){let{children:t,value:n}=e;const o=r.useContext(a),i=(0,r.useMemo)((()=>function(e){let{parent:t,value:n}=e;if(!t){if(!n)throw new Error("Unexpected: no Docusaurus route context found");if(!("plugin"in n))throw new Error("Unexpected: Docusaurus topmost route context has no `plugin` attribute");return n}const r={...t.data,...n?.data};return{plugin:t.plugin,data:r}}({parent:o,value:n})),[o,n]);return r.createElement(a.Provider,{value:i},t)}},143:(e,t,n)=>{"use strict";n.d(t,{Iw:()=>g,gA:()=>f,_r:()=>c,Jo:()=>h,zh:()=>d,yW:()=>m,gB:()=>p});var r=n(6550),a=n(2263),o=n(9935);function i(e,t){void 0===t&&(t={});const n=function(){const{globalData:e}=(0,a.Z)();return e}()[e];if(!n&&t.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin.`);return n}const l=e=>e.versions.find((e=>e.isLast));function s(e,t){const n=function(e,t){const n=l(e);return[...e.versions.filter((e=>e!==n)),n].find((e=>!!(0,r.LX)(t,{path:e.path,exact:!1,strict:!1})))}(e,t),a=n?.docs.find((e=>!!(0,r.LX)(t,{path:e.path,exact:!0,strict:!1})));return{activeVersion:n,activeDoc:a,alternateDocVersions:a?function(t){const n={};return e.versions.forEach((e=>{e.docs.forEach((r=>{r.id===t&&(n[e.name]=r)}))})),n}(a.id):{}}}const u={},c=()=>i("docusaurus-plugin-content-docs")??u,d=e=>function(e,t,n){void 0===t&&(t=o.m),void 0===n&&(n={});const r=i(e),a=r?.[t];if(!a&&n.failfast)throw new Error(`Docusaurus plugin global data not found for "${e}" plugin with id "${t}".`);return a}("docusaurus-plugin-content-docs",e,{failfast:!0});function f(e){void 0===e&&(e={});const t=c(),{pathname:n}=(0,r.TH)();return function(e,t,n){void 0===n&&(n={});const a=Object.entries(e).sort(((e,t)=>t[1].path.localeCompare(e[1].path))).find((e=>{let[,n]=e;return!!(0,r.LX)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error(`Can't find active docs plugin for "${t}" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: ${Object.values(e).map((e=>e.path)).join(", ")}`);return o}(t,n,e)}function p(e){return d(e).versions}function m(e){const t=d(e);return l(t)}function g(e){const t=d(e),{pathname:n}=(0,r.TH)();return s(t,n)}function h(e){const t=d(e),{pathname:n}=(0,r.TH)();return function(e,t){const n=l(e);return{latestDocSuggestion:s(e,t).alternateDocVersions[n.name],latestVersionSuggestion:n}}(t,n)}},8320:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>o});var r=n(4865),a=n.n(r);a().configure({showSpinner:!1});const o={onRouteUpdate(e){let{location:t,previousLocation:n}=e;if(n&&t.pathname!==n.pathname){const e=window.setTimeout((()=>{a().start()}),200);return()=>window.clearTimeout(e)}},onRouteDidUpdate(){a().done()}}},3310:(e,t,n)=>{"use strict";n.r(t);var r=n(7410),a=n(6809);!function(e){const{themeConfig:{prism:t}}=a.default,{additionalLanguages:r}=t;globalThis.Prism=e,r.forEach((e=>{n(6726)(`./prism-${e}`)})),delete globalThis.Prism}(r.Z)},9471:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294);const a={iconExternalLink:"iconExternalLink_nPIU"};function o(e){let{width:t=13.5,height:n=13.5}=e;return r.createElement("svg",{width:t,height:n,"aria-hidden":"true",viewBox:"0 0 24 24",className:a.iconExternalLink},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},7961:(e,t,n)=>{"use strict";n.d(t,{Z:()=>dt});var r=n(7294),a=n(6010),o=n(4763),i=n(1944),l=n(7462),s=n(6550),u=n(5999),c=n(5936);const d="__docusaurus_skipToContent_fallback";function f(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function p(){const e=(0,r.useRef)(null),{action:t}=(0,s.k6)(),n=(0,r.useCallback)((e=>{e.preventDefault();const t=document.querySelector("main:first-of-type")??document.getElementById(d);t&&f(t)}),[]);return(0,c.S)((n=>{let{location:r}=n;e.current&&!r.hash&&"PUSH"===t&&f(e.current)})),{containerRef:e,onClick:n}}const m=(0,u.I)({id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",message:"Skip to main content"});function g(e){const t=e.children??m,{containerRef:n,onClick:a}=p();return r.createElement("div",{ref:n,role:"region","aria-label":m},r.createElement("a",(0,l.Z)({},e,{href:`#${d}`,onClick:a}),t))}var h=n(5281),b=n(9727);const v={skipToContent:"skipToContent_fXgn"};function y(){return r.createElement(g,{className:v.skipToContent})}var w=n(6668),k=n(9689);function E(e){let{width:t=21,height:n=21,color:a="currentColor",strokeWidth:o=1.2,className:i,...s}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 15 15",width:t,height:n},s),r.createElement("g",{stroke:a,strokeWidth:o},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}const S={closeButton:"closeButton_CVFx"};function x(e){return r.createElement("button",(0,l.Z)({type:"button","aria-label":(0,u.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},e,{className:(0,a.Z)("clean-btn close",S.closeButton,e.className)}),r.createElement(E,{width:14,height:14,strokeWidth:3.1}))}const _={content:"content_knG7"};function C(e){const{announcementBar:t}=(0,w.L)(),{content:n}=t;return r.createElement("div",(0,l.Z)({},e,{className:(0,a.Z)(_.content,e.className),dangerouslySetInnerHTML:{__html:n}}))}const T={announcementBar:"announcementBar_mb4j",announcementBarPlaceholder:"announcementBarPlaceholder_vyr4",announcementBarClose:"announcementBarClose_gvF7",announcementBarContent:"announcementBarContent_xLdY"};function A(){const{announcementBar:e}=(0,w.L)(),{isActive:t,close:n}=(0,k.nT)();if(!t)return null;const{backgroundColor:a,textColor:o,isCloseable:i}=e;return r.createElement("div",{className:T.announcementBar,style:{backgroundColor:a,color:o},role:"banner"},i&&r.createElement("div",{className:T.announcementBarPlaceholder}),r.createElement(C,{className:T.announcementBarContent}),i&&r.createElement(x,{onClick:n,className:T.announcementBarClose}))}var L=n(2961),D=n(2466);var P=n(902),N=n(3102);const R=r.createContext(null);function O(e){let{children:t}=e;const n=function(){const e=(0,L.e)(),t=(0,N.HY)(),[n,a]=(0,r.useState)(!1),o=null!==t.component,i=(0,P.D9)(o);return(0,r.useEffect)((()=>{o&&!i&&a(!0)}),[o,i]),(0,r.useEffect)((()=>{o?e.shown||a(!0):a(!1)}),[e.shown,o]),(0,r.useMemo)((()=>[n,a]),[n])}();return r.createElement(R.Provider,{value:n},t)}function I(e){if(e.component){const t=e.component;return r.createElement(t,e.props)}}function M(){const e=(0,r.useContext)(R);if(!e)throw new P.i6("NavbarSecondaryMenuDisplayProvider");const[t,n]=e,a=(0,r.useCallback)((()=>n(!1)),[n]),o=(0,N.HY)();return(0,r.useMemo)((()=>({shown:t,hide:a,content:I(o)})),[a,o,t])}function F(e){let{header:t,primaryMenu:n,secondaryMenu:o}=e;const{shown:i}=M();return r.createElement("div",{className:"navbar-sidebar"},t,r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":i})},r.createElement("div",{className:"navbar-sidebar__item menu"},n),r.createElement("div",{className:"navbar-sidebar__item menu"},o)))}var B=n(2949),j=n(2389);function z(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function U(e){return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}const $={toggle:"toggle_vylO",toggleButton:"toggleButton_gllP",darkToggleIcon:"darkToggleIcon_wfgR",lightToggleIcon:"lightToggleIcon_pyhR",toggleButtonDisabled:"toggleButtonDisabled_aARS"};function q(e){let{className:t,buttonClassName:n,value:o,onChange:i}=e;const l=(0,j.Z)(),s=(0,u.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:"dark"===o?(0,u.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,u.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})});return r.createElement("div",{className:(0,a.Z)($.toggle,t)},r.createElement("button",{className:(0,a.Z)("clean-btn",$.toggleButton,!l&&$.toggleButtonDisabled,n),type:"button",onClick:()=>i("dark"===o?"light":"dark"),disabled:!l,title:s,"aria-label":s,"aria-live":"polite"},r.createElement(z,{className:(0,a.Z)($.toggleIcon,$.lightToggleIcon)}),r.createElement(U,{className:(0,a.Z)($.toggleIcon,$.darkToggleIcon)})))}const H=r.memo(q),G={darkNavbarColorModeToggle:"darkNavbarColorModeToggle_X3D1"};function Z(e){let{className:t}=e;const n=(0,w.L)().navbar.style,a=(0,w.L)().colorMode.disableSwitch,{colorMode:o,setColorMode:i}=(0,B.I)();return a?null:r.createElement(H,{className:t,buttonClassName:"dark"===n?G.darkNavbarColorModeToggle:void 0,value:o,onChange:i})}var V=n(1327);function W(){return r.createElement(V.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title text--truncate"})}function Y(){const e=(0,L.e)();return r.createElement("button",{type:"button","aria-label":(0,u.I)({id:"theme.docs.sidebar.closeSidebarButtonAriaLabel",message:"Close navigation bar",description:"The ARIA label for close button of mobile sidebar"}),className:"clean-btn navbar-sidebar__close",onClick:()=>e.toggle()},r.createElement(E,{color:"var(--ifm-color-emphasis-600)"}))}function K(){return r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(W,null),r.createElement(Z,{className:"margin-right--md"}),r.createElement(Y,null))}var Q=n(9960),X=n(4996),J=n(3919);function ee(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var te=n(9471);function ne(e){let{activeBasePath:t,activeBaseRegex:n,to:a,href:o,label:i,html:s,isDropdownLink:u,prependBaseUrlToHref:c,...d}=e;const f=(0,X.Z)(a),p=(0,X.Z)(t),m=(0,X.Z)(o,{forcePrependBaseUrl:!0}),g=i&&o&&!(0,J.Z)(o),h=s?{dangerouslySetInnerHTML:{__html:s}}:{children:r.createElement(r.Fragment,null,i,g&&r.createElement(te.Z,u&&{width:12,height:12}))};return o?r.createElement(Q.Z,(0,l.Z)({href:c?m:o},d,h)):r.createElement(Q.Z,(0,l.Z)({to:f,isNavLink:!0},(t||n)&&{isActive:(e,t)=>n?ee(n,t.pathname):t.pathname.startsWith(p)},d,h))}function re(e){let{className:t,isDropdownItem:n=!1,...o}=e;const i=r.createElement(ne,(0,l.Z)({className:(0,a.Z)(n?"dropdown__link":"navbar__item navbar__link",t),isDropdownLink:n},o));return n?r.createElement("li",null,i):i}function ae(e){let{className:t,isDropdownItem:n,...o}=e;return r.createElement("li",{className:"menu__list-item"},r.createElement(ne,(0,l.Z)({className:(0,a.Z)("menu__link",t)},o)))}function oe(e){let{mobile:t=!1,position:n,...a}=e;const o=t?ae:re;return r.createElement(o,(0,l.Z)({},a,{activeClassName:a.activeClassName??(t?"menu__link--active":"navbar__link--active")}))}var ie=n(6043),le=n(8596),se=n(2263);function ue(e,t){return e.some((e=>function(e,t){return!!(0,le.Mg)(e.to,t)||!!ee(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)))}function ce(e){let{items:t,position:n,className:o,onClick:i,...s}=e;const u=(0,r.useRef)(null),[c,d]=(0,r.useState)(!1);return(0,r.useEffect)((()=>{const e=e=>{u.current&&!u.current.contains(e.target)&&d(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),document.addEventListener("focusin",e),()=>{document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e),document.removeEventListener("focusin",e)}}),[u]),r.createElement("div",{ref:u,className:(0,a.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===n,"dropdown--show":c})},r.createElement(ne,(0,l.Z)({"aria-haspopup":"true","aria-expanded":c,role:"button",href:s.to?void 0:"#",className:(0,a.Z)("navbar__link",o)},s,{onClick:s.to?void 0:e=>e.preventDefault(),onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),d(!c))}}),s.children??s.label),r.createElement("ul",{className:"dropdown__menu"},t.map(((e,t)=>r.createElement(xe,(0,l.Z)({isDropdownItem:!0,activeClassName:"dropdown__link--active"},e,{key:t}))))))}function de(e){let{items:t,className:n,position:o,onClick:i,...u}=e;const c=function(){const{siteConfig:{baseUrl:e}}=(0,se.Z)(),{pathname:t}=(0,s.TH)();return t.replace(e,"/")}(),d=ue(t,c),{collapsed:f,toggleCollapsed:p,setCollapsed:m}=(0,ie.u)({initialState:()=>!d});return(0,r.useEffect)((()=>{d&&m(!d)}),[c,d,m]),r.createElement("li",{className:(0,a.Z)("menu__list-item",{"menu__list-item--collapsed":f})},r.createElement(ne,(0,l.Z)({role:"button",className:(0,a.Z)("menu__link menu__link--sublist menu__link--sublist-caret",n)},u,{onClick:e=>{e.preventDefault(),p()}}),u.children??u.label),r.createElement(ie.z,{lazy:!0,as:"ul",className:"menu__list",collapsed:f},t.map(((e,t)=>r.createElement(xe,(0,l.Z)({mobile:!0,isDropdownItem:!0,onClick:i,activeClassName:"menu__link--active"},e,{key:t}))))))}function fe(e){let{mobile:t=!1,...n}=e;const a=t?de:ce;return r.createElement(a,n)}var pe=n(4711);function me(e){let{width:t=20,height:n=20,...a}=e;return r.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:t,height:n,"aria-hidden":!0},a),r.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}const ge="iconLanguage_nlXk";var he=n(1875);const be={searchBox:"searchBox_ZlJk"};function ve(e){let{children:t,className:n}=e;return r.createElement("div",{className:(0,a.Z)(n,be.searchBox)},t)}var ye=n(143),we=n(2802);var ke=n(373);const Ee=e=>e.docs.find((t=>t.id===e.mainDocId));const Se={default:oe,localeDropdown:function(e){let{mobile:t,dropdownItemsBefore:n,dropdownItemsAfter:a,...o}=e;const{i18n:{currentLocale:i,locales:c,localeConfigs:d}}=(0,se.Z)(),f=(0,pe.l)(),{search:p,hash:m}=(0,s.TH)(),g=[...n,...c.map((e=>{const n=`${`pathname://${f.createUrl({locale:e,fullyQualified:!1})}`}${p}${m}`;return{label:d[e].label,lang:d[e].htmlLang,to:n,target:"_self",autoAddBaseUrl:!1,className:e===i?t?"menu__link--active":"dropdown__link--active":""}})),...a],h=t?(0,u.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):d[i].label;return r.createElement(fe,(0,l.Z)({},o,{mobile:t,label:r.createElement(r.Fragment,null,r.createElement(me,{className:ge}),h),items:g}))},search:function(e){let{mobile:t,className:n}=e;return t?null:r.createElement(ve,{className:n},r.createElement(he.Z,null))},dropdown:fe,html:function(e){let{value:t,className:n,mobile:o=!1,isDropdownItem:i=!1}=e;const l=i?"li":"div";return r.createElement(l,{className:(0,a.Z)({navbar__item:!o&&!i,"menu__list-item":o},n),dangerouslySetInnerHTML:{__html:t}})},doc:function(e){let{docId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.vY)(t,a);return null===s?null:r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.path===s.path||!!i?.sidebar&&i.sidebar===s.sidebar,label:n??s.id,to:s.path}))},docSidebar:function(e){let{sidebarId:t,label:n,docsPluginId:a,...o}=e;const{activeDoc:i}=(0,ye.Iw)(a),s=(0,we.oz)(t,a).link;if(!s)throw new Error(`DocSidebarNavbarItem: Sidebar with ID "${t}" doesn't have anything to be linked to.`);return r.createElement(oe,(0,l.Z)({exact:!0},o,{isActive:()=>i?.sidebar===t,label:n??s.label,to:s.path}))},docsVersion:function(e){let{label:t,to:n,docsPluginId:a,...o}=e;const i=(0,we.lO)(a)[0],s=t??i.label,u=n??(e=>e.docs.find((t=>t.id===e.mainDocId)))(i).path;return r.createElement(oe,(0,l.Z)({},o,{label:s,to:u}))},docsVersionDropdown:function(e){let{mobile:t,docsPluginId:n,dropdownActiveClassDisabled:a,dropdownItemsBefore:o,dropdownItemsAfter:i,...c}=e;const{search:d,hash:f}=(0,s.TH)(),p=(0,ye.Iw)(n),m=(0,ye.gB)(n),{savePreferredVersionName:g}=(0,ke.J)(n),h=[...o,...m.map((e=>{const t=p.alternateDocVersions[e.name]??Ee(e);return{label:e.label,to:`${t.path}${d}${f}`,isActive:()=>e===p.activeVersion,onClick:()=>g(e.name)}})),...i],b=(0,we.lO)(n)[0],v=t&&h.length>1?(0,u.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):b.label,y=t&&h.length>1?void 0:Ee(b).path;return h.length<=1?r.createElement(oe,(0,l.Z)({},c,{mobile:t,label:v,to:y,isActive:a?()=>!1:void 0})):r.createElement(fe,(0,l.Z)({},c,{mobile:t,label:v,to:y,items:h,isActive:a?()=>!1:void 0}))}};function xe(e){let{type:t,...n}=e;const a=function(e,t){return e&&"default"!==e?e:"items"in t?"dropdown":"default"}(t,n),o=Se[a];if(!o)throw new Error(`No NavbarItem component found for type "${t}".`);return r.createElement(o,n)}function _e(){const e=(0,L.e)(),t=(0,w.L)().navbar.items;return r.createElement("ul",{className:"menu__list"},t.map(((t,n)=>r.createElement(xe,(0,l.Z)({mobile:!0},t,{onClick:()=>e.toggle(),key:n})))))}function Ce(e){return r.createElement("button",(0,l.Z)({},e,{type:"button",className:"clean-btn navbar-sidebar__back"}),r.createElement(u.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu"))}function Te(){const e=0===(0,w.L)().navbar.items.length,t=M();return r.createElement(r.Fragment,null,!e&&r.createElement(Ce,{onClick:()=>t.hide()}),t.content)}function Ae(){const e=(0,L.e)();var t;return void 0===(t=e.shown)&&(t=!0),(0,r.useEffect)((()=>(document.body.style.overflow=t?"hidden":"visible",()=>{document.body.style.overflow="visible"})),[t]),e.shouldRender?r.createElement(F,{header:r.createElement(K,null),primaryMenu:r.createElement(_e,null),secondaryMenu:r.createElement(Te,null)}):null}const Le={navbarHideable:"navbarHideable_m1mJ",navbarHidden:"navbarHidden_jGov"};function De(e){return r.createElement("div",(0,l.Z)({role:"presentation"},e,{className:(0,a.Z)("navbar-sidebar__backdrop",e.className)}))}function Pe(e){let{children:t}=e;const{navbar:{hideOnScroll:n,style:o}}=(0,w.L)(),i=(0,L.e)(),{navbarRef:l,isNavbarVisible:s}=function(e){const[t,n]=(0,r.useState)(e),a=(0,r.useRef)(!1),o=(0,r.useRef)(0),i=(0,r.useCallback)((e=>{null!==e&&(o.current=e.getBoundingClientRect().height)}),[]);return(0,D.RF)(((t,r)=>{let{scrollY:i}=t;if(!e)return;if(i=l?n(!1):i+u{if(!e)return;const r=t.location.hash;if(r?document.getElementById(r.substring(1)):void 0)return a.current=!0,void n(!1);n(!0)})),{navbarRef:i,isNavbarVisible:t}}(n);return r.createElement("nav",{ref:l,"aria-label":(0,u.I)({id:"theme.NavBar.navAriaLabel",message:"Main",description:"The ARIA label for the main navigation"}),className:(0,a.Z)("navbar","navbar--fixed-top",n&&[Le.navbarHideable,!s&&Le.navbarHidden],{"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown})},t,r.createElement(De,{onClick:i.toggle}),r.createElement(Ae,null))}var Ne=n(8780);const Re={errorBoundaryError:"errorBoundaryError_a6uf"};function Oe(e){return r.createElement("button",(0,l.Z)({type:"button"},e),r.createElement(u.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again rendering when the React error boundary captures an error"},"Try again"))}function Ie(e){let{error:t}=e;const n=(0,Ne.getErrorCausalChain)(t).map((e=>e.message)).join("\n\nCause:\n");return r.createElement("p",{className:Re.errorBoundaryError},n)}class Me extends r.Component{componentDidCatch(e,t){throw this.props.onError(e,t)}render(){return this.props.children}}const Fe="right";function Be(e){let{width:t=30,height:n=30,className:a,...o}=e;return r.createElement("svg",(0,l.Z)({className:a,width:t,height:n,viewBox:"0 0 30 30","aria-hidden":"true"},o),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}function je(){const{toggle:e,shown:t}=(0,L.e)();return r.createElement("button",{onClick:e,"aria-label":(0,u.I)({id:"theme.docs.sidebar.toggleSidebarButtonAriaLabel",message:"Toggle navigation bar",description:"The ARIA label for hamburger menu button of mobile navigation"}),"aria-expanded":t,className:"navbar__toggle clean-btn",type:"button"},r.createElement(Be,null))}const ze={colorModeToggle:"colorModeToggle_DEke"};function Ue(e){let{items:t}=e;return r.createElement(r.Fragment,null,t.map(((e,t)=>r.createElement(Me,{key:t,onError:t=>new Error(`A theme navbar item failed to render.\nPlease double-check the following navbar item (themeConfig.navbar.items) of your Docusaurus config:\n${JSON.stringify(e,null,2)}`,{cause:t})},r.createElement(xe,e)))))}function $e(e){let{left:t,right:n}=e;return r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},t),r.createElement("div",{className:"navbar__items navbar__items--right"},n))}function qe(){const e=(0,L.e)(),t=(0,w.L)().navbar.items,[n,a]=function(e){function t(e){return"left"===(e.position??Fe)}return[e.filter(t),e.filter((e=>!t(e)))]}(t),o=t.find((e=>"search"===e.type));return r.createElement($e,{left:r.createElement(r.Fragment,null,!e.disabled&&r.createElement(je,null),r.createElement(W,null),r.createElement(Ue,{items:n})),right:r.createElement(r.Fragment,null,r.createElement(Ue,{items:a}),r.createElement(Z,{className:ze.colorModeToggle}),!o&&r.createElement(ve,null,r.createElement(he.Z,null)))})}function He(){return r.createElement(Pe,null,r.createElement(qe,null))}function Ge(e){let{item:t}=e;const{to:n,href:a,label:o,prependBaseUrlToHref:i,...s}=t,u=(0,X.Z)(n),c=(0,X.Z)(a,{forcePrependBaseUrl:!0});return r.createElement(Q.Z,(0,l.Z)({className:"footer__link-item"},a?{href:i?c:a}:{to:u},s),o,a&&!(0,J.Z)(a)&&r.createElement(te.Z,null))}function Ze(e){let{item:t}=e;return t.html?r.createElement("li",{className:"footer__item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement("li",{key:t.href??t.to,className:"footer__item"},r.createElement(Ge,{item:t}))}function Ve(e){let{column:t}=e;return r.createElement("div",{className:"col footer__col"},r.createElement("div",{className:"footer__title"},t.title),r.createElement("ul",{className:"footer__items clean-list"},t.items.map(((e,t)=>r.createElement(Ze,{key:t,item:e})))))}function We(e){let{columns:t}=e;return r.createElement("div",{className:"row footer__links"},t.map(((e,t)=>r.createElement(Ve,{key:t,column:e}))))}function Ye(){return r.createElement("span",{className:"footer__link-separator"},"\xb7")}function Ke(e){let{item:t}=e;return t.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:t.html}}):r.createElement(Ge,{item:t})}function Qe(e){let{links:t}=e;return r.createElement("div",{className:"footer__links text--center"},r.createElement("div",{className:"footer__links"},t.map(((e,n)=>r.createElement(r.Fragment,{key:n},r.createElement(Ke,{item:e}),t.length!==n+1&&r.createElement(Ye,null))))))}function Xe(e){let{links:t}=e;return function(e){return"title"in e[0]}(t)?r.createElement(We,{columns:t}):r.createElement(Qe,{links:t})}var Je=n(941);const et={footerLogoLink:"footerLogoLink_BH7S"};function tt(e){let{logo:t}=e;const{withBaseUrl:n}=(0,X.C)(),o={light:n(t.src),dark:n(t.srcDark??t.src)};return r.createElement(Je.Z,{className:(0,a.Z)("footer__logo",t.className),alt:t.alt,sources:o,width:t.width,height:t.height,style:t.style})}function nt(e){let{logo:t}=e;return t.href?r.createElement(Q.Z,{href:t.href,className:et.footerLogoLink,target:t.target},r.createElement(tt,{logo:t})):r.createElement(tt,{logo:t})}function rt(e){let{copyright:t}=e;return r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:t}})}function at(e){let{style:t,links:n,logo:o,copyright:i}=e;return r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===t})},r.createElement("div",{className:"container container-fluid"},n,(o||i)&&r.createElement("div",{className:"footer__bottom text--center"},o&&r.createElement("div",{className:"margin-bottom--sm"},o),i)))}function ot(){const{footer:e}=(0,w.L)();if(!e)return null;const{copyright:t,links:n,logo:a,style:o}=e;return r.createElement(at,{style:o,links:n&&n.length>0&&r.createElement(Xe,{links:n}),logo:a&&r.createElement(nt,{logo:a}),copyright:t&&r.createElement(rt,{copyright:t})})}const it=r.memo(ot),lt=(0,P.Qc)([B.S,k.pl,D.OC,ke.L5,i.VC,function(e){let{children:t}=e;return r.createElement(N.n2,null,r.createElement(L.M,null,r.createElement(O,null,t)))}]);function st(e){let{children:t}=e;return r.createElement(lt,null,t)}function ut(e){let{error:t,tryAgain:n}=e;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(u.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("div",{className:"margin-vert--lg"},r.createElement(Oe,{onClick:n,className:"button button--primary shadow--lw"})),r.createElement("hr",null),r.createElement("div",{className:"margin-vert--md"},r.createElement(Ie,{error:t})))))}const ct={mainWrapper:"mainWrapper_z2l0"};function dt(e){const{children:t,noFooter:n,wrapperClassName:l,title:s,description:u}=e;return(0,b.t)(),r.createElement(st,null,r.createElement(i.d,{title:s,description:u}),r.createElement(y,null),r.createElement(A,null),r.createElement(He,null),r.createElement("div",{id:d,className:(0,a.Z)(h.k.wrapper.main,ct.mainWrapper,l)},r.createElement(o.Z,{fallback:e=>r.createElement(ut,e)},t)),!n&&r.createElement(it,null))}},1327:(e,t,n)=>{"use strict";n.d(t,{Z:()=>d});var r=n(7462),a=n(7294),o=n(9960),i=n(4996),l=n(2263),s=n(6668),u=n(941);function c(e){let{logo:t,alt:n,imageClassName:r}=e;const o={light:(0,i.Z)(t.src),dark:(0,i.Z)(t.srcDark||t.src)},l=a.createElement(u.Z,{className:t.className,sources:o,height:t.height,width:t.width,alt:n,style:t.style});return r?a.createElement("div",{className:r},l):l}function d(e){const{siteConfig:{title:t}}=(0,l.Z)(),{navbar:{title:n,logo:u}}=(0,s.L)(),{imageClassName:d,titleClassName:f,...p}=e,m=(0,i.Z)(u?.href||"/"),g=n?"":t,h=u?.alt??g;return a.createElement(o.Z,(0,r.Z)({to:m},p,u?.target&&{target:u.target}),u&&a.createElement(c,{logo:u,alt:h,imageClassName:d}),null!=n&&a.createElement("b",{className:f},n))}},197:(e,t,n)=>{"use strict";n.d(t,{Z:()=>o});var r=n(7294),a=n(5742);function o(e){let{locale:t,version:n,tag:o}=e;const i=t;return r.createElement(a.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),o&&r.createElement("meta",{name:"docusaurus_tag",content:o}),i&&r.createElement("meta",{name:"docsearch:language",content:i}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),o&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:o}))}},941:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var r=n(7462),a=n(7294),o=n(6010),i=n(2389),l=n(2949);const s={themedImage:"themedImage_ToTc","themedImage--light":"themedImage--light_HNdA","themedImage--dark":"themedImage--dark_i4oU"};function u(e){const t=(0,i.Z)(),{colorMode:n}=(0,l.I)(),{sources:u,className:c,alt:d,...f}=e,p=t?"dark"===n?["dark"]:["light"]:["light","dark"];return a.createElement(a.Fragment,null,p.map((e=>a.createElement("img",(0,r.Z)({key:e,src:u[e],alt:d,className:(0,o.Z)(s.themedImage,s[`themedImage--${e}`],c)},f)))))}},6043:(e,t,n)=>{"use strict";n.d(t,{u:()=>s,z:()=>h});var r=n(7462),a=n(7294),o=n(412),i=n(1442);const l="ease-in-out";function s(e){let{initialState:t}=e;const[n,r]=(0,a.useState)(t??!1),o=(0,a.useCallback)((()=>{r((e=>!e))}),[]);return{collapsed:n,setCollapsed:r,toggleCollapsed:o}}const u={display:"none",overflow:"hidden",height:"0px"},c={display:"block",overflow:"visible",height:"auto"};function d(e,t){const n=t?u:c;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function f(e){let{collapsibleRef:t,collapsed:n,animation:r}=e;const o=(0,a.useRef)(!1);(0,a.useEffect)((()=>{const e=t.current;function a(){const t=e.scrollHeight,n=r?.duration??function(e){if((0,i.n)())return 1;const t=e/36;return Math.round(10*(4+15*t**.25+t/5))}(t);return{transition:`height ${n}ms ${r?.easing??l}`,height:`${t}px`}}function s(){const t=a();e.style.transition=t.transition,e.style.height=t.height}if(!o.current)return d(e,n),void(o.current=!0);return e.style.willChange="height",function(){const t=requestAnimationFrame((()=>{n?(s(),requestAnimationFrame((()=>{e.style.height=u.height,e.style.overflow=u.overflow}))):(e.style.display="block",requestAnimationFrame((()=>{s()})))}));return()=>cancelAnimationFrame(t)}()}),[t,n,r])}function p(e){if(!o.Z.canUseDOM)return e?u:c}function m(e){let{as:t="div",collapsed:n,children:r,animation:o,onCollapseTransitionEnd:i,className:l,disableSSRStyle:s}=e;const u=(0,a.useRef)(null);return f({collapsibleRef:u,collapsed:n,animation:o}),a.createElement(t,{ref:u,style:s?void 0:p(n),onTransitionEnd:e=>{"height"===e.propertyName&&(d(u.current,n),i?.(n))},className:l},r)}function g(e){let{collapsed:t,...n}=e;const[o,i]=(0,a.useState)(!t),[l,s]=(0,a.useState)(t);return(0,a.useLayoutEffect)((()=>{t||i(!0)}),[t]),(0,a.useLayoutEffect)((()=>{o&&s(t)}),[o,t]),o?a.createElement(m,(0,r.Z)({},n,{collapsed:l})):null}function h(e){let{lazy:t,...n}=e;const r=t?g:m;return a.createElement(r,n)}},9689:(e,t,n)=>{"use strict";n.d(t,{nT:()=>m,pl:()=>p});var r=n(7294),a=n(2389),o=n(12),i=n(902),l=n(6668);const s=(0,o.WA)("docusaurus.announcement.dismiss"),u=(0,o.WA)("docusaurus.announcement.id"),c=()=>"true"===s.get(),d=e=>s.set(String(e)),f=r.createContext(null);function p(e){let{children:t}=e;const n=function(){const{announcementBar:e}=(0,l.L)(),t=(0,a.Z)(),[n,o]=(0,r.useState)((()=>!!t&&c()));(0,r.useEffect)((()=>{o(c())}),[]);const i=(0,r.useCallback)((()=>{d(!0),o(!0)}),[]);return(0,r.useEffect)((()=>{if(!e)return;const{id:t}=e;let n=u.get();"annoucement-bar"===n&&(n="announcement-bar");const r=t!==n;u.set(t),r&&d(!1),!r&&c()||o(!1)}),[e]),(0,r.useMemo)((()=>({isActive:!!e&&!n,close:i})),[e,n,i])}();return r.createElement(f.Provider,{value:n},t)}function m(){const e=(0,r.useContext)(f);if(!e)throw new i.i6("AnnouncementBarProvider");return e}},2949:(e,t,n)=>{"use strict";n.d(t,{I:()=>h,S:()=>g});var r=n(7294),a=n(412),o=n(902),i=n(12),l=n(6668);const s=r.createContext(void 0),u="theme",c=(0,i.WA)(u),d={light:"light",dark:"dark"},f=e=>e===d.dark?d.dark:d.light,p=e=>a.Z.canUseDOM?f(document.documentElement.getAttribute("data-theme")):f(e),m=e=>{c.set(f(e))};function g(e){let{children:t}=e;const n=function(){const{colorMode:{defaultMode:e,disableSwitch:t,respectPrefersColorScheme:n}}=(0,l.L)(),[a,o]=(0,r.useState)(p(e));(0,r.useEffect)((()=>{t&&c.del()}),[t]);const i=(0,r.useCallback)((function(t,r){void 0===r&&(r={});const{persist:a=!0}=r;t?(o(t),a&&m(t)):(o(n?window.matchMedia("(prefers-color-scheme: dark)").matches?d.dark:d.light:e),c.del())}),[n,e]);(0,r.useEffect)((()=>{document.documentElement.setAttribute("data-theme",f(a))}),[a]),(0,r.useEffect)((()=>{if(t)return;const e=e=>{if(e.key!==u)return;const t=c.get();null!==t&&i(f(t))};return window.addEventListener("storage",e),()=>window.removeEventListener("storage",e)}),[t,i]);const s=(0,r.useRef)(!1);return(0,r.useEffect)((()=>{if(t&&!n)return;const e=window.matchMedia("(prefers-color-scheme: dark)"),r=()=>{window.matchMedia("print").matches||s.current?s.current=window.matchMedia("print").matches:i(null)};return e.addListener(r),()=>e.removeListener(r)}),[i,t,n]),(0,r.useMemo)((()=>({colorMode:a,setColorMode:i,get isDarkTheme(){return a===d.dark},setLightTheme(){i(d.light)},setDarkTheme(){i(d.dark)}})),[a,i])}();return r.createElement(s.Provider,{value:n},t)}function h(){const e=(0,r.useContext)(s);if(null==e)throw new o.i6("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}},373:(e,t,n)=>{"use strict";n.d(t,{J:()=>v,L5:()=>h});var r=n(7294),a=n(143),o=n(9935),i=n(6668),l=n(2802),s=n(902),u=n(12);const c=e=>`docs-preferred-version-${e}`,d={save:(e,t,n)=>{(0,u.WA)(c(e),{persistence:t}).set(n)},read:(e,t)=>(0,u.WA)(c(e),{persistence:t}).get(),clear:(e,t)=>{(0,u.WA)(c(e),{persistence:t}).del()}},f=e=>Object.fromEntries(e.map((e=>[e,{preferredVersionName:null}])));const p=r.createContext(null);function m(){const e=(0,a._r)(),t=(0,i.L)().docs.versionPersistence,n=(0,r.useMemo)((()=>Object.keys(e)),[e]),[o,l]=(0,r.useState)((()=>f(n)));(0,r.useEffect)((()=>{l(function(e){let{pluginIds:t,versionPersistence:n,allDocsData:r}=e;function a(e){const t=d.read(e,n);return r[e].versions.some((e=>e.name===t))?{preferredVersionName:t}:(d.clear(e,n),{preferredVersionName:null})}return Object.fromEntries(t.map((e=>[e,a(e)])))}({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]);return[o,(0,r.useMemo)((()=>({savePreferredVersion:function(e,n){d.save(e,t,n),l((t=>({...t,[e]:{preferredVersionName:n}})))}})),[t])]}function g(e){let{children:t}=e;const n=m();return r.createElement(p.Provider,{value:n},t)}function h(e){let{children:t}=e;return l.cE?r.createElement(g,null,t):r.createElement(r.Fragment,null,t)}function b(){const e=(0,r.useContext)(p);if(!e)throw new s.i6("DocsPreferredVersionContextProvider");return e}function v(e){void 0===e&&(e=o.m);const t=(0,a.zh)(e),[n,i]=b(),{preferredVersionName:l}=n[e];return{preferredVersion:t.versions.find((e=>e.name===l))??null,savePreferredVersionName:(0,r.useCallback)((t=>{i.savePreferredVersion(e,t)}),[i,e])}}},1116:(e,t,n)=>{"use strict";n.d(t,{V:()=>s,b:()=>l});var r=n(7294),a=n(902);const o=Symbol("EmptyContext"),i=r.createContext(o);function l(e){let{children:t,name:n,items:a}=e;const o=(0,r.useMemo)((()=>n&&a?{name:n,items:a}:null),[n,a]);return r.createElement(i.Provider,{value:o},t)}function s(){const e=(0,r.useContext)(i);if(e===o)throw new a.i6("DocsSidebarProvider");return e}},2961:(e,t,n)=>{"use strict";n.d(t,{M:()=>f,e:()=>p});var r=n(7294),a=n(3102),o=n(7524),i=n(6550),l=(n(1688),n(902));function s(e){!function(e){const t=(0,i.k6)(),n=(0,l.zX)(e);(0,r.useEffect)((()=>t.block(((e,t)=>n(e,t)))),[t,n])}(((t,n)=>{if("POP"===n)return e(t,n)}))}var u=n(6668);const c=r.createContext(void 0);function d(){const e=function(){const e=(0,a.HY)(),{items:t}=(0,u.L)().navbar;return 0===t.length&&!e.component}(),t=(0,o.i)(),n=!e&&"mobile"===t,[i,l]=(0,r.useState)(!1);s((()=>{if(i)return l(!1),!1}));const c=(0,r.useCallback)((()=>{l((e=>!e))}),[]);return(0,r.useEffect)((()=>{"desktop"===t&&l(!1)}),[t]),(0,r.useMemo)((()=>({disabled:e,shouldRender:n,toggle:c,shown:i})),[e,n,c,i])}function f(e){let{children:t}=e;const n=d();return r.createElement(c.Provider,{value:n},t)}function p(){const e=r.useContext(c);if(void 0===e)throw new l.i6("NavbarMobileSidebarProvider");return e}},3102:(e,t,n)=>{"use strict";n.d(t,{HY:()=>l,Zo:()=>s,n2:()=>i});var r=n(7294),a=n(902);const o=r.createContext(null);function i(e){let{children:t}=e;const n=(0,r.useState)({component:null,props:null});return r.createElement(o.Provider,{value:n},t)}function l(){const e=(0,r.useContext)(o);if(!e)throw new a.i6("NavbarSecondaryMenuContentProvider");return e[0]}function s(e){let{component:t,props:n}=e;const i=(0,r.useContext)(o);if(!i)throw new a.i6("NavbarSecondaryMenuContentProvider");const[,l]=i,s=(0,a.Ql)(n);return(0,r.useEffect)((()=>{l({component:t,props:s})}),[l,t,s]),(0,r.useEffect)((()=>()=>l({component:null,props:null})),[l]),null}},9727:(e,t,n)=>{"use strict";n.d(t,{h:()=>a,t:()=>o});var r=n(7294);const a="navigation-with-keyboard";function o(){(0,r.useEffect)((()=>{function e(e){"keydown"===e.type&&"Tab"===e.key&&document.body.classList.add(a),"mousedown"===e.type&&document.body.classList.remove(a)}return document.addEventListener("keydown",e),document.addEventListener("mousedown",e),()=>{document.body.classList.remove(a),document.removeEventListener("keydown",e),document.removeEventListener("mousedown",e)}}),[])}},7524:(e,t,n)=>{"use strict";n.d(t,{i:()=>u});var r=n(7294),a=n(412);const o={desktop:"desktop",mobile:"mobile",ssr:"ssr"},i=996;function l(){return a.Z.canUseDOM?window.innerWidth>i?o.desktop:o.mobile:o.ssr}const s=!1;function u(){const[e,t]=(0,r.useState)((()=>s?"ssr":l()));return(0,r.useEffect)((()=>{function e(){t(l())}const n=s?window.setTimeout(e,1e3):void 0;return window.addEventListener("resize",e),()=>{window.removeEventListener("resize",e),clearTimeout(n)}}),[]),e}},5281:(e,t,n)=>{"use strict";n.d(t,{k:()=>r});const r={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block",admonition:"theme-admonition",admonitionType:e=>`theme-admonition-${e}`},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:e=>`theme-doc-sidebar-item-category-level-${e}`,docSidebarItemLinkLevel:e=>`theme-doc-sidebar-item-link-level-${e}`},blog:{}}},1442:(e,t,n)=>{"use strict";function r(){return window.matchMedia("(prefers-reduced-motion: reduce)").matches}n.d(t,{n:()=>r})},2802:(e,t,n)=>{"use strict";n.d(t,{Wl:()=>f,_F:()=>g,cE:()=>d,hI:()=>k,lO:()=>v,vY:()=>w,oz:()=>y,s1:()=>b});var r=n(7294),a=n(6550),o=n(8790),i=n(143),l=n(373),s=n(1116);function u(e){return Array.from(new Set(e))}var c=n(8596);const d=!!i._r;function f(e){if(e.href)return e.href;for(const t of e.items){if("link"===t.type)return t.href;if("category"===t.type){const e=f(t);if(e)return e}}}const p=(e,t)=>void 0!==e&&(0,c.Mg)(e,t),m=(e,t)=>e.some((e=>g(e,t)));function g(e,t){return"link"===e.type?p(e.href,t):"category"===e.type&&(p(e.href,t)||m(e.items,t))}function h(e){let{sidebarItems:t,pathname:n,onlyCategories:r=!1}=e;const a=[];return function e(t){for(const o of t)if("category"===o.type&&((0,c.Mg)(o.href,n)||e(o.items))||"link"===o.type&&(0,c.Mg)(o.href,n)){return r&&"category"!==o.type||a.unshift(o),!0}return!1}(t),a}function b(){const e=(0,s.V)(),{pathname:t}=(0,a.TH)(),n=(0,i.gA)()?.pluginData.breadcrumbs;return!1!==n&&e?h({sidebarItems:e.items,pathname:t}):null}function v(e){const{activeVersion:t}=(0,i.Iw)(e),{preferredVersion:n}=(0,l.J)(e),a=(0,i.yW)(e);return(0,r.useMemo)((()=>u([t,n,a].filter(Boolean))),[t,n,a])}function y(e,t){const n=v(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.sidebars?Object.entries(e.sidebars):[])),r=t.find((t=>t[0]===e));if(!r)throw new Error(`Can't find any sidebar with id "${e}" in version${n.length>1?"s":""} ${n.map((e=>e.name)).join(", ")}".\nAvailable sidebar ids are:\n- ${t.map((e=>e[0])).join("\n- ")}`);return r[1]}),[e,n])}function w(e,t){const n=v(t);return(0,r.useMemo)((()=>{const t=n.flatMap((e=>e.docs)),r=t.find((t=>t.id===e));if(!r){if(n.flatMap((e=>e.draftIds)).includes(e))return null;throw new Error(`Couldn't find any doc with id "${e}" in version${n.length>1?"s":""} "${n.map((e=>e.name)).join(", ")}".\nAvailable doc ids are:\n- ${u(t.map((e=>e.id))).join("\n- ")}`)}return r}),[e,n])}function k(e){let{route:t,versionMetadata:n}=e;const r=(0,a.TH)(),i=t.routes,l=i.find((e=>(0,a.LX)(r.pathname,e)));if(!l)return null;const s=l.sidebar,u=s?n.docsSidebars[s]:void 0;return{docElement:(0,o.H)(i),sidebarName:s,sidebarItems:u}}},1944:(e,t,n)=>{"use strict";n.d(t,{FG:()=>f,d:()=>c,VC:()=>p});var r=n(7294),a=n(6010),o=n(5742),i=n(226);function l(){const e=r.useContext(i._);if(!e)throw new Error("Unexpected: no Docusaurus route context found");return e}var s=n(4996),u=n(2263);function c(e){let{title:t,description:n,keywords:a,image:i,children:l}=e;const c=function(e){const{siteConfig:t}=(0,u.Z)(),{title:n,titleDelimiter:r}=t;return e?.trim().length?`${e.trim()} ${r} ${n}`:n}(t),{withBaseUrl:d}=(0,s.C)(),f=i?d(i,{absolute:!0}):void 0;return r.createElement(o.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),a&&r.createElement("meta",{name:"keywords",content:Array.isArray(a)?a.join(","):a}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),l)}const d=r.createContext(void 0);function f(e){let{className:t,children:n}=e;const i=r.useContext(d),l=(0,a.Z)(i,t);return r.createElement(d.Provider,{value:l},r.createElement(o.Z,null,r.createElement("html",{className:l})),n)}function p(e){let{children:t}=e;const n=l(),o=`plugin-${n.plugin.name.replace(/docusaurus-(?:plugin|theme)-(?:content-)?/gi,"")}`;const i=`plugin-id-${n.plugin.id}`;return r.createElement(f,{className:(0,a.Z)(o,i)},t)}},902:(e,t,n)=>{"use strict";n.d(t,{D9:()=>i,Qc:()=>u,Ql:()=>s,i6:()=>l,zX:()=>o});var r=n(7294);const a=n(412).Z.canUseDOM?r.useLayoutEffect:r.useEffect;function o(e){const t=(0,r.useRef)(e);return a((()=>{t.current=e}),[e]),(0,r.useCallback)((function(){return t.current(...arguments)}),[])}function i(e){const t=(0,r.useRef)();return a((()=>{t.current=e})),t.current}class l extends Error{constructor(e,t){super(),this.name="ReactContextError",this.message=`Hook ${this.stack?.split("\n")[1]?.match(/at (?:\w+\.)?(?\w+)/)?.groups.name??""} is called outside the <${e}>. ${t??""}`}}function s(e){const t=Object.entries(e);return t.sort(((e,t)=>e[0].localeCompare(t[0]))),(0,r.useMemo)((()=>e),t.flat())}function u(e){return t=>{let{children:n}=t;return r.createElement(r.Fragment,null,e.reduceRight(((e,t)=>r.createElement(t,null,e)),n))}}},8596:(e,t,n)=>{"use strict";n.d(t,{Mg:()=>i,Ns:()=>l});var r=n(7294),a=n(723),o=n(2263);function i(e,t){const n=e=>(!e||e.endsWith("/")?e:`${e}/`)?.toLowerCase();return n(e)===n(t)}function l(){const{baseUrl:e}=(0,o.Z)().siteConfig;return(0,r.useMemo)((()=>function(e){let{baseUrl:t,routes:n}=e;function r(e){return e.path===t&&!0===e.exact}function a(e){return e.path===t&&!e.exact}return function e(t){if(0===t.length)return;return t.find(r)||e(t.filter(a).flatMap((e=>e.routes??[])))}(n)}({routes:a.Z,baseUrl:e})),[e])}},2466:(e,t,n)=>{"use strict";n.d(t,{Ct:()=>f,OC:()=>s,RF:()=>d});var r=n(7294),a=n(412),o=n(2389),i=n(902);const l=r.createContext(void 0);function s(e){let{children:t}=e;const n=function(){const e=(0,r.useRef)(!0);return(0,r.useMemo)((()=>({scrollEventsEnabledRef:e,enableScrollEvents:()=>{e.current=!0},disableScrollEvents:()=>{e.current=!1}})),[])}();return r.createElement(l.Provider,{value:n},t)}function u(){const e=(0,r.useContext)(l);if(null==e)throw new i.i6("ScrollControllerProvider");return e}const c=()=>a.Z.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null;function d(e,t){void 0===t&&(t=[]);const{scrollEventsEnabledRef:n}=u(),a=(0,r.useRef)(c()),o=(0,i.zX)(e);(0,r.useEffect)((()=>{const e=()=>{if(!n.current)return;const e=c();o(e,a.current),a.current=e},t={passive:!0};return e(),window.addEventListener("scroll",e,t),()=>window.removeEventListener("scroll",e,t)}),[o,n,...t])}function f(){const e=(0,r.useRef)(null),t=(0,o.Z)()&&"smooth"===getComputedStyle(document.documentElement).scrollBehavior;return{startScroll:n=>{e.current=t?function(e){return window.scrollTo({top:e,behavior:"smooth"}),()=>{}}(n):function(e){let t=null;const n=document.documentElement.scrollTop>e;return function r(){const a=document.documentElement.scrollTop;(n&&a>e||!n&&at&&cancelAnimationFrame(t)}(n)},cancelScroll:()=>e.current?.()}}},3320:(e,t,n)=>{"use strict";n.d(t,{HX:()=>r,os:()=>a});n(2263);const r="default";function a(e,t){return`docs-${e}-${t}`}},12:(e,t,n)=>{"use strict";n.d(t,{WA:()=>s});n(7294),n(1688);const r="localStorage";function a(e){let{key:t,oldValue:n,newValue:r,storage:a}=e;if(n===r)return;const o=document.createEvent("StorageEvent");o.initStorageEvent("storage",!1,!1,t,n,r,window.location.href,a),window.dispatchEvent(o)}function o(e){if(void 0===e&&(e=r),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,i||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),i=!0),null}var t}let i=!1;const l={get:()=>null,set:()=>{},del:()=>{},listen:()=>()=>{}};function s(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error(`Illegal storage API usage for storage key "${e}".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.`)}return{get:t,set:t,del:t,listen:t}}(e);const n=o(t?.persistence);return null===n?l:{get:()=>{try{return n.getItem(e)}catch(t){return console.error(`Docusaurus storage error, can't get key=${e}`,t),null}},set:t=>{try{const r=n.getItem(e);n.setItem(e,t),a({key:e,oldValue:r,newValue:t,storage:n})}catch(r){console.error(`Docusaurus storage error, can't set ${e}=${t}`,r)}},del:()=>{try{const t=n.getItem(e);n.removeItem(e),a({key:e,oldValue:t,newValue:null,storage:n})}catch(t){console.error(`Docusaurus storage error, can't delete key=${e}`,t)}},listen:t=>{try{const r=r=>{r.storageArea===n&&r.key===e&&t(r)};return window.addEventListener("storage",r),()=>window.removeEventListener("storage",r)}catch(r){return console.error(`Docusaurus storage error, can't listen for changes of key=${e}`,r),()=>{}}}}}},4711:(e,t,n)=>{"use strict";n.d(t,{l:()=>o});var r=n(2263),a=n(6550);function o(){const{siteConfig:{baseUrl:e,url:t},i18n:{defaultLocale:n,currentLocale:o}}=(0,r.Z)(),{pathname:i}=(0,a.TH)(),l=o===n?e:e.replace(`/${o}/`,"/"),s=i.replace(e,"");return{createUrl:function(e){let{locale:r,fullyQualified:a}=e;return`${a?t:""}${function(e){return e===n?`${l}`:`${l}${e}/`}(r)}${s}`}}}},5936:(e,t,n)=>{"use strict";n.d(t,{S:()=>i});var r=n(7294),a=n(6550),o=n(902);function i(e){const t=(0,a.TH)(),n=(0,o.D9)(t),i=(0,o.zX)(e);(0,r.useEffect)((()=>{n&&t!==n&&i({location:t,previousLocation:n})}),[i,t,n])}},6668:(e,t,n)=>{"use strict";n.d(t,{L:()=>a});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}},8802:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){const{trailingSlash:n,baseUrl:r}=t;if(e.startsWith("#"))return e;if(void 0===n)return e;const[a]=e.split(/[#?]/),o="/"===a||a===r?a:(i=a,n?function(e){return e.endsWith("/")?e:`${e}/`}(i):function(e){return e.endsWith("/")?e.slice(0,-1):e}(i));var i;return e.replace(a,o)}},4143:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=void 0,t.getErrorCausalChain=function e(t){return t.cause?[t,...e(t.cause)]:[t]}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.getErrorCausalChain=t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="__blog-post-container";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}});var o=n(4143);Object.defineProperty(t,"getErrorCausalChain",{enumerable:!0,get:function(){return o.getErrorCausalChain}})},6010:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;ta});const a=function(){for(var e,t,n=0,a="";n{"use strict";n.d(t,{lX:()=>w,q_:()=>C,ob:()=>p,PP:()=>A,Ep:()=>f});var r=n(7462);function a(e){return"/"===e.charAt(0)}function o(e,t){for(var n=t,r=n+1,a=e.length;r=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};var l=n(8776);function s(e){return"/"===e.charAt(0)?e:"/"+e}function u(e){return"/"===e.charAt(0)?e.substr(1):e}function c(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function d(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function f(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function p(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function m(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=p(e,t,g(),w.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(w.entries[w.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t{"use strict";var r=n(9864),a={childContextTypes:!0,contextType:!0,contextTypes:!0,defaultProps:!0,displayName:!0,getDefaultProps:!0,getDerivedStateFromError:!0,getDerivedStateFromProps:!0,mixins:!0,propTypes:!0,type:!0},o={name:!0,length:!0,prototype:!0,caller:!0,callee:!0,arguments:!0,arity:!0},i={$$typeof:!0,compare:!0,defaultProps:!0,displayName:!0,propTypes:!0,type:!0},l={};function s(e){return r.isMemo(e)?i:l[e.$$typeof]||a}l[r.ForwardRef]={$$typeof:!0,render:!0,defaultProps:!0,displayName:!0,propTypes:!0},l[r.Memo]=i;var u=Object.defineProperty,c=Object.getOwnPropertyNames,d=Object.getOwnPropertySymbols,f=Object.getOwnPropertyDescriptor,p=Object.getPrototypeOf,m=Object.prototype;e.exports=function e(t,n,r){if("string"!=typeof n){if(m){var a=p(n);a&&a!==m&&e(t,a,r)}var i=c(n);d&&(i=i.concat(d(n)));for(var l=s(t),g=s(n),h=0;h{"use strict";e.exports=function(e,t,n,r,a,o,i,l){if(!e){var s;if(void 0===t)s=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var u=[n,r,a,o,i,l],c=0;(s=new Error(t.replace(/%s/g,(function(){return u[c++]})))).name="Invariant Violation"}throw s.framesToPop=1,s}}},5826:e=>{e.exports=Array.isArray||function(e){return"[object Array]"==Object.prototype.toString.call(e)}},2497:(e,t,n)=>{"use strict";n.r(t)},2295:(e,t,n)=>{"use strict";n.r(t)},4865:function(e,t,n){var r,a;r=function(){var e,t,n={version:"0.2.0"},r=n.settings={minimum:.08,easing:"ease",positionUsing:"",speed:200,trickle:!0,trickleRate:.02,trickleSpeed:800,showSpinner:!0,barSelector:'[role="bar"]',spinnerSelector:'[role="spinner"]',parent:"body",template:'
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),u=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,i(e,c,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),u=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:e=>{"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,a){for(var o,i,l=function(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}(e),s=1;s{var r=n(5826);e.exports=p,e.exports.parse=o,e.exports.compile=function(e,t){return l(o(e,t),t)},e.exports.tokensToFunction=l,e.exports.tokensToRegExp=f;var a=new RegExp(["(\\\\.)","([\\/.])?(?:(?:\\:(\\w+)(?:\\(((?:\\\\.|[^\\\\()])+)\\))?|\\(((?:\\\\.|[^\\\\()])+)\\))([+*?])?|(\\*))"].join("|"),"g");function o(e,t){for(var n,r=[],o=0,i=0,l="",c=t&&t.delimiter||"/";null!=(n=a.exec(e));){var d=n[0],f=n[1],p=n.index;if(l+=e.slice(i,p),i=p+d.length,f)l+=f[1];else{var m=e[i],g=n[2],h=n[3],b=n[4],v=n[5],y=n[6],w=n[7];l&&(r.push(l),l="");var k=null!=g&&null!=m&&m!==g,E="+"===y||"*"===y,S="?"===y||"*"===y,x=n[2]||c,_=b||v;r.push({name:h||o++,prefix:g||"",delimiter:x,optional:S,repeat:E,partial:k,asterisk:!!w,pattern:_?u(_):w?".*":"[^"+s(x)+"]+?"})}}return i{"use strict";n.d(t,{Z:()=>o});var r=function(){var e=/(?:^|\s)lang(?:uage)?-([\w-]+)(?=\s|$)/i,t=0,n={},r={util:{encode:function e(t){return t instanceof a?new a(t.type,e(t.content),t.alias):Array.isArray(t)?t.map(e):t.replace(/&/g,"&").replace(/=d.reach);S+=E.value.length,E=E.next){var x=E.value;if(t.length>e.length)return;if(!(x instanceof a)){var _,C=1;if(v){if(!(_=o(k,S,e,b))||_.index>=e.length)break;var T=_.index,A=_.index+_[0].length,L=S;for(L+=E.value.length;T>=L;)L+=(E=E.next).value.length;if(S=L-=E.value.length,E.value instanceof a)continue;for(var D=E;D!==t.tail&&(Ld.reach&&(d.reach=O);var I=E.prev;if(N&&(I=s(t,I,N),S+=N.length),u(t,I,C),E=s(t,I,new a(f,h?r.tokenize(P,h):P,y,P)),R&&s(t,E,R),C>1){var M={cause:f+","+m,reach:O};i(e,t,n,E.prev,S,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function u(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=/#(?!\{).+/,n={pattern:/#\{[^}]+\}/,alias:"variable"};e.languages.coffeescript=e.languages.extend("javascript",{comment:t,string:[{pattern:/'(?:\\[\s\S]|[^\\'])*'/,greedy:!0},{pattern:/"(?:\\[\s\S]|[^\\"])*"/,greedy:!0,inside:{interpolation:n}}],keyword:/\b(?:and|break|by|catch|class|continue|debugger|delete|do|each|else|extend|extends|false|finally|for|if|in|instanceof|is|isnt|let|loop|namespace|new|no|not|null|of|off|on|or|own|return|super|switch|then|this|throw|true|try|typeof|undefined|unless|until|when|while|window|with|yes|yield)\b/,"class-member":{pattern:/@(?!\d)\w+/,alias:"variable"}}),e.languages.insertBefore("coffeescript","comment",{"multiline-comment":{pattern:/###[\s\S]+?###/,alias:"comment"},"block-regex":{pattern:/\/{3}[\s\S]*?\/{3}/,alias:"regex",inside:{comment:t,interpolation:n}}}),e.languages.insertBefore("coffeescript","string",{"inline-javascript":{pattern:/`(?:\\[\s\S]|[^\\`])*`/,inside:{delimiter:{pattern:/^`|`$/,alias:"punctuation"},script:{pattern:/[\s\S]+/,alias:"language-javascript",inside:e.languages.javascript}}},"multiline-string":[{pattern:/'''[\s\S]*?'''/,greedy:!0,alias:"string"},{pattern:/"""[\s\S]*?"""/,greedy:!0,alias:"string",inside:{interpolation:n}}]}),e.languages.insertBefore("coffeescript","keyword",{property:/(?!\d)\w+(?=\s*:(?!:))/}),delete e.languages.coffeescript["template-string"],e.languages.coffee=e.languages.coffeescript}(a),function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=f(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s=0&&p(u,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t=e.languages.javascript["template-string"],n=t.pattern.source,r=t.inside.interpolation,a=r.inside["interpolation-punctuation"],o=r.pattern.source;function i(t,r){if(e.languages[t])return{pattern:RegExp("((?:"+r+")\\s*)"+n),lookbehind:!0,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},"embedded-code":{pattern:/[\s\S]+/,alias:t}}}}function l(e,t){return"___"+t.toUpperCase()+"_"+e+"___"}function s(t,n,r){var a={code:t,grammar:n,language:r};return e.hooks.run("before-tokenize",a),a.tokens=e.tokenize(a.code,a.grammar),e.hooks.run("after-tokenize",a),a.tokens}function u(t){var n={};n["interpolation-punctuation"]=a;var o=e.tokenize(t,n);if(3===o.length){var i=[1,1];i.push.apply(i,s(o[1],e.languages.javascript,"javascript")),o.splice.apply(o,i)}return new e.Token("interpolation",o,r.alias,t)}function c(t,n,r){var a=e.tokenize(t,{interpolation:{pattern:RegExp(o),lookbehind:!0}}),i=0,c={},d=s(a.map((function(e){if("string"==typeof e)return e;for(var n,a=e.content;-1!==t.indexOf(n=l(i++,r)););return c[n]=a,n})).join(""),n,r),f=Object.keys(c);return i=0,function e(t){for(var n=0;n=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=f[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=u(c[a]),p=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),p){var g=[p];e(g),m.push.apply(m,g)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var h=r.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function f(e){return"string"==typeof e?e:Array.isArray(e)?e.map(f).join(""):f(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){e.languages.diff={coord:[/^(?:\*{3}|-{3}|\+{3}).*$/m,/^@@.*@@$/m,/^\d.*$/m]};var t={"deleted-sign":"-","deleted-arrow":"<","inserted-sign":"+","inserted-arrow":">",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,l=i.length;-1!==n.code.indexOf(a=t(r,l));)++l;return i[l]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(l){for(var s=0;s=o.length);s++){var u=l[s];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=o[a],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),m=f.indexOf(p);if(m>-1){++a;var g=f.substring(0,m),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=f.substring(m+p.length),v=[];g&&v.push.apply(v,i([g])),v.push(h),b&&v.push.apply(v,i([b])),"string"==typeof u?l.splice.apply(l,[s,1].concat(v)):u.content=v}}else u.content&&i(u.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/};const o=a},9901:e=>{e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},armasm:{title:"ARM Assembly",alias:"arm-asm",owner:"RunDevelopment"},arturo:{title:"Arturo",alias:"art",optional:["bash","css","javascript","markup","markdown","sql"],owner:"drkameleon"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},awk:{title:"AWK",alias:"gawk",aliasTitles:{gawk:"GAWK"},owner:"RunDevelopment"},bash:{title:"Bash",alias:["sh","shell"],aliasTitles:{sh:"Shell",shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bbj:{title:"BBj",owner:"hyyan"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},bqn:{title:"BQN",owner:"yewscion"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},cilkc:{title:"Cilk/C",require:"c",alias:"cilk-c",owner:"OpenCilk"},cilkcpp:{title:"Cilk/C++",require:"cpp",alias:["cilk-cpp","cilk"],owner:"OpenCilk"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},cooklang:{title:"Cooklang",owner:"ahue"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cue:{title:"CUE",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gettext:{title:"gettext",alias:"po",owner:"RunDevelopment"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},"linker-script":{title:"GNU Linker Script",alias:"ld",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},gradle:{title:"Gradle",require:"clike",owner:"zeabdelkhalek-badido18"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:["hbs","mustache"],aliasTitles:{mustache:"Mustache"},owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},mata:{title:"Mata",owner:"RunDevelopment"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},metafont:{title:"METAFONT",owner:"LaeriExNihilo"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},odin:{title:"Odin",owner:"edukisto"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},"plant-uml":{title:"PlantUML",alias:"plantuml",owner:"RunDevelopment"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rescript:{title:"ReScript",alias:"res",owner:"vmarcosp"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (SCSS)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},stata:{title:"Stata Ado",require:["mata","java","python"],owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},supercollider:{title:"SuperCollider",alias:"sclang",owner:"RunDevelopment"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wgsl:{title:"WGSL",owner:"Dr4gonthree"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:(e,t,n)=>{var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:e=>{"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function u(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,u),t(s.optional,u),t(s.modify,u)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),u=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(u),l=(l||[]).map(u);var c=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var f,p=r(s),m=c;a(m);){for(var g in f={},m){var h=s[g];t(h&&h.modify,(function(e){e in d&&(f[e]=!0)}))}for(var b in d)if(!(b in c))for(var v in p(b))if(v in c){f[b]=!0;break}for(var y in m=f)c[y]=!0}var w={getIds:function(){var e=[];return w.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function u(e){if(e in l)return l[e];s[e]=!0;var a,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)a=r(e);else{var f=i(c.map((function(e){var t=u(e);return delete s[e],t})));o?a=o(f,(function(){return r(e)})):r(e)}return l[e]=a}for(var c in n)u(c);var d=[];for(var f in s)d.push(l[f]);return i(d)}(p,c,t,n)}};return w}}();e.exports=t},2703:(e,t,n)=>{"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:(e,t,n)=>{e.exports=n(2703)()},414:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:(e,t,n)=>{"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n