Repository: facelessuser/coloraide (language: python)

Issue:
Adjustment to spline interpolation and extrapolation
When extrapolating past the end of a clamped spline, the intention is for the interpolation to continue, but in a linear fashion. While this currently works, sort of, the results are somewhat stunted. This is because we are still using the spline logic, but forcing the interpolation by stacking multiple endpoints. This is great for guiding a spline through its endpoint, but not necessarily to extend it past the end.

We can see here our stunted extrapolation:

![bad_extrapolate](https://user-images.githubusercontent.com/1055125/184139355-5e762e87-db5a-48d9-9b0a-d0ef82ea21d5.png)

But the fix is simple. For any initial `t` (not counting what happens after an easing function) that is beyond the [0, 1] range, we can simply use linear interpolation between the last 2 control points.  This will extend the line in a linear fashion. And due to the way the endpoints are clamped, this should have the slopes matching just fine.

![good-extrapolate](https://user-images.githubusercontent.com/1055125/184139817-55e05c91-0328-4814-824d-4156cf3e1aec.png)







Discussion / hints:

Fix patch:
diff --git a/.stylelintrc b/.stylelintrc
index c4a1b2871..f683e4cf4 100644
--- a/.stylelintrc
+++ b/.stylelintrc
@@ -38,6 +38,7 @@
     "unit-allowed-list": ["px", "em", "deg", "ms", "%", "mm", "vh", "dppx", "s"],
     "value-keyword-case": "lower",
     "value-no-vendor-prefix": true,
-    "function-no-unknown": null
+    "function-no-unknown": null,
+    "annotation-no-unknown": [true, {"ignoreAnnotations": ["default"]}]
   }
 }
diff --git a/coloraide/__meta__.py b/coloraide/__meta__.py
index d4d51a092..a20c1cf28 100644
--- a/coloraide/__meta__.py
+++ b/coloraide/__meta__.py
@@ -192,5 +192,5 @@ def parse_version(ver: str) -> Version:
     return Version(major, minor, micro, release, pre, post, dev)
 
 
-__version_info__ = Version(1, 1, 1, ".dev")
+__version_info__ = Version(1, 2, 0, ".dev")
 __version__ = __version_info__._get_canonical()
diff --git a/coloraide/interpolate/bspline.py b/coloraide/interpolate/bspline.py
index 945b919e2..0e1afefb6 100644
--- a/coloraide/interpolate/bspline.py
+++ b/coloraide/interpolate/bspline.py
@@ -108,8 +108,8 @@ def adjust_endpoints(self) -> None:
         # can properly evaluate the spline from start to finish. Additionally, when the extrapolating
         # past the 0 - 1 boundary, provide some linear behavior
         self.extrapolated = [
-            list(zip(self.coordinates[0], self.coordinates[0], self.coordinates[0], self.coordinates[1])),
-            list(zip(self.coordinates[-2], self.coordinates[-1], self.coordinates[-1], self.coordinates[-1]))
+            list(zip(self.coordinates[0], self.coordinates[1])),
+            list(zip(self.coordinates[-2], self.coordinates[-1]))
         ]
         self.coordinates.insert(0, [2 * a - b for a, b in zip(self.coordinates[0], self.coordinates[1])])
         self.coordinates.append([2 * a - b for a, b in zip(self.coordinates[-1], self.coordinates[-2])])
@@ -154,13 +154,14 @@ def interpolate(
 
             # If `t` ends up spilling out past our boundaries, we need to extrapolate
             if self.extrapolate and index == 1 and point < 0.0:
-                p0, p1, p2, p3 = self.extrapolated[0][i]
+                p0, p1 = self.extrapolated[0][i]
+                channels.append(alg.lerp(p0, p1, t))
             elif self.extrapolate and index == self.length - 1 and point > 1.0:
-                p0, p1, p2, p3 = self.extrapolated[1][i]
+                p0, p1 = self.extrapolated[1][i]
+                channels.append(alg.lerp(p0, p1, t))
             else:
                 p0, p1, p2, p3 = coords[i]
-
-            channels.append(self.calculate(p0, p1, p2, p3, t))
+                channels.append(self.calculate(p0, p1, p2, p3, t))
 
         # Small adjustment for floating point math and alpha channels
         if 1 - channels[-1] < 1e-6:
diff --git a/docs/src/markdown/about/changelog.md b/docs/src/markdown/about/changelog.md
index da46405be..df1a3d2b6 100644
--- a/docs/src/markdown/about/changelog.md
+++ b/docs/src/markdown/about/changelog.md
@@ -1,7 +1,8 @@
 # Changelog
 
-## x.x.x
+## 1.2.0
 
+- **Enhance**: Better extrapolation past end of spline.
 - **FIX**: Small speed up in natural spline calculation.
 - **FIX**: Fix import that should have been relative, not absolute.
 
diff --git a/docs/src/mkdocs.yml b/docs/src/mkdocs.yml
index 4b7e711af..812aa7b7e 100644
--- a/docs/src/mkdocs.yml
+++ b/docs/src/mkdocs.yml
@@ -205,7 +205,7 @@ extra_css:
   - assets/coloraide-extras/extra.css
 extra_javascript:
   - https://unpkg.com/mermaid@8.13.3/dist/mermaid.min.js
-  - playground-config-4a739f7f.js
+  - playground-config-4f253b91.js
   - https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js
   - assets/coloraide-extras/extra-notebook.js
 
diff --git a/docs/src/py/notebook.py b/docs/src/py/notebook.py
index bae3e71b8..9ce225433 100644
--- a/docs/src/py/notebook.py
+++ b/docs/src/py/notebook.py
@@ -156,6 +156,7 @@ def execute(cmd, no_except=True, inline=False):
         extras = None
 
     g = {k: getattr(coloraide, k) for k in coloraide.__all__}
+    g['coloraide'] = coloraide
     g['Color'] = everything.ColorAll
     g['HtmlRow'] = HtmlRow
     g['HtmlSteps'] = HtmlSteps
diff --git a/docs/theme/assets/coloraide-extras/extra-notebook-a4927f29.js b/docs/theme/assets/coloraide-extras/extra-notebook-a4927f29.js
deleted file mode 100644
index f5f3139ba..000000000
--- a/docs/theme/assets/coloraide-extras/extra-notebook-a4927f29.js
+++ /dev/null
@@ -1,4 +0,0 @@
-function _typeof(e){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_typeof(e)}var runtime=function(e){"use strict";var t,n=Object.prototype,o=n.hasOwnProperty,r="function"==typeof Symbol?Symbol:{},i=r.iterator||"@@iterator",a=r.asyncIterator||"@@asyncIterator",s=r.toStringTag||"@@toStringTag";function c(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{c({},"")}catch(e){c=function(e,t,n){return e[t]=n}}function l(e,t,n,o){var r=t&&t.prototype instanceof y?t:y,i=Object.create(r.prototype),a=new T(o||[]);return i._invoke=function(e,t,n){var o=d;return function(r,i){if(o===f)throw new Error("Generator is already running");if(o===m){if("throw"===r)throw i;return P()}for(n.method=r,n.arg=i;;){var a=n.delegate;if(a){var s=L(a,n);if(s){if(s===h)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===d)throw o=m,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=f;var c=u(e,t,n);if("normal"===c.type){if(o=n.done?m:p,c.arg===h)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o=m,n.method="throw",n.arg=c.arg)}}}(e,n,a),i}function u(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}e.wrap=l;var d="suspendedStart",p="suspendedYield",f="executing",m="completed",h={};function y(){}function g(){}function v(){}var w={};c(w,i,(function(){return this}));var _=Object.getPrototypeOf,x=_&&_(_(I([])));x&&x!==n&&o.call(x,i)&&(w=x);var b=v.prototype=y.prototype=Object.create(w);function E(e){["next","throw","return"].forEach((function(t){c(e,t,(function(e){return this._invoke(t,e)}))}))}function k(e,t){function n(r,i,a,s){var c=u(e[r],e,i);if("throw"!==c.type){var l=c.arg,d=l.value;return d&&"object"===_typeof(d)&&o.call(d,"__await")?t.resolve(d.__await).then((function(e){n("next",e,a,s)}),(function(e){n("throw",e,a,s)})):t.resolve(d).then((function(e){l.value=e,a(l)}),(function(e){return n("throw",e,a,s)}))}s(c.arg)}var r;this._invoke=function(e,o){function i(){return new t((function(t,r){n(e,o,t,r)}))}return r=r?r.then(i,i):i()}}function L(e,n){var o=e.iterator[n.method];if(o===t){if(n.delegate=null,"throw"===n.method){if(e.iterator.return&&(n.method="return",n.arg=t,L(e,n),"throw"===n.method))return h;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return h}var r=u(o,e.iterator,n.arg);if("throw"===r.type)return n.method="throw",n.arg=r.arg,n.delegate=null,h;var i=r.arg;return i?i.done?(n[e.resultName]=i.value,n.next=e.nextLoc,"return"!==n.method&&(n.method="next",n.arg=t),n.delegate=null,h):i:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,h)}function S(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function C(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function T(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(S,this),this.reset(!0)}function I(e){if(e){var n=e[i];if(n)return n.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var r=-1,a=function n(){for(;++r<e.length;)if(o.call(e,r))return n.value=e[r],n.done=!1,n;return n.value=t,n.done=!0,n};return a.next=a}}return{next:P}}function P(){return{value:t,done:!0}}return g.prototype=v,c(b,"constructor",v),c(v,"constructor",g),g.displayName=c(v,s,"GeneratorFunction"),e.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===g||"GeneratorFunction"===(t.displayName||t.name))},e.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,v):(e.__proto__=v,c(e,s,"GeneratorFunction")),e.prototype=Object.create(b),e},e.awrap=function(e){return{__await:e}},E(k.prototype),c(k.prototype,a,(function(){return this})),e.AsyncIterator=k,e.async=function(t,n,o,r,i){void 0===i&&(i=Promise);var a=new k(l(t,n,o,r),i);return e.isGeneratorFunction(n)?a:a.next().then((function(e){return e.done?e.value:a.next()}))},E(b),c(b,s,"Generator"),c(b,i,(function(){return this})),c(b,"toString",(function(){return"[object Generator]"})),e.keys=function(e){var t=[];for(var n in e)t.push(n);return t.reverse(),function n(){for(;t.length;){var o=t.pop();if(o in e)return n.value=o,n.done=!1,n}return n.done=!0,n}},e.values=I,T.prototype={constructor:T,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=t,this.done=!1,this.delegate=null,this.method="next",this.arg=t,this.tryEntries.forEach(C),!e)for(var n in this)"t"===n.charAt(0)&&o.call(this,n)&&!isNaN(+n.slice(1))&&(this[n]=t)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var n=this;function r(o,r){return s.type="throw",s.arg=e,n.next=o,r&&(n.method="next",n.arg=t),!!r}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],s=a.completion;if("root"===a.tryLoc)return r("end");if(a.tryLoc<=this.prev){var c=o.call(a,"catchLoc"),l=o.call(a,"finallyLoc");if(c&&l){if(this.prev<a.catchLoc)return r(a.catchLoc,!0);if(this.prev<a.finallyLoc)return r(a.finallyLoc)}else if(c){if(this.prev<a.catchLoc)return r(a.catchLoc,!0)}else{if(!l)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return r(a.finallyLoc)}}}},abrupt:function(e,t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev<r.finallyLoc){var i=r;break}}i&&("break"===e||"continue"===e)&&i.tryLoc<=t&&t<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=e,a.arg=t,i?(this.method="next",this.next=i.finallyLoc,h):this.complete(a)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),h},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),C(n),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var o=n.completion;if("throw"===o.type){var r=o.arg;C(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(e,n,o){return this.delegate={iterator:I(e),resultName:n,nextLoc:o},"next"===this.method&&(this.arg=t),h}},e}("object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports:{});try{regeneratorRuntime=runtime}catch(e){"object"===("undefined"==typeof globalThis?"undefined":_typeof(globalThis))?globalThis.regeneratorRuntime=runtime:Function("r","regeneratorRuntime = r")(runtime)}!function(){"use strict";function e(){
-/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
-e=function(){return t};var t={},n=Object.prototype,o=n.hasOwnProperty,r="function"==typeof Symbol?Symbol:{},i=r.iterator||"@@iterator",a=r.asyncIterator||"@@asyncIterator",s=r.toStringTag||"@@toStringTag";function c(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{c({},"")}catch(e){c=function(e,t,n){return e[t]=n}}function l(e,t,n,o){var r=t&&t.prototype instanceof p?t:p,i=Object.create(r.prototype),a=new k(o||[]);return i._invoke=function(e,t,n){var o="suspendedStart";return function(r,i){if("executing"===o)throw new Error("Generator is already running");if("completed"===o){if("throw"===r)throw i;return S()}for(n.method=r,n.arg=i;;){var a=n.delegate;if(a){var s=x(a,n);if(s){if(s===d)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===o)throw o="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o="executing";var c=u(e,t,n);if("normal"===c.type){if(o=n.done?"completed":"suspendedYield",c.arg===d)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o="completed",n.method="throw",n.arg=c.arg)}}}(e,n,a),i}function u(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}t.wrap=l;var d={};function p(){}function f(){}function m(){}var h={};c(h,i,(function(){return this}));var y=Object.getPrototypeOf,g=y&&y(y(L([])));g&&g!==n&&o.call(g,i)&&(h=g);var v=m.prototype=p.prototype=Object.create(h);function w(e){["next","throw","return"].forEach((function(t){c(e,t,(function(e){return this._invoke(t,e)}))}))}function _(e,t){function n(r,i,a,s){var c=u(e[r],e,i);if("throw"!==c.type){var l=c.arg,d=l.value;return d&&"object"==_typeof(d)&&o.call(d,"__await")?t.resolve(d.__await).then((function(e){n("next",e,a,s)}),(function(e){n("throw",e,a,s)})):t.resolve(d).then((function(e){l.value=e,a(l)}),(function(e){return n("throw",e,a,s)}))}s(c.arg)}var r;this._invoke=function(e,o){function i(){return new t((function(t,r){n(e,o,t,r)}))}return r=r?r.then(i,i):i()}}function x(e,t){var n=e.iterator[t.method];if(void 0===n){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=void 0,x(e,t),"throw"===t.method))return d;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return d}var o=u(n,e.iterator,t.arg);if("throw"===o.type)return t.method="throw",t.arg=o.arg,t.delegate=null,d;var r=o.arg;return r?r.done?(t[e.resultName]=r.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=void 0),t.delegate=null,d):r:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,d)}function b(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function E(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function k(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(b,this),this.reset(!0)}function L(e){if(e){var t=e[i];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var n=-1,r=function t(){for(;++n<e.length;)if(o.call(e,n))return t.value=e[n],t.done=!1,t;return t.value=void 0,t.done=!0,t};return r.next=r}}return{next:S}}function S(){return{value:void 0,done:!0}}return f.prototype=m,c(v,"constructor",m),c(m,"constructor",f),f.displayName=c(m,s,"GeneratorFunction"),t.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===f||"GeneratorFunction"===(t.displayName||t.name))},t.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,m):(e.__proto__=m,c(e,s,"GeneratorFunction")),e.prototype=Object.create(v),e},t.awrap=function(e){return{__await:e}},w(_.prototype),c(_.prototype,a,(function(){return this})),t.AsyncIterator=_,t.async=function(e,n,o,r,i){void 0===i&&(i=Promise);var a=new _(l(e,n,o,r),i);return t.isGeneratorFunction(n)?a:a.next().then((function(e){return e.done?e.value:a.next()}))},w(v),c(v,s,"Generator"),c(v,i,(function(){return this})),c(v,"toString",(function(){return"[object Generator]"})),t.keys=function(e){var t=[];for(var n in e)t.push(n);return t.reverse(),function n(){for(;t.length;){var o=t.pop();if(o in e)return n.value=o,n.done=!1,n}return n.done=!0,n}},t.values=L,k.prototype={constructor:k,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(E),!e)for(var t in this)"t"===t.charAt(0)&&o.call(this,t)&&!isNaN(+t.slice(1))&&(this[t]=void 0)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var t=this;function n(n,o){return a.type="throw",a.arg=e,t.next=n,o&&(t.method="next",t.arg=void 0),!!o}for(var r=this.tryEntries.length-1;r>=0;--r){var i=this.tryEntries[r],a=i.completion;if("root"===i.tryLoc)return n("end");if(i.tryLoc<=this.prev){var s=o.call(i,"catchLoc"),c=o.call(i,"finallyLoc");if(s&&c){if(this.prev<i.catchLoc)return n(i.catchLoc,!0);if(this.prev<i.finallyLoc)return n(i.finallyLoc)}else if(s){if(this.prev<i.catchLoc)return n(i.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return n(i.finallyLoc)}}}},abrupt:function(e,t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev<r.finallyLoc){var i=r;break}}i&&("break"===e||"continue"===e)&&i.tryLoc<=t&&t<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=e,a.arg=t,i?(this.method="next",this.next=i.finallyLoc,d):this.complete(a)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),d},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),E(n),d}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var o=n.completion;if("throw"===o.type){var r=o.arg;E(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,n){return this.delegate={iterator:L(e),resultName:t,nextLoc:n},"next"===this.method&&(this.arg=void 0),d}},t}function t(e,t,n,o,r,i,a){try{var s=e[i](a),c=s.value}catch(e){return void n(e)}s.done?t(c):Promise.resolve(c).then(o,r)}function n(e){return function(){var n=this,o=arguments;return new Promise((function(r,i){var a=e.apply(n,o);function s(e){t(a,r,i,s,c,"next",e)}function c(e){t(a,r,i,s,c,"throw",e)}s(void 0)}))}}function o(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var o,r,i=[],a=!0,s=!1;try{for(n=n.call(e);!(a=(o=n.next()).done)&&(i.push(o.value),!t||i.length!==t);a=!0);}catch(e){s=!0,r=e}finally{try{a||null==n.return||n.return()}finally{if(s)throw r}}return i}(e,t)||r(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(e,t){if(e){if("string"==typeof e)return i(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(e,t):void 0}}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n<t;n++)o[n]=e[n];return o}var a,s,c,l,u,d,p,f,m,h,y,g,v,w,_,x,b,E,k,L,S,C,T,I;a=null,s=!1,c="",l="",u={},d=/.*?_(\d+)$/,p=!1,f="",m=!1,h=/^( {1,4}|\t)/,y="\n\"\"\"\nExecute Python code in code blocks (color previews added specifically for ColorAide).\n\nThis can be executed in either a Pyodide environment of a normal Python environment.\n3rd party libraries (that are not available directly from Pyodide) are only loaded\nwhen needed so that Pyodide will have a chance to load them if necessary. This is also\nhardcoded to work with ColorAide.\n\nThis is meant to be executed by Pyodide on preformatted HTML to allow for live execution of\ncode snippets using `coloraide`.\n\nTransform Python code by executing it, transforming to a Python console output,\nand finding and outputting color previews.\n\"\"\"\nimport xml.etree.ElementTree as Etree\nfrom collections.abc import Sequence\nfrom collections import namedtuple\nimport ast\nfrom io import StringIO\nimport contextlib\nimport sys\nimport re\n\nWEBSPACE = \"srgb\"\nAST_BLOCKS = (ast.If, ast.For, ast.While, ast.Try, ast.With, ast.FunctionDef, ast.ClassDef)\n\nRE_COLOR_START = re.compile(\n    r\"(?i)(?:\\b(?<![-#&$])(?:color|hsla?|lch|lab|hwb|rgba?)\\(|\\b(?<![-#&$])[\\w]{3,}(?![(-])\\b|(?<![&])#)\"\n)\n\ntemplate = '''<div class=\"playground\" id=\"__playground_{el_id}\">\n<div class=\"playground-results\" id=\"__playground-results_{el_id}\">\n{results}\n</div>\n<div class=\"playground-code hidden\" id=\"__playground-code_{el_id}\">\n<form autocomplete=\"off\">\n<textarea class=\"playground-inputs\" id=\"__playground-inputs_{el_id}\" spellcheck=\"false\">{raw_source}</textarea>\n</form>\n</div>\n\n<button id=\"__playground-edit_{el_id}\" class=\"playground-edit\" title=\"Edit the current snippet\">Edit</button>\n<button id=\"__playground-share_{el_id}\" class=\"playground-share\" title=\"Copy URL to current snippet\">Share</button>\n<button id=\"__playground-run_{el_id}\" class=\"playground-run hidden\" title=\"Run code (Ctrl + Enter)\">Run</button>\n<button id=\"__playground-cancel_{el_id}\" class=\"playground-cancel hidden\" title=\"Cancel edit (Escape)\">Cancel</button>\n</div>'''\n\ncode_id = 0\n\n\nclass HtmlGradient(list):\n    \"\"\"HTML color gradient.\"\"\"\n\n\nclass HtmlSteps(list):\n    \"\"\"HTML color steps.\"\"\"\n\n\nclass ColorTuple(namedtuple('ColorTuple', ['string', 'color'])):\n    \"\"\"Color tuple.\"\"\"\n\n\nclass HtmlRow(list):\n    \"\"\"Create a row with the given colors.\"\"\"\n\n\ndef _escape(txt):\n    \"\"\"Basic HTML escaping.\"\"\"\n\n    txt = txt.replace('&', '&amp;')\n    txt = txt.replace('<', '&lt;')\n    txt = txt.replace('>', '&gt;')\n    return txt\n\n\n@contextlib.contextmanager\ndef std_output(stdout=None):\n    \"\"\"Capture standard out.\"\"\"\n    old = sys.stdout\n    if stdout is None:\n        stdout = StringIO()\n    sys.stdout = stdout\n    yield stdout\n    sys.stdout = old\n\n\ndef get_colors(result):\n    \"\"\"Get color from results.\"\"\"\n\n    from coloraide import Color\n    from coloraide.everything import ColorAll\n    from coloraide.interpolate import Interpolator\n    try:\n        from coloraide_extras.everything import ColorAll as Color2\n    except ImportError:\n        Color2 = ColorAll\n\n    colors = []\n    if isinstance(result, HtmlRow):\n        colors = HtmlRow(\n            [\n                ColorTuple(c.to_string(fit=False), c.clone()) if isinstance(c, Color) else ColorTuple(c, Color2(c))\n                for c in result\n            ]\n        )\n    elif isinstance(result, (HtmlSteps, HtmlGradient)):\n        t = type(result)\n        colors = t([c.clone() if isinstance(c, Color) else Color2(c) for c in result])\n    elif isinstance(result, Color):\n        colors.append(ColorTuple(result.to_string(fit=False), result.clone()))\n    elif isinstance(result, Interpolator):\n        colors = HtmlGradient(result.steps(steps=5, max_delta_e=2.3))\n    elif isinstance(result, str):\n        try:\n            colors.append(ColorTuple(result, Color2(result)))\n        except Exception:\n            pass\n    elif isinstance(result, Sequence):\n        for x in result:\n            if isinstance(x, Color):\n                colors.append(ColorTuple(x.to_string(fit=False), x.clone()))\n            elif isinstance(x, str):\n                try:\n                    colors.append(ColorTuple(x, Color2(x)))\n                except Exception:\n                    pass\n    return colors\n\n\ndef find_colors(text):\n    \"\"\"Find colors in text buffer.\"\"\"\n\n    try:\n        from coloraide_extras.everything import ColorAll as Color\n    except ImportError:\n        from coloraide.everything import ColorAll as Color\n\n    colors = []\n    for m in RE_COLOR_START.finditer(text):\n        start = m.start()\n        mcolor = Color.match(text, start=start)\n        if mcolor is not None:\n            colors.append(ColorTuple(text[mcolor.start:mcolor.end], mcolor.color))\n    return colors\n\n\ndef execute(cmd, no_except=True, inline=False):\n    \"\"\"Execute color commands.\"\"\"\n\n    import coloraide\n    import coloraide.everything as everything\n    try:\n        import coloraide_extras\n        import coloraide_extras.everything as extras\n    except ImportError:\n        coloraide_extras = None\n        extras = None\n\n    g = {k: getattr(coloraide, k) for k in coloraide.__all__}\n    g['Color'] = everything.ColorAll\n    g['HtmlRow'] = HtmlRow\n    g['HtmlSteps'] = HtmlSteps\n    g['HtmlGradient'] = HtmlGradient\n\n    if extras is not None:\n        g['Color'] = extras.ColorAll\n        g['coloraide_extras'] = coloraide_extras\n\n    console = ''\n    colors = []\n\n    # Build AST tree\n    src = cmd.strip()\n    lines = src.split('\\n')\n    try:\n        tree = ast.parse(src)\n    except Exception as e:\n        if no_except:\n            if not inline:\n                from pymdownx.superfences import SuperFencesException\n                raise SuperFencesException from e\n            else:\n                from pymdownx.inlinehilite import InlineHiliteException\n                raise InlineHiliteException from e\n        import traceback\n        return '{}'.format(traceback.format_exc()), colors\n\n    for node in tree.body:\n        result = None\n\n        # Format source as Python console statements\n        start = node.lineno\n        end = node.end_lineno\n        stmt = lines[start - 1: end]\n        command = ''\n        for i, line in enumerate(stmt, 0):\n            if i == 0:\n                stmt[i] = '>>> ' + line\n            else:\n                stmt[i] = '... ' + line\n        command += '\\n'.join(stmt)\n        if isinstance(node, AST_BLOCKS):\n            command += '\\n... '\n\n        try:\n            # Capture anything sent to standard out\n            text = ''\n            with std_output() as s:\n                # Execute code\n                if isinstance(node, ast.Expr):\n                    _eval = ast.Expression(node.value)\n                    result = eval(compile(_eval, '<string>', 'eval'), g)\n                else:\n                    _exec = ast.Module([node], [])\n                    exec(compile(_exec, '<string>', 'exec'), g)\n\n                # Execution went well, so append command\n                console += command\n\n                # Output captured standard out after statements\n                text = s.getvalue()\n                if text:\n                    clist = find_colors(text)\n                    if clist:\n                        colors.append(clist)\n                    console += '\\n{}'.format(text)\n                s.flush()\n        except Exception as e:\n            if no_except:\n                if not inline:\n                    from pymdownx.superfences import SuperFencesException\n                    raise SuperFencesException from e\n                else:\n                    from pymdownx.inlinehilite import InlineHiliteException\n                    raise InlineHiliteException from e\n            import traceback\n            console += '{}\\n{}'.format(command, traceback.format_exc())\n            # Failed for some reason, so quit\n            break\n\n        # If we got a result, output it as well\n        if result is not None:\n            clist = get_colors(result)\n            if clist:\n                colors.append(clist)\n            console += '{}{}\\n'.format('\\n' if not text else '', str(result))\n        else:\n            console += '\\n' if not text else ''\n\n    return console, colors\n\n\ndef colorize(src, lang, **options):\n    \"\"\"Colorize.\"\"\"\n\n    from pygments import highlight\n    from pygments.lexers import get_lexer_by_name\n    from pygments.formatters import find_formatter_class\n    HtmlFormatter = find_formatter_class('html')\n\n    lexer = get_lexer_by_name(lang, **options)\n    formatter = HtmlFormatter(cssclass=\"highlight\", wrapcode=True)\n    return highlight(src, lexer, formatter).strip()\n\n\ndef color_command_validator(language, inputs, options, attrs, md):\n    \"\"\"Color validator.\"\"\"\n\n    valid_inputs = set(['exceptions'])\n\n    for k, v in inputs.items():\n        if k in valid_inputs:\n            options[k] = True\n            continue\n        attrs[k] = v\n    return True\n\n\ndef _color_command_console(colors):\n    \"\"\"Color command formatter.\"\"\"\n\n    el = ''\n    bar = False\n    values = []\n    for item in colors:\n        if isinstance(item, (HtmlGradient, HtmlSteps)):\n            current = total = percent = last = 0\n            if isinstance(item, HtmlSteps):\n                total = len(item)\n                percent = 100 / total\n                current = percent\n\n            if bar:\n                el += '<div class=\"swatch-bar\">{}</div>'.format(' '.join(values))\n                values = []\n            sub_el1 = '<div class=\"swatch-bar\"><span class=\"swatch swatch-gradient\">{}</span></div>'\n            style = \"--swatch-stops: \"\n            stops = []\n            for e, color in enumerate(item):\n                color.fit(WEBSPACE)\n                if current:\n                    stops.append('{} {}%'.format(color.convert(WEBSPACE).to_string(), str(last)))\n                    stops.append('{} {}%'.format(color.convert(WEBSPACE).to_string(), str(current)))\n                    last = current\n                    if e < (total - 1):\n                        current += percent\n                    else:\n                        current = 100\n                else:\n                    stops.append(color.convert(WEBSPACE).to_string())\n            if not stops:\n                stops.extend(['transparent'] * 2)\n            if len(stops) == 1:\n                stops.append(stops[0])\n            style += ','.join(stops)\n            sub_el2 = '<span class=\"swatch-color\" style=\"{}\"></span>'.format(style)\n            el += sub_el1.format(sub_el2)\n            bar = False\n        else:\n            is_row = False\n            if isinstance(item, HtmlRow):\n                is_row = True\n                if bar and values:\n                    el += '<div class=\"swatch-bar\">{}</div>'.format(' '.join(values))\n                    values = []\n                bar = False\n\n            bar = True\n            base_classes = \"swatch\"\n            for color in item:\n                if not color.color.in_gamut(WEBSPACE):\n                    base_classes += \" out-of-gamut\"\n                color.color.fit(WEBSPACE)\n                srgb = color.color.convert(WEBSPACE)\n                value1 = srgb.to_string(alpha=False)\n                value2 = srgb.to_string()\n                style = \"--swatch-stops: {} 50%, {} 50%\".format(value1, value2)\n                title = color.string\n                classes = base_classes\n                c = '<span class=\"swatch-color\" style=\"{style}\"></span>'.format(style=style)\n                c = '<span class=\"{classes}\" title=\"{title}&#013;Copy to clipboard\">{color}</span>'.format(\n                    classes=classes,\n                    color=c,\n                    title=title\n                )\n                values.append(c)\n\n            if is_row and values:\n                el += '<div class=\"swatch-bar\">{}</div>'.format(' '.join(values))\n                values = []\n                bar = False\n    if bar:\n        el += '<div class=\"swatch-bar\">{}</div>'.format(' '.join(values))\n        values = []\n\n    return el\n\n\ndef color_command_formatter(src=\"\", language=\"\", class_name=None, options=None, md=\"\", **kwargs):\n    \"\"\"Formatter wrapper.\"\"\"\n\n    global code_id\n    from pymdownx.superfences import SuperFencesException\n\n    try:\n        if len(md.preprocessors['fenced_code_block'].extension.stash) == 0:\n            code_id = 0\n\n        # Check if we should allow exceptions\n        exceptions = options.get('exceptions', False) if options is not None else False\n\n        console, colors = execute(src.strip(), not exceptions)\n        el = _color_command_console(colors)\n\n        el += md.preprocessors['fenced_code_block'].extension.superfences[0]['formatter'](\n            src=console,\n            class_name=\"highlight\",\n            language='pycon',\n            md=md,\n            options=options,\n            **kwargs\n        )\n        el = '<div class=\"color-command\">{}</div>'.format(el)\n        el = template.format(el_id=code_id, raw_source=_escape(src), results=el)\n        code_id += 1\n    except SuperFencesException:\n        raise\n    except Exception:\n        from pymdownx import superfences\n        import traceback\n        print(traceback.format_exc())\n        return superfences.fence_code_format(src, 'text', class_name, options, md, **kwargs)\n    return el\n\n\ndef color_formatter(src=\"\", language=\"\", class_name=None, md=\"\", exceptions=True):\n    \"\"\"Formatter wrapper.\"\"\"\n\n    from pymdownx.inlinehilite import InlineHiliteException\n    try:\n        from coloraide_extras.everything import ColorAll as Color\n    except ImportError:\n        from coloraide.everything import ColorAll as Color\n\n    try:\n        result = src.strip()\n\n        try:\n            color = Color(result.strip())\n        except Exception:\n            console, colors = execute(result, exceptions, inline=True)\n            if len(colors) != 1 or len(colors[0]) != 1:\n                if exceptions:\n                    raise InlineHiliteException('Only one color allowed')\n                else:\n                    raise ValueError('Only one color allowed')\n            color = colors[0][0].color\n            result = colors[0][0].string\n\n        el = Etree.Element('span')\n        stops = []\n        if not color.in_gamut(WEBSPACE):\n            color.fit(WEBSPACE)\n            attributes = {'class': \"swatch out-of-gamut\", \"title\": result}\n            sub_el = Etree.SubElement(el, 'span', attributes)\n            stops.append(color.convert(WEBSPACE).to_string(hex=True, alpha=False))\n            if color[-1] < 1.0:\n                stops[-1] += ' 50%'\n                stops.append(color.convert(WEBSPACE).to_string(hex=True) + ' 50%')\n        else:\n            attributes = {'class': \"swatch\", \"title\": result}\n            sub_el = Etree.SubElement(el, 'span', attributes)\n            stops.append(color.convert(WEBSPACE).to_string(hex=True, alpha=False))\n            if color[-1] < 1.0:\n                stops[-1] += ' 50%'\n                stops.append(color.convert(WEBSPACE).to_string(hex=True) + ' 50%')\n\n        if not stops:\n            stops.extend(['transparent'] * 2)\n        if len(stops) == 1:\n            stops.append(stops[0])\n\n        Etree.SubElement(\n            sub_el,\n            'span',\n            {\n                \"class\": \"swatch-color\",\n                \"style\": \"--swatch-stops: {};\".format(','.join(stops))\n            }\n        )\n\n        el.append(md.inlinePatterns['backtick'].handle_code('css-color', result))\n    except InlineHiliteException:\n        raise\n    except Exception:\n        import traceback\n        print(traceback.format_exc())\n        el = md.inlinePatterns['backtick'].handle_code('text', src)\n    return el\n\n\n#############################\n# Pyodide specific code\n#############################\ndef live_color_command_formatter(src):\n    \"\"\"Formatter wrapper.\"\"\"\n\n    try:\n        console, colors = execute(src.strip(), False)\n        el = _color_command_console(colors)\n\n        if not colors:\n            el += '<div class=\"swatch-bar\"></div>'\n\n        el += colorize(console, 'pycon', **{'python3': True, 'stripnl': False})\n        el = '<div class=\"color-command\">{}</div>'.format(el)\n    except Exception:\n        return '<div class=\"color-command\"><div class=\"swatch-bar\"></div>{}</div>'.format(colorize('', 'text'))\n    return el\n\n\ndef live_color_command_validator(language, inputs, options, attrs, md):\n    \"\"\"Color validator.\"\"\"\n\n    value = color_command_validator(language, inputs, options, attrs, md)\n    # Live edit, we always allow exceptions so not to crash the service.\n    options['exceptions'] = True\n    return value\n\n\ndef live_color_formatter(src=\"\", language=\"\", class_name=None, md=\"\"):\n    \"\"\"Color formatter for a live environment.\"\"\"\n\n    return color_formatter(src, language, class_name, md, exceptions=False)\n\n\ndef render_console(*args):\n    \"\"\"Render console update.\"\"\"\n\n    from js import document\n\n    try:\n        # Run code\n        inputs = document.getElementById(\"__playground-inputs_{}\".format(globals()['id_num']))\n        results = document.getElementById(\"__playground-results_{}\".format(globals()['id_num']))\n        results.innerHTML = live_color_command_formatter(inputs.value)\n        scrollingElement = results.querySelector('code')\n        scrollingElement.scrollTop = scrollingElement.scrollHeight\n    except Exception as e:\n        print(e)\n\n\ndef render_notebook(*args):\n    \"\"\"Render notebook.\"\"\"\n\n    import markdown\n    from pymdownx import slugs\n    from js import document\n\n    text = globals().get('content', '')\n    extensions = [\n        'markdown.extensions.toc',\n        'markdown.extensions.admonition',\n        'markdown.extensions.smarty',\n        'pymdownx.betterem',\n        'markdown.extensions.attr_list',\n        'markdown.extensions.def_list',\n        'markdown.extensions.tables',\n        'markdown.extensions.abbr',\n        'markdown.extensions.footnotes',\n        'markdown.extensions.md_in_html',\n        'pymdownx.superfences',\n        'pymdownx.highlight',\n        'pymdownx.inlinehilite',\n        'pymdownx.magiclink',\n        'pymdownx.tilde',\n        'pymdownx.caret',\n        'pymdownx.smartsymbols',\n        'pymdownx.emoji',\n        'pymdownx.escapeall',\n        'pymdownx.tasklist',\n        'pymdownx.striphtml',\n        'pymdownx.snippets',\n        'pymdownx.keys',\n        'pymdownx.details',\n        'pymdownx.saneheaders',\n        'pymdownx.tabbed'\n    ]\n    extension_configs = {\n        'markdown.extensions.toc': {\n            'slugify': slugs.slugify(case=\"lower\"),\n            'permalink': \"\"\n        },\n        'markdown.extensions.smarty': {\n            \"smart_quotes\": False,\n        },\n        'pymdownx.superfences': {\n            'preserve_tabs': True,\n            'custom_fences': [\n                {\n                    \"name\": 'playground',\n                    \"class\": 'playground',\n                    \"format\": color_command_formatter,\n                    \"validator\": live_color_command_validator\n                }\n            ]\n        },\n        'pymdownx.inlinehilite': {\n            'custom_inline': [\n                {\n                    'name': 'color',\n                    'class': 'color',\n                    'format': live_color_formatter\n                }\n            ]\n        },\n        'pymdownx.magiclink': {\n            'repo_url_shortener': True,\n            'repo_url_shorthand': True,\n            'social_url_shorthand': True,\n            'user': 'facelessuser',\n            'repo': 'coloraide'\n        },\n        'pymdownx.keys': {\n            'separator': \"\\uff0b\"\n        }\n    }\n\n    try:\n        html = markdown.markdown(text, extensions=extensions, extension_configs=extension_configs)\n    except Exception:\n        html = ''\n    content = document.getElementById(\"__notebook-render\")\n    content.innerHTML = html\n\n\nimport micropip\nfrom js import location\n\naction = globals().get('action')\nif action == 'notebook':\n    callback = render_notebook\nelse:\n    callback = render_console\n\nbase = location.pathname.lstrip('/').split('/')[0]\nawait micropip.install([location.origin + '/{}/playground/{}'.format(base, w) for w in wheels])\ncallback()\n",g=window.color_notebook.default_playground,v=function(e){return'\n!!! new "This notebook is powered by [Pyodide](https://github.com/pyodide/pyodide). Learn more [here](?notebook=https://gist.githubusercontent.com/facelessuser/7c819668b5eb248ecb9ac608d91391cf/raw/playground.md). Preview, convert, interpolate, and explore!"\n\n````````playground\n'.concat(e,"\n````````\n")},w=function(){m=!0,window.document.dispatchEvent(new Event("DOMContentLoaded",{bubbles:!0,cancelable:!0}))},_=function(e){var t=window.pageXOffset||(document.documentElement||document.body.parentNode||document.body).scrollLeft,n=window.pageYOffset||(document.documentElement||document.body.parentNode||document.body).scrollTop;e.style.height="5px",e.style.height="".concat(e.scrollHeight,"px"),window.scrollTo(t,n)},x=function(e){return encodeURIComponent(e).replace(/[.!'()*]/g,(function(e){return"%".concat(e.charCodeAt(0).toString(16))}))},b=function(){var t=n(e().mark((function t(n){var o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return(o=document.getElementById("__playground-inputs_".concat(n))).setAttribute("readonly",""),a.globals.set("id_num",n),a.globals.set("action","playground"),a.globals.set("wheels",window.color_notebook.playground_wheels),e.next=7,a.runPythonAsync(y);case 7:o.removeAttribute("readonly");case 8:case"end":return e.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}(),E=function(){var t=n(e().mark((function t(n){var o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a.globals.set("content",n),a.globals.set("action","notebook"),a.globals.set("wheels",window.color_notebook.notebook_wheels),e.next=5,a.runPythonAsync(y);case 5:(o=document.getElementById("__notebook-input"))&&(c=n,o.value=n),window.location.hash&&(window.location.href=window.location.href);case 8:case"end":return e.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}(),k=function(){var t=n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(p){e.next=7;break}return p=!0,e.next=4,loadPyodide({indexURL:"https://cdn.jsdelivr.net/pyodide/v0.20.0/full/",fullStdLib:!1});case 4:return a=e.sent,e.next=7,a.loadPackage(["micropip"]);case 7:case"end":return e.stop()}}),t)})));return function(){return t.apply(this,arguments)}}(),L=function(e,t,n){var o=null==t?"Loading...":t,r=n?"loading relative":"loading",i=document.createElement("template");i.innerHTML='<div class="'.concat(r,'"><div class="loader"></div><div>').concat(o,"</div></div>"),e.appendChild(i.content.firstChild)},S=function(e){e.querySelector(".loading")&&e.removeChild(e.querySelector(".loading"))},C=function(e){if("Tab"===e.key){var t=e.target;if(t.selectionStart!==t.selectionEnd){e.preventDefault();for(var n=t.selectionStart,o=t.selectionEnd,r=t.value;n>0&&"\n"!==r[n-1];)n--;for(;o>0&&"\n"!==r[o-1]&&o<r.length;)o++;for(var i=r.substr(n,o-n).split("\n"),a=0;a<i.length;a++)a===i.length-1&&0===i[a].length||(e.shiftKey?i[a]=i[a].replace(h,""):i[a]="    ".concat(i[a]));i=i.join("\n"),t.value=r.substr(0,n)+i+r.substr(o),t.selectionStart=n,t.selectionEnd=n+i.length}}},T=function(){var t=n(e().mark((function t(o){var r;return e().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:r=document.getElementById("__notebook-source"),document.querySelectorAll(".playground").forEach((function(t){var i=t.id.replace(d,"$1"),a=document.getElementById("__playground-inputs_".concat(i)),p=document.getElementById("__playground-results_".concat(i)),f=document.getElementById("__playground-code_".concat(i)),m=document.querySelector("button#__playground-edit_".concat(i)),h=document.querySelector("button#__playground-share_".concat(i)),y=document.querySelector("button#__playground-run_".concat(i)),g=document.querySelector("button#__playground-cancel_".concat(i));if(a.addEventListener("input",(function(){_(a)})),a.addEventListener("keydown",C),r&&o){var v=document.getElementById("__notebook-input");v.addEventListener("input",(function(e){_(e.target)})),v.addEventListener("keydown",C),document.getElementById("__notebook-edit").addEventListener("click",(function(){u[v.id]=v.value,document.getElementById("__notebook-render").classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden"),_(document.getElementById("__notebook-input"))})),document.getElementById("__notebook-md-gist").addEventListener("click",function(){var t=n(e().mark((function t(n){var o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:null!==(o=prompt("Please enter link to the Markdown page source:",l))&&(o=x(o),n.preventDefault(),history.pushState({notebook:o},"","?".concat(new URLSearchParams("notebook=".concat(o)).toString())),I(!1));case 2:case"end":return e.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}()),document.getElementById("__notebook-py-gist").addEventListener("click",function(){var t=n(e().mark((function t(n){var o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:null!==(o=prompt("Please enter the link to the Python code source:",l))&&(o=x(o),n.preventDefault(),history.pushState({source:o},"","?".concat(new URLSearchParams("source=".concat(o)).toString())),I(!1));case 2:case"end":return e.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}()),document.getElementById("__notebook-input").value=c,document.getElementById("__notebook-cancel").addEventListener("click",(function(){v.value=u[v.id],delete u[v.id],document.getElementById("__notebook-render").classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden")})),document.getElementById("__notebook-submit").addEventListener("click",n(e().mark((function t(){var n,o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=document.getElementById("__notebook-render"),c=document.getElementById("__notebook-input").value,n.classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden"),o=document.querySelector("article"),L(o,"Loading Notebook..."),n.innerHTML="",u={},e.next=10,k();case 10:return e.next=12,E(c);case 12:return e.next=14,T();case 14:S(o);case 15:case"end":return e.stop()}}),t)}))))}a.addEventListener("touchmove",(function(e){e.stopPropagation()})),p.addEventListener("click",(function(e){var t=e.target;if(t.matches("span.swatch-color")){var n="",o=t.parentNode;if(!o.matches("span.swatch-gradient")){if(n=(n=o.getAttribute("title").replace("Copy to clipboard","")).replace("\n",""),window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",n);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){var r=document.createElement("textarea");r.textContent=n,r.style.position="fixed",document.body.appendChild(r),r.select();try{return document.execCommand("copy")}catch(e){return prompt("Copy to clipboard: Ctrl+C, Enter",n)}finally{document.body.removeChild(r)}}}}})),m.addEventListener("click",n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:u[i]=a.value,f.classList.toggle("hidden"),p.classList.toggle("hidden"),y.classList.toggle("hidden"),g.classList.toggle("hidden"),m.classList.toggle("hidden"),h.classList.toggle("hidden"),_(a),a.focus();case 9:case"end":return e.stop()}}),t)})))),h.addEventListener("click",n(e().mark((function t(){var o,r,i,s,c;return e().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:o=window.location.pathname.split("/")[1],r=x(a.value),i=window.location,s="/playground/",i.pathname.startsWith("/".concat(o,"/"))&&(s="/".concat(o,"/playground/")),c="".concat(i.protocol,"//").concat(i.host).concat(s,"?code=").concat(r),r.length>1e3?alert("Code must be under a 1000 characters to generate a URL!"):navigator.clipboard.writeText(c).then(n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:alert("Link copied to clipboard :)");case 1:case"end":return e.stop()}}),t)}))),n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:alert("Failed to copy link clipboard!");case 1:case"end":return e.stop()}}),t)}))));case 7:case"end":return t.stop()}}),t)})))),y.addEventListener("click",n(e().mark((function t(){var n,o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!s){e.next=2;break}return e.abrupt("return");case 2:return s=!0,n=f.querySelector("form"),L(n,null,!0),(o=document.querySelectorAll(".playground .playground-run"))&&o.forEach((function(e){e.setAttribute("disabled","")})),e.next=9,k();case 9:return p.querySelector("code").innerHTML="",e.next=12,b(i);case 12:o&&o.forEach((function(e){e.removeAttribute("disabled")})),S(n),f.classList.toggle("hidden"),p.classList.toggle("hidden"),m.classList.toggle("hidden"),h.classList.toggle("hidden"),y.classList.toggle("hidden"),g.classList.toggle("hidden"),delete u[i],s=!1;case 22:case"end":return e.stop()}}),t)})))),g.addEventListener("click",(function(){a.value=u[i],delete u[i],f.classList.toggle("hidden"),p.classList.toggle("hidden"),m.classList.toggle("hidden"),h.classList.toggle("hidden"),y.classList.toggle("hidden"),g.classList.toggle("hidden")}))}));case 3:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}(),I=function(){var t=n(e().mark((function t(o){var r,i,a,s,c,d,p,m,h;return e().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(u={},!window.location.pathname.endsWith("/playground/")){t.next=32;break}if(r=new URLSearchParams(window.location.search),i="Loading Pyodide...",a="Loading Notebook...",s=r.has("source")?r.get("source"):r.get("notebook"),c=document.querySelector("article"),null===s||!s.trim()){t.next=16;break}return L(c,i),t.next=11,k();case 11:S(c),L(c,a);try{d=r.has("source")?"source":"notebook",f=decodeURIComponent(r.toString()),p="",m=new XMLHttpRequest,l=s,m.open("GET",s,!0),m.onload=n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return 4===m.readyState&&200===m.status&&(p=m.responseText),"source"===d&&(p=v(p)),e.next=4,E(p);case 4:return e.next=6,T(o);case 6:S(c),w();case 8:case"end":return e.stop()}}),t)}))),m.send()}catch(e){}t.next=30;break;case 16:return l="",h=v(r.has("code")?r.get("code"):g),f=decodeURIComponent(r.toString()),L(c,i),t.next=22,k();case 22:return S(c),L(c,a),t.next=26,E(h);case 26:return t.next=28,T(o);case 28:S(c),w();case 30:t.next=35;break;case 32:l="",f="",T(o);case 35:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}(),document.addEventListener("click",(function(e){var t=window.location.pathname.split("/")[1],n=e.target||e.srcElement;if("A"===n.tagName&&I&&n.getAttribute("href")&&n.host===window.location.host&&window.location.pathname==="/".concat(t,'/playground/"')&&window.location.pathname===n.pathname&&window.location.search!==n.search){e.preventDefault();var i,a={},s=function(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=r(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var o=0,i=function(){};return{s:i,n:function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,c=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return s=e.done,e},e:function(e){c=!0,a=e},f:function(){try{s||null==n.return||n.return()}finally{if(c)throw a}}}}(new URLSearchParams(n.search));try{for(s.s();!(i=s.n()).done;){var c=o(i.value,2),l=c[0],u=c[1];a[l]=u}}catch(e){s.e(e)}finally{s.f()}history.pushState(a,"",n.href),I(!1)}})),window.addEventListener("popstate",(function(){var e=window.location.pathname.split("/")[1];window.location.pathname==="/".concat(e,"/playground/")&&decodeURIComponent(new URLSearchParams(window.location.search).toString())!==f&&I(!1)})),window.addEventListener("unload",(function(){m=!0})),window.document$.subscribe((function(){m?m=!1:I(!0)}))}();
-//# sourceMappingURL=extra-notebook-a4927f29.js.map
diff --git a/docs/theme/assets/coloraide-extras/extra-notebook-ced27dd8.js b/docs/theme/assets/coloraide-extras/extra-notebook-ced27dd8.js
new file mode 100644
index 000000000..14aa47dc0
--- /dev/null
+++ b/docs/theme/assets/coloraide-extras/extra-notebook-ced27dd8.js
@@ -0,0 +1,4 @@
+function _typeof(e){return _typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},_typeof(e)}var runtime=function(e){"use strict";var t,n=Object.prototype,o=n.hasOwnProperty,r="function"==typeof Symbol?Symbol:{},i=r.iterator||"@@iterator",a=r.asyncIterator||"@@asyncIterator",s=r.toStringTag||"@@toStringTag";function c(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{c({},"")}catch(e){c=function(e,t,n){return e[t]=n}}function l(e,t,n,o){var r=t&&t.prototype instanceof y?t:y,i=Object.create(r.prototype),a=new T(o||[]);return i._invoke=function(e,t,n){var o=d;return function(r,i){if(o===f)throw new Error("Generator is already running");if(o===m){if("throw"===r)throw i;return P()}for(n.method=r,n.arg=i;;){var a=n.delegate;if(a){var s=L(a,n);if(s){if(s===h)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if(o===d)throw o=m,n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o=f;var c=u(e,t,n);if("normal"===c.type){if(o=n.done?m:p,c.arg===h)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o=m,n.method="throw",n.arg=c.arg)}}}(e,n,a),i}function u(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}e.wrap=l;var d="suspendedStart",p="suspendedYield",f="executing",m="completed",h={};function y(){}function g(){}function v(){}var w={};c(w,i,(function(){return this}));var _=Object.getPrototypeOf,x=_&&_(_(I([])));x&&x!==n&&o.call(x,i)&&(w=x);var b=v.prototype=y.prototype=Object.create(w);function E(e){["next","throw","return"].forEach((function(t){c(e,t,(function(e){return this._invoke(t,e)}))}))}function k(e,t){function n(r,i,a,s){var c=u(e[r],e,i);if("throw"!==c.type){var l=c.arg,d=l.value;return d&&"object"===_typeof(d)&&o.call(d,"__await")?t.resolve(d.__await).then((function(e){n("next",e,a,s)}),(function(e){n("throw",e,a,s)})):t.resolve(d).then((function(e){l.value=e,a(l)}),(function(e){return n("throw",e,a,s)}))}s(c.arg)}var r;this._invoke=function(e,o){function i(){return new t((function(t,r){n(e,o,t,r)}))}return r=r?r.then(i,i):i()}}function L(e,n){var o=e.iterator[n.method];if(o===t){if(n.delegate=null,"throw"===n.method){if(e.iterator.return&&(n.method="return",n.arg=t,L(e,n),"throw"===n.method))return h;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return h}var r=u(o,e.iterator,n.arg);if("throw"===r.type)return n.method="throw",n.arg=r.arg,n.delegate=null,h;var i=r.arg;return i?i.done?(n[e.resultName]=i.value,n.next=e.nextLoc,"return"!==n.method&&(n.method="next",n.arg=t),n.delegate=null,h):i:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,h)}function S(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function C(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function T(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(S,this),this.reset(!0)}function I(e){if(e){var n=e[i];if(n)return n.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var r=-1,a=function n(){for(;++r<e.length;)if(o.call(e,r))return n.value=e[r],n.done=!1,n;return n.value=t,n.done=!0,n};return a.next=a}}return{next:P}}function P(){return{value:t,done:!0}}return g.prototype=v,c(b,"constructor",v),c(v,"constructor",g),g.displayName=c(v,s,"GeneratorFunction"),e.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===g||"GeneratorFunction"===(t.displayName||t.name))},e.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,v):(e.__proto__=v,c(e,s,"GeneratorFunction")),e.prototype=Object.create(b),e},e.awrap=function(e){return{__await:e}},E(k.prototype),c(k.prototype,a,(function(){return this})),e.AsyncIterator=k,e.async=function(t,n,o,r,i){void 0===i&&(i=Promise);var a=new k(l(t,n,o,r),i);return e.isGeneratorFunction(n)?a:a.next().then((function(e){return e.done?e.value:a.next()}))},E(b),c(b,s,"Generator"),c(b,i,(function(){return this})),c(b,"toString",(function(){return"[object Generator]"})),e.keys=function(e){var t=[];for(var n in e)t.push(n);return t.reverse(),function n(){for(;t.length;){var o=t.pop();if(o in e)return n.value=o,n.done=!1,n}return n.done=!0,n}},e.values=I,T.prototype={constructor:T,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=t,this.done=!1,this.delegate=null,this.method="next",this.arg=t,this.tryEntries.forEach(C),!e)for(var n in this)"t"===n.charAt(0)&&o.call(this,n)&&!isNaN(+n.slice(1))&&(this[n]=t)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var n=this;function r(o,r){return s.type="throw",s.arg=e,n.next=o,r&&(n.method="next",n.arg=t),!!r}for(var i=this.tryEntries.length-1;i>=0;--i){var a=this.tryEntries[i],s=a.completion;if("root"===a.tryLoc)return r("end");if(a.tryLoc<=this.prev){var c=o.call(a,"catchLoc"),l=o.call(a,"finallyLoc");if(c&&l){if(this.prev<a.catchLoc)return r(a.catchLoc,!0);if(this.prev<a.finallyLoc)return r(a.finallyLoc)}else if(c){if(this.prev<a.catchLoc)return r(a.catchLoc,!0)}else{if(!l)throw new Error("try statement without catch or finally");if(this.prev<a.finallyLoc)return r(a.finallyLoc)}}}},abrupt:function(e,t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev<r.finallyLoc){var i=r;break}}i&&("break"===e||"continue"===e)&&i.tryLoc<=t&&t<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=e,a.arg=t,i?(this.method="next",this.next=i.finallyLoc,h):this.complete(a)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),h},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),C(n),h}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var o=n.completion;if("throw"===o.type){var r=o.arg;C(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(e,n,o){return this.delegate={iterator:I(e),resultName:n,nextLoc:o},"next"===this.method&&(this.arg=t),h}},e}("object"===("undefined"==typeof module?"undefined":_typeof(module))?module.exports:{});try{regeneratorRuntime=runtime}catch(e){"object"===("undefined"==typeof globalThis?"undefined":_typeof(globalThis))?globalThis.regeneratorRuntime=runtime:Function("r","regeneratorRuntime = r")(runtime)}!function(){"use strict";function e(){
+/*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */
+e=function(){return t};var t={},n=Object.prototype,o=n.hasOwnProperty,r="function"==typeof Symbol?Symbol:{},i=r.iterator||"@@iterator",a=r.asyncIterator||"@@asyncIterator",s=r.toStringTag||"@@toStringTag";function c(e,t,n){return Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}),e[t]}try{c({},"")}catch(e){c=function(e,t,n){return e[t]=n}}function l(e,t,n,o){var r=t&&t.prototype instanceof p?t:p,i=Object.create(r.prototype),a=new k(o||[]);return i._invoke=function(e,t,n){var o="suspendedStart";return function(r,i){if("executing"===o)throw new Error("Generator is already running");if("completed"===o){if("throw"===r)throw i;return S()}for(n.method=r,n.arg=i;;){var a=n.delegate;if(a){var s=x(a,n);if(s){if(s===d)continue;return s}}if("next"===n.method)n.sent=n._sent=n.arg;else if("throw"===n.method){if("suspendedStart"===o)throw o="completed",n.arg;n.dispatchException(n.arg)}else"return"===n.method&&n.abrupt("return",n.arg);o="executing";var c=u(e,t,n);if("normal"===c.type){if(o=n.done?"completed":"suspendedYield",c.arg===d)continue;return{value:c.arg,done:n.done}}"throw"===c.type&&(o="completed",n.method="throw",n.arg=c.arg)}}}(e,n,a),i}function u(e,t,n){try{return{type:"normal",arg:e.call(t,n)}}catch(e){return{type:"throw",arg:e}}}t.wrap=l;var d={};function p(){}function f(){}function m(){}var h={};c(h,i,(function(){return this}));var y=Object.getPrototypeOf,g=y&&y(y(L([])));g&&g!==n&&o.call(g,i)&&(h=g);var v=m.prototype=p.prototype=Object.create(h);function w(e){["next","throw","return"].forEach((function(t){c(e,t,(function(e){return this._invoke(t,e)}))}))}function _(e,t){function n(r,i,a,s){var c=u(e[r],e,i);if("throw"!==c.type){var l=c.arg,d=l.value;return d&&"object"==_typeof(d)&&o.call(d,"__await")?t.resolve(d.__await).then((function(e){n("next",e,a,s)}),(function(e){n("throw",e,a,s)})):t.resolve(d).then((function(e){l.value=e,a(l)}),(function(e){return n("throw",e,a,s)}))}s(c.arg)}var r;this._invoke=function(e,o){function i(){return new t((function(t,r){n(e,o,t,r)}))}return r=r?r.then(i,i):i()}}function x(e,t){var n=e.iterator[t.method];if(void 0===n){if(t.delegate=null,"throw"===t.method){if(e.iterator.return&&(t.method="return",t.arg=void 0,x(e,t),"throw"===t.method))return d;t.method="throw",t.arg=new TypeError("The iterator does not provide a 'throw' method")}return d}var o=u(n,e.iterator,t.arg);if("throw"===o.type)return t.method="throw",t.arg=o.arg,t.delegate=null,d;var r=o.arg;return r?r.done?(t[e.resultName]=r.value,t.next=e.nextLoc,"return"!==t.method&&(t.method="next",t.arg=void 0),t.delegate=null,d):r:(t.method="throw",t.arg=new TypeError("iterator result is not an object"),t.delegate=null,d)}function b(e){var t={tryLoc:e[0]};1 in e&&(t.catchLoc=e[1]),2 in e&&(t.finallyLoc=e[2],t.afterLoc=e[3]),this.tryEntries.push(t)}function E(e){var t=e.completion||{};t.type="normal",delete t.arg,e.completion=t}function k(e){this.tryEntries=[{tryLoc:"root"}],e.forEach(b,this),this.reset(!0)}function L(e){if(e){var t=e[i];if(t)return t.call(e);if("function"==typeof e.next)return e;if(!isNaN(e.length)){var n=-1,r=function t(){for(;++n<e.length;)if(o.call(e,n))return t.value=e[n],t.done=!1,t;return t.value=void 0,t.done=!0,t};return r.next=r}}return{next:S}}function S(){return{value:void 0,done:!0}}return f.prototype=m,c(v,"constructor",m),c(m,"constructor",f),f.displayName=c(m,s,"GeneratorFunction"),t.isGeneratorFunction=function(e){var t="function"==typeof e&&e.constructor;return!!t&&(t===f||"GeneratorFunction"===(t.displayName||t.name))},t.mark=function(e){return Object.setPrototypeOf?Object.setPrototypeOf(e,m):(e.__proto__=m,c(e,s,"GeneratorFunction")),e.prototype=Object.create(v),e},t.awrap=function(e){return{__await:e}},w(_.prototype),c(_.prototype,a,(function(){return this})),t.AsyncIterator=_,t.async=function(e,n,o,r,i){void 0===i&&(i=Promise);var a=new _(l(e,n,o,r),i);return t.isGeneratorFunction(n)?a:a.next().then((function(e){return e.done?e.value:a.next()}))},w(v),c(v,s,"Generator"),c(v,i,(function(){return this})),c(v,"toString",(function(){return"[object Generator]"})),t.keys=function(e){var t=[];for(var n in e)t.push(n);return t.reverse(),function n(){for(;t.length;){var o=t.pop();if(o in e)return n.value=o,n.done=!1,n}return n.done=!0,n}},t.values=L,k.prototype={constructor:k,reset:function(e){if(this.prev=0,this.next=0,this.sent=this._sent=void 0,this.done=!1,this.delegate=null,this.method="next",this.arg=void 0,this.tryEntries.forEach(E),!e)for(var t in this)"t"===t.charAt(0)&&o.call(this,t)&&!isNaN(+t.slice(1))&&(this[t]=void 0)},stop:function(){this.done=!0;var e=this.tryEntries[0].completion;if("throw"===e.type)throw e.arg;return this.rval},dispatchException:function(e){if(this.done)throw e;var t=this;function n(n,o){return a.type="throw",a.arg=e,t.next=n,o&&(t.method="next",t.arg=void 0),!!o}for(var r=this.tryEntries.length-1;r>=0;--r){var i=this.tryEntries[r],a=i.completion;if("root"===i.tryLoc)return n("end");if(i.tryLoc<=this.prev){var s=o.call(i,"catchLoc"),c=o.call(i,"finallyLoc");if(s&&c){if(this.prev<i.catchLoc)return n(i.catchLoc,!0);if(this.prev<i.finallyLoc)return n(i.finallyLoc)}else if(s){if(this.prev<i.catchLoc)return n(i.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return n(i.finallyLoc)}}}},abrupt:function(e,t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc<=this.prev&&o.call(r,"finallyLoc")&&this.prev<r.finallyLoc){var i=r;break}}i&&("break"===e||"continue"===e)&&i.tryLoc<=t&&t<=i.finallyLoc&&(i=null);var a=i?i.completion:{};return a.type=e,a.arg=t,i?(this.method="next",this.next=i.finallyLoc,d):this.complete(a)},complete:function(e,t){if("throw"===e.type)throw e.arg;return"break"===e.type||"continue"===e.type?this.next=e.arg:"return"===e.type?(this.rval=this.arg=e.arg,this.method="return",this.next="end"):"normal"===e.type&&t&&(this.next=t),d},finish:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.finallyLoc===e)return this.complete(n.completion,n.afterLoc),E(n),d}},catch:function(e){for(var t=this.tryEntries.length-1;t>=0;--t){var n=this.tryEntries[t];if(n.tryLoc===e){var o=n.completion;if("throw"===o.type){var r=o.arg;E(n)}return r}}throw new Error("illegal catch attempt")},delegateYield:function(e,t,n){return this.delegate={iterator:L(e),resultName:t,nextLoc:n},"next"===this.method&&(this.arg=void 0),d}},t}function t(e,t,n,o,r,i,a){try{var s=e[i](a),c=s.value}catch(e){return void n(e)}s.done?t(c):Promise.resolve(c).then(o,r)}function n(e){return function(){var n=this,o=arguments;return new Promise((function(r,i){var a=e.apply(n,o);function s(e){t(a,r,i,s,c,"next",e)}function c(e){t(a,r,i,s,c,"throw",e)}s(void 0)}))}}function o(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=null==e?null:"undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(null==n)return;var o,r,i=[],a=!0,s=!1;try{for(n=n.call(e);!(a=(o=n.next()).done)&&(i.push(o.value),!t||i.length!==t);a=!0);}catch(e){s=!0,r=e}finally{try{a||null==n.return||n.return()}finally{if(s)throw r}}return i}(e,t)||r(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}()}function r(e,t){if(e){if("string"==typeof e)return i(e,t);var n=Object.prototype.toString.call(e).slice(8,-1);return"Object"===n&&e.constructor&&(n=e.constructor.name),"Map"===n||"Set"===n?Array.from(e):"Arguments"===n||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)?i(e,t):void 0}}function i(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,o=new Array(t);n<t;n++)o[n]=e[n];return o}var a,s,c,l,u,d,p,f,m,h,y,g,v,w,_,x,b,E,k,L,S,C,T,I;a=null,s=!1,c="",l="",u={},d=/.*?_(\d+)$/,p=!1,f="",m=!1,h=/^( {1,4}|\t)/,y="\n\"\"\"\nExecute Python code in code blocks (color previews added specifically for ColorAide).\n\nThis can be executed in either a Pyodide environment of a normal Python environment.\n3rd party libraries (that are not available directly from Pyodide) are only loaded\nwhen needed so that Pyodide will have a chance to load them if necessary. This is also\nhardcoded to work with ColorAide.\n\nThis is meant to be executed by Pyodide on preformatted HTML to allow for live execution of\ncode snippets using `coloraide`.\n\nTransform Python code by executing it, transforming to a Python console output,\nand finding and outputting color previews.\n\"\"\"\nimport xml.etree.ElementTree as Etree\nfrom collections.abc import Sequence\nfrom collections import namedtuple\nimport ast\nfrom io import StringIO\nimport contextlib\nimport sys\nimport re\n\nWEBSPACE = \"srgb\"\nAST_BLOCKS = (ast.If, ast.For, ast.While, ast.Try, ast.With, ast.FunctionDef, ast.ClassDef)\n\nRE_COLOR_START = re.compile(\n    r\"(?i)(?:\\b(?<![-#&$])(?:color|hsla?|lch|lab|hwb|rgba?)\\(|\\b(?<![-#&$])[\\w]{3,}(?![(-])\\b|(?<![&])#)\"\n)\n\ntemplate = '''<div class=\"playground\" id=\"__playground_{el_id}\">\n<div class=\"playground-results\" id=\"__playground-results_{el_id}\">\n{results}\n</div>\n<div class=\"playground-code hidden\" id=\"__playground-code_{el_id}\">\n<form autocomplete=\"off\">\n<textarea class=\"playground-inputs\" id=\"__playground-inputs_{el_id}\" spellcheck=\"false\">{raw_source}</textarea>\n</form>\n</div>\n\n<button id=\"__playground-edit_{el_id}\" class=\"playground-edit\" title=\"Edit the current snippet\">Edit</button>\n<button id=\"__playground-share_{el_id}\" class=\"playground-share\" title=\"Copy URL to current snippet\">Share</button>\n<button id=\"__playground-run_{el_id}\" class=\"playground-run hidden\" title=\"Run code (Ctrl + Enter)\">Run</button>\n<button id=\"__playground-cancel_{el_id}\" class=\"playground-cancel hidden\" title=\"Cancel edit (Escape)\">Cancel</button>\n</div>'''\n\ncode_id = 0\n\n\nclass HtmlGradient(list):\n    \"\"\"HTML color gradient.\"\"\"\n\n\nclass HtmlSteps(list):\n    \"\"\"HTML color steps.\"\"\"\n\n\nclass ColorTuple(namedtuple('ColorTuple', ['string', 'color'])):\n    \"\"\"Color tuple.\"\"\"\n\n\nclass HtmlRow(list):\n    \"\"\"Create a row with the given colors.\"\"\"\n\n\ndef _escape(txt):\n    \"\"\"Basic HTML escaping.\"\"\"\n\n    txt = txt.replace('&', '&amp;')\n    txt = txt.replace('<', '&lt;')\n    txt = txt.replace('>', '&gt;')\n    return txt\n\n\n@contextlib.contextmanager\ndef std_output(stdout=None):\n    \"\"\"Capture standard out.\"\"\"\n    old = sys.stdout\n    if stdout is None:\n        stdout = StringIO()\n    sys.stdout = stdout\n    yield stdout\n    sys.stdout = old\n\n\ndef get_colors(result):\n    \"\"\"Get color from results.\"\"\"\n\n    from coloraide import Color\n    from coloraide.everything import ColorAll\n    from coloraide.interpolate import Interpolator\n    try:\n        from coloraide_extras.everything import ColorAll as Color2\n    except ImportError:\n        Color2 = ColorAll\n\n    colors = []\n    if isinstance(result, HtmlRow):\n        colors = HtmlRow(\n            [\n                ColorTuple(c.to_string(fit=False), c.clone()) if isinstance(c, Color) else ColorTuple(c, Color2(c))\n                for c in result\n            ]\n        )\n    elif isinstance(result, (HtmlSteps, HtmlGradient)):\n        t = type(result)\n        colors = t([c.clone() if isinstance(c, Color) else Color2(c) for c in result])\n    elif isinstance(result, Color):\n        colors.append(ColorTuple(result.to_string(fit=False), result.clone()))\n    elif isinstance(result, Interpolator):\n        colors = HtmlGradient(result.steps(steps=5, max_delta_e=2.3))\n    elif isinstance(result, str):\n        try:\n            colors.append(ColorTuple(result, Color2(result)))\n        except Exception:\n            pass\n    elif isinstance(result, Sequence):\n        for x in result:\n            if isinstance(x, Color):\n                colors.append(ColorTuple(x.to_string(fit=False), x.clone()))\n            elif isinstance(x, str):\n                try:\n                    colors.append(ColorTuple(x, Color2(x)))\n                except Exception:\n                    pass\n    return colors\n\n\ndef find_colors(text):\n    \"\"\"Find colors in text buffer.\"\"\"\n\n    try:\n        from coloraide_extras.everything import ColorAll as Color\n    except ImportError:\n        from coloraide.everything import ColorAll as Color\n\n    colors = []\n    for m in RE_COLOR_START.finditer(text):\n        start = m.start()\n        mcolor = Color.match(text, start=start)\n        if mcolor is not None:\n            colors.append(ColorTuple(text[mcolor.start:mcolor.end], mcolor.color))\n    return colors\n\n\ndef execute(cmd, no_except=True, inline=False):\n    \"\"\"Execute color commands.\"\"\"\n\n    import coloraide\n    import coloraide.everything as everything\n    try:\n        import coloraide_extras\n        import coloraide_extras.everything as extras\n    except ImportError:\n        coloraide_extras = None\n        extras = None\n\n    g = {k: getattr(coloraide, k) for k in coloraide.__all__}\n    g['coloraide'] = coloraide\n    g['Color'] = everything.ColorAll\n    g['HtmlRow'] = HtmlRow\n    g['HtmlSteps'] = HtmlSteps\n    g['HtmlGradient'] = HtmlGradient\n\n    if extras is not None:\n        g['Color'] = extras.ColorAll\n        g['coloraide_extras'] = coloraide_extras\n\n    console = ''\n    colors = []\n\n    # Build AST tree\n    src = cmd.strip()\n    lines = src.split('\\n')\n    try:\n        tree = ast.parse(src)\n    except Exception as e:\n        if no_except:\n            if not inline:\n                from pymdownx.superfences import SuperFencesException\n                raise SuperFencesException from e\n            else:\n                from pymdownx.inlinehilite import InlineHiliteException\n                raise InlineHiliteException from e\n        import traceback\n        return '{}'.format(traceback.format_exc()), colors\n\n    for node in tree.body:\n        result = None\n\n        # Format source as Python console statements\n        start = node.lineno\n        end = node.end_lineno\n        stmt = lines[start - 1: end]\n        command = ''\n        for i, line in enumerate(stmt, 0):\n            if i == 0:\n                stmt[i] = '>>> ' + line\n            else:\n                stmt[i] = '... ' + line\n        command += '\\n'.join(stmt)\n        if isinstance(node, AST_BLOCKS):\n            command += '\\n... '\n\n        try:\n            # Capture anything sent to standard out\n            text = ''\n            with std_output() as s:\n                # Execute code\n                if isinstance(node, ast.Expr):\n                    _eval = ast.Expression(node.value)\n                    result = eval(compile(_eval, '<string>', 'eval'), g)\n                else:\n                    _exec = ast.Module([node], [])\n                    exec(compile(_exec, '<string>', 'exec'), g)\n\n                # Execution went well, so append command\n                console += command\n\n                # Output captured standard out after statements\n                text = s.getvalue()\n                if text:\n                    clist = find_colors(text)\n                    if clist:\n                        colors.append(clist)\n                    console += '\\n{}'.format(text)\n                s.flush()\n        except Exception as e:\n            if no_except:\n                if not inline:\n                    from pymdownx.superfences import SuperFencesException\n                    raise SuperFencesException from e\n                else:\n                    from pymdownx.inlinehilite import InlineHiliteException\n                    raise InlineHiliteException from e\n            import traceback\n            console += '{}\\n{}'.format(command, traceback.format_exc())\n            # Failed for some reason, so quit\n            break\n\n        # If we got a result, output it as well\n        if result is not None:\n            clist = get_colors(result)\n            if clist:\n                colors.append(clist)\n            console += '{}{}\\n'.format('\\n' if not text else '', str(result))\n        else:\n            console += '\\n' if not text else ''\n\n    return console, colors\n\n\ndef colorize(src, lang, **options):\n    \"\"\"Colorize.\"\"\"\n\n    from pygments import highlight\n    from pygments.lexers import get_lexer_by_name\n    from pygments.formatters import find_formatter_class\n    HtmlFormatter = find_formatter_class('html')\n\n    lexer = get_lexer_by_name(lang, **options)\n    formatter = HtmlFormatter(cssclass=\"highlight\", wrapcode=True)\n    return highlight(src, lexer, formatter).strip()\n\n\ndef color_command_validator(language, inputs, options, attrs, md):\n    \"\"\"Color validator.\"\"\"\n\n    valid_inputs = set(['exceptions'])\n\n    for k, v in inputs.items():\n        if k in valid_inputs:\n            options[k] = True\n            continue\n        attrs[k] = v\n    return True\n\n\ndef _color_command_console(colors):\n    \"\"\"Color command formatter.\"\"\"\n\n    el = ''\n    bar = False\n    values = []\n    for item in colors:\n        if isinstance(item, (HtmlGradient, HtmlSteps)):\n            current = total = percent = last = 0\n            if isinstance(item, HtmlSteps):\n                total = len(item)\n                percent = 100 / total\n                current = percent\n\n            if bar:\n                el += '<div class=\"swatch-bar\">{}</div>'.format(' '.join(values))\n                values = []\n            sub_el1 = '<div class=\"swatch-bar\"><span class=\"swatch swatch-gradient\">{}</span></div>'\n            style = \"--swatch-stops: \"\n            stops = []\n            for e, color in enumerate(item):\n                color.fit(WEBSPACE)\n                if current:\n                    stops.append('{} {}%'.format(color.convert(WEBSPACE).to_string(), str(last)))\n                    stops.append('{} {}%'.format(color.convert(WEBSPACE).to_string(), str(current)))\n                    last = current\n                    if e < (total - 1):\n                        current += percent\n                    else:\n                        current = 100\n                else:\n                    stops.append(color.convert(WEBSPACE).to_string())\n            if not stops:\n                stops.extend(['transparent'] * 2)\n            if len(stops) == 1:\n                stops.append(stops[0])\n            style += ','.join(stops)\n            sub_el2 = '<span class=\"swatch-color\" style=\"{}\"></span>'.format(style)\n            el += sub_el1.format(sub_el2)\n            bar = False\n        else:\n            is_row = False\n            if isinstance(item, HtmlRow):\n                is_row = True\n                if bar and values:\n                    el += '<div class=\"swatch-bar\">{}</div>'.format(' '.join(values))\n                    values = []\n                bar = False\n\n            bar = True\n            base_classes = \"swatch\"\n            for color in item:\n                if not color.color.in_gamut(WEBSPACE):\n                    base_classes += \" out-of-gamut\"\n                color.color.fit(WEBSPACE)\n                srgb = color.color.convert(WEBSPACE)\n                value1 = srgb.to_string(alpha=False)\n                value2 = srgb.to_string()\n                style = \"--swatch-stops: {} 50%, {} 50%\".format(value1, value2)\n                title = color.string\n                classes = base_classes\n                c = '<span class=\"swatch-color\" style=\"{style}\"></span>'.format(style=style)\n                c = '<span class=\"{classes}\" title=\"{title}&#013;Copy to clipboard\">{color}</span>'.format(\n                    classes=classes,\n                    color=c,\n                    title=title\n                )\n                values.append(c)\n\n            if is_row and values:\n                el += '<div class=\"swatch-bar\">{}</div>'.format(' '.join(values))\n                values = []\n                bar = False\n    if bar:\n        el += '<div class=\"swatch-bar\">{}</div>'.format(' '.join(values))\n        values = []\n\n    return el\n\n\ndef color_command_formatter(src=\"\", language=\"\", class_name=None, options=None, md=\"\", **kwargs):\n    \"\"\"Formatter wrapper.\"\"\"\n\n    global code_id\n    from pymdownx.superfences import SuperFencesException\n\n    try:\n        if len(md.preprocessors['fenced_code_block'].extension.stash) == 0:\n            code_id = 0\n\n        # Check if we should allow exceptions\n        exceptions = options.get('exceptions', False) if options is not None else False\n\n        console, colors = execute(src.strip(), not exceptions)\n        el = _color_command_console(colors)\n\n        el += md.preprocessors['fenced_code_block'].extension.superfences[0]['formatter'](\n            src=console,\n            class_name=\"highlight\",\n            language='pycon',\n            md=md,\n            options=options,\n            **kwargs\n        )\n        el = '<div class=\"color-command\">{}</div>'.format(el)\n        el = template.format(el_id=code_id, raw_source=_escape(src), results=el)\n        code_id += 1\n    except SuperFencesException:\n        raise\n    except Exception:\n        from pymdownx import superfences\n        import traceback\n        print(traceback.format_exc())\n        return superfences.fence_code_format(src, 'text', class_name, options, md, **kwargs)\n    return el\n\n\ndef color_formatter(src=\"\", language=\"\", class_name=None, md=\"\", exceptions=True):\n    \"\"\"Formatter wrapper.\"\"\"\n\n    from pymdownx.inlinehilite import InlineHiliteException\n    try:\n        from coloraide_extras.everything import ColorAll as Color\n    except ImportError:\n        from coloraide.everything import ColorAll as Color\n\n    try:\n        result = src.strip()\n\n        try:\n            color = Color(result.strip())\n        except Exception:\n            console, colors = execute(result, exceptions, inline=True)\n            if len(colors) != 1 or len(colors[0]) != 1:\n                if exceptions:\n                    raise InlineHiliteException('Only one color allowed')\n                else:\n                    raise ValueError('Only one color allowed')\n            color = colors[0][0].color\n            result = colors[0][0].string\n\n        el = Etree.Element('span')\n        stops = []\n        if not color.in_gamut(WEBSPACE):\n            color.fit(WEBSPACE)\n            attributes = {'class': \"swatch out-of-gamut\", \"title\": result}\n            sub_el = Etree.SubElement(el, 'span', attributes)\n            stops.append(color.convert(WEBSPACE).to_string(hex=True, alpha=False))\n            if color[-1] < 1.0:\n                stops[-1] += ' 50%'\n                stops.append(color.convert(WEBSPACE).to_string(hex=True) + ' 50%')\n        else:\n            attributes = {'class': \"swatch\", \"title\": result}\n            sub_el = Etree.SubElement(el, 'span', attributes)\n            stops.append(color.convert(WEBSPACE).to_string(hex=True, alpha=False))\n            if color[-1] < 1.0:\n                stops[-1] += ' 50%'\n                stops.append(color.convert(WEBSPACE).to_string(hex=True) + ' 50%')\n\n        if not stops:\n            stops.extend(['transparent'] * 2)\n        if len(stops) == 1:\n            stops.append(stops[0])\n\n        Etree.SubElement(\n            sub_el,\n            'span',\n            {\n                \"class\": \"swatch-color\",\n                \"style\": \"--swatch-stops: {};\".format(','.join(stops))\n            }\n        )\n\n        el.append(md.inlinePatterns['backtick'].handle_code('css-color', result))\n    except InlineHiliteException:\n        raise\n    except Exception:\n        import traceback\n        print(traceback.format_exc())\n        el = md.inlinePatterns['backtick'].handle_code('text', src)\n    return el\n\n\n#############################\n# Pyodide specific code\n#############################\ndef live_color_command_formatter(src):\n    \"\"\"Formatter wrapper.\"\"\"\n\n    try:\n        console, colors = execute(src.strip(), False)\n        el = _color_command_console(colors)\n\n        if not colors:\n            el += '<div class=\"swatch-bar\"></div>'\n\n        el += colorize(console, 'pycon', **{'python3': True, 'stripnl': False})\n        el = '<div class=\"color-command\">{}</div>'.format(el)\n    except Exception:\n        return '<div class=\"color-command\"><div class=\"swatch-bar\"></div>{}</div>'.format(colorize('', 'text'))\n    return el\n\n\ndef live_color_command_validator(language, inputs, options, attrs, md):\n    \"\"\"Color validator.\"\"\"\n\n    value = color_command_validator(language, inputs, options, attrs, md)\n    # Live edit, we always allow exceptions so not to crash the service.\n    options['exceptions'] = True\n    return value\n\n\ndef live_color_formatter(src=\"\", language=\"\", class_name=None, md=\"\"):\n    \"\"\"Color formatter for a live environment.\"\"\"\n\n    return color_formatter(src, language, class_name, md, exceptions=False)\n\n\ndef render_console(*args):\n    \"\"\"Render console update.\"\"\"\n\n    from js import document\n\n    try:\n        # Run code\n        inputs = document.getElementById(\"__playground-inputs_{}\".format(globals()['id_num']))\n        results = document.getElementById(\"__playground-results_{}\".format(globals()['id_num']))\n        results.innerHTML = live_color_command_formatter(inputs.value)\n        scrollingElement = results.querySelector('code')\n        scrollingElement.scrollTop = scrollingElement.scrollHeight\n    except Exception as e:\n        print(e)\n\n\ndef render_notebook(*args):\n    \"\"\"Render notebook.\"\"\"\n\n    import markdown\n    from pymdownx import slugs\n    from js import document\n\n    text = globals().get('content', '')\n    extensions = [\n        'markdown.extensions.toc',\n        'markdown.extensions.admonition',\n        'markdown.extensions.smarty',\n        'pymdownx.betterem',\n        'markdown.extensions.attr_list',\n        'markdown.extensions.def_list',\n        'markdown.extensions.tables',\n        'markdown.extensions.abbr',\n        'markdown.extensions.footnotes',\n        'markdown.extensions.md_in_html',\n        'pymdownx.superfences',\n        'pymdownx.highlight',\n        'pymdownx.inlinehilite',\n        'pymdownx.magiclink',\n        'pymdownx.tilde',\n        'pymdownx.caret',\n        'pymdownx.smartsymbols',\n        'pymdownx.emoji',\n        'pymdownx.escapeall',\n        'pymdownx.tasklist',\n        'pymdownx.striphtml',\n        'pymdownx.snippets',\n        'pymdownx.keys',\n        'pymdownx.details',\n        'pymdownx.saneheaders',\n        'pymdownx.tabbed'\n    ]\n    extension_configs = {\n        'markdown.extensions.toc': {\n            'slugify': slugs.slugify(case=\"lower\"),\n            'permalink': \"\"\n        },\n        'markdown.extensions.smarty': {\n            \"smart_quotes\": False,\n        },\n        'pymdownx.superfences': {\n            'preserve_tabs': True,\n            'custom_fences': [\n                {\n                    \"name\": 'playground',\n                    \"class\": 'playground',\n                    \"format\": color_command_formatter,\n                    \"validator\": live_color_command_validator\n                }\n            ]\n        },\n        'pymdownx.inlinehilite': {\n            'custom_inline': [\n                {\n                    'name': 'color',\n                    'class': 'color',\n                    'format': live_color_formatter\n                }\n            ]\n        },\n        'pymdownx.magiclink': {\n            'repo_url_shortener': True,\n            'repo_url_shorthand': True,\n            'social_url_shorthand': True,\n            'user': 'facelessuser',\n            'repo': 'coloraide'\n        },\n        'pymdownx.keys': {\n            'separator': \"\\uff0b\"\n        }\n    }\n\n    try:\n        html = markdown.markdown(text, extensions=extensions, extension_configs=extension_configs)\n    except Exception:\n        html = ''\n    content = document.getElementById(\"__notebook-render\")\n    content.innerHTML = html\n\n\nimport micropip\nfrom js import location\n\naction = globals().get('action')\nif action == 'notebook':\n    callback = render_notebook\nelse:\n    callback = render_console\n\nbase = location.pathname.lstrip('/').split('/')[0]\nawait micropip.install([location.origin + '/{}/playground/{}'.format(base, w) for w in wheels])\ncallback()\n",g=window.color_notebook.default_playground,v=function(e){return'\n!!! new "This notebook is powered by [Pyodide](https://github.com/pyodide/pyodide). Learn more [here](?notebook=https://gist.githubusercontent.com/facelessuser/7c819668b5eb248ecb9ac608d91391cf/raw/playground.md). Preview, convert, interpolate, and explore!"\n\n````````playground\n'.concat(e,"\n````````\n")},w=function(){m=!0,window.document.dispatchEvent(new Event("DOMContentLoaded",{bubbles:!0,cancelable:!0}))},_=function(e){var t=window.pageXOffset||(document.documentElement||document.body.parentNode||document.body).scrollLeft,n=window.pageYOffset||(document.documentElement||document.body.parentNode||document.body).scrollTop;e.style.height="5px",e.style.height="".concat(e.scrollHeight,"px"),window.scrollTo(t,n)},x=function(e){return encodeURIComponent(e).replace(/[.!'()*]/g,(function(e){return"%".concat(e.charCodeAt(0).toString(16))}))},b=function(){var t=n(e().mark((function t(n){var o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return(o=document.getElementById("__playground-inputs_".concat(n))).setAttribute("readonly",""),a.globals.set("id_num",n),a.globals.set("action","playground"),a.globals.set("wheels",window.color_notebook.playground_wheels),e.next=7,a.runPythonAsync(y);case 7:o.removeAttribute("readonly");case 8:case"end":return e.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}(),E=function(){var t=n(e().mark((function t(n){var o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return a.globals.set("content",n),a.globals.set("action","notebook"),a.globals.set("wheels",window.color_notebook.notebook_wheels),e.next=5,a.runPythonAsync(y);case 5:(o=document.getElementById("__notebook-input"))&&(c=n,o.value=n),window.location.hash&&(window.location.href=window.location.href);case 8:case"end":return e.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}(),k=function(){var t=n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(p){e.next=7;break}return p=!0,e.next=4,loadPyodide({indexURL:"https://cdn.jsdelivr.net/pyodide/v0.20.0/full/",fullStdLib:!1});case 4:return a=e.sent,e.next=7,a.loadPackage(["micropip"]);case 7:case"end":return e.stop()}}),t)})));return function(){return t.apply(this,arguments)}}(),L=function(e,t,n){var o=null==t?"Loading...":t,r=n?"loading relative":"loading",i=document.createElement("template");i.innerHTML='<div class="'.concat(r,'"><div class="loader"></div><div>').concat(o,"</div></div>"),e.appendChild(i.content.firstChild)},S=function(e){e.querySelector(".loading")&&e.removeChild(e.querySelector(".loading"))},C=function(e){if("Tab"===e.key){var t=e.target;if(t.selectionStart!==t.selectionEnd){e.preventDefault();for(var n=t.selectionStart,o=t.selectionEnd,r=t.value;n>0&&"\n"!==r[n-1];)n--;for(;o>0&&"\n"!==r[o-1]&&o<r.length;)o++;for(var i=r.substr(n,o-n).split("\n"),a=0;a<i.length;a++)a===i.length-1&&0===i[a].length||(e.shiftKey?i[a]=i[a].replace(h,""):i[a]="    ".concat(i[a]));i=i.join("\n"),t.value=r.substr(0,n)+i+r.substr(o),t.selectionStart=n,t.selectionEnd=n+i.length}}},T=function(){var t=n(e().mark((function t(o){var r;return e().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:r=document.getElementById("__notebook-source"),document.querySelectorAll(".playground").forEach((function(t){var i=t.id.replace(d,"$1"),a=document.getElementById("__playground-inputs_".concat(i)),p=document.getElementById("__playground-results_".concat(i)),f=document.getElementById("__playground-code_".concat(i)),m=document.querySelector("button#__playground-edit_".concat(i)),h=document.querySelector("button#__playground-share_".concat(i)),y=document.querySelector("button#__playground-run_".concat(i)),g=document.querySelector("button#__playground-cancel_".concat(i));if(a.addEventListener("input",(function(){_(a)})),a.addEventListener("keydown",C),r&&o){var v=document.getElementById("__notebook-input");v.addEventListener("input",(function(e){_(e.target)})),v.addEventListener("keydown",C),document.getElementById("__notebook-edit").addEventListener("click",(function(){u[v.id]=v.value,document.getElementById("__notebook-render").classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden"),_(document.getElementById("__notebook-input"))})),document.getElementById("__notebook-md-gist").addEventListener("click",function(){var t=n(e().mark((function t(n){var o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:null!==(o=prompt("Please enter link to the Markdown page source:",l))&&(o=x(o),n.preventDefault(),history.pushState({notebook:o},"","?".concat(new URLSearchParams("notebook=".concat(o)).toString())),I(!1));case 2:case"end":return e.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}()),document.getElementById("__notebook-py-gist").addEventListener("click",function(){var t=n(e().mark((function t(n){var o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:null!==(o=prompt("Please enter the link to the Python code source:",l))&&(o=x(o),n.preventDefault(),history.pushState({source:o},"","?".concat(new URLSearchParams("source=".concat(o)).toString())),I(!1));case 2:case"end":return e.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}()),document.getElementById("__notebook-input").value=c,document.getElementById("__notebook-cancel").addEventListener("click",(function(){v.value=u[v.id],delete u[v.id],document.getElementById("__notebook-render").classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden")})),document.getElementById("__notebook-submit").addEventListener("click",n(e().mark((function t(){var n,o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return n=document.getElementById("__notebook-render"),c=document.getElementById("__notebook-input").value,n.classList.toggle("hidden"),document.getElementById("__notebook-source").classList.toggle("hidden"),o=document.querySelector("article"),L(o,"Loading Notebook..."),n.innerHTML="",u={},e.next=10,k();case 10:return e.next=12,E(c);case 12:return e.next=14,T();case 14:S(o);case 15:case"end":return e.stop()}}),t)}))))}a.addEventListener("touchmove",(function(e){e.stopPropagation()})),p.addEventListener("click",(function(e){var t=e.target;if(t.matches("span.swatch-color")){var n="",o=t.parentNode;if(!o.matches("span.swatch-gradient")){if(n=(n=o.getAttribute("title").replace("Copy to clipboard","")).replace("\n",""),window.clipboardData&&window.clipboardData.setData)return window.clipboardData.setData("Text",n);if(document.queryCommandSupported&&document.queryCommandSupported("copy")){var r=document.createElement("textarea");r.textContent=n,r.style.position="fixed",document.body.appendChild(r),r.select();try{return document.execCommand("copy")}catch(e){return prompt("Copy to clipboard: Ctrl+C, Enter",n)}finally{document.body.removeChild(r)}}}}})),m.addEventListener("click",n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:u[i]=a.value,f.classList.toggle("hidden"),p.classList.toggle("hidden"),y.classList.toggle("hidden"),g.classList.toggle("hidden"),m.classList.toggle("hidden"),h.classList.toggle("hidden"),_(a),a.focus();case 9:case"end":return e.stop()}}),t)})))),h.addEventListener("click",n(e().mark((function t(){var o,r,i,s,c;return e().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:o=window.location.pathname.split("/")[1],r=x(a.value),i=window.location,s="/playground/",i.pathname.startsWith("/".concat(o,"/"))&&(s="/".concat(o,"/playground/")),c="".concat(i.protocol,"//").concat(i.host).concat(s,"?code=").concat(r),r.length>1e3?alert("Code must be under a 1000 characters to generate a URL!"):navigator.clipboard.writeText(c).then(n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:alert("Link copied to clipboard :)");case 1:case"end":return e.stop()}}),t)}))),n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:alert("Failed to copy link clipboard!");case 1:case"end":return e.stop()}}),t)}))));case 7:case"end":return t.stop()}}),t)})))),y.addEventListener("click",n(e().mark((function t(){var n,o;return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:if(!s){e.next=2;break}return e.abrupt("return");case 2:return s=!0,n=f.querySelector("form"),L(n,null,!0),(o=document.querySelectorAll(".playground .playground-run"))&&o.forEach((function(e){e.setAttribute("disabled","")})),e.next=9,k();case 9:return p.querySelector("code").innerHTML="",e.next=12,b(i);case 12:o&&o.forEach((function(e){e.removeAttribute("disabled")})),S(n),f.classList.toggle("hidden"),p.classList.toggle("hidden"),m.classList.toggle("hidden"),h.classList.toggle("hidden"),y.classList.toggle("hidden"),g.classList.toggle("hidden"),delete u[i],s=!1;case 22:case"end":return e.stop()}}),t)})))),g.addEventListener("click",(function(){a.value=u[i],delete u[i],f.classList.toggle("hidden"),p.classList.toggle("hidden"),m.classList.toggle("hidden"),h.classList.toggle("hidden"),y.classList.toggle("hidden"),g.classList.toggle("hidden")}))}));case 3:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}(),I=function(){var t=n(e().mark((function t(o){var r,i,a,s,c,d,p,m,h;return e().wrap((function(t){for(;;)switch(t.prev=t.next){case 0:if(u={},!window.location.pathname.endsWith("/playground/")){t.next=32;break}if(r=new URLSearchParams(window.location.search),i="Loading Pyodide...",a="Loading Notebook...",s=r.has("source")?r.get("source"):r.get("notebook"),c=document.querySelector("article"),null===s||!s.trim()){t.next=16;break}return L(c,i),t.next=11,k();case 11:S(c),L(c,a);try{d=r.has("source")?"source":"notebook",f=decodeURIComponent(r.toString()),p="",m=new XMLHttpRequest,l=s,m.open("GET",s,!0),m.onload=n(e().mark((function t(){return e().wrap((function(e){for(;;)switch(e.prev=e.next){case 0:return 4===m.readyState&&200===m.status&&(p=m.responseText),"source"===d&&(p=v(p)),e.next=4,E(p);case 4:return e.next=6,T(o);case 6:S(c),w();case 8:case"end":return e.stop()}}),t)}))),m.send()}catch(e){}t.next=30;break;case 16:return l="",h=v(r.has("code")?r.get("code"):g),f=decodeURIComponent(r.toString()),L(c,i),t.next=22,k();case 22:return S(c),L(c,a),t.next=26,E(h);case 26:return t.next=28,T(o);case 28:S(c),w();case 30:t.next=35;break;case 32:l="",f="",T(o);case 35:case"end":return t.stop()}}),t)})));return function(e){return t.apply(this,arguments)}}(),document.addEventListener("click",(function(e){var t=window.location.pathname.split("/")[1],n=e.target||e.srcElement;if("A"===n.tagName&&I&&n.getAttribute("href")&&n.host===window.location.host&&window.location.pathname==="/".concat(t,'/playground/"')&&window.location.pathname===n.pathname&&window.location.search!==n.search){e.preventDefault();var i,a={},s=function(e,t){var n="undefined"!=typeof Symbol&&e[Symbol.iterator]||e["@@iterator"];if(!n){if(Array.isArray(e)||(n=r(e))||t&&e&&"number"==typeof e.length){n&&(e=n);var o=0,i=function(){};return{s:i,n:function(){return o>=e.length?{done:!0}:{done:!1,value:e[o++]}},e:function(e){throw e},f:i}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var a,s=!0,c=!1;return{s:function(){n=n.call(e)},n:function(){var e=n.next();return s=e.done,e},e:function(e){c=!0,a=e},f:function(){try{s||null==n.return||n.return()}finally{if(c)throw a}}}}(new URLSearchParams(n.search));try{for(s.s();!(i=s.n()).done;){var c=o(i.value,2),l=c[0],u=c[1];a[l]=u}}catch(e){s.e(e)}finally{s.f()}history.pushState(a,"",n.href),I(!1)}})),window.addEventListener("popstate",(function(){var e=window.location.pathname.split("/")[1];window.location.pathname==="/".concat(e,"/playground/")&&decodeURIComponent(new URLSearchParams(window.location.search).toString())!==f&&I(!1)})),window.addEventListener("unload",(function(){m=!0})),window.document$.subscribe((function(){m?m=!1:I(!0)}))}();
+//# sourceMappingURL=extra-notebook-ced27dd8.js.map
diff --git a/docs/theme/assets/coloraide-extras/extra-notebook-a4927f29.js.map b/docs/theme/assets/coloraide-extras/extra-notebook-ced27dd8.js.map
similarity index 99%
rename from docs/theme/assets/coloraide-extras/extra-notebook-a4927f29.js.map
rename to docs/theme/assets/coloraide-extras/extra-notebook-ced27dd8.js.map
index 417f1101e..0b35fecae 100644
--- a/docs/theme/assets/coloraide-extras/extra-notebook-a4927f29.js.map
+++ b/docs/theme/assets/coloraide-extras/extra-notebook-ced27dd8.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"extra-notebook-a4927f29.js","sources":["../../../src/js/extra-notebook.js"],"sourcesContent":["(() => {\n  let pyodide = null\n  let busy = false\n  let raw = \"\"\n  let gist = \"\"\n  let editTemp = {}\n  const reIdNum = /.*?_(\\d+)$/\n  let initialized = false\n  let lastSearch = \"\"\n  let fake = false\n  const tabStart = /^( {1,4}|\\t)/\n  // This is the Python payload that will be executed when the user\n  // presses the `Run` button. It will execute the code, create a\n  // Python console output, find color references, steps, and interpolation\n  // references and render the appropriate preview.\n  const pycode = `\n{{pycode}}\n\nimport micropip\nfrom js import location\n\naction = globals().get('action')\nif action == 'notebook':\n    callback = render_notebook\nelse:\n    callback = render_console\n\nbase = location.pathname.lstrip('/').split('/')[0]\nawait micropip.install([location.origin + '/{}/playground/{}'.format(base, w) for w in wheels])\ncallback()\n`\n\n  const defContent = window.color_notebook.default_playground\n\n  const getContent = content => {\n    return `\n!!! new \"This notebook is powered by [Pyodide](https://github.com/pyodide/pyodide). \\\nLearn more [here](\\\n?notebook=https://gist.githubusercontent.com/facelessuser/7c819668b5eb248ecb9ac608d91391cf/raw/playground.md\\\n). Preview, convert, interpolate, and explore!\"\n\n\\`\\`\\`\\`\\`\\`\\`\\`playground\n${content}\n\\`\\`\\`\\`\\`\\`\\`\\`\n`\n  }\n\n  const fakeDOMContentLoaded = () => {\n    // Send a fake `DOMContentLoaded`\n    fake = true\n    window.document.dispatchEvent(new Event(\"DOMContentLoaded\", {\n      bubbles: true,\n      cancelable: true\n    }))\n  }\n\n  const textResize = inpt => {\n    // Resize inputs based on text height.\n\n    const scrollLeft = window.pageXOffset ||\n      (document.documentElement || document.body.parentNode || document.body).scrollLeft\n\n    const scrollTop  = window.pageYOffset ||\n      (document.documentElement || document.body.parentNode || document.body).scrollTop\n\n    inpt.style.height = \"5px\"\n    inpt.style.height = `${inpt.scrollHeight}px`\n\n    window.scrollTo(scrollLeft, scrollTop)\n  }\n\n  const encodeuri = uri => {\n    // Encode the URI component.\n\n    return encodeURIComponent(uri).replace(/[.!'()*]/g, c => {\n      return `%${c.charCodeAt(0).toString(16)}`\n    })\n  }\n\n  const pyexecute = async currentID => {\n    // Execute Python code inside a playground\n\n    const currentInputs = document.getElementById(`__playground-inputs_${currentID}`)\n    currentInputs.setAttribute(\"readonly\", \"\")\n    pyodide.globals.set(\"id_num\", currentID)\n    pyodide.globals.set(\"action\", \"playground\")\n    pyodide.globals.set('wheels', window.color_notebook.playground_wheels)\n    await pyodide.runPythonAsync(pycode)\n    currentInputs.removeAttribute(\"readonly\")\n  }\n\n  const pyrender = async text => {\n    // Render an entire notebook page\n\n    pyodide.globals.set(\"content\", text)\n    pyodide.globals.set(\"action\", \"notebook\")\n    pyodide.globals.set('wheels', window.color_notebook.notebook_wheels)\n    await pyodide.runPythonAsync(pycode)\n    const src = document.getElementById(\"__notebook-input\")\n    if (src) {\n      raw = text\n      src.value = text\n    }\n    if (window.location.hash) {\n      // Force jumping to hashes\n      window.location.href = window.location.href // eslint-disable-line no-self-assign\n    }\n  }\n\n  const setupPyodide = async() => {\n    // Load `Pyodide` and the any default packages we can need and can load.\n\n    if (!initialized) {\n      initialized = true\n      pyodide = await loadPyodide({ // eslint-disable-line no-undef\n        indexURL: \"https://cdn.jsdelivr.net/pyodide/v0.20.0/full/\",\n        fullStdLib: false\n      })\n      await pyodide.loadPackage([\"micropip\"])\n    }\n  }\n\n  const showBusy = (target, label, relative) => {\n    // Show busy indicator\n\n    const loaderLabel = (typeof label === \"undefined\" || label === null) ? \"Loading...\" : label\n    const classes = relative ? \"loading relative\" : \"loading\"\n    const template = document.createElement(\"template\")\n    template.innerHTML = `<div class=\"${classes}\"><div class=\"loader\"></div><div>${loaderLabel}</div></div>`\n    target.appendChild(template.content.firstChild)\n  }\n\n  const hideBusy = target => {\n    // Hide busy indicator\n\n    const loading = target.querySelector(\".loading\")\n    if (loading) {\n      target.removeChild(target.querySelector(\".loading\"))\n    }\n  }\n\n  const popState = () => {\n    // Handle notebook history\n\n    const base = window.location.pathname.split('/')[1]\n    if (\n      window.location.pathname === `/${base}/playground/`\n    ) {\n      const current = decodeURIComponent(new URLSearchParams(window.location.search).toString())\n      if (current !== lastSearch) {\n        main(false) // eslint-disable-line no-use-before-define\n      }\n    }\n  }\n\n  const interceptClickEvent = e => {\n    // Catch links to other notebook pages and handle them\n\n    const base = window.location.pathname.split('/')[1]\n    const target = e.target || e.srcElement\n    if (target.tagName === \"A\" && main) { // eslint-disable-line no-use-before-define\n      if (\n        target.getAttribute(\"href\") &&\n        target.host === window.location.host &&\n        window.location.pathname === `/${base}/playground/\"` &&\n        window.location.pathname === target.pathname &&\n        window.location.search !== target.search\n      ) {\n        e.preventDefault()\n        const search = new URLSearchParams(target.search)\n        const state = {}\n        for (const [key, value] of search) {\n          state[key] = value\n        }\n        history.pushState(state, \"\", target.href)\n        main(false) // eslint-disable-line no-use-before-define\n      }\n    }\n  }\n\n  const handleTab = e => {\n    // Prevent tab from tabbing out.\n\n    if (e.key === 'Tab') {\n      const target = e.target\n\n      if (target.selectionStart !== target.selectionEnd) {\n        e.preventDefault()\n\n        let start = target.selectionStart\n        let end = target.selectionEnd\n\n        const text = target.value\n\n        while (start > 0 && text[start - 1] !== '\\n') {\n          start--\n        }\n        while (end > 0 && text[end - 1] !== '\\n' && end < text.length) {\n          end++\n        }\n\n        let lines = text.substr(start, end - start).split('\\n')\n\n        for (let i = 0; i < lines.length; i++) {\n\n          // Don't indent last line if cursor at start of line\n          if (i === lines.length - 1 && lines[i].length === 0) {\n            continue\n          }\n\n          // Indent or deindent\n          if (e.shiftKey) {\n            lines[i] = lines[i].replace(tabStart, '')\n          } else {\n            lines[i] = `    ${lines[i]}`\n          }\n        }\n        lines = lines.join('\\n')\n\n        // Update the text area\n        target.value = text.substr(0, start) + lines + text.substr(end)\n        target.selectionStart = start\n        target.selectionEnd = start + lines.length\n      }\n    }\n  }\n\n  const init = async first => {\n    // Setup input highlighting and events to run Python code blocks.\n\n    const notebook = document.getElementById(\"__notebook-source\")\n    const playgrounds = document.querySelectorAll(\".playground\")\n    playgrounds.forEach(pg => {\n\n      const currentID = pg.id.replace(reIdNum, \"$1\")\n      const inputs = document.getElementById(`__playground-inputs_${currentID}`)\n      const results = document.getElementById(`__playground-results_${currentID}`)\n      const pgcode = document.getElementById(`__playground-code_${currentID}`)\n      const buttonEdit = document.querySelector(`button#__playground-edit_${currentID}`)\n      const buttonShare = document.querySelector(`button#__playground-share_${currentID}`)\n      const buttonRun = document.querySelector(`button#__playground-run_${currentID}`)\n      const buttonCancel = document.querySelector(`button#__playground-cancel_${currentID}`)\n\n      inputs.addEventListener(\"input\", () => {\n        // Adjust textarea height on text input.\n\n        textResize(inputs)\n      })\n\n      inputs.addEventListener('keydown', handleTab)\n\n      if (notebook && first) {\n        const notebookInput = document.getElementById(\"__notebook-input\")\n\n        notebookInput.addEventListener(\"input\", e => {\n          // Adjust textarea height on text input.\n\n          textResize(e.target)\n        })\n\n        notebookInput.addEventListener('keydown', handleTab)\n\n        const editPage = document.getElementById(\"__notebook-edit\")\n        editPage.addEventListener(\"click\", () => {\n          editTemp[notebookInput.id] = notebookInput.value\n          document.getElementById(\"__notebook-render\").classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n          textResize(document.getElementById(\"__notebook-input\"))\n        })\n\n        document.getElementById(\"__notebook-md-gist\").addEventListener(\"click\", async e => {\n          let uri = prompt(\"Please enter link to the Markdown page source:\", gist) // eslint-disable-line no-alert\n          if (uri !== null) {\n            uri = encodeuri(uri)\n            e.preventDefault()\n            history.pushState({notebook: uri}, \"\", `?${new URLSearchParams(`notebook=${uri}`).toString()}`)\n            main(false) // eslint-disable-line no-use-before-define\n          }\n        })\n\n        document.getElementById(\"__notebook-py-gist\").addEventListener(\"click\", async e => {\n          let uri = prompt(\"Please enter the link to the Python code source:\", gist) // eslint-disable-line no-alert\n          if (uri !== null) {\n            uri = encodeuri(uri)\n            e.preventDefault()\n            history.pushState({source: uri}, \"\", `?${new URLSearchParams(`source=${uri}`).toString()}`)\n            main(false) // eslint-disable-line no-use-before-define\n          }\n        })\n\n        document.getElementById(\"__notebook-input\").value = raw\n        document.getElementById(\"__notebook-cancel\").addEventListener(\"click\", () => {\n          notebookInput.value = editTemp[notebookInput.id]\n          delete editTemp[notebookInput.id]\n          document.getElementById(\"__notebook-render\").classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n        })\n\n        document.getElementById(\"__notebook-submit\").addEventListener(\"click\", async() => {\n          const render = document.getElementById(\"__notebook-render\")\n          raw = document.getElementById(\"__notebook-input\").value\n          render.classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n          const article = document.querySelector(\"article\")\n          showBusy(article, \"Loading Notebook...\")\n          render.innerHTML = \"\"\n          editTemp = {}\n          await setupPyodide()\n          await pyrender(raw)\n          await init()\n          hideBusy(article)\n        })\n      }\n\n      inputs.addEventListener(\"touchmove\", e => {\n        // Stop propagation on \"touchmove\".\n\n        e.stopPropagation()\n      })\n\n      results.addEventListener(\"click\", e => {\n        // Handle clicks on results and copies color from single color swatch when clicked.\n\n        const el = e.target\n        if (el.matches('span.swatch-color')) {\n          let content = ''\n          const parent = el.parentNode\n          if (!parent.matches('span.swatch-gradient')) {\n            content = parent.getAttribute('title').replace('Copy to clipboard', '')\n            content = content.replace('\\n', '')\n            if (window.clipboardData && window.clipboardData.setData) {\n              // Old `IE`` handling, do we really need this?\n              return window.clipboardData.setData(\"Text\", content)\n            } else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n              const textarea = document.createElement(\"textarea\")\n              textarea.textContent = content\n              textarea.style.position = \"fixed\"\n              document.body.appendChild(textarea)\n              textarea.select()\n              try {\n                return document.execCommand(\"copy\")\n              } catch (ex) {\n                return prompt(\"Copy to clipboard: Ctrl+C, Enter\", content) // eslint-disable-line no-alert\n              } finally {\n                document.body.removeChild(textarea)\n              }\n            }\n          }\n        }\n      })\n\n      buttonEdit.addEventListener(\"click\", async() => {\n        // Handle the button click: show source or execute source.\n\n        editTemp[currentID] = inputs.value\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        textResize(inputs)\n        inputs.focus()\n      })\n\n      buttonShare.addEventListener(\"click\", async() => {\n        // Handle the share click: copy URL with code as parameter.\n\n        const base = window.location.pathname.split('/')[1]\n        const uri = encodeuri(inputs.value)\n        const loc = window.location\n        let pathname = \"/playground/\"\n        if (loc.pathname.startsWith(`/${base}/`)) {\n          pathname = `/${base}/playground/`\n        }\n        const path = `${loc.protocol}//${loc.host}${pathname}?code=${uri}`\n        if (uri.length > 1000) {\n          alert(\"Code must be under a 1000 characters to generate a URL!\") // eslint-disable-line no-alert\n        } else {\n          navigator.clipboard.writeText(path).then(async() => {\n            alert(\"Link copied to clipboard :)\") // eslint-disable-line no-alert\n          }, async() => {\n            alert(\"Failed to copy link clipboard!\") // eslint-disable-line no-alert\n          })\n        }\n      })\n\n      buttonRun.addEventListener(\"click\", async() => {\n        // Handle the button click: show source or execute source.\n\n        if (busy) {\n          return\n        }\n\n        busy = true\n        // Load Pyodide and related packages.\n        const form = pgcode.querySelector(\"form\")\n        showBusy(form, null, true)\n        const buttons = document.querySelectorAll(\".playground .playground-run\")\n        if (buttons) {\n          buttons.forEach(b => {\n            b.setAttribute(\"disabled\", \"\")\n          })\n        }\n        await setupPyodide()\n        results.querySelector(\"code\").innerHTML = \"\"\n        await pyexecute(currentID)\n        if (buttons) {\n          buttons.forEach(b => {\n            b.removeAttribute(\"disabled\")\n          })\n        }\n        hideBusy(form)\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n\n        delete editTemp[currentID]\n        busy = false\n      })\n\n      buttonCancel.addEventListener(\"click\", () => {\n        // Cancel edit.\n\n        inputs.value = editTemp[currentID]\n        delete editTemp[currentID]\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n      })\n    })\n  }\n\n  const main = async first => {\n    // Load external source to render in a playground.\n    // This can be something like a file on a gist we must read in (?source=)\n    // or raw code (?code=).\n\n    editTemp = {}\n\n    if (window.location.pathname.endsWith(\"/playground/\")) {\n      const params = new URLSearchParams(window.location.search)\n      const loadMsg = \"Loading Pyodide...\"\n      const pageMsg = \"Loading Notebook...\"\n      const uri = params.has(\"source\") ? params.get(\"source\") : params.get(\"notebook\")\n      const article = document.querySelector(\"article\")\n      if (uri !== null && uri.trim()) {\n        // A source was specified, so load it.\n        showBusy(article, loadMsg)\n        await setupPyodide()\n        hideBusy(article)\n        showBusy(article, pageMsg)\n        try {\n          const gistType = params.has(\"source\") ? \"source\" : \"notebook\"\n          lastSearch = decodeURIComponent(params.toString())\n          let value = \"\"\n          const xhr = new XMLHttpRequest()\n          gist = uri\n          xhr.open(\"GET\", uri, true)\n          xhr.onload = async() => {\n            // Try and load the requested content\n            if (xhr.readyState === 4) {\n              if (xhr.status === 200) {\n                value = xhr.responseText\n              }\n            }\n\n            if (gistType === \"source\") {\n              value = getContent(value)\n            }\n            await pyrender(value)\n            await init(first)\n            hideBusy(article)\n            fakeDOMContentLoaded()\n          }\n          xhr.send()\n        } catch (err) {} // eslint-disable-line no-empty\n      } else {\n        gist = \"\"\n        const content = getContent(params.has(\"code\") ? params.get(\"code\") : defContent)\n        lastSearch = decodeURIComponent(params.toString())\n        showBusy(article, loadMsg)\n        await setupPyodide()\n        hideBusy(article)\n        showBusy(article, pageMsg)\n        await pyrender(content)\n        await init(first)\n        hideBusy(article)\n        fakeDOMContentLoaded()\n      }\n    } else {\n      gist = \"\"\n      lastSearch = \"\"\n      init(first)\n    }\n  }\n\n  // Capture links in notebook pages so that we can make playgound links load instantly\n  document.addEventListener(\"click\", interceptClickEvent)\n\n  // Handle history of notebook pages as they are loaded dynamically\n  window.addEventListener(\"popstate\", popState)\n\n  // Before leaving, turn off fake, just in case we navigated away before finished\n  window.addEventListener(\"unload\", () => {\n    fake = true\n  })\n\n  // Attach main via subscribe (subscribes to Materials on page load and instant page loads)\n  window.document$.subscribe(() => {\n    // To get other libraries to to reload, we may create a fake `DOMContentLoaded`\n    // No need to process these events.\n    if (fake) {\n      fake = false\n      return\n    }\n    main(true)\n  })\n})()\n"],"names":["pyodide","busy","raw","gist","editTemp","reIdNum","initialized","lastSearch","fake","tabStart","pycode","defContent","getContent","fakeDOMContentLoaded","textResize","encodeuri","pyexecute","pyrender","setupPyodide","showBusy","hideBusy","handleTab","init","main","window","color_notebook","default_playground","content","concat","document","dispatchEvent","Event","bubbles","cancelable","inpt","scrollLeft","pageXOffset","documentElement","body","parentNode","scrollTop","pageYOffset","style","height","scrollHeight","scrollTo","uri","encodeURIComponent","replace","c","charCodeAt","toString","_ref","_asyncToGenerator","_regeneratorRuntime","mark","currentID","currentInputs","wrap","_context","prev","next","getElementById","setAttribute","globals","set","playground_wheels","runPythonAsync","removeAttribute","stop","_callee","_x","apply","this","arguments","_ref2","text","src","_context2","notebook_wheels","value","location","hash","href","_callee2","_x2","_ref3","_callee3","_context3","loadPyodide","indexURL","fullStdLib","sent","loadPackage","target","label","relative","loaderLabel","classes","template","createElement","innerHTML","appendChild","firstChild","querySelector","removeChild","e","key","selectionStart","selectionEnd","preventDefault","start","end","length","lines","substr","split","i","shiftKey","join","_ref4","first","notebook","_context12","querySelectorAll","forEach","pg","id","inputs","results","pgcode","buttonEdit","buttonShare","buttonRun","buttonCancel","addEventListener","notebookInput","classList","toggle","_ref5","_context4","prompt","history","pushState","URLSearchParams","_callee4","_x4","_ref6","_context5","source","_callee5","_x5","_callee6","render","article","_context6","stopPropagation","el","matches","parent","getAttribute","clipboardData","setData","queryCommandSupported","textarea","textContent","position","select","execCommand","ex","_callee7","_context7","focus","_callee10","base","loc","pathname","path","_context10","startsWith","protocol","host","alert","navigator","clipboard","writeText","then","_callee8","_context8","_callee9","_context9","_callee11","form","buttons","_context11","abrupt","b","_callee12","_x3","_ref13","params","loadMsg","pageMsg","gistType","xhr","_context14","endsWith","search","has","get","trim","decodeURIComponent","XMLHttpRequest","open","onload","_callee13","_context13","readyState","status","responseText","send","err","_callee14","_x6","srcElement","tagName","_step","state","_iterator","_createForOfIteratorHelper","s","n","done","_step$value","_slicedToArray","f","document$","subscribe"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"extra-notebook-ced27dd8.js","sources":["../../../src/js/extra-notebook.js"],"sourcesContent":["(() => {\n  let pyodide = null\n  let busy = false\n  let raw = \"\"\n  let gist = \"\"\n  let editTemp = {}\n  const reIdNum = /.*?_(\\d+)$/\n  let initialized = false\n  let lastSearch = \"\"\n  let fake = false\n  const tabStart = /^( {1,4}|\\t)/\n  // This is the Python payload that will be executed when the user\n  // presses the `Run` button. It will execute the code, create a\n  // Python console output, find color references, steps, and interpolation\n  // references and render the appropriate preview.\n  const pycode = `\n{{pycode}}\n\nimport micropip\nfrom js import location\n\naction = globals().get('action')\nif action == 'notebook':\n    callback = render_notebook\nelse:\n    callback = render_console\n\nbase = location.pathname.lstrip('/').split('/')[0]\nawait micropip.install([location.origin + '/{}/playground/{}'.format(base, w) for w in wheels])\ncallback()\n`\n\n  const defContent = window.color_notebook.default_playground\n\n  const getContent = content => {\n    return `\n!!! new \"This notebook is powered by [Pyodide](https://github.com/pyodide/pyodide). \\\nLearn more [here](\\\n?notebook=https://gist.githubusercontent.com/facelessuser/7c819668b5eb248ecb9ac608d91391cf/raw/playground.md\\\n). Preview, convert, interpolate, and explore!\"\n\n\\`\\`\\`\\`\\`\\`\\`\\`playground\n${content}\n\\`\\`\\`\\`\\`\\`\\`\\`\n`\n  }\n\n  const fakeDOMContentLoaded = () => {\n    // Send a fake `DOMContentLoaded`\n    fake = true\n    window.document.dispatchEvent(new Event(\"DOMContentLoaded\", {\n      bubbles: true,\n      cancelable: true\n    }))\n  }\n\n  const textResize = inpt => {\n    // Resize inputs based on text height.\n\n    const scrollLeft = window.pageXOffset ||\n      (document.documentElement || document.body.parentNode || document.body).scrollLeft\n\n    const scrollTop  = window.pageYOffset ||\n      (document.documentElement || document.body.parentNode || document.body).scrollTop\n\n    inpt.style.height = \"5px\"\n    inpt.style.height = `${inpt.scrollHeight}px`\n\n    window.scrollTo(scrollLeft, scrollTop)\n  }\n\n  const encodeuri = uri => {\n    // Encode the URI component.\n\n    return encodeURIComponent(uri).replace(/[.!'()*]/g, c => {\n      return `%${c.charCodeAt(0).toString(16)}`\n    })\n  }\n\n  const pyexecute = async currentID => {\n    // Execute Python code inside a playground\n\n    const currentInputs = document.getElementById(`__playground-inputs_${currentID}`)\n    currentInputs.setAttribute(\"readonly\", \"\")\n    pyodide.globals.set(\"id_num\", currentID)\n    pyodide.globals.set(\"action\", \"playground\")\n    pyodide.globals.set('wheels', window.color_notebook.playground_wheels)\n    await pyodide.runPythonAsync(pycode)\n    currentInputs.removeAttribute(\"readonly\")\n  }\n\n  const pyrender = async text => {\n    // Render an entire notebook page\n\n    pyodide.globals.set(\"content\", text)\n    pyodide.globals.set(\"action\", \"notebook\")\n    pyodide.globals.set('wheels', window.color_notebook.notebook_wheels)\n    await pyodide.runPythonAsync(pycode)\n    const src = document.getElementById(\"__notebook-input\")\n    if (src) {\n      raw = text\n      src.value = text\n    }\n    if (window.location.hash) {\n      // Force jumping to hashes\n      window.location.href = window.location.href // eslint-disable-line no-self-assign\n    }\n  }\n\n  const setupPyodide = async() => {\n    // Load `Pyodide` and the any default packages we can need and can load.\n\n    if (!initialized) {\n      initialized = true\n      pyodide = await loadPyodide({ // eslint-disable-line no-undef\n        indexURL: \"https://cdn.jsdelivr.net/pyodide/v0.20.0/full/\",\n        fullStdLib: false\n      })\n      await pyodide.loadPackage([\"micropip\"])\n    }\n  }\n\n  const showBusy = (target, label, relative) => {\n    // Show busy indicator\n\n    const loaderLabel = (typeof label === \"undefined\" || label === null) ? \"Loading...\" : label\n    const classes = relative ? \"loading relative\" : \"loading\"\n    const template = document.createElement(\"template\")\n    template.innerHTML = `<div class=\"${classes}\"><div class=\"loader\"></div><div>${loaderLabel}</div></div>`\n    target.appendChild(template.content.firstChild)\n  }\n\n  const hideBusy = target => {\n    // Hide busy indicator\n\n    const loading = target.querySelector(\".loading\")\n    if (loading) {\n      target.removeChild(target.querySelector(\".loading\"))\n    }\n  }\n\n  const popState = () => {\n    // Handle notebook history\n\n    const base = window.location.pathname.split('/')[1]\n    if (\n      window.location.pathname === `/${base}/playground/`\n    ) {\n      const current = decodeURIComponent(new URLSearchParams(window.location.search).toString())\n      if (current !== lastSearch) {\n        main(false) // eslint-disable-line no-use-before-define\n      }\n    }\n  }\n\n  const interceptClickEvent = e => {\n    // Catch links to other notebook pages and handle them\n\n    const base = window.location.pathname.split('/')[1]\n    const target = e.target || e.srcElement\n    if (target.tagName === \"A\" && main) { // eslint-disable-line no-use-before-define\n      if (\n        target.getAttribute(\"href\") &&\n        target.host === window.location.host &&\n        window.location.pathname === `/${base}/playground/\"` &&\n        window.location.pathname === target.pathname &&\n        window.location.search !== target.search\n      ) {\n        e.preventDefault()\n        const search = new URLSearchParams(target.search)\n        const state = {}\n        for (const [key, value] of search) {\n          state[key] = value\n        }\n        history.pushState(state, \"\", target.href)\n        main(false) // eslint-disable-line no-use-before-define\n      }\n    }\n  }\n\n  const handleTab = e => {\n    // Prevent tab from tabbing out.\n\n    if (e.key === 'Tab') {\n      const target = e.target\n\n      if (target.selectionStart !== target.selectionEnd) {\n        e.preventDefault()\n\n        let start = target.selectionStart\n        let end = target.selectionEnd\n\n        const text = target.value\n\n        while (start > 0 && text[start - 1] !== '\\n') {\n          start--\n        }\n        while (end > 0 && text[end - 1] !== '\\n' && end < text.length) {\n          end++\n        }\n\n        let lines = text.substr(start, end - start).split('\\n')\n\n        for (let i = 0; i < lines.length; i++) {\n\n          // Don't indent last line if cursor at start of line\n          if (i === lines.length - 1 && lines[i].length === 0) {\n            continue\n          }\n\n          // Indent or deindent\n          if (e.shiftKey) {\n            lines[i] = lines[i].replace(tabStart, '')\n          } else {\n            lines[i] = `    ${lines[i]}`\n          }\n        }\n        lines = lines.join('\\n')\n\n        // Update the text area\n        target.value = text.substr(0, start) + lines + text.substr(end)\n        target.selectionStart = start\n        target.selectionEnd = start + lines.length\n      }\n    }\n  }\n\n  const init = async first => {\n    // Setup input highlighting and events to run Python code blocks.\n\n    const notebook = document.getElementById(\"__notebook-source\")\n    const playgrounds = document.querySelectorAll(\".playground\")\n    playgrounds.forEach(pg => {\n\n      const currentID = pg.id.replace(reIdNum, \"$1\")\n      const inputs = document.getElementById(`__playground-inputs_${currentID}`)\n      const results = document.getElementById(`__playground-results_${currentID}`)\n      const pgcode = document.getElementById(`__playground-code_${currentID}`)\n      const buttonEdit = document.querySelector(`button#__playground-edit_${currentID}`)\n      const buttonShare = document.querySelector(`button#__playground-share_${currentID}`)\n      const buttonRun = document.querySelector(`button#__playground-run_${currentID}`)\n      const buttonCancel = document.querySelector(`button#__playground-cancel_${currentID}`)\n\n      inputs.addEventListener(\"input\", () => {\n        // Adjust textarea height on text input.\n\n        textResize(inputs)\n      })\n\n      inputs.addEventListener('keydown', handleTab)\n\n      if (notebook && first) {\n        const notebookInput = document.getElementById(\"__notebook-input\")\n\n        notebookInput.addEventListener(\"input\", e => {\n          // Adjust textarea height on text input.\n\n          textResize(e.target)\n        })\n\n        notebookInput.addEventListener('keydown', handleTab)\n\n        const editPage = document.getElementById(\"__notebook-edit\")\n        editPage.addEventListener(\"click\", () => {\n          editTemp[notebookInput.id] = notebookInput.value\n          document.getElementById(\"__notebook-render\").classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n          textResize(document.getElementById(\"__notebook-input\"))\n        })\n\n        document.getElementById(\"__notebook-md-gist\").addEventListener(\"click\", async e => {\n          let uri = prompt(\"Please enter link to the Markdown page source:\", gist) // eslint-disable-line no-alert\n          if (uri !== null) {\n            uri = encodeuri(uri)\n            e.preventDefault()\n            history.pushState({notebook: uri}, \"\", `?${new URLSearchParams(`notebook=${uri}`).toString()}`)\n            main(false) // eslint-disable-line no-use-before-define\n          }\n        })\n\n        document.getElementById(\"__notebook-py-gist\").addEventListener(\"click\", async e => {\n          let uri = prompt(\"Please enter the link to the Python code source:\", gist) // eslint-disable-line no-alert\n          if (uri !== null) {\n            uri = encodeuri(uri)\n            e.preventDefault()\n            history.pushState({source: uri}, \"\", `?${new URLSearchParams(`source=${uri}`).toString()}`)\n            main(false) // eslint-disable-line no-use-before-define\n          }\n        })\n\n        document.getElementById(\"__notebook-input\").value = raw\n        document.getElementById(\"__notebook-cancel\").addEventListener(\"click\", () => {\n          notebookInput.value = editTemp[notebookInput.id]\n          delete editTemp[notebookInput.id]\n          document.getElementById(\"__notebook-render\").classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n        })\n\n        document.getElementById(\"__notebook-submit\").addEventListener(\"click\", async() => {\n          const render = document.getElementById(\"__notebook-render\")\n          raw = document.getElementById(\"__notebook-input\").value\n          render.classList.toggle(\"hidden\")\n          document.getElementById(\"__notebook-source\").classList.toggle(\"hidden\")\n          const article = document.querySelector(\"article\")\n          showBusy(article, \"Loading Notebook...\")\n          render.innerHTML = \"\"\n          editTemp = {}\n          await setupPyodide()\n          await pyrender(raw)\n          await init()\n          hideBusy(article)\n        })\n      }\n\n      inputs.addEventListener(\"touchmove\", e => {\n        // Stop propagation on \"touchmove\".\n\n        e.stopPropagation()\n      })\n\n      results.addEventListener(\"click\", e => {\n        // Handle clicks on results and copies color from single color swatch when clicked.\n\n        const el = e.target\n        if (el.matches('span.swatch-color')) {\n          let content = ''\n          const parent = el.parentNode\n          if (!parent.matches('span.swatch-gradient')) {\n            content = parent.getAttribute('title').replace('Copy to clipboard', '')\n            content = content.replace('\\n', '')\n            if (window.clipboardData && window.clipboardData.setData) {\n              // Old `IE`` handling, do we really need this?\n              return window.clipboardData.setData(\"Text\", content)\n            } else if (document.queryCommandSupported && document.queryCommandSupported(\"copy\")) {\n              const textarea = document.createElement(\"textarea\")\n              textarea.textContent = content\n              textarea.style.position = \"fixed\"\n              document.body.appendChild(textarea)\n              textarea.select()\n              try {\n                return document.execCommand(\"copy\")\n              } catch (ex) {\n                return prompt(\"Copy to clipboard: Ctrl+C, Enter\", content) // eslint-disable-line no-alert\n              } finally {\n                document.body.removeChild(textarea)\n              }\n            }\n          }\n        }\n      })\n\n      buttonEdit.addEventListener(\"click\", async() => {\n        // Handle the button click: show source or execute source.\n\n        editTemp[currentID] = inputs.value\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        textResize(inputs)\n        inputs.focus()\n      })\n\n      buttonShare.addEventListener(\"click\", async() => {\n        // Handle the share click: copy URL with code as parameter.\n\n        const base = window.location.pathname.split('/')[1]\n        const uri = encodeuri(inputs.value)\n        const loc = window.location\n        let pathname = \"/playground/\"\n        if (loc.pathname.startsWith(`/${base}/`)) {\n          pathname = `/${base}/playground/`\n        }\n        const path = `${loc.protocol}//${loc.host}${pathname}?code=${uri}`\n        if (uri.length > 1000) {\n          alert(\"Code must be under a 1000 characters to generate a URL!\") // eslint-disable-line no-alert\n        } else {\n          navigator.clipboard.writeText(path).then(async() => {\n            alert(\"Link copied to clipboard :)\") // eslint-disable-line no-alert\n          }, async() => {\n            alert(\"Failed to copy link clipboard!\") // eslint-disable-line no-alert\n          })\n        }\n      })\n\n      buttonRun.addEventListener(\"click\", async() => {\n        // Handle the button click: show source or execute source.\n\n        if (busy) {\n          return\n        }\n\n        busy = true\n        // Load Pyodide and related packages.\n        const form = pgcode.querySelector(\"form\")\n        showBusy(form, null, true)\n        const buttons = document.querySelectorAll(\".playground .playground-run\")\n        if (buttons) {\n          buttons.forEach(b => {\n            b.setAttribute(\"disabled\", \"\")\n          })\n        }\n        await setupPyodide()\n        results.querySelector(\"code\").innerHTML = \"\"\n        await pyexecute(currentID)\n        if (buttons) {\n          buttons.forEach(b => {\n            b.removeAttribute(\"disabled\")\n          })\n        }\n        hideBusy(form)\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n\n        delete editTemp[currentID]\n        busy = false\n      })\n\n      buttonCancel.addEventListener(\"click\", () => {\n        // Cancel edit.\n\n        inputs.value = editTemp[currentID]\n        delete editTemp[currentID]\n        pgcode.classList.toggle(\"hidden\")\n        results.classList.toggle(\"hidden\")\n        buttonEdit.classList.toggle(\"hidden\")\n        buttonShare.classList.toggle(\"hidden\")\n        buttonRun.classList.toggle(\"hidden\")\n        buttonCancel.classList.toggle(\"hidden\")\n      })\n    })\n  }\n\n  const main = async first => {\n    // Load external source to render in a playground.\n    // This can be something like a file on a gist we must read in (?source=)\n    // or raw code (?code=).\n\n    editTemp = {}\n\n    if (window.location.pathname.endsWith(\"/playground/\")) {\n      const params = new URLSearchParams(window.location.search)\n      const loadMsg = \"Loading Pyodide...\"\n      const pageMsg = \"Loading Notebook...\"\n      const uri = params.has(\"source\") ? params.get(\"source\") : params.get(\"notebook\")\n      const article = document.querySelector(\"article\")\n      if (uri !== null && uri.trim()) {\n        // A source was specified, so load it.\n        showBusy(article, loadMsg)\n        await setupPyodide()\n        hideBusy(article)\n        showBusy(article, pageMsg)\n        try {\n          const gistType = params.has(\"source\") ? \"source\" : \"notebook\"\n          lastSearch = decodeURIComponent(params.toString())\n          let value = \"\"\n          const xhr = new XMLHttpRequest()\n          gist = uri\n          xhr.open(\"GET\", uri, true)\n          xhr.onload = async() => {\n            // Try and load the requested content\n            if (xhr.readyState === 4) {\n              if (xhr.status === 200) {\n                value = xhr.responseText\n              }\n            }\n\n            if (gistType === \"source\") {\n              value = getContent(value)\n            }\n            await pyrender(value)\n            await init(first)\n            hideBusy(article)\n            fakeDOMContentLoaded()\n          }\n          xhr.send()\n        } catch (err) {} // eslint-disable-line no-empty\n      } else {\n        gist = \"\"\n        const content = getContent(params.has(\"code\") ? params.get(\"code\") : defContent)\n        lastSearch = decodeURIComponent(params.toString())\n        showBusy(article, loadMsg)\n        await setupPyodide()\n        hideBusy(article)\n        showBusy(article, pageMsg)\n        await pyrender(content)\n        await init(first)\n        hideBusy(article)\n        fakeDOMContentLoaded()\n      }\n    } else {\n      gist = \"\"\n      lastSearch = \"\"\n      init(first)\n    }\n  }\n\n  // Capture links in notebook pages so that we can make playgound links load instantly\n  document.addEventListener(\"click\", interceptClickEvent)\n\n  // Handle history of notebook pages as they are loaded dynamically\n  window.addEventListener(\"popstate\", popState)\n\n  // Before leaving, turn off fake, just in case we navigated away before finished\n  window.addEventListener(\"unload\", () => {\n    fake = true\n  })\n\n  // Attach main via subscribe (subscribes to Materials on page load and instant page loads)\n  window.document$.subscribe(() => {\n    // To get other libraries to to reload, we may create a fake `DOMContentLoaded`\n    // No need to process these events.\n    if (fake) {\n      fake = false\n      return\n    }\n    main(true)\n  })\n})()\n"],"names":["pyodide","busy","raw","gist","editTemp","reIdNum","initialized","lastSearch","fake","tabStart","pycode","defContent","getContent","fakeDOMContentLoaded","textResize","encodeuri","pyexecute","pyrender","setupPyodide","showBusy","hideBusy","handleTab","init","main","window","color_notebook","default_playground","content","concat","document","dispatchEvent","Event","bubbles","cancelable","inpt","scrollLeft","pageXOffset","documentElement","body","parentNode","scrollTop","pageYOffset","style","height","scrollHeight","scrollTo","uri","encodeURIComponent","replace","c","charCodeAt","toString","_ref","_asyncToGenerator","_regeneratorRuntime","mark","currentID","currentInputs","wrap","_context","prev","next","getElementById","setAttribute","globals","set","playground_wheels","runPythonAsync","removeAttribute","stop","_callee","_x","apply","this","arguments","_ref2","text","src","_context2","notebook_wheels","value","location","hash","href","_callee2","_x2","_ref3","_callee3","_context3","loadPyodide","indexURL","fullStdLib","sent","loadPackage","target","label","relative","loaderLabel","classes","template","createElement","innerHTML","appendChild","firstChild","querySelector","removeChild","e","key","selectionStart","selectionEnd","preventDefault","start","end","length","lines","substr","split","i","shiftKey","join","_ref4","first","notebook","_context12","querySelectorAll","forEach","pg","id","inputs","results","pgcode","buttonEdit","buttonShare","buttonRun","buttonCancel","addEventListener","notebookInput","classList","toggle","_ref5","_context4","prompt","history","pushState","URLSearchParams","_callee4","_x4","_ref6","_context5","source","_callee5","_x5","_callee6","render","article","_context6","stopPropagation","el","matches","parent","getAttribute","clipboardData","setData","queryCommandSupported","textarea","textContent","position","select","execCommand","ex","_callee7","_context7","focus","_callee10","base","loc","pathname","path","_context10","startsWith","protocol","host","alert","navigator","clipboard","writeText","then","_callee8","_context8","_callee9","_context9","_callee11","form","buttons","_context11","abrupt","b","_callee12","_x3","_ref13","params","loadMsg","pageMsg","gistType","xhr","_context14","endsWith","search","has","get","trim","decodeURIComponent","XMLHttpRequest","open","onload","_callee13","_context13","readyState","status","responseText","send","err","_callee14","_x6","srcElement","tagName","_step","state","_iterator","_createForOfIteratorHelper","s","n","done","_step$value","_slicedToArray","f","document$","subscribe"],"mappings":"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"}
\ No newline at end of file
diff --git a/docs/theme/playground-config-4f253b91.js b/docs/theme/playground-config-4f253b91.js
new file mode 100644
index 000000000..7c1ab265c
--- /dev/null
+++ b/docs/theme/playground-config-4f253b91.js
@@ -0,0 +1,5 @@
+var color_notebook = {
+    "playground_wheels": ['Pygments-2.12.0-py3-none-any.whl', 'coloraide-1.2.dev0-py3-none-any.whl'],
+    "notebook_wheels": ['Markdown-3.3.4-py3-none-any.whl', 'pymdown_extensions-9.5-py3-none-any.whl', 'Pygments-2.12.0-py3-none-any.whl', 'coloraide-1.2.dev0-py3-none-any.whl'],
+    "default_playground": "import coloraide\ncoloraide.__version__\nColor('red')"
+}
diff --git a/mkdocs.yml b/mkdocs.yml
index 4b570a8c8..6103f75d4 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -205,9 +205,9 @@ extra_css:
   - assets/coloraide-extras/extra-753860a807.css
 extra_javascript:
   - https://unpkg.com/mermaid@8.13.3/dist/mermaid.min.js
-  - playground-config-4a739f7f.js
+  - playground-config-4f253b91.js
   - https://cdn.jsdelivr.net/pyodide/v0.20.0/full/pyodide.js
-  - assets/coloraide-extras/extra-notebook-a4927f29.js
+  - assets/coloraide-extras/extra-notebook-ced27dd8.js
 
 extra:
   social:
diff --git a/package-lock.json b/package-lock.json
index deac959fc..d2cf2d741 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9,23 +9,23 @@
       "version": "0.1.0",
       "license": "MIT",
       "devDependencies": {
-        "@babel/cli": "^7.18.9",
-        "@babel/core": "^7.18.9",
+        "@babel/cli": "^7.18.10",
+        "@babel/core": "^7.18.10",
         "@babel/eslint-parser": "^7.18.9",
         "@babel/plugin-external-helpers": "^7.18.6",
-        "@babel/preset-env": "^7.18.9",
+        "@babel/preset-env": "^7.18.10",
         "@babel/register": "^7.18.9",
-        "@fortawesome/fontawesome-free": "^6.1.1",
+        "@fortawesome/fontawesome-free": "^6.1.2",
         "@mdi/svg": "^7.0.96",
-        "@primer/octicons": "^17.3.0",
+        "@primer/octicons": "^17.4.0",
         "@rollup/plugin-babel": "^5.3.1",
         "@rollup/plugin-replace": "^4.0.0",
-        "autoprefixer": "^10.4.7",
+        "autoprefixer": "^10.4.8",
         "babel-core": "^7.0.0-bridge.0",
         "clean-css": "^5.3.1",
         "css-mqpacker": "^7.0.0",
         "del": "^7.0.0",
-        "eslint": "^8.20.0",
+        "eslint": "^8.21.0",
         "fast-glob": "^3.2.11",
         "gulp": "^4.0.2",
         "gulp-clean-css": "^4.3.0",
@@ -46,18 +46,18 @@
         "postcss-pseudo-classes": "^0.2.1",
         "postcss-svgo": "^5.1.0",
         "promise": "^8.1.0",
-        "rollup": "^2.77.0",
+        "rollup": "^2.77.3",
         "rollup-plugin-output-manifest": "^2.0.0",
         "rollup-plugin-regenerator": "^0.6.0",
         "rollup-plugin-terser": "^7.0.2",
-        "sass": "^1.54.0",
-        "stylelint": "^14.9.1",
+        "sass": "^1.54.4",
+        "stylelint": "^14.10.0",
         "stylelint-config-rational-order": "^0.1.2",
-        "stylelint-config-standard": "^26.0.0",
+        "stylelint-config-standard": "^27.0.0",
         "stylelint-order": "^5.0.0",
         "stylelint-scss": "^4.3.0",
         "terser": "^5.14.2",
-        "vinyl-paths": "^4.0.0",
+        "vinyl-paths": "^5.0.0",
         "yargs": "^17.5.1"
       },
       "engines": {
@@ -77,16 +77,16 @@
       }
     },
     "node_modules/@babel/cli": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.18.9.tgz",
-      "integrity": "sha512-e7TOtHVrAXBJGNgoROVxqx0mathd01oJGXIDekRfxdrISnRqfM795APwkDtse9GdyPYivjg3iXiko3sF3W7f5Q==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.18.10.tgz",
+      "integrity": "sha512-dLvWH+ZDFAkd2jPBSghrsFBuXrREvFwjpDycXbmUoeochqKYe4zNSLEJYErpLg8dvxvZYe79/MkN461XCwpnGw==",
       "dev": true,
       "dependencies": {
         "@jridgewell/trace-mapping": "^0.3.8",
         "commander": "^4.0.1",
         "convert-source-map": "^1.1.0",
         "fs-readdir-recursive": "^1.1.0",
-        "glob": "^7.0.0",
+        "glob": "^7.2.0",
         "make-dir": "^2.1.0",
         "slash": "^2.0.0"
       },
@@ -127,21 +127,21 @@
       }
     },
     "node_modules/@babel/core": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz",
-      "integrity": "sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz",
+      "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==",
       "dev": true,
       "dependencies": {
         "@ampproject/remapping": "^2.1.0",
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.18.9",
+        "@babel/generator": "^7.18.10",
         "@babel/helper-compilation-targets": "^7.18.9",
         "@babel/helper-module-transforms": "^7.18.9",
         "@babel/helpers": "^7.18.9",
-        "@babel/parser": "^7.18.9",
-        "@babel/template": "^7.18.6",
-        "@babel/traverse": "^7.18.9",
-        "@babel/types": "^7.18.9",
+        "@babel/parser": "^7.18.10",
+        "@babel/template": "^7.18.10",
+        "@babel/traverse": "^7.18.10",
+        "@babel/types": "^7.18.10",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
@@ -175,12 +175,12 @@
       }
     },
     "node_modules/@babel/generator": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.9.tgz",
-      "integrity": "sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==",
+      "version": "7.18.12",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.12.tgz",
+      "integrity": "sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==",
       "dev": true,
       "dependencies": {
-        "@babel/types": "^7.18.9",
+        "@babel/types": "^7.18.10",
         "@jridgewell/gen-mapping": "^0.3.2",
         "jsesc": "^2.5.1"
       },
@@ -269,15 +269,13 @@
       }
     },
     "node_modules/@babel/helper-define-polyfill-provider": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz",
-      "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==",
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz",
+      "integrity": "sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-compilation-targets": "^7.13.0",
-        "@babel/helper-module-imports": "^7.12.13",
-        "@babel/helper-plugin-utils": "^7.13.0",
-        "@babel/traverse": "^7.13.0",
+        "@babel/helper-compilation-targets": "^7.17.7",
+        "@babel/helper-plugin-utils": "^7.16.7",
         "debug": "^4.1.1",
         "lodash.debounce": "^4.0.8",
         "resolve": "^1.14.2",
@@ -398,15 +396,15 @@
       }
     },
     "node_modules/@babel/helper-remap-async-to-generator": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.6.tgz",
-      "integrity": "sha512-z5wbmV55TveUPZlCLZvxWHtrjuJd+8inFhk7DG0WW87/oJuGDcjDiu7HIvGcpf5464L6xKCg3vNkmlVVz9hwyQ==",
+      "version": "7.18.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz",
+      "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==",
       "dev": true,
       "dependencies": {
         "@babel/helper-annotate-as-pure": "^7.18.6",
-        "@babel/helper-environment-visitor": "^7.18.6",
-        "@babel/helper-wrap-function": "^7.18.6",
-        "@babel/types": "^7.18.6"
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-wrap-function": "^7.18.9",
+        "@babel/types": "^7.18.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -467,6 +465,15 @@
         "node": ">=6.9.0"
       }
     },
+    "node_modules/@babel/helper-string-parser": {
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
+      "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
+      "dev": true,
+      "engines": {
+        "node": ">=6.9.0"
+      }
+    },
     "node_modules/@babel/helper-validator-identifier": {
       "version": "7.18.6",
       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
@@ -486,15 +493,15 @@
       }
     },
     "node_modules/@babel/helper-wrap-function": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.6.tgz",
-      "integrity": "sha512-I5/LZfozwMNbwr/b1vhhuYD+J/mU+gfGAj5td7l5Rv9WYmH6i3Om69WGKNmlIpsVW/mF6O5bvTKbvDQZVgjqOw==",
+      "version": "7.18.11",
+      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.11.tgz",
+      "integrity": "sha512-oBUlbv+rjZLh2Ks9SKi4aL7eKaAXBWleHzU89mP0G6BMUlRxSckk9tSIkgDGydhgFxHuGSlBQZfnaD47oBEB7w==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-function-name": "^7.18.6",
-        "@babel/template": "^7.18.6",
-        "@babel/traverse": "^7.18.6",
-        "@babel/types": "^7.18.6"
+        "@babel/helper-function-name": "^7.18.9",
+        "@babel/template": "^7.18.10",
+        "@babel/traverse": "^7.18.11",
+        "@babel/types": "^7.18.10"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -529,9 +536,9 @@
       }
     },
     "node_modules/@babel/parser": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz",
-      "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==",
+      "version": "7.18.11",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.11.tgz",
+      "integrity": "sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==",
       "dev": true,
       "bin": {
         "parser": "bin/babel-parser.js"
@@ -588,14 +595,14 @@
       }
     },
     "node_modules/@babel/plugin-proposal-async-generator-functions": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz",
-      "integrity": "sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.10.tgz",
+      "integrity": "sha512-1mFuY2TOsR1hxbjCo4QL+qlIjV07p4H4EUYw2J/WCqsvFV6V9X9z9YhXbWndc/4fw+hYGlDT7egYxliMp5O6Ew==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-environment-visitor": "^7.18.6",
-        "@babel/helper-plugin-utils": "^7.18.6",
-        "@babel/helper-remap-async-to-generator": "^7.18.6",
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-plugin-utils": "^7.18.9",
+        "@babel/helper-remap-async-to-generator": "^7.18.9",
         "@babel/plugin-syntax-async-generators": "^7.8.4"
       },
       "engines": {
@@ -1506,12 +1513,12 @@
       }
     },
     "node_modules/@babel/plugin-transform-unicode-escapes": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz",
-      "integrity": "sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz",
+      "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-plugin-utils": "^7.18.6"
+        "@babel/helper-plugin-utils": "^7.18.9"
       },
       "engines": {
         "node": ">=6.9.0"
@@ -1537,9 +1544,9 @@
       }
     },
     "node_modules/@babel/preset-env": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.9.tgz",
-      "integrity": "sha512-75pt/q95cMIHWssYtyfjVlvI+QEZQThQbKvR9xH+F/Agtw/s4Wfc2V9Bwd/P39VtixB7oWxGdH4GteTTwYJWMg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.10.tgz",
+      "integrity": "sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA==",
       "dev": true,
       "dependencies": {
         "@babel/compat-data": "^7.18.8",
@@ -1548,7 +1555,7 @@
         "@babel/helper-validator-option": "^7.18.6",
         "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6",
         "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9",
-        "@babel/plugin-proposal-async-generator-functions": "^7.18.6",
+        "@babel/plugin-proposal-async-generator-functions": "^7.18.10",
         "@babel/plugin-proposal-class-properties": "^7.18.6",
         "@babel/plugin-proposal-class-static-block": "^7.18.6",
         "@babel/plugin-proposal-dynamic-import": "^7.18.6",
@@ -1608,13 +1615,13 @@
         "@babel/plugin-transform-sticky-regex": "^7.18.6",
         "@babel/plugin-transform-template-literals": "^7.18.9",
         "@babel/plugin-transform-typeof-symbol": "^7.18.9",
-        "@babel/plugin-transform-unicode-escapes": "^7.18.6",
+        "@babel/plugin-transform-unicode-escapes": "^7.18.10",
         "@babel/plugin-transform-unicode-regex": "^7.18.6",
         "@babel/preset-modules": "^0.1.5",
-        "@babel/types": "^7.18.9",
-        "babel-plugin-polyfill-corejs2": "^0.3.1",
-        "babel-plugin-polyfill-corejs3": "^0.5.2",
-        "babel-plugin-polyfill-regenerator": "^0.3.1",
+        "@babel/types": "^7.18.10",
+        "babel-plugin-polyfill-corejs2": "^0.3.2",
+        "babel-plugin-polyfill-corejs3": "^0.5.3",
+        "babel-plugin-polyfill-regenerator": "^0.4.0",
         "core-js-compat": "^3.22.1",
         "semver": "^6.3.0"
       },
@@ -1673,33 +1680,33 @@
       }
     },
     "node_modules/@babel/template": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz",
-      "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
+      "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.18.6",
-        "@babel/parser": "^7.18.6",
-        "@babel/types": "^7.18.6"
+        "@babel/parser": "^7.18.10",
+        "@babel/types": "^7.18.10"
       },
       "engines": {
         "node": ">=6.9.0"
       }
     },
     "node_modules/@babel/traverse": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.9.tgz",
-      "integrity": "sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==",
+      "version": "7.18.11",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.11.tgz",
+      "integrity": "sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==",
       "dev": true,
       "dependencies": {
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.18.9",
+        "@babel/generator": "^7.18.10",
         "@babel/helper-environment-visitor": "^7.18.9",
         "@babel/helper-function-name": "^7.18.9",
         "@babel/helper-hoist-variables": "^7.18.6",
         "@babel/helper-split-export-declaration": "^7.18.6",
-        "@babel/parser": "^7.18.9",
-        "@babel/types": "^7.18.9",
+        "@babel/parser": "^7.18.11",
+        "@babel/types": "^7.18.10",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
       },
@@ -1708,11 +1715,12 @@
       }
     },
     "node_modules/@babel/types": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.9.tgz",
-      "integrity": "sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz",
+      "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==",
       "dev": true,
       "dependencies": {
+        "@babel/helper-string-parser": "^7.18.10",
         "@babel/helper-validator-identifier": "^7.18.6",
         "to-fast-properties": "^2.0.0"
       },
@@ -1721,9 +1729,9 @@
       }
     },
     "node_modules/@csstools/selector-specificity": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.1.tgz",
-      "integrity": "sha512-aG20vknL4/YjQF9BSV7ts4EWm/yrjagAN7OWBNmlbEOUiu0llj4OGrFoOKK3g2vey4/p2omKCoHrWtPxSwV3HA==",
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
+      "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==",
       "dev": true,
       "engines": {
         "node": "^12 || ^14 || >=16"
@@ -1733,7 +1741,7 @@
         "url": "https://opencollective.com/csstools"
       },
       "peerDependencies": {
-        "postcss": "^8.3",
+        "postcss": "^8.2",
         "postcss-selector-parser": "^6.0.10"
       }
     },
@@ -1812,9 +1820,9 @@
       }
     },
     "node_modules/@fortawesome/fontawesome-free": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.1.tgz",
-      "integrity": "sha512-J/3yg2AIXc9wznaVqpHVX3Wa5jwKovVF0AMYSnbmcXTiL3PpRPfF58pzWucCwEiCJBp+hCNRLWClTomD8SseKg==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.2.tgz",
+      "integrity": "sha512-XwWADtfdSN73/udaFm+1mnGIj/ShDZNFMe/PRoqv3FhQ4GNI2PUN70yFTPsjq65Lw2C9i4TG5/hTbxXIXVCiqQ==",
       "dev": true,
       "hasInstallScript": true,
       "engines": {
@@ -1924,9 +1932,9 @@
       }
     },
     "node_modules/@humanwhocodes/config-array": {
-      "version": "0.9.2",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
-      "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==",
+      "version": "0.10.4",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
+      "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
       "dev": true,
       "dependencies": {
         "@humanwhocodes/object-schema": "^1.2.1",
@@ -1937,6 +1945,16 @@
         "node": ">=10.10.0"
       }
     },
+    "node_modules/@humanwhocodes/gitignore-to-minimatch": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+      "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+      "dev": true,
+      "funding": {
+        "type": "github",
+        "url": "https://github.com/sponsors/nzakas"
+      }
+    },
     "node_modules/@humanwhocodes/object-schema": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -2063,9 +2081,9 @@
       }
     },
     "node_modules/@primer/octicons": {
-      "version": "17.3.0",
-      "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.3.0.tgz",
-      "integrity": "sha512-4zPwwloYWdR6RznMafV7Fsw3n2CeDPp/+qEIQbaX/tBbPY1KmU0OAXmhRfhD5AzgB5kdV1aQ7KnQr1GeQXl9Dg==",
+      "version": "17.4.0",
+      "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.0.tgz",
+      "integrity": "sha512-fRD9A/JszKOe5mDIU+g1b8jvcPj/qzusxdxnrIrg8Db0mLHsbGc4xNMUtHbRmgFOKaF6/QBR+WnWGQxv4yTcBg==",
       "dev": true,
       "dependencies": {
         "object-assign": "^4.1.1"
@@ -2223,9 +2241,9 @@
       }
     },
     "node_modules/acorn": {
-      "version": "8.7.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "version": "8.8.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
       "dev": true,
       "bin": {
         "acorn": "bin/acorn"
@@ -2688,9 +2706,9 @@
       }
     },
     "node_modules/autoprefixer": {
-      "version": "10.4.7",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz",
-      "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==",
+      "version": "10.4.8",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz",
+      "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==",
       "dev": true,
       "funding": [
         {
@@ -2703,8 +2721,8 @@
         }
       ],
       "dependencies": {
-        "browserslist": "^4.20.3",
-        "caniuse-lite": "^1.0.30001335",
+        "browserslist": "^4.21.3",
+        "caniuse-lite": "^1.0.30001373",
         "fraction.js": "^4.2.0",
         "normalize-range": "^0.1.2",
         "picocolors": "^1.0.0",
@@ -2914,13 +2932,13 @@
       }
     },
     "node_modules/babel-plugin-polyfill-corejs2": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz",
-      "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==",
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz",
+      "integrity": "sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==",
       "dev": true,
       "dependencies": {
-        "@babel/compat-data": "^7.13.11",
-        "@babel/helper-define-polyfill-provider": "^0.3.1",
+        "@babel/compat-data": "^7.17.7",
+        "@babel/helper-define-polyfill-provider": "^0.3.2",
         "semver": "^6.1.1"
       },
       "peerDependencies": {
@@ -2928,12 +2946,12 @@
       }
     },
     "node_modules/babel-plugin-polyfill-corejs3": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz",
-      "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==",
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz",
+      "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-define-polyfill-provider": "^0.3.1",
+        "@babel/helper-define-polyfill-provider": "^0.3.2",
         "core-js-compat": "^3.21.0"
       },
       "peerDependencies": {
@@ -2941,12 +2959,12 @@
       }
     },
     "node_modules/babel-plugin-polyfill-regenerator": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz",
-      "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==",
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz",
+      "integrity": "sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw==",
       "dev": true,
       "dependencies": {
-        "@babel/helper-define-polyfill-provider": "^0.3.1"
+        "@babel/helper-define-polyfill-provider": "^0.3.2"
       },
       "peerDependencies": {
         "@babel/core": "^7.0.0-0"
@@ -3347,9 +3365,9 @@
       }
     },
     "node_modules/browserslist": {
-      "version": "4.20.3",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz",
-      "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==",
+      "version": "4.21.3",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+      "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
       "dev": true,
       "funding": [
         {
@@ -3362,11 +3380,10 @@
         }
       ],
       "dependencies": {
-        "caniuse-lite": "^1.0.30001332",
-        "electron-to-chromium": "^1.4.118",
-        "escalade": "^3.1.1",
-        "node-releases": "^2.0.3",
-        "picocolors": "^1.0.0"
+        "caniuse-lite": "^1.0.30001370",
+        "electron-to-chromium": "^1.4.202",
+        "node-releases": "^2.0.6",
+        "update-browserslist-db": "^1.0.5"
       },
       "bin": {
         "browserslist": "cli.js"
@@ -3498,9 +3515,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001335",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz",
-      "integrity": "sha512-ddP1Tgm7z2iIxu6QTtbZUv6HJxSaV/PZeSrWFZtbY4JZ69tOeNhBCl3HyRQgeNZKE5AOn1kpV7fhljigy0Ty3w==",
+      "version": "1.0.30001375",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz",
+      "integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==",
       "dev": true,
       "funding": [
         {
@@ -3911,18 +3928,6 @@
         "node": ">=6"
       }
     },
-    "node_modules/clone-regexp": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz",
-      "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==",
-      "dev": true,
-      "dependencies": {
-        "is-regexp": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/clone-stats": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
@@ -4202,12 +4207,12 @@
       }
     },
     "node_modules/core-js-compat": {
-      "version": "3.22.4",
-      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.4.tgz",
-      "integrity": "sha512-dIWcsszDezkFZrfm1cnB4f/J85gyhiCpxbgBdohWCDtSVuAaChTSpPV7ldOQf/Xds2U5xCIJZOK82G4ZPAIswA==",
+      "version": "3.24.1",
+      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.24.1.tgz",
+      "integrity": "sha512-XhdNAGeRnTpp8xbD+sR/HFDK9CbeeeqXT6TuofXh3urqEevzkWmLRgrVoykodsw8okqo2pu1BOmuCKrHx63zdw==",
       "dev": true,
       "dependencies": {
-        "browserslist": "^4.20.3",
+        "browserslist": "^4.21.3",
         "semver": "7.0.0"
       },
       "funding": {
@@ -4823,10 +4828,22 @@
         "object.defaults": "^1.1.0"
       }
     },
+    "node_modules/easy-transform-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/easy-transform-stream/-/easy-transform-stream-1.0.0.tgz",
+      "integrity": "sha512-kIEXvPNtqUQ/lrgkULIP0/l2m88Ahlk2ySZhmuLdRidXBIEPyHuDgDt04b9DvnCy+nIQDjpygVft+Op3PZFUQg==",
+      "dev": true,
+      "engines": {
+        "node": ">=14.16"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/electron-to-chromium": {
-      "version": "1.4.130",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.130.tgz",
-      "integrity": "sha512-Xmht+yS42G0QAzLBYFTuCYofQ3NGUBENPyW9hi8PxrVm3E76AVVdFNl3xxTJ8/N2L8XEUb29hOEMGh/GFnZHrA==",
+      "version": "1.4.215",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.215.tgz",
+      "integrity": "sha512-vqZxT8C5mlDZ//hQFhneHmOLnj1LhbzxV0+I1yqHV8SB1Oo4Y5Ne9+qQhwHl7O1s9s9cRuo2l5CoLEHdhMTwZg==",
       "dev": true
     },
     "node_modules/emoji-regex": {
@@ -4931,13 +4948,14 @@
       }
     },
     "node_modules/eslint": {
-      "version": "8.20.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz",
-      "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==",
+      "version": "8.21.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz",
+      "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==",
       "dev": true,
       "dependencies": {
         "@eslint/eslintrc": "^1.3.0",
-        "@humanwhocodes/config-array": "^0.9.2",
+        "@humanwhocodes/config-array": "^0.10.4",
+        "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
@@ -4947,14 +4965,17 @@
         "eslint-scope": "^7.1.1",
         "eslint-utils": "^3.0.0",
         "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.2",
+        "espree": "^9.3.3",
         "esquery": "^1.4.0",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
         "file-entry-cache": "^6.0.1",
+        "find-up": "^5.0.0",
         "functional-red-black-tree": "^1.0.1",
         "glob-parent": "^6.0.1",
         "globals": "^13.15.0",
+        "globby": "^11.1.0",
+        "grapheme-splitter": "^1.0.4",
         "ignore": "^5.2.0",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
@@ -5120,6 +5141,22 @@
         "node": ">=4.0"
       }
     },
+    "node_modules/eslint/node_modules/find-up": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+      "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+      "dev": true,
+      "dependencies": {
+        "locate-path": "^6.0.0",
+        "path-exists": "^4.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
     "node_modules/eslint/node_modules/glob-parent": {
       "version": "6.0.2",
       "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -5177,6 +5214,60 @@
         "js-yaml": "bin/js-yaml.js"
       }
     },
+    "node_modules/eslint/node_modules/locate-path": {
+      "version": "6.0.0",
+      "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+      "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+      "dev": true,
+      "dependencies": {
+        "p-locate": "^5.0.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/p-limit": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+      "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+      "dev": true,
+      "dependencies": {
+        "yocto-queue": "^0.1.0"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/p-locate": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+      "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+      "dev": true,
+      "dependencies": {
+        "p-limit": "^3.0.2"
+      },
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
+    },
+    "node_modules/eslint/node_modules/path-exists": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+      "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+      "dev": true,
+      "engines": {
+        "node": ">=8"
+      }
+    },
     "node_modules/eslint/node_modules/supports-color": {
       "version": "7.2.0",
       "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -5202,17 +5293,20 @@
       }
     },
     "node_modules/espree": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
-      "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+      "version": "9.3.3",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
+      "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
       "dev": true,
       "dependencies": {
-        "acorn": "^8.7.1",
+        "acorn": "^8.8.0",
         "acorn-jsx": "^5.3.2",
         "eslint-visitor-keys": "^3.3.0"
       },
       "engines": {
         "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+      },
+      "funding": {
+        "url": "https://opencollective.com/eslint"
       }
     },
     "node_modules/espree/node_modules/eslint-visitor-keys": {
@@ -5313,18 +5407,6 @@
         "es5-ext": "~0.10.14"
       }
     },
-    "node_modules/execall": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
-      "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==",
-      "dev": true,
-      "dependencies": {
-        "clone-regexp": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
     "node_modules/expand-brackets": {
       "version": "2.1.4",
       "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
@@ -5645,10 +5727,13 @@
       "dev": true
     },
     "node_modules/fastest-levenshtein": {
-      "version": "1.0.12",
-      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
-      "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==",
-      "dev": true
+      "version": "1.0.16",
+      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+      "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
+      "dev": true,
+      "engines": {
+        "node": ">= 4.9.1"
+      }
     },
     "node_modules/fastq": {
       "version": "1.13.0",
@@ -5960,18 +6045,6 @@
         "url": "https://github.com/sponsors/ljharb"
       }
     },
-    "node_modules/get-stdin": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
-      "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
-      "dev": true,
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
     "node_modules/get-value": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -5982,15 +6055,15 @@
       }
     },
     "node_modules/glob": {
-      "version": "7.1.7",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
-      "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
       "dev": true,
       "dependencies": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.1",
         "once": "^1.3.0",
         "path-is-absolute": "^1.0.0"
       },
@@ -6272,6 +6345,12 @@
       "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
+    "node_modules/grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+      "dev": true
+    },
     "node_modules/gulp": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
@@ -8127,15 +8206,6 @@
       "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
       "dev": true
     },
-    "node_modules/is-regexp": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz",
-      "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==",
-      "dev": true,
-      "engines": {
-        "node": ">=6"
-      }
-    },
     "node_modules/is-relative": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
@@ -8543,7 +8613,7 @@
     "node_modules/lodash.debounce": {
       "version": "4.0.8",
       "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
-      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
+      "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
       "dev": true
     },
     "node_modules/lodash.merge": {
@@ -9103,9 +9173,9 @@
       "dev": true
     },
     "node_modules/node-releases": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz",
-      "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+      "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
       "dev": true
     },
     "node_modules/normalize-package-data": {
@@ -9809,9 +9879,9 @@
       }
     },
     "node_modules/postcss": {
-      "version": "8.4.14",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
-      "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
+      "version": "8.4.16",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz",
+      "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==",
       "dev": true,
       "funding": [
         {
@@ -11299,9 +11369,9 @@
       }
     },
     "node_modules/rollup": {
-      "version": "2.77.0",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz",
-      "integrity": "sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==",
+      "version": "2.77.3",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz",
+      "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==",
       "dev": true,
       "bin": {
         "rollup": "dist/bin/rollup"
@@ -11439,9 +11509,9 @@
       "dev": true
     },
     "node_modules/sass": {
-      "version": "1.54.0",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.0.tgz",
-      "integrity": "sha512-C4zp79GCXZfK0yoHZg+GxF818/aclhp9F48XBu/+bm9vXEVAYov9iU3FBVRMq3Hx3OA4jfKL+p2K9180mEh0xQ==",
+      "version": "1.54.4",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.4.tgz",
+      "integrity": "sha512-3tmF16yvnBwtlPrNBHw/H907j8MlOX8aTBnlNX1yrKx24RKcJGPyLhFUwkoKBKesR3unP93/2z14Ll8NicwQUA==",
       "dev": true,
       "dependencies": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -12223,22 +12293,20 @@
       "dev": true
     },
     "node_modules/stylelint": {
-      "version": "14.9.1",
-      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz",
-      "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==",
+      "version": "14.10.0",
+      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.10.0.tgz",
+      "integrity": "sha512-VAmyKrEK+wNFh9R8mNqoxEFzaa4gsHGhcT4xgkQDuOA5cjF6CaNS8loYV7gpi4tIZBPUyXesotPXzJAMN8VLOQ==",
       "dev": true,
       "dependencies": {
-        "@csstools/selector-specificity": "^2.0.1",
+        "@csstools/selector-specificity": "^2.0.2",
         "balanced-match": "^2.0.0",
         "colord": "^2.9.2",
         "cosmiconfig": "^7.0.1",
         "css-functions-list": "^3.1.0",
         "debug": "^4.3.4",
-        "execall": "^2.0.0",
         "fast-glob": "^3.2.11",
-        "fastest-levenshtein": "^1.0.12",
+        "fastest-levenshtein": "^1.0.16",
         "file-entry-cache": "^6.0.1",
-        "get-stdin": "^8.0.0",
         "global-modules": "^2.0.0",
         "globby": "^11.1.0",
         "globjoin": "^0.1.4",
@@ -12253,7 +12321,7 @@
         "micromatch": "^4.0.5",
         "normalize-path": "^3.0.0",
         "picocolors": "^1.0.0",
-        "postcss": "^8.4.14",
+        "postcss": "^8.4.16",
         "postcss-media-query-parser": "^0.2.3",
         "postcss-resolve-nested-selector": "^0.1.1",
         "postcss-safe-parser": "^6.0.0",
@@ -13161,24 +13229,24 @@
       }
     },
     "node_modules/stylelint-config-recommended": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-8.0.0.tgz",
-      "integrity": "sha512-IK6dWvE000+xBv9jbnHOnBq01gt6HGVB2ZTsot+QsMpe82doDQ9hvplxfv4YnpEuUwVGGd9y6nbaAnhrjcxhZQ==",
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz",
+      "integrity": "sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==",
       "dev": true,
       "peerDependencies": {
-        "stylelint": "^14.8.0"
+        "stylelint": "^14.10.0"
       }
     },
     "node_modules/stylelint-config-standard": {
-      "version": "26.0.0",
-      "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-26.0.0.tgz",
-      "integrity": "sha512-hUuB7LaaqM8abvkOO84wh5oYSkpXgTzHu2Zza6e7mY+aOmpNTjoFBRxSLlzY0uAOMWEFx0OMKzr+reG1BUtcqQ==",
+      "version": "27.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-27.0.0.tgz",
+      "integrity": "sha512-J+wxyODWQCW2kgdhVzj51a4cFcJkglkMQrjPU/1Jo8w2oKSKK5ZRqHvDDWxEmjYWIYbMhhIMS5dOgVpGUMIACw==",
       "dev": true,
       "dependencies": {
-        "stylelint-config-recommended": "^8.0.0"
+        "stylelint-config-recommended": "^9.0.0"
       },
       "peerDependencies": {
-        "stylelint": "^14.9.0"
+        "stylelint": "^14.10.0"
       }
     },
     "node_modules/stylelint-order": {
@@ -14141,6 +14209,32 @@
         "yarn": "*"
       }
     },
+    "node_modules/update-browserslist-db": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz",
+      "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==",
+      "dev": true,
+      "funding": [
+        {
+          "type": "opencollective",
+          "url": "https://opencollective.com/browserslist"
+        },
+        {
+          "type": "tidelift",
+          "url": "https://tidelift.com/funding/github/npm/browserslist"
+        }
+      ],
+      "dependencies": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      },
+      "bin": {
+        "browserslist-lint": "cli.js"
+      },
+      "peerDependencies": {
+        "browserslist": ">= 4.21.0"
+      }
+    },
     "node_modules/uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -14357,43 +14451,20 @@
       }
     },
     "node_modules/vinyl-paths": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/vinyl-paths/-/vinyl-paths-4.0.0.tgz",
-      "integrity": "sha512-7LmsEWQoDHfLfJoF2SGT+vll4W/67XNAcQUW3Q48j3Rv7CoF/ptbp1IaXMgJTIjOIF7ehrbRFG0h1du+/gVaIQ==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/vinyl-paths/-/vinyl-paths-5.0.0.tgz",
+      "integrity": "sha512-mlclGXHx/ZWInRh92Ti/qaJAZSDmfXL9TsUVs5z8mKueiS76GtVaZYD2vEtm4RePAt69vGZGHKe5d790CPcd1g==",
       "dev": true,
       "dependencies": {
-        "through2": "^4.0.2"
+        "easy-transform-stream": "^1.0.0"
       },
       "engines": {
-        "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+        "node": ">=14.16"
       },
       "funding": {
         "url": "https://github.com/sponsors/sindresorhus"
       }
     },
-    "node_modules/vinyl-paths/node_modules/readable-stream": {
-      "version": "3.6.0",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-      "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-      "dev": true,
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/vinyl-paths/node_modules/through2": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
-      "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
-      "dev": true,
-      "dependencies": {
-        "readable-stream": "3"
-      }
-    },
     "node_modules/vinyl-sourcemap": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
@@ -14627,6 +14698,18 @@
       "engines": {
         "node": ">=12"
       }
+    },
+    "node_modules/yocto-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true,
+      "engines": {
+        "node": ">=10"
+      },
+      "funding": {
+        "url": "https://github.com/sponsors/sindresorhus"
+      }
     }
   },
   "dependencies": {
@@ -14640,9 +14723,9 @@
       }
     },
     "@babel/cli": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.18.9.tgz",
-      "integrity": "sha512-e7TOtHVrAXBJGNgoROVxqx0mathd01oJGXIDekRfxdrISnRqfM795APwkDtse9GdyPYivjg3iXiko3sF3W7f5Q==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.18.10.tgz",
+      "integrity": "sha512-dLvWH+ZDFAkd2jPBSghrsFBuXrREvFwjpDycXbmUoeochqKYe4zNSLEJYErpLg8dvxvZYe79/MkN461XCwpnGw==",
       "dev": true,
       "requires": {
         "@jridgewell/trace-mapping": "^0.3.8",
@@ -14651,7 +14734,7 @@
         "commander": "^4.0.1",
         "convert-source-map": "^1.1.0",
         "fs-readdir-recursive": "^1.1.0",
-        "glob": "^7.0.0",
+        "glob": "^7.2.0",
         "make-dir": "^2.1.0",
         "slash": "^2.0.0"
       }
@@ -14672,21 +14755,21 @@
       "dev": true
     },
     "@babel/core": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.9.tgz",
-      "integrity": "sha512-1LIb1eL8APMy91/IMW+31ckrfBM4yCoLaVzoDhZUKSM4cu1L1nIidyxkCgzPAgrC5WEz36IPEr/eSeSF9pIn+g==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.18.10.tgz",
+      "integrity": "sha512-JQM6k6ENcBFKVtWvLavlvi/mPcpYZ3+R+2EySDEMSMbp7Mn4FexlbbJVrx2R7Ijhr01T8gyqrOaABWIOgxeUyw==",
       "dev": true,
       "requires": {
         "@ampproject/remapping": "^2.1.0",
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.18.9",
+        "@babel/generator": "^7.18.10",
         "@babel/helper-compilation-targets": "^7.18.9",
         "@babel/helper-module-transforms": "^7.18.9",
         "@babel/helpers": "^7.18.9",
-        "@babel/parser": "^7.18.9",
-        "@babel/template": "^7.18.6",
-        "@babel/traverse": "^7.18.9",
-        "@babel/types": "^7.18.9",
+        "@babel/parser": "^7.18.10",
+        "@babel/template": "^7.18.10",
+        "@babel/traverse": "^7.18.10",
+        "@babel/types": "^7.18.10",
         "convert-source-map": "^1.7.0",
         "debug": "^4.1.0",
         "gensync": "^1.0.0-beta.2",
@@ -14706,12 +14789,12 @@
       }
     },
     "@babel/generator": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.9.tgz",
-      "integrity": "sha512-wt5Naw6lJrL1/SGkipMiFxJjtyczUWTP38deiP1PO60HsBjDeKk08CGC3S8iVuvf0FmTdgKwU1KIXzSKL1G0Ug==",
+      "version": "7.18.12",
+      "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.18.12.tgz",
+      "integrity": "sha512-dfQ8ebCN98SvyL7IxNMCUtZQSq5R7kxgN+r8qYTGDmmSion1hX2C0zq2yo1bsCDhXixokv1SAWTZUMYbO/V5zg==",
       "dev": true,
       "requires": {
-        "@babel/types": "^7.18.9",
+        "@babel/types": "^7.18.10",
         "@jridgewell/gen-mapping": "^0.3.2",
         "jsesc": "^2.5.1"
       }
@@ -14773,15 +14856,13 @@
       }
     },
     "@babel/helper-define-polyfill-provider": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.1.tgz",
-      "integrity": "sha512-J9hGMpJQmtWmj46B3kBHmL38UhJGhYX7eqkcq+2gsstyYt341HmPeWspihX43yVRA0mS+8GGk2Gckc7bY/HCmA==",
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.3.2.tgz",
+      "integrity": "sha512-r9QJJ+uDWrd+94BSPcP6/de67ygLtvVy6cK4luE6MOuDsZIdoaPBnfSpbO/+LTifjPckbKXRuI9BB/Z2/y3iTg==",
       "dev": true,
       "requires": {
-        "@babel/helper-compilation-targets": "^7.13.0",
-        "@babel/helper-module-imports": "^7.12.13",
-        "@babel/helper-plugin-utils": "^7.13.0",
-        "@babel/traverse": "^7.13.0",
+        "@babel/helper-compilation-targets": "^7.17.7",
+        "@babel/helper-plugin-utils": "^7.16.7",
         "debug": "^4.1.1",
         "lodash.debounce": "^4.0.8",
         "resolve": "^1.14.2",
@@ -14872,15 +14953,15 @@
       "dev": true
     },
     "@babel/helper-remap-async-to-generator": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.6.tgz",
-      "integrity": "sha512-z5wbmV55TveUPZlCLZvxWHtrjuJd+8inFhk7DG0WW87/oJuGDcjDiu7HIvGcpf5464L6xKCg3vNkmlVVz9hwyQ==",
+      "version": "7.18.9",
+      "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.18.9.tgz",
+      "integrity": "sha512-dI7q50YKd8BAv3VEfgg7PS7yD3Rtbi2J1XMXaalXO0W0164hYLnh8zpjRS0mte9MfVp/tltvr/cfdXPvJr1opA==",
       "dev": true,
       "requires": {
         "@babel/helper-annotate-as-pure": "^7.18.6",
-        "@babel/helper-environment-visitor": "^7.18.6",
-        "@babel/helper-wrap-function": "^7.18.6",
-        "@babel/types": "^7.18.6"
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-wrap-function": "^7.18.9",
+        "@babel/types": "^7.18.9"
       }
     },
     "@babel/helper-replace-supers": {
@@ -14923,6 +15004,12 @@
         "@babel/types": "^7.18.6"
       }
     },
+    "@babel/helper-string-parser": {
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz",
+      "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==",
+      "dev": true
+    },
     "@babel/helper-validator-identifier": {
       "version": "7.18.6",
       "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.18.6.tgz",
@@ -14936,15 +15023,15 @@
       "dev": true
     },
     "@babel/helper-wrap-function": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.6.tgz",
-      "integrity": "sha512-I5/LZfozwMNbwr/b1vhhuYD+J/mU+gfGAj5td7l5Rv9WYmH6i3Om69WGKNmlIpsVW/mF6O5bvTKbvDQZVgjqOw==",
+      "version": "7.18.11",
+      "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.18.11.tgz",
+      "integrity": "sha512-oBUlbv+rjZLh2Ks9SKi4aL7eKaAXBWleHzU89mP0G6BMUlRxSckk9tSIkgDGydhgFxHuGSlBQZfnaD47oBEB7w==",
       "dev": true,
       "requires": {
-        "@babel/helper-function-name": "^7.18.6",
-        "@babel/template": "^7.18.6",
-        "@babel/traverse": "^7.18.6",
-        "@babel/types": "^7.18.6"
+        "@babel/helper-function-name": "^7.18.9",
+        "@babel/template": "^7.18.10",
+        "@babel/traverse": "^7.18.11",
+        "@babel/types": "^7.18.10"
       }
     },
     "@babel/helpers": {
@@ -14970,9 +15057,9 @@
       }
     },
     "@babel/parser": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.9.tgz",
-      "integrity": "sha512-9uJveS9eY9DJ0t64YbIBZICtJy8a5QrDEVdiLCG97fVLpDTpGX7t8mMSb6OWw6Lrnjqj4O8zwjELX3dhoMgiBg==",
+      "version": "7.18.11",
+      "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.18.11.tgz",
+      "integrity": "sha512-9JKn5vN+hDt0Hdqn1PiJ2guflwP+B6Ga8qbDuoF0PzzVhrzsKIJo8yGqVk6CmMHiMei9w1C1Bp9IMJSIK+HPIQ==",
       "dev": true
     },
     "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": {
@@ -15005,14 +15092,14 @@
       }
     },
     "@babel/plugin-proposal-async-generator-functions": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.6.tgz",
-      "integrity": "sha512-WAz4R9bvozx4qwf74M+sfqPMKfSqwM0phxPTR6iJIi8robgzXwkEgmeJG1gEKhm6sDqT/U9aV3lfcqybIpev8w==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.18.10.tgz",
+      "integrity": "sha512-1mFuY2TOsR1hxbjCo4QL+qlIjV07p4H4EUYw2J/WCqsvFV6V9X9z9YhXbWndc/4fw+hYGlDT7egYxliMp5O6Ew==",
       "dev": true,
       "requires": {
-        "@babel/helper-environment-visitor": "^7.18.6",
-        "@babel/helper-plugin-utils": "^7.18.6",
-        "@babel/helper-remap-async-to-generator": "^7.18.6",
+        "@babel/helper-environment-visitor": "^7.18.9",
+        "@babel/helper-plugin-utils": "^7.18.9",
+        "@babel/helper-remap-async-to-generator": "^7.18.9",
         "@babel/plugin-syntax-async-generators": "^7.8.4"
       }
     },
@@ -15596,12 +15683,12 @@
       }
     },
     "@babel/plugin-transform-unicode-escapes": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.6.tgz",
-      "integrity": "sha512-XNRwQUXYMP7VLuy54cr/KS/WeL3AZeORhrmeZ7iewgu+X2eBqmpaLI/hzqr9ZxCeUoq0ASK4GUzSM0BDhZkLFw==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.18.10.tgz",
+      "integrity": "sha512-kKAdAI+YzPgGY/ftStBFXTI1LZFju38rYThnfMykS+IXy8BVx+res7s2fxf1l8I35DV2T97ezo6+SGrXz6B3iQ==",
       "dev": true,
       "requires": {
-        "@babel/helper-plugin-utils": "^7.18.6"
+        "@babel/helper-plugin-utils": "^7.18.9"
       }
     },
     "@babel/plugin-transform-unicode-regex": {
@@ -15615,9 +15702,9 @@
       }
     },
     "@babel/preset-env": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.9.tgz",
-      "integrity": "sha512-75pt/q95cMIHWssYtyfjVlvI+QEZQThQbKvR9xH+F/Agtw/s4Wfc2V9Bwd/P39VtixB7oWxGdH4GteTTwYJWMg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.18.10.tgz",
+      "integrity": "sha512-wVxs1yjFdW3Z/XkNfXKoblxoHgbtUF7/l3PvvP4m02Qz9TZ6uZGxRVYjSQeR87oQmHco9zWitW5J82DJ7sCjvA==",
       "dev": true,
       "requires": {
         "@babel/compat-data": "^7.18.8",
@@ -15626,7 +15713,7 @@
         "@babel/helper-validator-option": "^7.18.6",
         "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression": "^7.18.6",
         "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.18.9",
-        "@babel/plugin-proposal-async-generator-functions": "^7.18.6",
+        "@babel/plugin-proposal-async-generator-functions": "^7.18.10",
         "@babel/plugin-proposal-class-properties": "^7.18.6",
         "@babel/plugin-proposal-class-static-block": "^7.18.6",
         "@babel/plugin-proposal-dynamic-import": "^7.18.6",
@@ -15686,13 +15773,13 @@
         "@babel/plugin-transform-sticky-regex": "^7.18.6",
         "@babel/plugin-transform-template-literals": "^7.18.9",
         "@babel/plugin-transform-typeof-symbol": "^7.18.9",
-        "@babel/plugin-transform-unicode-escapes": "^7.18.6",
+        "@babel/plugin-transform-unicode-escapes": "^7.18.10",
         "@babel/plugin-transform-unicode-regex": "^7.18.6",
         "@babel/preset-modules": "^0.1.5",
-        "@babel/types": "^7.18.9",
-        "babel-plugin-polyfill-corejs2": "^0.3.1",
-        "babel-plugin-polyfill-corejs3": "^0.5.2",
-        "babel-plugin-polyfill-regenerator": "^0.3.1",
+        "@babel/types": "^7.18.10",
+        "babel-plugin-polyfill-corejs2": "^0.3.2",
+        "babel-plugin-polyfill-corejs3": "^0.5.3",
+        "babel-plugin-polyfill-regenerator": "^0.4.0",
         "core-js-compat": "^3.22.1",
         "semver": "^6.3.0"
       }
@@ -15733,49 +15820,51 @@
       }
     },
     "@babel/template": {
-      "version": "7.18.6",
-      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.6.tgz",
-      "integrity": "sha512-JoDWzPe+wgBsTTgdnIma3iHNFC7YVJoPssVBDjiHfNlyt4YcunDtcDOUmfVDfCK5MfdsaIoX9PkijPhjH3nYUw==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz",
+      "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.18.6",
-        "@babel/parser": "^7.18.6",
-        "@babel/types": "^7.18.6"
+        "@babel/parser": "^7.18.10",
+        "@babel/types": "^7.18.10"
       }
     },
     "@babel/traverse": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.9.tgz",
-      "integrity": "sha512-LcPAnujXGwBgv3/WHv01pHtb2tihcyW1XuL9wd7jqh1Z8AQkTd+QVjMrMijrln0T7ED3UXLIy36P9Ao7W75rYg==",
+      "version": "7.18.11",
+      "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.18.11.tgz",
+      "integrity": "sha512-TG9PiM2R/cWCAy6BPJKeHzNbu4lPzOSZpeMfeNErskGpTJx6trEvFaVCbDvpcxwy49BKWmEPwiW8mrysNiDvIQ==",
       "dev": true,
       "requires": {
         "@babel/code-frame": "^7.18.6",
-        "@babel/generator": "^7.18.9",
+        "@babel/generator": "^7.18.10",
         "@babel/helper-environment-visitor": "^7.18.9",
         "@babel/helper-function-name": "^7.18.9",
         "@babel/helper-hoist-variables": "^7.18.6",
         "@babel/helper-split-export-declaration": "^7.18.6",
-        "@babel/parser": "^7.18.9",
-        "@babel/types": "^7.18.9",
+        "@babel/parser": "^7.18.11",
+        "@babel/types": "^7.18.10",
         "debug": "^4.1.0",
         "globals": "^11.1.0"
       }
     },
     "@babel/types": {
-      "version": "7.18.9",
-      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.9.tgz",
-      "integrity": "sha512-WwMLAg2MvJmt/rKEVQBBhIVffMmnilX4oe0sRe7iPOHIGsqpruFHHdrfj4O1CMMtgMtCU4oPafZjDPCRgO57Wg==",
+      "version": "7.18.10",
+      "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.18.10.tgz",
+      "integrity": "sha512-MJvnbEiiNkpjo+LknnmRrqbY1GPUUggjv+wQVjetM/AONoupqRALB7I6jGqNUAZsKcRIEu2J6FRFvsczljjsaQ==",
       "dev": true,
       "requires": {
+        "@babel/helper-string-parser": "^7.18.10",
         "@babel/helper-validator-identifier": "^7.18.6",
         "to-fast-properties": "^2.0.0"
       }
     },
     "@csstools/selector-specificity": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.1.tgz",
-      "integrity": "sha512-aG20vknL4/YjQF9BSV7ts4EWm/yrjagAN7OWBNmlbEOUiu0llj4OGrFoOKK3g2vey4/p2omKCoHrWtPxSwV3HA==",
-      "dev": true
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz",
+      "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==",
+      "dev": true,
+      "requires": {}
     },
     "@eslint/eslintrc": {
       "version": "1.3.0",
@@ -15833,9 +15922,9 @@
       }
     },
     "@fortawesome/fontawesome-free": {
-      "version": "6.1.1",
-      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.1.tgz",
-      "integrity": "sha512-J/3yg2AIXc9wznaVqpHVX3Wa5jwKovVF0AMYSnbmcXTiL3PpRPfF58pzWucCwEiCJBp+hCNRLWClTomD8SseKg==",
+      "version": "6.1.2",
+      "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-6.1.2.tgz",
+      "integrity": "sha512-XwWADtfdSN73/udaFm+1mnGIj/ShDZNFMe/PRoqv3FhQ4GNI2PUN70yFTPsjq65Lw2C9i4TG5/hTbxXIXVCiqQ==",
       "dev": true
     },
     "@gulp-sourcemaps/identity-map": {
@@ -15917,9 +16006,9 @@
       }
     },
     "@humanwhocodes/config-array": {
-      "version": "0.9.2",
-      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.9.2.tgz",
-      "integrity": "sha512-UXOuFCGcwciWckOpmfKDq/GyhlTf9pN/BzG//x8p8zTOFEcGuA68ANXheFS0AGvy3qgZqLBUkMs7hqzqCKOVwA==",
+      "version": "0.10.4",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.4.tgz",
+      "integrity": "sha512-mXAIHxZT3Vcpg83opl1wGlVZ9xydbfZO3r5YfRSH6Gpp2J/PfdBP0wbDa2sO6/qRbcalpoevVyW6A/fI6LfeMw==",
       "dev": true,
       "requires": {
         "@humanwhocodes/object-schema": "^1.2.1",
@@ -15927,6 +16016,12 @@
         "minimatch": "^3.0.4"
       }
     },
+    "@humanwhocodes/gitignore-to-minimatch": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz",
+      "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==",
+      "dev": true
+    },
     "@humanwhocodes/object-schema": {
       "version": "1.2.1",
       "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
@@ -16032,9 +16127,9 @@
       }
     },
     "@primer/octicons": {
-      "version": "17.3.0",
-      "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.3.0.tgz",
-      "integrity": "sha512-4zPwwloYWdR6RznMafV7Fsw3n2CeDPp/+qEIQbaX/tBbPY1KmU0OAXmhRfhD5AzgB5kdV1aQ7KnQr1GeQXl9Dg==",
+      "version": "17.4.0",
+      "resolved": "https://registry.npmjs.org/@primer/octicons/-/octicons-17.4.0.tgz",
+      "integrity": "sha512-fRD9A/JszKOe5mDIU+g1b8jvcPj/qzusxdxnrIrg8Db0mLHsbGc4xNMUtHbRmgFOKaF6/QBR+WnWGQxv4yTcBg==",
       "dev": true,
       "requires": {
         "object-assign": "^4.1.1"
@@ -16166,16 +16261,17 @@
       }
     },
     "acorn": {
-      "version": "8.7.1",
-      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.1.tgz",
-      "integrity": "sha512-Xx54uLJQZ19lKygFXOWsscKUbsBZW0CPykPhVQdhIeIwrbPmJzqeASDInc8nKBnp/JT6igTs82qPXz069H8I/A==",
+      "version": "8.8.0",
+      "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz",
+      "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==",
       "dev": true
     },
     "acorn-jsx": {
       "version": "5.3.2",
       "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
       "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "aggregate-error": {
       "version": "4.0.1",
@@ -16507,13 +16603,13 @@
       "dev": true
     },
     "autoprefixer": {
-      "version": "10.4.7",
-      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.7.tgz",
-      "integrity": "sha512-ypHju4Y2Oav95SipEcCcI5J7CGPuvz8oat7sUtYj3ClK44bldfvtvcxK6IEK++7rqB7YchDGzweZIBG+SD0ZAA==",
+      "version": "10.4.8",
+      "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.8.tgz",
+      "integrity": "sha512-75Jr6Q/XpTqEf6D2ltS5uMewJIx5irCU1oBYJrWjFenq/m12WRRrz6g15L1EIoYvPLXTbEry7rDOwrcYNj77xw==",
       "dev": true,
       "requires": {
-        "browserslist": "^4.20.3",
-        "caniuse-lite": "^1.0.30001335",
+        "browserslist": "^4.21.3",
+        "caniuse-lite": "^1.0.30001373",
         "fraction.js": "^4.2.0",
         "normalize-range": "^0.1.2",
         "picocolors": "^1.0.0",
@@ -16583,7 +16679,8 @@
       "version": "7.0.0-bridge.0",
       "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
       "integrity": "sha512-poPX9mZH/5CSanm50Q+1toVci6pv5KSRv/5TWCwtzQS5XEwn40BcCrgIeMFWP9CKKIniKXNxoIOnOq4VVlGXhg==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "babel-generator": {
       "version": "6.26.1",
@@ -16697,33 +16794,33 @@
       }
     },
     "babel-plugin-polyfill-corejs2": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.1.tgz",
-      "integrity": "sha512-v7/T6EQcNfVLfcN2X8Lulb7DjprieyLWJK/zOWH5DUYcAgex9sP3h25Q+DLsX9TloXe3y1O8l2q2Jv9q8UVB9w==",
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.2.tgz",
+      "integrity": "sha512-LPnodUl3lS0/4wN3Rb+m+UK8s7lj2jcLRrjho4gLw+OJs+I4bvGXshINesY5xx/apM+biTnQ9reDI8yj+0M5+Q==",
       "dev": true,
       "requires": {
-        "@babel/compat-data": "^7.13.11",
-        "@babel/helper-define-polyfill-provider": "^0.3.1",
+        "@babel/compat-data": "^7.17.7",
+        "@babel/helper-define-polyfill-provider": "^0.3.2",
         "semver": "^6.1.1"
       }
     },
     "babel-plugin-polyfill-corejs3": {
-      "version": "0.5.2",
-      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.2.tgz",
-      "integrity": "sha512-G3uJih0XWiID451fpeFaYGVuxHEjzKTHtc9uGFEjR6hHrvNzeS/PX+LLLcetJcytsB5m4j+K3o/EpXJNb/5IEQ==",
+      "version": "0.5.3",
+      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.5.3.tgz",
+      "integrity": "sha512-zKsXDh0XjnrUEW0mxIHLfjBfnXSMr5Q/goMe/fxpQnLm07mcOZiIZHBNWCMx60HmdvjxfXcalac0tfFg0wqxyw==",
       "dev": true,
       "requires": {
-        "@babel/helper-define-polyfill-provider": "^0.3.1",
+        "@babel/helper-define-polyfill-provider": "^0.3.2",
         "core-js-compat": "^3.21.0"
       }
     },
     "babel-plugin-polyfill-regenerator": {
-      "version": "0.3.1",
-      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.1.tgz",
-      "integrity": "sha512-Y2B06tvgHYt1x0yz17jGkGeeMr5FeKUu+ASJ+N6nB5lQ8Dapfg42i0OVrf8PNGJ3zKL4A23snMi1IRwrqqND7A==",
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.4.0.tgz",
+      "integrity": "sha512-RW1cnryiADFeHmfLS+WW/G431p1PsW5qdRdz0SDRi7TKcUgc7Oh/uXkT7MZ/+tGsT1BkczEAmD5XjUyJ5SWDTw==",
       "dev": true,
       "requires": {
-        "@babel/helper-define-polyfill-provider": "^0.3.1"
+        "@babel/helper-define-polyfill-provider": "^0.3.2"
       }
     },
     "babel-plugin-syntax-async-functions": {
@@ -17087,16 +17184,15 @@
       }
     },
     "browserslist": {
-      "version": "4.20.3",
-      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.20.3.tgz",
-      "integrity": "sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==",
+      "version": "4.21.3",
+      "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.3.tgz",
+      "integrity": "sha512-898rgRXLAyRkM1GryrrBHGkqA5hlpkV5MhtZwg9QXeiyLUYs2k00Un05aX5l2/yJIOObYKOpS2JNo8nJDE7fWQ==",
       "dev": true,
       "requires": {
-        "caniuse-lite": "^1.0.30001332",
-        "electron-to-chromium": "^1.4.118",
-        "escalade": "^3.1.1",
-        "node-releases": "^2.0.3",
-        "picocolors": "^1.0.0"
+        "caniuse-lite": "^1.0.30001370",
+        "electron-to-chromium": "^1.4.202",
+        "node-releases": "^2.0.6",
+        "update-browserslist-db": "^1.0.5"
       }
     },
     "buffer-equal": {
@@ -17194,9 +17290,9 @@
       }
     },
     "caniuse-lite": {
-      "version": "1.0.30001335",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001335.tgz",
-      "integrity": "sha512-ddP1Tgm7z2iIxu6QTtbZUv6HJxSaV/PZeSrWFZtbY4JZ69tOeNhBCl3HyRQgeNZKE5AOn1kpV7fhljigy0Ty3w==",
+      "version": "1.0.30001375",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001375.tgz",
+      "integrity": "sha512-kWIMkNzLYxSvnjy0hL8w1NOaWNr2rn39RTAVyIwcw8juu60bZDWiF1/loOYANzjtJmy6qPgNmn38ro5Pygagdw==",
       "dev": true
     },
     "ccount": {
@@ -17500,15 +17596,6 @@
         "shallow-clone": "^3.0.0"
       }
     },
-    "clone-regexp": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz",
-      "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==",
-      "dev": true,
-      "requires": {
-        "is-regexp": "^2.0.0"
-      }
-    },
     "clone-stats": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
@@ -17741,12 +17828,12 @@
       }
     },
     "core-js-compat": {
-      "version": "3.22.4",
-      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.22.4.tgz",
-      "integrity": "sha512-dIWcsszDezkFZrfm1cnB4f/J85gyhiCpxbgBdohWCDtSVuAaChTSpPV7ldOQf/Xds2U5xCIJZOK82G4ZPAIswA==",
+      "version": "3.24.1",
+      "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.24.1.tgz",
+      "integrity": "sha512-XhdNAGeRnTpp8xbD+sR/HFDK9CbeeeqXT6TuofXh3urqEevzkWmLRgrVoykodsw8okqo2pu1BOmuCKrHx63zdw==",
       "dev": true,
       "requires": {
-        "browserslist": "^4.20.3",
+        "browserslist": "^4.21.3",
         "semver": "7.0.0"
       },
       "dependencies": {
@@ -18218,10 +18305,16 @@
         "object.defaults": "^1.1.0"
       }
     },
+    "easy-transform-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/easy-transform-stream/-/easy-transform-stream-1.0.0.tgz",
+      "integrity": "sha512-kIEXvPNtqUQ/lrgkULIP0/l2m88Ahlk2ySZhmuLdRidXBIEPyHuDgDt04b9DvnCy+nIQDjpygVft+Op3PZFUQg==",
+      "dev": true
+    },
     "electron-to-chromium": {
-      "version": "1.4.130",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.130.tgz",
-      "integrity": "sha512-Xmht+yS42G0QAzLBYFTuCYofQ3NGUBENPyW9hi8PxrVm3E76AVVdFNl3xxTJ8/N2L8XEUb29hOEMGh/GFnZHrA==",
+      "version": "1.4.215",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.215.tgz",
+      "integrity": "sha512-vqZxT8C5mlDZ//hQFhneHmOLnj1LhbzxV0+I1yqHV8SB1Oo4Y5Ne9+qQhwHl7O1s9s9cRuo2l5CoLEHdhMTwZg==",
       "dev": true
     },
     "emoji-regex": {
@@ -18319,13 +18412,14 @@
       "dev": true
     },
     "eslint": {
-      "version": "8.20.0",
-      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.20.0.tgz",
-      "integrity": "sha512-d4ixhz5SKCa1D6SCPrivP7yYVi7nyD6A4vs6HIAul9ujBzcEmZVM3/0NN/yu5nKhmO1wjp5xQ46iRfmDGlOviA==",
+      "version": "8.21.0",
+      "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.21.0.tgz",
+      "integrity": "sha512-/XJ1+Qurf1T9G2M5IHrsjp+xrGT73RZf23xA1z5wB1ZzzEAWSZKvRwhWxTFp1rvkvCfwcvAUNAP31bhKTTGfDA==",
       "dev": true,
       "requires": {
         "@eslint/eslintrc": "^1.3.0",
-        "@humanwhocodes/config-array": "^0.9.2",
+        "@humanwhocodes/config-array": "^0.10.4",
+        "@humanwhocodes/gitignore-to-minimatch": "^1.0.2",
         "ajv": "^6.10.0",
         "chalk": "^4.0.0",
         "cross-spawn": "^7.0.2",
@@ -18335,14 +18429,17 @@
         "eslint-scope": "^7.1.1",
         "eslint-utils": "^3.0.0",
         "eslint-visitor-keys": "^3.3.0",
-        "espree": "^9.3.2",
+        "espree": "^9.3.3",
         "esquery": "^1.4.0",
         "esutils": "^2.0.2",
         "fast-deep-equal": "^3.1.3",
         "file-entry-cache": "^6.0.1",
+        "find-up": "^5.0.0",
         "functional-red-black-tree": "^1.0.1",
         "glob-parent": "^6.0.1",
         "globals": "^13.15.0",
+        "globby": "^11.1.0",
+        "grapheme-splitter": "^1.0.4",
         "ignore": "^5.2.0",
         "import-fresh": "^3.0.0",
         "imurmurhash": "^0.1.4",
@@ -18429,6 +18526,16 @@
           "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
           "dev": true
         },
+        "find-up": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+          "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^6.0.0",
+            "path-exists": "^4.0.0"
+          }
+        },
         "glob-parent": {
           "version": "6.0.2",
           "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
@@ -18468,6 +18575,39 @@
             "argparse": "^2.0.1"
           }
         },
+        "locate-path": {
+          "version": "6.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+          "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^5.0.0"
+          }
+        },
+        "p-limit": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+          "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+          "dev": true,
+          "requires": {
+            "yocto-queue": "^0.1.0"
+          }
+        },
+        "p-locate": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+          "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^3.0.2"
+          }
+        },
+        "path-exists": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+          "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+          "dev": true
+        },
         "supports-color": {
           "version": "7.2.0",
           "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
@@ -18511,12 +18651,12 @@
       "dev": true
     },
     "espree": {
-      "version": "9.3.2",
-      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.2.tgz",
-      "integrity": "sha512-D211tC7ZwouTIuY5x9XnS0E9sWNChB7IYKX/Xp5eQj3nFXhqmiUDB9q27y76oFl8jTg3pXcQx/bpxMfs3CIZbA==",
+      "version": "9.3.3",
+      "resolved": "https://registry.npmjs.org/espree/-/espree-9.3.3.tgz",
+      "integrity": "sha512-ORs1Rt/uQTqUKjDdGCyrtYxbazf5umATSf/K4qxjmZHORR6HJk+2s/2Pqe+Kk49HHINC/xNIrGfgh8sZcll0ng==",
       "dev": true,
       "requires": {
-        "acorn": "^8.7.1",
+        "acorn": "^8.8.0",
         "acorn-jsx": "^5.3.2",
         "eslint-visitor-keys": "^3.3.0"
       },
@@ -18597,15 +18737,6 @@
         "es5-ext": "~0.10.14"
       }
     },
-    "execall": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
-      "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==",
-      "dev": true,
-      "requires": {
-        "clone-regexp": "^2.1.0"
-      }
-    },
     "expand-brackets": {
       "version": "2.1.4",
       "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
@@ -18878,9 +19009,9 @@
       "dev": true
     },
     "fastest-levenshtein": {
-      "version": "1.0.12",
-      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz",
-      "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==",
+      "version": "1.0.16",
+      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
+      "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
       "dev": true
     },
     "fastq": {
@@ -19127,12 +19258,6 @@
         "has-symbols": "^1.0.1"
       }
     },
-    "get-stdin": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz",
-      "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==",
-      "dev": true
-    },
     "get-value": {
       "version": "2.0.6",
       "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
@@ -19140,15 +19265,15 @@
       "dev": true
     },
     "glob": {
-      "version": "7.1.7",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz",
-      "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==",
+      "version": "7.2.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
+      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
       "dev": true,
       "requires": {
         "fs.realpath": "^1.0.0",
         "inflight": "^1.0.4",
         "inherits": "2",
-        "minimatch": "^3.0.4",
+        "minimatch": "^3.1.1",
         "once": "^1.3.0",
         "path-is-absolute": "^1.0.0"
       }
@@ -19375,6 +19500,12 @@
       "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==",
       "dev": true
     },
+    "grapheme-splitter": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+      "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+      "dev": true
+    },
     "gulp": {
       "version": "4.0.2",
       "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.2.tgz",
@@ -20803,12 +20934,6 @@
       "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
       "dev": true
     },
-    "is-regexp": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz",
-      "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==",
-      "dev": true
-    },
     "is-relative": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
@@ -21125,7 +21250,7 @@
     "lodash.debounce": {
       "version": "4.0.8",
       "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
-      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
+      "integrity": "sha512-FT1yDzDYEoYWhnSGnpE/4Kj1fLZkDFyqRb7fNt6FdYOSxlUWAtp42Eh6Wb0rGIv/m9Bgo7x4GhQbm5Ys4SG5ow==",
       "dev": true
     },
     "lodash.merge": {
@@ -21580,9 +21705,9 @@
       "dev": true
     },
     "node-releases": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.4.tgz",
-      "integrity": "sha512-gbMzqQtTtDz/00jQzZ21PQzdI9PyLYqUSvD0p3naOhX4odFji0ZxYdnVwPTxmSwkmxhcFImpozceidSG+AgoPQ==",
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz",
+      "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==",
       "dev": true
     },
     "normalize-package-data": {
@@ -22111,9 +22236,9 @@
       "dev": true
     },
     "postcss": {
-      "version": "8.4.14",
-      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.14.tgz",
-      "integrity": "sha512-E398TUmfAYFPBSdzgeieK2Y1+1cpdxJx8yXbK/m57nRhKSmk1GB2tO4lbLBtlkfPQTDKfe4Xqv1ASWPpayPEig==",
+      "version": "8.4.16",
+      "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz",
+      "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==",
       "dev": true,
       "requires": {
         "nanoid": "^3.3.4",
@@ -22488,7 +22613,8 @@
       "version": "7.0.1",
       "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz",
       "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-svgo": {
       "version": "5.1.0",
@@ -22504,7 +22630,8 @@
       "version": "0.36.2",
       "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz",
       "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==",
-      "dev": true
+      "dev": true,
+      "requires": {}
     },
     "postcss-value-parser": {
       "version": "4.2.0",
@@ -23288,9 +23415,9 @@
       }
     },
     "rollup": {
-      "version": "2.77.0",
-      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.0.tgz",
-      "integrity": "sha512-vL8xjY4yOQEw79DvyXLijhnhh+R/O9zpF/LEgkCebZFtb6ELeN9H3/2T0r8+mp+fFTBHZ5qGpOpW2ela2zRt3g==",
+      "version": "2.77.3",
+      "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.77.3.tgz",
+      "integrity": "sha512-/qxNTG7FbmefJWoeeYJFbHehJ2HNWnjkAFRKzWN/45eNBBF/r8lo992CwcJXEzyVxs5FmfId+vTSTQDb+bxA+g==",
       "dev": true,
       "requires": {
         "fsevents": "~2.3.2"
@@ -23400,9 +23527,9 @@
       "dev": true
     },
     "sass": {
-      "version": "1.54.0",
-      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.0.tgz",
-      "integrity": "sha512-C4zp79GCXZfK0yoHZg+GxF818/aclhp9F48XBu/+bm9vXEVAYov9iU3FBVRMq3Hx3OA4jfKL+p2K9180mEh0xQ==",
+      "version": "1.54.4",
+      "resolved": "https://registry.npmjs.org/sass/-/sass-1.54.4.tgz",
+      "integrity": "sha512-3tmF16yvnBwtlPrNBHw/H907j8MlOX8aTBnlNX1yrKx24RKcJGPyLhFUwkoKBKesR3unP93/2z14Ll8NicwQUA==",
       "dev": true,
       "requires": {
         "chokidar": ">=3.0.0 <4.0.0",
@@ -24043,22 +24170,20 @@
       "dev": true
     },
     "stylelint": {
-      "version": "14.9.1",
-      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz",
-      "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==",
+      "version": "14.10.0",
+      "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.10.0.tgz",
+      "integrity": "sha512-VAmyKrEK+wNFh9R8mNqoxEFzaa4gsHGhcT4xgkQDuOA5cjF6CaNS8loYV7gpi4tIZBPUyXesotPXzJAMN8VLOQ==",
       "dev": true,
       "requires": {
-        "@csstools/selector-specificity": "^2.0.1",
+        "@csstools/selector-specificity": "^2.0.2",
         "balanced-match": "^2.0.0",
         "colord": "^2.9.2",
         "cosmiconfig": "^7.0.1",
         "css-functions-list": "^3.1.0",
         "debug": "^4.3.4",
-        "execall": "^2.0.0",
         "fast-glob": "^3.2.11",
-        "fastest-levenshtein": "^1.0.12",
+        "fastest-levenshtein": "^1.0.16",
         "file-entry-cache": "^6.0.1",
-        "get-stdin": "^8.0.0",
         "global-modules": "^2.0.0",
         "globby": "^11.1.0",
         "globjoin": "^0.1.4",
@@ -24073,7 +24198,7 @@
         "micromatch": "^4.0.5",
         "normalize-path": "^3.0.0",
         "picocolors": "^1.0.0",
-        "postcss": "^8.4.14",
+        "postcss": "^8.4.16",
         "postcss-media-query-parser": "^0.2.3",
         "postcss-resolve-nested-selector": "^0.1.1",
         "postcss-safe-parser": "^6.0.0",
@@ -24166,7 +24291,8 @@
           "version": "6.0.0",
           "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz",
           "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==",
-          "dev": true
+          "dev": true,
+          "requires": {}
         },
         "resolve-from": {
           "version": "5.0.0",
@@ -24887,18 +25013,19 @@
       }
     },
     "stylelint-config-recommended": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-8.0.0.tgz",
-      "integrity": "sha512-IK6dWvE000+xBv9jbnHOnBq01gt6HGVB2ZTsot+QsMpe82doDQ9hvplxfv4YnpEuUwVGGd9y6nbaAnhrjcxhZQ==",
-      "dev": true
+      "version": "9.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz",
+      "integrity": "sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==",
+      "dev": true,
+      "requires": {}
     },
     "stylelint-config-standard": {
-      "version": "26.0.0",
-      "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-26.0.0.tgz",
-      "integrity": "sha512-hUuB7LaaqM8abvkOO84wh5oYSkpXgTzHu2Zza6e7mY+aOmpNTjoFBRxSLlzY0uAOMWEFx0OMKzr+reG1BUtcqQ==",
+      "version": "27.0.0",
+      "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-27.0.0.tgz",
+      "integrity": "sha512-J+wxyODWQCW2kgdhVzj51a4cFcJkglkMQrjPU/1Jo8w2oKSKK5ZRqHvDDWxEmjYWIYbMhhIMS5dOgVpGUMIACw==",
       "dev": true,
       "requires": {
-        "stylelint-config-recommended": "^8.0.0"
+        "stylelint-config-recommended": "^9.0.0"
       }
     },
     "stylelint-order": {
@@ -25568,6 +25695,16 @@
       "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==",
       "dev": true
     },
+    "update-browserslist-db": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.5.tgz",
+      "integrity": "sha512-dteFFpCyvuDdr9S/ff1ISkKt/9YZxKjI9WlRR99c180GaztJtRa/fn18FdxGVKVsnPY7/a/FDN68mcvUmP4U7Q==",
+      "dev": true,
+      "requires": {
+        "escalade": "^3.1.1",
+        "picocolors": "^1.0.0"
+      }
+    },
     "uri-js": {
       "version": "4.4.1",
       "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
@@ -25763,34 +25900,12 @@
       }
     },
     "vinyl-paths": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/vinyl-paths/-/vinyl-paths-4.0.0.tgz",
-      "integrity": "sha512-7LmsEWQoDHfLfJoF2SGT+vll4W/67XNAcQUW3Q48j3Rv7CoF/ptbp1IaXMgJTIjOIF7ehrbRFG0h1du+/gVaIQ==",
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/vinyl-paths/-/vinyl-paths-5.0.0.tgz",
+      "integrity": "sha512-mlclGXHx/ZWInRh92Ti/qaJAZSDmfXL9TsUVs5z8mKueiS76GtVaZYD2vEtm4RePAt69vGZGHKe5d790CPcd1g==",
       "dev": true,
       "requires": {
-        "through2": "^4.0.2"
-      },
-      "dependencies": {
-        "readable-stream": {
-          "version": "3.6.0",
-          "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-          "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
-          "dev": true,
-          "requires": {
-            "inherits": "^2.0.3",
-            "string_decoder": "^1.1.1",
-            "util-deprecate": "^1.0.1"
-          }
-        },
-        "through2": {
-          "version": "4.0.2",
-          "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz",
-          "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==",
-          "dev": true,
-          "requires": {
-            "readable-stream": "3"
-          }
-        }
+        "easy-transform-stream": "^1.0.0"
       }
     },
     "vinyl-sourcemap": {
@@ -25969,6 +26084,12 @@
       "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
       "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
       "dev": true
+    },
+    "yocto-queue": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+      "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+      "dev": true
     }
   }
 }
diff --git a/package.json b/package.json
index c695b6d8d..df8645ef3 100644
--- a/package.json
+++ b/package.json
@@ -17,23 +17,23 @@
     "node": ">= 10"
   },
   "devDependencies": {
-    "@babel/cli": "^7.18.9",
-    "@babel/core": "^7.18.9",
+    "@babel/cli": "^7.18.10",
+    "@babel/core": "^7.18.10",
     "@babel/eslint-parser": "^7.18.9",
     "@babel/plugin-external-helpers": "^7.18.6",
-    "@babel/preset-env": "^7.18.9",
+    "@babel/preset-env": "^7.18.10",
     "@babel/register": "^7.18.9",
-    "@fortawesome/fontawesome-free": "^6.1.1",
+    "@fortawesome/fontawesome-free": "^6.1.2",
     "@mdi/svg": "^7.0.96",
-    "@primer/octicons": "^17.3.0",
+    "@primer/octicons": "^17.4.0",
     "@rollup/plugin-babel": "^5.3.1",
     "@rollup/plugin-replace": "^4.0.0",
-    "autoprefixer": "^10.4.7",
+    "autoprefixer": "^10.4.8",
     "babel-core": "^7.0.0-bridge.0",
     "clean-css": "^5.3.1",
     "css-mqpacker": "^7.0.0",
     "del": "^7.0.0",
-    "eslint": "^8.20.0",
+    "eslint": "^8.21.0",
     "fast-glob": "^3.2.11",
     "gulp": "^4.0.2",
     "gulp-clean-css": "^4.3.0",
@@ -54,18 +54,18 @@
     "postcss-pseudo-classes": "^0.2.1",
     "postcss-svgo": "^5.1.0",
     "promise": "^8.1.0",
-    "rollup": "^2.77.0",
+    "rollup": "^2.77.3",
     "rollup-plugin-output-manifest": "^2.0.0",
     "rollup-plugin-regenerator": "^0.6.0",
     "rollup-plugin-terser": "^7.0.2",
-    "sass": "^1.54.0",
-    "stylelint": "^14.9.1",
+    "sass": "^1.54.4",
+    "stylelint": "^14.10.0",
     "stylelint-config-rational-order": "^0.1.2",
-    "stylelint-config-standard": "^26.0.0",
+    "stylelint-config-standard": "^27.0.0",
     "stylelint-order": "^5.0.0",
     "stylelint-scss": "^4.3.0",
     "terser": "^5.14.2",
-    "vinyl-paths": "^4.0.0",
+    "vinyl-paths": "^5.0.0",
     "yargs": "^17.5.1"
   }
 }


Test patch:
diff --git a/tests/test_interpolation.py b/tests/test_interpolation.py
index 39659a3d6..5b2ff66c6 100644
--- a/tests/test_interpolation.py
+++ b/tests/test_interpolation.py
@@ -1091,8 +1091,8 @@ def test_extrapolate_bspline(self):
             method='bspline',
             extrapolate=True
         )
-        self.assertColorEqual(i(-0.5), Color('color(--oklab 0.7 0.15417 0.1 / 1)'))
-        self.assertColorEqual(i(1.5), Color('color(--oklab 0.7 -0.02875 -0.12292 / 1)'))
+        self.assertColorEqual(i(-0.5), Color('oklab(0.7 0.25 0.1)'))
+        self.assertColorEqual(i(1.5), Color('oklab(0.7 0 -0.19)'))
 
     def test_extrapolate_linear(self):
         """