Current configured baseUrl = '+e+" "+("/"===e?" (default value)":"")+'
\n
We suggest trying baseUrl =
\n\n'}(e)).replace(/=0||Object.prototype.hasOwnProperty.call(e,r)&&(n[r]=e[r]);return n},H=function(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t},W=function(e){var t=!(arguments.length>1&&void 0!==arguments[1])||arguments[1];return!1===t?String(e):String(e).replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")},V=function(e){var t=X(e,y.TITLE),n=X(e,F);if(n&&t)return n.replace(/%s/g,(function(){return Array.isArray(t)?t.join(""):t}));var r=X(e,N);return t||r||void 0},Z=function(e){return X(e,D)||function(){}},K=function(e,t){return t.filter((function(t){return void 0!==t[e]})).map((function(t){return t[e]})).reduce((function(e,t){return G({},e,t)}),{})},Y=function(e,t){return t.filter((function(e){return void 0!==e[y.BASE]})).map((function(e){return e[y.BASE]})).reverse().reduce((function(t,n){if(!t.length)for(var r=Object.keys(n),i=0;i=0;n--){var r=e[n];if(r.hasOwnProperty(t))return r[t]}return null},J=(r=Date.now(),function(e){var t=Date.now();t-r>16?(r=t,e(t)):setTimeout((function(){J(e)}),0)}),ee=function(e){return clearTimeout(e)},te="undefined"!=typeof window?window.requestAnimationFrame&&window.requestAnimationFrame.bind(window)||window.webkitRequestAnimationFrame||window.mozRequestAnimationFrame||J:n.g.requestAnimationFrame||J,ne="undefined"!=typeof window?window.cancelAnimationFrame||window.webkitCancelAnimationFrame||window.mozCancelAnimationFrame||ee:n.g.cancelAnimationFrame||ee,re=function(e){return console&&"function"==typeof console.warn&&console.warn(e)},ie=null,oe=function(e,t){var n=e.baseTag,r=e.bodyAttributes,i=e.htmlAttributes,o=e.linkTags,a=e.metaTags,l=e.noscriptTags,u=e.onChangeClientState,s=e.scriptTags,c=e.styleTags,d=e.title,f=e.titleAttributes;ue(y.BODY,r),ue(y.HTML,i),le(d,f);var p={baseTag:se(y.BASE,n),linkTags:se(y.LINK,o),metaTags:se(y.META,a),noscriptTags:se(y.NOSCRIPT,l),scriptTags:se(y.SCRIPT,s),styleTags:se(y.STYLE,c)},m={},h={};Object.keys(p).forEach((function(e){var t=p[e],n=t.newTags,r=t.oldTags;n.length&&(m[e]=n),r.length&&(h[e]=p[e].oldTags)})),t&&t(),u(e,m,h)},ae=function(e){return Array.isArray(e)?e.join(""):e},le=function(e,t){void 0!==e&&document.title!==e&&(document.title=ae(e)),ue(y.TITLE,t)},ue=function(e,t){var n=document.getElementsByTagName(e)[0];if(n){for(var r=n.getAttribute(B),i=r?r.split(","):[],o=[].concat(i),a=Object.keys(t),l=0;l=0;d--)n.removeAttribute(o[d]);i.length===o.length?n.removeAttribute(B):n.getAttribute(B)!==a.join(",")&&n.setAttribute(B,a.join(","))}},se=function(e,t){var n=document.head||document.querySelector(y.HEAD),r=n.querySelectorAll(e+"["+"data-react-helmet]"),i=Array.prototype.slice.call(r),o=[],a=void 0;return t&&t.length&&t.forEach((function(t){var n=document.createElement(e);for(var r in t)if(t.hasOwnProperty(r))if(r===x)n.innerHTML=t.innerHTML;else if(r===k)n.styleSheet?n.styleSheet.cssText=t.cssText:n.appendChild(document.createTextNode(t.cssText));else{var l=void 0===t[r]?"":t[r];n.setAttribute(r,l)}n.setAttribute(B,"true"),i.some((function(e,t){return a=t,n.isEqualNode(e)}))?i.splice(a,1):o.push(n)})),i.forEach((function(e){return e.parentNode.removeChild(e)})),o.forEach((function(e){return n.appendChild(e)})),{oldTags:i,newTags:o}},ce=function(e){return Object.keys(e).reduce((function(t,n){var r=void 0!==e[n]?n+'="'+e[n]+'"':""+n;return t?t+" "+r:r}),"")},de=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce((function(t,n){return t[R[n]||n]=e[n],t}),t)},fe=function(e,t,n){switch(e){case y.TITLE:return{toComponent:function(){return e=t.title,n=t.titleAttributes,(r={key:e})[B]=!0,i=de(n,r),[l.createElement(y.TITLE,i,e)];var e,n,r,i},toString:function(){return function(e,t,n,r){var i=ce(n),o=ae(t);return i?"<"+e+' data-react-helmet="true" '+i+">"+W(o,r)+""+e+">":"<"+e+' data-react-helmet="true">'+W(o,r)+""+e+">"}(e,t.title,t.titleAttributes,n)}};case g:case b:return{toComponent:function(){return de(t)},toString:function(){return ce(t)}};default:return{toComponent:function(){return function(e,t){return t.map((function(t,n){var r,i=((r={key:n})[B]=!0,r);return Object.keys(t).forEach((function(e){var n=R[e]||e;if(n===x||n===k){var r=t.innerHTML||t.cssText;i.dangerouslySetInnerHTML={__html:r}}else i[n]=t[e]})),l.createElement(e,i)}))}(e,t)},toString:function(){return function(e,t,n){return t.reduce((function(t,r){var i=Object.keys(r).filter((function(e){return!(e===x||e===k)})).reduce((function(e,t){var i=void 0===r[t]?t:t+'="'+W(r[t],n)+'"';return e?e+" "+i:i}),""),o=r.innerHTML||r.cssText||"",a=-1===j.indexOf(e);return t+"<"+e+' data-react-helmet="true" '+i+(a?"/>":">"+o+""+e+">")}),"")}(e,t,n)}}}},pe=function(e){var t=e.baseTag,n=e.bodyAttributes,r=e.encode,i=e.htmlAttributes,o=e.linkTags,a=e.metaTags,l=e.noscriptTags,u=e.scriptTags,s=e.styleTags,c=e.title,d=void 0===c?"":c,f=e.titleAttributes;return{base:fe(y.BASE,t,r),bodyAttributes:fe(g,n,r),htmlAttributes:fe(b,i,r),link:fe(y.LINK,o,r),meta:fe(y.META,a,r),noscript:fe(y.NOSCRIPT,l,r),script:fe(y.SCRIPT,u,r),style:fe(y.STYLE,s,r),title:fe(y.TITLE,{title:d,titleAttributes:f},r)}},me=d()((function(e){return{baseTag:Y([E,A],e),bodyAttributes:K(g,e),defer:X(e,L),encode:X(e,I),htmlAttributes:K(b,e),linkTags:Q(y.LINK,[_,E],e),metaTags:Q(y.META,[C,w,S,P,T],e),noscriptTags:Q(y.NOSCRIPT,[x],e),onChangeClientState:Z(e),scriptTags:Q(y.SCRIPT,[O,x],e),styleTags:Q(y.STYLE,[k],e),title:V(e),titleAttributes:K(v,e)}}),(function(e){ie&&ne(ie),e.defer?ie=te((function(){oe(e,(function(){ie=null}))})):(oe(e),ie=null)}),pe)((function(){return null})),he=(i=me,a=o=function(e){function t(){return U(this,t),H(this,e.apply(this,arguments))}return function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}(t,e),t.prototype.shouldComponentUpdate=function(e){return!p()(this.props,e)},t.prototype.mapNestedChildrenToProps=function(e,t){if(!t)return null;switch(e.type){case y.SCRIPT:case y.NOSCRIPT:return{innerHTML:t};case y.STYLE:return{cssText:t}}throw new Error("<"+e.type+" /> elements are self-closing and can not contain children. Refer to our API for more information.")},t.prototype.flattenArrayTypeChildren=function(e){var t,n=e.child,r=e.arrayTypeChildren,i=e.newChildProps,o=e.nestedChildren;return G({},r,((t={})[n.type]=[].concat(r[n.type]||[],[G({},i,this.mapNestedChildrenToProps(n,o))]),t))},t.prototype.mapObjectTypeChildren=function(e){var t,n,r=e.child,i=e.newProps,o=e.newChildProps,a=e.nestedChildren;switch(r.type){case y.TITLE:return G({},i,((t={})[r.type]=a,t.titleAttributes=G({},o),t));case y.BODY:return G({},i,{bodyAttributes:G({},o)});case y.HTML:return G({},i,{htmlAttributes:G({},o)})}return G({},i,((n={})[r.type]=G({},o),n))},t.prototype.mapArrayTypeChildrenToProps=function(e,t){var n=G({},t);return Object.keys(e).forEach((function(t){var r;n=G({},n,((r={})[t]=e[t],r))})),n},t.prototype.warnOnInvalidChildren=function(e,t){return!0},t.prototype.mapChildrenToProps=function(e,t){var n=this,r={};return l.Children.forEach(e,(function(e){if(e&&e.props){var i=e.props,o=i.children,a=function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};return Object.keys(e).reduce((function(t,n){return t[M[n]||n]=e[n],t}),t)}(q(i,["children"]));switch(n.warnOnInvalidChildren(e,o),e.type){case y.LINK:case y.META:case y.NOSCRIPT:case y.SCRIPT:case y.STYLE:r=n.flattenArrayTypeChildren({child:e,arrayTypeChildren:r,newChildProps:a,nestedChildren:o});break;default:t=n.mapObjectTypeChildren({child:e,newProps:t,newChildProps:a,nestedChildren:o})}}})),t=this.mapArrayTypeChildrenToProps(r,t)},t.prototype.render=function(){var e=this.props,t=e.children,n=q(e,["children"]),r=G({},n);return t&&(r=this.mapChildrenToProps(t,r)),l.createElement(i,r)},$(t,null,[{key:"canUseDOM",set:function(e){i.canUseDOM=e}}]),t}(l.Component),o.propTypes={base:s().object,bodyAttributes:s().object,children:s().oneOfType([s().arrayOf(s().node),s().node]),defaultTitle:s().string,defer:s().bool,encodeSpecialCharacters:s().bool,htmlAttributes:s().object,link:s().arrayOf(s().object),meta:s().arrayOf(s().object),noscript:s().arrayOf(s().object),onChangeClientState:s().func,script:s().arrayOf(s().object),style:s().arrayOf(s().object),title:s().string,titleAttributes:s().object,titleTemplate:s().string},o.defaultProps={defer:!0,encodeSpecialCharacters:!0},o.peek=i.peek,o.rewind=function(){var e=i.rewind();return e||(e=pe({baseTag:[],bodyAttributes:{},encodeSpecialCharacters:!0,htmlAttributes:{},linkTags:[],metaTags:[],noscriptTags:[],scriptTags:[],styleTags:[],title:"",titleAttributes:{}})),e},a);he.renderStatic=he.rewind;var ge=function(e){return l.createElement(he,Object.assign({},e))}},4748:function(e,t,n){"use strict";var r=n(7294);t.Z=r.createContext(null)},6291:function(e,t,n){"use strict";var r=n(8790);t.Z=r.H},2263:function(e,t,n){"use strict";var r=n(7294),i=n(4748);t.Z=function(){var e=(0,r.useContext)(i.Z);if(null===e)throw new Error("Docusaurus context not provided");return e}},2203:function(e,t,n){"use strict";function r(e,t){e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e.__proto__=t}function i(e){if(void 0===e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return e}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(){return a=Object.assign||function(e){for(var t=1;t=0;f--){var p=a[f];"."===p?o(a,f):".."===p?(o(a,f),d++):d&&(o(a,f),d--)}if(!s)for(;d--;d)a.unshift("..");!s||""===a[0]||a[0]&&i(a[0])||a.unshift("");var m=a.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};function l(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}var u=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"==typeof t||"object"==typeof n){var r=l(t),i=l(n);return r!==t||i!==n?e(r,i):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1},s=n(2177);function c(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function f(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 p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function m(e){var t=e.pathname,n=e.search,r=e.hash,i=t||"/";return n&&"?"!==n&&(i+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(i+="#"===r.charAt(0)?r:"#"+r),i}function h(e,t,n,i){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",i=t.indexOf("#");-1!==i&&(r=t.substr(i),t=t.substr(0,i));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),i?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=a(o.pathname,i.pathname)):o.pathname=i.pathname:o.pathname||(o.pathname="/"),o}function g(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&u(e.state,t.state)}function b(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,i){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,i):i(!0):i(!1!==o)}else i(!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,i):n.push(i),d({action:r,location:i,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",i=h(e,t,f(),w.location);c.confirmTransitionTo(i,r,n,(function(e){e&&(w.entries[w.index]=i,d({action:r,location:i}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=w.index+e;return t>=0&&t
'};function i(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function a(e,t,n){var i;return(i="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,i}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=i(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),s=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),u(s,a(e,c,d)),1===e?(u(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){u(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)*i(Math.random()*t,.1,.95)),t=i(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 i,a=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),s=document.querySelector(r.parent);return u(a,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(i=t.querySelector(r.spinnerSelector))&&p(i),s!=document.body&&c(s,"nprogress-custom-parent"),s.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()}}(),u=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,i=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);i--;)if((r=e[i]+o)in n)return r;return t}function i(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=i(t),e.style[t]=n}return function(e,t){var n,r,i=arguments;if(2==i.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,i[1],i[2])}}();function s(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;s(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);s(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===(i="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=i)},7418:function(e){"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function i(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}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(i){return!1}}()?Object.assign:function(e,o){for(var a,l,u=i(e),s=1;se.length)return;if(!(k instanceof u)){if(h&&y!=t.length-1){if(f.lastIndex=w,!(P=f.exec(e)))break;for(var E=P.index+(m?P[1].length:0),S=P.index+P[0].length,x=y,T=w,C=t.length;x=(T+=t[x].length)&&(++y,w=T);if(t[y]instanceof u)continue;_=x-y,k=e.slice(w,T),P.index-=w}else{f.lastIndex=0;var P=f.exec(k),_=1}if(P){m&&(g=P[1]?P[1].length:0),S=(E=P.index+g)+(P=P[0].slice(g)).length;var O=k.slice(0,E),A=k.slice(S),R=[y,_];O&&(++y,w+=O.length,R.push(O));var N=new u(s,p?r.tokenize(P,p):P,b,P,h);if(R.push(N),A&&R.push(A),Array.prototype.splice.apply(t,R),1!=_&&r.matchGrammar(e,t,n,y,w,!0,s),a)break}else if(a)break}}}}},hooks:{add:function(){},run:function(e,t){}},tokenize:function(e,t,n){var i=[e],o=t.rest;if(o){for(var a in o)t[a]=o[a];delete t.rest}return r.matchGrammar(e,i,t,0,0,!1),i}},(i=r.Token=function(e,t,n,r,i){this.type=e,this.content=t,this.alias=n,this.length=0|(r||"").length,this.greedy=!!i}).stringify=function(e,t,n){if("string"==typeof e)return e;if("Array"===r.util.type(e))return e.map((function(n){return i.stringify(n,t,e)})).join("");var o={type:e.type,content:i.stringify(e.content,t,n),tag:"span",classes:["token",e.type],attributes:{},language:t,parent:n};if(e.alias){var a="Array"===r.util.type(e.alias)?e.alias:[e.alias];Array.prototype.push.apply(o.classes,a)}var l=Object.keys(o.attributes).map((function(e){return e+'="'+(o.attributes[e]||"").replace(/"/g,""")+'"'})).join(" ");return"<"+o.tag+' class="'+o.classes.join(" ")+'"'+(l?" "+l:"")+">"+o.content+""+o.tag+">"},r);o.languages.markup={comment://,prolog:/<\?[\s\S]+?\?>/,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/,name:/[^\s<>'"]+/}},cdata://i,tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"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"},/?[\da-f]{1,8};/i]},o.languages.markup.tag.inside["attr-value"].inside.entity=o.languages.markup.entity,o.languages.markup.doctype.inside["internal-subset"].inside=o.languages.markup,o.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(o.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:o.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:o.languages[t]};var i={};i[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},o.languages.insertBefore("markup","cdata",i)}}),o.languages.html=o.languages.markup,o.languages.mathml=o.languages.markup,o.languages.svg=o.languages.markup,o.languages.xml=o.languages.extend("markup",{}),o.languages.ssml=o.languages.xml,o.languages.atom=o.languages.xml,o.languages.rss=o.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}|x[0-9a-fA-F]{1,2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})/};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]|\$\([^)]+\)|\$(?!\()|`[^`]+`|(?!\2)[^\\`$])*\2/,lookbehind:!0,greedy:!0,inside:r}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|aptitude|apt-cache|apt-get|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|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|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|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|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;|&]|[<>]\()(?:if|then|else|elif|fi|for|while|in|case|esac|function|select|do|done|until)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|break|cd|continue|eval|exec|exit|export|getopts|hash|pwd|readonly|return|shift|test|times|trap|umask|unset|alias|bind|builtin|caller|command|declare|echo|enable|help|let|local|logout|mapfile|printf|read|readarray|source|type|typeset|ulimit|unalias|set|shopt)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:true|false)(?=$|[)\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 i=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,a=0;a]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},o.languages.c=o.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,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(?:__attribute__|_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|asm|typeof|inline|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|union|unsigned|void|volatile|while)\b/,function:/[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|[?:~]|[-+*/%&|^!=<>]=?/}),o.languages.insertBefore("c","string",{macro:{pattern:/(^\s*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},o.languages.c.string],comment:o.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:o.languages.c}}},constant:/\b(?:__FILE__|__LINE__|__DATE__|__TIME__|__TIMESTAMP__|__func__|EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|stdin|stdout|stderr)\b/}),delete o.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char8_t|char16_t|char32_t|class|compl|concept|const|consteval|constexpr|constinit|const_cast|continue|co_await|co_return|co_yield|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|float|for|friend|goto|if|inline|int|int8_t|int16_t|int32_t|int64_t|uint8_t|uint16_t|uint32_t|uint64_t|long|mutable|namespace|new|noexcept|nullptr|operator|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|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/;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,/\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:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:true|false)\b/}),e.languages.insertBefore("cpp","string",{"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),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","operator",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(o),function(e){var t=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;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:RegExp("[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),string:{pattern:t,greedy:!0},property:/(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,important:/!important\b/i,function:/[-a-z0-9]+(?=\()/i,punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),e.languages.insertBefore("inside","attr-value",{"style-attr":{pattern:/(^|["'\s])style\s*=\s*(?:"[^"]*"|'[^']*')/i,lookbehind:!0,inside:{"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{style:{pattern:/(["'])[\s\S]+(?=["']$)/,lookbehind:!0,alias:"language-css",inside:e.languages.css},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},"attr-name":/^style/i}}},n.tag))}(o),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector,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]+\b)/,lookbehind:!0},i={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#(?:[\da-f]{1,2}){3,4}\b/i,alias:"color"},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(?:rgb|hsl)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:rgb|hsl)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:i,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:i})}(o),o.languages.javascript=o.languages.extend("clike",{"class-name":[o.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:prototype|constructor))/,lookbehind:!0}],keyword:[{pattern:/((?:^|})\s*)(?:catch|finally)\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|for|from|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:/\b(?:(?:0[xX](?:[\dA-Fa-f](?:_[\dA-Fa-f])?)+|0[bB](?:[01](?:_[01])?)+|0[oO](?:[0-7](?:_[0-7])?)+)n?|(?:\d(?:_\d)?)+n|NaN|Infinity)\b|(?:\b(?:\d(?:_\d)?)+\.?(?:\d(?:_\d)?)*|\B\.(?:\d(?:_\d)?)+)(?:[Ee][+-]?(?:\d(?:_\d)?)+)?/,operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),o.languages.javascript["class-name"][0].pattern=/(\b(?:class|interface|extends|implements|instanceof|new)\s+)[\w.\\]+/,o.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*]|\\.|[^/\\\[\r\n])+\/[gimyus]{0,6}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:o.languages.regex},"regex-flags":/[a-z]+$/,"regex-delimiter":/^\/|\/$/}},"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:o.languages.javascript},{pattern:/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,inside:o.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:o.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:o.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),o.languages.insertBefore("javascript","string",{"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:o.languages.javascript}},string:/[\s\S]+/}}}),o.languages.markup&&o.languages.markup.tag.addInlined("script","javascript"),o.languages.js=o.languages.javascript,function(e){var t=e.util.clone(e.languages.javascript);e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=/<\/?(?:[\w.:-]+(?:\s+(?:[\w.:$-]+(?:=(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s{'">=]+|\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])+\}))?|\{\s*\.{3}\s*[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\s*\}))*\s*\/?)?>/i,e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/i,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[^]|[^\\"])*"|'(?:\\[^]|[^\\'])*'|[^\s'">]+)/i,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.insertBefore("inside","attr-name",{spread:{pattern:/\{\s*\.{3}\s*[a-z_$][\w$]*(?:\.[a-z_$][\w$]*)*\s*\}/,inside:{punctuation:/\.{3}|[{}.]/,"attr-value":/\w+/}}},e.languages.jsx.tag),e.languages.insertBefore("inside","attr-value",{script:{pattern:/=(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])+\})/i,inside:{"script-punctuation":{pattern:/^=(?={)/,alias:"punctuation"},rest:e.languages.jsx},alias:"language-javascript"}},e.languages.jsx.tag);var n=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(n).join(""):""},r=function(t){for(var i=[],o=0;o0&&i[i.length-1].tagName===n(a.content[0].content[1])&&i.pop():"/>"===a.content[a.content.length-1].content||i.push({tagName:n(a.content[0].content[1]),openedBraces:0}):i.length>0&&"punctuation"===a.type&&"{"===a.content?i[i.length-1].openedBraces++:i.length>0&&i[i.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?i[i.length-1].openedBraces--:l=!0),(l||"string"==typeof a)&&i.length>0&&0===i[i.length-1].openedBraces){var u=n(a);o0&&("string"==typeof t[o-1]||"plain-text"===t[o-1].type)&&(u=n(t[o-1])+u,t.splice(o-1,1),o--),t[o]=new e.Token("plain-text",u,null,u)}a.content&&"string"!=typeof a.content&&r(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||r(e.tokens)}))}(o),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(?:(?:(?:Uint|Int)(?:8|16|32)|Uint8Clamped|Float(?:32|64))?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|(?:Weak)?(?:Set|Map)|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|for|finally|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|location|navigator|performance|(?:local|session)Storage|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",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],i=[];/^\w+$/.test(n)||i.push(/\w+/.exec(n)[0]),"diff"===n&&i.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:i,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})}(o),o.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/m,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/m}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},o.languages.go=o.languages.extend("clike",{string:{pattern:/(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,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(?:_|iota|nil|true|false)\b/,number:/(?:\b0x[a-f\d]+|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[-+]?\d+)?)i?/i,operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:bool|byte|complex(?:64|128)|error|float(?:32|64)|rune|string|u?int(?:8|16|32|64)?|uintptr|append|cap|close|complex|copy|delete|imag|len|make|new|panic|print(?:ln)?|real|recover)\b/}),delete o.languages.go["class-name"],o.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:o.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:true|false)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*)[a-zA-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[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}/,punctuation:/[!(){}\[\]:=,]/,constant:/\b(?!ID\b)[A-Z][A-Z_\d]*\b/},function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,i,o){if(n.language===r){var a=n.tokenStack=[];n.code=n.code.replace(i,(function(e){if("function"==typeof o&&!o(e))return e;for(var i,l=a.length;-1!==n.code.indexOf(i=t(r,l));)++l;return a[l]=e,i})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var i=0,o=Object.keys(n.tokenStack);!function a(l){for(var u=0;u=o.length);u++){var s=l[u];if("string"==typeof s||s.content&&"string"==typeof s.content){var c=o[i],d=n.tokenStack[c],f="string"==typeof s?s:s.content,p=t(r,c),m=f.indexOf(p);if(m>-1){++i;var h=f.substring(0,m),g=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=f.substring(m+p.length),v=[];h&&v.push.apply(v,a([h])),v.push(g),b&&v.push.apply(v,a([b])),"string"==typeof s?l.splice.apply(l,[u,1].concat(v)):s.content=v}}else s.content&&a(s.content)}return l}(n.tokens)}}}})}(o),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/i,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:true|false)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/i,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")}))}(o),o.languages.json={property:{pattern:/"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,greedy:!0},string:{pattern:/"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},o.languages.webmanifest=o.languages.json,o.languages.less=o.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*:)/i,operator:/[+\-*\/]/}),o.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),o.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:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,symbol:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,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/,{pattern:/(\()(?:addsuffix|abspath|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(?:s|list)?)(?=[ \t])/,lookbehind:!0}],operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?!\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,i=/\|?__(?:\|__)+\|?(?:(?:\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:/^---|---$/,"font-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+i+o+"(?:"+i+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+i+o+")(?:"+i+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+i+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+i+"$"),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:/``.+?``|`[^`\r\n]+`/,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:/~~?/}},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"].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]?|\+\+?|!=?|<=?|>>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete o.languages.objectivec["class-name"],o.languages.objc=o.languages.objectivec,o.languages.ocaml={comment:/\(\*[\s\S]*?\*\)/,string:[{pattern:/"(?:\\.|[^\\\r\n"])*"/,greedy:!0},{pattern:/(['`])(?:\\(?:\d+|x[\da-f]+|.)|(?!\1)[^\\\r\n])\1/i,greedy:!0}],number:/\b(?:0x[\da-f][\da-f_]+|(?:0[bo])?\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?[\d_]+)?)/i,directive:{pattern:/\B#\w+/,alias:"important"},label:{pattern:/\B~\w+/,alias:"function"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"variable"},module:{pattern:/\b[A-Z]\w+/,alias:"variable"},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:/:=|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/[(){}\[\]|.,:;]|\b_\b/},o.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0},"string-interpolation":{pattern:/(?:f|rf|fr)(?:("""|''')[\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]|rb|br)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|rb|br)?("|')(?:\\.|(?!\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:/(^\s*)@\w+(?:\.\w+)*/im,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:and|as|assert|async|await|break|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|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(?:True|False|None)\b/,number:/(?:\b(?=\d)|\B(?=\.))(?:0[bo])?(?:(?:\d|0x[\da-f])[\da-f]*(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?j?\b/i,operator:/[-+%=]=?|!=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},o.languages.python["string-interpolation"].inside.interpolation.inside.rest=o.languages.python,o.languages.py=o.languages.python,o.languages.reason=o.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(?:mod|land|lor|lxor|lsl|lsr|asr)\b/}),o.languages.insertBefore("reason","class-name",{character:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,alias:"string"},constructor:{pattern:/\b[A-Z]\w*\b(?!\s*\.)/,alias:"variable"},label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete o.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,inside:{atrule:/(?:@[\w-]+|[+=])/m}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|or|not)\b/,{pattern:/(\s+)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,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]+)*)*/,lookbehind:!0}})}(o),o.languages.scss=o.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|[^}][^:{}]*[:{][^}]+))/m,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),o.languages.insertBefore("scss","atrule",{keyword:[/@(?:if|else(?: if)?|forward|for|each|while|import|use|extend|debug|warn|mixin|include|function|return|content)\b/i,{pattern:/( +)(?:from|through)(?= )/,lookbehind:!0}]}),o.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),o.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|with|show|hide)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:true|false)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|or|not)(?=\s)/,lookbehind:!0}}),o.languages.scss.atrule.inside.rest=o.languages.scss,o.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:_INSERT|COL)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:S|ING)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:TRUE|FALSE|NULL)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|IN|LIKE|NOT|OR|IS|DIV|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},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:/url\((["']?).*?\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+)(?:(?:if|else|for|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(?:rgb|hsl)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:rgb|hsl)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(?:true|false)\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:/(^\s*)@.+/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]*)(?:if|else|for|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:/[{}()\[\];:.]/}}(o),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},keyword:/\b(?:abstract|as|asserts|async|await|break|case|catch|class|const|constructor|continue|debugger|declare|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|is|keyof|let|module|namespace|new|null|of|package|private|protected|public|readonly|return|require|set|static|super|switch|this|throw|try|type|typeof|undefined|var|void|while|with|yield)\b/,builtin:/\b(?:string|Function|any|number|boolean|Array|symbol|console|Promise|unknown|never)\b/}),delete e.languages.typescript.parameter;var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{"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}(o),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t);var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(o),o.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|nearest|neg?|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|store(?:8|16|32)?|sqrt|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!#$%&'*+\-./:<=>?@\\^_`|~]+/i,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:/[()]/},function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",i=/(?:[^\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 a(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"(?:"+i+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:a(/\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:a(/true|false/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:a(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:a(o),lookbehind:!0,greedy:!0},number:{pattern:a(/[+-]?(?: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}(o),t.Z=o},9901:function(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",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},bash:{title:"Bash",alias:"shell",aliasTitles:{shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},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"},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"},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"},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"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},go:{title:"Go",require:"clike",owner:"arnehormann"},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",owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},http:{title:"HTTP",optional:["css","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"},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"},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",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},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"},matlab:{title:"MATLAB",owner:"Golmote"},mel:{title:"MEL",owner:"Golmote"},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"},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"},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"},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"},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",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",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"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},swift:{title:"Swift",require:"clike",owner:"chrischares"},"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"},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup",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"},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"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},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 matched in the code. For example, the keyword if will have the class keyword-if as well. You can have fine grained control over the appearance of each keyword by providing your own CSS rules.",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:function(e,t,n){const r=n(9901),i=n(9642),o=new Set;function a(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)];i(r,e,t).load((e=>{if(!(e in r.languages))return void(a.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)}))}a.silent=!1,e.exports=a},6500:function(e,t,n){var r={"./":2885};function i(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]}i.keys=function(){return Object.keys(r)},i.resolve=o,e.exports=i,i.id=6500},9642:function(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={},u=e[r];if(u){function a(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var a in i(t,o),l[t]=!0,n[t])l[a]=!0}t(u.require,a),t(u.optional,a),t(u.modify,a)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(i(e,r),t=n[e]),t}}function i(e){for(var t in e)return!0;return!1}return function(o,a,l){var u=function(e){var t={};for(var n in e){var r=e[n];for(var i in r)if("meta"!=i){var o=r[i];t[i]="string"==typeof o?{title:o}:o}}return t}(o),s=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var i in n={},e){var o=e[i];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+i+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+i+" because it is a component.");n[t]=i}))}return n[r]||r}}(u);a=a.map(s),l=(l||[]).map(s);var c=n(a),d=n(l);a.forEach((function e(n){var r=u[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var f,p=r(u),m=c;i(m);){for(var h in f={},m){var g=u[h];t(g&&g.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,i){var o=i?i.series:void 0,a=i?i.parallel:e,l={},u={};function s(e){if(e in l)return l[e];u[e]=!0;var i,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)i=r(e);else{var f=a(c.map((function(e){var t=s(e);return delete u[e],t})));o?i=o(f,(function(){return r(e)})):r(e)}return l[e]=i}for(var c in n)s(c);var d=[];for(var f in u)d.push(l[f]);return a(d)}(p,c,t,n)}};return w}}();e.exports=t},2703:function(e,t,n){"use strict";var r=n(414);function i(){}function o(){}o.resetWarningCache=i,e.exports=function(){function e(e,t,n,i,o,a){if(a!==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,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:i};return n.PropTypes=n,n}},5697:function(e,t,n){e.exports=n(2703)()},414:function(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:function(e,t,n){"use strict";var r=n(7294),i=n(7418),o=n(3840);function a(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;nt}return!1}(t,n,i,r)&&(n=null),r||null===i?function(e){return!!G.call(H,e)||!G.call(q,e)&&($.test(e)?H[e]=!0:(q[e]=!0,!1))}(t)&&(null===n?e.removeAttribute(t):e.setAttribute(t,""+n)):i.mustUseProperty?e[i.propertyName]=null===n?3!==i.type&&"":n:(t=i.attributeName,r=i.attributeNamespace,null===n?e.removeAttribute(t):(n=3===(i=i.type)||4===i&&!0===n?"":""+n,r?e.setAttributeNS(r,t,n):e.setAttribute(t,n))))}Y.hasOwnProperty("ReactCurrentDispatcher")||(Y.ReactCurrentDispatcher={current:null}),Y.hasOwnProperty("ReactCurrentBatchConfig")||(Y.ReactCurrentBatchConfig={suspense:null});var X=/^(.*)[\\\/]/,J="function"==typeof Symbol&&Symbol.for,ee=J?Symbol.for("react.element"):60103,te=J?Symbol.for("react.portal"):60106,ne=J?Symbol.for("react.fragment"):60107,re=J?Symbol.for("react.strict_mode"):60108,ie=J?Symbol.for("react.profiler"):60114,oe=J?Symbol.for("react.provider"):60109,ae=J?Symbol.for("react.context"):60110,le=J?Symbol.for("react.concurrent_mode"):60111,ue=J?Symbol.for("react.forward_ref"):60112,se=J?Symbol.for("react.suspense"):60113,ce=J?Symbol.for("react.suspense_list"):60120,de=J?Symbol.for("react.memo"):60115,fe=J?Symbol.for("react.lazy"):60116,pe=J?Symbol.for("react.block"):60121,me="function"==typeof Symbol&&Symbol.iterator;function he(e){return null===e||"object"!=typeof e?null:"function"==typeof(e=me&&e[me]||e["@@iterator"])?e:null}function ge(e){if(null==e)return null;if("function"==typeof e)return e.displayName||e.name||null;if("string"==typeof e)return e;switch(e){case ne:return"Fragment";case te:return"Portal";case ie:return"Profiler";case re:return"StrictMode";case se:return"Suspense";case ce:return"SuspenseList"}if("object"==typeof e)switch(e.$$typeof){case ae:return"Context.Consumer";case oe:return"Context.Provider";case ue:var t=e.render;return t=t.displayName||t.name||"",e.displayName||(""!==t?"ForwardRef("+t+")":"ForwardRef");case de:return ge(e.type);case pe:return ge(e.render);case fe:if(e=1===e._status?e._result:null)return ge(e)}return null}function be(e){var t="";do{e:switch(e.tag){case 3:case 4:case 6:case 7:case 10:case 9:var n="";break e;default:var r=e._debugOwner,i=e._debugSource,o=ge(e.type);n=null,r&&(n=ge(r.type)),r=o,o="",i?o=" (at "+i.fileName.replace(X,"")+":"+i.lineNumber+")":n&&(o=" (created by "+n+")"),n="\n in "+(r||"Unknown")+o}t+=n,e=e.return}while(e);return t}function ve(e){switch(typeof e){case"boolean":case"number":case"object":case"string":case"undefined":return e;default:return""}}function ye(e){var t=e.type;return(e=e.nodeName)&&"input"===e.toLowerCase()&&("checkbox"===t||"radio"===t)}function we(e){e._valueTracker||(e._valueTracker=function(e){var t=ye(e)?"checked":"value",n=Object.getOwnPropertyDescriptor(e.constructor.prototype,t),r=""+e[t];if(!e.hasOwnProperty(t)&&void 0!==n&&"function"==typeof n.get&&"function"==typeof n.set){var i=n.get,o=n.set;return Object.defineProperty(e,t,{configurable:!0,get:function(){return i.call(this)},set:function(e){r=""+e,o.call(this,e)}}),Object.defineProperty(e,t,{enumerable:n.enumerable}),{getValue:function(){return r},setValue:function(e){r=""+e},stopTracking:function(){e._valueTracker=null,delete e[t]}}}}(e))}function ke(e){if(!e)return!1;var t=e._valueTracker;if(!t)return!0;var n=t.getValue(),r="";return e&&(r=ye(e)?e.checked?"true":"false":e.value),(e=r)!==n&&(t.setValue(e),!0)}function Ee(e,t){var n=t.checked;return i({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=n?n:e._wrapperState.initialChecked})}function Se(e,t){var n=null==t.defaultValue?"":t.defaultValue,r=null!=t.checked?t.checked:t.defaultChecked;n=ve(null!=t.value?t.value:n),e._wrapperState={initialChecked:r,initialValue:n,controlled:"checkbox"===t.type||"radio"===t.type?null!=t.checked:null!=t.value}}function xe(e,t){null!=(t=t.checked)&&Q(e,"checked",t,!1)}function Te(e,t){xe(e,t);var n=ve(t.value),r=t.type;if(null!=n)"number"===r?(0===n&&""===e.value||e.value!=n)&&(e.value=""+n):e.value!==""+n&&(e.value=""+n);else if("submit"===r||"reset"===r)return void e.removeAttribute("value");t.hasOwnProperty("value")?Pe(e,t.type,n):t.hasOwnProperty("defaultValue")&&Pe(e,t.type,ve(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(e.defaultChecked=!!t.defaultChecked)}function Ce(e,t,n){if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var r=t.type;if(!("submit"!==r&&"reset"!==r||void 0!==t.value&&null!==t.value))return;t=""+e._wrapperState.initialValue,n||t===e.value||(e.value=t),e.defaultValue=t}""!==(n=e.name)&&(e.name=""),e.defaultChecked=!!e._wrapperState.initialChecked,""!==n&&(e.name=n)}function Pe(e,t,n){"number"===t&&e.ownerDocument.activeElement===e||(null==n?e.defaultValue=""+e._wrapperState.initialValue:e.defaultValue!==""+n&&(e.defaultValue=""+n))}function _e(e,t){return e=i({children:void 0},t),(t=function(e){var t="";return r.Children.forEach(e,(function(e){null!=e&&(t+=e)})),t}(t.children))&&(e.children=t),e}function Oe(e,t,n,r){if(e=e.options,t){t={};for(var i=0;i=n.length))throw Error(a(93));n=n[0]}t=n}null==t&&(t=""),n=t}e._wrapperState={initialValue:ve(n)}}function Ne(e,t){var n=ve(t.value),r=ve(t.defaultValue);null!=n&&((n=""+n)!==e.value&&(e.value=n),null==t.defaultValue&&e.defaultValue!==n&&(e.defaultValue=n)),null!=r&&(e.defaultValue=""+r)}function Le(e){var t=e.textContent;t===e._wrapperState.initialValue&&""!==t&&null!==t&&(e.value=t)}var Ie="http://www.w3.org/1999/xhtml",De="http://www.w3.org/2000/svg";function Fe(e){switch(e){case"svg":return"http://www.w3.org/2000/svg";case"math":return"http://www.w3.org/1998/Math/MathML";default:return"http://www.w3.org/1999/xhtml"}}function Me(e,t){return null==e||"http://www.w3.org/1999/xhtml"===e?Fe(t):"http://www.w3.org/2000/svg"===e&&"foreignObject"===t?"http://www.w3.org/1999/xhtml":e}var je,Be,ze=(Be=function(e,t){if(e.namespaceURI!==De||"innerHTML"in e)e.innerHTML=t;else{for((je=je||document.createElement("div")).innerHTML="",t=je.firstChild;e.firstChild;)e.removeChild(e.firstChild);for(;t.firstChild;)e.appendChild(t.firstChild)}},"undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction?function(e,t,n,r){MSApp.execUnsafeLocalFunction((function(){return Be(e,t)}))}:Be);function Ue(e,t){if(t){var n=e.firstChild;if(n&&n===e.lastChild&&3===n.nodeType)return void(n.nodeValue=t)}e.textContent=t}function $e(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n}var Ge={animationend:$e("Animation","AnimationEnd"),animationiteration:$e("Animation","AnimationIteration"),animationstart:$e("Animation","AnimationStart"),transitionend:$e("Transition","TransitionEnd")},qe={},He={};function We(e){if(qe[e])return qe[e];if(!Ge[e])return e;var t,n=Ge[e];for(t in n)if(n.hasOwnProperty(t)&&t in He)return qe[e]=n[t];return e}P&&(He=document.createElement("div").style,"AnimationEvent"in window||(delete Ge.animationend.animation,delete Ge.animationiteration.animation,delete Ge.animationstart.animation),"TransitionEvent"in window||delete Ge.transitionend.transition);var Ve=We("animationend"),Ze=We("animationiteration"),Ke=We("animationstart"),Ye=We("transitionend"),Qe="abort canplay canplaythrough durationchange emptied encrypted ended error loadeddata loadedmetadata loadstart pause play playing progress ratechange seeked seeking stalled suspend timeupdate volumechange waiting".split(" "),Xe=new("function"==typeof WeakMap?WeakMap:Map);function Je(e){var t=Xe.get(e);return void 0===t&&(t=new Map,Xe.set(e,t)),t}function et(e){var t=e,n=e;if(e.alternate)for(;t.return;)t=t.return;else{e=t;do{0!=(1026&(t=e).effectTag)&&(n=t.return),e=t.return}while(e)}return 3===t.tag?n:null}function tt(e){if(13===e.tag){var t=e.memoizedState;if(null===t&&(null!==(e=e.alternate)&&(t=e.memoizedState)),null!==t)return t.dehydrated}return null}function nt(e){if(et(e)!==e)throw Error(a(188))}function rt(e){if(e=function(e){var t=e.alternate;if(!t){if(null===(t=et(e)))throw Error(a(188));return t!==e?null:e}for(var n=e,r=t;;){var i=n.return;if(null===i)break;var o=i.alternate;if(null===o){if(null!==(r=i.return)){n=r;continue}break}if(i.child===o.child){for(o=i.child;o;){if(o===n)return nt(i),e;if(o===r)return nt(i),t;o=o.sibling}throw Error(a(188))}if(n.return!==r.return)n=i,r=o;else{for(var l=!1,u=i.child;u;){if(u===n){l=!0,n=i,r=o;break}if(u===r){l=!0,r=i,n=o;break}u=u.sibling}if(!l){for(u=o.child;u;){if(u===n){l=!0,n=o,r=i;break}if(u===r){l=!0,r=o,n=i;break}u=u.sibling}if(!l)throw Error(a(189))}}if(n.alternate!==r)throw Error(a(190))}if(3!==n.tag)throw Error(a(188));return n.stateNode.current===n?e:t}(e),!e)return null;for(var t=e;;){if(5===t.tag||6===t.tag)return t;if(t.child)t.child.return=t,t=t.child;else{if(t===e)break;for(;!t.sibling;){if(!t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}}return null}function it(e,t){if(null==t)throw Error(a(30));return null==e?t:Array.isArray(e)?Array.isArray(t)?(e.push.apply(e,t),e):(e.push(t),e):Array.isArray(t)?[e].concat(t):[e,t]}function ot(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)}var at=null;function lt(e){if(e){var t=e._dispatchListeners,n=e._dispatchInstances;if(Array.isArray(t))for(var r=0;rdt.length&&dt.push(e)}function pt(e,t,n,r){if(dt.length){var i=dt.pop();return i.topLevelType=e,i.eventSystemFlags=r,i.nativeEvent=t,i.targetInst=n,i}return{topLevelType:e,eventSystemFlags:r,nativeEvent:t,targetInst:n,ancestors:[]}}function mt(e){var t=e.targetInst,n=t;do{if(!n){e.ancestors.push(n);break}var r=n;if(3===r.tag)r=r.stateNode.containerInfo;else{for(;r.return;)r=r.return;r=3!==r.tag?null:r.stateNode.containerInfo}if(!r)break;5!==(t=n.tag)&&6!==t||e.ancestors.push(n),n=Rn(r)}while(n);for(n=0;n=t)return{node:r,offset:t-e};e=n}e:{for(;r;){if(r.nextSibling){r=r.nextSibling;break e}r=r.parentNode}r=void 0}r=fn(r)}}function mn(e,t){return!(!e||!t)&&(e===t||(!e||3!==e.nodeType)&&(t&&3===t.nodeType?mn(e,t.parentNode):"contains"in e?e.contains(t):!!e.compareDocumentPosition&&!!(16&e.compareDocumentPosition(t))))}function hn(){for(var e=window,t=dn();t instanceof e.HTMLIFrameElement;){try{var n="string"==typeof t.contentWindow.location.href}catch(r){n=!1}if(!n)break;t=dn((e=t.contentWindow).document)}return t}function gn(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}var bn="$?",vn="$!",yn=null,wn=null;function kn(e,t){switch(e){case"button":case"input":case"select":case"textarea":return!!t.autoFocus}return!1}function En(e,t){return"textarea"===e||"option"===e||"noscript"===e||"string"==typeof t.children||"number"==typeof t.children||"object"==typeof t.dangerouslySetInnerHTML&&null!==t.dangerouslySetInnerHTML&&null!=t.dangerouslySetInnerHTML.__html}var Sn="function"==typeof setTimeout?setTimeout:void 0,xn="function"==typeof clearTimeout?clearTimeout:void 0;function Tn(e){for(;null!=e;e=e.nextSibling){var t=e.nodeType;if(1===t||3===t)break}return e}function Cn(e){e=e.previousSibling;for(var t=0;e;){if(8===e.nodeType){var n=e.data;if("$"===n||n===vn||n===bn){if(0===t)return e;t--}else"/$"===n&&t++}e=e.previousSibling}return null}var Pn=Math.random().toString(36).slice(2),_n="__reactInternalInstance$"+Pn,On="__reactEventHandlers$"+Pn,An="__reactContainere$"+Pn;function Rn(e){var t=e[_n];if(t)return t;for(var n=e.parentNode;n;){if(t=n[An]||n[_n]){if(n=t.alternate,null!==t.child||null!==n&&null!==n.child)for(e=Cn(e);null!==e;){if(n=e[_n])return n;e=Cn(e)}return t}n=(e=n).parentNode}return null}function Nn(e){return!(e=e[_n]||e[An])||5!==e.tag&&6!==e.tag&&13!==e.tag&&3!==e.tag?null:e}function Ln(e){if(5===e.tag||6===e.tag)return e.stateNode;throw Error(a(33))}function In(e){return e[On]||null}function Dn(e){do{e=e.return}while(e&&5!==e.tag);return e||null}function Fn(e,t){var n=e.stateNode;if(!n)return null;var r=m(n);if(!r)return null;n=r[t];e:switch(t){case"onClick":case"onClickCapture":case"onDoubleClick":case"onDoubleClickCapture":case"onMouseDown":case"onMouseDownCapture":case"onMouseMove":case"onMouseMoveCapture":case"onMouseUp":case"onMouseUpCapture":case"onMouseEnter":(r=!r.disabled)||(r=!("button"===(e=e.type)||"input"===e||"select"===e||"textarea"===e)),e=!r;break e;default:e=!1}if(e)return null;if(n&&"function"!=typeof n)throw Error(a(231,t,typeof n));return n}function Mn(e,t,n){(t=Fn(e,n.dispatchConfig.phasedRegistrationNames[t]))&&(n._dispatchListeners=it(n._dispatchListeners,t),n._dispatchInstances=it(n._dispatchInstances,e))}function jn(e){if(e&&e.dispatchConfig.phasedRegistrationNames){for(var t=e._targetInst,n=[];t;)n.push(t),t=Dn(t);for(t=n.length;0this.eventPool.length&&this.eventPool.push(e)}function Qn(e){e.eventPool=[],e.getPooled=Kn,e.release=Yn}i(Zn.prototype,{preventDefault:function(){this.defaultPrevented=!0;var e=this.nativeEvent;e&&(e.preventDefault?e.preventDefault():"unknown"!=typeof e.returnValue&&(e.returnValue=!1),this.isDefaultPrevented=Wn)},stopPropagation:function(){var e=this.nativeEvent;e&&(e.stopPropagation?e.stopPropagation():"unknown"!=typeof e.cancelBubble&&(e.cancelBubble=!0),this.isPropagationStopped=Wn)},persist:function(){this.isPersistent=Wn},isPersistent:Vn,destructor:function(){var e,t=this.constructor.Interface;for(e in t)this[e]=null;this.nativeEvent=this._targetInst=this.dispatchConfig=null,this.isPropagationStopped=this.isDefaultPrevented=Vn,this._dispatchInstances=this._dispatchListeners=null}}),Zn.Interface={type:null,target:null,currentTarget:function(){return null},eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null},Zn.extend=function(e){function t(){}function n(){return r.apply(this,arguments)}var r=this;t.prototype=r.prototype;var o=new t;return i(o,n.prototype),n.prototype=o,n.prototype.constructor=n,n.Interface=i({},r.Interface,e),n.extend=r.extend,Qn(n),n},Qn(Zn);var Xn=Zn.extend({data:null}),Jn=Zn.extend({data:null}),er=[9,13,27,32],tr=P&&"CompositionEvent"in window,nr=null;P&&"documentMode"in document&&(nr=document.documentMode);var rr=P&&"TextEvent"in window&&!nr,ir=P&&(!tr||nr&&8=nr),or=String.fromCharCode(32),ar={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:["compositionend","keypress","textInput","paste"]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:"blur compositionend keydown keypress keyup mousedown".split(" ")},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:"blur compositionstart keydown keypress keyup mousedown".split(" ")},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:"blur compositionupdate keydown keypress keyup mousedown".split(" ")}},lr=!1;function ur(e,t){switch(e){case"keyup":return-1!==er.indexOf(t.keyCode);case"keydown":return 229!==t.keyCode;case"keypress":case"mousedown":case"blur":return!0;default:return!1}}function sr(e){return"object"==typeof(e=e.detail)&&"data"in e?e.data:null}var cr=!1;var dr={eventTypes:ar,extractEvents:function(e,t,n,r){var i;if(tr)e:{switch(e){case"compositionstart":var o=ar.compositionStart;break e;case"compositionend":o=ar.compositionEnd;break e;case"compositionupdate":o=ar.compositionUpdate;break e}o=void 0}else cr?ur(e,n)&&(o=ar.compositionEnd):"keydown"===e&&229===n.keyCode&&(o=ar.compositionStart);return o?(ir&&"ko"!==n.locale&&(cr||o!==ar.compositionStart?o===ar.compositionEnd&&cr&&(i=Hn()):(Gn="value"in($n=r)?$n.value:$n.textContent,cr=!0)),o=Xn.getPooled(o,t,n,r),i?o.data=i:null!==(i=sr(n))&&(o.data=i),Un(o),i=o):i=null,(e=rr?function(e,t){switch(e){case"compositionend":return sr(t);case"keypress":return 32!==t.which?null:(lr=!0,or);case"textInput":return(e=t.data)===or&&lr?null:e;default:return null}}(e,n):function(e,t){if(cr)return"compositionend"===e||!tr&&ur(e,t)?(e=Hn(),qn=Gn=$n=null,cr=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(t.ctrlKey||t.altKey||t.metaKey)||t.ctrlKey&&t.altKey){if(t.char&&1=document.documentMode,Hr={select:{phasedRegistrationNames:{bubbled:"onSelect",captured:"onSelectCapture"},dependencies:"blur contextmenu dragend focus keydown keyup mousedown mouseup selectionchange".split(" ")}},Wr=null,Vr=null,Zr=null,Kr=!1;function Yr(e,t){var n=t.window===t?t.document:9===t.nodeType?t:t.ownerDocument;return Kr||null==Wr||Wr!==dn(n)?null:("selectionStart"in(n=Wr)&&gn(n)?n={start:n.selectionStart,end:n.selectionEnd}:n={anchorNode:(n=(n.ownerDocument&&n.ownerDocument.defaultView||window).getSelection()).anchorNode,anchorOffset:n.anchorOffset,focusNode:n.focusNode,focusOffset:n.focusOffset},Zr&&Gr(Zr,n)?null:(Zr=n,(e=Zn.getPooled(Hr.select,Vr,e,t)).type="select",e.target=Wr,Un(e),e))}var Qr={eventTypes:Hr,extractEvents:function(e,t,n,r,i,o){if(!(o=!(i=o||(r.window===r?r.document:9===r.nodeType?r:r.ownerDocument)))){e:{i=Je(i),o=T.onSelect;for(var a=0;adi||(e.current=ci[di],ci[di]=null,di--)}function pi(e,t){di++,ci[di]=e.current,e.current=t}var mi={},hi={current:mi},gi={current:!1},bi=mi;function vi(e,t){var n=e.type.contextTypes;if(!n)return mi;var r=e.stateNode;if(r&&r.__reactInternalMemoizedUnmaskedChildContext===t)return r.__reactInternalMemoizedMaskedChildContext;var i,o={};for(i in n)o[i]=t[i];return r&&((e=e.stateNode).__reactInternalMemoizedUnmaskedChildContext=t,e.__reactInternalMemoizedMaskedChildContext=o),o}function yi(e){return null!=(e=e.childContextTypes)}function wi(){fi(gi),fi(hi)}function ki(e,t,n){if(hi.current!==mi)throw Error(a(168));pi(hi,t),pi(gi,n)}function Ei(e,t,n){var r=e.stateNode;if(e=t.childContextTypes,"function"!=typeof r.getChildContext)return n;for(var o in r=r.getChildContext())if(!(o in e))throw Error(a(108,ge(t)||"Unknown",o));return i({},n,{},r)}function Si(e){return e=(e=e.stateNode)&&e.__reactInternalMemoizedMergedChildContext||mi,bi=hi.current,pi(hi,e),pi(gi,gi.current),!0}function xi(e,t,n){var r=e.stateNode;if(!r)throw Error(a(169));n?(e=Ei(e,t,bi),r.__reactInternalMemoizedMergedChildContext=e,fi(gi),fi(hi),pi(hi,e)):fi(gi),pi(gi,n)}var Ti=o.unstable_runWithPriority,Ci=o.unstable_scheduleCallback,Pi=o.unstable_cancelCallback,_i=o.unstable_requestPaint,Oi=o.unstable_now,Ai=o.unstable_getCurrentPriorityLevel,Ri=o.unstable_ImmediatePriority,Ni=o.unstable_UserBlockingPriority,Li=o.unstable_NormalPriority,Ii=o.unstable_LowPriority,Di=o.unstable_IdlePriority,Fi={},Mi=o.unstable_shouldYield,ji=void 0!==_i?_i:function(){},Bi=null,zi=null,Ui=!1,$i=Oi(),Gi=1e4>$i?Oi:function(){return Oi()-$i};function qi(){switch(Ai()){case Ri:return 99;case Ni:return 98;case Li:return 97;case Ii:return 96;case Di:return 95;default:throw Error(a(332))}}function Hi(e){switch(e){case 99:return Ri;case 98:return Ni;case 97:return Li;case 96:return Ii;case 95:return Di;default:throw Error(a(332))}}function Wi(e,t){return e=Hi(e),Ti(e,t)}function Vi(e,t,n){return e=Hi(e),Ci(e,t,n)}function Zi(e){return null===Bi?(Bi=[e],zi=Ci(Ri,Yi)):Bi.push(e),Fi}function Ki(){if(null!==zi){var e=zi;zi=null,Pi(e)}Yi()}function Yi(){if(!Ui&&null!==Bi){Ui=!0;var e=0;try{var t=Bi;Wi(99,(function(){for(;e=t&&(Ia=!0),e.firstContext=null)}function lo(e,t){if(no!==e&&!1!==t&&0!==t)if("number"==typeof t&&1073741823!==t||(no=e,t=1073741823),t={context:e,observedBits:t,next:null},null===to){if(null===eo)throw Error(a(308));to=t,eo.dependencies={expirationTime:0,firstContext:t,responders:null}}else to=to.next=t;return e._currentValue}var uo=!1;function so(e){e.updateQueue={baseState:e.memoizedState,baseQueue:null,shared:{pending:null},effects:null}}function co(e,t){e=e.updateQueue,t.updateQueue===e&&(t.updateQueue={baseState:e.baseState,baseQueue:e.baseQueue,shared:e.shared,effects:e.effects})}function fo(e,t){return(e={expirationTime:e,suspenseConfig:t,tag:0,payload:null,callback:null,next:null}).next=e}function po(e,t){if(null!==(e=e.updateQueue)){var n=(e=e.shared).pending;null===n?t.next=t:(t.next=n.next,n.next=t),e.pending=t}}function mo(e,t){var n=e.alternate;null!==n&&co(n,e),null===(n=(e=e.updateQueue).baseQueue)?(e.baseQueue=t.next=t,t.next=t):(t.next=n.next,n.next=t)}function ho(e,t,n,r){var o=e.updateQueue;uo=!1;var a=o.baseQueue,l=o.shared.pending;if(null!==l){if(null!==a){var u=a.next;a.next=l.next,l.next=u}a=l,o.shared.pending=null,null!==(u=e.alternate)&&(null!==(u=u.updateQueue)&&(u.baseQueue=l))}if(null!==a){u=a.next;var s=o.baseState,c=0,d=null,f=null,p=null;if(null!==u)for(var m=u;;){if((l=m.expirationTime)c&&(c=l)}else{null!==p&&(p=p.next={expirationTime:1073741823,suspenseConfig:m.suspenseConfig,tag:m.tag,payload:m.payload,callback:m.callback,next:null}),pu(l,m.suspenseConfig);e:{var g=e,b=m;switch(l=t,h=n,b.tag){case 1:if("function"==typeof(g=b.payload)){s=g.call(h,s,l);break e}s=g;break e;case 3:g.effectTag=-4097&g.effectTag|64;case 0:if(null==(l="function"==typeof(g=b.payload)?g.call(h,s,l):g))break e;s=i({},s,l);break e;case 2:uo=!0}}null!==m.callback&&(e.effectTag|=32,null===(l=o.effects)?o.effects=[m]:l.push(m))}if(null===(m=m.next)||m===u){if(null===(l=o.shared.pending))break;m=a.next=l.next,l.next=u,o.baseQueue=a=l,o.shared.pending=null}}null===p?d=s:p.next=f,o.baseState=d,o.baseQueue=p,mu(c),e.expirationTime=c,e.memoizedState=s}}function go(e,t,n){if(e=t.effects,t.effects=null,null!==e)for(t=0;th?(g=d,d=null):g=d.sibling;var b=p(i,d,l[h],u);if(null===b){null===d&&(d=g);break}e&&d&&null===b.alternate&&t(i,d),a=o(b,a,h),null===c?s=b:c.sibling=b,c=b,d=g}if(h===l.length)return n(i,d),s;if(null===d){for(;hg?(b=h,h=null):b=h.sibling;var y=p(i,h,v.value,s);if(null===y){null===h&&(h=b);break}e&&h&&null===y.alternate&&t(i,h),l=o(y,l,g),null===d?c=y:d.sibling=y,d=y,h=b}if(v.done)return n(i,h),c;if(null===h){for(;!v.done;g++,v=u.next())null!==(v=f(i,v.value,s))&&(l=o(v,l,g),null===d?c=v:d.sibling=v,d=v);return c}for(h=r(i,h);!v.done;g++,v=u.next())null!==(v=m(h,i,g,v.value,s))&&(e&&null!==v.alternate&&h.delete(null===v.key?g:v.key),l=o(v,l,g),null===d?c=v:d.sibling=v,d=v);return e&&h.forEach((function(e){return t(i,e)})),c}return function(e,r,o,u){var s="object"==typeof o&&null!==o&&o.type===ne&&null===o.key;s&&(o=o.props.children);var c="object"==typeof o&&null!==o;if(c)switch(o.$$typeof){case ee:e:{for(c=o.key,s=r;null!==s;){if(s.key===c){if(7===s.tag){if(o.type===ne){n(e,s.sibling),(r=i(s,o.props.children)).return=e,e=r;break e}}else if(s.elementType===o.type){n(e,s.sibling),(r=i(s,o.props)).ref=Co(e,s,o),r.return=e,e=r;break e}n(e,s);break}t(e,s),s=s.sibling}o.type===ne?((r=Fu(o.props.children,e.mode,u,o.key)).return=e,e=r):((u=Du(o.type,o.key,o.props,null,e.mode,u)).ref=Co(e,r,o),u.return=e,e=u)}return l(e);case te:e:{for(s=o.key;null!==r;){if(r.key===s){if(4===r.tag&&r.stateNode.containerInfo===o.containerInfo&&r.stateNode.implementation===o.implementation){n(e,r.sibling),(r=i(r,o.children||[])).return=e,e=r;break e}n(e,r);break}t(e,r),r=r.sibling}(r=ju(o,e.mode,u)).return=e,e=r}return l(e)}if("string"==typeof o||"number"==typeof o)return o=""+o,null!==r&&6===r.tag?(n(e,r.sibling),(r=i(r,o)).return=e,e=r):(n(e,r),(r=Mu(o,e.mode,u)).return=e,e=r),l(e);if(To(o))return h(e,r,o,u);if(he(o))return g(e,r,o,u);if(c&&Po(e,o),void 0===o&&!s)switch(e.tag){case 1:case 0:throw e=e.type,Error(a(152,e.displayName||e.name||"Component"))}return n(e,r)}}var Oo=_o(!0),Ao=_o(!1),Ro={},No={current:Ro},Lo={current:Ro},Io={current:Ro};function Do(e){if(e===Ro)throw Error(a(174));return e}function Fo(e,t){switch(pi(Io,t),pi(Lo,e),pi(No,Ro),e=t.nodeType){case 9:case 11:t=(t=t.documentElement)?t.namespaceURI:Me(null,"");break;default:t=Me(t=(e=8===e?t.parentNode:t).namespaceURI||null,e=e.tagName)}fi(No),pi(No,t)}function Mo(){fi(No),fi(Lo),fi(Io)}function jo(e){Do(Io.current);var t=Do(No.current),n=Me(t,e.type);t!==n&&(pi(Lo,e),pi(No,n))}function Bo(e){Lo.current===e&&(fi(No),fi(Lo))}var zo={current:0};function Uo(e){for(var t=e;null!==t;){if(13===t.tag){var n=t.memoizedState;if(null!==n&&(null===(n=n.dehydrated)||n.data===bn||n.data===vn))return t}else if(19===t.tag&&void 0!==t.memoizedProps.revealOrder){if(0!=(64&t.effectTag))return t}else if(null!==t.child){t.child.return=t,t=t.child;continue}if(t===e)break;for(;null===t.sibling;){if(null===t.return||t.return===e)return null;t=t.return}t.sibling.return=t.return,t=t.sibling}return null}function $o(e,t){return{responder:e,props:t}}var Go=Y.ReactCurrentDispatcher,qo=Y.ReactCurrentBatchConfig,Ho=0,Wo=null,Vo=null,Zo=null,Ko=!1;function Yo(){throw Error(a(321))}function Qo(e,t){if(null===t)return!1;for(var n=0;no))throw Error(a(301));o+=1,Zo=Vo=null,t.updateQueue=null,Go.current=Sa,e=n(r,i)}while(t.expirationTime===Ho)}if(Go.current=wa,t=null!==Vo&&null!==Vo.next,Ho=0,Zo=Vo=Wo=null,Ko=!1,t)throw Error(a(300));return e}function Jo(){var e={memoizedState:null,baseState:null,baseQueue:null,queue:null,next:null};return null===Zo?Wo.memoizedState=Zo=e:Zo=Zo.next=e,Zo}function ea(){if(null===Vo){var e=Wo.alternate;e=null!==e?e.memoizedState:null}else e=Vo.next;var t=null===Zo?Wo.memoizedState:Zo.next;if(null!==t)Zo=t,Vo=e;else{if(null===e)throw Error(a(310));e={memoizedState:(Vo=e).memoizedState,baseState:Vo.baseState,baseQueue:Vo.baseQueue,queue:Vo.queue,next:null},null===Zo?Wo.memoizedState=Zo=e:Zo=Zo.next=e}return Zo}function ta(e,t){return"function"==typeof t?t(e):t}function na(e){var t=ea(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var r=Vo,i=r.baseQueue,o=n.pending;if(null!==o){if(null!==i){var l=i.next;i.next=o.next,o.next=l}r.baseQueue=i=o,n.pending=null}if(null!==i){i=i.next,r=r.baseState;var u=l=o=null,s=i;do{var c=s.expirationTime;if(cWo.expirationTime&&(Wo.expirationTime=c,mu(c))}else null!==u&&(u=u.next={expirationTime:1073741823,suspenseConfig:s.suspenseConfig,action:s.action,eagerReducer:s.eagerReducer,eagerState:s.eagerState,next:null}),pu(c,s.suspenseConfig),r=s.eagerReducer===e?s.eagerState:e(r,s.action);s=s.next}while(null!==s&&s!==i);null===u?o=r:u.next=l,Ur(r,t.memoizedState)||(Ia=!0),t.memoizedState=r,t.baseState=o,t.baseQueue=u,n.lastRenderedState=r}return[t.memoizedState,n.dispatch]}function ra(e){var t=ea(),n=t.queue;if(null===n)throw Error(a(311));n.lastRenderedReducer=e;var r=n.dispatch,i=n.pending,o=t.memoizedState;if(null!==i){n.pending=null;var l=i=i.next;do{o=e(o,l.action),l=l.next}while(l!==i);Ur(o,t.memoizedState)||(Ia=!0),t.memoizedState=o,null===t.baseQueue&&(t.baseState=o),n.lastRenderedState=o}return[o,r]}function ia(e){var t=Jo();return"function"==typeof e&&(e=e()),t.memoizedState=t.baseState=e,e=(e=t.queue={pending:null,dispatch:null,lastRenderedReducer:ta,lastRenderedState:e}).dispatch=ya.bind(null,Wo,e),[t.memoizedState,e]}function oa(e,t,n,r){return e={tag:e,create:t,destroy:n,deps:r,next:null},null===(t=Wo.updateQueue)?(t={lastEffect:null},Wo.updateQueue=t,t.lastEffect=e.next=e):null===(n=t.lastEffect)?t.lastEffect=e.next=e:(r=n.next,n.next=e,e.next=r,t.lastEffect=e),e}function aa(){return ea().memoizedState}function la(e,t,n,r){var i=Jo();Wo.effectTag|=e,i.memoizedState=oa(1|t,n,void 0,void 0===r?null:r)}function ua(e,t,n,r){var i=ea();r=void 0===r?null:r;var o=void 0;if(null!==Vo){var a=Vo.memoizedState;if(o=a.destroy,null!==r&&Qo(r,a.deps))return void oa(t,n,o,r)}Wo.effectTag|=e,i.memoizedState=oa(1|t,n,o,r)}function sa(e,t){return la(516,4,e,t)}function ca(e,t){return ua(516,4,e,t)}function da(e,t){return ua(4,2,e,t)}function fa(e,t){return"function"==typeof t?(e=e(),t(e),function(){t(null)}):null!=t?(e=e(),t.current=e,function(){t.current=null}):void 0}function pa(e,t,n){return n=null!=n?n.concat([e]):null,ua(4,2,fa.bind(null,t,e),n)}function ma(){}function ha(e,t){return Jo().memoizedState=[e,void 0===t?null:t],e}function ga(e,t){var n=ea();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Qo(t,r[1])?r[0]:(n.memoizedState=[e,t],e)}function ba(e,t){var n=ea();t=void 0===t?null:t;var r=n.memoizedState;return null!==r&&null!==t&&Qo(t,r[1])?r[0]:(e=e(),n.memoizedState=[e,t],e)}function va(e,t,n){var r=qi();Wi(98>r?98:r,(function(){e(!0)})),Wi(97<\/script>",e=e.removeChild(e.firstChild)):"string"==typeof r.is?e=u.createElement(o,{is:r.is}):(e=u.createElement(o),"select"===o&&(u=e,r.multiple?u.multiple=!0:r.size&&(u.size=r.size))):e=u.createElementNS(e,o),e[_n]=t,e[On]=r,qa(e,t),t.stateNode=e,u=ln(o,r),o){case"iframe":case"object":case"embed":Zt("load",e),s=r;break;case"video":case"audio":for(s=0;sr.tailExpiration&&1t)&&Yl.set(e,t))}}function ru(e,t){e.expirationTime=(e=n>(e=e.nextKnownPendingLevel)?n:e)&&t!==e?0:e}function ou(e){if(0!==e.lastExpiredTime)e.callbackExpirationTime=1073741823,e.callbackPriority=99,e.callbackNode=Zi(lu.bind(null,e));else{var t=iu(e),n=e.callbackNode;if(0===t)null!==n&&(e.callbackNode=null,e.callbackExpirationTime=0,e.callbackPriority=90);else{var r=eu();if(1073741823===t?r=99:1===t||2===t?r=95:r=0>=(r=10*(1073741821-t)-10*(1073741821-r))?99:250>=r?98:5250>=r?97:95,null!==n){var i=e.callbackPriority;if(e.callbackExpirationTime===t&&i>=r)return;n!==Fi&&Pi(n)}e.callbackExpirationTime=t,e.callbackPriority=r,t=1073741823===t?Zi(lu.bind(null,e)):Vi(r,au.bind(null,e),{timeout:10*(1073741821-t)-Gi()}),e.callbackNode=t}}}function au(e,t){if(Jl=0,t)return Gu(e,t=eu()),ou(e),null;var n=iu(e);if(0!==n){if(t=e.callbackNode,0!=(48&Rl))throw Error(a(327));if(Su(),e===Nl&&n===Il||cu(e,n),null!==Ll){var r=Rl;Rl|=Cl;for(var i=fu();;)try{gu();break}catch(u){du(e,u)}if(ro(),Rl=r,xl.current=i,1===Dl)throw t=Fl,cu(e,n),Uu(e,n),ou(e),t;if(null===Ll)switch(i=e.finishedWork=e.current.alternate,e.finishedExpirationTime=n,r=Dl,Nl=null,r){case _l:case 1:throw Error(a(345));case 2:Gu(e,2=n){e.lastPingedTime=n,cu(e,n);break}}if(0!==(o=iu(e))&&o!==n)break;if(0!==r&&r!==n){e.lastPingedTime=r;break}e.timeoutHandle=Sn(wu.bind(null,e),i);break}wu(e);break;case Al:if(Uu(e,n),n===(r=e.lastSuspendedTime)&&(e.nextKnownPendingLevel=yu(i)),Ul&&(0===(i=e.lastPingedTime)||i>=n)){e.lastPingedTime=n,cu(e,n);break}if(0!==(i=iu(e))&&i!==n)break;if(0!==r&&r!==n){e.lastPingedTime=r;break}if(1073741823!==jl?r=10*(1073741821-jl)-Gi():1073741823===Ml?r=0:(r=10*(1073741821-Ml)-5e3,0>(r=(i=Gi())-r)&&(r=0),(n=10*(1073741821-n)-i)<(r=(120>r?120:480>r?480:1080>r?1080:1920>r?1920:3e3>r?3e3:4320>r?4320:1960*Sl(r/1960))-r)&&(r=n)),10=(r=0|l.busyMinDurationMs)?r=0:(i=0|l.busyDelayMs,r=(o=Gi()-(10*(1073741821-o)-(0|l.timeoutMs||5e3)))<=i?0:i+r-o),10 component higher in the tree to provide a loading indicator or placeholder to display."+be(a))}5!==Dl&&(Dl=2),l=nl(l,a),d=o;do{switch(d.tag){case 3:u=l,d.effectTag|=4096,d.expirationTime=t,mo(d,wl(d,u,t));break e;case 1:u=l;var w=d.type,k=d.stateNode;if(0==(64&d.effectTag)&&("function"==typeof w.getDerivedStateFromError||null!==k&&"function"==typeof k.componentDidCatch&&(null===Wl||!Wl.has(k)))){d.effectTag|=4096,d.expirationTime=t,mo(d,kl(d,u,t));break e}}d=d.return}while(null!==d)}Ll=vu(Ll)}catch(E){t=E;continue}break}}function fu(){var e=xl.current;return xl.current=wa,null===e?wa:e}function pu(e,t){ezl&&(zl=e)}function hu(){for(;null!==Ll;)Ll=bu(Ll)}function gu(){for(;null!==Ll&&!Mi();)Ll=bu(Ll)}function bu(e){var t=El(e.alternate,e,Il);return e.memoizedProps=e.pendingProps,null===t&&(t=vu(e)),Tl.current=null,t}function vu(e){Ll=e;do{var t=Ll.alternate;if(e=Ll.return,0==(2048&Ll.effectTag)){if(t=el(t,Ll,Il),1===Il||1!==Ll.childExpirationTime){for(var n=0,r=Ll.child;null!==r;){var i=r.expirationTime,o=r.childExpirationTime;i>n&&(n=i),o>n&&(n=o),r=r.sibling}Ll.childExpirationTime=n}if(null!==t)return t;null!==e&&0==(2048&e.effectTag)&&(null===e.firstEffect&&(e.firstEffect=Ll.firstEffect),null!==Ll.lastEffect&&(null!==e.lastEffect&&(e.lastEffect.nextEffect=Ll.firstEffect),e.lastEffect=Ll.lastEffect),1(e=e.childExpirationTime)?t:e}function wu(e){var t=qi();return Wi(99,ku.bind(null,e,t)),null}function ku(e,t){do{Su()}while(null!==Zl);if(0!=(48&Rl))throw Error(a(327));var n=e.finishedWork,r=e.finishedExpirationTime;if(null===n)return null;if(e.finishedWork=null,e.finishedExpirationTime=0,n===e.current)throw Error(a(177));e.callbackNode=null,e.callbackExpirationTime=0,e.callbackPriority=90,e.nextKnownPendingLevel=0;var i=yu(n);if(e.firstPendingTime=i,r<=e.lastSuspendedTime?e.firstSuspendedTime=e.lastSuspendedTime=e.nextKnownPendingLevel=0:r<=e.firstSuspendedTime&&(e.firstSuspendedTime=r-1),r<=e.lastPingedTime&&(e.lastPingedTime=0),r<=e.lastExpiredTime&&(e.lastExpiredTime=0),e===Nl&&(Ll=Nl=null,Il=0),1u&&(c=u,u=l,l=c),c=pn(w,l),d=pn(w,u),c&&d&&(1!==E.rangeCount||E.anchorNode!==c.node||E.anchorOffset!==c.offset||E.focusNode!==d.node||E.focusOffset!==d.offset)&&((k=k.createRange()).setStart(c.node,c.offset),E.removeAllRanges(),l>u?(E.addRange(k),E.extend(d.node,d.offset)):(k.setEnd(d.node,d.offset),E.addRange(k))))),k=[];for(E=w;E=E.parentNode;)1===E.nodeType&&k.push({element:E,left:E.scrollLeft,top:E.scrollTop});for("function"==typeof w.focus&&w.focus(),w=0;w=n?Za(e,t,n):(pi(zo,1&zo.current),null!==(t=Xa(e,t,n))?t.sibling:null);pi(zo,1&zo.current);break;case 19:if(r=t.childExpirationTime>=n,0!=(64&e.effectTag)){if(r)return Qa(e,t,n);t.effectTag|=64}if(null!==(i=t.memoizedState)&&(i.rendering=null,i.tail=null),pi(zo,zo.current),!r)return null}return Xa(e,t,n)}Ia=!1}}else Ia=!1;switch(t.expirationTime=0,t.tag){case 2:if(r=t.type,null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),e=t.pendingProps,i=vi(t,hi.current),ao(t,n),i=Xo(null,t,r,e,i,n),t.effectTag|=1,"object"==typeof i&&null!==i&&"function"==typeof i.render&&void 0===i.$$typeof){if(t.tag=1,t.memoizedState=null,t.updateQueue=null,yi(r)){var o=!0;Si(t)}else o=!1;t.memoizedState=null!==i.state&&void 0!==i.state?i.state:null,so(t);var l=r.getDerivedStateFromProps;"function"==typeof l&&yo(t,r,l,e),i.updater=wo,t.stateNode=i,i._reactInternalFiber=t,xo(t,r,e,n),t=$a(null,t,r,!0,o,n)}else t.tag=0,Da(null,t,i,n),t=t.child;return t;case 16:e:{if(i=t.elementType,null!==e&&(e.alternate=null,t.alternate=null,t.effectTag|=2),e=t.pendingProps,function(e){if(-1===e._status){e._status=0;var t=e._ctor;t=t(),e._result=t,t.then((function(t){0===e._status&&(t=t.default,e._status=1,e._result=t)}),(function(t){0===e._status&&(e._status=2,e._result=t)}))}}(i),1!==i._status)throw i._result;switch(i=i._result,t.type=i,o=t.tag=function(e){if("function"==typeof e)return Lu(e)?1:0;if(null!=e){if((e=e.$$typeof)===ue)return 11;if(e===de)return 14}return 2}(i),e=Xi(i,e),o){case 0:t=za(null,t,i,e,n);break e;case 1:t=Ua(null,t,i,e,n);break e;case 11:t=Fa(null,t,i,e,n);break e;case 14:t=Ma(null,t,i,Xi(i.type,e),r,n);break e}throw Error(a(306,i,""))}return t;case 0:return r=t.type,i=t.pendingProps,za(e,t,r,i=t.elementType===r?i:Xi(r,i),n);case 1:return r=t.type,i=t.pendingProps,Ua(e,t,r,i=t.elementType===r?i:Xi(r,i),n);case 3:if(Ga(t),r=t.updateQueue,null===e||null===r)throw Error(a(282));if(r=t.pendingProps,i=null!==(i=t.memoizedState)?i.element:null,co(e,t),ho(t,r,null,n),(r=t.memoizedState.element)===i)Na(),t=Xa(e,t,n);else{if((i=t.stateNode.hydrate)&&(Ta=Tn(t.stateNode.containerInfo.firstChild),xa=t,i=Ca=!0),i)for(n=Ao(t,null,r,n),t.child=n;n;)n.effectTag=-3&n.effectTag|1024,n=n.sibling;else Da(e,t,r,n),Na();t=t.child}return t;case 5:return jo(t),null===e&&Oa(t),r=t.type,i=t.pendingProps,o=null!==e?e.memoizedProps:null,l=i.children,En(r,i)?l=null:null!==o&&En(r,o)&&(t.effectTag|=16),Ba(e,t),4&t.mode&&1!==n&&i.hidden?(t.expirationTime=t.childExpirationTime=1,t=null):(Da(e,t,l,n),t=t.child),t;case 6:return null===e&&Oa(t),null;case 13:return Za(e,t,n);case 4:return Fo(t,t.stateNode.containerInfo),r=t.pendingProps,null===e?t.child=Oo(t,null,r,n):Da(e,t,r,n),t.child;case 11:return r=t.type,i=t.pendingProps,Fa(e,t,r,i=t.elementType===r?i:Xi(r,i),n);case 7:return Da(e,t,t.pendingProps,n),t.child;case 8:case 12:return Da(e,t,t.pendingProps.children,n),t.child;case 10:e:{r=t.type._context,i=t.pendingProps,l=t.memoizedProps,o=i.value;var u=t.type._context;if(pi(Ji,u._currentValue),u._currentValue=o,null!==l)if(u=l.value,0===(o=Ur(u,o)?0:0|("function"==typeof r._calculateChangedBits?r._calculateChangedBits(u,o):1073741823))){if(l.children===i.children&&!gi.current){t=Xa(e,t,n);break e}}else for(null!==(u=t.child)&&(u.return=t);null!==u;){var s=u.dependencies;if(null!==s){l=u.child;for(var c=s.firstContext;null!==c;){if(c.context===r&&0!=(c.observedBits&o)){1===u.tag&&((c=fo(n,null)).tag=2,po(u,c)),u.expirationTime=t&&e<=t}function Uu(e,t){var n=e.firstSuspendedTime,r=e.lastSuspendedTime;nt||0===n)&&(e.lastSuspendedTime=t),t<=e.lastPingedTime&&(e.lastPingedTime=0),t<=e.lastExpiredTime&&(e.lastExpiredTime=0)}function $u(e,t){t>e.firstPendingTime&&(e.firstPendingTime=t);var n=e.firstSuspendedTime;0!==n&&(t>=n?e.firstSuspendedTime=e.lastSuspendedTime=e.nextKnownPendingLevel=0:t>=e.lastSuspendedTime&&(e.lastSuspendedTime=t+1),t>e.nextKnownPendingLevel&&(e.nextKnownPendingLevel=t))}function Gu(e,t){var n=e.lastExpiredTime;(0===n||n>t)&&(e.lastExpiredTime=t)}function qu(e,t,n,r){var i=t.current,o=eu(),l=bo.suspense;o=tu(o,i,l);e:if(n){t:{if(et(n=n._reactInternalFiber)!==n||1!==n.tag)throw Error(a(170));var u=n;do{switch(u.tag){case 3:u=u.stateNode.context;break t;case 1:if(yi(u.type)){u=u.stateNode.__reactInternalMemoizedMergedChildContext;break t}}u=u.return}while(null!==u);throw Error(a(171))}if(1===n.tag){var s=n.type;if(yi(s)){n=Ei(n,s,u);break e}}n=u}else n=mi;return null===t.context?t.context=n:t.pendingContext=n,(t=fo(o,l)).payload={element:e},null!==(r=void 0===r?null:r)&&(t.callback=r),po(i,t),nu(i,o),o}function Hu(e){return(e=e.current).child?(e.child.tag,e.child.stateNode):null}function Wu(e,t){null!==(e=e.memoizedState)&&null!==e.dehydrated&&e.retryTimeA.length&&A.push(e)}function L(e,t,n,r){var i=typeof e;"undefined"!==i&&"boolean"!==i||(e=null);var l=!1;if(null===e)l=!0;else switch(i){case"string":case"number":l=!0;break;case"object":switch(e.$$typeof){case o:case a:l=!0}}if(l)return n(r,e,""===t?"."+D(e,0):t),1;if(l=0,t=""===t?".":t+":",Array.isArray(e))for(var u=0;u=k},a=function(){},t.unstable_forceFrameRate=function(e){0>e||125>>1,i=e[r];if(!(void 0!==i&&0
P(a,n))void 0!==u&&0>P(u,a)?(e[r]=u,e[l]=n,r=l):(e[r]=a,e[o]=n,r=o);else{if(!(void 0!==u&&0>P(u,n)))break e;e[r]=u,e[l]=n,r=l}}}return t}return null}function P(e,t){var n=e.sortIndex-t.sortIndex;return 0!==n?n:e.id-t.id}var _=[],O=[],A=1,R=null,N=3,L=!1,I=!1,D=!1;function F(e){for(var t=T(O);null!==t;){if(null===t.callback)C(O);else{if(!(t.startTime<=e))break;C(O),t.sortIndex=t.expirationTime,x(_,t)}t=T(O)}}function M(e){if(D=!1,F(e),!I)if(null!==T(_))I=!0,n(j);else{var t=T(O);null!==t&&r(M,t.startTime-e)}}function j(e,n){I=!1,D&&(D=!1,i()),L=!0;var a=N;try{for(F(n),R=T(_);null!==R&&(!(R.expirationTime>n)||e&&!o());){var l=R.callback;if(null!==l){R.callback=null,N=R.priorityLevel;var u=l(R.expirationTime<=n);n=t.unstable_now(),"function"==typeof u?R.callback=u:R===T(_)&&C(_),F(n)}else C(_);R=T(_)}if(null!==R)var s=!0;else{var c=T(O);null!==c&&r(M,c.startTime-n),s=!1}return s}finally{R=null,N=a,L=!1}}function B(e){switch(e){case 1:return-1;case 2:return 250;case 5:return 1073741823;case 4:return 1e4;default:return 5e3}}var z=a;t.unstable_IdlePriority=5,t.unstable_ImmediatePriority=1,t.unstable_LowPriority=4,t.unstable_NormalPriority=3,t.unstable_Profiling=null,t.unstable_UserBlockingPriority=2,t.unstable_cancelCallback=function(e){e.callback=null},t.unstable_continueExecution=function(){I||L||(I=!0,n(j))},t.unstable_getCurrentPriorityLevel=function(){return N},t.unstable_getFirstCallbackNode=function(){return T(_)},t.unstable_next=function(e){switch(N){case 1:case 2:case 3:var t=3;break;default:t=N}var n=N;N=t;try{return e()}finally{N=n}},t.unstable_pauseExecution=function(){},t.unstable_requestPaint=z,t.unstable_runWithPriority=function(e,t){switch(e){case 1:case 2:case 3:case 4:case 5:break;default:e=3}var n=N;N=e;try{return t()}finally{N=n}},t.unstable_scheduleCallback=function(e,o,a){var l=t.unstable_now();if("object"==typeof a&&null!==a){var u=a.delay;u="number"==typeof u&&0l?(e.sortIndex=u,x(O,e),null===T(_)&&e===T(O)&&(D?i():D=!0,r(M,u-l))):(e.sortIndex=a,x(_,e),I||L||(I=!0,n(j))),e},t.unstable_shouldYield=function(){var e=t.unstable_now();F(e);var n=T(_);return n!==R&&null!==R&&null!==n&&null!==n.callback&&n.startTime<=e&&n.expirationTime=0||(i[n]=e[n]);return i}n.d(t,{Z:function(){return r}})},7529:function(e){"use strict";e.exports={}}},function(e){e.O(0,[532],(function(){return t=8845,e(e.s=t);var t}));e.O()}]);
\ No newline at end of file
diff --git a/assets/js/main.8697a4a8.js.LICENSE.txt b/assets/js/main.8697a4a8.js.LICENSE.txt
new file mode 100644
index 00000000..8039c42a
--- /dev/null
+++ b/assets/js/main.8697a4a8.js.LICENSE.txt
@@ -0,0 +1,44 @@
+/*
+object-assign
+(c) Sindre Sorhus
+@license MIT
+*/
+
+/* NProgress, (c) 2013, 2014 Rico Sta. Cruz - http://ricostacruz.com/nprogress
+ * @license MIT */
+
+/** @license React v0.19.1
+ * scheduler.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+/** @license React v16.13.1
+ * react-is.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+/** @license React v16.14.0
+ * react-dom.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+/** @license React v16.14.0
+ * react.production.min.js
+ *
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
diff --git a/assets/js/runtime~main.2c83ebaf.js b/assets/js/runtime~main.2c83ebaf.js
new file mode 100644
index 00000000..3c104b15
--- /dev/null
+++ b/assets/js/runtime~main.2c83ebaf.js
@@ -0,0 +1 @@
+!function(){"use strict";var e,t,n,r,f,c={},a={};function o(e){var t=a[e];if(void 0!==t)return t.exports;var n=a[e]={id:e,loaded:!1,exports:{}};return c[e].call(n.exports,n,n.exports,o),n.loaded=!0,n.exports}o.m=c,o.c=a,e=[],o.O=function(t,n,r,f){if(!n){var c=1/0;for(i=0;i=f)&&Object.keys(o.O).every((function(e){return o.O[e](n[d])}))?n.splice(d--,1):(a=!1,f0&&e[i-1][2]>f;i--)e[i]=e[i-1];e[i]=[n,r,f]},o.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return o.d(t,{a:t}),t},n=Object.getPrototypeOf?function(e){return Object.getPrototypeOf(e)}:function(e){return e.__proto__},o.t=function(e,r){if(1&r&&(e=this(e)),8&r)return e;if("object"==typeof e&&e){if(4&r&&e.__esModule)return e;if(16&r&&"function"==typeof e.then)return e}var f=Object.create(null);o.r(f);var c={};t=t||[null,n({}),n([]),n(n)];for(var a=2&r&&e;"object"==typeof a&&!~t.indexOf(a);a=n(a))Object.getOwnPropertyNames(a).forEach((function(t){c[t]=function(){return e[t]}}));return c.default=function(){return e},o.d(f,c),f},o.d=function(e,t){for(var n in t)o.o(t,n)&&!o.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},o.f={},o.e=function(e){return Promise.all(Object.keys(o.f).reduce((function(t,n){return o.f[n](e,t),t}),[]))},o.u=function(e){return"assets/js/"+({4:"8edf8477",21:"b26d0282",42:"0ec633e3",48:"845bd1c2",53:"935f2afb",80:"4d54d076",85:"1f391b9e",90:"c262d75c",97:"68fa943a",115:"fe10cfa2",123:"efc1d014",217:"ff9389ff",226:"cceaa720",232:"9713dba4",243:"04f02758",291:"e747ec83",295:"e90f1b0f",300:"8f06a039",334:"babc9e1e",352:"dea0f9ea",363:"b7e6c2c9",393:"d3ca088c",399:"54960599",431:"f0e91c34",457:"203a24fb",514:"1be78505",519:"9afee992",562:"3154b02d",583:"e6153e31",594:"7ce205db",635:"400ba6ed",666:"8d63c64e",679:"6a6437be",712:"d924a180",720:"e2ac0c50",786:"d112f800",799:"a5cde68b",834:"60c74a79",844:"f3976560",858:"d99c9437",918:"17896441",923:"8c5da4da"}[e]||e)+"."+{4:"1b6a23bc",21:"18c1ecf9",42:"3d23dbcc",48:"1c675eaa",53:"3e0dc861",80:"ba6db6b4",85:"aeaa3c07",90:"12ef6589",97:"eb18008b",115:"6e9fdb55",118:"c1af23f2",123:"8500a96d",217:"344dd689",226:"4ef1cfe7",232:"8da195bd",243:"1a62e4a9",291:"e7763713",295:"458f9049",300:"de60aa88",334:"549de8b4",352:"9f242e0b",363:"cf483ec2",393:"e95359e6",399:"f2ccc76e",431:"78f254f2",457:"404b1195",486:"3dcb45d1",514:"d8cebf73",519:"f0848694",562:"076c6cc6",583:"20c8d44d",594:"882954d2",608:"1cb0b926",635:"cdf1b014",666:"d220d537",679:"e2191433",712:"e9fbeadf",720:"bbda80cc",776:"d45e0e7f",786:"18e5f376",799:"5418cd5d",834:"466e37af",844:"2f003989",858:"308664c3",918:"c8a6b470",923:"8552330e"}[e]+".js"},o.miniCssF=function(e){return"assets/css/styles.e956416b.css"},o.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),o.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},r={},f="devsite:",o.l=function(e,t,n,c){if(r[e])r[e].push(t);else{var a,d;if(void 0!==n)for(var u=document.getElementsByTagName("script"),i=0;i
\ No newline at end of file
diff --git a/assets/opensource.png b/assets/opensource.png
new file mode 100644
index 00000000..0d6f48de
Binary files /dev/null and b/assets/opensource.png differ
diff --git a/assets/spruce-corporate-cla.pdf b/assets/spruce-corporate-cla.pdf
new file mode 100644
index 00000000..307aacc4
Binary files /dev/null and b/assets/spruce-corporate-cla.pdf differ
diff --git a/assets/spruce-individual-cla.md b/assets/spruce-individual-cla.md
new file mode 100644
index 00000000..ea4fc4f5
--- /dev/null
+++ b/assets/spruce-individual-cla.md
@@ -0,0 +1,121 @@
+Spruce Systems, LLC. (“Spruce”)
+ Software Grant and Corporate Contributor License Agreement ("Agreement")
+
+ http://www.spruceid.com
+
+Thank you for your interest in Spruce’s Open Source projects. In order to
+clarify the intellectual property license granted with Contributions from any
+person or entity, Spruce must have a Contributor License Agreement (CLA) on
+file that has been signed by each Contributor, indicating agreement to the
+license terms below. This license is for your protection as a Contributor as
+well as the protection of Spruce and its users; it does not change your
+rights to use your own Contributions for any other purpose.
+
+ This version of the Agreement allows an entity (the "Corporation") to
+submit Contributions to Spruce, to authorize Contributions submitted by its
+designated employees to Spruce, and to grant copyright and patent licenses
+thereto.
+
+ If you have not already done so, please complete and sign, then scan and
+email a pdf file of this Agreement to oss@spruceid.com . If necessary, send
+an original signed Agreement to Spruce Systems at 228 Park Ave S, PMB 28788,
+New York, NY 10003
+
+ Please read this document carefully before signing and keep a copy for
+ your records.
+
+ Corporation name: ________________________________________________
+ Corporation address: ________________________________________________
+ ________________________________________________
+ ________________________________________________
+ Point of Contact: ________________________________________________
+ E-Mail: ________________________________________________
+ Telephone: _____________________ Fax: _____________________
+
+ You accept and agree to the following terms and conditions for Your
+present and future Contributions submitted to Spruce. In return, Spruce shall
+not use Your Contributions in a way that is contrary to the public benefit or
+inconsistent with its nonprofit status and bylaws in effect at the time of
+the Contribution. Except for the license granted herein to Spruce and
+recipients of software distributed by Spruce, You reserve all right, title,
+and interest in and to Your Contributions.
+ 1. Definitions.
+ "You" (or "Your") shall mean the copyright owner or legal entity
+ authorized by the copyright owner that is making this Agreement
+ with Spruce. For legal entities, the entity making a
+ Contribution and all other entities that control, are controlled by,
+ or are under common control with that entity are considered to be a
+ single Contributor. For the purposes of this definition, "control"
+ means (i) the power, direct or indirect, to cause the direction or
+ management of such entity, whether by contract or otherwise, or
+ (ii) ownership of fifty percent (50%) or more of the outstanding
+ shares, or (iii) beneficial ownership of such entity.
+ "Contribution" shall mean the code, documentation or other original
+ works of authorship expressly identified in Schedule B, as well as
+ any original work of authorship, including any modifications or
+ additions to an existing work, that is intentionally
+ submitted by You to Spruce for inclusion in, or
+ documentation of, any of the products owned or managed by
+ Spruce (the "Work"). For the purposes of this definition,
+ "submitted" means any form of electronic, verbal, or written
+ communication sent to Spruce or its representatives,
+ including but not limited to communication on electronic mailing
+ lists, source code control systems, and issue tracking systems
+ that are managed by, or on behalf of, Spruce for the
+ purpose of discussing and improving the Work, but excluding
+ communication that is conspicuously marked or otherwise designated
+ in writing by You as "Not a Contribution."
+ 2. Grant of Copyright License. Subject to the terms and conditions
+ of this Agreement, You hereby grant to Spruce and to
+ recipients of software distributed by Spruce a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare derivative works of,
+ publicly display, publicly perform, sublicense, and distribute
+ Your Contributions and such derivative works.
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this Agreement, You hereby grant to Spruce and to recipients
+ of software distributed by Spruce a perpetual, worldwide,
+ non-exclusive, no-charge, royalty-free, irrevocable (except as
+ stated in this section) patent license to make, have made, use,
+ offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by You that are necessarily infringed by Your Contribution(s)
+ alone or by combination of Your Contribution(s) with the Work to
+ which such Contribution(s) were submitted. If any entity institutes
+ patent litigation against You or any other entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that your
+ Contribution, or the Work to which you have contributed, constitutes
+ direct or contributory patent infringement, then any patent licenses
+ granted to that entity under this Agreement for that Contribution or
+ Work shall terminate as of the date such litigation is filed.
+ 4. You represent that You are legally entitled to grant the above
+ license. You represent further that each employee of the
+ Corporation designated on Schedule A below (or in a subsequent
+ written modification to that Schedule) is authorized to submit
+ Contributions on behalf of the Corporation.
+ 5. You represent that each of Your Contributions is Your original
+ creation (see section 7 for submissions on behalf of others).
+ 6. You are not expected to provide support for Your Contributions,
+ except to the extent You desire to provide support. You may provide
+ support for free, for a fee, or not at all. Unless required by
+ applicable law or agreed to in writing, You provide Your
+ Contributions on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
+ OF ANY KIND, either express or implied, including, without
+ limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT,
+ MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE.
+ 7. Should You wish to submit work that is not Your original creation,
+ You may submit it to Spruce separately from any
+ Contribution, identifying the complete details of its source and
+ of any license or other restriction (including, but not limited
+ to, related patents, trademarks, and license agreements) of which
+ you are personally aware, and conspicuously marking the work as
+ "Submitted on behalf of a third-party: [named here]".
+ 8. It is your responsibility to notify Spruce when any change
+ is required to the list of designated employees authorized to submit
+ Contributions on behalf of the Corporation, or to the Corporation's
+ Point of Contact with Spruce.
+
+ Please sign: __________________________________ Date: _______________
+ Title: __________________________________
+ Corporation: __________________________________
+ Github Handle(s): _____________________________
diff --git a/assets/spruce-individual-cla.pdf b/assets/spruce-individual-cla.pdf
new file mode 100644
index 00000000..58aed094
Binary files /dev/null and b/assets/spruce-individual-cla.pdf differ
diff --git a/assets/undraw_docusaurus_mountain.svg b/assets/undraw_docusaurus_mountain.svg
new file mode 100644
index 00000000..431cef2f
--- /dev/null
+++ b/assets/undraw_docusaurus_mountain.svg
@@ -0,0 +1,170 @@
+
diff --git a/assets/undraw_docusaurus_react.svg b/assets/undraw_docusaurus_react.svg
new file mode 100644
index 00000000..e4170504
--- /dev/null
+++ b/assets/undraw_docusaurus_react.svg
@@ -0,0 +1,169 @@
+
diff --git a/assets/undraw_docusaurus_tree.svg b/assets/undraw_docusaurus_tree.svg
new file mode 100644
index 00000000..a05cc03d
--- /dev/null
+++ b/assets/undraw_docusaurus_tree.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/undraw_education_f8ru.svg b/assets/undraw_education_f8ru.svg
new file mode 100644
index 00000000..dd9368b0
--- /dev/null
+++ b/assets/undraw_education_f8ru.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/assets/whitelabel.jpg b/assets/whitelabel.jpg
new file mode 100644
index 00000000..9e384574
Binary files /dev/null and b/assets/whitelabel.jpg differ
diff --git a/blog/atom.xml b/blog/atom.xml
new file mode 100644
index 00000000..339526df
--- /dev/null
+++ b/blog/atom.xml
@@ -0,0 +1,10 @@
+
+
+ https://spruceid.dev/blog
+ Spruce Developer Portal Blog
+ 2015-10-25T23:29:00.000Z
+ https://github.com/jpmonette/feed
+
+ Spruce Developer Portal Blog
+ https://spruceid.dev/assets/logo.png
+
\ No newline at end of file
diff --git a/blog/rss.xml b/blog/rss.xml
new file mode 100644
index 00000000..2bb5318d
--- /dev/null
+++ b/blog/rss.xml
@@ -0,0 +1,11 @@
+
+
+
+ Spruce Developer Portal Blog
+ https://spruceid.dev/blog
+ Spruce Developer Portal Blog
+ Sun, 25 Oct 2015 23:29:00 GMT
+ https://validator.w3.org/feed/docs/rss2.html
+ https://github.com/jpmonette/feed
+
+
\ No newline at end of file
diff --git a/docs/code-of-conduct/index.html b/docs/code-of-conduct/index.html
new file mode 100644
index 00000000..3b4d5244
--- /dev/null
+++ b/docs/code-of-conduct/index.html
@@ -0,0 +1,31 @@
+
+
+
+
+
+
+
+Code of Conduct | Spruce Developer Portal
+
+
+
+
+
Speech is free, but speech has consequences. We at Spruce bring decades of
+community and open-source experience to the table, and it has taught us that
+good community is only possible with proactive effort and structure. To this
+end, we would like to invite you familiarize yourself with the long history of
+open source bottoms-up governance leading up to the "rulebooks" we follow.
Some large, veteran-filled communities have invested significant time and effort
+formulating very specific rulebooks, full of normative and non-normative
+statements worded as testably as possible. Pick whichever one fits your learning
+style best and study it closely: all roads lead to Rome, and taking on any of
+them in good faith will guarantee your contributions and communications in our
+corner of the open source world will be well-received in good faith.
As with all open-source-- if you see a typo or want to propose a feature
+upgrade, open an issue! All of these are hosted on git for this very purpose.
Our Open Source Manager (aka our "OS Yenta") prioritizes these questions and
+dispute resolution generally, so feel free to
+reach out early and often if you see a dispute or a
+conflict coming.
We'd love to accept your patches, feature upgrades, and adapters that can make
+DIDKit, Credible, and/or ssi compatible with other SSI systems and legacy
+systems. To make contributions like these, there are just a few small guidelines
+you need to follow.
Contributions to Spruce's OS projects must be accompanied by a Contributor
+License Agreement. (Don't worry about signing a CLA just for documentation bugs and
+requests, those are not licensed the same way as our software releases).
By signing a "CLA", you (and/or your employer) retain all copyrights to your
+contribution; this simply gives us permission to use and redistribute your
+contributions as part of the project and, if necessary, update the project's
+licensing without having to track down all contributors for explicit consent.
Please note that there are two distinct contributor agreements: a Corporate
+CLA and an Individual CLA. If your employment contract gives blanket or
+scoped control and ownership of your contributions to your employer (as almost
+all do in the modern software industry), the corporate contributor agreement is
+recommended. Please check with your employer, counsel, or HR staff if you
+have any questions about what you are signing or on whose behalf. Do not sign an
+individual CLA unless you are certain it does not contradict a pre-existing
+contract with your employer.
You generally only need to submit a CLA to Spruce once, so if you've already
+submitted one (even if it was for a different Spruce project), you don't need to
+do it again. Within two business days of being received, the submitted github
+handle(s) will be added to the allowlist for all our repos.
If you are not the sole contributor to a contribution (pull request), please
+identify all contributors in the pull request comment.
To add a contributor (other than yourself, that's automatic), mark them one per
+line as follows:
+@github_username
If you added a contributor by mistake, you can remove them in a comment with:
-@github_username
If you are making a pull request on behalf of someone else but you had no part
+in designing the feature, you can remove yourself with the above syntax. This
+updates the list of contributors to a given PR that must be checked against the
+CLA signees list to be accepted.
All submissions, including submissions by full-time Spruce employees, require
+review. We use GitHub pull requests for this purpose. Consult GitHub
+Help for more
+information on using pull requests. You may tag oustide reviewers additionally,
+but review by Spruce is still the condition of acceptance.
By default, Credible does not generate "on-chain" DIDs that publish their DID
+document to the main-net. Instead, people who install DIDKit (whether from the
+App Store or a build generated from our open-source code) will instead be
+prompted to generate an
+"implicit" DID, which
+can be used to hold credentials anonymously or to participate in small, local
+networks where users register themselves and "discover" one another locally.
Given the intricacies of privacy law and the consequences of putting
+personally-associated identifiers into immutable, publicly-readable storage, we
+do not recommend on-chain DIDs for general use, and this is why they are
+disabled by default in our demonstrator app. Legal entities that are
+bootstrapping an existing strong public presence on web2 (i.e., companies with
+major websites and infrastructure access to them) are encouraged to use
+did:web, which is implemented
+out-of-the-box in DIDKit
+and can be resolved by Credible verification.
There are, however, other use-cases. A DID may need to be publicly resolvable,
+and if it's not being used in public and correlated, publishing its DID Document
+to a blockchain might be an appropriate way of doing so. An independent artist
+selling NFTs or e-books might want to publish a DID Document and be "resolvable"
+to allow direct communications and to "hang a shingle" for their micro-business,
+as it were. A large enterprise might want to provision its employees with mobile
+phones that handle signatures and authentication functions on a private network,
+or even a "private blockchain". A Credible wallet can receive and present
+credentials of which an inanimate object is the subject. All of these could
+require a private key generated on a web-wallet, a phone, or a virtual/emulated
+phone to register its DID Document on a distributed ledger.
For these use-cases, we are including the following step-by-step instructions-- how these fit into a proof-of-concept or production project will, of course, take some further research.
Before deploying smart contracts en masse or building smart-contract
+capability into a custom build of Credible, you should get to know the Tezos
+DID Manager.
+To do so, use the node package manager to install the Taquito virtual machine
+interface from the contract/taquito folder of a DIDKit
+environment.
+This will turn your local sandbox into a Tezos-connected local sandbox.
As you can see in the readme
+file
+for the smart contract, the default target for DID Manager smart contracts is
+the Tezos main-net, but this can be overriden with the -u / --url flag.
Know your smart contract (practice makes perfect)#
Florencenet is the best test-net to use, as it runs the current stable code and
+is actively maintained. There are, however, various
+options which might be
+more appropriate to your use-case or project.
There is also a faucet interface for manually
+generating test-accounts (one at a time) that works on Florencenet or on another
+testnets.
Download a faucet file to your local /contract/taquito folder and then use it to
+test the RPC calls and returns outlined in our contracts/taquito folder
+readme.
For example, if you take a JSON file from the faucet and copy it into your
+DIDKit DID manager folder as "faucet.json", you can run this command from the
+same folder:
And it will create a smart contract on florencenet that resolves to a DID
+Document with service block that
+looks like this (except with a valid tz1 address instead of tz1...)
"service": [{
"id": "did:tz:florencenet:tz1...",
"type": "TezosDiscoveryService",
"serviceEndpoint": "https://example.com"
}]
When you run this command over the RPC interface, it will return the name of the
+smart contract (KT1...), which you can then see querying a florencenet block
+explorer like better-call.dev, and which yields a stable web URL that looks like this:
`https://better-call.dev/florencenet/KT1...`
Playing around with the options (on a testnet) is a good way to get comfortable with your options-- without paying any transaction fees or worrying about anyone's privacy.
If you would like to build on-chain registration into a custom build of
+Credible, you will have to build RPC calls into your application based on what
+you learned experimenting above. Similarly, "off-chain registration" or local
+registration of keypairs into a more gated or permissions network is also
+possible, but out of scope for the Credible SDK.
When architecting such a system though, we strongly recommend thinking about the
+correlation, privacy, and context-preservating risks involved in publishing
+identifiers of any kind: what information can be gleaned and correlated to other
+data by crawlers of various kinds? What deletion or tombstoning options are
+available for "pruning" or removing those publications from the crawlable public
+record? What historical query capabilities are offered by that record system or
+ledger, after a takedown/deletion request has been executed?
This video demonstrates the QR-triggered issuance flow described on the Core
+Concepts page. Note that:
java.theosirian.com is the test-server generating the QR code issuing
+the credential. The pop-up, which is enabled by default, serves to prevent
+spoofing or phishing attacks, should the page serving the qR and
+the contents of the QR be in different domains. The consent pop-up can be
+skipped if the requesting domain matches the domain referenced from a QR
+code. Further validation can also be added as a failsafe or alternative.
The credential offered, containing a proof of control of a doximity.com
+account, is dummy data from a client project. The contents displayed should
+normally come from a processing of the contents of the actual credential, but
+in this demo, they are mocked up graphically by a few manual overrides in the
+folder /lib/app/pages/credentials/widget/document/ . For more details, see the VC Display example
Credible is an SDK that we have optimized for white-labelling, i.e., bundling
+into apps that have their own design goals and non-Verifiable Credential
+capabilities. One example of how we have optimized the design of Credible for
+modularity and adaptation to various contexts is that the display of VCs is
+highly adaptable-- and the first thing you would need to adapt in most
+use-cases, before getting into finer points of user experience.
The component that renders the credential is implemented by the DocumentWidget
+class located at
+lib/app/pages/credentials/widget/document.dart
+and the model rendered by the component is implemented by the
+DocumentWidgetModel
+class located in the same file. Changing and adding traits to these two classes
+will change how Credible renders VCs to its user after building credible from
+source.
By default, the DocumentWidgetModel provided by Credible displays only the [unresolved, un-aliased] contents of the top-level issuer property of each VC and its "status" (currently defined by whether the expiration date is in the future or the past; more involved status mechanisms are forthcoming).
To add display of other kinds of information stored in the VC, just add it to the DocumentWidgetModel class and set the values from the CredentialModel inside the factory method factory DocumentWidgetModel.fromCredentialModel(CredentialModel model).
Here is an example, written in Dart:
class DocumentWidgetModel {
// Current class fields.
// Add your custom fields that will be extracted from the credential model
// Extract your field contents from withing the `CredentialModel` type
// The `data` field contains the raw data of the Verifiable Credential
// so any value can be extracted.
final myCustomField = model.data["myCustomField"];
+
return DocumentWidgetModel(..., myCustomField);
}
}
Rendering the newly-added fields in the final end-user interface#
The DocumentWidget component receives an instance of DocumentWidgetModel and renders its content as a tree of widgets. Any fields you've pulled out of the data object into a named property are available in each individual document object.
To render these new properties, simply update the widget's build method by adding your own custom components. Note that when a property is not found in the .data object, the value for the property will be set to NULL; for this reason, it is best to check for a non-null value at display runtime and build in some logic accordingly.
Here is an example in Dart:
@override
Widget build(BuildContext context) => Container(
// ...
child: Padding(
// ...
child: Column(
// ...
children: [
// Other fields widget
// ...
if (model.myCustomField != null) {
const SizedBox(height: 24.0), // Add a spacing between fields.
DocumentItemWidget(
label: 'My Custom Field:',
value: model.myCustomField,
)
;
}
else {
const SizedBox(height: 48.0); // Add a spacing between fields.
Credible's current authentication model is simple: services request a verifiable
+credential issued to the wallet-holder at each authentication, and an
+interactive presentation is used to initiate a session. Future extensions and
+alternatives are roadmapped.
The presentation request formulated by a "relying party" (i.e., the service
+relying on credible to authenticate its user) currently comes in only three
+forms:
Unspecified VP Request for enrollment: any wallet holding 1 or more VCs
+can pass this verification to create an account keyed to the presenting
+identifier.
Unspecified VP Request for authentication: if the relying party wants to
+allow any enrolled party to sign in, they can simply request a presentation
+of any credential and check the received credential's presenter identifier
+against records of enrolled users from above. Anyone who has previously been
+enrolled using the above mechanism can be authenticated by this mechanism.
Specified VP Request for authentication: if the relying party retained
+the wallet/identifier pair used in an interactive enrolment, they can simply
+specify the same identifier in a VP request-- only that identifier and a
+valid VP signature from it will pass.
It is presently only possible to verify that a verifiable presentation is valid,
+i.e. that the signature is valid and corresponds to the public key & identifier
+(DID) passed with it. For this reason, the passed DID may be used as a unique,
+stable user identifier between sessions on the basis that a valid VC-holding
+wallet will consistently prove the same private key for the life of the
+wallet/identifier combination. Please note that in the current release, no
+verification based on the content of the presented credential is yet
+supported.
See also the code snippets provided in the CHAPI example for how Credible can
+authenticate to another service.
Future versions will be able to apply business logic to specify a subject DID,
+or a subject DID type (by method), or a date range of issuance, or an issuer,
+etc etc. Without such specification against which to validate a authenticating
+presentation, Credible's authentication should be considered "for testing
+purposes only" and not used to authenticate users to real-world systems.
Spruce is watching closely as the standards around OIDC evolve, as well as the
+DIDComm protocol incubated across the DIF and Aries communities. We have every
+intention of supporting both these authentication mechanisms as they mature.
If the wallet manages multiple keypairs/subject identifiers, the user will be
+prompted to select one. If no additional subject identifiers are available, the
+wallet will default to the on-device keypair created at time of installation. If
+this cannot be found, the protocol will throw an exception.
After receiving a CredentialOffer from a trusted host and selecting (or
+defaulting to) an identifier to which that credential will be issued, the wallet
+app calls the issuer's API with the selected subject_id in the form body. If
+the on-device identifier is chosen or defaulted to, it must first be wrapped in
+a "DID:Key" object (See glossary), which is derived deterministically from the
+keypair stored in the FlutterSecureStorage, which is backed by KeyStore on
+Android and Keychain on iOS.
Note: some features in this flow are current unstable and may not work as documented.
The flow of events and actions is thus:
User is presented a credential preview to review and make their decision
+whether or not receive it (coming soon: option to select subject DID if
+wallet holds multiple)
App makes a POST request to the initial URL with subject_id set to this
+DID;
App receives and stores the new credential in app storage;
After receiving a VerifiablePresentationRequest from a trusted host, the
+wallet app calls the requestor's POST API with the presentation value set in
+the body. This value is a stringified JSON-LD presentation object generated
+from the selected credential and signed with the credential's private key using
+DIDKit.issuePresentation.
Note: Verifiable Presentation requests are presented in the form specified by the current W3C-CCG VP Request Spec draft. As community-wide, vendor-agnostic specifications for Credential/Presentation Exchange, Wallet Portability, and DID-based Transport come into maturity, we will support them in future versions.
Verifiable Credentials combine properties and superpowers from many different
+mental models. They are like portable, free-floating data units, which are not
+exactly documents or data points or records. They are signed and thus
+tamper-evident, and thus share much of the verifiability of blockchain data or
+signed PDFs insofar as the signatures they contain can be properly verified by
+reference to the identities included inside the document. Particularly in the
+form of JSON-LD verifiable credentials, they are highly portable, in that the
+structure of their data can often be reconstructed years later and completely
+out of their original context. For more on JSON-LD and linked data, see the
+Semantics section of the DIDKit Core
+Concepts entry.
The mental model of a "wallet" for storing directly and manually controlled
+information and assets has become increasingly common in recent years thanks to
+the growing popularity of ledger-based cryptocurrencies, NFTs, and other virtual
+assets controlled by cryptography. Just as wallet software makes cryptographic
+key management intuitive and human-scaled when handling such
+cryptographically-controlled assets on common ledgers, so too can "wallet"
+interfaces make cryptographically-controlled documents like Verifiable
+Credentials manageable.
In the verifiable credential space, a "wallet" is traditionally assumed to
+manage one or more strong cryptographic identifiers, which must be authenticated
+to an issuer to receive identifier-specific or identifier-locked credentials.
+This is often assumed to be a direct and interactive process, as is the process
+of presenting these strong credentials to verifiers (usually
+double-authenticated, to both the verifier and to the credential, with two
+respective identifiers). Credible Wallet was designed to a secure,
+production-grade, yet lightweight and general-purpose wallet for such use cases,
+completely free of platform-, vendor-, or blockchain-lock-in.
There are, however, fiduciary, automated, and/or "custodial" wallets (by analogy
+to cryptocurrency). Here, the dividing line between wallets and agents,
+services, and service providers gets a little blurry; particularly when the
+wallet holder is a legal entity or non-human actor, this is an important wrinkle
+on the concept of the "wallet." Here, DIDKit may be combined with enterprise
+identity and security platforms to provide a less human-scale "wallet" for
+handling strong credentials about human and non-human actors.
Decentralized Identifiers are stable identifiers which are bound to a
+controlling keypair, which is usually rotatable without changing the identifier.
+This is achieved by a publication mechanism maintaining information about key
+material in verifiable data stores (usually distributed ledgers) over time. This
+information is referred to as a DID Document. The
+specification governing these identifiers is
+maintained by a dedicated W3C working group,
+of which Spruce is a member. For more information on the W3C, see the Further
+Reading section.
A record returned by a query for a DID, containing information on how to verify
+information linked in some way to that identifier. The name can be misleading,
+since in many cases this "document" is entirely ephemeral or contextual and not
+intended to be a static file or document stored or cached anywhere. It is
+sometimes couched in a "Resolution object," which contains metadata about the
+query and resolution process, although most application developers have no need
+to worry about these DID mechanics. For a The
+specification governing the
+DID-->Document resolution process is maintained by a dedicated W3C working
+group, of which Spruce is a member. For more
+information on the W3C, see the Further Reading section.
A set of interdependent governance, publication, and discovery mechanisms for
+DIDs in a given DID namespace, specified by a shared specification. This
+specification explains how to validate a DID (namespace rules), where to query
+and what to expect back when resolving a DID, etc. The
+registry of compliant
+specifications for DID Methods is maintained by a dedicated W3C working
+group, of which Spruce is a member. For more
+information on the W3C, see the Further Reading section.
A special DID Method that generates conformant, offchain DID documents for
+local, private, and/or ephemeral resolution from a keypair. This can be helpful
+for integrating conventional PKI or signing infrastructure with DID issuance, or
+to allow caching or local resolution of DID documents where it is undesirable or
+impossible to resolve remote DIDs. The
+specification for this method was
+originally created in, and maintained in, the W3C-Credentials Community
+Group.
Further educational/contextual resources on decentralized identity topics can be
+found on the Education page of the
+Decentralized Identity Foundation.
For insight into the core specifications authored and maintained by the W3C
+working group, the best overview is the github repositories section of their
+homepage on W3.org. The largely overlapping
+Credentials Community Group, with weekly open,
+recorded, and scribed calls open to W3C
+non-members, is also a good venue for getting to know the debates around the
+core specifications.
Credible is a lightweight wallet for individuals to manage DIDs and VCs from
+their mobile phones. It is white-label friendly, open-source, and built on our
+core SSI libraries. As soon as it is feature-complete and ready for external
+review, it will even be downloadable from the appstore in its basic, unextended
+form. Over time, we expect to integrate many DID methods and presentation
+protocols to make this the wallet fully-featured without being ledger-bound or
+vendor-favoring.
We are also in the process of listing Credible on the iOS TestFlight and Android
+Play Beta programs, and eventually their respective app marketplaces plus
+F-Droid.
Please follow the official instalation instructions available
+here to install Flutter,
+don't forget to also install the build dependencies for the platform you
+will be building (Android SDK/NDK, Xcode, etc).
We currently only support build this project using the dev channel of Flutter.
To change your installation to the dev channel, please execute the following command:
$ flutter channel dev
$ flutter upgrade
To confirm that everything is setup correctly, please run the following command
+and resolve any issues that arise before proceeding to the next steps.
The wasm-pack cannot yet be compiled from crates.io. For now, to build the WASM
+target you will need wasm-pack, the fastest way is to fetch the script from
+github and run it in the credible root directory:
To build Credible for WEB using ASM.js you will need
+binaryen, which allows the conversion
+of DIDKit WASM to ASM.js. This is necessary in context where WASM support is not
+available and DIDKit needs to run in pure Javascript. More detailed instructions
+on how to build binaryen can be found
+here.
If you are in a UNIX-like distribution you just have to clone the repo and build,
+we recommend cloning into your ${HOME}, to avoid having to specify the
+${BINARYEN_ROOT} variable:
Not that binaryen support for OS X and Windows is still limited, so it is highly
+recommended to build it in a linux shell on OS X and on WSL2 in Windows. For
+instructions on building it natively in Windows, see the binaryen
+FAQ on github.
This project also depends on two other Spruce projects,
+DIDKit and
+SSI.
These projects are all configured to work with relative paths by default, so it
+is recommended to clone them all as subdirectories of the same root directory,
+for example
+$HOME/spruceid/didkit
+$HOME/spruceid/ssi
+$HOME/spruceid/credible
+$HOME/spruceid/treehouse
+etc
To build Credible for Android, you will require both the Android SDK and NDK.
These two dependencies can be easily obtained with Android
+Studio, which install further
+dependencies upon first being opened after installation. Installing the
+appropriate Android NDK (often not the newest) in Android Studio can be
+accomplished by going to Settings > Appearance & Behavior > System Settings >
+Android SDK and selecting to install the "NDK (Side by Side)". An alternative
+method of installing SDK and NDK without Android Studio can be found in the
+optional
+install_android_dependencies.sh
+script included here.
If your Android SDK doesn't live at $HOME/Android/Sdk you will need to set
+ANDROID_SDK_ROOT like so:
$ exportANDROID_SDK_ROOT=/path/to/Android/Sdk
Note: Some users have experienced difficulties with expected cross-compilation
+artefacts missing from the newest NDK, which is downloaded by default in the
+installation process. If you experience errors of this kind, you may have to
+manually downgrade or install multiple NDK versions as [shown
+here])(img/ndk_downgrade.png) in the Android Studio installer (screengrabbed
+from an Ubuntu installation). Alternately, running all or parts of the
+install_android_dependencies.sh script may be
+helpful.
If your build-tools and/or NDK live in different locations than the default ones inside /SDK/, or if you want to specify a specific NDK or build-tools version, you can manually configure the following two environment variables:
To build Credible for iOS you will need to install CocoaPods, which can be done
+with Homebrew on MacOS, WSL2, or Linux-based systems. You will also need
+XCode, which is not available for WSL2 or
+Linux systems; it is currently possible but not recommended to install XCode
+in those build environments.
To build Credible for WASM, you will need the Node.JS and its package manager,
+npm to be installed:
$ sudoaptinstall nodejs
$ sudoaptinstallnpm
Note: in some environments, such as Ubuntu 18.04, npm may not automatically
+install a new enough version for our makefile to execute succesfully; overriding
+it with npm's internal
+commands may be
+necessary.
If you want to run the project on your browser, you can use:
$ flutter run --no-sound-null-safety -d chrome --csp --release
Otherwise, Flutter allows us to build many artifacts for Android, iOS and WEB,
+below you can find the most common and useful commands, all of which you should
+run from the root of Credible.
If you don't have support for WASM, you'll probably need to provide your own
+canvaskit dependency without WASM as well as DIDKit, to do that you need to
+specify the FLUTTER_WEB_CANVASKIT_URL in the build command like below.
$ flutter build web \
--no-sound-null-safety \
--csp \
--dart-define=FLUTTER_WEB_CANVASKIT_URL=vendor/ \
--release
For more details about any of these commands you can run
While we are ready to migrate to Dart with nullsafety, a couple of the
+dependencies of the project are still lagging behind, so we need to add --no-sound-null-safely to both run and build commands for the time being.
NPM may through an opaque error when compiling to WASM or ASM.js if apt
+install has installed too old of a version of npm based on your operating
+system kernel. This can be manually overridden from npm's internal
+commands
This shell script can be used to quickly generate a large volume of VCs for testing purposes. The generated VCs use the bare-minimum schema and contain essentially nothing aside from a unique UUID each, in the id field.
To generate these VC ids, they use the commonplace uuidgen command. For more realistic sample VCs, simply start with a credential definition from a real-world context, and populate values for all the fields, such as names and addresses, with command-line tools or spreadsheets of dummy data.
In this script, a verification method is derived from a local key and manually passed with the -v parameter. This is not the default behavior of DIDKit's verification function, but it greatly accelerates the verification of a large batch of VCs being testing against the known key material and verification method of a known issuer.
Were one to remove the key.jwk check, the generation of a verification method, and the passing of that method to the verification function, a verification method would be extracted for each VC verified, from the DID Document of the issuer, which would be resolved each time as specified in the VC being verified. This is the default behavior of DIDKit.
This document gets wrapped around the keypair generated (or passed) in the previous step. For more context on the DID:key method, see the specification.
This is used to identify the key in linked data proofs. Verifiers of such proofs query a DID found in a credential based on what [registered] proof type (i.e., what kind of signatures) it needs key material to verify.
Here, we'll issue an example credential (unsigned) and save it to a file. In
+this credential, the issuance date, id, and credential subject id are arbitrary,
+but in real-world usage these are diverse and critical properties. For more info
+about what these properties mean, see the Verifiable Credentials Data Model
+specification. Note that SUBJECTDID and
+ISSUERDID fields need to be URIs, so if you are using non-DID identifiers such
+as certificates or UUIDs, they need to be prefixed with the approriate URN
+prefix,
+i.e., "urn:uuid:", etc.
We ask DIDKit to issue a verifiable credential using the given keypair file, verification method, and proof purpose, passing the unsigned credential on standard input.
DIDKit creates a linked data proof to add to the unsigned credential, and outputs the resulting newly-issued (signed) verifiable credential on standard output, which we save to a file.
We pass the newly-issued signed verifiable credential back to didkit for verification using the given verification method and proof purpose.
DIDKit then outputs the verification result as JSON and saves it. If verification is successful, the command completes successfully (returns exit code 0).
if! didkit vc-verify-credential \
-v "$verification_method"\
-p assertionMethod \
< credential-signed.jsonld \
> credential-verify-result.json
then
echo'Unable to verify credential:'
print_json credential-verify-result.json
exit1
fi
echo'Verified verifiable credential:'
print_json credential-verify-result.json
echo
Create a verifiable presentation that embeds the verifiable credential.#
Prepare to present the verifiable credential by wrapping it in a verifiable presentation (VP).
The id here is an arbitrary URL for example purposes; VPs are often but not always uniquely identified, whether by identifiers, URLs, or URIs.
Pass the unsigned verifiable presentation to DIDKit to be issued as a verifiable presentation. * DIDKit signs the presentation with a linked data proof, using the given keypair, verification method and proof type.
We save the resulting newly created verifiable presentation to a file.
note
In most use-cases, the holder field contains a DID or other identifier verifiably linked to the key material signing the presentation, which has some relationship to the credential(s) being presented. The classic example is a fresh and interactive proof of being the [human] subject identified by a credential, but there are many VP use-cases as well. This may be a manual, consented, unique and interactive identity assurance operation, but it can also be an assurance of the identity of a machine or a legal entity, operated by an API call or an automation carried out by a fiduciary/trusted piece of software, etc.
In these examples, the keys representing the two parties are stored in expressive filenames, 'issuer_key' and 'holder_key'. There are, however, no differences between these keys, and the JWK filenames were chosen simply to clarify the example; there are no restrictions on them.
This document gets wrapped around the keypair generated (or passed) in the previous step. For more context on the DID:key method, see the specification.
This is used to identify the key in linked data proofs. Verifiers of such proofs query a DID found in a credential based on what [registered] proof type (i.e., what kind of signatures) it needs key material to verify.
In this example credential, the issuance date, id, and credential subject id are arbitrary, but in real-world usage these are diverse and critical properties. For more info about what these properties mean, see the Verifiable Credentials Data Model specification
Ask didkit to issue a verifiable credential using the given keypair file, verification method, and proof purpose, passing the unsigned credential on standard input.
DIDKit creates a linked data proof to add to the credential, and outputs the resulting newly-issued verifiable credential on standard output, which we save to a file.
Pass the unsigned verifiable presentation to DIDKit to be issued as a verifiable presentation. * DIDKit signs the presentation with a linked data proof, using the given keypair, verification method and proof type.
We save the resulting newly created verifiable presentation to a file.
note
In most use-cases, the holder field contains a DID or other identifier verifiably linked to the key material signing the presentation, which has some relationship to the credential(s) being presented. The classic example is a fresh and interactive proof of being the [human] subject identified by a credential, but there are many VP use-cases as well. This may be a manual, consented, unique and interactive identity assurance operation, but it can also be an assurance of the identity of a machine or a legal entity, operated by an API call or an automation carried out by a fiduciary/trusted piece of software, etc.
In these examples, the keys representing the two parties are stored in expressive filenames, 'issuer_key' and 'holder_key'. There are, however, no differences between these keys, and the JWK filenames were chosen simply to clarify the example; there are no restrictions on them.
This project demonstrates use of verifiable credentials and presentations to
+enable user authentication for an application. See the DIDKit repository's
+examples folder for code snippets.
The web application makes use of DIDKit to handle credentials and presentations,
+please refer to the project's documentation to build the library for your platform,
+libdidkit.so on UNIX-like systems, didkit.dll on Windows, libdidkit.dylib
+on MacOS, etc.
Then you will have to add it to the classpath of your platform. On UNIX systems,
+for example, you can copy (or symlink) libdidkit.so to /usr/lib or
+/usr/local/lib. In the instructions below, we will list commands to create a
+symlink to the local build folder.
You will then require the Java artifact (didkit.jar). This example project
+already has a symlink in the build directory. All you have to do is run the
+following commands in the root folder to build everything and ensure proper
+linking:
$ cargo build
# Use libdidkit.so for UNIX-like, didkit.dll for Windows, libdidkit.dylib for MacOS
If you are trying to use DIDKit with an external Java project, you will have to
+point your build tool (Gradle, Maven, etc) to the didkit.jar file. Also
+ensure that the static library (e.g., libdidkit.so is in the
+java.library.path or specified using the proper environment variables, such
+as LD_LIBRARY_PATH on UNIX-like. Please refer to the full documentation for
+those tools. Here is an excerpt of how we have listed it on this project's
+pom.xml for Maven:
This project uses a MySQL database to store the user entity. We will use the
+root user for simplicity because this is only an example. In your actual
+deployments, it is very important that you configure the correct accounts,
+policies, and permissions for your SQL installations.
We are now ready to build and run the installation. To download the required
+Java dependencies, build the project, and then run it, you can execute the
+following commands from the root project directory:
$ cd examples/java-sprintboot
$ LD_LIBRARY_PATH=`pwd` ./mvnw spring-boot:run
You can then load http://localhost:8081 to see the web application.
To verify that DIDKit has been setup correctly, you can then run:
$ curl -v http://localhost:8081/version
And you should expect to see a version string in the response.
Visit http://localhost:8081 with your web browser.
Create a user by clicking "Sign Up" on the navigation bar.
Log in with your newly created user by clicking "Sign In" on the navigation
+bar.
Issue yourself a credential to use for login instead of username and
+password. You can receive credentials in the example CHAPI wallet or
+using the QR code workflow and
+Credible mobile wallet.
This project demonstrates how to implement a CHAPI-conformant Wallet using
+DIDKit compiled to WASM and the Svelte
+web development framework. It uses did:key as its only DID Method.
Features:
Simple listing of credentials
Responds to GET and STORE requests
[STORE] Verifies credentials with DIDKit and stores them.
[GET] Issues VPs generated and signed using DIDKit
To be able to run this example, you will need to build DIDKit for the WASM
+target. More instructions about the process can be found
+here. You will also
+need the Yarn package manager.
In short, you need to install the wasm-unknown-unknown Rust target and
+wasm-pack, which can be done with the following command on the root of
+DIDKit:
You can run the newly built app with yarn run start. This uses
+sirv, which is included in your
+package.json's dependencies so the app will function when deployed to
+platforms such as Heroku.
Of all the interfaces DIDKit exposes, the C library is closest to the Rust original.
For a quick function & type reference, you can study the test.c file.
A C header file can be built, but it resides in a separate crate that must be compiled separately after building DIDKit. Instructions can be found here
To build manually and just for Android, building from the C wrapper is faster and simpler than going through Flutter; for instructions, see the Android section below.
More detailed C tests can be found in the C
+library of the
+DIDKit repository on GitHub. This doubles as a comprehensive code snippet
+demonstrating key calls and responses in C.
DIDKit can be exposed to Android projects using the Android Library (AAR file). This AAR file includes Java class files using JNI, and binary shared libraries for Android's supported architectures (x86, armeabi-v7a, arm64-v8a, x86_64). The AAR can be added to existing Android projects using Android Studio or Gradle.
Android SDK and NDK for Linux x86_64. The Android SDK is expected to be installed at ~/Android/Sdk. If it is somewhere else instead, you can specify it with a Make variable, e.g. make ANDROID_SDK_ROOT=/other/location/android-sdk.
Rust Android targets are also required. To install those with rustup, run:
For setting up an HTTP server, whether for internal use, over the open internet, or both, we recommend using our dockerized HTTP server. Instructions below
Instructions for building manually can be found on the main Installation page
See the Examples section below for automation and testing building blocks.
The HTTP server is containerised and available under
+ghcr.io/spruceid/didkit-cli.
You can use the Docker image as a CLI:
$ docker run ghcr.io/spruceid/didkit-cli:latest --help
Note: You can pass JWKs either by sharing a volume with docker run --volume, or by passing the JWK directly with docker run -e JWK=$MY_JWK or docker run didkit-http --jwk $MY_JWK.
Issue a verifiable credential. Reads credential on stdin,
+constructs a linked data proof to add to the
+credential, and outputs the resulting verifiable credential.
The proof type is set automatically based on the key file provided.
+JWK parameters besides the cryptographic components, such as
+kid (Key ID), are ignored currently. For an RSA key, the
+alg (Algorithm) parameter is ignored and RS256 is used for
+it, for RsaSignature2018.
-C, --challenge <challenge> - challenge property of the
+proof
-c, --created <created> - created property of the proof.
+ISO8601 datetime. Defaults to the current time.
-d, --domain <domain> - domain property of the proof
-k, --key-path <key> (required, conflicts with jwk):
+Filename of JWK for signing.
-j, --jwk <jwk> (required, conflicts with key-path):
+JWK for signing.
-p, --proof-purpose <proof-purpose>proofPurpose
+property of the proof.
-v, --verification-method <verification-method>verificationMethod
+property of the proof. URI for proof verification
+information, e.g. a public key identifier.
Verify a verifiable credential. Reads verifiable credential on
+standard input, and outputs verification result. Returns exit
+status zero if credential successfully verified, or non-zero
+if errors were encountered.
Options are linked data proof options as specified in
+ld-proofs and vc-http-api. If there is more than one
+proof present, at least one must pass all the requirements
+passed in the options.
-C, --challenge <challenge> - The challenge property
+of the proof must equal this value.
-c, --created <created> - The created property of the
+proof must be on or after the given ISO8601 datetime. Defaults
+to the current time.
-d, --domain <domain> - The domain property of the proof
+must equal the given value.
-p, --proof-purpose <proof-purpose> - The proofPurpose
+property of the proof must equal this value.
-v, --verification-method <verification-method> - The
+verificationMethod property of the proof must equal this value.
Verify a verifiable presentation. Reads verifiable presentation
+on stdin, and outputs verification result. Returns exit status
+zero if presentation successfully verified, or non-zero if
+errors were encountered.
For setting up an HTTP server, whether for internal use, over the open internet, or both, we recommend using our dockerized HTTP server. Instructions below
Instructions for building manually can be found on the main Installation page
Rather than design our own API, we have opted to adopt (and contribute to) the W3C Credentials Community Group's neutral, open standard for VC-handling APIs, the vc-http-api; we invite you to consider doing the same for your projects, if it is a reasonable fit for your needs. For details, see that project's documentation and its separate use cases document.
The server is run as a Rust "Tower" Service, which can be spun up with a single line upon installation.
The HTTP server is containerised and available under
+ghcr.io/spruceid/didkit-http.
You can use the images as a CLI:
$ docker run --init -p 8080 ghcr.io/spruceid/didkit-http:latest --port 8080
Note: You can pass JWKs either by sharing a volume with docker run --volume, or by passing the JWK directly with docker run -e JWK=$MY_JWK or docker run didkit-http --jwk $MY_JWK.
Provide issuer keys using the -k/--key-path or -j/--jwk options. If none are provided, issuance functionality will be unavailable. If one is provided, that one will be used to sign all credentials and presentations, regardless of the proof options in the issuance request. If more than one key is provided, the issuance request may identify which key to use for signing by its DID in the verificationMethod property of the proof options; if none is identified in that property, the first key is used.
Rust crate didkit-http contains DIDKit's HTTP server implementation as a Rust
+library. Struct didkit_http::DIDKitHTTPMakeSvc implements a Tower
+(hyper)
The following routes implement W3C CCG's VC HTTP API (vc-http-api)v0.0.1. POST bodies should be typed as application/json. Output will be application/json on success; on error it will be either application/json or plain text. For more details, see the documentation for the vc-http-api specification.
Issue a verifiable credential. The server uses its configured key and the given linked data proof options to generate a proof and append it to the given credential. On success, the resulting verifiable credential is returned, with HTTP status 201.
Verify a verifiable credential. The server verifies the given credential with the given linked data proof options. To successfully verify, the credential must contain at least one proof that verifies successfully. Verification results include a list of checks performed, warnings that should be flagged to the user, and errors encountered. On success, the errors list will be empty, and the HTTP status code will be 200.
Create a verifiable presentation. Given a presentation and linked data proof options, the server uses its key to generate a proof and append it to the presentation. On success, returns the verifiable presentation and HTTP status 201.
DIDKit exposes a straightforward set of Java bindings, using the Java Native Interface (JNI).
The JAR file includes all of DIDKit's Java class files. To use this in an
+application, you must also include the shared library (libdidkit.so) in your
+application in the Java library path
Android Library (AAR file) for DIDKit. The AAR file includes Java class files using JNI, and binary shared libraries for Android's supported architectures (x86, armeabi-v7a, arm64-v8a, x86_64). The AAR can be added to existing Android projects using Android Studio or Gradle.
Android SDK and NDK for Linux x86_64. The Android SDK is expected to be installed at ~/Android/Sdk. If it is somewhere else instead, you can specify it with a Make variable, e.g. make ANDROID_SDK_ROOT=/other/location/android-sdk.
Rust Android targets are also required. To install those with rustup, run:
For a quick function & type reference, you can check out the Issuing a Credential and Options sections of the /lib/node/README.md file in the DIDKit repo. Better yet, install it and run the commands yourself!
To test your installation or just to see examples of calls and returns with valid DID-key test vectors, see the provided test script
To use DIDKit in Python, import the didkit library and manipulate the didkit
+object as you would any other. It contains all the same methods and properties
+as the didkit object in Rust, so you can refer to the Rust
+docs for an overview of the core structure of
+DIDKit as a library.
The method issueCredential, for example, takes all the properties you would
+expect, as strings (mind the escape quotes!) and returns a credential as a JSON
+object that the user then .dumps or .loads. See this example from the Python-Flask example
+project:
Our core libraries are built in Rust and we are active members of the growing Rust community.
Our code comments inside the core libraries auto-generate an authoritative and
+comprehensive Rust Documentation site at each
+versioned release through the crates.io package manager.
Installation via the crates.io package manager is the easiest way to get started.
Instructions for building manually can be found on the main Installation page
Spruce is very proud to have built these core products to date using
+the Rust language, which offers a secure, performant, and memory-safe
+alternative to the dominant web development languages of today.
DIDKit can also be downloaded & updated from crates.io, Rust's native package
+manager, from inside of other Rust projects. DIDKit (and its underlying ssi
+crate) can be called as library dependencies inside of a Rust environment, but
+they are not targets in crates.io, (and thus, cannot be installed by a simple
+cargo install call).
Note that many of the DIDKit functions and traits in turn call functions and
+traits in ssi, a separate package/crate on which
+it depends. Similarly, each DID method that you want a given DID Kit instance
+to implement is also distinct library (rather than simply a trait), so
+constraining a specific instance of DIDKit to a specific subset of available DID
+Methods is best achieved by modifying the [dependencies] section of the
+/lib/Cargo.toml file.
Note: the core library /ssi/ also keeps its own, distinct changelog, where
+low-level functions get added to be wrapped/exposed by DIDKit's various
+interfaces. DIDKit pulls the newest ssi by commit-specific dependency calls,
+and the version numbers of the two libraries are not "in lockstep"; hotfixes or
+minor, "nightly" features are often pulled into DIDKit from ssi between major
+versions.
DID Kit makes as accessible, simple, and portable as possible
+the core engine of any credentialing system built around W3C
+verifiable credentials: the issuance and verification mechanisms.
The generation of VCs and VPs requires three separate inputs:
Key Material: of the issuer in the case of a VC, or of
+the holder in the case of a VP
Data Payload: typically JSON in the case of VCs, and an
+array of 1 or more VCs in the case of VPs
Data Structure: in the form of JSON-LD Schema
From these, a 4th element, the "proof" is generated by signing
+over 2 and 3 with 1. Once these four elements have been
+combined, a verifiable credential is a portable, tamper-evident
+unit of data. Optionally, the data often contains the identifier
+of a "data subject" of the credential; this identifier is often
+the vital link between a VP and its contents, rendering the
+whole package meaningful and verifiable.
Running the process in reverse from the side of a verifier, we
+start from the whole tamperproofed package. Verifying the proofs
+on a VC or VP requires fetching key material and verification
+method (i.e., the type of key material) from the listed issuer
+or holder (respectively). It is important to note that the data
+"payload" of a VP is usually one or more VCs and nothing else,
+so verifying the outer layer (the VP) reveals a new proof and
+identity to be queried for key and key type (the VC).
The third element in the above explanation can be the hardest for
+developers new to the world of decentralized identity and
+credentialing to grapple with. This is because the data structure
+mechanisms assumed and expressed in the examples of the core
+W3C specifications are so-called "open-world," semantic-web
+semantics expressed in JSON-LD, rather than the closed-world,
+static JSON schema that most developers use day in and day
+out. While static JSON schema are easier to use and easier
+to secure in conventional ways, the more dynamic and
+open-data-friendly mechanics of JSON-LD are given pride of
+place in the decentralized identity community.
note
DIDKit was built for LD data structures, and currently requires
+VC semantics to be expressed in JSON-LD, but support for static
+structures in "vanilla" JSON VC/VP representations (aka "JWT"s)
+is forthcoming in the next version.
For a good introduction to the Semantic Web and JSON-LD as a
+data format and as a novel approach to web engineering, see
+these articles by Nader Helmy
+and Orie Steele.
did-tezos: architected by Spruce, did:tezos supports a powerful and robust multi-layer architecture. This includes support for "implicit" (unpublished) DIDs, on-chain (published) DIDs, DIDs that begin their lives as the former and become the latter, and additional metadata local to specific networks, including Sidetree networks.
did-key: the classic deterministic method for generating DIDs deterministically from a JWK file or other local key material
did-pkh: a did-key-like deterministic method for generating DIDs from blockchain addresses encoded and validated according to the emerging "CAIP" cross-chain addressing specification
did-web: a DID method for publishing a DID document to a domain's "/.wellknown/" configuration directory, to be resolved over HTTPS
did-webkey: a DID method designed in-house for deterministically deriving DID Documents from key material exposed by major web APIs; while we implemented it specifically for the SSH and GPG keys exposed and consumed by GitHub's APIs, it could readily be extended to analogous contexts.
did:onion: a DID method designed to be resolved over Tor-style onion routing
did-ethr: the classic Ethereum-based DID method at the heart of uPort, Veramo, and many web3 dApp projects (implicit only; main-net indexing & resolution coming soon)
did-sol: the native DID method of the Solana blockchain and DeFi ecosystem
One of the trickiest things about Verifiable Credentials, for people without
+JSON-LD or Semantic Web experience, is the referencing of external (linked)
+documents, represented in Verifiable Credentials and other Linked-Data documents
+by URLs. Thinking of them as URLs is deceptive, however, as fetching each from
+the open web at the time of verification of a credential bears many risks to
+both security and privacy-- although represented as URLs, they are best "cached"
+or stored locally, to be checked at time of verification.
The most common Linked-Data documents used to make Verifiable Contexts more
+portable are "context files", which are linked in the mandatory @context field
+of all verifiable credentials. These contain all the additional the vocabulary
+references needed to semantically disambiguate the keys
+and values that make up a credential. I say "additional" because there is a
+core vocabulary in the core context
+file maintained by the Verifiable Credentials working group, which must be
+referenced by all conformant VCs to anchor all mandatory terms defined by the VC
+specification. There are also some additional core vocabularies that cover a lot
+of common semantics, like the schema.org project central
+to the Semantic Web community, and VC-specific extensions to the core context
+maintained by the W3C-CCG community, such as the security
+vocabulary for anchoring
+cryptographic terms and proof-object properties and the traceability
+vocabulary for anchoring terms
+common across major supply chain use cases. It is common practice, when
+establishing anything from a small use-case to a vast ecosystem, to establish
+one context file (or more) to anchor all the VCs involved.
In addition to context files, there are other kinds of Linked-Data/JSON-LD
+documents that you might need to publish/host or resolve. For example, the
+RevocationList2020 and
+StatusList2021 specifications
+rely on "status lists" to be published to and queried over the open web in much
+the same was as context files. These lists are the linked-data equivalent of the
+OCSP status
+lists so central to the certificate-authority PKI networks that power HTTPS/TLS
+and other basic cybersecurity infrastructure. Like those, they may need to be
+propagated and cached, with latency built into systems relying on them. See
+below for details on how to handle that on both publisher and verifier sides of
+the interaction.
In a nutshell, there are three options for loading contexts into an
+issuer/verifier, i.e., four different ways an instance of DIDKit can dereference
+a URL pointing to a document. Technically, these are "resources" in the
+classical sense, but DIDKit is configured to build and maintain a local
+reference table to avoid fetching remote resources, which is disabled by
+default.
Ranked by their simplicity and security, the four ways of loading a document for
+issuance or verification purposes are:
Package a resource into DIDKit at build time.
Load a context resource locally at run time. (Coming soon)
Periodically reload a context resource "remotely" from a remote trusted
+source. (Coming soon)
Load a context resource remotely at time of verification (Strongly
+discouraged and not supported or endorsed by Spruce)
The security advantages of 1 over 2 and 2 over 3 should be clear, but it is also
+worth mentioning that option #4 has major privacy/data-leakage implications
+which make it categorically deprecated. Option #3 is not completely free from
+the complications and risks of option #4, so it is strongly recommended that 1
+and 2 be ruled out categorically before finding an optimal balance of
+mitigations and performance for implementing #3.
Any context file can be added to the directory, ssi/contexts/, which DIDKit
+queries for contexts. A few considerations, though:
Context files are intellectual property, and as such should be covered by
+licenses if upstreamed or otherwise distributed. Add licensing information
+about any new context file to ssi/contexts/LICENSES.md and
+ssi/contexts/README.md as needed.
If it's a W3C context file you are adding, simply add the name and URL in
+ssi/contexts/README.md with the other W3C documents (they are already
+covered by W3C license statements).
If the new context is covered by neither W3C's license, or an Apache-2.0 or
+CC-BY-SA-3.0 license, you will also need to update the license property in
+ssi/contexts/Cargo.toml.
Add a line in contexts/src/lib.rs using include_str to load the JSON-LD
+file and export it as a constant variable.
Optionally, you may want to add the URL in a rustdoc comment.
In ssi/src/jsonld.rs:
Declare and export a constant for the context file's canonical URL.
In the lazy_static block, define the context document as a
+RemoteDocument, referencing the context file variable defined in
+contexts/src/lib.rs and the constant defined for the URL.
In StaticLoader, match the context file's URL(s) to the context document.
After that, you are ready to follow the steps in didkit to build didkit-cli or
+didkit-http, using the locally-modified ssi repo.
Wallets are specialized pieces of software that store credentials, usually
+secured access to the cryptographic keys associated with a specific identifiers.
+It may store other kinds of credentials as well, such as unsigned credentials,
+self-attested/self-issued credentials, or credentials with subjects whose keys
+it does not control, but its primary function is signing to receive and present
+its "own" credentials. DIDKit is unopinionated and easy to extend, but DIDKit
+is also primary designed to work with Credible, and both are built around
+Spruce's core ssi library. For a more introductory explanation and
+specification, see the glossary
+entry
Decentralized Identifiers are stable identifiers which are bound to a
+controlling keypair, which is usually rotatable without changing the identifier.
+These stable identifiers can be used to query a verifiable data registry to get
+a "DID Document" containing the current controlling keypair and other
+information for verifying information associated with the DID. For a more
+introductory explanation and specification, see the DID glossary
+entry and
+the DID Document glossary
+entry
A set of interdependent governance, publication, and discovery mechanisms for
+DIDs in a given DID namespace, specified by a registered specification. Most DID
+methods use blockchains or other publically-readable distributed ledgers as data
+registries, but some, such as DID:Web, use other systems of verification, such
+as secure DNS resolution. For a more introductory explanation and
+specification, see the glossary
+entry
A special DID Method that generates conformant, offchain DID documents for
+local, private, and/or ephemeral resolution from a keypair. This can be helpful
+for integrating conventional PKI or signing infrastructure with DID issuance, or
+to allow caching or local resolution of DID documents where it is undesirable or
+impossible to resolve remote DIDs. For a more introductory explanation and
+specification, see the glossary
+entry
A JSON Web Key, or a "JWK" for short, is a special class of JSON objects(see
+glossary entry ) objects specified
+for containing cryptographic key or set of keys. They were
+specified in 2015 through the IETF.
DIDKit provides Verifiable Credential and Decentralized Identifier
+functionality across different platforms. DIDKit's core libraries are written in Rust due to Rust's expressive type system, memory safety, simple dependency web, and
+suitability across different platforms including embedded systems, but the comprehensive DIDKit SDK includes many libraries and interfaces for using it almost everywhere.
Where is anywhere, you ask? See the "DIDKit Interfaces" section to the left for a growing list of language-specific libraries, many available via package manager, and foreign function interfaces.
Credible is also anywhere-- DIDKit powers our SDK for web-wallets and mobile app development, which spans a whole additional range of anywheres you might need to handle DIDs and VCs.
If you need a server, not a library, DIDKit also powers a dockerized, ready-to-go HTTP/HTTPS server that can be called using the VC-HTTP-API standard or customized to use any other API interface.
It can juggle and translate between the two major signing systems and proof formats used in Verifiable Credentials today: Linked Data Proofs and the JOSE family of tokens and envelopes, abstracting out all the complexity of both.
It can handle, authenticate, validate, register, and even determininstically generate many kinds of W3C Decentralized Identifiers, aka the titular "DIDs": full-featured "on-chain" DIDs, implicit or "off-chain" DIDs, disposable, short-lived DIDs, pseudo-DIDs generated by key material borrowed from other systems
This includes "GitHub keys", HSM keys, any blockchain addresses representable as CAIP codes... the list keeps growing!
It can also issue and consume authorization tokens based on the Object Capabilities model, also known as "ZCaps", which drive the security model of our powerful Kepler storage system, as well as many other next-generation resource management systems.
That's it-- you're not ready to use didkit's CLI. For comprehensive documentation of CLI commands, see Github, and for a more skimmable overview, see the CLI page) here. For example, these basic commands should confirm the installation was succesful:
You're also ready to spin up a didkit-powered HTTP server for internal or external use, depending on your context. For comprehensive documentation of the HTTP commands, see Github , and for a more skimmable overview, see the HTTP page here. The HTTP server can be spun up with a single command if passed a key and some flags, and will respond with the port on which it will listen for valid calls:
$ ./target/debug/didkit-http -k key.jwk
Listening on http://127.0.0.1:51467/
More detailed installation instructions and variants, including Docker instructions, can be found on our installation page.
DIDKit is written in Rust. To get Rust, you can use Rustup.
We do not depend on any Rust nightly features, so our installation instructions assume stable versions; be sure to switch the installation defaults to nightly if the calling application depends on them.
Spruce's ssi library must be cloned alongside the didkit repository in a parallel directory between downloading didkit and building it.
Build DIDKit using Cargo, from root directory of DIDKit project:
$ cargo build
This will give you the DIDKit CLI and HTTP server executables located at
+target/debug/didkit and target/debug/didkit-http, respectively. You can also build and install DIDKit's components separately. Building the FFI libraries will require additional dependencies. See the corresponding readmes linked below for more info.
$ docker run ghcr.io/spruceid/didkit-cli:latest --help
$ docker run --init -p 8080 ghcr.io/spruceid/didkit-http:latest --port 8080
Note: You can pass JWKs either by sharing a volume with docker run --volume, or by passing the JWK directly with docker run -e JWK=$MY_JWK or docker run didkit-http --jwk $MY_JWK.
While many of the DIDKit interfaces can be installed as libraries via each
+language's dedicated package manager, they can also be built manually. For
+instructions, see the "Installation" section of each interface's dedicated page
+in the section to the left.
At Spruce, we consider it essential to be very explicit and up-front about
+our definition of standards compliance, our evidence to back that up, and
+the open-source dependencies and libraries which power our security and
+trust guarantees. To this end, we maintain both lists here, and think that
+both are as important as our changelogs.
To demonstrate our commitment to standards and interoperability, we have
+ensured that our implementation conforms to the following specifications and
+aspire to pass their test suites where applicable:
We strongly prefer tried and tested implementations of cryptographic functions
+and believe that it's most responsible to list them out in a forthcoming manner
+to any potential users. DIDKit is engineered so that the target platform and
+compile-time flags may be used to specify different cryptographic backends,
+such as to leverage native hardware capabilities, cross-compile to e.g. WASM,
+or to give advanced users the option to only use libraries that they trust.
ring, v0.16: default for hashes, ed25519
+functions, RSA, and randomness. The ed25519 functions here cannot currently
+compile to WASM.
Further educational/contextual resources on decentralized identity topics can be
+found on the Education page of the
+Decentralized Identity Foundation.
For insight into the core specifications authored and maintained by the W3C
+working group, the best overview is the github repositories section of their
+homepage on W3.org. The largely overlapping
+Credentials Community Group, with weekly open,
+recorded, and scribed calls open to W3C
+non-members, is also a good venue for getting to know the debates around the
+core specifications.
Verifiable Credentials combine properties and superpowers from many different
+mental models. They are like portable, free-floating data units, which are not
+exactly documents or data points or records. They are signed and thus
+tamper-evident, and thus share much of the verifiability of blockchain data or
+signed PDFs insofar as the signatures they contain can be properly verified by
+reference to the identities included inside the document. Particularly in the
+form of JSON-LD verifiable credentials, they are highly portable, in that the
+structure of their data can often be reconstructed years later and completely
+out of their original context. For more on JSON-LD and linked data, see the
+Semantics section of the DIDKit Core
+Concepts entry.
The mental model of a "wallet" for storing directly and manually controlled
+information and assets has become increasingly common in recent years thanks to
+the growing popularity of ledger-based cryptocurrencies, NFTs, and other virtual
+assets controlled by cryptography. Just as wallet software makes cryptographic
+key management intuitive and human-scaled when handling such
+cryptographically-controlled assets on common ledgers, so too can "wallet"
+interfaces make cryptographically-controlled documents like Verifiable
+Credentials manageable.
In the verifiable credential space, a "wallet" is traditionally assumed to
+manage one or more strong cryptographic identifiers, which must be authenticated
+to an issuer to receive identifier-specific or identifier-locked credentials.
+This is often assumed to be a direct and interactive process, as is the process
+of presenting these strong credentials to verifiers (usually
+double-authenticated, to both the verifier and to the credential, with two
+respective identifiers). Credible Wallet was designed to a secure,
+production-grade, yet lightweight and general-purpose wallet for such use cases,
+completely free of platform-, vendor-, or blockchain-lock-in and almost free of
+opinions (our preference for open standards is, after all, an opinion).
There are, however, fiduciary, automated, and/or "custodial" wallets (by analogy
+to cryptocurrency). Here, the dividing line between wallets and agents,
+services, and service providers gets a little blurry; particularly when the
+wallet holder is a legal entity or non-human actor, this is an important wrinkle
+on the concept of the "wallet." Here, DIDKit may be combined with enterprise
+identity and security platforms to provide a less human-scale "wallet" for
+handling strong credentials about human and non-human actors.
Decentralized Identifiers are stable identifiers which are bound to a
+controlling keypair, which is usually rotatable without changing the identifier.
+This is achieved by a publication mechanism maintaining information about key
+material in verifiable data stores (usually distributed ledgers) over time. This
+information is referred to as a DID Document. The
+specification governing these identifiers is
+maintained by a dedicated W3C working group,
+of which Spruce is a member. For more information on the W3C, see the Further
+Reading section.
A record returned by a query for a DID, containing information on how to verify
+information linked in some way to that identifier. The name can be misleading,
+since in many cases this "document" is entirely ephemeral or contextual and not
+intended to be a static file or document stored or cached anywhere. It is
+sometimes couched in a "Resolution object," which contains metadata about the
+query and resolution process, although most application developers have no need
+to worry about these DID mechanics. For a The
+specification governing the
+DID-->Document resolution process is maintained by a dedicated W3C working
+group, of which Spruce is a member. For more
+information on the W3C, see the Further Reading section on our Developer
+Portal.
A set of interdependent governance, publication, and discovery mechanisms for
+DIDs in a given DID namespace. Most DID methods use blockchains or other
+publically-readable distributed ledgers as data registries, but some, such as
+DID:Web, use other systems of verification, such as secure DNS resolution. All
+methods are specified by a registered specification. This specification explains
+how to validate a DID (namespace rules), where to query and what to expect back
+when resolving a DID, etc. The
+registry of compliant
+specifications for DID Methods is maintained by a dedicated W3C working
+group, of which Spruce is a member. For more
+information on the W3C, see the Further Reading section on our Developer
+Portal.
A special DID Method that generates conformant, offchain DID documents for
+local, private, and/or ephemeral resolution from a keypair. This can be helpful
+for integrating conventional PKI or signing infrastructure with DID issuance, or
+to allow caching or local resolution of DID documents where it is undesirable or
+impossible to resolve remote DIDs. The
+specification for this method was
+originally created in, and maintained in, the W3C-Credentials Community
+Group.
First described in 2006 as Javascript was becoming the most dominant web
+development language, and already widespread with it was standardized in 2013 by
+ECMA-404,
+the JSON "blob" or "object" is the most widely-used, language-independent format
+for data. It is often pronounced "JAson" or "JaySON".
JSON-LD is a serialization and messaging format building Linked Data
+capabilities onto data objects expressable as JSON objects. This means it is
+built on (but not 100% within) the JSON format, with slightly different
+properties, including serialization, ordering, and referencing mechanics. In
+the language of its specification's abstract, its "syntax is designed to easily
+integrate into deployed systems that already use JSON, and provides a smooth
+upgrade path from JSON to JSON-LD." The
+specification is maintained and
+governed in the W3C.
A JSON Web Key, or a "JWK" for short, is a subset of JSON objects specified for
+containing cryptographic key or set of keys. They were
+specified in 2015 through the IETF.
Welcome! This portal offers many ways of getting started with SpruceID libraries
+and projects. At a high level, the core components in our modular framework
+are:
DIDKit - our cross-platform toolkit for signing and
+verifying W3C Verifiable Credentials with or without W3C Decentralized
+Identifiers ("DIDs"), configurable across many interfaces and installable from
+most major package managers
Credible - our lightweight credential wallet,
+demonstrating how DIDKit can be built into a native mobile app or web wallet
+and ready to be whitelabeled for a use-case-specific client application
Kepler - a key-governed solution for self-sovereign storage (the new S3!),
+providing a granular and decentralized Authorization model, robust replication
+and localization controls, and other next-generation features that Web3
+developers need stat. (Separate documentation site coming soon)
Our goal is to make SpruceID useful, open, and versatile, which drives our
+design of each component to be modular and just complex enough to do the heavy
+lifting for a wide range of use cases. For example:
Rebase contains a wide range of verification flows that authenticate users and
+guide them through a proof-of-control and produce a receipt in the form of a
+Verifiable Credential (DIDKit under the hood). These can be mixed and matched to
+create a self-service reputation-system portal like
+TzProfiles.com.
Decentralized backup and recovery of a decentralized identity#
It takes less than a minute for any user to install a stock-model Credible
+mobile wallet from a Big Name App Store, generate a unique, private DID, receive
+their first VC, and backup the wallet's contents to a self-registered Kepler
+account. In case of catastrophe, that same DID can be reconstituted in a new
+wallet from a seed recovery phase, and the wallet contents restored from
+Kepler-- you can't ask for a more censorship-resistant or decentralized account
+system.
These Rebase credentials can be mixed and matched with other Verifiable
+Credentials from other dApps (on-chain history checks, fresh proofs of staking,
+or even an "employment history" from a decentralized marketplace like
+gitcoin) to gate access in a decentralized, secure, and
+impartial way to DeFi applications that need to reduce spam, sybils, and/or
+looky-loos.
Just as Rebase bootstraps reputation and history from centralized systems to
+identify a blockchain address, so too can DIDKit bootstrap a github account to
+sign and verify trustworthy and tamperproof packages. This allows dApps to be
+distributed as packages and hosted privately from a Kepler orbit or other
+privacy-preserving decentralized storage system.
Still can't quite grok what all these building blocks add up to? Start with our
+primer, "What is Decentralized Identity?", or use the
+glossary to go deeper into the technological foundations and
+pre-standards specifications that inspire this next-generation tooling.
When was the last time you felt comfortable sending or receiving important
+documents digitally? Have you ever been shocked at how much an online platform
+knows about you and wish you had more control over your identity? As a business,
+do your customers feel any of the above when they’re doing business with you?
Spruce is reimagining trusted interactions for enterprises and governments — the
+stewards of the most foundational and impactful layers of infrastructure shaping
+our lives.
We believe that in any organization you can find people working to build
+institutions that honor individual’s control over their own information and
+privacy. We are also pragmatists who understand that these principles are most
+likely to be implemented at scale when they also make commercial and operational
+sense. We firmly believe that there are paths striking a balance that both
+respects individual liberty and allows for enterprise success.
We are creating open-source software products that help our customers go from
+untrusted data to verifiable information that can be shared privately and with
+consent. Our products enable complete lifecycle management for licenses,
+certificates, audit reports, registrations, and other mission-critical data that
+must remain secure while passing many hands. Our main workflows allow end-users
+to manage their own data, and for everyone else to have confidence in the
+consent and purpose of data shared by them. To achieve this, we will utilize a
+cadre of emerging data technologies, including the recent W3C Verifiable
+Credentials and W3C Decentralized Identifiers specifications, which have been
+designed to solve business problems while leaving ample room to champion the end
+user’s control within a data supply chain.
Have any questions about Spruce's development efforts? Reach us via email at
+oss@spruceid.com.
Please note: this site documents multiple early-stage open-source products, and
+we are still incorporating feedback from our first comprehensive third-party
+code audit. These artefacts are presented as functional "betas" for
+experimentation and to show the direction of the projects (inviting proposals
+for changes of direction, even!). They are not, however, intended for
+transacting real-world business yet.
Identifying users securely with minimum invasion of privacy or risk of leakage
+is a core problem in essentially all software systems. Since the great boom of
+personal computing, this has created a whole sub-industry of identity and
+access-management (IAM) technologies, which overwhelmingly improve the mousetrap
+of mapping users to "accounts".
Centralized databases concentrate not just informational power, but also risk
+and liability.
As more and more real-world value get digitized over the decades, "identity
+data" has become a chokepoint for virtually all other digital value systems.
+Furthermore, every central repository of personal information has become a
+target of opportunistic business models, many of them illegal and based on
+exfiltration and interception of personal data. The legal spheres of so-called
+"ad-tech" and data brokerages and the illegal spheres of espionage, identity
+theft, and industrialized computer fraud share many characteristics.
Both legal and illegal industries devoted to non-consentual data sharing are
+growing every year. Both are largely impervious to regulation, and both are
+deeply demoralizing and disempowering to the average end-user.
In recent years, however, we have seen a wave of identity technologies emerge
+that strive to re-architect this whole landscape defensively, giving
+fine-grained control over all personal data back to you, the user.
+Decentralization of data systems, in the sense of bottoms-up governance of
+infrastructure and alternatives to monopolistic platform economics, tends to fit
+hand in glove with decentralized identity technologies. Center stage among this
+web of human-centric technologies is increasingly given to so-called
+"self-sovereign identity," which apply decentralized identity technologies to
+management of individuals' personal data.
Spruce is an open-source, decentralized identity company that works openly to
+advance these technologies in a sustainable, standards-driven way. We share the
+values of the community that has been driving this technology for a decade, and
+we want to see it succeed in the most organic and decentralized way possible.
+That means high standards for future-proof engineering, and an open-source
+strategy that keeps infrastructure and standards governance in the hands of a
+democratic commons.
Breaking the momentum of decades of centralized server/client architectures and
+"user accounts" requires a rethinking of the basic assumptions of data
+management, as well as data business. This requires imagining forms of
+information that can be self-securing, highly portable, self-verifying, and not
+bound too tightly to their original context and architecture. While this may
+sound like an esoteric problem for computer science, it is also a political,
+legal, and social question, because it requires reconceiving of the roles and
+rights of all the parties to data exchanges.
Decentralized identity thinking tends to call any valuable information about
+someone a "credential" and the person in question a "subject". It names the
+roles thusly:
"Issuers", who emit portable credentials about a subject. Ex: A university.
"holders" of that information, usually the subjects or trusted agents acting
+on their behalf. Ex: Students holding digital diplomas.
"verifiers" who might consume or act on that information.
The goals of decentralized identity are often expressed in negatives and
+minimums: the disclosure of the minimum data to each verifier necessary to their
+purpose, the minimum possibility of exfiltration or correlation (colloquially,
+"tracking"), the highest possible barrier to collusion between verifiers, the
+greatest possible privacy for all parties relative to their peers and
+counterparties. Even things like checking the revocation status when verifying a
+revocable credential is thought of defensively-- how to ensure that the issuer
+can revoke a credential while still ensuring that it receives no information
+about who verifies it, or how often? This requires sophisticated indirection,
+and new ways of hiding sensitive information in shared, even public data
+registries.
From the point of view of politics, this impersonal and democratic archive of
+verifiable "facts" accessed in common by all parties, is the most mysterious and
+enigmatic of the actors. Decentralization makes many such omnipotent but
+impersonal authorities in the form of ledgers, oracles, "blockchains," and
+meshes of immutable or content-addressed data, so this concept may be less
+mysterious to those steeped in those technologies. It is a registry in the sense
+that all data gets puts there (registered) by people and software running on
+behalf of people and organizations, but it is a decentralized and unconventional
+series of linked registries.
There is a whole vocabulary used to describe how credentials are handled,
+stored, presented, verified, and revoked. The software that individual actors
+use to receive, hold, and present them is called a "wallet", and the software
+used to issue, transfer, revoke, and verify them is called an "agent". Both
+interact with verifiable registries in various ways, must importantly for
+identifying and verifying each other. Spruce's wallet is called Credible, and
+the engine Spruce uses to create and power agents is called DIDKit. Both are
+intended to work at many scales and in many contexts.
Verifiable Credentials are designed refer to their issuers and subjects
+verifiably. This means that in the ideal case, any reference to an entity should
+be under that entity's direct and ultimate control, yet still be used to verify
+the credential's contents and trustworthiness cryptographically. In plain
+language, this means that a verifier would need to be able to get a
+cryptographic public key corresponding to that identifier, which might change or
+be deactivated over time.
The most "decentralized" of the identifiers that meet these requirements are
+so-called "decentralized identifiers," or DIDs. These are each registered and
+resolved on autonomous namespaces (often closely coupled to specific
+public-readable DLTs like blockchains), which function as verifiable data
+registries for their specific kind of identifiers. Each such namespace is
+governed by a "DID Method," which is a publically-specified micro-protocol
+containing namespace rules, CRUD and resolution mechanics, cryptographic
+signatures schemes, and blockchain-specific data models and algorithms. Each
+"DID method" has unique characteristics and infrastructures, with particular
+strengths and weaknesses; even their security guarantees and privacy engineering
+vary widely, so it can be dangerous to assume they are all equal and
+interchangeable. Each is like a little internet unto itself!
Further educational/contextual resources on decentralized identity topics can be
+found on the Education page of the
+Decentralized Identity Foundation.
For insight into the core specifications authored and maintained by the W3C
+working group, the best overview is the github repositories section of their
+homepage on W3.org. The largely overlapping
+Credentials Community Group, with weekly open,
+recorded, and scribed calls open to W3C
+non-members, is also a good venue for getting to know the debates around the
+core specifications.
Note: Spruce gets no data about DID or VC usage, contents, or metadata from
DIDKit or Credible; this entire policy refers to direct and voluntary
interactions between Service users and Spruce as an entity on an opt-in basis.
This privacy policy (“Policy”) describes how Spruce Systems, Inc. (“Spruce”
+“Company”, “we”,“our”, “us”) collects, uses, shares, and stores personal
+information of Spruce’s services, including any associated features or
+functionalities, websites and user interfaces, as well as all content and
+software applications associated with our services (collectively, the
+“Services”).
By using the Services, you accept the terms of this Policy and our Terms &
+Conditions (“Terms”), and consent to our collection, use, disclosure, and
+retention of your information as described in this Policy. If you have not done
+so already, please also review our Terms. The Terms contain provisions that
+limit our liability to you and require you to resolve any dispute with us on an
+individual basis and not as part of any class or representative action. IF YOU
+DO NOT AGREE WITH ANY PART OF THIS PRIVACY POLICY OR OUR TERMS, THEN PLEASE DO
+NOT USE ANY OF THE SERVICES.
Please note that this Policy does not apply to information collected through
+third-party websites or sites that you may access through the Services, or that
+you submit to us through email, text message or other electronic message or
+offline.
If you are engaging with the Services from the European Union (EU), see our
+Notice to EU Data Subjects for our legal bases for processing and transfer of
+your data.
We get information about you in a range of ways.
+Information You Give Us. Information we collect from you includes:
Account registration or user information, such as your name, display name or
+social media account handles when you sign up for use of our Services;
Feedback and correspondence, such as information you provide in your responses
+to surveys, when you participate in market research activities, report a
+problem with Services, receive customer support or otherwise correspond with
+us;
Anonymized usage information, such as information about how you use the
+Services and interact with us; and
Marketing information, such as your preferences for receiving marketing
+communications and details about how you engage with them.
Information We Get From Others. We may get information about you from other
+third party sources and we may add this to information we get from your use of
+the Services.
Information Automatically Collected. We may automatically record certain
+information about how you use our Services (we refer to this information as “Log
+Data“). Log Data may include information such as a user’s Internet Protocol (IP)
+address, device and browser type, the pages or features of our Services which a
+user browsed and the time spent on those pages or features, the frequency with
+which the Services are used by a user, search terms, the links on our sites that
+a user clicked on or used, referral url, and other statistics. We use this
+information to administer the Services and we analyze (and may engage third
+parties to analyze) this information to improve and enhance the Services by
+expanding features and functionality and tailoring to our users’ needs and
+preferences.
We may use cookies or similar technologies to analyze trends, administer the
+website, track users’ movements around the website, and to gather demographic
+information about our user base as a whole. Users can control the use of cookies
+at the individual browser level. For more information, please see the section
+entitled “Cookies Policy” below.
We may also use data analytics sites to help us offer you an optimized user
+experience.
We use your personal information as we believe necessary or appropriate to
+comply with applicable laws, lawful requests and legal process, such as to
+respond to subpoenas or requests from government authorities.
We use contact and personal information in some circumstances, such as your
+social media information, to communicate to you about updates or changes to
+the use of our Services.
In order to optimize your user experience, we may use your personal
+information to operate, maintain, and improve our Services. We may also use
+your information to respond to your comments and questions regarding the
+Services.
We may use or share your personal information with your consent, such as when
+you instruct us to take a specific action with respect to your personal
+information, or you opt into third party marketing communications.
We do not share or sell the personal information that you provide us with
+other organizations without your express consent, except as described in this
+Policy. We disclose personal information to third parties under the following
+circumstances:
Affiliates. We may disclose your personal information to our subsidiaries
+and corporate affiliates for purposes consistent with this Policy.
Business Transfers. We may share personal information when we do a business
+deal, or negotiate a business deal, involving the sale or transfer of all or a
+part of our business or assets. These deals can include any merger, financing,
+acquisition, or bankruptcy transaction or proceeding.
Compliance with Laws and Law Enforcement; Protection and Safety. We may
+share personal information for legal, protection, and safety purposes.
We may share information to comply with laws.
We may share information to respond to lawful requests and legal processes.
We may share information to protect the rights and property of the Company,
+our agents, customers, and others. This includes enforcing our agreements,
+policies, and terms and conditions.
We may share information in an emergency. This includes protecting the safety
+of our employees and agents, our customers, or any person.
Professional Advisors and Service Providers. We may share information with
+those who need it to do work for us. These recipients may include third party
+companies and individuals to administer and provide the Services on our behalf
+(such as customer support, hosting, email delivery and database management), as
+well as lawyers, bankers, auditors, and insurers.
If you are engaging with the Services from the European Union (EU), see our
+Notice to EU Data Subjects for our legal bases for processing and transfer of
+your data.
The Company has offices outside of the EU and has affiliates and Services
+providers in the United States and in other countries.Your personal information
+may be transferred to or from the United States or other locations outside of
+your state, province, country or other governmental jurisdiction where privacy
+laws may not be as protective as those in your jurisdiction.
EU users should read the important information provided below about transfer of
+personal information outside of the European Economic Area (EEA).
We retain information we collect as long as it is necessary and relevant to
+fulfill the purposes outlined in this Policy. In addition, we retain personal
+information to comply with applicable law where required, prevent fraud, resolve
+disputes, troubleshoot problems, assist with any investigation, enforce our
+Terms, and other actions permitted by law. To determine the appropriate
+retention period for personal information, we consider the amount, nature, and
+sensitivity of the personal information, the potential risk of harm from
+unauthorized use or disclosure of your personal information, the purposes for
+which we process your personal information and whether we can achieve those
+purposes through other means, and the applicable legal requirements.
In some circumstances we may anonymize your personal information (so that it can
+no longer be associated with you) in which case we may use this information
+indefinitely without further notice to you.
We employ industry-standard security measures designed to protect the security
+of all information submitted through the Services. However, the security of
+information transmitted through the internet can never be guaranteed. We are not
+responsible for any interception or interruption of any communications through
+the internet or for changes to or losses of data. In order to protect you and
+your data, we may suspend your use of any of the Services, without notice,
+pending an investigation, if any breach of security is suspected.
Accessing, Updating, Correcting, and Deleting your Information - You may
+access information that you have voluntarily provided through your account, and
+to review, correct, or delete it by sending a request to support@spruceid.com.
+You can request to change contact choices, opt-out of our sharing with others,
+and update your personal information and preferences.
Tracking Technologies Generally - Regular cookies may generally be disabled
+or removed by tools available as part of most commercial browsers, and in some
+instances blocked in the future by selecting certain settings. For more
+information, please see the section entitled “Cookies Policy” below.
CONTACT INFORMATION. We welcome your comments or questions about this
+Policy, and you may contact us at: support@spruceid.com.*
CHANGES TO THIS PRIVACY POLICY. We may change this privacy policy at any
+time. We encourage you to periodically review this page for the latest
+information on our privacy practices. If we make any changes, we will change the
+Last Updated date above. Any modifications to this Policy will be effective upon
+our posting of the new terms and/or upon implementation of the changes to the
+Services (or as otherwise indicated at the time of posting). In all cases, your
+continued use of the Services after the posting of any modified Privacy Policy
+indicates your acceptance of the terms of the modified Privacy Policy.
If you are under the age of majority in your jurisdiction of residence, you may
+use the Services only with the consent of or under the supervision of your
+parent or legal guardian. Consistent with the requirements of the Children's
+Online Privacy Protection Act (COPPA), if we learn that we have received any
+information directly from a child under age 13 without first receiving their
+parent's verified consent, we will use that information only to respond directly
+to that child (or their parent or legal guardian) to inform the child that they
+cannot use the Services and subsequently we will delete that information.
Under California Civil Code Section 1789.3, California users are entitled to the
+following consumer rights notice: California residents may reach the Complaint
+Assistance Unit of the Division of Consumer Site of the California Department of
+Consumer Affairs by mail at 1625 North Market Blvd., Sacramento, CA 95834, or by
+telephone at (916) 445-1254 or (800) 952-5210.
Personal Information
With respect to EU data subjects, “personal information,” as used in this
+Policy, is equivalent to “personal data” as defined in the European Union
+General Data Protection Regulation (GDPR).
Sensitive Data
Some of the information you provide us may constitute sensitive data as defined
+in the GDPR (also referred to as special categories of personal data).
Legal Bases for Processing
We only use your personal information as permitted by law. We are required to
+inform you of the legal bases of our processing of your personal
+information,which are described in the table below. If you have questions about
+the legal bases under which we process your personal information, contact us at
+support@spruceid.com.
Processing Purpose - Legal Basis
To communicate with you and to optimize our Services. These processing
+activities constitute our legitimate interests. We make sure we consider and
+balance any potential impacts on you and your rights before we process your
+personal information for our legitimate interests. We do not use your personal
+information for activities where our interests are overridden by any adverse
+impact on you (unless we have your consent or are otherwise required or
+permitted to by law).
We use your personal information to comply with applicable laws and our legal
+obligations.
Where our use of your personal information is based upon your consent, you have
+the right to withdraw it at any time by contacting us at support@spruceid.com.
We may use your personal information for reasons not described in this Privacy
+Policy, where we are permitted by law to do so and where the reason is
+compatible with the purpose for which we collected it. If we need to use your
+personal information for an unrelated purpose, we will notify you and explain
+the applicable legal basis for that use. If we have relied upon your consent for
+a particular use of your personal information, we will seek your consent for any
+unrelated purpose.
Under the GDPR, you have certain rights regarding your personal information. You
+may ask us to take the following actions in relation to your personal
+information that we hold:
Opt-out. Stop sending you direct marketing communications which you have
+previously consented to receive. We may continue to send you Services-related
+and other non-marketing communications.
Access. Provide you with information about our processing of your personal
+information and give you access to your personal information.
Correct. Update or correct inaccuracies in your personal information.
Transfer. Transfer a machine-readable copy of your personal information to
+you or a third party of your choice.
Restrict. Restrict the processing of your personal information.
Object. Object to our reliance on our legitimate interests as the basis of
+our processing of your personal information that impacts your rights.
You can submit these requests by email to support@spruceid.com. We may request
+specific information from you to help us confirm your identity and process your
+request. Applicable law may require or permit us to decline your request. If we
+decline your request, we will tell you why, subject to legal restrictions. If
+you would like to submit a complaint about our use of your personal information
+or response to your requests regarding your personal information, you may
+contact us at support@spruceid.com or submit a complaint to the data protection
+regulator in your jurisdiction.
Please be aware that your personal data will be transferred to, processed, and
+stored in the United States. Data protection laws in the U.S. may be different
+from those in your country of residence. You consent to the transfer of your
+information, including personal information, to the U.S. as set forth in this
+Policy by visiting our site or using our Services.
Whenever we transfer your personal information out of the EEA to the U.S. or
+countries not deemed by the European Commission to provide an adequate level of
+personal information protection, the transfer will be based on a data transfer
+mechanism recognized by the European Commission as providing adequate protection
+for personal information.
Please contact us if you want further information on the specific mechanism used
+by us when transferring your personal information out of the EEA.
Your information will remain subject to the terms of this Privacy Policy even if
+the Services undergo an organizational transition. However, we may transfer your
+information to a successor entity upon a merger, consolidation, or other
+reorganization in which our Services participate or to a successor
+not-for-profit assignee or licensee of all or substantially all of our Services’
+assets. You hereby consent to such transfers and our Services may assign and
+transfer all of the rights, benefits, duties, and obligations of this Privacy
+Policy, under the circumstances described in this paragraph.
Our Services may provide links to websites of other organizations or companies
+that may offer materials and services as well as links to other sites. In using
+our Services or the linked sites of other organizations or companies, you may
+have the option to sign up for email lists operated by these organizations or
+companies. If you choose to request that your address be removed from the
+organizations’ or companies’ lists, we cannot control whether or not they will
+immediately stop using your address. To stop receiving communications from these
+organizations or companies, you should contact them directly.
This Privacy Policy applies only to the privacy of users of our Services. If you
+follow links and move from our Services to external websites owned or operated
+by other entities or individuals, you should read the privacy policies of those
+external websites carefully. The terms by which the owners or operators of those
+websites manage your information could differ from how our Services manages your
+information. Our Services are not responsible for the practices of these third
+parties.
We understand that your privacy is important to you and are committed to being
+transparent about the technologies we use. In the spirit of transparency, this
+policy provides detailed information about how and when we use cookies.
No, but we reserve the right to in the future. We and our marketing partners,
+affiliates, and analytics or site providers may use cookies, web beacons, or
+pixels and other technologies to ensure everyone who uses the Services has the
+best possible experience.
A cookie (“Cookie”) is a small text file that is placed on your hard drive by a
+web page server. Cookies contain information that can later be read by a web
+server in the domain that issued the cookie to you. Some of the cookies will
+only be used if you use certain features or select certain preferences, and some
+cookies will always be used. You can find out more about each cookie by viewing
+our current cookie list below. We update this list periodically, so there may be
+additional cookies that are not yet listed. Web beacons, tags and scripts may be
+used in the Services or in emails to help us to deliver cookies, count visits,
+understand usage and campaign effectiveness and determine whether an email has
+been opened and acted upon. We may receive reports based on the use of these
+technologies by our site/analytics providers on an individual and aggregated
+basis.
We may generally use Cookies for the following purposes:
To recognize new or past customers.
To improve our Services and to better understand your visits on our platforms.
To serve you with interest-based or targeted advertising.
To observe your behaviors and browsing activities over time across multiple
+websites or other platforms.
To better understand the interests of our customers and our website visitors.
We may also use functional Cookies and Cookies from third parties for analysis
+and marketing purposes. Functional Cookies enable certain parts of the site to
+work properly and your user preferences to remain known.
If you want to learn more about cookies, or how to control, disable or delete
+them, please visit http://www.aboutcookies.org for detailed guidance. In
+addition, certain third party advertising networks, including Google, permit
+users to opt out of or customize preferences associated with your internet
+browsing.
We may link the information collected by Cookies with other information we
+collect from you pursuant to this Policy and use the combined information as set
+forth herein. Similarly, the third parties who serve cookies in our Services
+may link your name or email address together with information they collect,
+which may include past purchases made offline or online, or your online usage
+information. If you are located in the European Economic Area, you have certain
+rights that are described above under the header “Notice to EU Data Subjects”,
+including the right to inspect and correct or delete the data that we have about
+you.
This page is devoted to #1 for the do-first crowd. If jumping straight into a command line sounds little scary, feel free to choose your own adventure and click around on those links above first. Then come back for ther tour! Similarly, if you already know what DIDKit is and does, and just want a reference page specific to the interface you'll be using, jump straight to that page from this
+list:
These examples will walk you through installing DIDKit and using it on a Linux
+command-line environment-- Linux on a Mac or WSL2 on a Windows machine should
+work fine (but run sudo apt install build-essential just in case).
cargo install didkit-cli
If you prefer to build manually from source or via docker, instructions are in our docs.
If you're not familiar with Verifiable Credentials, they're a low-level data
+format designed to be Very Portable, as in: anyone can authenticate this data,
+and if they understand who it was that "issued" (i.e. minted) that unique,
+signed, data object, they can trust it as much as they trust the issuer. More
+info in the primer.
So what do you need to get started with VCs? Basically just DIDKit and a dream!
+The first ingredient is DIDKit, the second is a signing key, which DIDKit can
+generate for you once it's installed. From the DIDKit root directory:
didkit generate-ed25519-key > issuer_key.jwk
Or, if you want to BYO a private key you already have (Ed25519 for now, to keep
+the examples simple), you can just copy it into the folder like so:
cp /path/to/privkey.jwk issuer_key.jwk
Once this key is on hand, you have to structure some data to be the payload of
+this VC you want to issue. For simplicity, let's throw this into a JSON file to
+be signed over in the next step. Don't worry too much about the meaning or
+function of any specific property if this is your first Verifiable Credential--
+all things in time. You're not signing away your soul, don't worry-- these are the basic ingredients of a verified credential.
Now you're ready to mint the thing by signing it with that private key, which has to be passed in two different ways: as a key, and as a "verification method" (a transformation of the key which we'll explain later).
And that's it! Wherever this signed blob ends up, it can be handled by standard
+JSON tooling, and VC tooling can identity it as trustworthy information, or at
+least as trustworthy as 'yournamehere.com' was at the time in 'issuanceDate'.
+Notice that the 'issuer' field identified you by a website, and a "did:web:"
+prefix. We'll explain this one in the next step.
Let's take a real-life VC issued by our testing faucet and drop it into your DIDKit root directory as an example.
Click here for an example VC
Note: to get a fresher version of this credential issued to a real-world DID, you might want to install the Credible mobile wallet on a mobile device, whether from source code, from Apple Test Flight, or from the Google Play store. Once you have Credible installed, it will automatically generate an off-chain did-tz (it will resemble did:tz:tz1aTuW7578MTt3ZtWYCjX65nUXkzE1CMcAf), and when you navigate to our demo faucet, you can get a VC issued to you containing your unique, decentralized identifier.
(You can cut and paste it into a sample.vc file using a text editor or a bash command for simplicity's sake, or download it here). You will notice that this VC looks much like the one you issued in the previous step, but with a "proof" section attached with contains the issuer's signature and metadata for verifying it. Verifying this signature is as simple as another single-line DIDKit call:
That will spit out a verbose response as a JSON file listing the checks passed, warnings, and errors. If everything is set up properly, you should see this when you nano result.json:
{"checks":["proof"],"warnings":[],"errors":[]}
You might be asking yourself, though, how did DIDKit get from "issuer": "did:web:demo.spruceid.com:2021:vc-faucet" to having the public key (and knowing the type of the public key) to be able to verify the signature in the proof? This is the magic of DIDs!
Detailed explanation of the ✨Magic of Step 1.5✨
The [often implicit!] resolution step
Let's take the simple example VC above, issued by did:web:demo.spruceid.com:2021:vc-faucet, i.e. our VC faucet). Information about this issuer
+has to be "resolved" in much the same way that a web address (like
+demo.spruceid.com) needs to be resolved to an IP address to establish a browser
+connection. There are many ways of resolving DIDs, but let's stick to DID-web
+for now, as it is the easiest for young wizards to understand.
A "did-web" is a DID which publishes its "DID Document" (a data file containing
+identity information and public keys) in a standardized location at the website
+it identifies. https://demo.spruceid.com/2021/vc-faucet/did.json
+is, as a web-savvy user might expect, a JSON file that publishes resolution
+information about the DID did:web:demo.spruceid.com:2021:vc-faucet.
+A "did-web" tells you exactly where to go to "resolve" that DID into a DID
+document: you just tack /.well-known/did.json to the end of a root
+domain, or just /did.json for a qualified domain, and fetch that
+JSON blob. Other DID methods have more complex resolution mechanisms, but take
+the same input (a DID string) which, if succesfully resolved, outputs the same
+kind of DID document, give or take a few optional properties specific to each
+DID method.
The most basic and useful thing that a DID Document contains is a series of
+"verification methods", i.e., public keys used for specific purposes and which
+can be referenced by specific relative references. These are used to check the
+signature on a VC, among other purposes. See, for example, this DID document
+from the demo app we use to test DIDKit and wallets:
*Note: this DID Document has an Ed25519 key as its "key-1" (default key) that is the designated key for `authentication` and`assertionMethod` purposes. The latter alias signals to wallets that this is the key used to sign assertions about the world-- assertions that this public key makes verifiable.*
While on the issuer side, a verification method can be deterministically derived
+from the private key, a verifier downstream does not have that option, which is
+why DID Documents exist in the first place: to publish annotated key material
+that can be used to verify signatures out there in the world. Having resolved
+the issuer's DID, you now have the subset of its contents needed to verify a
+credential: the "verification method" for checking the signatures on a VC.
This might sound like a lot of work described step by step, but don't worry--
+DID resolution happens automatically once everything is up and running, as you
+already saw above. If you needed to do only the solution step for some reason,
+you could fetch a DID Document with a single DIDKit command as well, in any
+context with web access:
+
+
+
+
\ No newline at end of file
diff --git a/package.json b/package.json
index 88a0abae..6c4e036c 100644
--- a/package.json
+++ b/package.json
@@ -13,6 +13,7 @@
},
"dependencies": {
"@docusaurus/core": "^2.0.0-beta.ff31de0ff",
+ "@docusaurus/plugin-content-docs": "^2.0.0-beta.6",
"@docusaurus/preset-classic": "^2.0.0-beta.ff31de0ff",
"@mdx-js/react": "^1.6.21",
"clsx": "^1.1.1",
diff --git a/sidebars.js b/sidebars.js
index 0fce30b5..e460f511 100644
--- a/sidebars.js
+++ b/sidebars.js
@@ -2,7 +2,7 @@ module.exports = {
docs: {
'.dev Portal' : [
'devhome',
- 'primer'
+ 'primer',
],
'DIDKit': [
'didkit/intro',
@@ -14,14 +14,14 @@ module.exports = {
'didkit/specs_and_deps',
'didkit/glossary',
],
- 'DIDKit Interfaces': [
- 'didkit-interfaces/cli',
- 'didkit-interfaces/http',
- 'didkit-interfaces/rust',
- 'didkit-interfaces/C',
- 'didkit-interfaces/java',
- 'didkit-interfaces/python',
- 'didkit-interfaces/node',
+ 'DIDKit Packages': [
+ 'didkit-packages/cli',
+ 'didkit-packages/http',
+ 'didkit-packages/rust',
+ 'didkit-packages/C',
+ 'didkit-packages/java',
+ 'didkit-packages/python',
+ 'didkit-packages/node',
],
'DIDKit Examples': [
'didkit-examples/overview',
diff --git a/sitemap.xml b/sitemap.xml
new file mode 100644
index 00000000..45075471
--- /dev/null
+++ b/sitemap.xml
@@ -0,0 +1 @@
+https://spruceid.dev/weekly0.5https://spruceid.dev/docs/weekly0.5https://spruceid.dev/docs/code-of-conductweekly0.5https://spruceid.dev/docs/contributingweekly0.5https://spruceid.dev/docs/credible-examples/did-tz-deployweekly0.5https://spruceid.dev/docs/credible-examples/overviewweekly0.5https://spruceid.dev/docs/credible-examples/qr-issuanceweekly0.5https://spruceid.dev/docs/credible-examples/vc-displayweekly0.5https://spruceid.dev/docs/credible/weekly0.5https://spruceid.dev/docs/credible/authnweekly0.5https://spruceid.dev/docs/credible/conceptsweekly0.5https://spruceid.dev/docs/credible/glossaryweekly0.5https://spruceid.dev/docs/credible/installweekly0.5https://spruceid.dev/docs/didkit-examples/batch-generationweekly0.5https://spruceid.dev/docs/didkit-examples/core-functions-in-bashweekly0.5https://spruceid.dev/docs/didkit-examples/core-functions-in-curlweekly0.5https://spruceid.dev/docs/didkit-examples/java-springbootweekly0.5https://spruceid.dev/docs/didkit-examples/overviewweekly0.5https://spruceid.dev/docs/didkit-examples/svelte-chapiweekly0.5https://spruceid.dev/docs/didkit-interfaces/Cweekly0.5https://spruceid.dev/docs/didkit-interfaces/cliweekly0.5https://spruceid.dev/docs/didkit-interfaces/httpweekly0.5https://spruceid.dev/docs/didkit-interfaces/javaweekly0.5https://spruceid.dev/docs/didkit-interfaces/nodeweekly0.5https://spruceid.dev/docs/didkit-interfaces/pythonweekly0.5https://spruceid.dev/docs/didkit-interfaces/rustweekly0.5https://spruceid.dev/docs/didkit/weekly0.5https://spruceid.dev/docs/didkit/changelogweekly0.5https://spruceid.dev/docs/didkit/conceptsweekly0.5https://spruceid.dev/docs/didkit/did-methodsweekly0.5https://spruceid.dev/docs/didkit/document-loadingweekly0.5https://spruceid.dev/docs/didkit/glossaryweekly0.5https://spruceid.dev/docs/didkit/installweekly0.5https://spruceid.dev/docs/didkit/specs_and_depsweekly0.5https://spruceid.dev/docs/further-readingweekly0.5https://spruceid.dev/docs/glossaryweekly0.5https://spruceid.dev/docs/primerweekly0.5https://spruceid.dev/docs/privacy-policyweekly0.5
\ No newline at end of file
diff --git a/src/css/custom.css b/src/css/custom.css
index e41e026b..7f486022 100644
--- a/src/css/custom.css
+++ b/src/css/custom.css
@@ -23,3 +23,23 @@
margin: 0 calc(-1 * var(--ifm-pre-padding));
padding: 0 var(--ifm-pre-padding);
}
+
+.prism-code {
+ counter-reset: line-number;
+}
+
+/*
+ * Notice the chained .language-ts class name to .prism-code
+ * You can chain more languages in order to add line numbers
+ */
+.prism-code.language-sh .token-line::before {
+ counter-increment: line-number;
+ content: '$';
+ margin-right: 7px;
+ text-align: right;
+ min-width: 0.0rem;
+ display: inline-block;
+ opacity: .5;
+ position: sticky;
+ left: var(--ifm-pre-padding);
+}
diff --git a/src/pages/index.md b/src/pages/index.md
new file mode 100644
index 00000000..90e99b05
--- /dev/null
+++ b/src/pages/index.md
@@ -0,0 +1,233 @@
+---
+id: quickstart
+slug: /
+title: Quickstart Guide to working with DIDKit
+---
+
+# Getting Started with Spruce ID
+
+This website exists for two complementary purposes:
+1. To get you *using* DIDKit and other Spruce ID tooling as smoothly and quickly
+ as possible
+2. To provide developer [docs](/docs/) and [references](/docs/glossary)
+ that help you understand [DIDKit](/docs/didkit)
+3. To help you wrap your head around
+ [Verifiable Credentials](/docs/primer/), find the right [Decentralized
+ Identifier scheme](/docs/did-methods) for your project, and generally just
+ get you from "curious🤔" to "wizard🧙♂️" as fast as we can.
+
+The quickstart guide that follows describes how to perform credential issuance and verification with DIDKit's command line tool. Documentation for use with other platforms can be found in the navigation bar on the [DIDKit Packages](/docs/didkit-packages/rust) section.
+
+## Step 0: install DIDKit
+
+To install the DIDKit command line tool from crates.io on GNU/Linux, MacOS,
+Windows+WSL with
+[cargo](https://doc.rust-lang.org/cargo/getting-started/installation.html) and
+`build-essential` tools already installed, run:
+
+```sh
+cargo install didkit-cli
+```
+
+If you prefer to build manually from source or via docker, instructions are in our docs.
+
+## Step 1: Issue your first Verifiable Credential
+
+W3C Verifiable Credentials are a standard data format for claims expressed in
+JSON, also known as digital attestations. They contain the claim being made,
+data schema references, and a digital signature to be verified and consumed by
+unknown future parties. More info in the [primer](/docs/primer).
+
+So what do you need to get started with VCs? The first ingredient is DIDKit, and the second is a signing key, which DIDKit can generate automatically:
+
+```sh
+didkit generate-ed25519-key > issuer_key.jwk
+```
+
+Or, if you want to use pre-existing key material, it can be accessed from a filepath; a Ed25519 key in JWK format can be linked or copied to the DIDKit root.
+
+Once this key is on hand, you have to structure some data to be the payload of
+this VC you want to issue. For simplicity, let's throw this into a JSON file to
+be signed over in the next step. Don't worry too much about the meaning or
+function of any specific property if this is your first Verifiable Credential--
+all things in time. You're not signing away your soul, don't worry-- these are the basic ingredients of a verified credential.
+
+```bash
+cat > payload.json <credential-signed.jsonld
+cat credential-signed.jsonld
+```
+
+And that's it! Wherever this signed blob ends up, it can be handled by standard
+JSON tooling, and VC tooling can identity it as trustworthy information, or at
+least as trustworthy as 'yournamehere.com' was at the time in 'issuanceDate'.
+Notice that the 'issuer' field identified you by a website, and a "did:web:"
+prefix. We'll explain this one in the next step.
+
+## Step 2: Verifying a real VC
+
+Let's take a real-life VC issued by our testing faucet and drop it into your DIDKit root directory as an example.
+
+
+ Click here for an example VC
+
+
Note: to get a fresher version of this credential issued to a
+ real-world DID, you might want to install the Credible mobile wallet on
+ a mobile device, whether from source code,
+ from Apple Test Flight,
+ or from the Google Play store. Once you have Credible installed, it will automatically generate an off-chain did-tz (it will resemble did:tz:tz1aTuW7578MTt3ZtWYCjX65nUXkzE1CMcAf), and when you navigate to our demo faucet, you can get a VC issued to you containing your unique, decentralized identifier.
+
+ (You can cut and paste it into a {`
+sample.vc
+`.slice(1, -1)} file using a text editor or a bash command for simplicity's sake, or download it here).
+
+
+
+ You will notice that this VC looks much like the one you issued in the
+previous step, but with a "proof" section attached with contains the issuer's
+signature and metadata for verifying it. Verifying this signature is as simple
+as another single-line DIDKit call:
+
+```bash
+didkit vc-verify-credential -p assertionMethod result.json
+```
+
+That will spit out a verbose response as a JSON file listing the checks passed, warnings, and errors. If everything is set up properly, you should see this when you `nano result.json`:
+
+```json
+{"checks":["proof"],"warnings":[],"errors":[]}
+```
+
+You might be asking yourself, though, how did DIDKit get from `"issuer": "did:web:demo.spruceid.com:2021:vc-faucet"` to having the public key (and knowing the *type* of the public key) to be able to verify the signature in the proof? This is the magic of DIDs!
+
+Detailed explanation of the ✨Magic of Step 1.5✨
+
+
The [often implicit!] resolution step
+
+Let's take the simple example VC above, issued by did:web:demo.spruceid.com:2021:vc-faucet, i.e. our VC faucet). Information about this issuer
+has to be "resolved" in much the same way that a web address (like
+demo.spruceid.com) needs to be resolved to an IP address to establish a browser
+connection. There are many ways of resolving DIDs, but let's stick to DID-web
+for now, as it is the easiest for young wizards to understand.
+
+A "did-web" is a DID which publishes its "DID Document" (a data file containing
+identity information and public keys) in a standardized location at the website
+it identifies. https://demo.spruceid.com/2021/vc-faucet/did.json
+is, as a web-savvy user might expect, a JSON file that publishes resolution
+information about the DID did:web:demo.spruceid.com:2021:vc-faucet.
+A "did-web" tells you exactly where to go to "resolve" that DID into a DID
+document: you just tack /.well-known/did.json to the end of a root
+domain, or just /did.json for a qualified domain, and fetch that
+JSON blob. Other DID methods have more complex resolution mechanisms, but take
+the same input (a DID string) which, if succesfully resolved, outputs the same
+kind of DID document, give or take a few optional properties specific to each
+DID method.
+
+The most basic and useful thing that a DID Document contains is a series of
+"verification methods", i.e., public keys used for specific purposes and which
+can be referenced by specific relative references. These are used to check the
+signature on a VC, among other purposes. See, for example, this DID document
+from the demo app we use to test DIDKit and wallets:
+
+
+
Behold! A real-world DID Document!
+ {`
+{
+ "@context": [
+ "https://www.w3.org/ns/did/v1",
+ {
+ "@id": "https://w3id.org/security#publicKeyJwk",
+ "@type": "@json"
+ }
+ ],
+ "id": "did:web:demo.spruceid.com:2021:vc-faucet",
+ "verificationMethod": [
+ {
+ "id": "did:web:demo.spruceid.com:2021:vc-faucet#key-1",
+ "type": "Ed25519VerificationKey2018",
+ "controller": "did:web:demo.spruceid.com:2021:vc-faucet",
+ "publicKeyJwk": {
+ "kty": "OKP",
+ "crv": "Ed25519",
+ "x": "ZMKSD7bKSOg_4IQhZUd-2VCoBTCrEB8L2tql4oRNDUg"
+ }
+ }
+ ],
+ "authentication": [
+ "did:web:demo.spruceid.com:2021:vc-faucet#key-1"
+ ],
+ "assertionMethod": [
+ "did:web:demo.spruceid.com:2021:vc-faucet#key-1"
+ ]
+}
+`.slice(1, -1)}
+
+ *Note: this DID Document has an Ed25519 key as its "key-1" (default key)
+that is the designated key for `authentication` and
+`assertionMethod` purposes. The latter alias signals to wallets
+that this is the key used to sign assertions about the world-- assertions that
+this public key makes verifiable.*
+
+
+
+While on the issuer side, a verification method can be deterministically derived
+from the private key, a verifier downstream does not have that option, which is
+why DID Documents exist in the first place: to publish annotated key material
+that can be used to verify signatures out there in the world. Having resolved
+the issuer's DID, you now have the subset of its contents needed to verify a
+credential: the "verification method" for checking the signatures on a VC.
+
+This might sound like a lot of work described step by step, but don't worry--
+DID resolution happens automatically once everything is up and running, as you
+already saw above. If you needed to do only the solution step for some reason,
+you could fetch a DID Document with a single DIDKit command as well, in any
+context with web access:
+
+{`
+didkit did-dereference did:web:demo.spruceid.com:2021:vc-faucet
+`}
+
+
\ No newline at end of file
diff --git a/src/pages/styles.module.css b/src/pages/styles.module.css
deleted file mode 100644
index c1aa8512..00000000
--- a/src/pages/styles.module.css
+++ /dev/null
@@ -1,37 +0,0 @@
-/* stylelint-disable docusaurus/copyright-header */
-
-/**
- * CSS files with the .module.css suffix will be treated as CSS modules
- * and scoped locally.
- */
-
-.heroBanner {
- padding: 4rem 0;
- text-align: center;
- position: relative;
- overflow: hidden;
-}
-
-@media screen and (max-width: 966px) {
- .heroBanner {
- padding: 2rem;
- }
-}
-
-.buttons {
- display: flex;
- align-items: center;
- justify-content: center;
-}
-
-.features {
- display: flex;
- align-items: center;
- padding: 2rem 0;
- width: 100%;
-}
-
-.featureImage {
- height: 200px;
- width: 200px;
-}
diff --git a/static/assets/example_vc.json b/static/assets/example_vc.json
new file mode 100644
index 00000000..e2169200
--- /dev/null
+++ b/static/assets/example_vc.json
@@ -0,0 +1,21 @@
+{
+ "@context": [
+ "https://www.w3.org/2018/credentials/v1",
+ "https://schema.org/"
+ ],
+ "id": "urn:uuid:baef4793-ab07-4c17-a175-ec114b18245e",
+ "type": "VerifiableCredential",
+ "credentialSubject": {
+ "id": "did:tz:tz1aTuW7578MTt3ZtWYCjX65nUXkzE1CMcAf"
+ },
+ "issuer": "did:web:demo.spruceid.com:2021:vc-faucet",
+ "issuanceDate": "2021-09-13T09:19:41Z",
+ "proof": {
+ "type": "Ed25519Signature2018",
+ "proofPurpose": "assertionMethod",
+ "verificationMethod": "did:web:demo.spruceid.com:2021:vc-faucet#key-1",
+ "created": "2021-09-13T09:19:41.374Z",
+ "jws": "eyJhbGciOiJFZERTQSIsImNyaXQiOlsiYjY0Il0sImI2NCI6ZmFsc2V9..uwSzKxDeXk4nCd6EH6H-7GwaXNwgdoEBPNsrCbbcmJV9hJRrwZPJakXaK6c4uFkFoICGUikTBifmEdV_7BOCCg"
+ },
+ "expirationDate": "2021-10-13T09:19:41Z"
+}
\ No newline at end of file
diff --git a/static/index.html b/static/index.html
deleted file mode 100644
index 710a60f2..00000000
--- a/static/index.html
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
- Spruce Developer Portal
-
-
- If you are not redirected automatically, follow this
- link.
-
-
\ No newline at end of file