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.
diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/404.html b/404.html new file mode 100644 index 000000000000..04cd997203d4 --- /dev/null +++ b/404.html @@ -0,0 +1,16 @@ + + +
+ + +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.
Count: {state.count}
\n \nCount: {state.count}
\n \n["'])(?.*?)\1/,g=/\{(? [\d,-]+)\}/,y={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},bash:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}};function v(e,t){const n=e.map((e=>{const{start:n,end:o}=y[e];return`(?:${n}\\s*(${t.flatMap((e=>[e.line,e.block?.start,e.block?.end].filter(Boolean))).join("|")})\\s*${o})`})).join("|");return new RegExp(`^\\s*(?:${n})\\s*$`)}function b(e,t){let n=e.replace(/\n$/,"");const{language:o,magicComments:r,metastring:a}=t;if(a&&g.test(a)){const e=a.match(g).groups.range;if(0===r.length)throw new Error(`A highlight range has been given in code block's metastring (\`\`\` ${a}), but no magic comment config is available. Docusaurus applies the first magic comment entry's className for metastring ranges.`);const t=r[0].className,o=f()(e).filter((e=>e>0)).map((e=>[e-1,[t]]));return{lineClassNames:Object.fromEntries(o),code:n}}if(void 0===o)return{lineClassNames:{},code:n};const c=function(e,t){switch(e){case"js":case"javascript":case"ts":case"typescript":return v(["js","jsBlock"],t);case"jsx":case"tsx":return v(["js","jsBlock","jsx"],t);case"html":return v(["js","jsBlock","html"],t);case"python":case"py":case"bash":return v(["bash"],t);case"markdown":case"md":return v(["html","jsx","bash"],t);default:return v(Object.keys(y),t)}}(o,r),l=n.split("\n"),i=Object.fromEntries(r.map((e=>[e.className,{start:0,range:""}]))),s=Object.fromEntries(r.filter((e=>e.line)).map((e=>{let{className:t,line:n}=e;return[n,t]}))),u=Object.fromEntries(r.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.start,t]}))),m=Object.fromEntries(r.filter((e=>e.block)).map((e=>{let{className:t,block:n}=e;return[n.end,t]})));for(let p=0;p void 0!==e));s[t]?i[s[t]].range+=`${p},`:u[t]?i[u[t]].start=p:m[t]&&(i[m[t]].range+=`${i[m[t]].start}-${p-1},`),l.splice(p,1)}n=l.join("\n");const d={};return Object.entries(i).forEach((e=>{let[t,{range:n}]=e;f()(n).forEach((e=>{d[e]??=[],d[e].push(t)}))})),{lineClassNames:d,code:n}}const E={codeBlockContainer:"codeBlockContainer_Ckt0"};function k(e){let{as:t,...n}=e;const r=function(e){const t={color:"--prism-color",backgroundColor:"--prism-background-color"},n={};return Object.entries(e.plain).forEach((e=>{let[o,r]=e;const a=t[o];a&&"string"==typeof r&&(n[a]=r)})),n}(m());return o.createElement(t,(0,a.Z)({},n,{style:r,className:(0,i.Z)(n.className,E.codeBlockContainer,d.k.common.codeBlock)}))}const N={codeBlockContent:"codeBlockContent_biex",codeBlockTitle:"codeBlockTitle_Ktv7",codeBlock:"codeBlock_bY9V",codeBlockStandalone:"codeBlockStandalone_MEMb",codeBlockLines:"codeBlockLines_e6Vv",codeBlockLinesWithNumbering:"codeBlockLinesWithNumbering_o6Pm",buttonGroup:"buttonGroup__atx"};function C(e){let{children:t,className:n}=e;return o.createElement(k,{as:"pre",tabIndex:0,className:(0,i.Z)(N.codeBlockStandalone,"thin-scrollbar",n)},o.createElement("code",{className:N.codeBlockLines},t))}var L=n(902);const w={attributes:!0,characterData:!0,childList:!0,subtree:!0};function B(e,t){const[n,r]=(0,o.useState)(),a=(0,o.useCallback)((()=>{r(e.current?.closest("[role=tabpanel][hidden]"))}),[e,r]);(0,o.useEffect)((()=>{a()}),[a]),function(e,t,n){void 0===n&&(n=w);const r=(0,L.zX)(t),a=(0,L.Ql)(n);(0,o.useEffect)((()=>{const t=new MutationObserver(r);return e&&t.observe(e,a),()=>t.disconnect()}),[e,r,a])}(n,(e=>{e.forEach((e=>{"attributes"===e.type&&"hidden"===e.attributeName&&(t(),a())}))}),{attributes:!0,characterData:!1,childList:!1,subtree:!1})}const x={plain:{backgroundColor:"#2a2734",color:"#9a86fd"},styles:[{types:["comment","prolog","doctype","cdata","punctuation"],style:{color:"#6c6783"}},{types:["namespace"],style:{opacity:.7}},{types:["tag","operator","number"],style:{color:"#e09142"}},{types:["property","function"],style:{color:"#9a86fd"}},{types:["tag-id","selector","atrule-id"],style:{color:"#eeebff"}},{types:["attr-name"],style:{color:"#c4b9fe"}},{types:["boolean","string","entity","url","attr-value","keyword","control","directive","unit","statement","regex","atrule","placeholder","variable"],style:{color:"#ffcc99"}},{types:["deleted"],style:{textDecorationLine:"line-through"}},{types:["inserted"],style:{textDecorationLine:"underline"}},{types:["italic"],style:{fontStyle:"italic"}},{types:["important","bold"],style:{fontWeight:"bold"}},{types:["important"],style:{color:"#c4b9fe"}}]};var T={Prism:n(7410).Z,theme:x};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 Z(){return Z=Object.assign||function(e){for(var t=1;t 0&&e[n-1]===t?e:e.concat(t)};function S(e,t){var n={};for(var o in e)Object.prototype.hasOwnProperty.call(e,o)&&-1===t.indexOf(o)&&(n[o]=e[o]);return n}var A=function(e){function t(){for(var t=this,n=[],o=arguments.length;o--;)n[o]=arguments[o];e.apply(this,n),O(this,"getThemeDict",(function(e){if(void 0!==t.themeDict&&e.theme===t.prevTheme&&e.language===t.prevLanguage)return t.themeDict;t.prevTheme=e.theme,t.prevLanguage=e.language;var n=e.theme?function(e,t){var n=e.plain,o=Object.create(null),r=e.styles.reduce((function(e,n){var o=n.languages,r=n.style;return o&&!o.includes(t)||n.types.forEach((function(t){var n=Z({},e[t],r);e[t]=n})),e}),o);return r.root=n,r.plain=Z({},n,{backgroundColor:null}),r}(e.theme,e.language):void 0;return t.themeDict=n})),O(this,"getLineProps",(function(e){var n=e.key,o=e.className,r=e.style,a=Z({},S(e,["key","className","style","line"]),{className:"token-line",style:void 0,key:void 0}),c=t.getThemeDict(t.props);return void 0!==c&&(a.style=c.plain),void 0!==r&&(a.style=void 0!==a.style?Z({},a.style,r):r),void 0!==n&&(a.key=n),o&&(a.className+=" "+o),a})),O(this,"getStyleForToken",(function(e){var n=e.types,o=e.empty,r=n.length,a=t.getThemeDict(t.props);if(void 0!==a){if(1===r&&"plain"===n[0])return o?{display:"inline-block"}:void 0;if(1===r&&!o)return a[n[0]];var c=o?{display:"inline-block"}:{},l=n.map((function(e){return a[e]}));return Object.assign.apply(Object,[c].concat(l))}})),O(this,"getTokenProps",(function(e){var n=e.key,o=e.className,r=e.style,a=e.token,c=Z({},S(e,["key","className","style","token"]),{className:"token "+a.types.join(" "),children:a.content,style:t.getStyleForToken(a),key:void 0});return void 0!==r&&(c.style=void 0!==c.style?Z({},c.style,r):r),void 0!==n&&(c.key=n),o&&(c.className+=" "+o),c})),O(this,"tokenize",(function(e,t,n,o){var r={code:t,grammar:n,language:o,tokens:[]};e.hooks.run("before-tokenize",r);var a=r.tokens=e.tokenize(r.code,r.grammar,r.language);return e.hooks.run("after-tokenize",r),a}))}return e&&(t.__proto__=e),t.prototype=Object.create(e&&e.prototype),t.prototype.constructor=t,t.prototype.render=function(){var e=this.props,t=e.Prism,n=e.language,o=e.code,r=e.children,a=this.getThemeDict(this.props),c=t.languages[n];return r({tokens:function(e){for(var t=[[]],n=[e],o=[0],r=[e.length],a=0,c=0,l=[],i=[l];c>-1;){for(;(a=o[c]++) 0?u:["plain"],s=m):(u=H(u,m.type),m.alias&&(u=H(u,m.alias)),s=m.content),"string"==typeof s){var d=s.split(j),p=d.length;l.push({types:u,content:d[0]});for(var f=1;f o.createElement("span",(0,a.Z)({key:t},l({token:e,key:t})))));return o.createElement("span",s,r?o.createElement(o.Fragment,null,o.createElement("span",{className:P.codeLineNumber}),o.createElement("span",{className:P.codeLineContent},u)):u,o.createElement("br",null))}var M=n(5999);const D={copyButtonCopied:"copyButtonCopied_obH4",copyButtonIcons:"copyButtonIcons_eSgA",copyButtonIcon:"copyButtonIcon_y97N",copyButtonSuccessIcon:"copyButtonSuccessIcon_LjdS"};function W(e){let{code:t,className:n}=e;const[r,a]=(0,o.useState)(!1),c=(0,o.useRef)(void 0),l=(0,o.useCallback)((()=>{!function(e,t){let{target:n=document.body}=void 0===t?{}:t;if("string"!=typeof e)throw new TypeError(`Expected parameter \`text\` to be a \`string\`, got \`${typeof e}\`.`);const o=document.createElement("textarea"),r=document.activeElement;o.value=e,o.setAttribute("readonly",""),o.style.contain="strict",o.style.position="absolute",o.style.left="-9999px",o.style.fontSize="12pt";const a=document.getSelection(),c=a.rangeCount>0&&a.getRangeAt(0);n.append(o),o.select(),o.selectionStart=0,o.selectionEnd=e.length;let l=!1;try{l=document.execCommand("copy")}catch{}o.remove(),c&&(a.removeAllRanges(),a.addRange(c)),r&&r.focus()}(t),a(!0),c.current=window.setTimeout((()=>{a(!1)}),1e3)}),[t]);return(0,o.useEffect)((()=>()=>window.clearTimeout(c.current)),[]),o.createElement("button",{type:"button","aria-label":r?(0,M.I)({id:"theme.CodeBlock.copied",message:"Copied",description:"The copied button label on code blocks"}):(0,M.I)({id:"theme.CodeBlock.copyButtonAriaLabel",message:"Copy code to clipboard",description:"The ARIA label for copy code blocks button"}),title:(0,M.I)({id:"theme.CodeBlock.copy",message:"Copy",description:"The copy button label on code blocks"}),className:(0,i.Z)("clean-btn",n,D.copyButton,r&&D.copyButtonCopied),onClick:l},o.createElement("span",{className:D.copyButtonIcons,"aria-hidden":"true"},o.createElement("svg",{className:D.copyButtonIcon,viewBox:"0 0 24 24"},o.createElement("path",{d:"M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"})),o.createElement("svg",{className:D.copyButtonSuccessIcon,viewBox:"0 0 24 24"},o.createElement("path",{d:"M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"}))))}const R={wordWrapButtonIcon:"wordWrapButtonIcon_Bwma",wordWrapButtonEnabled:"wordWrapButtonEnabled_EoeP"};function V(e){let{className:t,onClick:n,isEnabled:r}=e;const a=(0,M.I)({id:"theme.CodeBlock.wordWrapToggle",message:"Toggle word wrap",description:"The title attribute for toggle word wrapping button of code block lines"});return o.createElement("button",{type:"button",onClick:n,className:(0,i.Z)("clean-btn",t,r&&R.wordWrapButtonEnabled),"aria-label":a,title:a},o.createElement("svg",{className:R.wordWrapButtonIcon,viewBox:"0 0 24 24","aria-hidden":"true"},o.createElement("path",{fill:"currentColor",d:"M4 19h6v-2H4v2zM20 5H4v2h16V5zm-3 6H4v2h13.25c1.1 0 2 .9 2 2s-.9 2-2 2H15v-2l-3 3l3 3v-2h2c2.21 0 4-1.79 4-4s-1.79-4-4-4z"})))}function $(e){let{children:t,className:n="",metastring:r,title:c,showLineNumbers:l,language:s}=e;const{prism:{defaultLanguage:d,magicComments:p}}=(0,u.L)(),f=s??function(e){const t=e.split(" ").find((e=>e.startsWith("language-")));return t?.replace(/language-/,"")}(n)??d,g=m(),y=function(){const[e,t]=(0,o.useState)(!1),[n,r]=(0,o.useState)(!1),a=(0,o.useRef)(null),c=(0,o.useCallback)((()=>{const n=a.current.querySelector("code");e?n.removeAttribute("style"):(n.style.whiteSpace="pre-wrap",n.style.overflowWrap="anywhere"),t((e=>!e))}),[a,e]),l=(0,o.useCallback)((()=>{const{scrollWidth:e,clientWidth:t}=a.current,n=e>t||a.current.querySelector("code").hasAttribute("style");r(n)}),[a]);return B(a,l),(0,o.useEffect)((()=>{l()}),[e,l]),(0,o.useEffect)((()=>(window.addEventListener("resize",l,{passive:!0}),()=>{window.removeEventListener("resize",l)})),[l]),{codeBlockRef:a,isEnabled:e,isCodeScrollable:n,toggle:c}}(),v=function(e){return e?.match(h)?.groups.title??""}(r)||c,{lineClassNames:E,code:C}=b(t,{metastring:r,language:f,magicComments:p}),L=l??function(e){return Boolean(e?.includes("showLineNumbers"))}(r);return o.createElement(k,{as:"div",className:(0,i.Z)(n,f&&!n.includes(`language-${f}`)&&`language-${f}`)},v&&o.createElement("div",{className:N.codeBlockTitle},v),o.createElement("div",{className:N.codeBlockContent},o.createElement(I,(0,a.Z)({},T,{theme:g,code:C,language:f??"text"}),(e=>{let{className:t,tokens:n,getLineProps:r,getTokenProps:a}=e;return o.createElement("pre",{tabIndex:0,ref:y.codeBlockRef,className:(0,i.Z)(t,N.codeBlock,"thin-scrollbar")},o.createElement("code",{className:(0,i.Z)(N.codeBlockLines,L&&N.codeBlockLinesWithNumbering)},n.map(((e,t)=>o.createElement(z,{key:t,line:e,getLineProps:r,getTokenProps:a,classNames:E[t],showLineNumbers:L})))))})),o.createElement("div",{className:N.buttonGroup},(y.isEnabled||y.isCodeScrollable)&&o.createElement(V,{className:N.codeButton,onClick:()=>y.toggle(),isEnabled:y.isEnabled}),o.createElement(W,{className:N.codeButton,code:C}))))}function q(e){let{children:t,...n}=e;const r=(0,l.Z)(),c=function(e){return o.Children.toArray(e).some((e=>(0,o.isValidElement)(e)))?e:Array.isArray(e)?e.join(""):e}(t),i="string"==typeof c?$:C;return o.createElement(i,(0,a.Z)({key:String(r)},n),c)}var F=n(9960);var U=n(6043);const G={details:"details_lb9f",isBrowser:"isBrowser_bmU9",collapsibleContent:"collapsibleContent_i85q"};function Y(e){return!!e&&("SUMMARY"===e.tagName||Y(e.parentElement))}function Q(e,t){return!!e&&(e===t||Q(e.parentElement,t))}function X(e){let{summary:t,children:n,...r}=e;const c=(0,l.Z)(),s=(0,o.useRef)(null),{collapsed:u,setCollapsed:m}=(0,U.u)({initialState:!r.open}),[d,p]=(0,o.useState)(r.open),f=o.isValidElement(t)?t:o.createElement("summary",null,t??"Details");return o.createElement("details",(0,a.Z)({},r,{ref:s,open:d,"data-collapsed":u,className:(0,i.Z)(G.details,c&&G.isBrowser,r.className),onMouseDown:e=>{Y(e.target)&&e.detail>1&&e.preventDefault()},onClick:e=>{e.stopPropagation();const t=e.target;Y(t)&&Q(t,s.current)&&(e.preventDefault(),u?(m(!1),p(!0)):m(!0))}}),f,o.createElement(U.z,{lazy:!1,collapsed:u,disableSSRStyle:!0,onCollapseTransitionEnd:e=>{m(e),p(!e)}},o.createElement("div",{className:G.collapsibleContent},n)))}const J={details:"details_b_Ee"},K="alert alert--info";function ee(e){let{...t}=e;return o.createElement(X,(0,a.Z)({},t,{className:(0,i.Z)(K,J.details,t.className)}))}var te=n(2503);function ne(e){return o.createElement(te.Z,e)}const oe={containsTaskList:"containsTaskList_mC6p"};const re={img:"img_ev3q"};const ae="admonition_LlT9",ce="admonitionHeading_tbUL",le="admonitionIcon_kALy",ie="admonitionContent_S0QG";const se={note:{infimaClassName:"secondary",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"}))},label:o.createElement(M.Z,{id:"theme.admonition.note",description:"The default label used for the Note admonition (:::note)"},"note")},tip:{infimaClassName:"success",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.tip",description:"The default label used for the Tip admonition (:::tip)"},"tip")},danger:{infimaClassName:"danger",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 12 16"},o.createElement("path",{fillRule:"evenodd",d:"M5.05.31c.81 2.17.41 3.38-.52 4.31C3.55 5.67 1.98 6.45.9 7.98c-1.45 2.05-1.7 6.53 3.53 7.7-2.2-1.16-2.67-4.52-.3-6.61-.61 2.03.53 3.33 1.94 2.86 1.39-.47 2.3.53 2.27 1.67-.02.78-.31 1.44-1.13 1.81 3.42-.59 4.78-3.42 4.78-5.56 0-2.84-2.53-3.22-1.25-5.61-1.52.13-2.03 1.13-1.89 2.75.09 1.08-1.02 1.8-1.86 1.33-.67-.41-.66-1.19-.06-1.78C8.18 5.31 8.68 2.45 5.05.32L5.03.3l.02.01z"}))},label:o.createElement(M.Z,{id:"theme.admonition.danger",description:"The default label used for the Danger admonition (:::danger)"},"danger")},info:{infimaClassName:"info",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 14 16"},o.createElement("path",{fillRule:"evenodd",d:"M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"}))},label:o.createElement(M.Z,{id:"theme.admonition.info",description:"The default label used for the Info admonition (:::info)"},"info")},caution:{infimaClassName:"warning",iconComponent:function(){return o.createElement("svg",{viewBox:"0 0 16 16"},o.createElement("path",{fillRule:"evenodd",d:"M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"}))},label:o.createElement(M.Z,{id:"theme.admonition.caution",description:"The default label used for the Caution admonition (:::caution)"},"caution")}},ue={secondary:"note",important:"info",success:"tip",warning:"danger"};function me(e){const{mdxAdmonitionTitle:t,rest:n}=function(e){const t=o.Children.toArray(e),n=t.find((e=>o.isValidElement(e)&&"mdxAdmonitionTitle"===e.props?.mdxType)),r=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return{mdxAdmonitionTitle:n,rest:r}}(e.children);return{...e,title:e.title??t,children:n}}const de={head:function(e){const t=o.Children.map(e.children,(e=>o.isValidElement(e)?function(e){if(e.props?.mdxType&&e.props.originalType){const{mdxType:t,originalType:n,...r}=e.props;return o.createElement(e.props.originalType,r)}return e}(e):e));return o.createElement(c.Z,e,t)},code:function(e){const t=["a","abbr","b","br","button","cite","code","del","dfn","em","i","img","input","ins","kbd","label","object","output","q","ruby","s","small","span","strong","sub","sup","time","u","var","wbr"];return o.Children.toArray(e.children).every((e=>"string"==typeof e&&!e.includes("\n")||(0,o.isValidElement)(e)&&t.includes(e.props?.mdxType)))?o.createElement("code",e):o.createElement(q,e)},a:function(e){return o.createElement(F.Z,e)},pre:function(e){return o.createElement(q,(0,o.isValidElement)(e.children)&&"code"===e.children.props?.originalType?e.children.props:{...e})},details:function(e){const t=o.Children.toArray(e.children),n=t.find((e=>o.isValidElement(e)&&"summary"===e.props?.mdxType)),r=o.createElement(o.Fragment,null,t.filter((e=>e!==n)));return o.createElement(ee,(0,a.Z)({},e,{summary:n}),r)},ul:function(e){return o.createElement("ul",(0,a.Z)({},e,{className:(t=e.className,(0,i.Z)(t,t?.includes("contains-task-list")&&oe.containsTaskList))}));var t},img:function(e){return o.createElement("img",(0,a.Z)({loading:"lazy"},e,{className:(t=e.className,(0,i.Z)(t,re.img))}));var t},h1:e=>o.createElement(ne,(0,a.Z)({as:"h1"},e)),h2:e=>o.createElement(ne,(0,a.Z)({as:"h2"},e)),h3:e=>o.createElement(ne,(0,a.Z)({as:"h3"},e)),h4:e=>o.createElement(ne,(0,a.Z)({as:"h4"},e)),h5:e=>o.createElement(ne,(0,a.Z)({as:"h5"},e)),h6:e=>o.createElement(ne,(0,a.Z)({as:"h6"},e)),admonition:function(e){const{children:t,type:n,title:r,icon:a}=me(e),c=function(e){const t=ue[e]??e,n=se[t];return n||(console.warn(`No admonition config found for admonition type "${t}". Using Info as fallback.`),se.info)}(n),l=r??c.label,{iconComponent:s}=c,u=a??o.createElement(s,null);return o.createElement("div",{className:(0,i.Z)(d.k.common.admonition,d.k.common.admonitionType(e.type),"alert",`alert--${c.infimaClassName}`,ae)},o.createElement("div",{className:ce},o.createElement("span",{className:le},u),l),o.createElement("div",{className:ie},t))},mermaid:()=>null};function pe(e){let{children:t}=e;return o.createElement(r.Zo,{components:de},t)}},9407:(e,t,n)=>{"use strict";n.d(t,{Z:()=>u});var o=n(7462),r=n(7294),a=n(6010),c=n(3743);const l={tableOfContents:"tableOfContents_bqdL",docItemContainer:"docItemContainer_F8PC"},i="table-of-contents__link toc-highlight",s="table-of-contents__link--active";function u(e){let{className:t,...n}=e;return r.createElement("div",{className:(0,a.Z)(l.tableOfContents,"thin-scrollbar",t)},r.createElement(c.Z,(0,o.Z)({},n,{linkClassName:i,linkActiveClassName:s})))}},3743:(e,t,n)=>{"use strict";n.d(t,{Z:()=>f});var o=n(7462),r=n(7294),a=n(6668);function c(e){const t=e.map((e=>({...e,parentIndex:-1,children:[]}))),n=Array(7).fill(-1);t.forEach(((e,t)=>{const o=n.slice(2,e.level);e.parentIndex=Math.max(...o),n[e.level]=t}));const o=[];return t.forEach((e=>{const{parentIndex:n,...r}=e;n>=0?t[n].children.push(r):o.push(r)})),o}function l(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:o}=e;return t.flatMap((e=>{const t=l({toc:e.children,minHeadingLevel:n,maxHeadingLevel:o});return function(e){return e.level>=n&&e.level<=o}(e)?[{...e,children:t}]:t}))}function i(e){const t=e.getBoundingClientRect();return t.top===t.bottom?i(e.parentNode):t}function s(e,t){let{anchorTopOffset:n}=t;const o=e.find((e=>i(e).top>=n));if(o){return function(e){return e.top>0&&e.bottom
{e.current=t?0:document.querySelector(".navbar").clientHeight}),[t]),e}function m(e){const t=(0,r.useRef)(void 0),n=u();(0,r.useEffect)((()=>{if(!e)return()=>{};const{linkClassName:o,linkActiveClassName:r,minHeadingLevel:a,maxHeadingLevel:c}=e;function l(){const e=function(e){return Array.from(document.getElementsByClassName(e))}(o),l=function(e){let{minHeadingLevel:t,maxHeadingLevel:n}=e;const o=[];for(let r=t;r<=n;r+=1)o.push(`h${r}.anchor`);return Array.from(document.querySelectorAll(o.join()))}({minHeadingLevel:a,maxHeadingLevel:c}),i=s(l,{anchorTopOffset:n.current}),u=e.find((e=>i&&i.id===function(e){return decodeURIComponent(e.href.substring(e.href.indexOf("#")+1))}(e)));e.forEach((e=>{!function(e,n){n?(t.current&&t.current!==e&&t.current.classList.remove(r),e.classList.add(r),t.current=e):e.classList.remove(r)}(e,e===u)}))}return document.addEventListener("scroll",l),document.addEventListener("resize",l),l(),()=>{document.removeEventListener("scroll",l),document.removeEventListener("resize",l)}}),[e,n])}function d(e){let{toc:t,className:n,linkClassName:o,isChild:a}=e;return t.length?r.createElement("ul",{className:a?void 0:n},t.map((e=>r.createElement("li",{key:e.id},r.createElement("a",{href:`#${e.id}`,className:o??void 0,dangerouslySetInnerHTML:{__html:e.value}}),r.createElement(d,{isChild:!0,toc:e.children,className:n,linkClassName:o}))))):null}const p=r.memo(d);function f(e){let{toc:t,className:n="table-of-contents table-of-contents__left-border",linkClassName:i="table-of-contents__link",linkActiveClassName:s,minHeadingLevel:u,maxHeadingLevel:d,...f}=e;const h=(0,a.L)(),g=u??h.tableOfContents.minHeadingLevel,y=d??h.tableOfContents.maxHeadingLevel,v=function(e){let{toc:t,minHeadingLevel:n,maxHeadingLevel:o}=e;return(0,r.useMemo)((()=>l({toc:c(t),minHeadingLevel:n,maxHeadingLevel:o})),[t,n,o])}({toc:t,minHeadingLevel:g,maxHeadingLevel:y});return m((0,r.useMemo)((()=>{if(i&&s)return{linkClassName:i,linkActiveClassName:s,minHeadingLevel:g,maxHeadingLevel:y}}),[i,s,g,y])),r.createElement(p,(0,o.Z)({toc:v,className:n,linkClassName:i},f))}},7594:(e,t)=>{function n(e){let t,n=[];for(let o of e.split(",").map((e=>e.trim())))if(/^-?\d+$/.test(o))n.push(parseInt(o,10));else if(t=o.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,o,r,a]=t;if(o&&a){o=parseInt(o),a=parseInt(a);const e=o{n.d(t,{Zo:()=>p,kt:()=>m});var o=n(7294);function a(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 i(e){for(var t=1;t =0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);for(o=0;o =0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=o.createContext({}),c=function(e){var t=o.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},p=function(e){var t=c(e.components);return o.createElement(l.Provider,{value:t},e.children)},d="mdxType",h={inlineCode:"code",wrapper:function(e){var t=e.children;return o.createElement(o.Fragment,{},t)}},u=o.forwardRef((function(e,t){var n=e.components,a=e.mdxType,r=e.originalType,l=e.parentName,p=s(e,["components","mdxType","originalType","parentName"]),d=c(n),u=a,m=d["".concat(l,".").concat(u)]||d[u]||h[u]||r;return n?o.createElement(m,i(i({ref:t},p),{},{components:n})):o.createElement(m,i({ref:t},p))}));function m(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var r=n.length,i=new Array(r);i[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s[d]="string"==typeof e?e:a,i[1]=s;for(var c=2;c {n.r(t),n.d(t,{assets:()=>l,contentTitle:()=>i,default:()=>h,frontMatter:()=>r,metadata:()=>s,toc:()=>c});var o=n(7462),a=(n(7294),n(3905));const r={},i="Studio Overview",s={unversionedId:"creator/studio/readme",id:"creator/studio/readme",title:"Studio Overview",description:"Ethereal Engine Studio",source:"@site/docs/2_creator/2_studio/readme.md",sourceDirName:"2_creator/2_studio",slug:"/creator/studio/",permalink:"/etherealengine-docs/docs/creator/studio/",draft:!1,editUrl:"https://github.com/EtherealEngine/etherealengine-docs/blob/master/docs/2_creator/2_studio/readme.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Studio & Locations",permalink:"/etherealengine-docs/docs/creator/concepts/editor_scenes_locations"},next:{title:"Asset Import Pipeline",permalink:"/etherealengine-docs/docs/creator/importing_assets/"}},l={},c=[{value:"1 Toolbar",id:"1-toolbar",level:2},{value:"1. File Menu",id:"1-file-menu",level:3},{value:"2: Advanced",id:"2-advanced",level:3},{value:"3. Active Instances",id:"3-active-instances",level:3},{value:"4. Transform Gizmo: Scale, Rotate, Move",id:"4-transform-gizmo--scale-rotate-move",level:3}],p={toc:c},d="wrapper";function h(e){let{components:t,...n}=e;return(0,a.kt)(d,(0,o.Z)({},p,n,{components:t,mdxType:"MDXLayout"}),(0,a.kt)("h1",{id:"studio-overview"},"Studio Overview"),(0,a.kt)("p",null,"Ethereal Engine Studio\nUI Overview\n",(0,a.kt)("img",{parentName:"p",src:"https://github.com/EtherealEngine/etherealengine-docs/assets/5104160/a26ad154-64f4-4681-a011-70af9f4213e1",alt:"image6"})),(0,a.kt)("p",null,"1: Toolbar"),(0,a.kt)("p",null,"2: Scene and File Directory "),(0,a.kt)("p",null,"3: Preview"),(0,a.kt)("p",null,"4: Viewport"),(0,a.kt)("p",null,"5: Hierarchy, Material Library, Node Graph"),(0,a.kt)("p",null,"6: Properties "),(0,a.kt)("p",null,"7: Assembly Menu"),(0,a.kt)("p",null,"8: User Profile "),(0,a.kt)("hr",null),(0,a.kt)("h2",{id:"1-toolbar"},"1 Toolbar"),(0,a.kt)("h3",{id:"1-file-menu"},"1. File Menu"),(0,a.kt)("p",null,"Create new scenes, import files, and save or export existing scenes. "),(0,a.kt)("h3",{id:"2-advanced"},"2: Advanced"),(0,a.kt)("p",null,"Toggle advanced options on Model or Avatar components.\nAdd and remove components in the Properties tab "),(0,a.kt)("h3",{id:"3-active-instances"},"3. Active Instances"),(0,a.kt)("p",null,"Active Instances shown here"),(0,a.kt)("h3",{id:"4-transform-gizmo--scale-rotate-move"},"4. Transform Gizmo: Scale, Rotate, Move"),(0,a.kt)("p",null," ","[ Y ]"," Scale\n","[ R ]"," Rotate\n","[ T ]"," Move"),(0,a.kt)("ol",{start:5},(0,a.kt)("li",{parentName:"ol"},"World Space or Object Space Transform - toggle to world or object\nSets your transform control to be oriented to the object(selection) or world\nWorld space relates to the entire scene\u2019s orientation\nObject space (your selection) relates to transforms made to a specific object in relationship to the world space")),(0,a.kt)("p",null,"[ Z ]"," Toggle World space or Object(Selection) space"),(0,a.kt)("ol",{start:6},(0,a.kt)("li",{parentName:"ol"},"Toggle Transform Pivot - modes: Selection, Center, Bottom, or Origin\nTo use, shift select objects, enter transform mode (Y, R, T), choose pivot type:\nSelection:the center pivot of the final asset you selected in the sequence\nCenter: a pivot that sits at an equal distance between all selections\nBottom: pivot that sits equally between all selections and at the bottom of your final selection in the sequence\nOrigin: sets pivot mode to the world origin (0,0,0)\n*it is recommended to use the Toggle Transform in conjunction with the World/Object Space transforms")),(0,a.kt)("p",null,"[ X ]"," Toggle between Selection, Center, or Bottom\n","[ E ]"," incrementally rotate around the Y axis, adopts the selected snapping degree value "),(0,a.kt)("ol",{start:7},(0,a.kt)("li",{parentName:"ol"},"Grid Snapping (toggle)\nTransform objects by a unit of measurement ","[.1 meters, .125 meters, 1 meter, 4 meters, etc]","\nRotate objects by a specific degrees ","[5o,10o, 20o, 90o, etc]")),(0,a.kt)("p",null,"[ C ]"," Toggle Snap Mode\n","[ E ]"," incrementally rotate around the Y axis, adopts the selected snapping degree value "),(0,a.kt)("ol",{start:8},(0,a.kt)("li",{parentName:"ol"},"Grid Visibility (toggle)\nSet grid spacing by meters")),(0,a.kt)("ol",{start:9},(0,a.kt)("li",{parentName:"ol"},"Render Mode\nHow you view materials in the Engine\n(Unlit, Lit, Shadows, Wireframe, Normals)")),(0,a.kt)("ol",{start:10},(0,a.kt)("li",{parentName:"ol"},"Preview Scene\nSpawns you into the scene ")),(0,a.kt)("ol",{start:11},(0,a.kt)("li",{parentName:"ol"},"Status (toggle)")),(0,a.kt)("p",null,"Show stats about the scene and gives you a clue as to how optimized your scene is\nMemory: Geometries, Textures\nRender: FPS, Frame Time, Calls(drawcalls), Triangles, Points, Lines"),(0,a.kt)("ol",{start:12},(0,a.kt)("li",{parentName:"ol"},"Helpers (toggle)\nView hidden information about your scene, ie: colliders ")),(0,a.kt)("ol",{start:13},(0,a.kt)("li",{parentName:"ol"},"Node Helpers (toggle)\nHelper geometry that helps components have visibility in the scene when inactive ")),(0,a.kt)("ol",{start:14},(0,a.kt)("li",{parentName:"ol"},"Take A Screenshot\nTakes a screenshot of your scene at the current view")),(0,a.kt)("p",null,"#2 Scene and File Directory "),(0,a.kt)("p",null,"Project Files\nContains all files associated with your project.\n.json files and various other file types in this menu are your project files and will show up automatically when you create a new scene."),(0,a.kt)("p",null,"Assets folder\nContains all assets you can import into your scene. When you use the Toolbar: File Menu to import files, they are delivered directly to the assets folder. To populate your scene simply drag them from the assets directly to your hierarchy.\nTip: Import may create a transform offset\nWhen some assets are loaded they automatically show up in the scene in the hierarchy and sometimes at an offset. Simply delete them from the hierarchy and re-drag them from your assets folder into your scene hierarchy to have them be set at home (0,0,0)"),(0,a.kt)("p",null,"#3 The Preview Panel\nThe preview panel allows you to preview certain files, currently supporting image, video and audio files "),(0,a.kt)("p",null,"#4 Viewport\nThe view of all things active inside your scene.\nObjects have the typical navigation controls\nX = red\nY = green\nZ = blue"),(0,a.kt)("p",null,"#5 Hierarchy & Material Library\nHierarchy\nThe scene Hierarchy contains all element currently in your scene (assets, lighting, items from the tool menu, etc)\nMaterial Library\nLocation of an assets materials and where you can select and edit them "),(0,a.kt)("p",null,"#6 Properties\nWhere you can access and edit detailed information about objects in your scene.\nSelect an object in the Hierarchy to view its Properties. This panel supports editing and adding actions to objects, ie: keying transforms, turning on animation tracks, looping motion, and adding components to objects "),(0,a.kt)("p",null,"Model URL\nShows the location of an object in your scene hierarchy "),(0,a.kt)("p",null,"Using the Advanced Tab (toolbar)\nBy activating the advanced tab from the toolbar you are able to add specific components to assets in your scene adding data to the entity.\nExplode objects that are imported as a collapsed group"),(0,a.kt)("p",null,"Types of Components "),(0,a.kt)("p",null,"#7 Assembly Menu"),(0,a.kt)("p",null,"Files\nModel\nCreates objects in the hierarchy. Drag a model from the assets folder into the URL box or drag assets directly from project files into the hierarchy\nVolumetric\nImport volumetric files. Accepts DRCS, UVOL, or Manifest Files, links to cloud hosting\nVideo\n2D plane accepts .mp4 .mkv .avi\nAudio\nImport audio clips, .mp3, .flac, .ogg, .wav, .m4a"),(0,a.kt)("p",null,"Scene Composition\nGround Plane\nCreate collision ground plane\nGroup\nCollection of models or assets\nAsset Prefab\nCreate prefabs from groups or objects that are saved to the assets folder. Saving requires specific naming: 'assetName'.xre.gltf\nCollider\nCreates a collision ball, cuboid, capsule, or cylinder to be manually placement"),(0,a.kt)("p",null,"Interaction\nSpawn Point\nA point where people will appear when they enter your scene\nPortal\nA portal to teleport a player to a port in a different location"),(0,a.kt)("p",null,"Lights\nHemisphere Light\nA light which illuminates the scene from directly overhead\nPoint Light\nA light which emits in all directions from a single point\nDirectional Light\nCreates a light that emits evenly in a single direction\nAmbient Light\nA combination of direct and indirect light, provides general lighting to all assets\nSpot Light\nCreates a light that shines in a specific direction"),(0,a.kt)("p",null,"Scripting\nInserts code into the scene by creating a new Entity Component System based on the provided .ts file"),(0,a.kt)("p",null,"FX\nOcean\nCube body of water\nParticle Emitter\nCreates a particle emitter\nCloud\nSprite based cloud volume\nWater\nCreates a circular water surface with ripple effect\nSpline\nCreate and customize curves"),(0,a.kt)("p",null,"Misc\nE-commerce shop\nCreate a shop, choose product from dropdown, click select product, click away, click back, select product item(.glb), select variant, select product, click away, click back, object will populate scene"),(0,a.kt)("p",null,"#8 User Profile",(0,a.kt)("br",{parentName:"p"}),"\n","Your Ethereal Engine account settings and linked account information"),(0,a.kt)("p",null,"The settings wheel icon allows you to turn up your scene resolution.\nIf you notice the scene looks blurry, go to the Graphics tab inside Settings and turn the Resolution tab all the way up."),(0,a.kt)("p",null,"Create a Project\nImport Assets\nYou can use the File menu to import assets or you can drag and drop them into the assets folder, when clicking and dragging notice a slight change in the color of the Engine, this signifies the engine is ready to ingest your file.\nImporting assets immediately creates them in the scene at an arbitrary location when imported via the viewport. It is recommended to delete that import and drag an asset directly from project files into the hierarchy to easily zero out your transforms.\nEthereal Engine accept the following file types"),(0,a.kt)("p",null,"3D Models .glb, .gltf\nImages .png, .tiff, .jpeg\nVolumetric DRCS, UVOL, Manifest Files on the Cloud\nVideos .mp4m, .mkv, .avi\nAudio .mp3, .mpeg, .m4a\nSave Project\nIn the File menu, click the save or save as button to save your scene\nSome projects require time to save so don't exit this window until a few minutes have passed\nEdit Materials\nEthereal Engine supports a PBR workflow and Vertex Colors\nPBR Workflow:\nDiffuse or Base Color Map\nMetalness Map\nRoughness Map\nNormal Map\nAmbient Occlusion (AO) Map\n*each of these loaded will represent one draw call, only use maps you absolutely need. You can drop the diffuse map and use our built in RGB color selector to save scene space."),(0,a.kt)("p",null,"Your asset materials are visible in the order below under the Material Library tab\nMaterial Library "),(0,a.kt)("blockquote",null,(0,a.kt)("p",{parentName:"blockquote"},"Asset Name\nmaterial name\nmaterial name\nmaterial name")),(0,a.kt)("p",null,"Material Types:\nMeshBasicMaterial\nThis material is not affected by lights.\n",(0,a.kt)("a",{parentName:"p",href:"https://threejs.org/docs/?q=meshba#api/en/materials/MeshBasicMaterial"},"https://threejs.org/docs/?q=meshba#api/en/materials/MeshBasicMaterial")," \t\t\t "),(0,a.kt)("p",null,"MeshStandardMaterial\nA standard physically based material, using Metallic-Roughness workflow.\n",(0,a.kt)("a",{parentName:"p",href:"https://threejs.org/docs/?q=meshstan#api/en/materials/MeshStandardMaterial"},"https://threejs.org/docs/?q=meshstan#api/en/materials/MeshStandardMaterial")),(0,a.kt)("p",null,"MeshMatcapMaterial\nMeshMatcapMaterial is defined by a MatCap (or Lit Sphere) texture, which encodes the \t\t\tmaterial color and shading.\nMeshPhysicalMaterial\nAn extension of the MeshStandardMaterial, providing more advanced physically-based rendering\n(added properties include: Clearcoat, Physically-based transparency, Advanced reflectivity, and Sheen)\nMeshLambertMaterial\nA material for non-shiny surfaces, without specular highlights.\nMeshPhongMaterial\nA material for shiny surfaces with specular highlights.\nMeshToonMaterial\nA material implementing toon shading.\nShaderMaterial\n",(0,a.kt)("a",{parentName:"p",href:"https://threejs.org/docs/?q=shadermat#api/en/materials/ShaderMaterial"},"https://threejs.org/docs/?q=shadermat#api/en/materials/ShaderMaterial"),"\nShadowMaterial\n",(0,a.kt)("a",{parentName:"p",href:"https://threejs.org/docs/?q=shadow#api/en/materials/ShadowMaterial"},"https://threejs.org/docs/?q=shadow#api/en/materials/ShadowMaterial")),(0,a.kt)("p",null,"Saving Changes\nAnytime you make a change to a model, you need to save your change.\nThis includes edits to the Position, Rotation, Scale, Normals, UVs, Materials and Attributes.\nAfter making your edit, go to the hierarchy and re-select your asset, in the Properties tab, scroll to the bottom and click the Save Changes button. If you want to Save As, in the url just above the Save Changes button, you can manually edit the name at the end of the url and click Save Changes. You can find the new version of your .glbl in the assets folder. "),(0,a.kt)("p",null,"Tip: Convert .gltfs or .usdz to .glb format in the engine using this method\nCompression\nThe in-engine compression menu is available when you select the model you want to run compression on from the Hierarchy. Scrolling down inside of the Properties panel you can expand the Model Transform Properties Menu.\nThere are three menus, gltF-Transform, Delete Attributes, Bake To Vertices."),(0,a.kt)("p",null,"gltF-Compression:\nRuns compression on the models geometry and image textures. Default settings work well for most models.\nThe Image Format menu allows you to either choose JPG, KTX2, or PNG for the image\u2019s compression format.\nThe Max Texture Size denotes the pixel scale of your image. Default settings downsize the textures to 1024 pixels x 1024 pixels\nPress Optimize to run the compression"),(0,a.kt)("p",null,"Delete Attributes:\nModels occasionally are imported with an excess of attributes taking up unwanted space, to delete the extra, unnecessary data list the attributes here with a space in between each attribute listed"),(0,a.kt)("p",null,"Bake To Vertices:\nThis tool bakes your texture to vertex color. By doing this we can eliminate the need for loading heavy images on some models. Vertex Baking transfers your PBR maps to the vertex of your model. We currently support diffuse, lightMap and emissive.\n*this method is for models that have a simple texture with either a single color or few details"),(0,a.kt)("p",null,"Animations in Objects\nAvatars\nTo turn on the animations of an imported model you would like to use as an avatar, in the Loop Animation tab you can select the animation track you wish to activate, \u201cmixamo.com\u201d.\nLoop Animations: loop the motion tracks available on your avatar\nChecking \u2018Is Avatar\u2019 allows you to use the animations built into the engine on your Avatar. "),(0,a.kt)("p",null,"Animated Geometry\nLoop Animations: loop the motion tracks available on your model"),(0,a.kt)("p",null,"Skybox/Cubemap\nThe Skybox Button from the Tools Panel allows you to create a Skybox for your scene.\nYou can choose between Color, Skybox, Cubemap, and Equirectangular\nColor: basic color as the sky\nSkybox: cubemap that surrounds your scene giving the look of being in an environment\nEquirectangular: sphere that surrounds your scene giving the look of being in an environment, recommended sources for equirectangular images are hdrihaven.com or "),(0,a.kt)("p",null,"Tip: HdriHaven has great free HDRI Resources"),(0,a.kt)("p",null,"Importing individual models (.glb/.gltf & .usdz)\nImport your model via the File Menu or drag and drop into the Viewport (when viewport changes color it is ready to ingest the file)\nWith the model in your Hierarchy, select it and scroll down in its Properties tab.\nRe-name to your desired description with a .glb or .gltf extension. You can find your saved model in your Assets tab in the Project Files directory\nscene should be determined by what your scene is composed of. Successful optimization is achieved by leveraging the appropriate use of detail per model.\nConverting Models to .glb (recommended)\nConvert .gltf to a .glb (in browser)\nRecommended to convert .gltf into .glbs for easier importing\n",(0,a.kt)("a",{parentName:"p",href:"https://glb-packer.glitch.me/"},"https://glb-packer.glitch.me/"),"\n",(0,a.kt)("a",{parentName:"p",href:"https://cartmagician.com/tools/3d-to-AR-converter"},"https://cartmagician.com/tools/3d-to-AR-converter")," (paid)\nConvert .fbx to .glb (app)\n",(0,a.kt)("a",{parentName:"p",href:"https://github.com/facebookincubator/FBX2glTF"},"https://github.com/facebookincubator/FBX2glTF"),"\nConvert .usd to .gltf (in browser)\n",(0,a.kt)("a",{parentName:"p",href:"https://products.groupdocs.app/conversion/usd-to-gltf"},"https://products.groupdocs.app/conversion/usd-to-gltf")),(0,a.kt)("p",null,"Using SampleStandardMaterial to enhance projects\nCustom settings for Glass, Plastic, Glow & Metal are provided below"),(0,a.kt)("p",null,"For the MeshStandardMaterial\n(re-create values below to simulate materials on your geometry)\n",(0,a.kt)("a",{parentName:"p",href:"https://threejs.org/docs/?q=meshstan#api/en/materials/MeshStandardMaterial"},"https://threejs.org/docs/?q=meshstan#api/en/materials/MeshStandardMaterial")),(0,a.kt)("p",null," Glass\t\t Plastic\t Glow\t\t\t Metal"),(0,a.kt)("p",null,"Tip: Exporting assets for basic materials\nIt is not required to have a texture map on all assets in 3D and it is recommended to use Standard Materials as often as possible. We recommended using basic materials for all basic metal, glass, emissive, and plastic assets (follow the sample material set-up above). You must denote which assets will have Standard Materials before you import your .glb to the engine. It is recommended to simply drag a native material from your chosen DCC or game engine prior to export, correctly name the basic material before exporting the .glb. Names given before import are the names the engine will inherit."),(0,a.kt)("p",null,"Saving Your Project "),(0,a.kt)("p",null,"Save As or Save Scene can be found in the File Menu.\nAllow the Engine a few minutes to save your file.\nTip: Change the view to create a thumbnail\nYou will be asked to create a thumbnail on Save which takes a screenshot from the current viewport view. Move your viewport to look at the desired view for your thumbnail before you click Save."))}h.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/291a898d.adadca59.js b/assets/js/291a898d.adadca59.js new file mode 100644 index 000000000000..4a1f896ca6b0 --- /dev/null +++ b/assets/js/291a898d.adadca59.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_etherealengine_docs=self.webpackChunk_etherealengine_docs||[]).push([[2606],{3905:(e,t,r)=>{r.d(t,{Zo:()=>p,kt:()=>f});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 l(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 l=Object.getOwnPropertySymbols(e);for(n=0;n =0||Object.prototype.propertyIsEnumerable.call(e,r)&&(o[r]=e[r])}return o}var i=n.createContext({}),s=function(e){var t=n.useContext(i),r=t;return e&&(r="function"==typeof e?e(t):a(a({},t),e)),r},p=function(e){var t=s(e.components);return n.createElement(i.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,l=e.originalType,i=e.parentName,p=c(e,["components","mdxType","originalType","parentName"]),u=s(r),m=o,f=u["".concat(i,".").concat(m)]||u[m]||d[m]||l;return r?n.createElement(f,a(a({ref:t},p),{},{components:r})):n.createElement(f,a({ref:t},p))}));function f(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var l=r.length,a=new Array(l);a[0]=m;var c={};for(var i in t)hasOwnProperty.call(t,i)&&(c[i]=t[i]);c.originalType=e,c[u]="string"==typeof e?e:o,a[1]=c;for(var s=2;s {r.r(t),r.d(t,{assets:()=>i,contentTitle:()=>a,default:()=>d,frontMatter:()=>l,metadata:()=>c,toc:()=>s});var n=r(7462),o=(r(7294),r(3905));const l={},a="Control Center App",c={unversionedId:"host/devops_deployment/tutorials/ethereal_control_center/readme",id:"host/devops_deployment/tutorials/ethereal_control_center/readme",title:"Control Center App",description:"In this section you will various tutorials for Ethereal Engine Control System app.",source:"@site/docs/1_host/2_devops_deployment/8_tutorials/1_ethereal_control_center/readme.md",sourceDirName:"1_host/2_devops_deployment/8_tutorials/1_ethereal_control_center",slug:"/host/devops_deployment/tutorials/ethereal_control_center/",permalink:"/etherealengine-docs/docs/host/devops_deployment/tutorials/ethereal_control_center/",draft:!1,editUrl:"https://github.com/EtherealEngine/etherealengine-docs/blob/master/docs/1_host/2_devops_deployment/8_tutorials/1_ethereal_control_center/readme.md",tags:[],version:"current",frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Tutorials",permalink:"/etherealengine-docs/docs/host/devops_deployment/tutorials/"},next:{title:"Getting Started",permalink:"/etherealengine-docs/docs/host/devops_deployment/tutorials/ethereal_control_center/getting_started"}},i={},s=[],p={toc:s},u="wrapper";function d(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},p,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"control-center-app"},"Control Center App"),(0,o.kt)("p",null,"In this section you will various tutorials for Ethereal Engine Control System app."))}d.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/33e7527e.bca6e6d3.js b/assets/js/33e7527e.bca6e6d3.js new file mode 100644 index 000000000000..f1e7da5c4b75 --- /dev/null +++ b/assets/js/33e7527e.bca6e6d3.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_etherealengine_docs=self.webpackChunk_etherealengine_docs||[]).push([[2984],{7085:e=>{e.exports=JSON.parse('{"name":"docusaurus-theme-search-algolia","id":"default"}')}}]); \ No newline at end of file diff --git a/assets/js/393be207.7aa10cb1.js b/assets/js/393be207.7aa10cb1.js new file mode 100644 index 000000000000..d6af3d113dea --- /dev/null +++ b/assets/js/393be207.7aa10cb1.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_etherealengine_docs=self.webpackChunk_etherealengine_docs||[]).push([[7414],{3905:(e,t,r)=>{r.d(t,{Zo:()=>u,kt:()=>d});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 p(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({}),i=function(e){var t=n.useContext(l),r=t;return e&&(r="function"==typeof e?e(t):p(p({},t),e)),r},u=function(e){var t=i(e.components);return n.createElement(l.Provider,{value:t},e.children)},s="mdxType",f={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,a=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),s=i(r),m=o,d=s["".concat(l,".").concat(m)]||s[m]||f[m]||a;return r?n.createElement(d,p(p({ref:t},u),{},{components:r})):n.createElement(d,p({ref:t},u))}));function d(e,t){var r=arguments,o=t&&t.mdxType;if("string"==typeof e||o){var a=r.length,p=new Array(a);p[0]=m;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c[s]="string"==typeof e?e:o,p[1]=c;for(var i=2;i{r.r(t),r.d(t,{contentTitle:()=>p,default:()=>s,frontMatter:()=>a,metadata:()=>c,toc:()=>l});var n=r(7462),o=(r(7294),r(3905));const a={title:"Markdown page example"},p="Markdown page example",c={type:"mdx",permalink:"/etherealengine-docs/markdown-page",source:"@site/src/pages/markdown-page.md",title:"Markdown page example",description:"You don't need React to write simple standalone pages.",frontMatter:{title:"Markdown page example"}},l=[],i={toc:l},u="wrapper";function s(e){let{components:t,...r}=e;return(0,o.kt)(u,(0,n.Z)({},i,r,{components:t,mdxType:"MDXLayout"}),(0,o.kt)("h1",{id:"markdown-page-example"},"Markdown page example"),(0,o.kt)("p",null,"You don't need React to write simple standalone pages."))}s.isMDXComponent=!0}}]); \ No newline at end of file diff --git a/assets/js/3c3cda30.cb790227.js b/assets/js/3c3cda30.cb790227.js new file mode 100644 index 000000000000..fed02072ca6f --- /dev/null +++ b/assets/js/3c3cda30.cb790227.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunk_etherealengine_docs=self.webpackChunk_etherealengine_docs||[]).push([[9037],{3905:(e,t,n)=>{n.d(t,{Zo:()=>u,kt:()=>h});var a=n(7294);function l(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(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||(l[n]=e[n]);return l}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a =0||Object.prototype.propertyIsEnumerable.call(e,n)&&(l[n]=e[n])}return l}var s=a.createContext({}),c=function(e){var t=a.useContext(s),n=t;return e&&(n="function"==typeof e?e(t):i(i({},t),e)),n},u=function(e){var t=c(e.components);return a.createElement(s.Provider,{value:t},e.children)},p="mdxType",d={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,l=e.mdxType,o=e.originalType,s=e.parentName,u=r(e,["components","mdxType","originalType","parentName"]),p=c(n),m=l,h=p["".concat(s,".").concat(m)]||p[m]||d[m]||o;return n?a.createElement(h,i(i({ref:t},u),{},{components:n})):a.createElement(h,i({ref:t},u))}));function h(e,t){var n=arguments,l=t&&t.mdxType;if("string"==typeof e||l){var o=n.length,i=new Array(o);i[0]=m;var r={};for(var s in t)hasOwnProperty.call(t,s)&&(r[s]=t[s]);r.originalType=e,r[p]="string"==typeof e?e:l,i[1]=r;for(var c=2;c {n.r(t),n.d(t,{assets:()=>c,contentTitle:()=>r,default:()=>m,frontMatter:()=>i,metadata:()=>s,toc:()=>u});var a=n(7462),l=(n(7294),n(3905)),o=n(4401);const i={},r="Ethereal Engine on MicroK8s (Windows)",s={unversionedId:"host/devops_deployment/microk8s_windows",id:"host/devops_deployment/microk8s_windows",title:"Ethereal Engine on MicroK8s (Windows)",description:"This guide is intended for local environment and currently tested on Windows 11.",source:"@site/docs/1_host/2_devops_deployment/0_microk8s_windows.md",sourceDirName:"1_host/2_devops_deployment",slug:"/host/devops_deployment/microk8s_windows",permalink:"/etherealengine-docs/docs/host/devops_deployment/microk8s_windows",draft:!1,editUrl:"https://github.com/EtherealEngine/etherealengine-docs/blob/master/docs/1_host/2_devops_deployment/0_microk8s_windows.md",tags:[],version:"current",sidebarPosition:0,frontMatter:{},sidebar:"tutorialSidebar",previous:{title:"Ethereal Engine on MicroK8s (Linux)",permalink:"/etherealengine-docs/docs/host/devops_deployment/microk8s_linux"},next:{title:"Ethereal Engine on Docker Desktop",permalink:"/etherealengine-docs/docs/host/devops_deployment/docker_desktop"}},c={},u=[{value:"Install Windows Subsystem for Linux (WSL)",id:"install-windows-subsystem-for-linux-wsl",level:2},{value:"Set Ubuntu as default WSL distribution",id:"set-ubuntu-as-default-wsl-distribution",level:3},{value:"Install Docker Desktop",id:"install-docker-desktop",level:2},{value:"Enable systemd in WSL",id:"enable-systemd-in-wsl",level:2},{value:"Enable localhostForwarding in WSL",id:"enable-localhostforwarding-in-wsl",level:2},{value:"Install Node",id:"install-node",level:2},{value:"Install Python 3",id:"install-python-3",level:2},{value:"Install Make",id:"install-make",level:2},{value:"Install kubectl and Helm",id:"install-kubectl-and-helm",level:2},{value:"Download and install MicroK8s",id:"download-and-install-microk8s",level:2},{value:"Clone Ethereal Engine repo to your local machine",id:"clone-ethereal-engine-repo-to-your-local-machine",level:2},{value:"Start MinIO & MariaDB server locally via Docker",id:"start-minio--mariadb-server-locally-via-docker",level:2},{value:"Enabling MicroK8s Addons",id:"enabling-microk8s-addons",level:2},{value:"Add MicroK8s to Kubectl",id:"add-microk8s-to-kubectl",level:2},{value:"(Optional) Add MicroK8s to Lens",id:"optional-add-microk8s-to-lens",level:2},{value:"Enable MicroK8s access for local docker",id:"enable-microk8s-access-for-local-docker",level:2},{value:"Verify and troubleshoot MicroK8s",id:"verify-and-troubleshoot-microk8s",level:2},{value:"Update system hostfile to point to MicroK8s",id:"update-system-hostfile-to-point-to-microk8s",level:2},{value:"Add Helm repos",id:"add-helm-repos",level:2},{value:"Install Agones and Redis deployments",id:"install-agones-and-redis-deployments",level:2},{value:"(Optional) Install Elastic Search and Kibana using Helm for Server Logs",id:"optional-install-elastic-search-and-kibana-using-helm-for-server-logs",level:2},{value:"Run build_microk8s.sh",id:"run-build_microk8ssh",level:2},{value:"Update Helm Values File",id:"update-helm-values-file",level:2},{value:"Deploy Ethereal Engine Helm chart",id:"deploy-ethereal-engine-helm-chart",level:2},{value:"Accept invalid certs",id:"accept-invalid-certs",level:2}],p={toc:u},d="wrapper";function m(e){let{components:t,...i}=e;return(0,l.kt)(d,(0,a.Z)({},p,i,{components:t,mdxType:"MDXLayout"}),(0,l.kt)("h1",{id:"ethereal-engine-on-microk8s-windows"},"Ethereal Engine on MicroK8s (Windows)"),(0,l.kt)("p",null,"This guide is intended for local environment and currently tested on Windows 11."),(0,l.kt)("h2",{id:"install-windows-subsystem-for-linux-wsl"},"Install Windows Subsystem for Linux (WSL)"),(0,l.kt)("p",null,"Install Ubuntu distribution of Linux from Microsoft Store by using guide ",(0,l.kt)("a",{parentName:"p",href:"https://learn.microsoft.com/en-us/windows/wsl/install"},"here"),"."),(0,l.kt)("p",null,"Alternatively, you can follow these instructions as well:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://pureinfotech.com/install-wsl-windows-11/"},"How to install WSL")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://learn.microsoft.com/en-us/windows/wsl/install-manual"},"Manual installation steps for WSL"))),(0,l.kt)("p",null,"Once WSL is installed, make sure to:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://learn.microsoft.com/en-us/windows/wsl/setup/environment#set-up-your-linux-username-and-password"},"Set up your Linux username and password")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://learn.microsoft.com/en-us/windows/wsl/setup/environment#update-and-upgrade-packages"},"Update and upgrade packages"))),(0,l.kt)("h3",{id:"set-ubuntu-as-default-wsl-distribution"},"Set Ubuntu as default WSL distribution"),(0,l.kt)("p",null,"In powershell/cmd run following command to see the list of distributions:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"wsl -l\n")),(0,l.kt)("p",null,"In the list you should be able to see ",(0,l.kt)("inlineCode",{parentName:"p"},"Ubuntu")," listed. Afterwards, run following command to set Ubuntu as default distribution:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"wsl -s Ubuntu\n")),(0,l.kt)("p",null,(0,l.kt)("img",{alt:"WSL Ubuntu Default Distribution",src:n(8488).Z,width:"769",height:"435"})),(0,l.kt)("h2",{id:"install-docker-desktop"},"Install Docker Desktop"),(0,l.kt)("p",null,"Install docker desktop with WSL 2 backend. You can find the instructions ",(0,l.kt)("a",{parentName:"p",href:"https://docs.docker.com/desktop/install/windows-install/"},"here"),"."),(0,l.kt)("p",null,"Once docker desktop is installed and running make sure to enable your WSL distribution. You can do so from Docker Desktop App by visiting ",(0,l.kt)("inlineCode",{parentName:"p"},"Settings > Resources > WSL Integration"),". Make sure to hit 'Apply & Restart'."),(0,l.kt)("p",null,(0,l.kt)("img",{alt:"Docker Desktop WSL Distro",src:n(5238).Z,width:"1918",height:"1033"})),(0,l.kt)("h2",{id:"enable-systemd-in-wsl"},"Enable systemd in WSL"),(0,l.kt)("p",null,"Inside your Ubuntu instance, add the following modification to ",(0,l.kt)("inlineCode",{parentName:"p"},"/etc/wsl.conf"),"."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-conf"},"[boot]\nsystemd=true\n")),(0,l.kt)("p",null,"Then restart your instance by running ",(0,l.kt)("inlineCode",{parentName:"p"},"wsl --shutdown")," in PowerShell and relaunching Ubuntu. Upon launch you should have systemd running. You can check this with the command ",(0,l.kt)("inlineCode",{parentName:"p"},"systemctl list-unit-files --type=service")," which should show your services status."),(0,l.kt)("p",null,"You can read more about this on ",(0,l.kt)("a",{parentName:"p",href:"https://ubuntu.com/blog/ubuntu-wsl-enable-systemd"},"Ubuntu blog")," & ",(0,l.kt)("a",{parentName:"p",href:"https://devblogs.microsoft.com/commandline/systemd-support-is-now-available-in-wsl/"},"Microsoft blog"),"."),(0,l.kt)("h2",{id:"enable-localhostforwarding-in-wsl"},"Enable localhostForwarding in WSL"),(0,l.kt)("p",null,"Create or update ",(0,l.kt)("inlineCode",{parentName:"p"},".wslconfig")," file located at ",(0,l.kt)("inlineCode",{parentName:"p"},"C:\\Users\\{USER_NAME}\\.wslconfig")," (Or ",(0,l.kt)("inlineCode",{parentName:"p"},"%UserProfile%\\.wslconfig"),") with following content:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-conf"},"[wsl2]\nlocalhostForwarding=true\n")),(0,l.kt)("p",null,"This requires WSL shutdown and reboot. Shutting down your terminal is insufficient. Also machine boot is not required. Simply run:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"wsl --shutdown (in Powershell) or \nwsl.exe --shutdown (within Ubuntu)\n")),(0,l.kt)("p",null,"Reference: ",(0,l.kt)("a",{parentName:"p",href:"https://stackoverflow.com/a/65707003/2077741"},"Custom hostname for servers running in WSL 2")),(0,l.kt)("h2",{id:"install-node"},"Install Node"),(0,l.kt)("p",null,"In your WSL Ubuntu terminal, if node (",(0,l.kt)("inlineCode",{parentName:"p"},"node --version"),") isn't already installed on your machine. You can do so by first installing ",(0,l.kt)("inlineCode",{parentName:"p"},"nvm")," by running following commands:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},'curl https://raw.githubusercontent.com/creationix/nvm/master/install.sh | bash\nsource ~/.profile\n\nexport NVM_DIR="$HOME/.nvm"\n[ -s "$NVM_DIR/nvm.sh" ] && \\. "$NVM_DIR/nvm.sh" # This loads nvm\n[ -s "$NVM_DIR/bash_completion" ] && \\. "$NVM_DIR/bash_completion" # This loads nvm bash_completion\n')),(0,l.kt)("p",null,"You can verify nvm by using ",(0,l.kt)("inlineCode",{parentName:"p"},"nvm --version")," command. Afterwards, install node by using:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"nvm install --lts\n")),(0,l.kt)("p",null,"You can verify nvm by using ",(0,l.kt)("inlineCode",{parentName:"p"},"node --version")," command."),(0,l.kt)("h2",{id:"install-python-3"},"Install Python 3"),(0,l.kt)("p",null,"In your WSL Ubuntu terminal, if python 3 (",(0,l.kt)("inlineCode",{parentName:"p"},"pip3 --version"),") isn't already installed on your machine. You can do so by running following commands:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt-get update -y\nsudo apt-get install -y python3-pip\n")),(0,l.kt)("p",null,"You can verify python3 by using ",(0,l.kt)("inlineCode",{parentName:"p"},"python3 --version")," command."),(0,l.kt)("h2",{id:"install-make"},"Install Make"),(0,l.kt)("p",null,"In your WSL Ubuntu terminal, if make (",(0,l.kt)("inlineCode",{parentName:"p"},"make --version"),") isn't already installed on your machine. You can do so by running following commands:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo apt-get update -y\nsudo apt-get install -y build-essential\n")),(0,l.kt)("p",null,"You can verify make by using ",(0,l.kt)("inlineCode",{parentName:"p"},"make --version")," command."),(0,l.kt)("h2",{id:"install-kubectl-and-helm"},"Install kubectl and Helm"),(0,l.kt)("p",null,"In your WSL Ubuntu terminal, if ",(0,l.kt)("a",{parentName:"p",href:"https://kubernetes.io/docs/tasks/tools/"},"kubectl")," & ",(0,l.kt)("a",{parentName:"p",href:"https://helm.sh/docs/intro/install/"},"Helm")," aren't already installed on your machine, install them."),(0,l.kt)("p",null,'Docker & Docker Compose should be installed if you successfully completed "',(0,l.kt)("a",{parentName:"p",href:"#install-docker-desktop"},"Install Docker Desktop"),'" step. You can verify by running ',(0,l.kt)("inlineCode",{parentName:"p"},"docker --version")," & ",(0,l.kt)("inlineCode",{parentName:"p"},"docker-compose --version")," commands in WSL Ubuntu terminal."),(0,l.kt)("h2",{id:"download-and-install-microk8s"},"Download and install MicroK8s"),(0,l.kt)("p",null,"Make sure to install MicroK8s in your WSL Ubuntu terminal. Instructions can be found ",(0,l.kt)("a",{parentName:"p",href:"https://ubuntu.com/tutorials/install-a-local-kubernetes-with-microk8s#1-overview"},"here")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo snap install microk8s --classic --channel=1.26/stable\n")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"Due to some ongoing issue with host storage access in microk8s 1.25 version, it is recommended to use version 1.26.")),(0,l.kt)("p",null,"While you can follow the demo instructions there about starting MicroK8s, deploying some demo deployments, etc. to get a feel for it."),(0,l.kt)("h2",{id:"clone-ethereal-engine-repo-to-your-local-machine"},"Clone Ethereal Engine repo to your local machine"),(0,l.kt)("p",null,"To build the Ethereal Engine Docker image locally, and to have a pre-tested way to run various local services, you'll need to get the Ethereal Engine repo on your machine. This is most easily done by running following command in WSL Ubuntu terminal."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"git clone https://github.com/etherealengine/etherealengine.git etherealengine\n")),(0,l.kt)("p",null,"If ",(0,l.kt)("inlineCode",{parentName:"p"},".env.local")," file does not exist in the root of your repo folder then create it by duplicating ",(0,l.kt)("inlineCode",{parentName:"p"},".env.local.default"),"."),(0,l.kt)("h2",{id:"start-minio--mariadb-server-locally-via-docker"},"Start MinIO & MariaDB server locally via Docker"),(0,l.kt)("p",null,"For simplicity, we recommend running MinIO & MariaDB server on your local machine outside of MicroK8s."),(0,l.kt)("p",null,"If you run ",(0,l.kt)("inlineCode",{parentName:"p"},"docker-compose up")," from the top-level ",(0,l.kt)("inlineCode",{parentName:"p"},"/scripts")," directory in the Ethereal Engine repo, it will start up MinIO & multiple MariaDB docker containers (as well as a redis server, which is not needed). For mariadb containers, one is intended for local development, runs on port 3306; another, intended for automated testing purposes, runs on port 3305; and the last one, intended for minikube/microk8s testing, runs on port 3304. Once the docker container is stopped, you can start it again by running ",(0,l.kt)("inlineCode",{parentName:"p"},"npm run dev-docker"),"."),(0,l.kt)("p",null,"Alternatively, if you want to just run MinIO & MariaDB on its own without Docker, that's fine too. You'll just have to configure the Helm config file to have the appropriate S3 & SQL server configuration, and possibly change the script ",(0,l.kt)("inlineCode",{parentName:"p"},"./scripts/build_microk8s.sh"),"."),(0,l.kt)("h2",{id:"enabling-microk8s-addons"},"Enabling MicroK8s Addons"),(0,l.kt)("p",null,"Execute following command in your WSL Ubuntu terminal to enable MicroK8s addons"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo microk8s enable dashboard dns registry host-access ingress rbac hostpath-storage helm3\n")),(0,l.kt)("h2",{id:"add-microk8s-to-kubectl"},"Add MicroK8s to Kubectl"),(0,l.kt)("p",null,"First make sure there is no existing configuration for microk8s in your kubectl config. To do so you run ",(0,l.kt)("inlineCode",{parentName:"p"},"kubectl config get-contexts")," command in WSL Ubuntu terminal and see if the output contains microk8s. You can remove the existing configurations using following commands:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl config delete-context microk8s\nkubectl config delete-cluster microk8s-cluster\nkubectl config delete-user microk8s-admin\n")),(0,l.kt)("p",null,"Now, we will add microk8s configuration to kubectl config. We can do this by using following commands in WSL Ubuntu terminal. ",(0,l.kt)("a",{parentName:"p",href:"https://discuss.kubernetes.io/t/use-kubectl-with-microk8s/5313/6"},"Reference")),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl config set-cluster microk8s --server=https://127.0.0.1:16443/ --certificate-authority=/var/snap/microk8s/current/certs/ca.crt\nkubectl config set-credentials microk8s-admin --token=\"$(sudo microk8s kubectl config view --raw -o 'jsonpath={.users[0].user.token}')\"\nkubectl config set-context microk8s --cluster=microk8s --namespace=default --user=microk8s-admin\n")),(0,l.kt)("p",null,"Afterwards you can use this newly create context by executing:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"kubectl config use-context microk8s\n")),(0,l.kt)("p",null,"Now if you run ",(0,l.kt)("inlineCode",{parentName:"p"},"kubectl config get-contexts")," command then microk8s should be current context."),(0,l.kt)("h2",{id:"optional-add-microk8s-to-lens"},"(Optional) Add MicroK8s to Lens"),(0,l.kt)("p",null," If the previous step was performed successfully then you should be able to see MicroK8s cluster in GUI tool ",(0,l.kt)("a",{parentName:"p",href:"https://k8slens.dev/"},"Lens"),". Else you can print the configuration using following command:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"microk8s config\n")),(0,l.kt)("p",null,"In Lens, goto ",(0,l.kt)("inlineCode",{parentName:"p"},"File")," > ",(0,l.kt)("inlineCode",{parentName:"p"},"Add Cluster")," and paste the output of above command to add cluster."),(0,l.kt)("h2",{id:"enable-microk8s-access-for-local-docker"},"Enable MicroK8s access for local docker"),(0,l.kt)("p",null,"For MicroK8s we will be using MicroK8s local ",(0,l.kt)("a",{parentName:"p",href:"https://microk8s.io/docs/registry-built-in"},"registry")),(0,l.kt)("p",null,"Option 1: In Windows, add the following lines to ",(0,l.kt)("inlineCode",{parentName:"p"},"%userprofile%\\.docker\\daemon.json"),". Create this file if it does not already exists."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-json"},'{ \n "insecure-registries" : ["http://microk8s.registry:32000", "microk8s.registry:32000"] \n}\n')),(0,l.kt)("p",null,"Afterwards, restart docker from Powershell: ",(0,l.kt)("inlineCode",{parentName:"p"},"restart-service *docker*")),(0,l.kt)("p",null,"Option 2: Edit configuration as shown in below image. Make sure to hit 'Apply & Restart' after making changes."),(0,l.kt)("p",null,(0,l.kt)("img",{alt:"Docker Desktop Configuration",src:n(7233).Z,width:"1920",height:"1030"})),(0,l.kt)("p",null,"Reference:"),(0,l.kt)("ul",null,(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://stackoverflow.com/a/55352883/2077741"},"daemon.json file in W1indows")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://github.com/docker/docs/blob/62adddbb6b1f8d861c72f6ade2c50977fd57f481/registry/insecure.md#troubleshoot-insecure-registry"},"When using buildkit, http needs to be added")),(0,l.kt)("li",{parentName:"ul"},(0,l.kt)("a",{parentName:"li",href:"https://forums.docker.com/t/restart-docker-service-from-command-line/27331/2"},"Restart Docker service from command line"))),(0,l.kt)("h2",{id:"verify-and-troubleshoot-microk8s"},"Verify and troubleshoot MicroK8s"),(0,l.kt)("p",null,"Run following command and check if there is any warning. Its recommended to fix the warnings for MicroK8s to work properly."),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"sudo microk8s inspect\n")),(0,l.kt)("h2",{id:"update-system-hostfile-to-point-to-microk8s"},"Update system hostfile to point to MicroK8s"),(0,l.kt)("p",null,"You'll need to edit your hostfile to point certain domains to host machine IP address. First you need to find the IP address of your WSL. Run ",(0,l.kt)("inlineCode",{parentName:"p"},"wsl hostname -I")," in powershell/cmd. For example:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-shell"},"C:\\Users\\hanzl>wsl hostname -I\n172.31.89.133 10.1.215.0\n")),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"Note: If you face issue while running above command, make sure that 'Ubuntu' distribution is selected as default. You can do so by running ",(0,l.kt)("inlineCode",{parentName:"p"},"wsl /l")," to view distributions and then run ",(0,l.kt)("inlineCode",{parentName:"p"},"wslconfig /s Ubuntu")," to select distribution.")),(0,l.kt)("p",null,"From the above output, use ",(0,l.kt)("inlineCode",{parentName:"p"},"172.31.89.133")," as ",(0,l.kt)("inlineCode",{parentName:"p"},"{WSL_IP}"),"."),(0,l.kt)("blockquote",null,(0,l.kt)("p",{parentName:"blockquote"},"Note: Your ip would be different, this is just for example.")),(0,l.kt)("p",null,"Next, edit your Windows hostfile, this is done by editing ",(0,l.kt)("inlineCode",{parentName:"p"},"C:\\Windows\\System32\\drivers\\etc\\hosts"),". Add/Update the following lines:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-conf"},"{WSL_IP} local.etherealengine.org api-local.etherealengine.org instanceserver-local.etherealengine.org 00000.instanceserver-local.etherealengine.org 00001.instanceserver-local.etherealengine.org 00002.instanceserver-local.etherealengine.org 00003.instanceserver-local.etherealengine.org\n\n{WSL_IP} microk8s.registry\n")),(0,l.kt)("p",null,"Make sure to replace ",(0,l.kt)("inlineCode",{parentName:"p"},"{WSL_IP}")," with ip address from ",(0,l.kt)("inlineCode",{parentName:"p"},"wsl hostname -I")," command."),(0,l.kt)("p",null,"The first line says to point several *-local.etherealengine.org domains internally to the host machine, where the nginx ingress server will redirect the traffic to the appropriate pod."),(0,l.kt)("p",null,"Make sure to save this file after you've edited it. Also, you will need to update hostfile with updated ip address after every Windows/WSL reboot."),(0,l.kt)("h2",{id:"add-helm-repos"},"Add Helm repos"),(0,l.kt)("p",null,"You'll need to add a few Helm repos. Run the following:"),(0,l.kt)("pre",null,(0,l.kt)("code",{parentName:"pre",className:"language-bash"},"helm repo add agones https://agones.dev/chart/stable\nhelm repo add redis https://charts.bitnami.com/bitnami\nhelm repo add etherealengine https://helm.etherealengine.org\n")),(0,l.kt)("p",null,"This will add the Helm charts for Agones, Redis, and Ethereal Engine, respectively."),(0,l.kt)("h2",{id:"install-agones-and-redis-deployments"},"Install Agones and Redis deployments"),(0,l.kt)("p",null,"After adding those Helm repos, you'll start installing deployments using Helm repos."),(0,l.kt)("p",null,"Make sure that kubectl is pointed at MicroK8s by running ",(0,l.kt)("inlineCode",{parentName:"p"},"kubectl config current-context"),", which should say 'microk8s'. You can also run ",(0,l.kt)("inlineCode",{parentName:"p"},"kubectl config get-contexts")," to get all contexts that kubectl has been configured to run; the current one will have a '*' under the left-most\n'current' column."),(0,l.kt)("p",null,"Once kubectl is pointed to microk8s, from the top of the Ethereal Engine repo, run ",(0,l.kt)("inlineCode",{parentName:"p"},"helm install -f